Guest User

Black Hat Bot

a guest
Jan 22nd, 2016
373
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 290.26 KB | None | 0 0
  1. // ==UserScript==
  2. // @name Bot By Black Hat Team
  3. // @namespace http://your.homepage/
  4. // @version 0.1
  5. // @description enter something useful
  6. // @author You
  7. // @match http://agar.io/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. !function(a){a.Parse=a.Parse||{},a.Parse.VERSION="js1.5.0"}(this),function(){var a=this,b=a._,c={},d=Array.prototype,e=Object.prototype,f=Function.prototype,g=d.push,h=d.slice,i=d.concat,j=e.toString,k=e.hasOwnProperty,l=d.forEach,m=d.map,n=d.reduce,o=d.reduceRight,p=d.filter,q=d.every,r=d.some,s=d.indexOf,t=d.lastIndexOf,u=Array.isArray,v=Object.keys,w=f.bind,x=function(a){return a instanceof x?a:this instanceof x?void(this._wrapped=a):new x(a)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=x),exports._=x):a._=x,x.VERSION="1.4.4";var y=x.each=x.forEach=function(a,b,d){if(null!=a)if(l&&a.forEach===l)a.forEach(b,d);else if(a.length===+a.length){for(var e=0,f=a.length;f>e;e++)if(b.call(d,a[e],e,a)===c)return}else for(var g in a)if(x.has(a,g)&&b.call(d,a[g],g,a)===c)return};x.map=x.collect=function(a,b,c){var d=[];return null==a?d:m&&a.map===m?a.map(b,c):(y(a,function(a,e,f){d[d.length]=b.call(c,a,e,f)}),d)};var z="Reduce of empty array with no initial value";x.reduce=x.foldl=x.inject=function(a,b,c,d){var e=arguments.length>2;if(null==a&&(a=[]),n&&a.reduce===n)return d&&(b=x.bind(b,d)),e?a.reduce(b,c):a.reduce(b);if(y(a,function(a,f,g){e?c=b.call(d,c,a,f,g):(c=a,e=!0)}),!e)throw new TypeError(z);return c},x.reduceRight=x.foldr=function(a,b,c,d){var e=arguments.length>2;if(null==a&&(a=[]),o&&a.reduceRight===o)return d&&(b=x.bind(b,d)),e?a.reduceRight(b,c):a.reduceRight(b);var f=a.length;if(f!==+f){var g=x.keys(a);f=g.length}if(y(a,function(h,i,j){i=g?g[--f]:--f,e?c=b.call(d,c,a[i],i,j):(c=a[i],e=!0)}),!e)throw new TypeError(z);return c},x.find=x.detect=function(a,b,c){var d;return A(a,function(a,e,f){return b.call(c,a,e,f)?(d=a,!0):void 0}),d},x.filter=x.select=function(a,b,c){var d=[];return null==a?d:p&&a.filter===p?a.filter(b,c):(y(a,function(a,e,f){b.call(c,a,e,f)&&(d[d.length]=a)}),d)},x.reject=function(a,b,c){return x.filter(a,function(a,d,e){return!b.call(c,a,d,e)},c)},x.every=x.all=function(a,b,d){b||(b=x.identity);var e=!0;return null==a?e:q&&a.every===q?a.every(b,d):(y(a,function(a,f,g){return(e=e&&b.call(d,a,f,g))?void 0:c}),!!e)};var A=x.some=x.any=function(a,b,d){b||(b=x.identity);var e=!1;return null==a?e:r&&a.some===r?a.some(b,d):(y(a,function(a,f,g){return e||(e=b.call(d,a,f,g))?c:void 0}),!!e)};x.contains=x.include=function(a,b){return null==a?!1:s&&a.indexOf===s?-1!=a.indexOf(b):A(a,function(a){return a===b})},x.invoke=function(a,b){var c=h.call(arguments,2),d=x.isFunction(b);return x.map(a,function(a){return(d?b:a[b]).apply(a,c)})},x.pluck=function(a,b){return x.map(a,function(a){return a[b]})},x.where=function(a,b,c){return x.isEmpty(b)?c?null:[]:x[c?"find":"filter"](a,function(a){for(var c in b)if(b[c]!==a[c])return!1;return!0})},x.findWhere=function(a,b){return x.where(a,b,!0)},x.max=function(a,b,c){if(!b&&x.isArray(a)&&a[0]===+a[0]&&a.length<65535)return Math.max.apply(Math,a);if(!b&&x.isEmpty(a))return-(1/0);var d={computed:-(1/0),value:-(1/0)};return y(a,function(a,e,f){var g=b?b.call(c,a,e,f):a;g>=d.computed&&(d={value:a,computed:g})}),d.value},x.min=function(a,b,c){if(!b&&x.isArray(a)&&a[0]===+a[0]&&a.length<65535)return Math.min.apply(Math,a);if(!b&&x.isEmpty(a))return 1/0;var d={computed:1/0,value:1/0};return y(a,function(a,e,f){var g=b?b.call(c,a,e,f):a;g<d.computed&&(d={value:a,computed:g})}),d.value},x.shuffle=function(a){var b,c=0,d=[];return y(a,function(a){b=x.random(c++),d[c-1]=d[b],d[b]=a}),d};var B=function(a){return x.isFunction(a)?a:function(b){return b[a]}};x.sortBy=function(a,b,c){var d=B(b);return x.pluck(x.map(a,function(a,b,e){return{value:a,index:b,criteria:d.call(c,a,b,e)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;if(c!==d){if(c>d||void 0===c)return 1;if(d>c||void 0===d)return-1}return a.index<b.index?-1:1}),"value")};var C=function(a,b,c,d){var e={},f=B(b||x.identity);return y(a,function(b,g){var h=f.call(c,b,g,a);d(e,h,b)}),e};x.groupBy=function(a,b,c){return C(a,b,c,function(a,b,c){(x.has(a,b)?a[b]:a[b]=[]).push(c)})},x.countBy=function(a,b,c){return C(a,b,c,function(a,b){x.has(a,b)||(a[b]=0),a[b]++})},x.sortedIndex=function(a,b,c,d){c=null==c?x.identity:B(c);for(var e=c.call(d,b),f=0,g=a.length;g>f;){var h=f+g>>>1;c.call(d,a[h])<e?f=h+1:g=h}return f},x.toArray=function(a){return a?x.isArray(a)?h.call(a):a.length===+a.length?x.map(a,x.identity):x.values(a):[]},x.size=function(a){return null==a?0:a.length===+a.length?a.length:x.keys(a).length},x.first=x.head=x.take=function(a,b,c){return null==a?void 0:null==b||c?a[0]:h.call(a,0,b)},x.initial=function(a,b,c){return h.call(a,0,a.length-(null==b||c?1:b))},x.last=function(a,b,c){return null==a?void 0:null==b||c?a[a.length-1]:h.call(a,Math.max(a.length-b,0))},x.rest=x.tail=x.drop=function(a,b,c){return h.call(a,null==b||c?1:b)},x.compact=function(a){return x.filter(a,x.identity)};var D=function(a,b,c){return y(a,function(a){x.isArray(a)?b?g.apply(c,a):D(a,b,c):c.push(a)}),c};x.flatten=function(a,b){return D(a,b,[])},x.without=function(a){return x.difference(a,h.call(arguments,1))},x.uniq=x.unique=function(a,b,c,d){x.isFunction(b)&&(d=c,c=b,b=!1);var e=c?x.map(a,c,d):a,f=[],g=[];return y(e,function(c,d){(b?d&&g[g.length-1]===c:x.contains(g,c))||(g.push(c),f.push(a[d]))}),f},x.union=function(){return x.uniq(i.apply(d,arguments))},x.intersection=function(a){var b=h.call(arguments,1);return x.filter(x.uniq(a),function(a){return x.every(b,function(b){return x.indexOf(b,a)>=0})})},x.difference=function(a){var b=i.apply(d,h.call(arguments,1));return x.filter(a,function(a){return!x.contains(b,a)})},x.zip=function(){for(var a=h.call(arguments),b=x.max(x.pluck(a,"length")),c=new Array(b),d=0;b>d;d++)c[d]=x.pluck(a,""+d);return c},x.object=function(a,b){if(null==a)return{};for(var c={},d=0,e=a.length;e>d;d++)b?c[a[d]]=b[d]:c[a[d][0]]=a[d][1];return c},x.indexOf=function(a,b,c){if(null==a)return-1;var d=0,e=a.length;if(c){if("number"!=typeof c)return d=x.sortedIndex(a,b),a[d]===b?d:-1;d=0>c?Math.max(0,e+c):c}if(s&&a.indexOf===s)return a.indexOf(b,c);for(;e>d;d++)if(a[d]===b)return d;return-1},x.lastIndexOf=function(a,b,c){if(null==a)return-1;var d=null!=c;if(t&&a.lastIndexOf===t)return d?a.lastIndexOf(b,c):a.lastIndexOf(b);for(var e=d?c:a.length;e--;)if(a[e]===b)return e;return-1},x.range=function(a,b,c){arguments.length<=1&&(b=a||0,a=0),c=arguments[2]||1;for(var d=Math.max(Math.ceil((b-a)/c),0),e=0,f=new Array(d);d>e;)f[e++]=a,a+=c;return f},x.bind=function(a,b){if(a.bind===w&&w)return w.apply(a,h.call(arguments,1));var c=h.call(arguments,2);return function(){return a.apply(b,c.concat(h.call(arguments)))}},x.partial=function(a){var b=h.call(arguments,1);return function(){return a.apply(this,b.concat(h.call(arguments)))}},x.bindAll=function(a){var b=h.call(arguments,1);return 0===b.length&&(b=x.functions(a)),y(b,function(b){a[b]=x.bind(a[b],a)}),a},x.memoize=function(a,b){var c={};return b||(b=x.identity),function(){var d=b.apply(this,arguments);return x.has(c,d)?c[d]:c[d]=a.apply(this,arguments)}},x.delay=function(a,b){var c=h.call(arguments,2);return setTimeout(function(){return a.apply(null,c)},b)},x.defer=function(a){return x.delay.apply(x,[a,1].concat(h.call(arguments,1)))},x.throttle=function(a,b){var c,d,e,f,g=0,h=function(){g=new Date,e=null,f=a.apply(c,d)};return function(){var i=new Date,j=b-(i-g);return c=this,d=arguments,0>=j?(clearTimeout(e),e=null,g=i,f=a.apply(c,d)):e||(e=setTimeout(h,j)),f}},x.debounce=function(a,b,c){var d,e;return function(){var f=this,g=arguments,h=function(){d=null,c||(e=a.apply(f,g))},i=c&&!d;return clearTimeout(d),d=setTimeout(h,b),i&&(e=a.apply(f,g)),e}},x.once=function(a){var b,c=!1;return function(){return c?b:(c=!0,b=a.apply(this,arguments),a=null,b)}},x.wrap=function(a,b){return function(){var c=[a];return g.apply(c,arguments),b.apply(this,c)}},x.compose=function(){var a=arguments;return function(){for(var b=arguments,c=a.length-1;c>=0;c--)b=[a[c].apply(this,b)];return b[0]}},x.after=function(a,b){return 0>=a?b():function(){return--a<1?b.apply(this,arguments):void 0}},x.keys=v||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var b=[];for(var c in a)x.has(a,c)&&(b[b.length]=c);return b},x.values=function(a){var b=[];for(var c in a)x.has(a,c)&&b.push(a[c]);return b},x.pairs=function(a){var b=[];for(var c in a)x.has(a,c)&&b.push([c,a[c]]);return b},x.invert=function(a){var b={};for(var c in a)x.has(a,c)&&(b[a[c]]=c);return b},x.functions=x.methods=function(a){var b=[];for(var c in a)x.isFunction(a[c])&&b.push(c);return b.sort()},x.extend=function(a){return y(h.call(arguments,1),function(b){if(b)for(var c in b)a[c]=b[c]}),a},x.pick=function(a){var b={},c=i.apply(d,h.call(arguments,1));return y(c,function(c){c in a&&(b[c]=a[c])}),b},x.omit=function(a){var b={},c=i.apply(d,h.call(arguments,1));for(var e in a)x.contains(c,e)||(b[e]=a[e]);return b},x.defaults=function(a){return y(h.call(arguments,1),function(b){if(b)for(var c in b)null==a[c]&&(a[c]=b[c])}),a},x.clone=function(a){return x.isObject(a)?x.isArray(a)?a.slice():x.extend({},a):a},x.tap=function(a,b){return b(a),a};var E=function(a,b,c,d){if(a===b)return 0!==a||1/a==1/b;if(null==a||null==b)return a===b;a instanceof x&&(a=a._wrapped),b instanceof x&&(b=b._wrapped);var e=j.call(a);if(e!=j.call(b))return!1;switch(e){case"[object String]":return a==String(b);case"[object Number]":return a!=+a?b!=+b:0==a?1/a==1/b:a==+b;case"[object Date]":case"[object Boolean]":return+a==+b;case"[object RegExp]":return a.source==b.source&&a.global==b.global&&a.multiline==b.multiline&&a.ignoreCase==b.ignoreCase}if("object"!=typeof a||"object"!=typeof b)return!1;for(var f=c.length;f--;)if(c[f]==a)return d[f]==b;c.push(a),d.push(b);var g=0,h=!0;if("[object Array]"==e){if(g=a.length,h=g==b.length)for(;g--&&(h=E(a[g],b[g],c,d)););}else{var i=a.constructor,k=b.constructor;if(i!==k&&!(x.isFunction(i)&&i instanceof i&&x.isFunction(k)&&k instanceof k))return!1;for(var l in a)if(x.has(a,l)&&(g++,!(h=x.has(b,l)&&E(a[l],b[l],c,d))))break;if(h){for(l in b)if(x.has(b,l)&&!g--)break;h=!g}}return c.pop(),d.pop(),h};x.isEqual=function(a,b){return E(a,b,[],[])},x.isEmpty=function(a){if(null==a)return!0;if(x.isArray(a)||x.isString(a))return 0===a.length;for(var b in a)if(x.has(a,b))return!1;return!0},x.isElement=function(a){return!(!a||1!==a.nodeType)},x.isArray=u||function(a){return"[object Array]"==j.call(a)},x.isObject=function(a){return a===Object(a)},y(["Arguments","Function","String","Number","Date","RegExp"],function(a){x["is"+a]=function(b){return j.call(b)=="[object "+a+"]"}}),x.isArguments(arguments)||(x.isArguments=function(a){return!(!a||!x.has(a,"callee"))}),"function"!=typeof/./&&(x.isFunction=function(a){return"function"==typeof a}),x.isFinite=function(a){return isFinite(a)&&!isNaN(parseFloat(a))},x.isNaN=function(a){return x.isNumber(a)&&a!=+a},x.isBoolean=function(a){return a===!0||a===!1||"[object Boolean]"==j.call(a)},x.isNull=function(a){return null===a},x.isUndefined=function(a){return void 0===a},x.has=function(a,b){return k.call(a,b)},x.noConflict=function(){return a._=b,this},x.identity=function(a){return a},x.times=function(a,b,c){for(var d=Array(a),e=0;a>e;e++)d[e]=b.call(c,e);return d},x.random=function(a,b){return null==b&&(b=a,a=0),a+Math.floor(Math.random()*(b-a+1))};var F={escape:{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;"}};F.unescape=x.invert(F.escape);var G={escape:new RegExp("["+x.keys(F.escape).join("")+"]","g"),unescape:new RegExp("("+x.keys(F.unescape).join("|")+")","g")};x.each(["escape","unescape"],function(a){x[a]=function(b){return null==b?"":(""+b).replace(G[a],function(b){return F[a][b]})}}),x.result=function(a,b){if(null==a)return null;var c=a[b];return x.isFunction(c)?c.call(a):c},x.mixin=function(a){y(x.functions(a),function(b){var c=x[b]=a[b];x.prototype[b]=function(){var a=[this._wrapped];return g.apply(a,arguments),L.call(this,c.apply(x,a))}})};var H=0;x.uniqueId=function(a){var b=++H+"";return a?a+b:b},x.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var I=/(.)^/,J={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},K=/\\|'|\r|\n|\t|\u2028|\u2029/g;x.template=function(a,b,c){var d;c=x.defaults({},c,x.templateSettings);var e=new RegExp([(c.escape||I).source,(c.interpolate||I).source,(c.evaluate||I).source].join("|")+"|$","g"),f=0,g="__p+='";a.replace(e,function(b,c,d,e,h){return g+=a.slice(f,h).replace(K,function(a){return"\\"+J[a]}),c&&(g+="'+\n((__t=("+c+"))==null?'':_.escape(__t))+\n'"),d&&(g+="'+\n((__t=("+d+"))==null?'':__t)+\n'"),e&&(g+="';\n"+e+"\n__p+='"),f=h+b.length,b}),g+="';\n",c.variable||(g="with(obj||{}){\n"+g+"}\n"),g="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+g+"return __p;\n";try{d=new Function(c.variable||"obj","_",g)}catch(h){throw h.source=g,h}if(b)return d(b,x);var i=function(a){return d.call(this,a,x)};return i.source="function("+(c.variable||"obj")+"){\n"+g+"}",i},x.chain=function(a){return x(a).chain()};var L=function(a){return this._chain?x(a).chain():a};x.mixin(x),y(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var b=d[a];x.prototype[a]=function(){var c=this._wrapped;return b.apply(c,arguments),"shift"!=a&&"splice"!=a||0!==c.length||delete c[0],L.call(this,c)}}),y(["concat","join","slice"],function(a){var b=d[a];x.prototype[a]=function(){return L.call(this,b.apply(this._wrapped,arguments))}}),x.extend(x.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}.call(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c="function"==typeof require?require:null;"undefined"!=typeof XMLHttpRequest?b.XMLHttpRequest=XMLHttpRequest:"function"==typeof require&&"undefined"==typeof require.ensure&&(b.XMLHttpRequest=c("xmlhttprequest").XMLHttpRequest),"undefined"!=typeof exports&&exports._?(b._=exports._.noConflict(),exports.Parse=b):b._=_.noConflict(),"undefined"!=typeof $&&(b.$=$);var d=function(){},e=function(a,c,e){var f;return f=c&&c.hasOwnProperty("constructor")?c.constructor:function(){a.apply(this,arguments)},b._.extend(f,a),d.prototype=a.prototype,f.prototype=new d,c&&b._.extend(f.prototype,c),e&&b._.extend(f,e),f.prototype.constructor=f,f.__super__=a.prototype,f};b.serverURL="https://api.parse.com","undefined"!=typeof process&&process.versions&&process.versions.node&&(b._isNode=!0),b.initialize=function(a,c,d){if(d)throw"Parse.initialize() was passed a Master Key, which is only allowed from within Node.js.";b._initialize(a,c)},b._initialize=function(a,c,d){b.applicationId=a,b.javaScriptKey=c,b.masterKey=d,b._useMasterKey=!1},b._isNode&&(b.initialize=b._initialize,b.Cloud=b.Cloud||{},b.Cloud.useMasterKey=function(){b._useMasterKey=!0}),b._getParsePath=function(a){if(!b.applicationId)throw"You need to call Parse.initialize before using Parse.";if(a||(a=""),!b._.isString(a))throw"Tried to get a Storage path that wasn't a String.";return"/"===a[0]&&(a=a.substring(1)),"Parse/"+b.applicationId+"/"+a},b._installationId=null,b._getInstallationId=function(){if(b._installationId)return b.Promise.as(b._installationId);var a=b._getParsePath("installationId");return b.Storage.getItemAsync(a).then(function(c){if(b._installationId=c,!b._installationId||""===b._installationId){var d=function(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)};return b._installationId=d()+d()+"-"+d()+"-"+d()+"-"+d()+"-"+d()+d()+d(),b.Storage.setItemAsync(a,b._installationId)}return b.Promise.as(b._installationId)})},b._parseDate=function(a){var b=new RegExp("^([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2})T([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})(.([0-9]+))?Z$"),c=b.exec(a);if(!c)return null;var d=c[1]||0,e=(c[2]||1)-1,f=c[3]||0,g=c[4]||0,h=c[5]||0,i=c[6]||0,j=c[8]||0;return new Date(Date.UTC(d,e,f,g,h,i,j))},b._ajaxIE8=function(a,c,d){var e=new b.Promise,f=new XDomainRequest;return f.onload=function(){var a;try{a=JSON.parse(f.responseText)}catch(b){e.reject(b)}a&&e.resolve(a)},f.onerror=f.ontimeout=function(){var a={responseText:JSON.stringify({code:b.Error.X_DOMAIN_REQUEST,error:"IE's XDomainRequest does not supply error info."})};e.reject(a)},f.onprogress=function(){},f.open(a,c),f.send(d),e},b._useXDomainRequest=function(){return"undefined"!=typeof XDomainRequest?"withCredentials"in new XMLHttpRequest?!1:!0:!1},b._ajax=function(a,c,d,e,f){var g={success:e,error:f};if(b._useXDomainRequest())return b._ajaxIE8(a,c,d)._thenRunCallbacks(g);var h=new b.Promise,i=0,j=function(){var e=!1,f=new b.XMLHttpRequest;f.onreadystatechange=function(){if(4===f.readyState){if(e)return;if(e=!0,f.status>=200&&f.status<300){var a;try{a=JSON.parse(f.responseText)}catch(b){h.reject(b)}a&&h.resolve(a,f.status,f)}else if(f.status>=500)if(++i<5){var c=Math.round(125*Math.random()*Math.pow(2,i));setTimeout(j,c)}else h.reject(f);else h.reject(f)}},f.open(a,c,!0),f.setRequestHeader("Content-Type","text/plain"),b._isNode&&f.setRequestHeader("User-Agent","Parse/"+b.VERSION+" (NodeJS "+process.versions.node+")"),f.send(d)};return j(),h._thenRunCallbacks(g)},b._extend=function(a,b){var c=e(this,a,b);return c.extend=this.extend,c},b._request=function(a){var c=a.route,d=a.className,e=a.objectId,f=a.method,g=a.useMasterKey,h=a.sessionToken,i=a.data;if(!b.applicationId)throw"You must specify your applicationId using Parse.initialize.";if(!b.javaScriptKey&&!b.masterKey)throw"You must specify a key using Parse.initialize.";if("batch"!==c&&"classes"!==c&&"events"!==c&&"files"!==c&&"functions"!==c&&"login"!==c&&"logout"!==c&&"push"!==c&&"requestPasswordReset"!==c&&"rest_verify_analytics"!==c&&"users"!==c&&"jobs"!==c&&"config"!==c&&"sessions"!==c&&"upgradeToRevocableSession"!==c)throw"Bad route: '"+c+"'.";var j=b.serverURL;if("/"!==j.charAt(j.length-1)&&(j+="/"),j+="1/"+c,d&&(j+="/"+d),e&&(j+="/"+e),i=b._.clone(i||{}),"POST"!==f&&(i._method=f,f="POST"),b._.isUndefined(g)&&(g=b._useMasterKey),i._ApplicationId=b.applicationId,g){if(!b.masterKey)throw new Error("Cannot use the Master Key, it has not been provided.");i._MasterKey=b.masterKey}else i._JavaScriptKey=b.javaScriptKey;return i._ClientVersion=b.VERSION,b._getInstallationId().then(function(a){return i._InstallationId=a,h?b.Promise.as({_sessionToken:h}):b.User._canUseCurrentUser()?b.User._currentAsync():b.Promise.as(null)}).then(function(a){a&&a._sessionToken&&(i._SessionToken=a._sessionToken),b.User._isRevocableSessionEnabled&&(i._RevocableSession="1");var c=JSON.stringify(i);return b._ajax(f,j,c)}).then(null,function(a){var c;if(a&&a.responseText)try{var d=JSON.parse(a.responseText);c=new b.Error(d.code,d.error)}catch(e){c=new b.Error(b.Error.INVALID_JSON,"Received an error with invalid JSON from Parse: "+a.responseText)}else c=new b.Error(b.Error.CONNECTION_FAILED,"XMLHttpRequest failed: "+JSON.stringify(a));return b.Promise.error(c)})},b._getValue=function(a,c){return a&&a[c]?b._.isFunction(a[c])?a[c]():a[c]:null},b._encode=function(a,c,d){var e=b._;if(a instanceof b.Object){if(d)throw"Parse.Objects not allowed here";if(!c||e.include(c,a)||!a._hasData)return a._toPointer();if(!a.dirty())return c=c.concat(a),b._encode(a._toFullJSON(c),c,d);throw"Tried to save an object with a pointer to a new, unsaved object."}if(a instanceof b.ACL)return a.toJSON();if(e.isDate(a)){if(isNaN(a))throw new Error("Cannot encode invalid Date");return{__type:"Date",iso:a.toJSON()}}if(a instanceof b.GeoPoint)return a.toJSON();if(e.isArray(a))return e.map(a,function(a){return b._encode(a,c,d)});if(e.isRegExp(a))return a.source;if(a instanceof b.Relation)return a.toJSON();if(a instanceof b.Op)return a.toJSON();if(a instanceof b.File){if(!a.url())throw"Tried to save an object containing an unsaved file.";return{__type:"File",name:a.name(),url:a.url()}}if(e.isObject(a)){var f={};return b._objectEach(a,function(a,e){f[e]=b._encode(a,c,d)}),f}return a},b._decode=function(a,c){var d=b._;if(!d.isObject(c))return c;if(d.isArray(c))return b._arrayEach(c,function(a,d){c[d]=b._decode(d,a)}),c;if(c instanceof b.Object)return c;if(c instanceof b.File)return c;if(c instanceof b.Op)return c;if(c.__op)return b.Op._decode(c);if("Pointer"===c.__type&&c.className){var e=b.Object._create(c.className);return e._finishFetch({objectId:c.objectId},!1),e}if("Object"===c.__type&&c.className){var f=c.className;delete c.__type,delete c.className;var g=b.Object._create(f);return g._finishFetch(c,!0),g}if("Date"===c.__type)return b._parseDate(c.iso);if("GeoPoint"===c.__type)return new b.GeoPoint({latitude:c.latitude,longitude:c.longitude});if("ACL"===a)return c instanceof b.ACL?c:new b.ACL(c);if("Relation"===c.__type){var h=new b.Relation(null,a);return h.targetClassName=c.className,h}if("File"===c.__type){var i=new b.File(c.name);return i._url=c.url,i}return b._objectEach(c,function(a,d){c[d]=b._decode(d,a)}),c},b._arrayEach=b._.each,b._traverse=function(a,c,d){if(a instanceof b.Object){if(d=d||[],b._.indexOf(d,a)>=0)return;return d.push(a),b._traverse(a.attributes,c,d),c(a)}return a instanceof b.Relation||a instanceof b.File?c(a):b._.isArray(a)?(b._.each(a,function(e,f){var g=b._traverse(e,c,d);g&&(a[f]=g)}),c(a)):b._.isObject(a)?(b._each(a,function(e,f){var g=b._traverse(e,c,d);g&&(a[f]=g)}),c(a)):c(a)},b._objectEach=b._each=function(a,c){var d=b._;d.isObject(a)?d.each(d.keys(a),function(b){c(a[b],b)}):d.each(a,c)},b._isNullOrUndefined=function(a){return b._.isNull(a)||b._.isUndefined(a)}}(this),function(root){root.Parse=root.Parse||{};var Parse=root.Parse,Storage={async:!1},hasLocalStorage="undefined"!=typeof localStorage;if(hasLocalStorage)try{localStorage.setItem("supported",!0),localStorage.removeItem("supported")}catch(e){hasLocalStorage=!1}if(hasLocalStorage)Storage.getItem=function(a){return localStorage.getItem(a)},Storage.setItem=function(a,b){return localStorage.setItem(a,b)},Storage.removeItem=function(a){return localStorage.removeItem(a)},Storage.clear=function(){return localStorage.clear()};else if("function"==typeof require){var AsyncStorage;try{AsyncStorage=eval("require('AsyncStorage')"),Storage.async=!0,Storage.getItemAsync=function(a){var b=new Parse.Promise;return AsyncStorage.getItem(a,function(a,c){a?b.reject(a):b.resolve(c)}),b},Storage.setItemAsync=function(a,b){var c=new Parse.Promise;return AsyncStorage.setItem(a,b,function(a){a?c.reject(a):c.resolve(b)}),c},Storage.removeItemAsync=function(a){var b=new Parse.Promise;return AsyncStorage.removeItem(a,function(a){a?b.reject(a):b.resolve()}),b},Storage.clear=function(){AsyncStorage.clear()}}catch(e){}}if(!Storage.async&&!Storage.getItem){var memMap=Storage.inMemoryMap={};Storage.getItem=function(a){return memMap.hasOwnProperty(a)?memMap[a]:null},Storage.setItem=function(a,b){memMap[a]=String(b)},Storage.removeItem=function(a){delete memMap[a]},Storage.clear=function(){for(var a in memMap)memMap.hasOwnProperty(a)&&delete memMap[a]}}Storage.async||(Storage.getItemAsync=function(a){return Parse.Promise.as(Storage.getItem(a))},Storage.setItemAsync=function(a,b){return Storage.setItem(a,b),Parse.Promise.as(b)},Storage.removeItemAsync=function(a){return Parse.Promise.as(Storage.removeItem(a))}),Parse.Storage=Storage}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._;b.Analytics=b.Analytics||{},c.extend(b.Analytics,{track:function(a,d,e){if(a=a||"",a=a.replace(/^\s*/,""),a=a.replace(/\s*$/,""),0===a.length)throw"A name for the custom event must be provided";return c.each(d,function(a,b){if(!c.isString(b)||!c.isString(a))throw'track() dimensions expects keys and values of type "string".'}),e=e||{},b._request({route:"events",className:a,method:"POST",data:{dimensions:d}})._thenRunCallbacks(e)}})}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._;b.Config=function(){this.attributes={},this._escapedAttributes={}},b.Config.current=function(){if(b.Config._currentConfig)return b.Config._currentConfig;var a=new b.Config;if(b.Storage.async)return a;var c=b.Storage.getItem(b._getParsePath(b.Config._CURRENT_CONFIG_KEY));return c&&(a._finishFetch(JSON.parse(c)),b.Config._currentConfig=a),a},b.Config.get=function(a){a=a||{};var c=b._request({route:"config",method:"GET"});return c.then(function(a){if(!a||!a.params){var c=new b.Error(b.Error.INVALID_JSON,"Config JSON response invalid.");return b.Promise.error(c)}var d=new b.Config;return d._finishFetch(a),b.Config._currentConfig=d,d})._thenRunCallbacks(a)},b.Config.prototype={escape:function(a){var d=this._escapedAttributes[a];if(d)return d;var e,f=this.attributes[a];return e=b._isNullOrUndefined(f)?"":c.escape(f.toString()),this._escapedAttributes[a]=e,e},get:function(a){return this.attributes[a]},_finishFetch:function(a){this.attributes=b._decode(null,c.clone(a.params)),b.Storage.async||b.Storage.setItem(b._getParsePath(b.Config._CURRENT_CONFIG_KEY),JSON.stringify(a))}},b.Config._currentConfig=null,b.Config._CURRENT_CONFIG_KEY="currentConfig"}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._;b.Error=function(a,b){this.code=a,this.message=b},c.extend(b.Error,{OTHER_CAUSE:-1,INTERNAL_SERVER_ERROR:1,CONNECTION_FAILED:100,OBJECT_NOT_FOUND:101,INVALID_QUERY:102,INVALID_CLASS_NAME:103,MISSING_OBJECT_ID:104,INVALID_KEY_NAME:105,INVALID_POINTER:106,INVALID_JSON:107,COMMAND_UNAVAILABLE:108,NOT_INITIALIZED:109,INCORRECT_TYPE:111,INVALID_CHANNEL_NAME:112,PUSH_MISCONFIGURED:115,OBJECT_TOO_LARGE:116,OPERATION_FORBIDDEN:119,CACHE_MISS:120,INVALID_NESTED_KEY:121,INVALID_FILE_NAME:122,INVALID_ACL:123,TIMEOUT:124,INVALID_EMAIL_ADDRESS:125,MISSING_CONTENT_TYPE:126,MISSING_CONTENT_LENGTH:127,INVALID_CONTENT_LENGTH:128,FILE_TOO_LARGE:129,FILE_SAVE_ERROR:130,DUPLICATE_VALUE:137,INVALID_ROLE_NAME:139,EXCEEDED_QUOTA:140,SCRIPT_FAILED:141,VALIDATION_ERROR:142,INVALID_IMAGE_DATA:150,UNSAVED_FILE_ERROR:151,INVALID_PUSH_TIME_ERROR:152,FILE_DELETE_ERROR:153,REQUEST_LIMIT_EXCEEDED:155,INVALID_EVENT_NAME:160,USERNAME_MISSING:200,PASSWORD_MISSING:201,USERNAME_TAKEN:202,EMAIL_TAKEN:203,EMAIL_MISSING:204,EMAIL_NOT_FOUND:205,SESSION_MISSING:206,MUST_CREATE_USER_THROUGH_SIGNUP:207,ACCOUNT_ALREADY_LINKED:208,INVALID_SESSION_TOKEN:209,LINKED_ID_MISSING:250,INVALID_LINKED_SESSION:251,UNSUPPORTED_SERVICE:252,AGGREGATE_ERROR:600,FILE_READ_ERROR:601,X_DOMAIN_REQUEST:602})}(this),function(){var a=this,b=a.Parse||(a.Parse={}),c=/\s+/,d=Array.prototype.slice;b.Events={on:function(a,b,d){var e,f,g,h,i;if(!b)return this;for(a=a.split(c),e=this._callbacks||(this._callbacks={}),f=a.shift();f;)i=e[f],g=i?i.tail:{},g.next=h={},g.context=d,g.callback=b,e[f]={tail:h,next:i?i.next:g},f=a.shift();return this},off:function(a,b,d){var e,f,g,h,i,j;if(f=this._callbacks){if(!(a||b||d))return delete this._callbacks,this;for(a=a?a.split(c):Object.keys(f),e=a.shift();e;)if(g=f[e],delete f[e],g&&(b||d)){for(h=g.tail,g=g.next;g!==h;)i=g.callback,j=g.context,(b&&i!==b||d&&j!==d)&&this.on(e,i,j),g=g.next;e=a.shift()}else e=a.shift();return this}},trigger:function(a){var b,e,f,g,h,i,j;if(!(f=this._callbacks))return this;for(i=f.all,a=a.split(c),j=d.call(arguments,1),b=a.shift();b;){if(e=f[b])for(g=e.tail;(e=e.next)!==g;)e.callback.apply(e.context||this,j);if(e=i)for(g=e.tail,h=[b].concat(j);(e=e.next)!==g;)e.callback.apply(e.context||this,h);b=a.shift()}return this}},b.Events.bind=b.Events.on,b.Events.unbind=b.Events.off}.call(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._;b.GeoPoint=function(a,d){c.isArray(a)?(b.GeoPoint._validate(a[0],a[1]),this.latitude=a[0],this.longitude=a[1]):c.isObject(a)?(b.GeoPoint._validate(a.latitude,a.longitude),this.latitude=a.latitude,this.longitude=a.longitude):c.isNumber(a)&&c.isNumber(d)?(b.GeoPoint._validate(a,d),this.latitude=a,this.longitude=d):(this.latitude=0,this.longitude=0);var e=this;this.__defineGetter__&&this.__defineSetter__&&(this._latitude=this.latitude,this._longitude=this.longitude,this.__defineGetter__("latitude",function(){return e._latitude}),this.__defineGetter__("longitude",function(){return e._longitude}),this.__defineSetter__("latitude",function(a){b.GeoPoint._validate(a,e.longitude),e._latitude=a}),this.__defineSetter__("longitude",function(a){b.GeoPoint._validate(e.latitude,a),e._longitude=a}))},b.GeoPoint._validate=function(a,b){if(-90>a)throw"Parse.GeoPoint latitude "+a+" < -90.0.";if(a>90)throw"Parse.GeoPoint latitude "+a+" > 90.0.";if(-180>b)throw"Parse.GeoPoint longitude "+b+" < -180.0.";if(b>180)throw"Parse.GeoPoint longitude "+b+" > 180.0."},b.GeoPoint.current=function(a){var c=new b.Promise;return navigator.geolocation.getCurrentPosition(function(a){c.resolve(new b.GeoPoint({latitude:a.coords.latitude,longitude:a.coords.longitude}))},function(a){c.reject(a)}),c._thenRunCallbacks(a)},b.GeoPoint.prototype={toJSON:function(){return b.GeoPoint._validate(this.latitude,this.longitude),{__type:"GeoPoint",latitude:this.latitude,longitude:this.longitude}},radiansTo:function(a){var b=Math.PI/180,c=this.latitude*b,d=this.longitude*b,e=a.latitude*b,f=a.longitude*b,g=c-e,h=d-f,i=Math.sin(g/2),j=Math.sin(h/2),k=i*i+Math.cos(c)*Math.cos(e)*j*j;return k=Math.min(1,k),2*Math.asin(Math.sqrt(k))},kilometersTo:function(a){return 6371*this.radiansTo(a)},milesTo:function(a){return 3958.8*this.radiansTo(a)}}}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._,d="*";b.ACL=function(a){var d=this;if(d.permissionsById={},c.isObject(a))if(a instanceof b.User)d.setReadAccess(a,!0),d.setWriteAccess(a,!0);else{if(c.isFunction(a))throw"Parse.ACL() called with a function. Did you forget ()?";b._objectEach(a,function(a,e){if(!c.isString(e))throw"Tried to create an ACL with an invalid userId.";d.permissionsById[e]={},b._objectEach(a,function(a,b){if("read"!==b&&"write"!==b)throw"Tried to create an ACL with an invalid permission type.";if(!c.isBoolean(a))throw"Tried to create an ACL with an invalid permission value.";d.permissionsById[e][b]=a})})}},b.ACL.prototype.toJSON=function(){return c.clone(this.permissionsById)},b.ACL.prototype._setAccess=function(a,d,e){if(d instanceof b.User?d=d.id:d instanceof b.Role&&(d="role:"+d.getName()),!c.isString(d))throw"userId must be a string.";if(!c.isBoolean(e))throw"allowed must be either true or false.";var f=this.permissionsById[d];if(!f){if(!e)return;f={},this.permissionsById[d]=f}e?this.permissionsById[d][a]=!0:(delete f[a],c.isEmpty(f)&&delete f[d])},b.ACL.prototype._getAccess=function(a,c){c instanceof b.User?c=c.id:c instanceof b.Role&&(c="role:"+c.getName());var d=this.permissionsById[c];return d&&d[a]?!0:!1},b.ACL.prototype.setReadAccess=function(a,b){this._setAccess("read",a,b)},b.ACL.prototype.getReadAccess=function(a){return this._getAccess("read",a)},b.ACL.prototype.setWriteAccess=function(a,b){this._setAccess("write",a,b)},b.ACL.prototype.getWriteAccess=function(a){return this._getAccess("write",a)},b.ACL.prototype.setPublicReadAccess=function(a){this.setReadAccess(d,a)},b.ACL.prototype.getPublicReadAccess=function(){return this.getReadAccess(d)},b.ACL.prototype.setPublicWriteAccess=function(a){this.setWriteAccess(d,a)},b.ACL.prototype.getPublicWriteAccess=function(){return this.getWriteAccess(d)},b.ACL.prototype.getRoleReadAccess=function(a){if(a instanceof b.Role&&(a=a.getName()),c.isString(a))return this.getReadAccess("role:"+a);throw"role must be a Parse.Role or a String"},b.ACL.prototype.getRoleWriteAccess=function(a){if(a instanceof b.Role&&(a=a.getName()),c.isString(a))return this.getWriteAccess("role:"+a);throw"role must be a Parse.Role or a String"},b.ACL.prototype.setRoleReadAccess=function(a,d){if(a instanceof b.Role&&(a=a.getName()),c.isString(a))return void this.setReadAccess("role:"+a,d);throw"role must be a Parse.Role or a String"},b.ACL.prototype.setRoleWriteAccess=function(a,d){if(a instanceof b.Role&&(a=a.getName()),c.isString(a))return void this.setWriteAccess("role:"+a,d);throw"role must be a Parse.Role or a String"}}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._;b.Op=function(){this._initialize.apply(this,arguments)},b.Op.prototype={_initialize:function(){}},c.extend(b.Op,{_extend:b._extend,_opDecoderMap:{},_registerDecoder:function(a,c){b.Op._opDecoderMap[a]=c},_decode:function(a){var c=b.Op._opDecoderMap[a.__op];return c?c(a):void 0;
  12. }}),b.Op._registerDecoder("Batch",function(a){var c=null;return b._arrayEach(a.ops,function(a){a=b.Op._decode(a),c=a._mergeWithPrevious(c)}),c}),b.Op.Set=b.Op._extend({_initialize:function(a){this._value=a},value:function(){return this._value},toJSON:function(){return b._encode(this.value())},_mergeWithPrevious:function(a){return this},_estimate:function(a){return this.value()}}),b.Op._UNSET={},b.Op.Unset=b.Op._extend({toJSON:function(){return{__op:"Delete"}},_mergeWithPrevious:function(a){return this},_estimate:function(a){return b.Op._UNSET}}),b.Op._registerDecoder("Delete",function(a){return new b.Op.Unset}),b.Op.Increment=b.Op._extend({_initialize:function(a){this._amount=a},amount:function(){return this._amount},toJSON:function(){return{__op:"Increment",amount:this._amount}},_mergeWithPrevious:function(a){if(a){if(a instanceof b.Op.Unset)return new b.Op.Set(this.amount());if(a instanceof b.Op.Set)return new b.Op.Set(a.value()+this.amount());if(a instanceof b.Op.Increment)return new b.Op.Increment(this.amount()+a.amount());throw"Op is invalid after previous op."}return this},_estimate:function(a){return a?a+this.amount():this.amount()}}),b.Op._registerDecoder("Increment",function(a){return new b.Op.Increment(a.amount)}),b.Op.Add=b.Op._extend({_initialize:function(a){this._objects=a},objects:function(){return this._objects},toJSON:function(){return{__op:"Add",objects:b._encode(this.objects())}},_mergeWithPrevious:function(a){if(a){if(a instanceof b.Op.Unset)return new b.Op.Set(this.objects());if(a instanceof b.Op.Set)return new b.Op.Set(this._estimate(a.value()));if(a instanceof b.Op.Add)return new b.Op.Add(a.objects().concat(this.objects()));throw"Op is invalid after previous op."}return this},_estimate:function(a){return a?a.concat(this.objects()):c.clone(this.objects())}}),b.Op._registerDecoder("Add",function(a){return new b.Op.Add(b._decode(void 0,a.objects))}),b.Op.AddUnique=b.Op._extend({_initialize:function(a){this._objects=c.uniq(a)},objects:function(){return this._objects},toJSON:function(){return{__op:"AddUnique",objects:b._encode(this.objects())}},_mergeWithPrevious:function(a){if(a){if(a instanceof b.Op.Unset)return new b.Op.Set(this.objects());if(a instanceof b.Op.Set)return new b.Op.Set(this._estimate(a.value()));if(a instanceof b.Op.AddUnique)return new b.Op.AddUnique(this._estimate(a.objects()));throw"Op is invalid after previous op."}return this},_estimate:function(a){if(a){var d=c.clone(a);return b._arrayEach(this.objects(),function(a){if(a instanceof b.Object&&a.id){var e=c.find(d,function(c){return c instanceof b.Object&&c.id===a.id});if(e){var f=c.indexOf(d,e);d[f]=a}else d.push(a)}else c.contains(d,a)||d.push(a)}),d}return c.clone(this.objects())}}),b.Op._registerDecoder("AddUnique",function(a){return new b.Op.AddUnique(b._decode(void 0,a.objects))}),b.Op.Remove=b.Op._extend({_initialize:function(a){this._objects=c.uniq(a)},objects:function(){return this._objects},toJSON:function(){return{__op:"Remove",objects:b._encode(this.objects())}},_mergeWithPrevious:function(a){if(a){if(a instanceof b.Op.Unset)return a;if(a instanceof b.Op.Set)return new b.Op.Set(this._estimate(a.value()));if(a instanceof b.Op.Remove)return new b.Op.Remove(c.union(a.objects(),this.objects()));throw"Op is invalid after previous op."}return this},_estimate:function(a){if(a){var d=c.difference(a,this.objects());return b._arrayEach(this.objects(),function(a){a instanceof b.Object&&a.id&&(d=c.reject(d,function(c){return c instanceof b.Object&&c.id===a.id}))}),d}return[]}}),b.Op._registerDecoder("Remove",function(a){return new b.Op.Remove(b._decode(void 0,a.objects))}),b.Op.Relation=b.Op._extend({_initialize:function(a,d){this._targetClassName=null;var e=this,f=function(a){if(a instanceof b.Object){if(!a.id)throw"You can't add an unsaved Parse.Object to a relation.";if(e._targetClassName||(e._targetClassName=a.className),e._targetClassName!==a.className)throw"Tried to create a Parse.Relation with 2 different types: "+e._targetClassName+" and "+a.className+".";return a.id}return a};this.relationsToAdd=c.uniq(c.map(a,f)),this.relationsToRemove=c.uniq(c.map(d,f))},added:function(){var a=this;return c.map(this.relationsToAdd,function(c){var d=b.Object._create(a._targetClassName);return d.id=c,d})},removed:function(){var a=this;return c.map(this.relationsToRemove,function(c){var d=b.Object._create(a._targetClassName);return d.id=c,d})},toJSON:function(){var a=null,b=null,d=this,e=function(a){return{__type:"Pointer",className:d._targetClassName,objectId:a}},f=null;return this.relationsToAdd.length>0&&(f=c.map(this.relationsToAdd,e),a={__op:"AddRelation",objects:f}),this.relationsToRemove.length>0&&(f=c.map(this.relationsToRemove,e),b={__op:"RemoveRelation",objects:f}),a&&b?{__op:"Batch",ops:[a,b]}:a||b||{}},_mergeWithPrevious:function(a){if(a){if(a instanceof b.Op.Unset)throw"You can't modify a relation after deleting it.";if(a instanceof b.Op.Relation){if(a._targetClassName&&a._targetClassName!==this._targetClassName)throw"Related object must be of class "+a._targetClassName+", but "+this._targetClassName+" was passed in.";var d=c.union(c.difference(a.relationsToAdd,this.relationsToRemove),this.relationsToAdd),e=c.union(c.difference(a.relationsToRemove,this.relationsToAdd),this.relationsToRemove),f=new b.Op.Relation(d,e);return f._targetClassName=this._targetClassName,f}throw"Op is invalid after previous op."}return this},_estimate:function(a,c,d){if(a){if(a instanceof b.Relation){if(this._targetClassName)if(a.targetClassName){if(a.targetClassName!==this._targetClassName)throw"Related object must be a "+a.targetClassName+", but a "+this._targetClassName+" was passed in."}else a.targetClassName=this._targetClassName;return a}throw"Op is invalid after previous op."}var e=new b.Relation(c,d);e.targetClassName=this._targetClassName}}),b.Op._registerDecoder("AddRelation",function(a){return new b.Op.Relation(b._decode(void 0,a.objects),[])}),b.Op._registerDecoder("RemoveRelation",function(a){return new b.Op.Relation([],b._decode(void 0,a.objects))})}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._;b.Relation=function(a,b){this.parent=a,this.key=b,this.targetClassName=null},b.Relation.prototype={_ensureParentAndKey:function(a,b){if(this.parent=this.parent||a,this.key=this.key||b,this.parent!==a)throw"Internal Error. Relation retrieved from two different Objects.";if(this.key!==b)throw"Internal Error. Relation retrieved from two different keys."},add:function(a){c.isArray(a)||(a=[a]);var d=new b.Op.Relation(a,[]);this.parent.set(this.key,d),this.targetClassName=d._targetClassName},remove:function(a){c.isArray(a)||(a=[a]);var d=new b.Op.Relation([],a);this.parent.set(this.key,d),this.targetClassName=d._targetClassName},toJSON:function(){return{__type:"Relation",className:this.targetClassName}},query:function(){var a,c;return this.targetClassName?(a=b.Object._getSubclass(this.targetClassName),c=new b.Query(a)):(a=b.Object._getSubclass(this.parent.className),c=new b.Query(a),c._extraOptions.redirectClassNameForKey=this.key),c._addCondition("$relatedTo","object",this.parent._toPointer()),c._addCondition("$relatedTo","key",this.key),c}}}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._;b.Promise=function(){this._resolved=!1,this._rejected=!1,this._resolvedCallbacks=[],this._rejectedCallbacks=[]},c.extend(b.Promise,{_isPromisesAPlusCompliant:!1,is:function(a){return a&&a.then&&c.isFunction(a.then)},as:function(){var a=new b.Promise;return a.resolve.apply(a,arguments),a},error:function(){var a=new b.Promise;return a.reject.apply(a,arguments),a},when:function(a){var c;c=a&&b._isNullOrUndefined(a.length)?arguments:a;var d=c.length,e=!1,f=[],g=[];if(f.length=c.length,g.length=c.length,0===d)return b.Promise.as.apply(this,f);var h=new b.Promise,i=function(){d-=1,0===d&&(e?h.reject(g):h.resolve.apply(h,f))};return b._arrayEach(c,function(a,c){b.Promise.is(a)?a.then(function(a){f[c]=a,i()},function(a){g[c]=a,e=!0,i()}):(f[c]=a,i())}),h},_continueWhile:function(a,c){return a()?c().then(function(){return b.Promise._continueWhile(a,c)}):b.Promise.as()}}),c.extend(b.Promise.prototype,{resolve:function(a){if(this._resolved||this._rejected)throw"A promise was resolved even though it had already been "+(this._resolved?"resolved":"rejected")+".";this._resolved=!0,this._result=arguments;var c=arguments;b._arrayEach(this._resolvedCallbacks,function(a){a.apply(this,c)}),this._resolvedCallbacks=[],this._rejectedCallbacks=[]},reject:function(a){if(this._resolved||this._rejected)throw"A promise was rejected even though it had already been "+(this._resolved?"resolved":"rejected")+".";this._rejected=!0,this._error=a,b._arrayEach(this._rejectedCallbacks,function(b){b(a)}),this._resolvedCallbacks=[],this._rejectedCallbacks=[]},then:function(a,c){var d=new b.Promise,e=function(){var c=arguments;if(a)if(b.Promise._isPromisesAPlusCompliant)try{c=[a.apply(this,c)]}catch(e){c=[b.Promise.error(e)]}else c=[a.apply(this,c)];1===c.length&&b.Promise.is(c[0])?c[0].then(function(){d.resolve.apply(d,arguments)},function(a){d.reject(a)}):d.resolve.apply(d,c)},f=function(a){var e=[];if(c){if(b.Promise._isPromisesAPlusCompliant)try{e=[c(a)]}catch(f){e=[b.Promise.error(f)]}else e=[c(a)];1===e.length&&b.Promise.is(e[0])?e[0].then(function(){d.resolve.apply(d,arguments)},function(a){d.reject(a)}):b.Promise._isPromisesAPlusCompliant?d.resolve.apply(d,e):d.reject(e[0])}else d.reject(a)},g=function(a){a.call()};b.Promise._isPromisesAPlusCompliant&&("undefined"!=typeof window&&window.setTimeout?g=function(a){window.setTimeout(a,0)}:"undefined"!=typeof process&&process.nextTick&&(g=function(a){process.nextTick(a)}));var h=this;return this._resolved?g(function(){e.apply(h,h._result)}):this._rejected?g(function(){f(h._error)}):(this._resolvedCallbacks.push(e),this._rejectedCallbacks.push(f)),d},always:function(a){return this.then(a,a)},done:function(a){return this.then(a)},fail:function(a){return this.then(null,a)},_thenRunCallbacks:function(a,d){var e;if(c.isFunction(a)){var f=a;e={success:function(a){f(a,null)},error:function(a){f(null,a)}}}else e=c.clone(a);return e=e||{},this.then(function(a){return e.success?e.success.apply(this,arguments):d&&d.trigger("sync",d,a,e),b.Promise.as.apply(b.Promise,arguments)},function(a){return e.error?c.isUndefined(d)?e.error(a):e.error(d,a):d&&d.trigger("error",d,a,e),b.Promise.error(a)})},_continueWith:function(a){return this.then(function(){return a(arguments,null)},function(b){return a(null,b)})}})}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._,d=function(a){if(26>a)return String.fromCharCode(65+a);if(52>a)return String.fromCharCode(97+(a-26));if(62>a)return String.fromCharCode(48+(a-52));if(62===a)return"+";if(63===a)return"/";throw"Tried to encode large digit "+a+" in base64."},e=function(a){var b=[];return b.length=Math.ceil(a.length/3),c.times(b.length,function(c){var e=a[3*c],f=a[3*c+1]||0,g=a[3*c+2]||0,h=3*c+1<a.length,i=3*c+2<a.length;b[c]=[d(e>>2&63),d(e<<4&48|f>>4&15),h?d(f<<2&60|g>>6&3):"=",i?d(63&g):"="].join("")}),b.join("")},f=function(a,c){var d=new b.Promise;if("undefined"==typeof FileReader)return b.Promise.error(new b.Error(b.Error.FILE_READ_ERROR,"Attempted to use a FileReader on an unsupported browser."));var e=new FileReader;return e.onloadend=function(){if(2!==e.readyState)return void d.reject(new b.Error(b.Error.FILE_READ_ERROR,"Error reading file."));var a=e.result,f=/^data:([^;]*);base64,(.*)$/.exec(a);return f?void d.resolve(f[2],c||f[1]):void d.reject(new b.Error(b.Error.FILE_READ_ERROR,"Unable to interpret data URL: "+a))},e.readAsDataURL(a),d};b.File=function(a,d,g){this._name=a;var h=/\.([^.]*)$/.exec(a);h&&(h=h[1].toLowerCase());var i=g||"";if(c.isArray(d))this._source=b.Promise.as(e(d),i);else if(d&&d.base64){var j=/^data:([a-zA-Z]*\/[a-zA-Z+.-]*);(charset=[a-zA-Z0-9\-\/\s]*,)?base64,(\S+)/,k=j.exec(d.base64);k&&k.length>0?this._source=b.Promise.as(4===k.length?k[3]:k[2],k[1]):this._source=b.Promise.as(d.base64,i)}else if("undefined"!=typeof File&&d instanceof File)this._source=f(d,g);else if(c.isString(d))throw"Creating a Parse.File from a String is not yet supported."},b.File.prototype={name:function(){return this._name},url:function(){return this._url},save:function(a){a=a||{};var c=this;return c._previousSave||(c._previousSave=c._source.then(function(d,e){var f={base64:d,_ContentType:e};return b._request({route:"files",className:c._name,method:"POST",data:f,useMasterKey:a.useMasterKey})}).then(function(a){return c._name=a.name,c._url=a.url,c})),c._previousSave._thenRunCallbacks(a)}}}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._;b.Object=function(a,d){if(c.isString(a))return b.Object._create.apply(this,arguments);a=a||{},d&&d.parse&&(a=this.parse(a));var e=b._getValue(this,"defaults");if(e&&(a=c.extend({},e,a)),d&&d.collection&&(this.collection=d.collection),this._serverData={},this._opSetQueue=[{}],this.attributes={},this._hashedJSON={},this._escapedAttributes={},this.cid=c.uniqueId("c"),this.changed={},this._silent={},this._pending={},!this.set(a,{silent:!0}))throw new Error("Can't create an invalid Parse.Object");this.changed={},this._silent={},this._pending={},this._hasData=!0,this._previousAttributes=c.clone(this.attributes),this.initialize.apply(this,arguments)},b.Object.saveAll=function(a,c){return c=c||{},b.Object._deepSaveAsync(a,{useMasterKey:c.useMasterKey,sessionToken:c.sessionToken})._thenRunCallbacks(c)},b.Object.destroyAll=function(a,d){d=d||{};var e=function(a){a.trigger("destroy",a,a.collection,d)},f=[],g=function(a){var g=b.Promise.as();return a.length>0&&(g=g.then(function(){return b._request({route:"batch",method:"POST",useMasterKey:d.useMasterKey,sessionToken:d.sessionToken,data:{requests:c.map(a,function(a){return{method:"DELETE",path:"/1/classes/"+a.className+"/"+a.id}})}})}).then(function(c,g,h){b._arrayEach(a,function(a,g){if(c[g].success&&d.wait)e(a);else if(c[g].error){var h=new b.Error(c[g].error.code,c[g].error.error);h.object=a,f.push(h)}})})),g},h=b.Promise.as(),i=[];return b._arrayEach(a,function(b,c){if(b.id&&d.wait||e(b),b.id&&i.push(b),20===i.length||c+1===a.length){var f=i;i=[],h=h.then(function(){return g(f)})}}),h.then(function(){if(0===f.length)return!0;var a=new b.Error(b.Error.AGGREGATE_ERROR,"Error deleting an object in destroyAll");return a.errors=f,b.Promise.error(a)})._thenRunCallbacks(d)},b.Object.fetchAll=function(a,c){return b.Object._fetchAll(a,!0)._thenRunCallbacks(c)},b.Object.fetchAllIfNeeded=function(a,c){return b.Object._fetchAll(a,!1)._thenRunCallbacks(c)},c.extend(b.Object.prototype,b.Events,{_existed:!1,initialize:function(){},toJSON:function(){var a=this._toFullJSON();return b._arrayEach(["__type","className"],function(b){delete a[b]}),a},_toFullJSON:function(a){var d=c.clone(this.attributes);return b._objectEach(d,function(c,e){d[e]=b._encode(c,a)}),b._objectEach(this._operations,function(a,b){d[b]=a}),c.has(this,"id")&&(d.objectId=this.id),c.has(this,"createdAt")&&(c.isDate(this.createdAt)?d.createdAt=this.createdAt.toJSON():d.createdAt=this.createdAt),c.has(this,"updatedAt")&&(c.isDate(this.updatedAt)?d.updatedAt=this.updatedAt.toJSON():d.updatedAt=this.updatedAt),d.__type="Object",d.className=this.className,d},_refreshCache:function(){var a=this;a._refreshingCache||(a._refreshingCache=!0,b._objectEach(this.attributes,function(d,e){if(d instanceof b.Object)d._refreshCache();else if(c.isObject(d)){var f=!1;c.isArray(d)&&c.each(d,function(a){a instanceof b.Object&&(f=!0,a._refreshCache())}),!f&&a._resetCacheForKey(e)&&a.set(e,new b.Op.Set(d),{silent:!0})}}),delete a._refreshingCache)},dirty:function(a){this._refreshCache();var b=c.last(this._opSetQueue);return a?b[a]?!0:!1:this.id?c.keys(b).length>0?!0:!1:!0},dirtyKeys:function(){return c.keys(c.last(this._opSetQueue))},_toPointer:function(){if(!this.id)throw new Error("Can't serialize an unsaved Parse.Object");return{__type:"Pointer",className:this.className,objectId:this.id}},get:function(a){return this.attributes[a]},relation:function(a){var c=this.get(a);if(c){if(!(c instanceof b.Relation))throw"Called relation() on non-relation field "+a;return c._ensureParentAndKey(this,a),c}return new b.Relation(this,a)},escape:function(a){var d=this._escapedAttributes[a];if(d)return d;var e,f=this.attributes[a];return e=b._isNullOrUndefined(f)?"":c.escape(f.toString()),this._escapedAttributes[a]=e,e},has:function(a){return!b._isNullOrUndefined(this.attributes[a])},_mergeMagicFields:function(a){var d=this,e=["id","objectId","createdAt","updatedAt"];b._arrayEach(e,function(e){a[e]&&("objectId"===e?d.id=a[e]:"createdAt"!==e&&"updatedAt"!==e||c.isDate(a[e])?d[e]=a[e]:d[e]=b._parseDate(a[e]),delete a[e])})},_copyServerData:function(a){var c={};b._objectEach(a,function(a,d){c[d]=b._decode(d,a)}),this._serverData=c,this._rebuildAllEstimatedData(),this._refreshCache(),this._opSetQueue=[{}],this._rebuildAllEstimatedData()},_mergeFromObject:function(a){a&&(this.id=a.id,this.createdAt=a.createdAt,this.updatedAt=a.updatedAt,this._copyServerData(a._serverData),this._hasData=!0)},_startSave:function(){this._opSetQueue.push({})},_cancelSave:function(){var a=c.first(this._opSetQueue);this._opSetQueue=c.rest(this._opSetQueue);var d=c.first(this._opSetQueue);b._objectEach(a,function(b,c){var e=a[c],f=d[c];e&&f?d[c]=f._mergeWithPrevious(e):e&&(d[c]=e)}),this._saving=this._saving-1},_finishSave:function(a){var d={};b._traverse(this.attributes,function(a){a instanceof b.Object&&a.id&&a._hasData&&(d[a.id]=a)});var e=c.first(this._opSetQueue);this._opSetQueue=c.rest(this._opSetQueue),this._applyOpSet(e,this._serverData),this._mergeMagicFields(a);var f=this;b._objectEach(a,function(a,c){f._serverData[c]=b._decode(c,a);var e=b._traverse(f._serverData[c],function(a){return a instanceof b.Object&&d[a.id]?d[a.id]:void 0});e&&(f._serverData[c]=e)}),this._rebuildAllEstimatedData(),this._saving=this._saving-1},_finishFetch:function(a,b){this._opSetQueue=[{}],this._mergeMagicFields(a),this._copyServerData(a),this._hasData=b},_applyOpSet:function(a,c){var d=this;b._objectEach(a,function(a,e){c[e]=a._estimate(c[e],d,e),c[e]===b.Op._UNSET&&delete c[e]})},_resetCacheForKey:function(a){var d=this.attributes[a];if(!(!c.isObject(d)||d instanceof b.Object||d instanceof b.File)){d=d.toJSON?d.toJSON():d;var e=JSON.stringify(d);if(this._hashedJSON[a]!==e){var f=!!this._hashedJSON[a];return this._hashedJSON[a]=e,f}}return!1},_rebuildEstimatedDataForKey:function(a){var c=this;delete this.attributes[a],this._serverData[a]&&(this.attributes[a]=this._serverData[a]),b._arrayEach(this._opSetQueue,function(d){var e=d[a];e&&(c.attributes[a]=e._estimate(c.attributes[a],c,a),c.attributes[a]===b.Op._UNSET?delete c.attributes[a]:c._resetCacheForKey(a))})},_rebuildAllEstimatedData:function(){var a=this,d=c.clone(this.attributes);this.attributes=c.clone(this._serverData),b._arrayEach(this._opSetQueue,function(c){a._applyOpSet(c,a.attributes),b._objectEach(c,function(b,c){a._resetCacheForKey(c)})}),b._objectEach(d,function(b,c){a.attributes[c]!==b&&a.trigger("change:"+c,a,a.attributes[c],{})}),b._objectEach(this.attributes,function(b,e){c.has(d,e)||a.trigger("change:"+e,a,b,{})})},set:function(a,d,e){var f;if(c.isObject(a)||b._isNullOrUndefined(a)?(f=a,b._objectEach(f,function(a,c){f[c]=b._decode(c,a)}),e=d):(f={},f[a]=b._decode(a,d)),e=e||{},!f)return this;f instanceof b.Object&&(f=f.attributes);var g=this;b._objectEach(f,function(a,b){if(g.constructor.readOnlyAttributes&&g.constructor.readOnlyAttributes[b])throw new Error("Cannot modify readonly key: "+b)}),e.unset&&b._objectEach(f,function(a,c){f[c]=new b.Op.Unset});var h=c.clone(f);if(b._objectEach(h,function(a,c){a instanceof b.Op&&(h[c]=a._estimate(g.attributes[c],g,c),h[c]===b.Op._UNSET&&delete h[c])}),!this._validate(f,e))return!1;this._mergeMagicFields(f),e.changes={};var i=this._escapedAttributes;this._previousAttributes||{};return b._arrayEach(c.keys(f),function(a){var d=f[a];d instanceof b.Relation&&(d.parent=g),d instanceof b.Op||(d=new b.Op.Set(d));var h=!0;d instanceof b.Op.Set&&c.isEqual(g.attributes[a],d.value)&&(h=!1),h&&(delete i[a],e.silent?g._silent[a]=!0:e.changes[a]=!0);var j=c.last(g._opSetQueue);j[a]=d._mergeWithPrevious(j[a]),g._rebuildEstimatedDataForKey(a),h?(g.changed[a]=g.attributes[a],e.silent||(g._pending[a]=!0)):(delete g.changed[a],delete g._pending[a])}),e.silent||this.change(e),this},unset:function(a,b){return b=b||{},b.unset=!0,this.set(a,null,b)},increment:function(a,d){return(c.isUndefined(d)||c.isNull(d))&&(d=1),this.set(a,new b.Op.Increment(d))},add:function(a,c){return this.set(a,new b.Op.Add([c]))},addUnique:function(a,c){return this.set(a,new b.Op.AddUnique([c]))},remove:function(a,c){return this.set(a,new b.Op.Remove([c]))},op:function(a){return c.last(this._opSetQueue)[a]},clear:function(a){a=a||{},a.unset=!0;var b=c.extend(this.attributes,this._operations);return this.set(b,a)},_getSaveJSON:function(){var a=c.clone(c.first(this._opSetQueue));return b._objectEach(a,function(b,c){a[c]=b.toJSON()}),a},_canBeSerialized:function(){return b.Object._canBeSerializedAsValue(this.attributes)},fetch:function(a){var c=this;a=a||{};var d=b._request({method:"GET",route:"classes",className:this.className,objectId:this.id,useMasterKey:a.useMasterKey,sessionToken:a.sessionToken});return d.then(function(a,b,d){return c._finishFetch(c.parse(a,b,d),!0),c})._thenRunCallbacks(a,this)},save:function(a,d,e){var f,g,h;if(c.isObject(a)||b._isNullOrUndefined(a)?(f=a,h=d):(f={},f[a]=d,h=e),!h&&f){var i=c.reject(f,function(a,b){return c.include(["success","error","wait"],b)});if(0===i.length){var j=!0;if(c.has(f,"success")&&!c.isFunction(f.success)&&(j=!1),c.has(f,"error")&&!c.isFunction(f.error)&&(j=!1),j)return this.save(null,f)}}h=c.clone(h)||{},h.wait&&(g=c.clone(this.attributes));var k=c.clone(h)||{};k.wait&&(k.silent=!0);var l;if(k.error=function(a,b){l=b},f&&!this.set(f,k))return b.Promise.error(l)._thenRunCallbacks(h,this);var m=this;m._refreshCache();var n=[],o=[];return b.Object._findUnsavedChildren(m.attributes,n,o),n.length+o.length>0?b.Object._deepSaveAsync(this.attributes,{useMasterKey:h.useMasterKey,sessionToken:h.sessionToken}).then(function(){return m.save(null,h)},function(a){return b.Promise.error(a)._thenRunCallbacks(h,m)}):(this._startSave(),this._saving=(this._saving||0)+1,this._allPreviousSaves=this._allPreviousSaves||b.Promise.as(),this._allPreviousSaves=this._allPreviousSaves._continueWith(function(){var a=m.id?"PUT":"POST",d=m._getSaveJSON(),e="classes",i=m.className;"_User"!==m.className||m.id||(e="users",i=null);var j=b._request({route:e,className:i,objectId:m.id,method:a,useMasterKey:h.useMasterKey,sessionToken:h.sessionToken,data:d});return j=j.then(function(a,b,d){var e=m.parse(a,b,d);return h.wait&&(e=c.extend(f||{},e)),m._finishSave(e),h.wait&&m.set(g,k),m},function(a){return m._cancelSave(),b.Promise.error(a)})._thenRunCallbacks(h,m)}),this._allPreviousSaves)},destroy:function(a){a=a||{};var c=this,d=function(){c.trigger("destroy",c,c.collection,a)};if(!this.id)return d();a.wait||d();var e=b._request({route:"classes",className:this.className,objectId:this.id,method:"DELETE",useMasterKey:a.useMasterKey,sessionToken:a.sessionToken});return e.then(function(){return a.wait&&d(),c})._thenRunCallbacks(a,this)},parse:function(a,d,e){var f=c.clone(a);return c(["createdAt","updatedAt"]).each(function(a){f[a]&&(f[a]=b._parseDate(f[a]))}),f.updatedAt||(f.updatedAt=f.createdAt),d&&(this._existed=201!==d),f},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return!this.id},change:function(a){a=a||{};var d=this._changing;this._changing=!0;var e=this;b._objectEach(this._silent,function(a){e._pending[a]=!0});var f=c.extend({},a.changes,this._silent);if(this._silent={},b._objectEach(f,function(b,c){e.trigger("change:"+c,e,e.get(c),a)}),d)return this;for(var g=function(a,b){e._pending[b]||e._silent[b]||delete e.changed[b]};!c.isEmpty(this._pending);)this._pending={},this.trigger("change",this,a),b._objectEach(this.changed,g),e._previousAttributes=c.clone(this.attributes);return this._changing=!1,this},existed:function(){return this._existed},hasChanged:function(a){return arguments.length?this.changed&&c.has(this.changed,a):!c.isEmpty(this.changed)},changedAttributes:function(a){if(!a)return this.hasChanged()?c.clone(this.changed):!1;var d={},e=this._previousAttributes;return b._objectEach(a,function(a,b){c.isEqual(e[b],a)||(d[b]=a)}),d},previous:function(a){return arguments.length&&this._previousAttributes?this._previousAttributes[a]:null},previousAttributes:function(){return c.clone(this._previousAttributes)},isValid:function(){return!this.validate(this.attributes)},validate:function(a,d){if(c.has(a,"ACL")&&!(a.ACL instanceof b.ACL))return new b.Error(b.Error.OTHER_CAUSE,"ACL must be a Parse.ACL.");var e=!0;return b._objectEach(a,function(a,b){/^[A-Za-z][0-9A-Za-z_]*$/.test(b)||(e=!1)}),e?!1:new b.Error(b.Error.INVALID_KEY_NAME)},_validate:function(a,b){if(b.silent||!this.validate)return!0;a=c.extend({},this.attributes,a);var d=this.validate(a,b);return d?(b&&b.error?b.error(this,d,b):this.trigger("error",this,d,b),!1):!0},getACL:function(){return this.get("ACL")},setACL:function(a,b){return this.set("ACL",a,b)}}),b.Object._getSubclass=function(a){if(!c.isString(a))throw"Parse.Object._getSubclass requires a string argument.";var d=b.Object._classMap[a];return d||(d=b.Object.extend(a),b.Object._classMap[a]=d),d},b.Object._create=function(a,c,d){var e=b.Object._getSubclass(a);return new e(c,d)},b.Object._toObjectIdArray=function(a,c){if(0===a.length)return b.Promise.as(a);for(var d,e=a[0].className,f=[],g=0;g<a.length;g++){var h=a[g];if(e!==h.className)return d=new b.Error(b.Error.INVALID_CLASS_NAME,"All objects should be of the same class"),b.Promise.error(d);if(!h.id)return d=new b.Error(b.Error.MISSING_OBJECT_ID,"All objects must have an ID"),b.Promise.error(d);c&&h._hasData||f.push(h.id)}return b.Promise.as(f)},b.Object._updateWithFetchedResults=function(a,c,d){var e={};b._arrayEach(c,function(a,b){e[a.id]=a});for(var f=0;f<a.length;f++){var g=a[f],h=e[g.id];if(!h&&d){var i=new b.Error(b.Error.OBJECT_NOT_FOUND,"All objects must exist on the server");return b.Promise.error(i)}g._mergeFromObject(h)}return b.Promise.as(a)},b.Object._fetchAll=function(a,c){if(0===a.length)return b.Promise.as(a);var d=!c;return b.Object._toObjectIdArray(a,d).then(function(c){var d=a[0].className,e=new b.Query(d);return e.containedIn("objectId",c),e.limit=c.length,e.find()}).then(function(d){return b.Object._updateWithFetchedResults(a,d,c)})},b.Object._classMap={},b.Object._extend=b._extend,b.Object.extend=function(a,d,e){if(!c.isString(a)){if(a&&c.has(a,"className"))return b.Object.extend(a.className,a,d);throw new Error("Parse.Object.extend's first argument should be the className.")}"User"===a&&b.User._performUserRewrite&&(a="_User"),d=d||{},d.className=a;var f=null;if(c.has(b.Object._classMap,a)){var g=b.Object._classMap[a];f=g._extend(d,e)}else f=this._extend(d,e);return f.extend=function(d){if(c.isString(d)||d&&c.has(d,"className"))return b.Object.extend.apply(f,arguments);var e=[a].concat(b._.toArray(arguments));return b.Object.extend.apply(f,e)},f.createWithoutData=function(a){var b=new f;return b.id=a,b},b.Object._classMap[a]=f,f},b.Object._findUnsavedChildren=function(a,c,d){b._traverse(a,function(a){return a instanceof b.Object?(a._refreshCache(),void(a.dirty()&&c.push(a))):a instanceof b.File?void(a.url()||d.push(a)):void 0})},b.Object._canBeSerializedAsValue=function(a){if(a instanceof b.Object)return!!a.id;if(a instanceof b.File)return!0;var d=!0;return c.isArray(a)?b._arrayEach(a,function(a){b.Object._canBeSerializedAsValue(a)||(d=!1)}):c.isObject(a)&&b._objectEach(a,function(a){b.Object._canBeSerializedAsValue(a)||(d=!1)}),d},b.Object._deepSaveAsync=function(a,d){var e=[],f=[];b.Object._findUnsavedChildren(a,e,f);var g=b.Promise.as();c.each(f,function(a){g=g.then(function(){return a.save(d)})});var h=c.uniq(e),i=c.uniq(h);return g.then(function(){return b.Promise._continueWhile(function(){return i.length>0},function(){var a=[],e=[];if(b._arrayEach(i,function(b){return a.length>20?void e.push(b):void(b._canBeSerialized()?a.push(b):e.push(b))}),i=e,0===a.length)return b.Promise.error(new b.Error(b.Error.OTHER_CAUSE,"Tried to save a batch with a cycle."));var f=b.Promise.when(c.map(a,function(a){return a._allPreviousSaves||b.Promise.as()})),g=new b.Promise;return b._arrayEach(a,function(a){a._allPreviousSaves=g}),f._continueWith(function(){return b._request({route:"batch",method:"POST",useMasterKey:d.useMasterKey,sessionToken:d.sessionToken,data:{requests:c.map(a,function(a){var b=a._getSaveJSON(),c="POST",d="/1/classes/"+a.className;return a.id&&(d=d+"/"+a.id,c="PUT"),a._startSave(),{method:c,path:d,body:b}})}}).then(function(c,d,e){var f;return b._arrayEach(a,function(a,b){c[b].success?a._finishSave(a.parse(c[b].success,d,e)):(f=f||c[b].error,a._cancelSave())}),f?b.Promise.error(new b.Error(f.code,f.error)):void 0}).then(function(a){return g.resolve(a),a},function(a){return g.reject(a),b.Promise.error(a)})})})}).then(function(){return a})}}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._;b.Role=b.Object.extend("_Role",{constructor:function(a,d){c.isString(a)&&d instanceof b.ACL?(b.Object.prototype.constructor.call(this,null,null),this.setName(a),this.setACL(d)):b.Object.prototype.constructor.call(this,a,d)},getName:function(){return this.get("name")},setName:function(a,b){return this.set("name",a,b)},getUsers:function(){return this.relation("users")},getRoles:function(){return this.relation("roles")},validate:function(a,d){if("name"in a&&a.name!==this.getName()){var e=a.name;if(this.id&&this.id!==a.objectId)return new b.Error(b.Error.OTHER_CAUSE,"A role's name can only be set before it has been saved.");if(!c.isString(e))return new b.Error(b.Error.OTHER_CAUSE,"A role's name must be a String.");if(!/^[0-9a-zA-Z\-_ ]+$/.test(e))return new b.Error(b.Error.OTHER_CAUSE,"A role's name can only contain alphanumeric characters, _, -, and spaces.")}return b.Object.prototype.validate?b.Object.prototype.validate.call(this,a,d):!1}})}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._;b.Collection=function(a,b){b=b||{},b.comparator&&(this.comparator=b.comparator),b.model&&(this.model=b.model),b.query&&(this.query=b.query),this._reset(),this.initialize.apply(this,arguments),a&&this.reset(a,{silent:!0,parse:b.parse})},c.extend(b.Collection.prototype,b.Events,{model:b.Object,initialize:function(){},toJSON:function(){return this.map(function(a){return a.toJSON()})},add:function(a,d){var e,f,g,h,i,j,k={},l={};for(d=d||{},a=c.isArray(a)?a.slice():[a],e=0,g=a.length;g>e;e++){if(a[e]=this._prepareModel(a[e],d),h=a[e],!h)throw new Error("Can't add an invalid model to a collection");if(i=h.cid,k[i]||this._byCid[i])throw new Error("Duplicate cid: can't add the same model to a collection twice");if(j=h.id,!b._isNullOrUndefined(j)&&(l[j]||this._byId[j]))throw new Error("Duplicate id: can't add the same model to a collection twice");l[j]=h,k[i]=h}for(e=0;g>e;e++)(h=a[e]).on("all",this._onModelEvent,this),this._byCid[h.cid]=h,h.id&&(this._byId[h.id]=h);if(this.length+=g,f=b._isNullOrUndefined(d.at)?this.models.length:d.at,this.models.splice.apply(this.models,[f,0].concat(a)),this.comparator&&this.sort({silent:!0}),d.silent)return this;for(e=0,g=this.models.length;g>e;e++)h=this.models[e],k[h.cid]&&(d.index=e,h.trigger("add",h,this,d));return this},remove:function(a,b){var d,e,f,g;for(b=b||{},a=c.isArray(a)?a.slice():[a],d=0,e=a.length;e>d;d++)g=this.getByCid(a[d])||this.get(a[d]),g&&(delete this._byId[g.id],delete this._byCid[g.cid],f=this.indexOf(g),this.models.splice(f,1),this.length--,b.silent||(b.index=f,g.trigger("remove",g,this,b)),this._removeReference(g));return this},get:function(a){return a&&this._byId[a.id||a]},getByCid:function(a){return a&&this._byCid[a.cid||a]},at:function(a){return this.models[a]},sort:function(a){if(a=a||{},!this.comparator)throw new Error("Cannot sort a set without a comparator");
  13. var b=c.bind(this.comparator,this);return 1===this.comparator.length?this.models=this.sortBy(b):this.models.sort(b),a.silent||this.trigger("reset",this,a),this},pluck:function(a){return c.map(this.models,function(b){return b.get(a)})},reset:function(a,c){var d=this;return a=a||[],c=c||{},b._arrayEach(this.models,function(a){d._removeReference(a)}),this._reset(),this.add(a,{silent:!0,parse:c.parse}),c.silent||this.trigger("reset",this,c),this},fetch:function(a){a=c.clone(a)||{},void 0===a.parse&&(a.parse=!0);var d=this,e=this.query||new b.Query(this.model);return e.find({useMasterKey:a.useMasterKey,sessionToken:a.sessionToken}).then(function(b){return a.add?d.add(b,a):d.reset(b,a),d})._thenRunCallbacks(a,this)},create:function(a,b){var d=this;if(b=b?c.clone(b):{},a=this._prepareModel(a,b),!a)return!1;b.wait||d.add(a,b);var e=b.success;return b.success=function(c,f,g){b.wait&&d.add(c,b),e?e(c,f):c.trigger("sync",a,f,b)},a.save(null,b),a},parse:function(a,b){return a},chain:function(){return c(this.models).chain()},_reset:function(a){this.length=0,this.models=[],this._byId={},this._byCid={}},_prepareModel:function(a,c){if(a instanceof b.Object)a.collection||(a.collection=this);else{var d=a;c.collection=this,a=new this.model(d,c),a._validate(a.attributes,c)||(a=!1)}return a},_removeReference:function(a){this===a.collection&&delete a.collection,a.off("all",this._onModelEvent,this)},_onModelEvent:function(a,b,c,d){("add"!==a&&"remove"!==a||c===this)&&("destroy"===a&&this.remove(b,d),b&&"change:objectId"===a&&(delete this._byId[b.previous("objectId")],this._byId[b.id]=b),this.trigger.apply(this,arguments))}});var d=["forEach","each","map","reduce","reduceRight","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","max","min","sortBy","sortedIndex","toArray","size","first","initial","rest","last","without","indexOf","shuffle","lastIndexOf","isEmpty","groupBy"];b._arrayEach(d,function(a){b.Collection.prototype[a]=function(){return c[a].apply(c,[this.models].concat(c.toArray(arguments)))}}),b.Collection.extend=b._extend}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._;b.View=function(a){this.cid=c.uniqueId("view"),this._configure(a||{}),this._ensureElement(),this.initialize.apply(this,arguments),this.delegateEvents()};var d=/^(\S+)\s*(.*)$/,e=["model","collection","el","id","attributes","className","tagName"];c.extend(b.View.prototype,b.Events,{tagName:"div",$:function(a){return this.$el.find(a)},initialize:function(){},render:function(){return this},remove:function(){return this.$el.remove(),this},make:function(a,c,d){var e=document.createElement(a);return c&&b.$(e).attr(c),d&&b.$(e).html(d),e},setElement:function(a,c){return this.$el=b.$(a),this.el=this.$el[0],c!==!1&&this.delegateEvents(),this},delegateEvents:function(a){if(a=a||b._getValue(this,"events")){this.undelegateEvents();var e=this;b._objectEach(a,function(b,f){if(c.isFunction(b)||(b=e[a[f]]),!b)throw new Error('Event "'+a[f]+'" does not exist');var g=f.match(d),h=g[1],i=g[2];b=c.bind(b,e),h+=".delegateEvents"+e.cid,""===i?e.$el.bind(h,b):e.$el.delegate(i,h,b)})}},undelegateEvents:function(){this.$el.unbind(".delegateEvents"+this.cid)},_configure:function(a){this.options&&(a=c.extend({},this.options,a));var b=this;c.each(e,function(c){a[c]&&(b[c]=a[c])}),this.options=a},_ensureElement:function(){if(this.el)this.setElement(this.el,!1);else{var a=b._getValue(this,"attributes")||{};this.id&&(a.id=this.id),this.className&&(a["class"]=this.className),this.setElement(this.make(this.tagName,a),!1)}}}),b.View.extend=b._extend}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._;b.User=b.Object.extend("_User",{_isCurrentUser:!1,_mergeFromObject:function(a){a.getSessionToken()&&(this._sessionToken=a.getSessionToken()),b.User.__super__._mergeFromObject.call(this,a)},_mergeMagicFields:function(a){a.sessionToken&&(this._sessionToken=a.sessionToken,delete a.sessionToken),b.User.__super__._mergeMagicFields.call(this,a)},_cleanupAuthData:function(){if(this.isCurrent()){var a=this.get("authData");a&&b._objectEach(this.get("authData"),function(b,c){a[c]||delete a[c]})}},_synchronizeAllAuthData:function(){var a=this.get("authData");if(a){var c=this;b._objectEach(this.get("authData"),function(a,b){c._synchronizeAuthData(b)})}},_synchronizeAuthData:function(a){if(this.isCurrent()){var d;c.isString(a)?(d=a,a=b.User._authProviders[d]):d=a.getAuthType();var e=this.get("authData");if(e&&a){var f=a.restoreAuthentication(e[d]);f||this._unlinkFrom(a)}}},_handleSaveResult:function(a){a&&(this._isCurrentUser=!0),this._cleanupAuthData(),this._synchronizeAllAuthData(),delete this._serverData.password,this._rebuildEstimatedDataForKey("password"),this._refreshCache(),(a||this.isCurrent())&&b.User._saveCurrentUser(this)},_linkWith:function(a,d){var e;if(c.isString(a)?(e=a,a=b.User._authProviders[a]):e=a.getAuthType(),c.has(d,"authData")){var f=this.get("authData")||{};f[e]=d.authData,this.set("authData",f);var g=c.clone(d)||{};return g.success=function(a){a._handleSaveResult(!0),d.success&&d.success.apply(this,arguments)},this.save({authData:f},g)}var h=this,i=new b.Promise;return a.authenticate({success:function(a,b){h._linkWith(a,{authData:b,success:d.success,error:d.error}).then(function(){i.resolve(h)})},error:function(a,b){d.error&&d.error(h,b),i.reject(b)}}),i},_unlinkFrom:function(a,d){var e;c.isString(a)?(e=a,a=b.User._authProviders[a]):e=a.getAuthType();var f=c.clone(d),g=this;return f.authData=null,f.success=function(b){g._synchronizeAuthData(a),d.success&&d.success.apply(this,arguments)},this._linkWith(a,f)},_isLinked:function(a){var b;b=c.isString(a)?a:a.getAuthType();var d=this.get("authData")||{};return!!d[b]},_logOutWithAll:function(){var a=this.get("authData");if(a){var c=this;b._objectEach(this.get("authData"),function(a,b){c._logOutWith(b)})}},_logOutWith:function(a){this.isCurrent()&&(c.isString(a)&&(a=b.User._authProviders[a]),a&&a.deauthenticate&&a.deauthenticate())},signUp:function(a,d){var e;d=d||{};var f=a&&a.username||this.get("username");if(!f||""===f)return e=new b.Error(b.Error.OTHER_CAUSE,"Cannot sign up user with an empty name."),d&&d.error&&d.error(this,e),b.Promise.error(e);var g=a&&a.password||this.get("password");if(!g||""===g)return e=new b.Error(b.Error.OTHER_CAUSE,"Cannot sign up user with an empty password."),d&&d.error&&d.error(this,e),b.Promise.error(e);var h=c.clone(d);return h.success=function(a){a._handleSaveResult(b.User._canUseCurrentUser()),d.success&&d.success.apply(this,arguments)},this.save(a,h)},logIn:function(a){if(!b.User._canUseCurrentUser())throw new Error("It is not possible to log in on a server environment.");var c=this;a=a||{};var d=b._request({route:"login",method:"GET",useMasterKey:a.useMasterKey,data:this.toJSON()});return d.then(function(a,b,d){var e=c.parse(a,b,d);return c._finishFetch(e),c._handleSaveResult(!0),c})._thenRunCallbacks(a,this)},save:function(a,d,e){var f,g;c.isObject(a)||c.isNull(a)||c.isUndefined(a)?(f=a,g=d):(f={},f[a]=d,g=e),g=g||{};var h=c.clone(g);return h.success=function(a){a._handleSaveResult(!1),g.success&&g.success.apply(this,arguments)},b.Object.prototype.save.call(this,f,h)},fetch:function(a){var d=a?c.clone(a):{};return d.success=function(b){b._handleSaveResult(!1),a&&a.success&&a.success.apply(this,arguments)},b.Object.prototype.fetch.call(this,d)},isCurrent:function(){return this._isCurrentUser},getUsername:function(){return this.get("username")},setUsername:function(a,b){return this.set("username",a,b)},setPassword:function(a,b){return this.set("password",a,b)},getEmail:function(){return this.get("email")},setEmail:function(a,b){return this.set("email",a,b)},authenticated:function(){return!!this._sessionToken&&b.User.current()&&b.User.current().id===this.id},getSessionToken:function(){return this._sessionToken},_upgradeToRevocableSession:function(a){if(a=a||{},!b.User.current())return b.Promise.as()._thenRunCallbacks(a);var c=b.User.current().getSessionToken();return b.Session._isRevocable(c)?b.Promise.as()._thenRunCallbacks(a):b._request({route:"upgradeToRevocableSession",method:"POST",useMasterKey:a.useMasterKey,sessionToken:c}).then(function(a){var c=new b.Session;c._finishFetch(a);var d=b.User.current();d._sessionToken=c.getSessionToken(),b.User._saveCurrentUser(d)})._thenRunCallbacks(a)}},{_currentUser:null,_currentUserMatchesDisk:!1,_CURRENT_USER_KEY:"currentUser",_authProviders:{},_performUserRewrite:!0,_isRevocableSessionEnabled:!1,_enableUnsafeCurrentUser:!1,signUp:function(a,c,d,e){d=d||{},d.username=a,d.password=c;var f=b.Object._create("_User");return f.signUp(d,e)},logIn:function(a,c,d){var e=b.Object._create("_User");return e._finishFetch({username:a,password:c}),e.logIn(d)},become:function(a,c){if(!b.User._canUseCurrentUser())throw new Error("It is not secure to become a user on a node.js server environment.");c=c||{};var d=b.Object._create("_User");return b._request({route:"users",className:"me",method:"GET",useMasterKey:c.useMasterKey,sessionToken:a}).then(function(a,b,c){var e=d.parse(a,b,c);return d._finishFetch(e),d._handleSaveResult(!0),d})._thenRunCallbacks(c,d)},logOut:function(){if(!b.User._canUseCurrentUser())throw new Error("There is no current user user on a node.js server environment.");return b.User._currentAsync().then(function(a){var c=b.Storage.removeItemAsync(b._getParsePath(b.User._CURRENT_USER_KEY));if(null!==a){var d=a.getSessionToken();b.Session._isRevocable(d)&&c.then(function(){return b._request({route:"logout",method:"POST",sessionToken:d})}),a._logOutWithAll(),a._isCurrentUser=!1}return b.User._currentUserMatchesDisk=!0,b.User._currentUser=null,c})},requestPasswordReset:function(a,c){c=c||{};var d=b._request({route:"requestPasswordReset",method:"POST",useMasterKey:c.useMasterKey,data:{email:a}});return d._thenRunCallbacks(c)},current:function(){if(!b.User._canUseCurrentUser())throw new Error("There is no current user user on a node.js server environment.");if(b.Storage.async)return b.User._currentAsync(),b.User._currentUser;if(b.User._currentUser)return b.User._currentUser;if(b.User._currentUserMatchesDisk)return b.User._currentUser;b.User._currentUserMatchesDisk=!0;var a=b.Storage.getItem(b._getParsePath(b.User._CURRENT_USER_KEY));if(!a)return null;b.User._currentUser=b.Object._create("_User"),b.User._currentUser._isCurrentUser=!0;var c=JSON.parse(a);return b.User._currentUser.id=c._id,delete c._id,b.User._currentUser._sessionToken=c._sessionToken,delete c._sessionToken,b.User._currentUser._finishFetch(c),b.User._currentUser._synchronizeAllAuthData(),b.User._currentUser._refreshCache(),b.User._currentUser._opSetQueue=[{}],b.User._currentUser},_currentAsync:function(){return b.User._currentUser?b.Promise.as(b.User._currentUser):b.User._currentUserMatchesDisk?b.Promise.as(b.User._currentUser):b.Storage.getItemAsync(b._getParsePath(b.User._CURRENT_USER_KEY)).then(function(a){if(!a)return null;b.User._currentUser=b.Object._create("_User"),b.User._currentUser._isCurrentUser=!0;var c=JSON.parse(a);return b.User._currentUser.id=c._id,delete c._id,b.User._currentUser._sessionToken=c._sessionToken,delete c._sessionToken,b.User._currentUser._finishFetch(c),b.User._currentUser._synchronizeAllAuthData(),b.User._currentUser._refreshCache(),b.User._currentUser._opSetQueue=[{}],b.User._currentUser})},allowCustomUserClass:function(a){this._performUserRewrite=!a},enableRevocableSession:function(a){return a=a||{},b.User._isRevocableSessionEnabled=!0,b.User._canUseCurrentUser()&&b.User.current()?b.User.current()._upgradeToRevocableSession(a):b.Promise.as()._thenRunCallbacks(a)},enableUnsafeCurrentUser:function(){b.User._enableUnsafeCurrentUser=!0},_canUseCurrentUser:function(){return!b._isNode||b.User._enableUnsafeCurrentUser},_saveCurrentUser:function(a){null!==b.User._currentUser&&b.User._currentUser!==a&&b.User.logOut(),a._isCurrentUser=!0,b.User._currentUser=a,b.User._currentUserMatchesDisk=!0;var c=a.toJSON();c._id=a.id,c._sessionToken=a._sessionToken,b.Storage.async?b.Storage.setItemAsync(b._getParsePath(b.User._CURRENT_USER_KEY),JSON.stringify(c)):b.Storage.setItem(b._getParsePath(b.User._CURRENT_USER_KEY),JSON.stringify(c))},_registerAuthenticationProvider:function(a){b.User._authProviders[a.getAuthType()]=a,b.User.current()&&b.User.current()._synchronizeAuthData(a.getAuthType())},_logInWith:function(a,c){var d=b.Object._create("_User");return d._linkWith(a,c)}})}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse;b.Session=b.Object.extend("_Session",{getSessionToken:function(){return this._sessionToken},_mergeMagicFields:function(a){a.sessionToken&&(this._sessionToken=a.sessionToken,delete a.sessionToken),b.Session.__super__._mergeMagicFields.call(this,a)}},{readOnlyAttributes:{createdWith:!0,expiresAt:!0,installationId:!0,restricted:!0,sessionToken:!0,user:!0},current:function(a){a=a||{};var c=b.Object._create("_Session"),d=b.User.current().getSessionToken();return b._request({route:"sessions",className:"me",method:"GET",useMasterKey:a.useMasterKey,sessionToken:d}).then(function(a,b,d){var e=c.parse(a,b,d);return c._finishFetch(e),c})._thenRunCallbacks(a,c)},_isRevocable:function(a){return a.indexOf("r:")>-1},isCurrentSessionRevocable:function(){return null!==b.User.current()?b.Session._isRevocable(b.User.current().getSessionToken()):void 0}})}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._;b.Query=function(a){c.isString(a)&&(a=b.Object._getSubclass(a)),this.objectClass=a,this.className=a.prototype.className,this._where={},this._include=[],this._limit=-1,this._skip=0,this._extraOptions={}},b.Query.or=function(){var a=c.toArray(arguments),d=null;b._arrayEach(a,function(a){if(c.isNull(d)&&(d=a.className),d!==a.className)throw"All queries must be for the same class"});var e=new b.Query(d);return e._orQuery(a),e},b.Query.prototype={get:function(a,d){var e=this;e.equalTo("objectId",a);var f={};return d&&c.has(d,"useMasterKey")&&(f={useMasterKey:d.useMasterKey}),d&&c.has(d,"sessionToken")&&(f.sessionToken=d.sessionToken),e.first(f).then(function(a){if(a)return a;var c=new b.Error(b.Error.OBJECT_NOT_FOUND,"Object not found.");return b.Promise.error(c)})._thenRunCallbacks(d,null)},toJSON:function(){var a={where:this._where};return this._include.length>0&&(a.include=this._include.join(",")),this._select&&(a.keys=this._select.join(",")),this._limit>=0&&(a.limit=this._limit),this._skip>0&&(a.skip=this._skip),void 0!==this._order&&(a.order=this._order.join(",")),b._objectEach(this._extraOptions,function(b,c){a[c]=b}),a},find:function(a){var d=this;a=a||{};var e=b._request({route:"classes",className:this.className,method:"GET",useMasterKey:a.useMasterKey,sessionToken:a.sessionToken,data:this.toJSON()});return e.then(function(a){return c.map(a.results,function(c){var e;return e=a.className?new b.Object(a.className):new d.objectClass,e._finishFetch(c,!0),e})})._thenRunCallbacks(a)},count:function(a){var c=this;a=a||{};var d=this.toJSON();d.limit=0,d.count=1;var e=b._request({route:"classes",className:c.className,method:"GET",useMasterKey:a.useMasterKey,sessionToken:a.sessionToken,data:d});return e.then(function(a){return a.count})._thenRunCallbacks(a)},first:function(a){var d=this;a=a||{};var e=this.toJSON();e.limit=1;var f=b._request({route:"classes",className:this.className,method:"GET",useMasterKey:a.useMasterKey,sessionToken:a.sessionToken,data:e});return f.then(function(a){return c.map(a.results,function(c){var e;return e=a.className?new b.Object(a.className):new d.objectClass,e._finishFetch(c,!0),e})[0]})._thenRunCallbacks(a)},collection:function(a,d){return d=d||{},new b.Collection(a,c.extend(d,{model:this.objectClass,query:this}))},skip:function(a){return this._skip=a,this},limit:function(a){return this._limit=a,this},equalTo:function(a,d){return c.isUndefined(d)?this.doesNotExist(a):(this._where[a]=b._encode(d),this)},_addCondition:function(a,c,d){return this._where[a]||(this._where[a]={}),this._where[a][c]=b._encode(d),this},notEqualTo:function(a,b){return this._addCondition(a,"$ne",b),this},lessThan:function(a,b){return this._addCondition(a,"$lt",b),this},greaterThan:function(a,b){return this._addCondition(a,"$gt",b),this},lessThanOrEqualTo:function(a,b){return this._addCondition(a,"$lte",b),this},greaterThanOrEqualTo:function(a,b){return this._addCondition(a,"$gte",b),this},containedIn:function(a,b){return this._addCondition(a,"$in",b),this},notContainedIn:function(a,b){return this._addCondition(a,"$nin",b),this},containsAll:function(a,b){return this._addCondition(a,"$all",b),this},exists:function(a){return this._addCondition(a,"$exists",!0),this},doesNotExist:function(a){return this._addCondition(a,"$exists",!1),this},matches:function(a,b,c){return this._addCondition(a,"$regex",b),c||(c=""),b.ignoreCase&&(c+="i"),b.multiline&&(c+="m"),c&&c.length&&this._addCondition(a,"$options",c),this},matchesQuery:function(a,b){var c=b.toJSON();return c.className=b.className,this._addCondition(a,"$inQuery",c),this},doesNotMatchQuery:function(a,b){var c=b.toJSON();return c.className=b.className,this._addCondition(a,"$notInQuery",c),this},matchesKeyInQuery:function(a,b,c){var d=c.toJSON();return d.className=c.className,this._addCondition(a,"$select",{key:b,query:d}),this},doesNotMatchKeyInQuery:function(a,b,c){var d=c.toJSON();return d.className=c.className,this._addCondition(a,"$dontSelect",{key:b,query:d}),this},_orQuery:function(a){var b=c.map(a,function(a){return a.toJSON().where});return this._where.$or=b,this},_quote:function(a){return"\\Q"+a.replace("\\E","\\E\\\\E\\Q")+"\\E"},contains:function(a,b){return this._addCondition(a,"$regex",this._quote(b)),this},startsWith:function(a,b){return this._addCondition(a,"$regex","^"+this._quote(b)),this},endsWith:function(a,b){return this._addCondition(a,"$regex",this._quote(b)+"$"),this},ascending:function(){return this._order=[],this.addAscending.apply(this,arguments)},addAscending:function(a){var c=this;return this._order||(this._order=[]),b._arrayEach(arguments,function(a){Array.isArray(a)&&(a=a.join()),c._order=c._order.concat(a.replace(/\s/g,"").split(","))}),this},descending:function(a){return this._order=[],this.addDescending.apply(this,arguments)},addDescending:function(a){var d=this;return this._order||(this._order=[]),b._arrayEach(arguments,function(a){Array.isArray(a)&&(a=a.join()),d._order=d._order.concat(c.map(a.replace(/\s/g,"").split(","),function(a){return"-"+a}))}),this},near:function(a,c){return c instanceof b.GeoPoint||(c=new b.GeoPoint(c)),this._addCondition(a,"$nearSphere",c),this},withinRadians:function(a,b,c){return this.near(a,b),this._addCondition(a,"$maxDistance",c),this},withinMiles:function(a,b,c){return this.withinRadians(a,b,c/3958.8)},withinKilometers:function(a,b,c){return this.withinRadians(a,b,c/6371)},withinGeoBox:function(a,c,d){return c instanceof b.GeoPoint||(c=new b.GeoPoint(c)),d instanceof b.GeoPoint||(d=new b.GeoPoint(d)),this._addCondition(a,"$within",{$box:[c,d]}),this},include:function(){var a=this;return b._arrayEach(arguments,function(b){c.isArray(b)?a._include=a._include.concat(b):a._include.push(b)}),this},select:function(){var a=this;return this._select=this._select||[],b._arrayEach(arguments,function(b){c.isArray(b)?a._select=a._select.concat(b):a._select.push(b)}),this},each:function(a,d){if(d=d||{},this._order||this._skip||this._limit>=0){var e="Cannot iterate on a query with sort, skip, or limit.";return b.Promise.error(e)._thenRunCallbacks(d)}var f=(new b.Promise,new b.Query(this.objectClass));f._limit=d.batchSize||100,f._where=c.clone(this._where),f._include=c.clone(this._include),this._select&&(f._select=c.clone(this._select)),f.ascending("objectId");var g={};c.has(d,"useMasterKey")&&(g.useMasterKey=d.useMasterKey),c.has(d,"sessionToken")&&(g.sessionToken=d.sessionToken);var h=!1;return b.Promise._continueWhile(function(){return!h},function(){return f.find(g).then(function(c){var d=b.Promise.as();return b._.each(c,function(b){d=d.then(function(){return a(b)})}),d.then(function(){c.length>=f._limit?f.greaterThan("objectId",c[c.length-1].id):h=!0})})})._thenRunCallbacks(d)}}}(this),function(a){a.Parse=a.Parse||{};var b,c,d=a.Parse,e=d._,f=!1,g={authenticate:function(a){var c=this;FB.login(function(b){b.authResponse?a.success&&a.success(c,{id:b.authResponse.userID,access_token:b.authResponse.accessToken,expiration_date:new Date(1e3*b.authResponse.expiresIn+(new Date).getTime()).toJSON()}):a.error&&a.error(c,b)},{scope:b})},restoreAuthentication:function(a){if(a){var b={userID:a.id,accessToken:a.access_token,expiresIn:(d._parseDate(a.expiration_date).getTime()-(new Date).getTime())/1e3},f=e.clone(c);f.authResponse=b,f.status=!1;var g=FB.getAuthResponse();g&&g.userID!==b.userID&&FB.logout(),FB.init(f)}return!0},getAuthType:function(){return"facebook"},deauthenticate:function(){this.restoreAuthentication(null)}};d.FacebookUtils={init:function(a){if("undefined"==typeof FB)throw"The Facebook JavaScript SDK must be loaded before calling init.";if(c=e.clone(a)||{},c.status&&"undefined"!=typeof console){var b=console.warn||console.log||function(){};b.call(console,"The 'status' flag passed into FB.init, when set to true, can interfere with Parse Facebook integration, so it has been suppressed. Please call FB.getLoginStatus() explicitly if you require this behavior.")}c.status=!1,FB.init(c),d.User._registerAuthenticationProvider(g),f=!0},isLinked:function(a){return a._isLinked("facebook")},logIn:function(a,c){if(!a||e.isString(a)){if(!f)throw"You must initialize FacebookUtils before calling logIn.";return b=a,d.User._logInWith("facebook",c)}var g=e.clone(c)||{};return g.authData=a,d.User._logInWith("facebook",g)},link:function(a,c,d){if(!c||e.isString(c)){if(!f)throw"You must initialize FacebookUtils before calling link.";return b=c,a._linkWith("facebook",d)}var g=e.clone(d)||{};return g.authData=c,a._linkWith("facebook",g)},unlink:function(a,b){if(!f)throw"You must initialize FacebookUtils before calling unlink.";return a._unlinkFrom("facebook",b)}}}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._;b.History=function(){this.handlers=[],c.bindAll(this,"checkUrl")};var d=/^[#\/]/,e=/msie [\w.]+/;b.History.started=!1,c.extend(b.History.prototype,b.Events,{interval:50,getHash:function(a){var b=a?a.location:window.location,c=b.href.match(/#(.*)$/);return c?c[1]:""},getFragment:function(a,c){if(b._isNullOrUndefined(a))if(this._hasPushState||c){a=window.location.pathname;var e=window.location.search;e&&(a+=e)}else a=this.getHash();return a.indexOf(this.options.root)||(a=a.substr(this.options.root.length)),a.replace(d,"")},start:function(a){if(b.History.started)throw new Error("Parse.history has already been started");b.History.started=!0,this.options=c.extend({},{root:"/"},this.options,a),this._wantsHashChange=this.options.hashChange!==!1,this._wantsPushState=!!this.options.pushState,this._hasPushState=!!(this.options.pushState&&window.history&&window.history.pushState);var f=this.getFragment(),g=document.documentMode,h=e.exec(navigator.userAgent.toLowerCase())&&(!g||7>=g);h&&(this.iframe=b.$('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow,this.navigate(f)),this._hasPushState?b.$(window).bind("popstate",this.checkUrl):this._wantsHashChange&&"onhashchange"in window&&!h?b.$(window).bind("hashchange",this.checkUrl):this._wantsHashChange&&(this._checkUrlInterval=window.setInterval(this.checkUrl,this.interval)),this.fragment=f;var i=window.location,j=i.pathname===this.options.root;return this._wantsHashChange&&this._wantsPushState&&!this._hasPushState&&!j?(this.fragment=this.getFragment(null,!0),window.location.replace(this.options.root+"#"+this.fragment),!0):(this._wantsPushState&&this._hasPushState&&j&&i.hash&&(this.fragment=this.getHash().replace(d,""),window.history.replaceState({},document.title,i.protocol+"//"+i.host+this.options.root+this.fragment)),this.options.silent?void 0:this.loadUrl())},stop:function(){b.$(window).unbind("popstate",this.checkUrl).unbind("hashchange",this.checkUrl),window.clearInterval(this._checkUrlInterval),b.History.started=!1},route:function(a,b){this.handlers.unshift({route:a,callback:b})},checkUrl:function(a){var b=this.getFragment();return b===this.fragment&&this.iframe&&(b=this.getFragment(this.getHash(this.iframe))),b===this.fragment?!1:(this.iframe&&this.navigate(b),void(this.loadUrl()||this.loadUrl(this.getHash())))},loadUrl:function(a){var b=this.fragment=this.getFragment(a),d=c.any(this.handlers,function(a){return a.route.test(b)?(a.callback(b),!0):void 0});return d},navigate:function(a,c){if(!b.History.started)return!1;c&&c!==!0||(c={trigger:c});var e=(a||"").replace(d,"");if(this.fragment!==e){if(this._hasPushState){0!==e.indexOf(this.options.root)&&(e=this.options.root+e),this.fragment=e;var f=c.replace?"replaceState":"pushState";window.history[f]({},document.title,e)}else this._wantsHashChange?(this.fragment=e,this._updateHash(window.location,e,c.replace),this.iframe&&e!==this.getFragment(this.getHash(this.iframe))&&(c.replace||this.iframe.document.open().close(),this._updateHash(this.iframe.location,e,c.replace))):window.location.assign(this.options.root+a);c.trigger&&this.loadUrl(a)}},_updateHash:function(a,b,c){if(c){var d=a.toString().replace(/(javascript:|#).*$/,"");a.replace(d+"#"+b)}else a.hash=b}})}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._;b.Router=function(a){a=a||{},a.routes&&(this.routes=a.routes),this._bindRoutes(),this.initialize.apply(this,arguments)};var d=/:\w+/g,e=/\*\w+/g,f=/[\-\[\]{}()+?.,\\\^\$\|#\s]/g;c.extend(b.Router.prototype,b.Events,{initialize:function(){},route:function(a,d,e){return b.history=b.history||new b.History,c.isRegExp(a)||(a=this._routeToRegExp(a)),e||(e=this[d]),b.history.route(a,c.bind(function(c){var f=this._extractParameters(a,c);e&&e.apply(this,f),this.trigger.apply(this,["route:"+d].concat(f)),b.history.trigger("route",this,d,f)},this)),this},navigate:function(a,c){b.history.navigate(a,c)},_bindRoutes:function(){if(this.routes){var a=[];for(var b in this.routes)this.routes.hasOwnProperty(b)&&a.unshift([b,this.routes[b]]);for(var c=0,d=a.length;d>c;c++)this.route(a[c][0],a[c][1],this[a[c][1]])}},_routeToRegExp:function(a){return a=a.replace(f,"\\$&").replace(d,"([^/]+)").replace(e,"(.*?)"),new RegExp("^"+a+"$")},_extractParameters:function(a,b){return a.exec(b).slice(1)}}),b.Router.extend=b._extend}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse,c=b._;b.Cloud=b.Cloud||{},c.extend(b.Cloud,{run:function(a,c,d){d=d||{};var e=b._request({route:"functions",className:a,method:"POST",useMasterKey:d.useMasterKey,sessionToken:d.sessionToken,data:b._encode(c,null,!0)});return e.then(function(a){return b._decode(null,a).result})._thenRunCallbacks(d)}})}(this),function(a){a.Parse=a.Parse||{};var b=a.Parse;b.Installation=b.Object.extend("_Installation"),b.Push=b.Push||{},b.Push.send=function(a,c){if(c=c||{},a.where&&(a.where=a.where.toJSON().where),a.push_time&&(a.push_time=a.push_time.toJSON()),a.expiration_time&&(a.expiration_time=a.expiration_time.toJSON()),a.expiration_time&&a.expiration_interval)throw"Both expiration_time and expiration_interval can't be set";var d=b._request({route:"push",method:"POST",data:a,useMasterKey:c.useMasterKey});return d._thenRunCallbacks(c)}}(this);
  14. /*The MIT License (MIT)
  15.  
  16. Copyright (c) 2015 Apostolique
  17.  
  18. Permission is hereby granted, free of charge, to any person obtaining a copy
  19. of this software and associated documentation files (the "Software"), to deal
  20. in the Software without restriction, including without limitation the rights
  21. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  22. copies of the Software, and to permit persons to whom the Software is
  23. furnished to do so, subject to the following conditions:
  24.  
  25. The above copyright notice and this permission notice shall be included in all
  26. copies or substantial portions of the Software.
  27.  
  28. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  29. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  30. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  31. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  32. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  33. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  34. SOFTWARE.*/
  35.  
  36. // ==UserScript==
  37. // @name AposFeedingBot
  38. // @namespace AposFeedingBot
  39. // @include http://agar.io/*
  40. // @version 3.71
  41. // @grant none
  42. // @author http://www.twitch.tv/apostolique
  43. // @require http://www.parsecdn.com/js/parse-1.5.0.min.js
  44. // ==/UserScript==
  45.  
  46. var aposFeedingBotVersion = 3.71;
  47.  
  48. //TODO: Team mode
  49. // Detect when people are merging
  50. // Split to catch smaller targets
  51. // Angle based cluster code
  52. // Better wall code
  53. // In team mode, make allies be obstacles.
  54.  
  55. Number.prototype.mod = function(n) {
  56. return ((this % n) + n) % n;
  57. };
  58.  
  59. Array.prototype.peek = function() {
  60. return this[this.length - 1];
  61. };
  62.  
  63. var sha = "efde0488cc2cc176db48dd23b28a20b90314352b";
  64. function getLatestCommit() {
  65. window.jQuery.ajax({
  66. url: "https://api.github.com/repos/apostolique/AposFeedingBot/git/refs/heads/master",
  67. cache: false,
  68. dataType: "jsonp"
  69. }).done(function(data) {
  70. console.dir(data.data);
  71. console.log("hmm: " + data.data.object.sha);
  72. sha = data.data.object.sha;
  73.  
  74. function update(prefix, name, url) {
  75. window.jQuery(document.body).prepend("<div id='" + prefix + "Dialog' style='position: absolute; left: 0px; right: 0px; top: 0px; bottom: 0px; z-index: 100; display: none;'>");
  76. window.jQuery('#' + prefix + 'Dialog').append("<div id='" + prefix + "Message' style='width: 350px; background-color: #FFFFFF; margin: 100px auto; border-radius: 15px; padding: 5px 15px 5px 15px;'>");
  77. window.jQuery('#' + prefix + 'Message').append("<h2>UPDATE TIME!!!</h2>");
  78. window.jQuery('#' + prefix + 'Message').append("<p>Grab the update for: <a id='" + prefix + "Link' href='" + url + "' target=\"_blank\">" + name + "</a></p>");
  79. window.jQuery('#' + prefix + 'Link').on('click', function() {
  80. window.jQuery("#" + prefix + "Dialog").hide();
  81. window.jQuery("#" + prefix + "Dialog").remove();
  82. });
  83. window.jQuery("#" + prefix + "Dialog").show();
  84. }
  85.  
  86. $.get('https://raw.githubusercontent.com/Apostolique/AposFeedingBot/master/AposFeedingBot.user.js?' + Math.floor((Math.random() * 1000000) + 1), function(data) {
  87. var latestVersion = data.replace(/(\r\n|\n|\r)/gm,"");
  88. latestVersion = latestVersion.substring(latestVersion.indexOf("// @version")+11,latestVersion.indexOf("// @grant"));
  89.  
  90. latestVersion = parseFloat(latestVersion + 0.0000);
  91. var myVersion = parseFloat(aposFeedingBotVersion + 0.0000);
  92.  
  93. if(latestVersion > myVersion)
  94. {
  95. update("aposFeedingBot", "AposFeedingBot.user.js", "https://github.com/Apostolique/AposFeedingBot/blob/" + sha + "/AposFeedingBot.user.js/");
  96. }
  97. console.log('Current AposFeedingBot.user.js Version: ' + myVersion + " on Github: " + latestVersion);
  98. });
  99.  
  100. }).fail(function() {});
  101. }
  102. getLatestCommit();
  103.  
  104. console.log("Running Apos Feeding Bot!");
  105.  
  106. var f = window;
  107. var g = window.jQuery;
  108.  
  109. Parse.initialize("nj3ycKuqW4k4CnzN1ZYtMYowoa97qNw7NafLimrF", "nh6arPQQxbE5rFOyR0dCgecQiDAN54Zgjsf7eAKH");
  110.  
  111. console.log("Apos Feeding Bot!");
  112.  
  113. window.botList = window.botList || [];
  114.  
  115. /*function QuickBot() {
  116. this.name = "QuickBot V1";
  117. this.keyAction = function(key) {};
  118. this.displayText = function() {return [];};
  119. this.mainLoop = function() {
  120. return [screenToGameX(getMouseX()),
  121. screenToGameY(getMouseY())];
  122. };
  123. }
  124.  
  125. window.botList.push(new QuickBot());*/
  126.  
  127.  
  128. function AposBot() {
  129. this.name = "AposFeedingBot " + aposFeedingBotVersion;
  130.  
  131. this.lastMasterUpdate = Date.now();
  132. this.MasterLocation = Parse.Object.extend("MasterLocation");
  133.  
  134. this.toggleFollow = false;
  135. this.master = false;
  136.  
  137. this.masterLocation = [100, 100];
  138. this.masterId = 0;
  139.  
  140. this.keyAction = function(key) {
  141. if (81 == key.keyCode) {
  142. console.log("Toggle Follow Mouse!");
  143. this.toggleFollow = !this.toggleFollow;
  144. }
  145. if (77 == key.keyCode) {
  146. console.log("Toggle Master!");
  147. this.master = !this.master;
  148. }
  149. };
  150.  
  151. this.displayText = function() {
  152. var theText = [];
  153. theText.push("Q - Follow Mouse: " + (this.toggleFollow ? "On" : "Off"));
  154. theText.push("M - Status: " + (this.master ? "Master" : "Slave"));
  155. return theText;
  156. };
  157.  
  158. this.splitDistance = 710;
  159.  
  160. //Given an angle value that was gotten from valueAndleBased(),
  161. //returns a new value that scales it appropriately.
  162. this.paraAngleValue = function(angleValue, range) {
  163. return (15 / (range[1])) * (angleValue * angleValue) - (range[1] / 6);
  164. };
  165.  
  166. this.valueAngleBased = function(angle, range) {
  167. var leftValue = (angle - range[0]).mod(360);
  168. var rightValue = (this.rangeToAngle(range) - angle).mod(360);
  169.  
  170. var bestValue = Math.min(leftValue, rightValue);
  171.  
  172. if (bestValue <= range[1]) {
  173. return this.paraAngleValue(bestValue, range);
  174. }
  175. return -1;
  176. };
  177.  
  178. this.computeDistance = function(x1, y1, x2, y2) {
  179. var xdis = x1 - x2; // <--- FAKE AmS OF COURSE!
  180. var ydis = y1 - y2;
  181. var distance = Math.sqrt(xdis * xdis + ydis * ydis);
  182.  
  183. return distance;
  184. };
  185.  
  186. this.computeDistanceFromCircleEdge = function(x1, y1, x2, y2, s2) {
  187. var tempD = this.computeDistance(x1, y1, x2, y2);
  188.  
  189. var offsetX = 0;
  190. var offsetY = 0;
  191.  
  192. var ratioX = tempD / (x1 - x2);
  193. var ratioY = tempD / (y1 - y2);
  194.  
  195. offsetX = x1 - (s2 / ratioX);
  196. offsetY = y1 - (s2 / ratioY);
  197.  
  198. drawPoint(offsetX, offsetY, 5, "");
  199.  
  200. return this.computeDistance(x2, y2, offsetX, offsetY);
  201. };
  202.  
  203. this.compareSize = function(player1, player2, ratio) {
  204. if (player1.size * player1.size * ratio < player2.size * player2.size) {
  205. return true;
  206. }
  207. return false;
  208. },
  209.  
  210. this.canSplit = function(player1, player2) {
  211. return this.compareSize(player1, player2, 2.8) && !this.compareSize(player1, player2, 20);
  212. };
  213.  
  214. this.isItMe = function(player, cell) {
  215. if (getMode() == ":teams") {
  216. var currentColor = player[0].color;
  217. var currentRed = currentColor.substring(1,3);
  218. var currentGreen = currentColor.substring(3,5);
  219. var currentBlue = currentColor.substring(5,7);
  220.  
  221. var currentTeam = this.getTeam(currentRed, currentGreen, currentBlue);
  222.  
  223. var cellColor = cell.color;
  224.  
  225. var cellRed = cellColor.substring(1,3);
  226. var cellGreen = cellColor.substring(3,5);
  227. var cellBlue = cellColor.substring(5,7);
  228.  
  229. var cellTeam = this.getTeam(cellRed, cellGreen, cellBlue);
  230.  
  231. if (currentTeam == cellTeam && !cell.isVirus()) {
  232. return true;
  233. }
  234.  
  235. //console.log("COLOR: " + color);
  236.  
  237. } else {
  238. for (var i = 0; i < player.length; i++) {
  239. if (cell.id == player[i].id) {
  240. return true;
  241. }
  242. }
  243. }
  244. return false;
  245. };
  246.  
  247. this.getTeam = function(red, green, blue) {
  248. if (red == "ff") {
  249. return 0;
  250. } else if (green == "ff") {
  251. return 1;
  252. }
  253. return 2;
  254. };
  255.  
  256. this.isFood = function(blob, cell) {
  257. if (!cell.isVirus() && this.compareSize(cell, blob, 1.33) || (cell.size <= 13)) {
  258. return true;
  259. }
  260. return false;
  261. };
  262.  
  263. this.isThreat = function(blob, cell) {
  264.  
  265. if (!cell.isVirus() && this.compareSize(blob, cell, 1.30)) {
  266. return true;
  267. }
  268. return false;
  269. };
  270.  
  271. this.isVirus = function(blob, cell) {
  272. if (cell.isVirus() && this.compareSize(cell, blob, 1.2)) {
  273. return true;
  274. } else if (cell.isVirus() && cell.color.substring(3,5).toLowerCase() != "ff") {
  275. return true;
  276. }
  277. return false;
  278. };
  279.  
  280. this.isSplitTarget = function(that, blob, cell) {
  281. if (that.canSplit(cell, blob)) {
  282. return true;
  283. }
  284. return false;
  285. };
  286.  
  287. this.getTimeToRemerge = function(mass){
  288. return ((mass*0.02) + 30);
  289. };
  290.  
  291. this.separateListBasedOnFunction = function(that, listToUse, blob) {
  292. var foodElementList = [];
  293. var threatList = [];
  294. var virusList = [];
  295. var splitTargetList = [];
  296. var foundMaster = [];
  297.  
  298. var player = getPlayer();
  299.  
  300. Object.keys(listToUse).forEach(function(element, index) {
  301. var isMe = that.isItMe(player, listToUse[element]);
  302.  
  303. if (!isMe) {
  304. if (!that.master && listToUse[element].id == that.masterId) {
  305. foundMaster.push(listToUse[element]);
  306. console.log("Found master! " + that.masterId + ", " + listToUse[element].id);
  307. } else if (that.isFood(blob, listToUse[element]) && listToUse[element].isNotMoving()) {
  308. //IT'S FOOD!
  309. foodElementList.push(listToUse[element]);
  310. } else if (that.isThreat(blob, listToUse[element])) {
  311. //IT'S DANGER!
  312. if ((!that.master && listToUse[element].id != that.masterId) || that.master) {
  313. threatList.push(listToUse[element]);
  314. } else {
  315. console.log("Found master! " + that.masterId);
  316. }
  317. } else if (that.isVirus(blob, listToUse[element])) {
  318. //IT'S VIRUS!
  319. virusList.push(listToUse[element]);
  320. }
  321. else if (that.isSplitTarget(that, blob, listToUse[element])) {
  322. drawCircle(listToUse[element].x, listToUse[element].y, listToUse[element].size + 50, 7);
  323. splitTargetList.push(listToUse[element]);
  324. foodElementList.push(listToUse[element]);
  325. }
  326. }/*else if(isMe && (getBlobCount(getPlayer()) > 0)){
  327. //Attempt to make the other cell follow the mother one
  328. foodElementList.push(listToUse[element]);
  329. }*/
  330. });
  331.  
  332. foodList = [];
  333. for (var i = 0; i < foodElementList.length; i++) {
  334. foodList.push([foodElementList[i].x, foodElementList[i].y, foodElementList[i].size]);
  335. }
  336.  
  337. return [foodList, threatList, virusList, splitTargetList, foundMaster];
  338. };
  339.  
  340. this.getAll = function(blob) {
  341. var dotList = [];
  342. var player = getPlayer();
  343. var interNodes = getMemoryCells();
  344.  
  345. dotList = this.separateListBasedOnFunction(this, interNodes, blob);
  346.  
  347. return dotList;
  348. };
  349.  
  350. this.clusterFood = function(foodList, blobSize) {
  351. var clusters = [];
  352. var addedCluster = false;
  353.  
  354. //1: x
  355. //2: y
  356. //3: size or value
  357. //4: Angle, not set here.
  358.  
  359. for (var i = 0; i < foodList.length; i++) {
  360. for (var j = 0; j < clusters.length; j++) {
  361. if (this.computeDistance(foodList[i][0], foodList[i][1], clusters[j][0], clusters[j][1]) < blobSize * 1.5) {
  362. clusters[j][0] = (foodList[i][0] + clusters[j][0]) / 2;
  363. clusters[j][1] = (foodList[i][1] + clusters[j][1]) / 2;
  364. clusters[j][2] += foodList[i][2];
  365. addedCluster = true;
  366. break;
  367. }
  368. }
  369. if (!addedCluster) {
  370. clusters.push([foodList[i][0], foodList[i][1], foodList[i][2], 0]);
  371. }
  372. addedCluster = false;
  373. }
  374. return clusters;
  375. };
  376.  
  377. this.getAngle = function(x1, y1, x2, y2) {
  378. //Handle vertical and horizontal lines.
  379.  
  380. if (x1 == x2) {
  381. if (y1 < y2) {
  382. return 271;
  383. //return 89;
  384. } else {
  385. return 89;
  386. }
  387. }
  388.  
  389. return (Math.round(Math.atan2(-(y1 - y2), -(x1 - x2)) / Math.PI * 180 + 180));
  390. };
  391.  
  392. this.slope = function(x1, y1, x2, y2) {
  393. var m = (y1 - y2) / (x1 - x2);
  394.  
  395. return m;
  396. };
  397.  
  398. this.slopeFromAngle = function(degree) {
  399. if (degree == 270) {
  400. degree = 271;
  401. } else if (degree == 90) {
  402. degree = 91;
  403. }
  404. return Math.tan((degree - 180) / 180 * Math.PI);
  405. };
  406.  
  407. //Given two points on a line, finds the slope of a perpendicular line crossing it.
  408. this.inverseSlope = function(x1, y1, x2, y2) {
  409. var m = this.slope(x1, y1, x2, y2);
  410. return (-1) / m;
  411. };
  412.  
  413. //Given a slope and an offset, returns two points on that line.
  414. this.pointsOnLine = function(slope, useX, useY, distance) {
  415. var b = useY - slope * useX;
  416. var r = Math.sqrt(1 + slope * slope);
  417.  
  418. var newX1 = (useX + (distance / r));
  419. var newY1 = (useY + ((distance * slope) / r));
  420. var newX2 = (useX + ((-distance) / r));
  421. var newY2 = (useY + (((-distance) * slope) / r));
  422.  
  423. return [
  424. [newX1, newY1],
  425. [newX2, newY2]
  426. ];
  427. };
  428.  
  429. this.followAngle = function(angle, useX, useY, distance) {
  430. var slope = this.slopeFromAngle(angle);
  431. var coords = this.pointsOnLine(slope, useX, useY, distance);
  432.  
  433. var side = (angle - 90).mod(360);
  434. if (side < 180) {
  435. return coords[1];
  436. } else {
  437. return coords[0];
  438. }
  439. };
  440.  
  441. //Using a line formed from point a to b, tells if point c is on S side of that line.
  442. this.isSideLine = function(a, b, c) {
  443. if ((b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]) > 0) {
  444. return true;
  445. }
  446. return false;
  447. };
  448.  
  449. //angle range2 is within angle range2
  450. //an Angle is a point and a distance between an other point [5, 40]
  451. this.angleRangeIsWithin = function(range1, range2) {
  452. if (range2[0] == (range2[0] + range2[1]).mod(360)) {
  453. return true;
  454. }
  455. //console.log("r1: " + range1[0] + ", " + range1[1] + " ... r2: " + range2[0] + ", " + range2[1]);
  456.  
  457. var distanceFrom0 = (range1[0] - range2[0]).mod(360);
  458. var distanceFrom1 = (range1[1] - range2[0]).mod(360);
  459.  
  460. if (distanceFrom0 < range2[1] && distanceFrom1 < range2[1] && distanceFrom0 < distanceFrom1) {
  461. return true;
  462. }
  463. return false;
  464. };
  465.  
  466. this.angleRangeIsWithinInverted = function(range1, range2) {
  467. var distanceFrom0 = (range1[0] - range2[0]).mod(360);
  468. var distanceFrom1 = (range1[1] - range2[0]).mod(360);
  469.  
  470. if (distanceFrom0 < range2[1] && distanceFrom1 < range2[1] && distanceFrom0 > distanceFrom1) {
  471. return true;
  472. }
  473. return false;
  474. };
  475.  
  476. this.angleIsWithin = function(angle, range) {
  477. var diff = (this.rangeToAngle(range) - angle).mod(360);
  478. if (diff >= 0 && diff <= range[1]) {
  479. return true;
  480. }
  481. return false;
  482. };
  483.  
  484. this.rangeToAngle = function(range) {
  485. return (range[0] + range[1]).mod(360);
  486. };
  487.  
  488. this.anglePair = function(range) {
  489. return (range[0] + ", " + this.rangeToAngle(range) + " range: " + range[1]);
  490. };
  491.  
  492. this.computeAngleRanges = function(blob1, blob2) {
  493. var mainAngle = this.getAngle(blob1.x, blob1.y, blob2.x, blob2.y);
  494. var leftAngle = (mainAngle - 90).mod(360);
  495. var rightAngle = (mainAngle + 90).mod(360);
  496.  
  497. var blob1Left = this.followAngle(leftAngle, blob1.x, blob1.y, blob1.size);
  498. var blob1Right = this.followAngle(rightAngle, blob1.x, blob1.y, blob1.size);
  499.  
  500. var blob2Left = this.followAngle(rightAngle, blob2.x, blob2.y, blob2.size);
  501. var blob2Right = this.followAngle(leftAngle, blob2.x, blob2.y, blob2.size);
  502.  
  503. var blob1AngleLeft = this.getAngle(blob2.x, blob2.y, blob1Left[0], blob1Left[1]);
  504. var blob1AngleRight = this.getAngle(blob2.x, blob2.y, blob1Right[0], blob1Right[1]);
  505.  
  506. var blob2AngleLeft = this.getAngle(blob1.x, blob1.y, blob2Left[0], blob2Left[1]);
  507. var blob2AngleRight = this.getAngle(blob1.x, blob1.y, blob2Right[0], blob2Right[1]);
  508.  
  509. var blob1Range = (blob1AngleRight - blob1AngleLeft).mod(360);
  510. var blob2Range = (blob2AngleRight - blob2AngleLeft).mod(360);
  511.  
  512. var tempLine = this.followAngle(blob2AngleLeft, blob2Left[0], blob2Left[1], 400);
  513. //drawLine(blob2Left[0], blob2Left[1], tempLine[0], tempLine[1], 0);
  514.  
  515. if ((blob1Range / blob2Range) > 1) {
  516. drawPoint(blob1Left[0], blob1Left[1], 3, "");
  517. drawPoint(blob1Right[0], blob1Right[1], 3, "");
  518. drawPoint(blob1.x, blob1.y, 3, "" + blob1Range + ", " + blob2Range + " R: " + (Math.round((blob1Range / blob2Range) * 1000) / 1000));
  519. }
  520.  
  521. //drawPoint(blob2.x, blob2.y, 3, "" + blob1Range);
  522. };
  523.  
  524. this.debugAngle = function(angle, text) {
  525. var player = getPlayer();
  526. var line1 = this.followAngle(angle, player[0].x, player[0].y, 300);
  527. drawLine(player[0].x, player[0].y, line1[0], line1[1], 5);
  528. drawPoint(line1[0], line1[1], 5, "" + text);
  529. };
  530.  
  531. //TODO: Don't let this function do the radius math.
  532. this.getEdgeLinesFromPoint = function(blob1, blob2, radius) {
  533. var px = blob1.x;
  534. var py = blob1.y;
  535.  
  536. var cx = blob2.x;
  537. var cy = blob2.y;
  538.  
  539. //var radius = blob2.size;
  540.  
  541. /*if (blob2.isVirus()) {
  542. radius = blob1.size;
  543. } else if(canSplit(blob1, blob2)) {
  544. radius += splitDistance;
  545. } else {
  546. radius += blob1.size * 2;
  547. }*/
  548.  
  549. var shouldInvert = false;
  550.  
  551. var tempRadius = this.computeDistance(px, py, cx, cy);
  552. if (tempRadius <= radius) {
  553. radius = tempRadius - 5;
  554. shouldInvert = true;
  555. }
  556.  
  557. var dx = cx - px;
  558. var dy = cy - py;
  559. var dd = Math.sqrt(dx * dx + dy * dy);
  560. var a = Math.asin(radius / dd);
  561. var b = Math.atan2(dy, dx);
  562.  
  563. var t = b - a;
  564. var ta = {
  565. x: radius * Math.sin(t),
  566. y: radius * -Math.cos(t)
  567. };
  568.  
  569. t = b + a;
  570. var tb = {
  571. x: radius * -Math.sin(t),
  572. y: radius * Math.cos(t)
  573. };
  574.  
  575. var angleLeft = this.getAngle(cx + ta.x, cy + ta.y, px, py);
  576. var angleRight = this.getAngle(cx + tb.x, cy + tb.y, px, py);
  577. var angleDistance = (angleRight - angleLeft).mod(360);
  578.  
  579. /*if (shouldInvert) {
  580. var temp = angleLeft;
  581. angleLeft = (angleRight + 180).mod(360);
  582. angleRight = (temp + 180).mod(360);
  583. angleDistance = (angleRight - angleLeft).mod(360);
  584. }*/
  585.  
  586. return [angleLeft, angleDistance, [cx + tb.x, cy + tb.y],
  587. [cx + ta.x, cy + ta.y]
  588. ];
  589. };
  590.  
  591. this.invertAngle = function(range) {
  592. var angle1 = this.rangeToAngle(badAngles[i]);
  593. var angle2 = (badAngles[i][0] - angle1).mod(360);
  594. return [angle1, angle2];
  595. },
  596.  
  597. this.addWall = function(listToUse, blob) {
  598. //var mapSizeX = Math.abs(f.getMapStartX - f.getMapEndX);
  599. //var mapSizeY = Math.abs(f.getMapStartY - f.getMapEndY);
  600. //var distanceFromWallX = mapSizeX/3;
  601. //var distanceFromWallY = mapSizeY/3;
  602. var distanceFromWallY = 2000;
  603. var distanceFromWallX = 2000;
  604. if (blob.x < getMapStartX() + distanceFromWallX) {
  605. //LEFT
  606. //console.log("Left");
  607. listToUse.push([
  608. [90, true],
  609. [270, false], this.computeDistance(getMapStartX(), blob.y, blob.x, blob.y)
  610. ]);
  611. var lineLeft = this.followAngle(90, blob.x, blob.y, 190 + blob.size);
  612. var lineRight = this.followAngle(270, blob.x, blob.y, 190 + blob.size);
  613. drawLine(blob.x, blob.y, lineLeft[0], lineLeft[1], 5);
  614. drawLine(blob.x, blob.y, lineRight[0], lineRight[1], 5);
  615. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob.x, blob.y, 5);
  616. }
  617. if (blob.y < getMapStartY() + distanceFromWallY) {
  618. //TOP
  619. //console.log("TOP");
  620. listToUse.push([
  621. [180, true],
  622. [0, false], this.computeDistance(blob.x, getMapStartY, blob.x, blob.y)
  623. ]);
  624. var lineLeft = this.followAngle(180, blob.x, blob.y, 190 + blob.size);
  625. var lineRight = this.followAngle(360, blob.x, blob.y, 190 + blob.size);
  626. drawLine(blob.x, blob.y, lineLeft[0], lineLeft[1], 5);
  627. drawLine(blob.x, blob.y, lineRight[0], lineRight[1], 5);
  628. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob.x, blob.y, 5);
  629. }
  630. if (blob.x > getMapEndX() - distanceFromWallX) {
  631. //RIGHT
  632. //console.log("RIGHT");
  633. listToUse.push([
  634. [270, true],
  635. [90, false], this.computeDistance(getMapEndX(), blob.y, blob.x, blob.y)
  636. ]);
  637. var lineLeft = this.followAngle(270, blob.x, blob.y, 190 + blob.size);
  638. var lineRight = this.followAngle(90, blob.x, blob.y, 190 + blob.size);
  639. drawLine(blob.x, blob.y, lineLeft[0], lineLeft[1], 5);
  640. drawLine(blob.x, blob.y, lineRight[0], lineRight[1], 5);
  641. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob.x, blob.y, 5);
  642. }
  643. if (blob.y > getMapEndY() - distanceFromWallY) {
  644. //BOTTOM
  645. //console.log("BOTTOM");
  646. listToUse.push([
  647. [0, true],
  648. [180, false], this.computeDistance(blob.x, getMapEndY(), blob.x, blob.y)
  649. ]);
  650. var lineLeft = this.followAngle(0, blob.x, blob.y, 190 + blob.size);
  651. var lineRight = this.followAngle(180, blob.x, blob.y, 190 + blob.size);
  652. drawLine(blob.x, blob.y, lineLeft[0], lineLeft[1], 5);
  653. drawLine(blob.x, blob.y, lineRight[0], lineRight[1], 5);
  654. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob.x, blob.y, 5);
  655. }
  656. return listToUse;
  657. };
  658.  
  659. //listToUse contains angles in the form of [angle, boolean].
  660. //boolean is true when the range is starting. False when it's ending.
  661. //range = [[angle1, true], [angle2, false]]
  662.  
  663. this.getAngleIndex = function(listToUse, angle) {
  664. if (listToUse.length == 0) {
  665. return 0;
  666. }
  667.  
  668. for (var i = 0; i < listToUse.length; i++) {
  669. if (angle <= listToUse[i][0]) {
  670. return i;
  671. }
  672. }
  673.  
  674. return listToUse.length;
  675. };
  676.  
  677. this.addAngle = function(listToUse, range) {
  678. //#1 Find first open element
  679. //#2 Try to add range1 to the list. If it is within other range, don't add it, set a boolean.
  680. //#3 Try to add range2 to the list. If it is withing other range, don't add it, set a boolean.
  681.  
  682. //TODO: Only add the new range at the end after the right stuff has been removed.
  683.  
  684. var newListToUse = listToUse.slice();
  685.  
  686. var startIndex = 1;
  687.  
  688. if (newListToUse.length > 0 && !newListToUse[0][1]) {
  689. startIndex = 0;
  690. }
  691.  
  692. var startMark = this.getAngleIndex(newListToUse, range[0][0]);
  693. var startBool = startMark.mod(2) != startIndex;
  694.  
  695. var endMark = this.getAngleIndex(newListToUse, range[1][0]);
  696. var endBool = endMark.mod(2) != startIndex;
  697.  
  698. var removeList = [];
  699.  
  700. if (startMark != endMark) {
  701. //Note: If there is still an error, this would be it.
  702. var biggerList = 0;
  703. if (endMark == newListToUse.length) {
  704. biggerList = 1;
  705. }
  706.  
  707. for (var i = startMark; i < startMark + (endMark - startMark).mod(newListToUse.length + biggerList); i++) {
  708. removeList.push((i).mod(newListToUse.length));
  709. }
  710. } else if (startMark < newListToUse.length && endMark < newListToUse.length) {
  711. var startDist = (newListToUse[startMark][0] - range[0][0]).mod(360);
  712. var endDist = (newListToUse[endMark][0] - range[1][0]).mod(360);
  713.  
  714. if (startDist < endDist) {
  715. for (var i = 0; i < newListToUse.length; i++) {
  716. removeList.push(i);
  717. }
  718. }
  719. }
  720.  
  721. removeList.sort(function(a, b){return b-a;});
  722.  
  723. for (var i = 0; i < removeList.length; i++) {
  724. newListToUse.splice(removeList[i], 1);
  725. }
  726.  
  727. if (startBool) {
  728. newListToUse.splice(this.getAngleIndex(newListToUse, range[0][0]), 0, range[0]);
  729. }
  730. if (endBool) {
  731. newListToUse.splice(this.getAngleIndex(newListToUse, range[1][0]), 0, range[1]);
  732. }
  733.  
  734. return newListToUse;
  735. };
  736.  
  737. this.getAngleRange = function(blob1, blob2, index, radius) {
  738. var angleStuff = this.getEdgeLinesFromPoint(blob1, blob2, radius);
  739.  
  740. var leftAngle = angleStuff[0];
  741. var rightAngle = this.rangeToAngle(angleStuff);
  742. var difference = angleStuff[1];
  743.  
  744. drawPoint(angleStuff[2][0], angleStuff[2][1], 3, "");
  745. drawPoint(angleStuff[3][0], angleStuff[3][1], 3, "");
  746.  
  747. //console.log("Adding badAngles: " + leftAngle + ", " + rightAngle + " diff: " + difference);
  748.  
  749. var lineLeft = this.followAngle(leftAngle, blob1.x, blob1.y, 150 + blob1.size - index * 10);
  750. var lineRight = this.followAngle(rightAngle, blob1.x, blob1.y, 150 + blob1.size - index * 10);
  751.  
  752. if (blob2.isVirus()) {
  753. drawLine(blob1.x, blob1.y, lineLeft[0], lineLeft[1], 6);
  754. drawLine(blob1.x, blob1.y, lineRight[0], lineRight[1], 6);
  755. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob1.x, blob1.y, 6);
  756. } else if(getCells().hasOwnProperty(blob2.id)) {
  757. drawLine(blob1.x, blob1.y, lineLeft[0], lineLeft[1], 0);
  758. drawLine(blob1.x, blob1.y, lineRight[0], lineRight[1], 0);
  759. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob1.x, blob1.y, 0);
  760. } else {
  761. drawLine(blob1.x, blob1.y, lineLeft[0], lineLeft[1], 3);
  762. drawLine(blob1.x, blob1.y, lineRight[0], lineRight[1], 3);
  763. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob1.x, blob1.y, 3);
  764. }
  765.  
  766. return [leftAngle, difference];
  767. };
  768.  
  769. //Given a list of conditions, shift the angle to the closest available spot respecting the range given.
  770. this.shiftAngle = function(listToUse, angle, range) {
  771. //TODO: shiftAngle needs to respect the range! DONE?
  772. for (var i = 0; i < listToUse.length; i++) {
  773. if (this.angleIsWithin(angle, listToUse[i])) {
  774. //console.log("Shifting needed!");
  775.  
  776. var angle1 = listToUse[i][0];
  777. var angle2 = this.rangeToAngle(listToUse[i]);
  778.  
  779. var dist1 = (angle - angle1).mod(360);
  780. var dist2 = (angle2 - angle).mod(360);
  781.  
  782. if (dist1 < dist2) {
  783. if (this.angleIsWithin(angle1, range)) {
  784. return angle1;
  785. } else {
  786. return angle2;
  787. }
  788. } else {
  789. if (this.angleIsWithin(angle2, range)) {
  790. return angle2;
  791. } else {
  792. return angle1;
  793. }
  794. }
  795. }
  796. }
  797. //console.log("No Shifting Was needed!");
  798. return angle;
  799. };
  800.  
  801. /**
  802. * This is the main bot logic. This is called quite often.
  803. * @return A 2 dimensional array with coordinates for every cells. [[x, y], [x, y]]
  804. */
  805. this.mainLoop = function() {
  806. var player = getPlayer();
  807. var interNodes = getMemoryCells();
  808.  
  809. if ( /*!toggle*/ 1) {
  810. //The following code converts the mouse position into an
  811. //absolute game coordinate.
  812. var useMouseX = screenToGameX(getMouseX());
  813. var useMouseY = screenToGameY(getMouseY());
  814. tempPoint = [useMouseX, useMouseY, 1];
  815.  
  816. //The current destination that the cells were going towards.
  817. var tempMoveX = getPointX();
  818. var tempMoveY = getPointY();
  819.  
  820. //This variable will be returned at the end.
  821. //It will contain the destination choices for all the cells.
  822. //BTW!!! ERROR ERROR ABORT MISSION!!!!!!! READ BELOW -----------
  823. //
  824. //SINCE IT'S STUPID NOW TO ASK EACH CELL WHERE THEY WANT TO GO,
  825. //THE BOT SHOULD SIMPLY PICK ONE AND THAT'S IT, I MEAN WTF....
  826. var destinationChoices = []; //destination, size, danger
  827.  
  828. //Just to make sure the player is alive.
  829. if (player.length > 0) {
  830. if (!this.master && Date.now() - this.lastMasterUpdate > 5000) {
  831. var query = new Parse.Query(this.MasterLocation);
  832. var self = this;
  833. query.equalTo("server", getServer());
  834. query.first().then(function(object) {
  835. if (typeof object != 'undefined') {
  836. console.log("Previous Location: " + self.masterLocation);
  837. console.log("Going to: " + object.get("location"));
  838. self.masterLocation = object.get("location");
  839. self.masterLocation = object.get("location");
  840. self.masterId = object.get("cellId");
  841. console.log("Updated Location: " + self.masterLocation);
  842. } else {
  843. console.log("No master was found... Let's be the master.");
  844. self.master = true;
  845. }
  846. },
  847. function(error) {
  848. console.log("Error: " + error.code + " " + error.message);
  849. });
  850. this.lastMasterUpdate = Date.now();
  851. }
  852.  
  853. //Loop through all the player's cells.
  854. for (var k = 0; k < player.length; k++) {
  855. if (true) {
  856. drawPoint(player[k].x, player[k].y + player[k].size, 0, "" + (getLastUpdate() - player[k].birth) + " / " + (30000 + (player[k].birthMass * 57) - (getLastUpdate() - player[k].birth)) + " / " + player[k].birthMass);
  857. }
  858. }
  859.  
  860. //Loops only for one cell for now.
  861. for (var k = 0; /*k < player.length*/ k < 1; k++) {
  862.  
  863. //console.log("Working on blob: " + k);
  864.  
  865. drawCircle(player[k].x, player[k].y, player[k].size + this.splitDistance, 5);
  866. //drawPoint(player[0].x, player[0].y - player[0].size, 3, "" + Math.floor(player[0].x) + ", " + Math.floor(player[0].y));
  867.  
  868. //var allDots = processEverything(interNodes);
  869.  
  870. //loop through everything that is on the screen and
  871. //separate everything in it's own category.
  872. var allIsAll = this.getAll(player[k]);
  873.  
  874. //The food stored in element 0 of allIsAll
  875. var allPossibleFood = allIsAll[0];
  876. //The threats are stored in element 1 of allIsAll
  877. var allPossibleThreats = allIsAll[1];
  878. //The viruses are stored in element 2 of allIsAll
  879. var allPossibleViruses = allIsAll[2];
  880.  
  881. if (allIsAll[4].length > 0) {
  882. console.log("Found my real Master! " + allIsAll[4][0].id);
  883. this.masterLocation = [allIsAll[4][0].x, allIsAll[4][0].y]
  884. }
  885.  
  886.  
  887. //The bot works by removing angles in which it is too
  888. //dangerous to travel towards to.
  889. var badAngles = [];
  890. var obstacleList = [];
  891.  
  892. var isSafeSpot = true;
  893. var isMouseSafe = true;
  894.  
  895. var clusterAllFood = this.clusterFood(allPossibleFood, player[k].size);
  896.  
  897. //console.log("Looking for enemies!");
  898.  
  899. //Loop through all the cells that were identified as threats.
  900. for (var i = 0; i < allPossibleThreats.length; i++) {
  901.  
  902. var enemyDistance = this.computeDistanceFromCircleEdge(allPossibleThreats[i].x, allPossibleThreats[i].y, player[k].x, player[k].y, allPossibleThreats[i].size);
  903.  
  904. allPossibleThreats[i].enemyDist = enemyDistance;
  905. }
  906.  
  907. /*allPossibleThreats.sort(function(a, b){
  908. return a.enemyDist-b.enemyDist;
  909. })*/
  910.  
  911. for (var i = 0; i < allPossibleThreats.length; i++) {
  912.  
  913. var enemyDistance = this.computeDistance(allPossibleThreats[i].x, allPossibleThreats[i].y, player[k].x, player[k].y);
  914.  
  915. var splitDangerDistance = allPossibleThreats[i].size + this.splitDistance + 150;
  916.  
  917. var normalDangerDistance = allPossibleThreats[i].size + 150;
  918.  
  919. var shiftDistance = player[k].size;
  920.  
  921. //console.log("Found distance.");
  922.  
  923. var enemyCanSplit = (this.master ? this.canSplit(player[k], allPossibleThreats[i]) : false);
  924.  
  925. for (var j = clusterAllFood.length - 1; j >= 0 ; j--) {
  926. var secureDistance = (enemyCanSplit ? splitDangerDistance : normalDangerDistance);
  927. if (this.computeDistance(allPossibleThreats[i].x, allPossibleThreats[i].y, clusterAllFood[j][0], clusterAllFood[j][1]) < secureDistance)
  928. clusterAllFood.splice(j, 1);
  929. }
  930.  
  931. //console.log("Removed some food.");
  932.  
  933. if (enemyCanSplit) {
  934. drawCircle(allPossibleThreats[i].x, allPossibleThreats[i].y, splitDangerDistance, 0);
  935. drawCircle(allPossibleThreats[i].x, allPossibleThreats[i].y, splitDangerDistance + shiftDistance, 6);
  936. } else {
  937. drawCircle(allPossibleThreats[i].x, allPossibleThreats[i].y, normalDangerDistance, 3);
  938. drawCircle(allPossibleThreats[i].x, allPossibleThreats[i].y, normalDangerDistance + shiftDistance, 6);
  939. }
  940.  
  941. if (allPossibleThreats[i].danger && getLastUpdate() - allPossibleThreats[i].dangerTimeOut > 1000) {
  942.  
  943. allPossibleThreats[i].danger = false;
  944. }
  945.  
  946. /*if ((enemyCanSplit && enemyDistance < splitDangerDistance) ||
  947. (!enemyCanSplit && enemyDistance < normalDangerDistance)) {
  948.  
  949. allPossibleThreats[i].danger = true;
  950. allPossibleThreats[i].dangerTimeOut = f.getLastUpdate();
  951. }*/
  952.  
  953. //console.log("Figured out who was important.");
  954.  
  955. if ((enemyCanSplit && enemyDistance < splitDangerDistance) || (enemyCanSplit && allPossibleThreats[i].danger)) {
  956.  
  957. badAngles.push(this.getAngleRange(player[k], allPossibleThreats[i], i, splitDangerDistance).concat(allPossibleThreats[i].enemyDist));
  958.  
  959. } else if ((!enemyCanSplit && enemyDistance < normalDangerDistance) || (!enemyCanSplit && allPossibleThreats[i].danger)) {
  960.  
  961. badAngles.push(this.getAngleRange(player[k], allPossibleThreats[i], i, normalDangerDistance).concat(allPossibleThreats[i].enemyDist));
  962.  
  963. } else if (enemyCanSplit && enemyDistance < splitDangerDistance + shiftDistance) {
  964. var tempOb = this.getAngleRange(player[k], allPossibleThreats[i], i, splitDangerDistance + shiftDistance);
  965. var angle1 = tempOb[0];
  966. var angle2 = this.rangeToAngle(tempOb);
  967.  
  968. obstacleList.push([[angle1, true], [angle2, false]]);
  969. } else if (!enemyCanSplit && enemyDistance < normalDangerDistance + shiftDistance) {
  970. var tempOb = this.getAngleRange(player[k], allPossibleThreats[i], i, normalDangerDistance + shiftDistance);
  971. var angle1 = tempOb[0];
  972. var angle2 = this.rangeToAngle(tempOb);
  973.  
  974. obstacleList.push([[angle1, true], [angle2, false]]);
  975. }
  976. //console.log("Done with enemy: " + i);
  977. }
  978.  
  979. //console.log("Done looking for enemies!");
  980.  
  981. var goodAngles = [];
  982. var stupidList = [];
  983.  
  984. for (var i = 0; i < allPossibleViruses.length; i++) {
  985. if (player[k].size < allPossibleViruses[i].size) {
  986. drawCircle(allPossibleViruses[i].x, allPossibleViruses[i].y, allPossibleViruses[i].size + 10, 3);
  987. drawCircle(allPossibleViruses[i].x, allPossibleViruses[i].y, allPossibleViruses[i].size * 2, 6);
  988.  
  989. } else {
  990. drawCircle(allPossibleViruses[i].x, allPossibleViruses[i].y, player[k].size + 50, 3);
  991. drawCircle(allPossibleViruses[i].x, allPossibleViruses[i].y, player[k].size * 2, 6);
  992. }
  993. }
  994.  
  995. for (var i = 0; i < allPossibleViruses.length; i++) {
  996. var virusDistance = this.computeDistance(allPossibleViruses[i].x, allPossibleViruses[i].y, player[k].x, player[k].y);
  997. if (player[k].size < allPossibleViruses[i].size) {
  998. if (virusDistance < (allPossibleViruses[i].size * 2)) {
  999. var tempOb = this.getAngleRange(player[k], allPossibleViruses[i], i, allPossibleViruses[i].size + 10);
  1000. var angle1 = tempOb[0];
  1001. var angle2 = this.rangeToAngle(tempOb);
  1002. obstacleList.push([[angle1, true], [angle2, false]]);
  1003. }
  1004. } else {
  1005. if (virusDistance < (player[k].size * 2)) {
  1006. var tempOb = this.getAngleRange(player[k], allPossibleViruses[i], i, player[k].size + 50);
  1007. var angle1 = tempOb[0];
  1008. var angle2 = this.rangeToAngle(tempOb);
  1009. obstacleList.push([[angle1, true], [angle2, false]]);
  1010. }
  1011. }
  1012. }
  1013.  
  1014. if (badAngles.length > 0) {
  1015. //NOTE: This is only bandaid wall code. It's not the best way to do it.
  1016. stupidList = this.addWall(stupidList, player[k]);
  1017. }
  1018.  
  1019. for (var i = 0; i < badAngles.length; i++) {
  1020. var angle1 = badAngles[i][0];
  1021. var angle2 = this.rangeToAngle(badAngles[i]);
  1022. stupidList.push([[angle1, true], [angle2, false], badAngles[i][2]]);
  1023. }
  1024.  
  1025. //stupidList.push([[45, true], [135, false]]);
  1026. //stupidList.push([[10, true], [200, false]]);
  1027.  
  1028. stupidList.sort(function(a, b){
  1029. //console.log("Distance: " + a[2] + ", " + b[2]);
  1030. return a[2]-b[2];
  1031. });
  1032.  
  1033. //console.log("Added random noob stuff.");
  1034.  
  1035. var sortedInterList = [];
  1036. var sortedObList = [];
  1037.  
  1038. for (var i = 0; i < stupidList.length; i++) {
  1039. //console.log("Adding to sorted: " + stupidList[i][0][0] + ", " + stupidList[i][1][0]);
  1040. var tempList = this.addAngle(sortedInterList, stupidList[i]);
  1041.  
  1042. if (tempList.length == 0) {
  1043. console.log("MAYDAY IT'S HAPPENING!");
  1044. break;
  1045. } else {
  1046. sortedInterList = tempList;
  1047. }
  1048. }
  1049.  
  1050. for (var i = 0; i < obstacleList.length; i++) {
  1051. sortedObList = this.addAngle(sortedObList, obstacleList[i]);
  1052.  
  1053. if (sortedObList.length == 0) {
  1054. break;
  1055. }
  1056. }
  1057.  
  1058. var offsetI = 0;
  1059. var obOffsetI = 1;
  1060.  
  1061. if (sortedInterList.length > 0 && sortedInterList[0][1]) {
  1062. offsetI = 1;
  1063. }
  1064. if (sortedObList.length > 0 && sortedObList[0][1]) {
  1065. obOffsetI = 0;
  1066. }
  1067.  
  1068. var goodAngles = [];
  1069. var obstacleAngles = [];
  1070.  
  1071. for (var i = 0; i < sortedInterList.length; i += 2) {
  1072. var angle1 = sortedInterList[(i + offsetI).mod(sortedInterList.length)][0];
  1073. var angle2 = sortedInterList[(i + 1 + offsetI).mod(sortedInterList.length)][0];
  1074. var diff = (angle2 - angle1).mod(360);
  1075. goodAngles.push([angle1, diff]);
  1076. }
  1077.  
  1078. for (var i = 0; i < sortedObList.length; i += 2) {
  1079. var angle1 = sortedObList[(i + obOffsetI).mod(sortedObList.length)][0];
  1080. var angle2 = sortedObList[(i + 1 + obOffsetI).mod(sortedObList.length)][0];
  1081. var diff = (angle2 - angle1).mod(360);
  1082. obstacleAngles.push([angle1, diff]);
  1083. }
  1084.  
  1085. for (var i = 0; i < goodAngles.length; i++) {
  1086. var line1 = this.followAngle(goodAngles[i][0], player[k].x, player[k].y, 100 + player[k].size);
  1087. var line2 = this.followAngle((goodAngles[i][0] + goodAngles[i][1]).mod(360), player[k].x, player[k].y, 100 + player[k].size);
  1088. drawLine(player[k].x, player[k].y, line1[0], line1[1], 1);
  1089. drawLine(player[k].x, player[k].y, line2[0], line2[1], 1);
  1090.  
  1091. drawArc(line1[0], line1[1], line2[0], line2[1], player[k].x, player[k].y, 1);
  1092.  
  1093. //drawPoint(player[0].x, player[0].y, 2, "");
  1094.  
  1095. drawPoint(line1[0], line1[1], 0, "" + i + ": 0");
  1096. drawPoint(line2[0], line2[1], 0, "" + i + ": 1");
  1097. }
  1098.  
  1099. for (var i = 0; i < obstacleAngles.length; i++) {
  1100. var line1 = this.followAngle(obstacleAngles[i][0], player[k].x, player[k].y, 50 + player[k].size);
  1101. var line2 = this.followAngle((obstacleAngles[i][0] + obstacleAngles[i][1]).mod(360), player[k].x, player[k].y, 50 + player[k].size);
  1102. drawLine(player[k].x, player[k].y, line1[0], line1[1], 6);
  1103. drawLine(player[k].x, player[k].y, line2[0], line2[1], 6);
  1104.  
  1105. drawArc(line1[0], line1[1], line2[0], line2[1], player[k].x, player[k].y, 6);
  1106.  
  1107. //drawPoint(player[0].x, player[0].y, 2, "");
  1108.  
  1109. drawPoint(line1[0], line1[1], 0, "" + i + ": 0");
  1110. drawPoint(line2[0], line2[1], 0, "" + i + ": 1");
  1111. }
  1112.  
  1113. if (!this.master && goodAngles.length == 0 && (player[k].size * player[k].size / 100) > 50) {
  1114. //This is the slave mode
  1115. console.log("Really Going to: " + this.masterLocation);
  1116. var distance = this.computeDistance(player[k].x, player[k].y, this.masterLocation[0], this.masterLocation[1]);
  1117.  
  1118. var shiftedAngle = this.shiftAngle(obstacleAngles, this.getAngle(this.masterLocation[0], this.masterLocation[1], player[k].x, player[k].y), [0, 360]);
  1119.  
  1120. var destination = this.followAngle(shiftedAngle, player[k].x, player[k].y, distance);
  1121.  
  1122. destinationChoices = destination;
  1123. drawLine(player[k].x, player[k].y, destination[0], destination[1], 1);
  1124. } else if (this.toggleFollow && goodAngles.length == 0) {
  1125. //This is the follow the mouse mode
  1126. var distance = this.computeDistance(player[k].x, player[k].y, tempPoint[0], tempPoint[1]);
  1127.  
  1128. var shiftedAngle = this.shiftAngle(obstacleAngles, this.getAngle(tempPoint[0], tempPoint[1], player[k].x, player[k].y), [0, 360]);
  1129.  
  1130. var destination = this.followAngle(shiftedAngle, player[k].x, player[k].y, distance);
  1131.  
  1132. destinationChoices = destination;
  1133. drawLine(player[k].x, player[k].y, destination[0], destination[1], 1);
  1134. //tempMoveX = destination[0];
  1135. //tempMoveY = destination[1];
  1136.  
  1137. } else if (goodAngles.length > 0) {
  1138. var bIndex = goodAngles[0];
  1139. var biggest = goodAngles[0][1];
  1140. for (var i = 1; i < goodAngles.length; i++) {
  1141. var size = goodAngles[i][1];
  1142. if (size > biggest) {
  1143. biggest = size;
  1144. bIndex = goodAngles[i];
  1145. }
  1146. }
  1147. var perfectAngle = (bIndex[0] + bIndex[1] / 2).mod(360);
  1148.  
  1149. perfectAngle = this.shiftAngle(obstacleAngles, perfectAngle, bIndex);
  1150.  
  1151. var line1 = this.followAngle(perfectAngle, player[k].x, player[k].y, verticalDistance());
  1152.  
  1153. destinationChoices = line1;
  1154. drawLine(player[k].x, player[k].y, line1[0], line1[1], 7);
  1155. //tempMoveX = line1[0];
  1156. //tempMoveY = line1[1];
  1157. } else if (badAngles.length > 0 && goodAngles == 0) {
  1158. //When there are enemies around but no good angles
  1159. //You're likely screwed. (This should never happen.)
  1160.  
  1161. console.log("Failed");
  1162. destinationChoices = [tempMoveX, tempMoveY];
  1163. /*var angleWeights = [] //Put weights on the angles according to enemy distance
  1164. for (var i = 0; i < allPossibleThreats.length; i++){
  1165. var dist = this.computeDistance(player[k].x, player[k].y, allPossibleThreats[i].x, allPossibleThreats[i].y);
  1166. var angle = this.getAngle(allPossibleThreats[i].x, allPossibleThreats[i].y, player[k].x, player[k].y);
  1167. angleWeights.push([angle,dist]);
  1168. }
  1169. var maxDist = 0;
  1170. var finalAngle = 0;
  1171. for (var i = 0; i < angleWeights.length; i++){
  1172. if (angleWeights[i][1] > maxDist){
  1173. maxDist = angleWeights[i][1];
  1174. finalAngle = (angleWeights[i][0] + 180).mod(360);
  1175. }
  1176. }
  1177. var line1 = this.followAngle(finalAngle,player[k].x,player[k].y,f.verticalDistance());
  1178. drawLine(player[k].x, player[k].y, line1[0], line1[1], 2);
  1179. destinationChoices.push(line1);*/
  1180. } else if (clusterAllFood.length > 0) {
  1181. for (var i = 0; i < clusterAllFood.length; i++) {
  1182. //console.log("mefore: " + clusterAllFood[i][2]);
  1183. //This is the cost function. Higher is better.
  1184.  
  1185. var clusterAngle = this.getAngle(clusterAllFood[i][0], clusterAllFood[i][1], player[k].x, player[k].y);
  1186.  
  1187. clusterAllFood[i][2] = clusterAllFood[i][2] * 6 - this.computeDistance(clusterAllFood[i][0], clusterAllFood[i][1], player[k].x, player[k].y);
  1188. //console.log("Current Value: " + clusterAllFood[i][2]);
  1189.  
  1190. //(goodAngles[bIndex][1] / 2 - (Math.abs(perfectAngle - clusterAngle)));
  1191.  
  1192. clusterAllFood[i][3] = clusterAngle;
  1193.  
  1194. drawPoint(clusterAllFood[i][0], clusterAllFood[i][1], 1, "");
  1195. //console.log("After: " + clusterAllFood[i][2]);
  1196. }
  1197.  
  1198. var bestFoodI = 0;
  1199. var bestFood = clusterAllFood[0][2];
  1200. for (var i = 1; i < clusterAllFood.length; i++) {
  1201. if (bestFood < clusterAllFood[i][2]) {
  1202. bestFood = clusterAllFood[i][2];
  1203. bestFoodI = i;
  1204. }
  1205. }
  1206.  
  1207. //console.log("Best Value: " + clusterAllFood[bestFoodI][2]);
  1208.  
  1209. var distance = this.computeDistance(player[k].x, player[k].y, clusterAllFood[bestFoodI][0], clusterAllFood[bestFoodI][1]);
  1210.  
  1211. var shiftedAngle = this.shiftAngle(obstacleAngles, this.getAngle(clusterAllFood[bestFoodI][0], clusterAllFood[bestFoodI][1], player[k].x, player[k].y), [0, 360]);
  1212.  
  1213. var destination = this.followAngle(shiftedAngle, player[k].x, player[k].y, distance);
  1214.  
  1215. destinationChoices = destination;
  1216. //tempMoveX = destination[0];
  1217. //tempMoveY = destination[1];
  1218. drawLine(player[k].x, player[k].y, destination[0], destination[1], 1);
  1219. } else {
  1220. //If there are no enemies around and no food to eat.
  1221. destinationChoices = [tempMoveX, tempMoveY];
  1222. }
  1223.  
  1224. drawPoint(tempPoint[0], tempPoint[1], tempPoint[2], "");
  1225. //drawPoint(tempPoint[0], tempPoint[1], tempPoint[2], "" + Math.floor(this.computeDistance(tempPoint[0], tempPoint[1], I, J)));
  1226. //drawLine(tempPoint[0], tempPoint[1], player[0].x, player[0].y, 6);
  1227. //console.log("Slope: " + slope(tempPoint[0], tempPoint[1], player[0].x, player[0].y) + " Angle: " + getAngle(tempPoint[0], tempPoint[1], player[0].x, player[0].y) + " Side: " + (getAngle(tempPoint[0], tempPoint[1], player[0].x, player[0].y) - 90).mod(360));
  1228. tempPoint[2] = 1;
  1229.  
  1230. //console.log("Done working on blob: " + i);
  1231. }
  1232.  
  1233. //TODO: Find where to go based on destinationChoices.
  1234. /*var dangerFound = false;
  1235. for (var i = 0; i < destinationChoices.length; i++) {
  1236. if (destinationChoices[i][2]) {
  1237. dangerFound = true;
  1238. break;
  1239. }
  1240. }
  1241.  
  1242. destinationChoices.sort(function(a, b){return b[1] - a[1]});
  1243.  
  1244. if (dangerFound) {
  1245. for (var i = 0; i < destinationChoices.length; i++) {
  1246. if (destinationChoices[i][2]) {
  1247. tempMoveX = destinationChoices[i][0][0];
  1248. tempMoveY = destinationChoices[i][0][1];
  1249. break;
  1250. }
  1251. }
  1252. } else {
  1253. tempMoveX = destinationChoices.peek()[0][0];
  1254. tempMoveY = destinationChoices.peek()[0][1];
  1255. //console.log("Done " + tempMoveX + ", " + tempMoveY);
  1256. }*/
  1257. }
  1258. //console.log("MOVING RIGHT NOW!");
  1259.  
  1260. //console.log("______Never lied ever in my life.");
  1261.  
  1262. if (this.master) {
  1263. this.masterLocation = destinationChoices;
  1264. this.masterId = player[0].id;
  1265. if (Date.now() - this.lastMasterUpdate > 5000) {
  1266. var self = this;
  1267. var query = new Parse.Query(this.MasterLocation);
  1268. query.equalTo("server", getServer());
  1269. query.first({
  1270. success: function(object) {
  1271. console.log("Done query");
  1272. if (typeof object != 'undefined') {
  1273. object.set("location", destinationChoices);
  1274. object.set("cellId", player[0].id);
  1275. object.set("server", getServer());
  1276. console.log("New location saved! " + object.get("location") + " ID: " + player[0].id + " Server: " + getServer());
  1277. object.save();
  1278. } else {
  1279. console.log("We have a problem!");
  1280. var ml = new self.MasterLocation();
  1281. ml.set("location", destinationChoices);
  1282. ml.set("cellId", player[0].id);
  1283. ml.set("server", getServer());
  1284. console.log("New location saved! " + ml.get("location") + " ID: " + player[0].id + " Server: " + getServer());
  1285. ml.save();
  1286. }
  1287. },
  1288. error: function(error) {
  1289. console.log("Error: " + error.code + " " + error.message);
  1290. }
  1291. });
  1292. this.lastMasterUpdate = Date.now();
  1293. }
  1294. }
  1295.  
  1296. return destinationChoices;
  1297. }
  1298. };
  1299. };
  1300. window.botList.push(new AposBot());
  1301.  
  1302. window.updateBotList(); //This function might not exist yet.
  1303.  
  1304. /*The MIT License (MIT)
  1305.  
  1306. Copyright (c) 2015 Apostolique
  1307.  
  1308. Permission is hereby granted, free of charge, to any person obtaining a copy
  1309. of this software and associated documentation files (the "Software"), to deal
  1310. in the Software without restriction, including without limitation the rights
  1311. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  1312. copies of the Software, and to permit persons to whom the Software is
  1313. furnished to do so, subject to the following conditions:
  1314.  
  1315. The above copyright notice and this permission notice shall be included in all
  1316. copies or substantial portions of the Software.
  1317.  
  1318. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  1319. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  1320. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  1321. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  1322. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  1323. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  1324. SOFTWARE.*/
  1325.  
  1326. // ==UserScript==
  1327. // @name AposBot
  1328. // @namespace AposBot
  1329. // @include http://agar.io/*
  1330. // @version 3.631
  1331. // @grant none
  1332. // @author http://www.twitch.tv/apostolique
  1333. // ==/UserScript==
  1334.  
  1335. var aposBotVersion = 3.631;
  1336.  
  1337. //TODO: Team mode
  1338. // Detect when people are merging
  1339. // Split to catch smaller targets
  1340. // Angle based cluster code
  1341. // Better wall code
  1342. // In team mode, make allies be obstacles.
  1343.  
  1344. Number.prototype.mod = function(n) {
  1345. return ((this % n) + n) % n;
  1346. };
  1347.  
  1348. Array.prototype.peek = function() {
  1349. return this[this.length - 1];
  1350. };
  1351.  
  1352. var sha = "efde0488cc2cc176db48dd23b28a20b90314352b";
  1353. function getLatestCommit() {
  1354. window.jQuery.ajax({
  1355. url: "https://api.github.com/repos/apostolique/Agar.io-bot/git/refs/heads/master",
  1356. cache: false,
  1357. dataType: "jsonp"
  1358. }).done(function(data) {
  1359. console.dir(data.data);
  1360. console.log("hmm: " + data.data.object.sha);
  1361. sha = data.data.object.sha;
  1362.  
  1363. function update(prefix, name, url) {
  1364. window.jQuery(document.body).prepend("<div id='" + prefix + "Dialog' style='position: absolute; left: 0px; right: 0px; top: 0px; bottom: 0px; z-index: 100; display: none;'>");
  1365. window.jQuery('#' + prefix + 'Dialog').append("<div id='" + prefix + "Message' style='width: 350px; background-color: #FFFFFF; margin: 100px auto; border-radius: 15px; padding: 5px 15px 5px 15px;'>");
  1366. window.jQuery('#' + prefix + 'Message').append("<h2>UPDATE TIME!!!</h2>");
  1367. window.jQuery('#' + prefix + 'Message').append("<p>Grab the update for: <a id='" + prefix + "Link' href='" + url + "' target=\"_blank\">" + name + "</a></p>");
  1368. window.jQuery('#' + prefix + 'Link').on('click', function() {
  1369. window.jQuery("#" + prefix + "Dialog").hide();
  1370. window.jQuery("#" + prefix + "Dialog").remove();
  1371. });
  1372. window.jQuery("#" + prefix + "Dialog").show();
  1373. }
  1374.  
  1375. $.get('https://raw.githubusercontent.com/Apostolique/Agar.io-bot/master/bot.user.js?' + Math.floor((Math.random() * 1000000) + 1), function(data) {
  1376. var latestVersion = data.replace(/(\r\n|\n|\r)/gm,"");
  1377. latestVersion = latestVersion.substring(latestVersion.indexOf("// @version")+11,latestVersion.indexOf("// @grant"));
  1378.  
  1379. latestVersion = parseFloat(latestVersion + 0.0000);
  1380. var myVersion = parseFloat(aposBotVersion + 0.0000);
  1381.  
  1382. if(latestVersion > myVersion)
  1383. {
  1384. update("aposBot", "bot.user.js", "https://github.com/Apostolique/Agar.io-bot/blob/" + sha + "/bot.user.js/");
  1385. }
  1386. console.log('Current bot.user.js Version: ' + myVersion + " on Github: " + latestVersion);
  1387. });
  1388.  
  1389. }).fail(function() {});
  1390. }
  1391. getLatestCommit();
  1392.  
  1393. console.log("Running Apos Bot!");
  1394.  
  1395. var f = window;
  1396. var g = window.jQuery;
  1397.  
  1398.  
  1399. console.log("Apos Bot!");
  1400.  
  1401. window.botList = window.botList || [];
  1402.  
  1403. /*function QuickBot() {
  1404. this.name = "QuickBot V1";
  1405. this.keyAction = function(key) {};
  1406. this.displayText = function() {return [];};
  1407. this.mainLoop = function() {
  1408. return [screenToGameX(getMouseX()),
  1409. screenToGameY(getMouseY())];
  1410. };
  1411. }
  1412.  
  1413. window.botList.push(new QuickBot());*/
  1414.  
  1415. function AposBot() {
  1416. this.name = "AposBot " + aposBotVersion;
  1417.  
  1418. this.toggleFollow = false;
  1419. this.keyAction = function(key) {
  1420. if (81 == key.keyCode) {
  1421. console.log("Toggle Follow Mouse!");
  1422. this.toggleFollow = !this.toggleFollow;
  1423. }
  1424. };
  1425.  
  1426. this.displayText = function() {
  1427. return ["Q - Follow Mouse: " + (this.toggleFollow ? "On" : "Off")];
  1428. };
  1429.  
  1430. this.splitDistance = 710;
  1431.  
  1432. //Given an angle value that was gotten from valueAndleBased(),
  1433. //returns a new value that scales it appropriately.
  1434. this.paraAngleValue = function(angleValue, range) {
  1435. return (15 / (range[1])) * (angleValue * angleValue) - (range[1] / 6);
  1436. };
  1437.  
  1438. this.valueAngleBased = function(angle, range) {
  1439. var leftValue = (angle - range[0]).mod(360);
  1440. var rightValue = (this.rangeToAngle(range) - angle).mod(360);
  1441.  
  1442. var bestValue = Math.min(leftValue, rightValue);
  1443.  
  1444. if (bestValue <= range[1]) {
  1445. return this.paraAngleValue(bestValue, range);
  1446. }
  1447. return -1;
  1448. };
  1449.  
  1450. this.computeDistance = function(x1, y1, x2, y2) {
  1451. var xdis = x1 - x2; // <--- FAKE AmS OF COURSE!
  1452. var ydis = y1 - y2;
  1453. var distance = Math.sqrt(xdis * xdis + ydis * ydis);
  1454.  
  1455. return distance;
  1456. };
  1457.  
  1458. this.computeDistanceFromCircleEdge = function(x1, y1, x2, y2, s2) {
  1459. var tempD = this.computeDistance(x1, y1, x2, y2);
  1460.  
  1461. var offsetX = 0;
  1462. var offsetY = 0;
  1463.  
  1464. var ratioX = tempD / (x1 - x2);
  1465. var ratioY = tempD / (y1 - y2);
  1466.  
  1467. offsetX = x1 - (s2 / ratioX);
  1468. offsetY = y1 - (s2 / ratioY);
  1469.  
  1470. drawPoint(offsetX, offsetY, 5, "");
  1471.  
  1472. return this.computeDistance(x2, y2, offsetX, offsetY);
  1473. };
  1474.  
  1475. this.compareSize = function(player1, player2, ratio) {
  1476. if (player1.size * player1.size * ratio < player2.size * player2.size) {
  1477. return true;
  1478. }
  1479. return false;
  1480. },
  1481.  
  1482. this.canSplit = function(player1, player2) {
  1483. return this.compareSize(player1, player2, 2.8) && !this.compareSize(player1, player2, 20);
  1484. };
  1485.  
  1486. this.isItMe = function(player, cell) {
  1487. if (getMode() == ":teams") {
  1488. var currentColor = player[0].color;
  1489. var currentRed = currentColor.substring(1,3);
  1490. var currentGreen = currentColor.substring(3,5);
  1491. var currentBlue = currentColor.substring(5,7);
  1492.  
  1493. var currentTeam = this.getTeam(currentRed, currentGreen, currentBlue);
  1494.  
  1495. var cellColor = cell.color;
  1496.  
  1497. var cellRed = cellColor.substring(1,3);
  1498. var cellGreen = cellColor.substring(3,5);
  1499. var cellBlue = cellColor.substring(5,7);
  1500.  
  1501. var cellTeam = this.getTeam(cellRed, cellGreen, cellBlue);
  1502.  
  1503. if (currentTeam == cellTeam && !cell.isVirus()) {
  1504. return true;
  1505. }
  1506.  
  1507. //console.log("COLOR: " + color);
  1508.  
  1509. } else {
  1510. for (var i = 0; i < player.length; i++) {
  1511. if (cell.id == player[i].id) {
  1512. return true;
  1513. }
  1514. }
  1515. }
  1516. return false;
  1517. };
  1518.  
  1519. this.getTeam = function(red, green, blue) {
  1520. if (red == "ff") {
  1521. return 0;
  1522. } else if (green == "ff") {
  1523. return 1;
  1524. }
  1525. return 2;
  1526. };
  1527.  
  1528. this.isFood = function(blob, cell) {
  1529. if (!cell.isVirus() && this.compareSize(cell, blob, 1.33) || (cell.size <= 13)) {
  1530. return true;
  1531. }
  1532. return false;
  1533. };
  1534.  
  1535. this.isThreat = function(blob, cell) {
  1536.  
  1537. if (!cell.isVirus() && this.compareSize(blob, cell, 1.30)) {
  1538. return true;
  1539. }
  1540. return false;
  1541. };
  1542.  
  1543. this.isVirus = function(blob, cell) {
  1544. if (cell.isVirus() && this.compareSize(cell, blob, 1.2)) {
  1545. return true;
  1546. } else if (cell.isVirus() && cell.color.substring(3,5).toLowerCase() != "ff") {
  1547. return true;
  1548. }
  1549. return false;
  1550. };
  1551.  
  1552. this.isSplitTarget = function(that, blob, cell) {
  1553. if (that.canSplit(cell, blob)) {
  1554. return true;
  1555. }
  1556. return false;
  1557. };
  1558.  
  1559. this.getTimeToRemerge = function(mass){
  1560. return ((mass*0.02) + 30);
  1561. };
  1562.  
  1563. this.separateListBasedOnFunction = function(that, listToUse, blob) {
  1564. var foodElementList = [];
  1565. var threatList = [];
  1566. var virusList = [];
  1567. var splitTargetList = [];
  1568.  
  1569. var player = getPlayer();
  1570.  
  1571. Object.keys(listToUse).forEach(function(element, index) {
  1572. var isMe = that.isItMe(player, listToUse[element]);
  1573.  
  1574. if (!isMe) {
  1575. if (that.isFood(blob, listToUse[element]) && listToUse[element].isNotMoving()) {
  1576. //IT'S FOOD!
  1577. foodElementList.push(listToUse[element]);
  1578.  
  1579.  
  1580. } else if (that.isThreat(blob, listToUse[element])) {
  1581. //IT'S DANGER!
  1582. threatList.push(listToUse[element]);
  1583. } else if (that.isVirus(blob, listToUse[element])) {
  1584. //IT'S VIRUS!
  1585. virusList.push(listToUse[element]);
  1586. }
  1587. else if (that.isSplitTarget(that, blob, listToUse[element])) {
  1588. drawCircle(listToUse[element].x, listToUse[element].y, listToUse[element].size + 50, 7);
  1589. splitTargetList.push(listToUse[element]);
  1590. foodElementList.push(listToUse[element]);
  1591. }
  1592. }/*else if(isMe && (getBlobCount(getPlayer()) > 0)){
  1593. //Attempt to make the other cell follow the mother one
  1594. foodElementList.push(listToUse[element]);
  1595. }*/
  1596. });
  1597.  
  1598. foodList = [];
  1599. for (var i = 0; i < foodElementList.length; i++) {
  1600. foodList.push([foodElementList[i].x, foodElementList[i].y, foodElementList[i].size]);
  1601. }
  1602.  
  1603. return [foodList, threatList, virusList, splitTargetList];
  1604. };
  1605.  
  1606. this.getAll = function(blob) {
  1607. var dotList = [];
  1608. var player = getPlayer();
  1609. var interNodes = getMemoryCells();
  1610.  
  1611. dotList = this.separateListBasedOnFunction(this, interNodes, blob);
  1612.  
  1613. return dotList;
  1614. };
  1615.  
  1616. this.clusterFood = function(foodList, blobSize) {
  1617. var clusters = [];
  1618. var addedCluster = false;
  1619.  
  1620. //1: x
  1621. //2: y
  1622. //3: size or value
  1623. //4: Angle, not set here.
  1624.  
  1625. for (var i = 0; i < foodList.length; i++) {
  1626. for (var j = 0; j < clusters.length; j++) {
  1627. if (this.computeDistance(foodList[i][0], foodList[i][1], clusters[j][0], clusters[j][1]) < blobSize * 1.5) {
  1628. clusters[j][0] = (foodList[i][0] + clusters[j][0]) / 2;
  1629. clusters[j][1] = (foodList[i][1] + clusters[j][1]) / 2;
  1630. clusters[j][2] += foodList[i][2];
  1631. addedCluster = true;
  1632. break;
  1633. }
  1634. }
  1635. if (!addedCluster) {
  1636. clusters.push([foodList[i][0], foodList[i][1], foodList[i][2], 0]);
  1637. }
  1638. addedCluster = false;
  1639. }
  1640. return clusters;
  1641. };
  1642.  
  1643. this.getAngle = function(x1, y1, x2, y2) {
  1644. //Handle vertical and horizontal lines.
  1645.  
  1646. if (x1 == x2) {
  1647. if (y1 < y2) {
  1648. return 271;
  1649. //return 89;
  1650. } else {
  1651. return 89;
  1652. }
  1653. }
  1654.  
  1655. return (Math.round(Math.atan2(-(y1 - y2), -(x1 - x2)) / Math.PI * 180 + 180));
  1656. };
  1657.  
  1658. this.slope = function(x1, y1, x2, y2) {
  1659. var m = (y1 - y2) / (x1 - x2);
  1660.  
  1661. return m;
  1662. };
  1663.  
  1664. this.slopeFromAngle = function(degree) {
  1665. if (degree == 270) {
  1666. degree = 271;
  1667. } else if (degree == 90) {
  1668. degree = 91;
  1669. }
  1670. return Math.tan((degree - 180) / 180 * Math.PI);
  1671. };
  1672.  
  1673. //Given two points on a line, finds the slope of a perpendicular line crossing it.
  1674. this.inverseSlope = function(x1, y1, x2, y2) {
  1675. var m = this.slope(x1, y1, x2, y2);
  1676. return (-1) / m;
  1677. };
  1678.  
  1679. //Given a slope and an offset, returns two points on that line.
  1680. this.pointsOnLine = function(slope, useX, useY, distance) {
  1681. var b = useY - slope * useX;
  1682. var r = Math.sqrt(1 + slope * slope);
  1683.  
  1684. var newX1 = (useX + (distance / r));
  1685. var newY1 = (useY + ((distance * slope) / r));
  1686. var newX2 = (useX + ((-distance) / r));
  1687. var newY2 = (useY + (((-distance) * slope) / r));
  1688.  
  1689. return [
  1690. [newX1, newY1],
  1691. [newX2, newY2]
  1692. ];
  1693. };
  1694.  
  1695. this.followAngle = function(angle, useX, useY, distance) {
  1696. var slope = this.slopeFromAngle(angle);
  1697. var coords = this.pointsOnLine(slope, useX, useY, distance);
  1698.  
  1699. var side = (angle - 90).mod(360);
  1700. if (side < 180) {
  1701. return coords[1];
  1702. } else {
  1703. return coords[0];
  1704. }
  1705. };
  1706.  
  1707. //Using a line formed from point a to b, tells if point c is on S side of that line.
  1708. this.isSideLine = function(a, b, c) {
  1709. if ((b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]) > 0) {
  1710. return true;
  1711. }
  1712. return false;
  1713. };
  1714.  
  1715. //angle range2 is within angle range2
  1716. //an Angle is a point and a distance between an other point [5, 40]
  1717. this.angleRangeIsWithin = function(range1, range2) {
  1718. if (range2[0] == (range2[0] + range2[1]).mod(360)) {
  1719. return true;
  1720. }
  1721. //console.log("r1: " + range1[0] + ", " + range1[1] + " ... r2: " + range2[0] + ", " + range2[1]);
  1722.  
  1723. var distanceFrom0 = (range1[0] - range2[0]).mod(360);
  1724. var distanceFrom1 = (range1[1] - range2[0]).mod(360);
  1725.  
  1726. if (distanceFrom0 < range2[1] && distanceFrom1 < range2[1] && distanceFrom0 < distanceFrom1) {
  1727. return true;
  1728. }
  1729. return false;
  1730. };
  1731.  
  1732. this.angleRangeIsWithinInverted = function(range1, range2) {
  1733. var distanceFrom0 = (range1[0] - range2[0]).mod(360);
  1734. var distanceFrom1 = (range1[1] - range2[0]).mod(360);
  1735.  
  1736. if (distanceFrom0 < range2[1] && distanceFrom1 < range2[1] && distanceFrom0 > distanceFrom1) {
  1737. return true;
  1738. }
  1739. return false;
  1740. };
  1741.  
  1742. this.angleIsWithin = function(angle, range) {
  1743. var diff = (this.rangeToAngle(range) - angle).mod(360);
  1744. if (diff >= 0 && diff <= range[1]) {
  1745. return true;
  1746. }
  1747. return false;
  1748. };
  1749.  
  1750. this.rangeToAngle = function(range) {
  1751. return (range[0] + range[1]).mod(360);
  1752. };
  1753.  
  1754. this.anglePair = function(range) {
  1755. return (range[0] + ", " + this.rangeToAngle(range) + " range: " + range[1]);
  1756. };
  1757.  
  1758. this.computeAngleRanges = function(blob1, blob2) {
  1759. var mainAngle = this.getAngle(blob1.x, blob1.y, blob2.x, blob2.y);
  1760. var leftAngle = (mainAngle - 90).mod(360);
  1761. var rightAngle = (mainAngle + 90).mod(360);
  1762.  
  1763. var blob1Left = this.followAngle(leftAngle, blob1.x, blob1.y, blob1.size);
  1764. var blob1Right = this.followAngle(rightAngle, blob1.x, blob1.y, blob1.size);
  1765.  
  1766. var blob2Left = this.followAngle(rightAngle, blob2.x, blob2.y, blob2.size);
  1767. var blob2Right = this.followAngle(leftAngle, blob2.x, blob2.y, blob2.size);
  1768.  
  1769. var blob1AngleLeft = this.getAngle(blob2.x, blob2.y, blob1Left[0], blob1Left[1]);
  1770. var blob1AngleRight = this.getAngle(blob2.x, blob2.y, blob1Right[0], blob1Right[1]);
  1771.  
  1772. var blob2AngleLeft = this.getAngle(blob1.x, blob1.y, blob2Left[0], blob2Left[1]);
  1773. var blob2AngleRight = this.getAngle(blob1.x, blob1.y, blob2Right[0], blob2Right[1]);
  1774.  
  1775. var blob1Range = (blob1AngleRight - blob1AngleLeft).mod(360);
  1776. var blob2Range = (blob2AngleRight - blob2AngleLeft).mod(360);
  1777.  
  1778. var tempLine = this.followAngle(blob2AngleLeft, blob2Left[0], blob2Left[1], 400);
  1779. //drawLine(blob2Left[0], blob2Left[1], tempLine[0], tempLine[1], 0);
  1780.  
  1781. if ((blob1Range / blob2Range) > 1) {
  1782. drawPoint(blob1Left[0], blob1Left[1], 3, "");
  1783. drawPoint(blob1Right[0], blob1Right[1], 3, "");
  1784. drawPoint(blob1.x, blob1.y, 3, "" + blob1Range + ", " + blob2Range + " R: " + (Math.round((blob1Range / blob2Range) * 1000) / 1000));
  1785. }
  1786.  
  1787. //drawPoint(blob2.x, blob2.y, 3, "" + blob1Range);
  1788. };
  1789.  
  1790. this.debugAngle = function(angle, text) {
  1791. var player = getPlayer();
  1792. var line1 = this.followAngle(angle, player[0].x, player[0].y, 300);
  1793. drawLine(player[0].x, player[0].y, line1[0], line1[1], 5);
  1794. drawPoint(line1[0], line1[1], 5, "" + text);
  1795. };
  1796.  
  1797. //TODO: Don't let this function do the radius math.
  1798. this.getEdgeLinesFromPoint = function(blob1, blob2, radius) {
  1799. var px = blob1.x;
  1800. var py = blob1.y;
  1801.  
  1802. var cx = blob2.x;
  1803. var cy = blob2.y;
  1804.  
  1805. //var radius = blob2.size;
  1806.  
  1807. /*if (blob2.isVirus()) {
  1808. radius = blob1.size;
  1809. } else if(canSplit(blob1, blob2)) {
  1810. radius += splitDistance;
  1811. } else {
  1812. radius += blob1.size * 2;
  1813. }*/
  1814.  
  1815. var shouldInvert = false;
  1816.  
  1817. var tempRadius = this.computeDistance(px, py, cx, cy);
  1818. if (tempRadius <= radius) {
  1819. radius = tempRadius - 5;
  1820. shouldInvert = true;
  1821. }
  1822.  
  1823. var dx = cx - px;
  1824. var dy = cy - py;
  1825. var dd = Math.sqrt(dx * dx + dy * dy);
  1826. var a = Math.asin(radius / dd);
  1827. var b = Math.atan2(dy, dx);
  1828.  
  1829. var t = b - a;
  1830. var ta = {
  1831. x: radius * Math.sin(t),
  1832. y: radius * -Math.cos(t)
  1833. };
  1834.  
  1835. t = b + a;
  1836. var tb = {
  1837. x: radius * -Math.sin(t),
  1838. y: radius * Math.cos(t)
  1839. };
  1840.  
  1841. var angleLeft = this.getAngle(cx + ta.x, cy + ta.y, px, py);
  1842. var angleRight = this.getAngle(cx + tb.x, cy + tb.y, px, py);
  1843. var angleDistance = (angleRight - angleLeft).mod(360);
  1844.  
  1845. /*if (shouldInvert) {
  1846. var temp = angleLeft;
  1847. angleLeft = (angleRight + 180).mod(360);
  1848. angleRight = (temp + 180).mod(360);
  1849. angleDistance = (angleRight - angleLeft).mod(360);
  1850. }*/
  1851.  
  1852. return [angleLeft, angleDistance, [cx + tb.x, cy + tb.y],
  1853. [cx + ta.x, cy + ta.y]
  1854. ];
  1855. };
  1856.  
  1857. this.invertAngle = function(range) {
  1858. var angle1 = this.rangeToAngle(badAngles[i]);
  1859. var angle2 = (badAngles[i][0] - angle1).mod(360);
  1860. return [angle1, angle2];
  1861. },
  1862.  
  1863. this.addWall = function(listToUse, blob) {
  1864. //var mapSizeX = Math.abs(f.getMapStartX - f.getMapEndX);
  1865. //var mapSizeY = Math.abs(f.getMapStartY - f.getMapEndY);
  1866. //var distanceFromWallX = mapSizeX/3;
  1867. //var distanceFromWallY = mapSizeY/3;
  1868. var distanceFromWallY = 2000;
  1869. var distanceFromWallX = 2000;
  1870. if (blob.x < getMapStartX() + distanceFromWallX) {
  1871. //LEFT
  1872. //console.log("Left");
  1873. listToUse.push([
  1874. [90, true],
  1875. [270, false], this.computeDistance(getMapStartX(), blob.y, blob.x, blob.y)
  1876. ]);
  1877. var lineLeft = this.followAngle(90, blob.x, blob.y, 190 + blob.size);
  1878. var lineRight = this.followAngle(270, blob.x, blob.y, 190 + blob.size);
  1879. drawLine(blob.x, blob.y, lineLeft[0], lineLeft[1], 5);
  1880. drawLine(blob.x, blob.y, lineRight[0], lineRight[1], 5);
  1881. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob.x, blob.y, 5);
  1882. }
  1883. if (blob.y < getMapStartY() + distanceFromWallY) {
  1884. //TOP
  1885. //console.log("TOP");
  1886. listToUse.push([
  1887. [180, true],
  1888. [0, false], this.computeDistance(blob.x, getMapStartY(), blob.x, blob.y)
  1889. ]);
  1890. var lineLeft = this.followAngle(180, blob.x, blob.y, 190 + blob.size);
  1891. var lineRight = this.followAngle(360, blob.x, blob.y, 190 + blob.size);
  1892. drawLine(blob.x, blob.y, lineLeft[0], lineLeft[1], 5);
  1893. drawLine(blob.x, blob.y, lineRight[0], lineRight[1], 5);
  1894. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob.x, blob.y, 5);
  1895. }
  1896. if (blob.x > getMapEndX() - distanceFromWallX) {
  1897. //RIGHT
  1898. //console.log("RIGHT");
  1899. listToUse.push([
  1900. [270, true],
  1901. [90, false], this.computeDistance(getMapEndX(), blob.y, blob.x, blob.y)
  1902. ]);
  1903. var lineLeft = this.followAngle(270, blob.x, blob.y, 190 + blob.size);
  1904. var lineRight = this.followAngle(90, blob.x, blob.y, 190 + blob.size);
  1905. drawLine(blob.x, blob.y, lineLeft[0], lineLeft[1], 5);
  1906. drawLine(blob.x, blob.y, lineRight[0], lineRight[1], 5);
  1907. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob.x, blob.y, 5);
  1908. }
  1909. if (blob.y > getMapEndY() - distanceFromWallY) {
  1910. //BOTTOM
  1911. //console.log("BOTTOM");
  1912. listToUse.push([
  1913. [0, true],
  1914. [180, false], this.computeDistance(blob.x, getMapEndY(), blob.x, blob.y)
  1915. ]);
  1916. var lineLeft = this.followAngle(0, blob.x, blob.y, 190 + blob.size);
  1917. var lineRight = this.followAngle(180, blob.x, blob.y, 190 + blob.size);
  1918. drawLine(blob.x, blob.y, lineLeft[0], lineLeft[1], 5);
  1919. drawLine(blob.x, blob.y, lineRight[0], lineRight[1], 5);
  1920. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob.x, blob.y, 5);
  1921. }
  1922. return listToUse;
  1923. };
  1924.  
  1925. //listToUse contains angles in the form of [angle, boolean].
  1926. //boolean is true when the range is starting. False when it's ending.
  1927. //range = [[angle1, true], [angle2, false]]
  1928.  
  1929. this.getAngleIndex = function(listToUse, angle) {
  1930. if (listToUse.length == 0) {
  1931. return 0;
  1932. }
  1933.  
  1934. for (var i = 0; i < listToUse.length; i++) {
  1935. if (angle <= listToUse[i][0]) {
  1936. return i;
  1937. }
  1938. }
  1939.  
  1940. return listToUse.length;
  1941. };
  1942.  
  1943. this.addAngle = function(listToUse, range) {
  1944. //#1 Find first open element
  1945. //#2 Try to add range1 to the list. If it is within other range, don't add it, set a boolean.
  1946. //#3 Try to add range2 to the list. If it is withing other range, don't add it, set a boolean.
  1947.  
  1948. //TODO: Only add the new range at the end after the right stuff has been removed.
  1949.  
  1950. var newListToUse = listToUse.slice();
  1951.  
  1952. var startIndex = 1;
  1953.  
  1954. if (newListToUse.length > 0 && !newListToUse[0][1]) {
  1955. startIndex = 0;
  1956. }
  1957.  
  1958. var startMark = this.getAngleIndex(newListToUse, range[0][0]);
  1959. var startBool = startMark.mod(2) != startIndex;
  1960.  
  1961. var endMark = this.getAngleIndex(newListToUse, range[1][0]);
  1962. var endBool = endMark.mod(2) != startIndex;
  1963.  
  1964. var removeList = [];
  1965.  
  1966. if (startMark != endMark) {
  1967. //Note: If there is still an error, this would be it.
  1968. var biggerList = 0;
  1969. if (endMark == newListToUse.length) {
  1970. biggerList = 1;
  1971. }
  1972.  
  1973. for (var i = startMark; i < startMark + (endMark - startMark).mod(newListToUse.length + biggerList); i++) {
  1974. removeList.push((i).mod(newListToUse.length));
  1975. }
  1976. } else if (startMark < newListToUse.length && endMark < newListToUse.length) {
  1977. var startDist = (newListToUse[startMark][0] - range[0][0]).mod(360);
  1978. var endDist = (newListToUse[endMark][0] - range[1][0]).mod(360);
  1979.  
  1980. if (startDist < endDist) {
  1981. for (var i = 0; i < newListToUse.length; i++) {
  1982. removeList.push(i);
  1983. }
  1984. }
  1985. }
  1986.  
  1987. removeList.sort(function(a, b){return b-a;});
  1988.  
  1989. for (var i = 0; i < removeList.length; i++) {
  1990. newListToUse.splice(removeList[i], 1);
  1991. }
  1992.  
  1993. if (startBool) {
  1994. newListToUse.splice(this.getAngleIndex(newListToUse, range[0][0]), 0, range[0]);
  1995. }
  1996. if (endBool) {
  1997. newListToUse.splice(this.getAngleIndex(newListToUse, range[1][0]), 0, range[1]);
  1998. }
  1999.  
  2000. return newListToUse;
  2001. };
  2002.  
  2003. this.getAngleRange = function(blob1, blob2, index, radius) {
  2004. var angleStuff = this.getEdgeLinesFromPoint(blob1, blob2, radius);
  2005.  
  2006. var leftAngle = angleStuff[0];
  2007. var rightAngle = this.rangeToAngle(angleStuff);
  2008. var difference = angleStuff[1];
  2009.  
  2010. drawPoint(angleStuff[2][0], angleStuff[2][1], 3, "");
  2011. drawPoint(angleStuff[3][0], angleStuff[3][1], 3, "");
  2012.  
  2013. //console.log("Adding badAngles: " + leftAngle + ", " + rightAngle + " diff: " + difference);
  2014.  
  2015. var lineLeft = this.followAngle(leftAngle, blob1.x, blob1.y, 150 + blob1.size - index * 10);
  2016. var lineRight = this.followAngle(rightAngle, blob1.x, blob1.y, 150 + blob1.size - index * 10);
  2017.  
  2018. if (blob2.isVirus()) {
  2019. drawLine(blob1.x, blob1.y, lineLeft[0], lineLeft[1], 6);
  2020. drawLine(blob1.x, blob1.y, lineRight[0], lineRight[1], 6);
  2021. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob1.x, blob1.y, 6);
  2022. } else if(getCells().hasOwnProperty(blob2.id)) {
  2023. drawLine(blob1.x, blob1.y, lineLeft[0], lineLeft[1], 0);
  2024. drawLine(blob1.x, blob1.y, lineRight[0], lineRight[1], 0);
  2025. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob1.x, blob1.y, 0);
  2026. } else {
  2027. drawLine(blob1.x, blob1.y, lineLeft[0], lineLeft[1], 3);
  2028. drawLine(blob1.x, blob1.y, lineRight[0], lineRight[1], 3);
  2029. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob1.x, blob1.y, 3);
  2030. }
  2031.  
  2032. return [leftAngle, difference];
  2033. };
  2034.  
  2035. //Given a list of conditions, shift the angle to the closest available spot respecting the range given.
  2036. this.shiftAngle = function(listToUse, angle, range) {
  2037. //TODO: shiftAngle needs to respect the range! DONE?
  2038. for (var i = 0; i < listToUse.length; i++) {
  2039. if (this.angleIsWithin(angle, listToUse[i])) {
  2040. //console.log("Shifting needed!");
  2041.  
  2042. var angle1 = listToUse[i][0];
  2043. var angle2 = this.rangeToAngle(listToUse[i]);
  2044.  
  2045. var dist1 = (angle - angle1).mod(360);
  2046. var dist2 = (angle2 - angle).mod(360);
  2047.  
  2048. if (dist1 < dist2) {
  2049. if (this.angleIsWithin(angle1, range)) {
  2050. return angle1;
  2051. } else {
  2052. return angle2;
  2053. }
  2054. } else {
  2055. if (this.angleIsWithin(angle2, range)) {
  2056. return angle2;
  2057. } else {
  2058. return angle1;
  2059. }
  2060. }
  2061. }
  2062. }
  2063. //console.log("No Shifting Was needed!");
  2064. return angle;
  2065. };
  2066.  
  2067. /**
  2068. * This is the main bot logic. This is called quite often.
  2069. * @return A 2 dimensional array with coordinates for every cells. [[x, y], [x, y]]
  2070. */
  2071. this.mainLoop = function() {
  2072. var player = getPlayer();
  2073. var interNodes = getMemoryCells();
  2074.  
  2075. if ( /*!toggle*/ 1) {
  2076. //The following code converts the mouse position into an
  2077. //absolute game coordinate.
  2078. var useMouseX = screenToGameX(getMouseX());
  2079. var useMouseY = screenToGameY(getMouseY());
  2080. tempPoint = [useMouseX, useMouseY, 1];
  2081.  
  2082. //The current destination that the cells were going towards.
  2083. var tempMoveX = getPointX();
  2084. var tempMoveY = getPointY();
  2085.  
  2086. //This variable will be returned at the end.
  2087. //It will contain the destination choices for all the cells.
  2088. //BTW!!! ERROR ERROR ABORT MISSION!!!!!!! READ BELOW -----------
  2089. //
  2090. //SINCE IT'S STUPID NOW TO ASK EACH CELL WHERE THEY WANT TO GO,
  2091. //THE BOT SHOULD SIMPLY PICK ONE AND THAT'S IT, I MEAN WTF....
  2092. var destinationChoices = []; //destination, size, danger
  2093.  
  2094. //Just to make sure the player is alive.
  2095. if (player.length > 0) {
  2096.  
  2097. //Loop through all the player's cells.
  2098. for (var k = 0; k < player.length; k++) {
  2099. if (true) {
  2100. drawPoint(player[k].x, player[k].y + player[k].size, 0, "" + (getLastUpdate() - player[k].birth) + " / " + (30000 + (player[k].birthMass * 57) - (getLastUpdate() - player[k].birth)) + " / " + player[k].birthMass);
  2101. }
  2102. }
  2103.  
  2104.  
  2105. //Loops only for one cell for now.
  2106. for (var k = 0; /*k < player.length*/ k < 1; k++) {
  2107.  
  2108. //console.log("Working on blob: " + k);
  2109.  
  2110. drawCircle(player[k].x, player[k].y, player[k].size + this.splitDistance, 5);
  2111. //drawPoint(player[0].x, player[0].y - player[0].size, 3, "" + Math.floor(player[0].x) + ", " + Math.floor(player[0].y));
  2112.  
  2113. //var allDots = processEverything(interNodes);
  2114.  
  2115. //loop through everything that is on the screen and
  2116. //separate everything in it's own category.
  2117. var allIsAll = this.getAll(player[k]);
  2118.  
  2119. //The food stored in element 0 of allIsAll
  2120. var allPossibleFood = allIsAll[0];
  2121. //The threats are stored in element 1 of allIsAll
  2122. var allPossibleThreats = allIsAll[1];
  2123. //The viruses are stored in element 2 of allIsAll
  2124. var allPossibleViruses = allIsAll[2];
  2125.  
  2126. //The bot works by removing angles in which it is too
  2127. //dangerous to travel towards to.
  2128. var badAngles = [];
  2129. var obstacleList = [];
  2130.  
  2131. var isSafeSpot = true;
  2132. var isMouseSafe = true;
  2133.  
  2134. var clusterAllFood = this.clusterFood(allPossibleFood, player[k].size);
  2135.  
  2136. //console.log("Looking for enemies!");
  2137.  
  2138. //Loop through all the cells that were identified as threats.
  2139. for (var i = 0; i < allPossibleThreats.length; i++) {
  2140.  
  2141. var enemyDistance = this.computeDistanceFromCircleEdge(allPossibleThreats[i].x, allPossibleThreats[i].y, player[k].x, player[k].y, allPossibleThreats[i].size);
  2142.  
  2143. allPossibleThreats[i].enemyDist = enemyDistance;
  2144. }
  2145.  
  2146. /*allPossibleThreats.sort(function(a, b){
  2147. return a.enemyDist-b.enemyDist;
  2148. })*/
  2149.  
  2150. for (var i = 0; i < allPossibleThreats.length; i++) {
  2151.  
  2152. var enemyDistance = this.computeDistance(allPossibleThreats[i].x, allPossibleThreats[i].y, player[k].x, player[k].y);
  2153.  
  2154. var splitDangerDistance = allPossibleThreats[i].size + this.splitDistance + 150;
  2155.  
  2156. var normalDangerDistance = allPossibleThreats[i].size + 150;
  2157.  
  2158. var shiftDistance = player[k].size;
  2159.  
  2160. //console.log("Found distance.");
  2161.  
  2162. var enemyCanSplit = this.canSplit(player[k], allPossibleThreats[i]);
  2163. var secureDistance = (enemyCanSplit ? splitDangerDistance : normalDangerDistance);
  2164.  
  2165. for (var j = clusterAllFood.length - 1; j >= 0 ; j--) {
  2166. if (this.computeDistance(allPossibleThreats[i].x, allPossibleThreats[i].y, clusterAllFood[j][0], clusterAllFood[j][1]) < secureDistance + shiftDistance)
  2167. clusterAllFood.splice(j, 1);
  2168. }
  2169.  
  2170. //console.log("Removed some food.");
  2171.  
  2172. if (enemyCanSplit) {
  2173. drawCircle(allPossibleThreats[i].x, allPossibleThreats[i].y, splitDangerDistance, 0);
  2174. drawCircle(allPossibleThreats[i].x, allPossibleThreats[i].y, splitDangerDistance + shiftDistance, 6);
  2175. } else {
  2176. drawCircle(allPossibleThreats[i].x, allPossibleThreats[i].y, normalDangerDistance, 3);
  2177. drawCircle(allPossibleThreats[i].x, allPossibleThreats[i].y, normalDangerDistance + shiftDistance, 6);
  2178. }
  2179.  
  2180. if (allPossibleThreats[i].danger && getLastUpdate() - allPossibleThreats[i].dangerTimeOut > 1000) {
  2181.  
  2182. allPossibleThreats[i].danger = false;
  2183. }
  2184.  
  2185. /*if ((enemyCanSplit && enemyDistance < splitDangerDistance) ||
  2186. (!enemyCanSplit && enemyDistance < normalDangerDistance)) {
  2187.  
  2188. allPossibleThreats[i].danger = true;
  2189. allPossibleThreats[i].dangerTimeOut = f.getLastUpdate();
  2190. }*/
  2191.  
  2192. //console.log("Figured out who was important.");
  2193.  
  2194. if ((enemyCanSplit && enemyDistance < splitDangerDistance) || (enemyCanSplit && allPossibleThreats[i].danger)) {
  2195.  
  2196. badAngles.push(this.getAngleRange(player[k], allPossibleThreats[i], i, splitDangerDistance).concat(allPossibleThreats[i].enemyDist));
  2197.  
  2198. } else if ((!enemyCanSplit && enemyDistance < normalDangerDistance) || (!enemyCanSplit && allPossibleThreats[i].danger)) {
  2199.  
  2200. badAngles.push(this.getAngleRange(player[k], allPossibleThreats[i], i, normalDangerDistance).concat(allPossibleThreats[i].enemyDist));
  2201.  
  2202. } else if (enemyCanSplit && enemyDistance < splitDangerDistance + shiftDistance) {
  2203. var tempOb = this.getAngleRange(player[k], allPossibleThreats[i], i, splitDangerDistance + shiftDistance);
  2204. var angle1 = tempOb[0];
  2205. var angle2 = this.rangeToAngle(tempOb);
  2206.  
  2207. obstacleList.push([[angle1, true], [angle2, false]]);
  2208. } else if (!enemyCanSplit && enemyDistance < normalDangerDistance + shiftDistance) {
  2209. var tempOb = this.getAngleRange(player[k], allPossibleThreats[i], i, normalDangerDistance + shiftDistance);
  2210. var angle1 = tempOb[0];
  2211. var angle2 = this.rangeToAngle(tempOb);
  2212.  
  2213. obstacleList.push([[angle1, true], [angle2, false]]);
  2214. }
  2215. //console.log("Done with enemy: " + i);
  2216. }
  2217.  
  2218. //console.log("Done looking for enemies!");
  2219.  
  2220. var goodAngles = [];
  2221. var stupidList = [];
  2222.  
  2223. for (var i = 0; i < allPossibleViruses.length; i++) {
  2224. if (player[k].size < allPossibleViruses[i].size) {
  2225. drawCircle(allPossibleViruses[i].x, allPossibleViruses[i].y, allPossibleViruses[i].size + 10, 3);
  2226. drawCircle(allPossibleViruses[i].x, allPossibleViruses[i].y, allPossibleViruses[i].size * 2, 6);
  2227.  
  2228. } else {
  2229. drawCircle(allPossibleViruses[i].x, allPossibleViruses[i].y, player[k].size + 50, 3);
  2230. drawCircle(allPossibleViruses[i].x, allPossibleViruses[i].y, player[k].size * 2, 6);
  2231. }
  2232. }
  2233.  
  2234. for (var i = 0; i < allPossibleViruses.length; i++) {
  2235. var virusDistance = this.computeDistance(allPossibleViruses[i].x, allPossibleViruses[i].y, player[k].x, player[k].y);
  2236. if (player[k].size < allPossibleViruses[i].size) {
  2237. if (virusDistance < (allPossibleViruses[i].size * 2)) {
  2238. var tempOb = this.getAngleRange(player[k], allPossibleViruses[i], i, allPossibleViruses[i].size + 10);
  2239. var angle1 = tempOb[0];
  2240. var angle2 = this.rangeToAngle(tempOb);
  2241. obstacleList.push([[angle1, true], [angle2, false]]);
  2242. }
  2243. } else {
  2244. if (virusDistance < (player[k].size * 2)) {
  2245. var tempOb = this.getAngleRange(player[k], allPossibleViruses[i], i, player[k].size + 50);
  2246. var angle1 = tempOb[0];
  2247. var angle2 = this.rangeToAngle(tempOb);
  2248. obstacleList.push([[angle1, true], [angle2, false]]);
  2249. }
  2250. }
  2251. }
  2252.  
  2253. if (badAngles.length > 0) {
  2254. //NOTE: This is only bandaid wall code. It's not the best way to do it.
  2255. stupidList = this.addWall(stupidList, player[k]);
  2256. }
  2257.  
  2258. for (var i = 0; i < badAngles.length; i++) {
  2259. var angle1 = badAngles[i][0];
  2260. var angle2 = this.rangeToAngle(badAngles[i]);
  2261. stupidList.push([[angle1, true], [angle2, false], badAngles[i][2]]);
  2262. }
  2263.  
  2264. //stupidList.push([[45, true], [135, false]]);
  2265. //stupidList.push([[10, true], [200, false]]);
  2266.  
  2267. stupidList.sort(function(a, b){
  2268. //console.log("Distance: " + a[2] + ", " + b[2]);
  2269. return a[2]-b[2];
  2270. });
  2271.  
  2272. //console.log("Added random noob stuff.");
  2273.  
  2274. var sortedInterList = [];
  2275. var sortedObList = [];
  2276.  
  2277. for (var i = 0; i < stupidList.length; i++) {
  2278. //console.log("Adding to sorted: " + stupidList[i][0][0] + ", " + stupidList[i][1][0]);
  2279. var tempList = this.addAngle(sortedInterList, stupidList[i]);
  2280.  
  2281. if (tempList.length == 0) {
  2282. console.log("MAYDAY IT'S HAPPENING!");
  2283. break;
  2284. } else {
  2285. sortedInterList = tempList;
  2286. }
  2287. }
  2288.  
  2289. for (var i = 0; i < obstacleList.length; i++) {
  2290. sortedObList = this.addAngle(sortedObList, obstacleList[i]);
  2291.  
  2292. if (sortedObList.length == 0) {
  2293. break;
  2294. }
  2295. }
  2296.  
  2297. var offsetI = 0;
  2298. var obOffsetI = 1;
  2299.  
  2300. if (sortedInterList.length > 0 && sortedInterList[0][1]) {
  2301. offsetI = 1;
  2302. }
  2303. if (sortedObList.length > 0 && sortedObList[0][1]) {
  2304. obOffsetI = 0;
  2305. }
  2306.  
  2307. var goodAngles = [];
  2308. var obstacleAngles = [];
  2309.  
  2310. for (var i = 0; i < sortedInterList.length; i += 2) {
  2311. var angle1 = sortedInterList[(i + offsetI).mod(sortedInterList.length)][0];
  2312. var angle2 = sortedInterList[(i + 1 + offsetI).mod(sortedInterList.length)][0];
  2313. var diff = (angle2 - angle1).mod(360);
  2314. goodAngles.push([angle1, diff]);
  2315. }
  2316.  
  2317. for (var i = 0; i < sortedObList.length; i += 2) {
  2318. var angle1 = sortedObList[(i + obOffsetI).mod(sortedObList.length)][0];
  2319. var angle2 = sortedObList[(i + 1 + obOffsetI).mod(sortedObList.length)][0];
  2320. var diff = (angle2 - angle1).mod(360);
  2321. obstacleAngles.push([angle1, diff]);
  2322. }
  2323.  
  2324. for (var i = 0; i < goodAngles.length; i++) {
  2325. var line1 = this.followAngle(goodAngles[i][0], player[k].x, player[k].y, 100 + player[k].size);
  2326. var line2 = this.followAngle((goodAngles[i][0] + goodAngles[i][1]).mod(360), player[k].x, player[k].y, 100 + player[k].size);
  2327. drawLine(player[k].x, player[k].y, line1[0], line1[1], 1);
  2328. drawLine(player[k].x, player[k].y, line2[0], line2[1], 1);
  2329.  
  2330. drawArc(line1[0], line1[1], line2[0], line2[1], player[k].x, player[k].y, 1);
  2331.  
  2332. //drawPoint(player[0].x, player[0].y, 2, "");
  2333.  
  2334. drawPoint(line1[0], line1[1], 0, "" + i + ": 0");
  2335. drawPoint(line2[0], line2[1], 0, "" + i + ": 1");
  2336. }
  2337.  
  2338. for (var i = 0; i < obstacleAngles.length; i++) {
  2339. var line1 = this.followAngle(obstacleAngles[i][0], player[k].x, player[k].y, 50 + player[k].size);
  2340. var line2 = this.followAngle((obstacleAngles[i][0] + obstacleAngles[i][1]).mod(360), player[k].x, player[k].y, 50 + player[k].size);
  2341. drawLine(player[k].x, player[k].y, line1[0], line1[1], 6);
  2342. drawLine(player[k].x, player[k].y, line2[0], line2[1], 6);
  2343.  
  2344. drawArc(line1[0], line1[1], line2[0], line2[1], player[k].x, player[k].y, 6);
  2345.  
  2346. //drawPoint(player[0].x, player[0].y, 2, "");
  2347.  
  2348. drawPoint(line1[0], line1[1], 0, "" + i + ": 0");
  2349. drawPoint(line2[0], line2[1], 0, "" + i + ": 1");
  2350. }
  2351.  
  2352. if (this.toggleFollow && goodAngles.length == 0) {
  2353. //This is the follow the mouse mode
  2354. var distance = this.computeDistance(player[k].x, player[k].y, tempPoint[0], tempPoint[1]);
  2355.  
  2356. var shiftedAngle = this.shiftAngle(obstacleAngles, this.getAngle(tempPoint[0], tempPoint[1], player[k].x, player[k].y), [0, 360]);
  2357.  
  2358. var destination = this.followAngle(shiftedAngle, player[k].x, player[k].y, distance);
  2359.  
  2360. destinationChoices = destination;
  2361. drawLine(player[k].x, player[k].y, destination[0], destination[1], 1);
  2362. //tempMoveX = destination[0];
  2363. //tempMoveY = destination[1];
  2364.  
  2365. } else if (goodAngles.length > 0) {
  2366. var bIndex = goodAngles[0];
  2367. var biggest = goodAngles[0][1];
  2368. for (var i = 1; i < goodAngles.length; i++) {
  2369. var size = goodAngles[i][1];
  2370. if (size > biggest) {
  2371. biggest = size;
  2372. bIndex = goodAngles[i];
  2373. }
  2374. }
  2375. var perfectAngle = (bIndex[0] + bIndex[1] / 2).mod(360);
  2376.  
  2377. perfectAngle = this.shiftAngle(obstacleAngles, perfectAngle, bIndex);
  2378.  
  2379. var line1 = this.followAngle(perfectAngle, player[k].x, player[k].y, verticalDistance());
  2380.  
  2381. destinationChoices = line1;
  2382. drawLine(player[k].x, player[k].y, line1[0], line1[1], 7);
  2383. //tempMoveX = line1[0];
  2384. //tempMoveY = line1[1];
  2385. } else if (badAngles.length > 0 && goodAngles == 0) {
  2386. //When there are enemies around but no good angles
  2387. //You're likely screwed. (This should never happen.)
  2388.  
  2389. console.log("Failed");
  2390. destinationChoices = [tempMoveX, tempMoveY];
  2391. /*var angleWeights = [] //Put weights on the angles according to enemy distance
  2392. for (var i = 0; i < allPossibleThreats.length; i++){
  2393. var dist = this.computeDistance(player[k].x, player[k].y, allPossibleThreats[i].x, allPossibleThreats[i].y);
  2394. var angle = this.getAngle(allPossibleThreats[i].x, allPossibleThreats[i].y, player[k].x, player[k].y);
  2395. angleWeights.push([angle,dist]);
  2396. }
  2397. var maxDist = 0;
  2398. var finalAngle = 0;
  2399. for (var i = 0; i < angleWeights.length; i++){
  2400. if (angleWeights[i][1] > maxDist){
  2401. maxDist = angleWeights[i][1];
  2402. finalAngle = (angleWeights[i][0] + 180).mod(360);
  2403. }
  2404. }
  2405. var line1 = this.followAngle(finalAngle,player[k].x,player[k].y,f.verticalDistance());
  2406. drawLine(player[k].x, player[k].y, line1[0], line1[1], 2);
  2407. destinationChoices.push(line1);*/
  2408. } else if (clusterAllFood.length > 0) {
  2409. for (var i = 0; i < clusterAllFood.length; i++) {
  2410. //console.log("mefore: " + clusterAllFood[i][2]);
  2411. //This is the cost function. Higher is better.
  2412.  
  2413. var clusterAngle = this.getAngle(clusterAllFood[i][0], clusterAllFood[i][1], player[k].x, player[k].y);
  2414.  
  2415. clusterAllFood[i][2] = clusterAllFood[i][2] * 6 - this.computeDistance(clusterAllFood[i][0], clusterAllFood[i][1], player[k].x, player[k].y);
  2416. //console.log("Current Value: " + clusterAllFood[i][2]);
  2417.  
  2418. //(goodAngles[bIndex][1] / 2 - (Math.abs(perfectAngle - clusterAngle)));
  2419.  
  2420. clusterAllFood[i][3] = clusterAngle;
  2421.  
  2422. drawPoint(clusterAllFood[i][0], clusterAllFood[i][1], 1, "");
  2423. //console.log("After: " + clusterAllFood[i][2]);
  2424. }
  2425.  
  2426. var bestFoodI = 0;
  2427. var bestFood = clusterAllFood[0][2];
  2428. for (var i = 1; i < clusterAllFood.length; i++) {
  2429. if (bestFood < clusterAllFood[i][2]) {
  2430. bestFood = clusterAllFood[i][2];
  2431. bestFoodI = i;
  2432. }
  2433. }
  2434.  
  2435. //console.log("Best Value: " + clusterAllFood[bestFoodI][2]);
  2436.  
  2437. var distance = this.computeDistance(player[k].x, player[k].y, clusterAllFood[bestFoodI][0], clusterAllFood[bestFoodI][1]);
  2438.  
  2439. var shiftedAngle = this.shiftAngle(obstacleAngles, this.getAngle(clusterAllFood[bestFoodI][0], clusterAllFood[bestFoodI][1], player[k].x, player[k].y), [0, 360]);
  2440.  
  2441. var destination = this.followAngle(shiftedAngle, player[k].x, player[k].y, distance);
  2442.  
  2443. destinationChoices = destination;
  2444. //tempMoveX = destination[0];
  2445. //tempMoveY = destination[1];
  2446. drawLine(player[k].x, player[k].y, destination[0], destination[1], 1);
  2447. } else {
  2448. //If there are no enemies around and no food to eat.
  2449. destinationChoices = [tempMoveX, tempMoveY];
  2450. }
  2451.  
  2452. drawPoint(tempPoint[0], tempPoint[1], tempPoint[2], "");
  2453. //drawPoint(tempPoint[0], tempPoint[1], tempPoint[2], "" + Math.floor(this.computeDistance(tempPoint[0], tempPoint[1], I, J)));
  2454. //drawLine(tempPoint[0], tempPoint[1], player[0].x, player[0].y, 6);
  2455. //console.log("Slope: " + slope(tempPoint[0], tempPoint[1], player[0].x, player[0].y) + " Angle: " + getAngle(tempPoint[0], tempPoint[1], player[0].x, player[0].y) + " Side: " + (getAngle(tempPoint[0], tempPoint[1], player[0].x, player[0].y) - 90).mod(360));
  2456. tempPoint[2] = 1;
  2457.  
  2458. //console.log("Done working on blob: " + i);
  2459. }
  2460.  
  2461. //TODO: Find where to go based on destinationChoices.
  2462. /*var dangerFound = false;
  2463. for (var i = 0; i < destinationChoices.length; i++) {
  2464. if (destinationChoices[i][2]) {
  2465. dangerFound = true;
  2466. break;
  2467. }
  2468. }
  2469.  
  2470. destinationChoices.sort(function(a, b){return b[1] - a[1]});
  2471.  
  2472. if (dangerFound) {
  2473. for (var i = 0; i < destinationChoices.length; i++) {
  2474. if (destinationChoices[i][2]) {
  2475. tempMoveX = destinationChoices[i][0][0];
  2476. tempMoveY = destinationChoices[i][0][1];
  2477. break;
  2478. }
  2479. }
  2480. } else {
  2481. tempMoveX = destinationChoices.peek()[0][0];
  2482. tempMoveY = destinationChoices.peek()[0][1];
  2483. //console.log("Done " + tempMoveX + ", " + tempMoveY);
  2484. }*/
  2485. }
  2486. //console.log("MOVING RIGHT NOW!");
  2487.  
  2488. //console.log("______Never lied ever in my life.");
  2489.  
  2490. return destinationChoices;
  2491. }
  2492. };
  2493. };
  2494. window.botList.push(new AposBot());
  2495.  
  2496. window.updateBotList(); //This function might not exist yet.
  2497.  
  2498. /*The MIT License (MIT)
  2499. Copyright (c) 2015 Apostolique
  2500. Permission is hereby granted, free of charge, to any person obtaining a copy
  2501. of this software and associated documentation files (the "Software"), to deal
  2502. in the Software without restriction, including without limitation the rights
  2503. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  2504. copies of the Software, and to permit persons to whom the Software is
  2505. furnished to do so, subject to the following conditions:
  2506. The above copyright notice and this permission notice shall be included in all
  2507. copies or substantial portions of the Software.
  2508. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  2509. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  2510. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  2511. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  2512. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  2513. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  2514. SOFTWARE.*/
  2515. // ==UserScript==
  2516. // @name AposLauncher
  2517. // @namespace AposLauncher
  2518. // @include http://agar.io/*
  2519. // @version 4.13
  2520. // @grant none
  2521. // @author http://www.twitch.tv/apostolique
  2522. // ==/UserScript==
  2523. var aposLauncherVersion = 4.13;
  2524.  
  2525. Number.prototype.mod = function(n) {
  2526. return ((this % n) + n) % n;
  2527. };
  2528.  
  2529. Array.prototype.peek = function() {
  2530. return this[this.length - 1];
  2531. };
  2532.  
  2533. var sha = "efde0488cc2cc176db48dd23b28a20b90314352b";
  2534.  
  2535. function getLatestCommit() {
  2536. window.jQuery.ajax({
  2537. url: "https://api.github.com/repos/apostolique/Agar.io-bot/git/refs/heads/master",
  2538. cache: false,
  2539. dataType: "jsonp"
  2540. }).done(function(data) {
  2541. console.dir(data.data);
  2542. console.log("hmm: " + data.data.object.sha);
  2543. sha = data.data.object.sha;
  2544.  
  2545. function update(prefix, name, url) {
  2546. window.jQuery(document.body).prepend("<div id='" + prefix + "Dialog' style='position: absolute; left: 0px; right: 0px; top: 0px; bottom: 0px; z-index: 100; display: none;'>");
  2547. window.jQuery('#' + prefix + 'Dialog').append("<div id='" + prefix + "Message' style='width: 350px; background-color: #FFFFFF; margin: 100px auto; border-radius: 15px; padding: 5px 15px 5px 15px;'>");
  2548. window.jQuery('#' + prefix + 'Message').append("<h2>UPDATE TIME!!!</h2>");
  2549. window.jQuery('#' + prefix + 'Message').append("<p>Grab the update for: <a id='" + prefix + "Link' href='" + url + "' target=\"_blank\">" + name + "</a></p>");
  2550. window.jQuery('#' + prefix + 'Link').on('click', function() {
  2551. window.jQuery("#" + prefix + "Dialog").hide();
  2552. window.jQuery("#" + prefix + "Dialog").remove();
  2553. });
  2554. window.jQuery("#" + prefix + "Dialog").show();
  2555. }
  2556.  
  2557. window.jQuery.get('https://raw.githubusercontent.com/Apostolique/Agar.io-bot/master/launcher.user.js?' + Math.floor((Math.random() * 1000000) + 1), function(data) {
  2558. var latestVersion = data.replace(/(\r\n|\n|\r)/gm, "");
  2559. latestVersion = latestVersion.substring(latestVersion.indexOf("// @version") + 11, latestVersion.indexOf("// @grant"));
  2560.  
  2561. latestVersion = parseFloat(latestVersion + 0.0000);
  2562. var myVersion = parseFloat(aposLauncherVersion + 0.0000);
  2563.  
  2564. if (latestVersion > myVersion) {
  2565. update("aposLauncher", "launcher.user.js", "https://github.com/Apostolique/Agar.io-bot/blob/" + sha + "/launcher.user.js/");
  2566. }
  2567. console.log('Current launcher.user.js Version: ' + myVersion + " on Github: " + latestVersion);
  2568. });
  2569.  
  2570. }).fail(function() {});
  2571. }
  2572. getLatestCommit();
  2573.  
  2574. console.log("Running Bot Launcher!");
  2575. (function(d, e) {
  2576.  
  2577. //UPDATE
  2578. function keyAction(e) {
  2579. if (84 == e.keyCode) {
  2580. console.log("Toggle");
  2581. toggle = !toggle;
  2582. }
  2583. if (82 == e.keyCode) {
  2584. console.log("ToggleDraw");
  2585. toggleDraw = !toggleDraw;
  2586. }
  2587. if (68 == e.keyCode) {
  2588. window.setDarkTheme(!getDarkBool());
  2589. }
  2590. if (70 == e.keyCode) {
  2591. window.setShowMass(!getMassBool());
  2592. }
  2593. if (69 == e.keyCode) {
  2594. if (message.length > 0) {
  2595. window.setMessage([]);
  2596. window.onmouseup = function() {};
  2597. window.ignoreStream = true;
  2598. } else {
  2599. window.ignoreStream = false;
  2600. window.refreshTwitch();
  2601. }
  2602. }
  2603. window.botList[botIndex].keyAction(e);
  2604. }
  2605.  
  2606. function humanPlayer() {
  2607. //Don't need to do anything.
  2608. return [getPointX(), getPointY()];
  2609. }
  2610.  
  2611.  
  2612.  
  2613. function pb() {
  2614.  
  2615. //UPDATE
  2616.  
  2617. window.botList = window.botList || [];
  2618.  
  2619. window.jQuery('#nick').val(originalName);
  2620.  
  2621. function HumanPlayerObject() {
  2622. this.name = "Human";
  2623. this.keyAction = function(key) {};
  2624. this.displayText = function() {
  2625. return [];
  2626. };
  2627. this.mainLoop = humanPlayer;
  2628. }
  2629.  
  2630. var hpo = new HumanPlayerObject();
  2631.  
  2632. window.botList.push(hpo);
  2633.  
  2634. window.updateBotList();
  2635.  
  2636. ya = !0;
  2637. Pa();
  2638. setInterval(Pa, 18E4);
  2639.  
  2640. var father = window.jQuery("#canvas").parent();
  2641. window.jQuery("#canvas").remove();
  2642. father.prepend("<canvas id='canvas'>");
  2643.  
  2644. G = za = document.getElementById("canvas");
  2645. f = G.getContext("2d");
  2646. G.onmousedown = function(a) {
  2647. if (Qa) {
  2648. var b = a.clientX - (5 + m / 5 / 2),
  2649. c = a.clientY - (5 + m / 5 / 2);
  2650. if (Math.sqrt(b * b + c * c) <= m / 5 / 2) {
  2651. V();
  2652. H(17);
  2653. return
  2654. }
  2655. }
  2656. fa = a.clientX;
  2657. ga = a.clientY;
  2658. Aa();
  2659. V();
  2660. };
  2661. G.onmousemove = function(a) {
  2662. fa = a.clientX;
  2663. ga = a.clientY;
  2664. Aa();
  2665. };
  2666. G.onmouseup = function() {};
  2667. /firefox/i.test(navigator.userAgent) ? document.addEventListener("DOMMouseScroll", Ra, !1) : document.body.onmousewheel = Ra;
  2668. var a = !1,
  2669. b = !1,
  2670. c = !1;
  2671. d.onkeydown = function(l) {
  2672. //UPDATE
  2673. if (!window.jQuery('#nick').is(":focus")) {
  2674. 32 != l.keyCode || a || (V(), H(17), a = !0);
  2675. 81 != l.keyCode || b || (H(18), b = !0);
  2676. 87 != l.keyCode || c || (V(), H(21), c = !0);
  2677. 27 == l.keyCode && Sa(!0);
  2678.  
  2679. //UPDATE
  2680. keyAction(l);
  2681. }
  2682. };
  2683. d.onkeyup = function(l) {
  2684. 32 == l.keyCode && (a = !1);
  2685. 87 == l.keyCode && (c = !1);
  2686. 81 == l.keyCode && b && (H(19), b = !1);
  2687. };
  2688. d.onblur = function() {
  2689. H(19);
  2690. c = b = a = !1
  2691. };
  2692. d.onresize = Ta;
  2693. d.requestAnimationFrame(Ua);
  2694. setInterval(V, 40);
  2695. y && e("#region").val(y);
  2696. Va();
  2697. ha(e("#region").val());
  2698. 0 == Ba && y && I();
  2699. W = !0;
  2700. e("#overlays").show();
  2701. Ta();
  2702. d.location.hash && 6 <= d.location.hash.length && Wa(d.location.hash)
  2703. }
  2704.  
  2705. function Ra(a) {
  2706. J *= Math.pow(.9, a.wheelDelta / -120 || a.detail || 0);
  2707. //UPDATE
  2708. 0.07 > J && (J = 0.07);
  2709. J > 4 / h && (J = 4 / h)
  2710. }
  2711.  
  2712. function qb() {
  2713. if (.4 > h) X = null;
  2714. else {
  2715. for (var a = Number.POSITIVE_INFINITY, b = Number.POSITIVE_INFINITY, c = Number.NEGATIVE_INFINITY, l = Number.NEGATIVE_INFINITY, d = 0, p = 0; p < v.length; p++) {
  2716. var g = v[p];
  2717. !g.N() || g.R || 20 >= g.size * h || (d = Math.max(g.size, d), a = Math.min(g.x, a), b = Math.min(g.y, b), c = Math.max(g.x, c), l = Math.max(g.y, l))
  2718. }
  2719. X = rb.ka({
  2720. ca: a - 10,
  2721. da: b - 10,
  2722. oa: c + 10,
  2723. pa: l + 10,
  2724. ma: 2,
  2725. na: 4
  2726. });
  2727. for (p = 0; p < v.length; p++)
  2728. if (g = v[p],
  2729. g.N() && !(20 >= g.size * h))
  2730. for (a = 0; a < g.a.length; ++a) b = g.a[a].x, c = g.a[a].y, b < s - m / 2 / h || c < t - r / 2 / h || b > s + m / 2 / h || c > t + r / 2 / h || X.m(g.a[a])
  2731. }
  2732. }
  2733.  
  2734. function Aa() {
  2735. //UPDATE
  2736. if (toggle || window.botList[botIndex].name == "Human") {
  2737. setPoint(((fa - m / 2) / h + s), ((ga - r / 2) / h + t));
  2738. }
  2739. }
  2740.  
  2741. function Pa() {
  2742. null == ka && (ka = {}, e("#region").children().each(function() {
  2743. var a = e(this),
  2744. b = a.val();
  2745. b && (ka[b] = a.text())
  2746. }));
  2747. e.get(ap + "info", function(a) {
  2748. var b = {},
  2749. c;
  2750. for (c in a.regions) {
  2751. var l = c.split(":")[0];
  2752. b[l] = b[l] || 0;
  2753. b[l] += a.regions[c].numPlayers
  2754. }
  2755. for (c in b) e('#region option[value="' + c + '"]').text(ka[c] + " (" + b[c] + " players)")
  2756. },
  2757. "json")
  2758. }
  2759.  
  2760. function Xa() {
  2761. e("#adsBottom").hide();
  2762. e("#overlays").hide();
  2763. W = !1;
  2764. Va();
  2765. d.googletag && d.googletag.pubads && d.googletag.pubads().clear(d.aa)
  2766. }
  2767.  
  2768. function ha(a) {
  2769. a && a != y && (e("#region").val() != a && e("#region").val(a), y = d.localStorage.location = a, e(".region-message").hide(), e(".region-message." + a).show(), e(".btn-needs-server").prop("disabled", !1), ya && I())
  2770. }
  2771.  
  2772. function Sa(a) {
  2773. W || (K = null, sb(), a && (x = 1), W = !0, e("#overlays").fadeIn(a ? 200 : 3E3))
  2774. }
  2775.  
  2776. function Y(a) {
  2777. e("#helloContainer").attr("data-gamemode", a);
  2778. P = a;
  2779. e("#gamemode").val(a)
  2780. }
  2781.  
  2782. function Va() {
  2783. e("#region").val() ? d.localStorage.location = e("#region").val() : d.localStorage.location && e("#region").val(d.localStorage.location);
  2784. e("#region").val() ? e("#locationKnown").append(e("#region")) : e("#locationUnknown").append(e("#region"))
  2785. }
  2786.  
  2787. function sb() {
  2788. la && (la = !1, setTimeout(function() {
  2789. la = !0
  2790. //UPDATE
  2791. }, 6E4 * Ya))
  2792. }
  2793.  
  2794. function Z(a) {
  2795. return d.i18n[a] || d.i18n_dict.en[a] || a
  2796. }
  2797.  
  2798. function Za() {
  2799. var a = ++Ba;
  2800. console.log("Find " + y + P);
  2801. e.ajax(ap + "findServer", {
  2802. error: function() {
  2803. setTimeout(Za, 1E3)
  2804. },
  2805. success: function(b) {
  2806. a == Ba && (b.alert && alert(b.alert), Ca("ws://" + b.ip, b.token))
  2807. },
  2808. dataType: "json",
  2809. method: "POST",
  2810. cache: !1,
  2811. crossDomain: !0,
  2812. data: (y + P || "?") + "\n154669603"
  2813. })
  2814. }
  2815.  
  2816. function I() {
  2817. ya && y && (e("#connecting").show(), Za())
  2818. }
  2819.  
  2820. function Ca(a, b) {
  2821. if (q) {
  2822. q.onopen = null;
  2823. q.onmessage = null;
  2824. q.onclose = null;
  2825. try {
  2826. q.close()
  2827. } catch (c) {}
  2828. q = null
  2829. }
  2830. Da.ip && (a = "ws://" + Da.ip);
  2831. if (null != L) {
  2832. var l = L;
  2833. L = function() {
  2834. l(b)
  2835. }
  2836. }
  2837. if (tb) {
  2838. var d = a.split(":");
  2839. a = d[0] + "s://ip-" + d[1].replace(/\./g, "-").replace(/\//g, "") + ".tech.agar.io:" + +d[2]
  2840. }
  2841. M = [];
  2842. k = [];
  2843. E = {};
  2844. v = [];
  2845. Q = [];
  2846. F = [];
  2847. z = A = null;
  2848. R = 0;
  2849. $ = !1;
  2850. console.log("Connecting to " + a);
  2851. //UPDATE
  2852. serverIP = a;
  2853. q = new WebSocket(a);
  2854. q.binaryType = "arraybuffer";
  2855. q.onopen = function() {
  2856. var a;
  2857. console.log("socket open");
  2858. a = N(5);
  2859. a.setUint8(0, 254);
  2860. a.setUint32(1, 5, !0);
  2861. O(a);
  2862. a = N(5);
  2863. a.setUint8(0, 255);
  2864. a.setUint32(1, 154669603, !0);
  2865. O(a);
  2866. a = N(1 + b.length);
  2867. a.setUint8(0, 80);
  2868. for (var c = 0; c < b.length; ++c) a.setUint8(c + 1, b.charCodeAt(c));
  2869. O(a);
  2870. $a()
  2871. };
  2872. q.onmessage = ub;
  2873. q.onclose = vb;
  2874. q.onerror = function() {
  2875. console.log("socket error")
  2876. }
  2877. }
  2878.  
  2879. function N(a) {
  2880. return new DataView(new ArrayBuffer(a))
  2881. }
  2882.  
  2883. function O(a) {
  2884. q.send(a.buffer)
  2885. }
  2886.  
  2887. function vb() {
  2888. $ && (ma = 500);
  2889. console.log("socket close");
  2890. setTimeout(I, ma);
  2891. ma *= 2
  2892. }
  2893.  
  2894. function ub(a) {
  2895. wb(new DataView(a.data))
  2896. }
  2897.  
  2898. function wb(a) {
  2899. function b() {
  2900. for (var b = "";;) {
  2901. var d = a.getUint16(c, !0);
  2902. c += 2;
  2903. if (0 == d) break;
  2904. b += String.fromCharCode(d)
  2905. }
  2906. return b
  2907. }
  2908. var c = 0;
  2909. 240 == a.getUint8(c) && (c += 5);
  2910. switch (a.getUint8(c++)) {
  2911. case 16:
  2912. xb(a, c);
  2913. break;
  2914. case 17:
  2915. aa = a.getFloat32(c, !0);
  2916. c += 4;
  2917. ba = a.getFloat32(c, !0);
  2918. c += 4;
  2919. ca = a.getFloat32(c, !0);
  2920. c += 4;
  2921. break;
  2922. case 20:
  2923. k = [];
  2924. M = [];
  2925. break;
  2926. case 21:
  2927. Ea = a.getInt16(c, !0);
  2928. c += 2;
  2929. Fa = a.getInt16(c, !0);
  2930. c += 2;
  2931. Ga || (Ga = !0, na = Ea, oa = Fa);
  2932. break;
  2933. case 32:
  2934. M.push(a.getUint32(c, !0));
  2935. c += 4;
  2936. break;
  2937. case 49:
  2938. if (null != A) break;
  2939. var l = a.getUint32(c, !0),
  2940. c = c + 4;
  2941. F = [];
  2942. for (var d = 0; d < l; ++d) {
  2943. var p = a.getUint32(c, !0),
  2944. c = c + 4;
  2945. F.push({
  2946. id: p,
  2947. name: b()
  2948. })
  2949. }
  2950. ab();
  2951. break;
  2952. case 50:
  2953. A = [];
  2954. l = a.getUint32(c, !0);
  2955. c += 4;
  2956. for (d = 0; d < l; ++d) A.push(a.getFloat32(c, !0)), c += 4;
  2957. ab();
  2958. break;
  2959. case 64:
  2960. pa = a.getFloat64(c, !0);
  2961. c += 8;
  2962. qa = a.getFloat64(c, !0);
  2963. c += 8;
  2964. ra = a.getFloat64(c, !0);
  2965. c += 8;
  2966. sa = a.getFloat64(c, !0);
  2967. c += 8;
  2968. aa = (ra + pa) / 2;
  2969. ba = (sa + qa) / 2;
  2970. ca = 1;
  2971. 0 == k.length && (s = aa, t = ba, h = ca);
  2972. break;
  2973. case 81:
  2974. var g = a.getUint32(c, !0),
  2975. c = c + 4,
  2976. e = a.getUint32(c, !0),
  2977. c = c + 4,
  2978. f = a.getUint32(c, !0),
  2979. c = c + 4;
  2980. setTimeout(function() {
  2981. S({
  2982. e: g,
  2983. f: e,
  2984. d: f
  2985. })
  2986. }, 1200)
  2987. }
  2988. }
  2989.  
  2990. function xb(a, b) {
  2991. bb = C = Date.now();
  2992. $ || ($ = !0, e("#connecting").hide(), cb(), L && (L(), L = null));
  2993. var c = Math.random();
  2994. Ha = !1;
  2995. var d = a.getUint16(b, !0);
  2996. b += 2;
  2997. for (var u = 0; u < d; ++u) {
  2998. var p = E[a.getUint32(b, !0)],
  2999. g = E[a.getUint32(b + 4, !0)];
  3000. b += 8;
  3001. p && g && (g.X(), g.s = g.x, g.t = g.y, g.r = g.size, g.J = p.x, g.K = p.y, g.q = g.size, g.Q =
  3002. C)
  3003. }
  3004. for (u = 0;;) {
  3005. d = a.getUint32(b, !0);
  3006. b += 4;
  3007. if (0 == d) break;
  3008. ++u;
  3009. var f, p = a.getInt16(b, !0);
  3010. b += 4;
  3011. g = a.getInt16(b, !0);
  3012. b += 4;
  3013. f = a.getInt16(b, !0);
  3014. b += 2;
  3015. for (var h = a.getUint8(b++), w = a.getUint8(b++), m = a.getUint8(b++), h = (h << 16 | w << 8 | m).toString(16); 6 > h.length;) h = "0" + h;
  3016. var h = "#" + h,
  3017. w = a.getUint8(b++),
  3018. m = !!(w & 1),
  3019. r = !!(w & 16);
  3020. w & 2 && (b += 4);
  3021. w & 4 && (b += 8);
  3022. w & 8 && (b += 16);
  3023. for (var q, n = "";;) {
  3024. q = a.getUint16(b, !0);
  3025. b += 2;
  3026. if (0 == q) break;
  3027. n += String.fromCharCode(q)
  3028. }
  3029. q = n;
  3030. n = null;
  3031. E.hasOwnProperty(d) ? (n = E[d], n.P(), n.s = n.x, n.t = n.y, n.r = n.size, n.color = h) :
  3032. (n = new da(d, p, g, f, h, q), v.push(n), E[d] = n, n.ua = p, n.va = g);
  3033. n.h = m;
  3034. n.n = r;
  3035. n.J = p;
  3036. n.K = g;
  3037. n.q = f;
  3038. n.sa = c;
  3039. n.Q = C;
  3040. n.ba = w;
  3041. q && n.B(q); - 1 != M.indexOf(d) && -1 == k.indexOf(n) && (document.getElementById("overlays").style.display = "none", k.push(n), n.birth = getLastUpdate(), n.birthMass = (n.size * n.size / 100), 1 == k.length && (s = n.x, t = n.y, db()))
  3042.  
  3043. //UPDATE
  3044. interNodes[d] = window.getCells()[d];
  3045. }
  3046.  
  3047. //UPDATE
  3048. Object.keys(interNodes).forEach(function(element, index) {
  3049. //console.log("start: " + interNodes[element].updateTime + " current: " + D + " life: " + (D - interNodes[element].updateTime));
  3050. var isRemoved = !window.getCells().hasOwnProperty(element);
  3051.  
  3052. //console.log("Time not updated: " + (window.getLastUpdate() - interNodes[element].getUptimeTime()));
  3053. if (isRemoved && (window.getLastUpdate() - interNodes[element].getUptimeTime()) > 3000) {
  3054. delete interNodes[element];
  3055. } else {
  3056. for (var i = 0; i < getPlayer().length; i++) {
  3057. if (isRemoved && computeDistance(getPlayer()[i].x, getPlayer()[i].y, interNodes[element].x, interNodes[element].y) < getPlayer()[i].size + 710) {
  3058.  
  3059. delete interNodes[element];
  3060. break;
  3061. }
  3062. }
  3063. }
  3064. });
  3065.  
  3066. c = a.getUint32(b, !0);
  3067. b += 4;
  3068. for (u = 0; u < c; u++) d = a.getUint32(b, !0), b += 4, n = E[d], null != n && n.X();
  3069. //UPDATE
  3070. //Ha && 0 == k.length && Sa(!1)
  3071. }
  3072.  
  3073. //UPDATE
  3074. function computeDistance(x1, y1, x2, y2) {
  3075. var xdis = x1 - x2; // <--- FAKE AmS OF COURSE!
  3076. var ydis = y1 - y2;
  3077. var distance = Math.sqrt(xdis * xdis + ydis * ydis);
  3078.  
  3079. return distance;
  3080. }
  3081.  
  3082. /**
  3083. * Some horse shit of some sort.
  3084. * @return Horse Shit
  3085. */
  3086. function screenDistance() {
  3087. return Math.min(computeDistance(getOffsetX(), getOffsetY(), screenToGameX(getWidth()), getOffsetY()), computeDistance(getOffsetX(), getOffsetY(), getOffsetX(), screenToGameY(getHeight())));
  3088. }
  3089.  
  3090. window.verticalDistance = function() {
  3091. return computeDistance(screenToGameX(0), screenToGameY(0), screenToGameX(getWidth()), screenToGameY(getHeight()));
  3092. }
  3093.  
  3094. /**
  3095. * A conversion from the screen's horizontal coordinate system
  3096. * to the game's horizontal coordinate system.
  3097. * @param x in the screen's coordinate system
  3098. * @return x in the game's coordinate system
  3099. */
  3100. window.screenToGameX = function(x) {
  3101. return (x - getWidth() / 2) / getRatio() + getX();
  3102. }
  3103.  
  3104. /**
  3105. * A conversion from the screen's vertical coordinate system
  3106. * to the game's vertical coordinate system.
  3107. * @param y in the screen's coordinate system
  3108. * @return y in the game's coordinate system
  3109. */
  3110. window.screenToGameY = function(y) {
  3111. return (y - getHeight() / 2) / getRatio() + getY();
  3112. }
  3113.  
  3114. window.drawPoint = function(x_1, y_1, drawColor, text) {
  3115. if (!toggleDraw) {
  3116. dPoints.push([x_1, y_1, drawColor]);
  3117. dText.push(text);
  3118. }
  3119. }
  3120.  
  3121. window.drawArc = function(x_1, y_1, x_2, y_2, x_3, y_3, drawColor) {
  3122. if (!toggleDraw) {
  3123. var radius = computeDistance(x_1, y_1, x_3, y_3);
  3124. dArc.push([x_1, y_1, x_2, y_2, x_3, y_3, radius, drawColor]);
  3125. }
  3126. }
  3127.  
  3128. window.drawLine = function(x_1, y_1, x_2, y_2, drawColor) {
  3129. if (!toggleDraw) {
  3130. lines.push([x_1, y_1, x_2, y_2, drawColor]);
  3131. }
  3132. }
  3133.  
  3134. window.drawCircle = function(x_1, y_1, radius, drawColor) {
  3135. if (!toggleDraw) {
  3136. circles.push([x_1, y_1, radius, drawColor]);
  3137. }
  3138. }
  3139.  
  3140. function V() {
  3141.  
  3142. //UPDATE
  3143. if (getPlayer().length == 0 && !reviving && ~~(getCurrentScore() / 100) > 0) {
  3144. console.log("Dead: " + ~~(getCurrentScore() / 100));
  3145. apos('send', 'pageview');
  3146. }
  3147.  
  3148. if (getPlayer().length == 0) {
  3149. console.log("Revive");
  3150. setNick(originalName);
  3151. reviving = true;
  3152. } else if (getPlayer().length > 0 && reviving) {
  3153. reviving = false;
  3154. console.log("Done Reviving!");
  3155. }
  3156.  
  3157. if (T()) {
  3158. var a = fa - m / 2;
  3159. var b = ga - r / 2;
  3160. 64 > a * a + b * b || .01 > Math.abs(eb - ia) &&
  3161. .01 > Math.abs(fb - ja) || (eb = ia, fb = ja, a = N(13), a.setUint8(0, 16), a.setInt32(1, ia, !0), a.setInt32(5, ja, !0), a.setUint32(9, 0, !0), O(a))
  3162. }
  3163. }
  3164.  
  3165. function cb() {
  3166. if (T() && $ && null != K) {
  3167. var a = N(1 + 2 * K.length);
  3168. a.setUint8(0, 0);
  3169. for (var b = 0; b < K.length; ++b) a.setUint16(1 + 2 * b, K.charCodeAt(b), !0);
  3170. O(a)
  3171. }
  3172. }
  3173.  
  3174. function T() {
  3175. return null != q && q.readyState == q.OPEN
  3176. }
  3177.  
  3178. window.opCode = function(a) {
  3179. console.log("Sending op code.");
  3180. H(parseInt(a));
  3181. }
  3182.  
  3183. function H(a) {
  3184. if (T()) {
  3185. var b = N(1);
  3186. b.setUint8(0, a);
  3187. O(b)
  3188. }
  3189. }
  3190.  
  3191. function $a() {
  3192. if (T() && null != B) {
  3193. var a = N(1 + B.length);
  3194. a.setUint8(0, 81);
  3195. for (var b = 0; b < B.length; ++b) a.setUint8(b + 1, B.charCodeAt(b));
  3196. O(a)
  3197. }
  3198. }
  3199.  
  3200. function Ta() {
  3201. m = d.innerWidth;
  3202. r = d.innerHeight;
  3203. za.width = G.width = m;
  3204. za.height = G.height = r;
  3205. var a = e("#helloContainer");
  3206. a.css("transform", "none");
  3207. var b = a.height(),
  3208. c = d.innerHeight;
  3209. b > c / 1.1 ? a.css("transform", "translate(-50%, -50%) scale(" + c / b / 1.1 + ")") : a.css("transform", "translate(-50%, -50%)");
  3210. gb()
  3211. }
  3212.  
  3213. function hb() {
  3214. var a;
  3215. a = Math.max(r / 1080, m / 1920);
  3216. return a *= J
  3217. }
  3218.  
  3219. function yb() {
  3220. if (0 != k.length) {
  3221. for (var a = 0, b = 0; b < k.length; b++) a += k[b].size;
  3222. a = Math.pow(Math.min(64 / a, 1), .4) * hb();
  3223. h = (9 * h + a) / 10
  3224. }
  3225. }
  3226.  
  3227. function gb() {
  3228. //UPDATE
  3229. dPoints = [];
  3230. circles = [];
  3231. dArc = [];
  3232. dText = [];
  3233. lines = [];
  3234.  
  3235.  
  3236. var a, b = Date.now();
  3237. ++zb;
  3238. C = b;
  3239. if (0 < k.length) {
  3240. yb();
  3241. for (var c = a = 0, d = 0; d < k.length; d++) k[d].P(), a += k[d].x / k.length, c += k[d].y / k.length;
  3242. aa = a;
  3243. ba = c;
  3244. ca = h;
  3245. s = (s + a) / 2;
  3246. t = (t + c) / 2;
  3247. } else s = (29 * s + aa) / 30, t = (29 * t + ba) / 30, h = (9 * h + ca * hb()) / 10;
  3248. qb();
  3249. Aa();
  3250. Ia || f.clearRect(0, 0, m, r);
  3251. Ia ? (f.fillStyle = ta ? "#111111" : "#F2FBFF", f.globalAlpha = .05, f.fillRect(0, 0, m, r), f.globalAlpha = 1) : Ab();
  3252. v.sort(function(a, b) {
  3253. return a.size == b.size ? a.id - b.id : a.size - b.size
  3254. });
  3255. f.save();
  3256. f.translate(m / 2, r / 2);
  3257. f.scale(h, h);
  3258. f.translate(-s, -t);
  3259. //UPDATE
  3260. f.save();
  3261. f.beginPath();
  3262. f.lineWidth = 5;
  3263. f.strokeStyle = (getDarkBool() ? '#F2FBFF' : '#111111');
  3264. f.moveTo(getMapStartX(), getMapStartY());
  3265. f.lineTo(getMapStartX(), getMapEndY());
  3266. f.stroke();
  3267. f.moveTo(getMapStartX(), getMapStartY());
  3268. f.lineTo(getMapEndX(), getMapStartY());
  3269. f.stroke();
  3270. f.moveTo(getMapEndX(), getMapStartY());
  3271. f.lineTo(getMapEndX(), getMapEndY());
  3272. f.stroke();
  3273. f.moveTo(getMapStartX(), getMapEndY());
  3274. f.lineTo(getMapEndX(), getMapEndY());
  3275. f.stroke();
  3276. f.restore();
  3277.  
  3278. for (d = 0; d < v.length; d++) v[d].w(f);
  3279. for (d = 0; d < Q.length; d++) Q[d].w(f);
  3280. //UPDATE
  3281. if (getPlayer().length > 0) {
  3282. var moveLoc = window.botList[botIndex].mainLoop();
  3283. if (!toggle) {
  3284. setPoint(moveLoc[0], moveLoc[1]);
  3285. }
  3286. }
  3287. customRender(f);
  3288. if (Ga) {
  3289. na = (3 * na + Ea) / 4;
  3290. oa = (3 * oa + Fa) / 4;
  3291. f.save();
  3292. f.strokeStyle = "#FFAAAA";
  3293. f.lineWidth = 10;
  3294. f.lineCap = "round";
  3295. f.lineJoin = "round";
  3296. f.globalAlpha = .5;
  3297. f.beginPath();
  3298. for (d = 0; d < k.length; d++) f.moveTo(k[d].x, k[d].y), f.lineTo(na, oa);
  3299. f.stroke();
  3300. f.restore();
  3301. }
  3302. f.restore();
  3303. z && z.width && f.drawImage(z, m - z.width - 10, 10);
  3304. R = Math.max(R, Bb());
  3305.  
  3306. //UPDATE
  3307.  
  3308. var currentDate = new Date();
  3309.  
  3310. var nbSeconds = 0;
  3311. if (getPlayer().length > 0) {
  3312. //nbSeconds = currentDate.getSeconds() + currentDate.getMinutes() * 60 + currentDate.getHours() * 3600 - lifeTimer.getSeconds() - lifeTimer.getMinutes() * 60 - lifeTimer.getHours() * 3600;
  3313. nbSeconds = (currentDate.getTime() - lifeTimer.getTime()) / 1000;
  3314. }
  3315.  
  3316. bestTime = Math.max(nbSeconds, bestTime);
  3317.  
  3318. var displayText = 'Score: ' + ~~(R / 100) + " Current Time: " + nbSeconds + " seconds.";
  3319.  
  3320. 0 != R && (null == ua && (ua = new va(24, "#FFFFFF")), ua.C(displayText), c = ua.L(), a = c.width, f.globalAlpha = .2, f.fillStyle = "#000000", f.fillRect(10, r - 10 - 24 - 10, a + 10, 34), f.globalAlpha = 1, f.drawImage(c, 15, r -
  3321. 10 - 24 - 5));
  3322. Cb();
  3323. b = Date.now() - b;
  3324. b > 1E3 / 60 ? D -= .01 : b < 1E3 / 65 && (D += .01);.4 > D && (D = .4);
  3325. 1 < D && (D = 1);
  3326. b = C - ib;
  3327. !T() || W ? (x += b / 2E3, 1 < x && (x = 1)) : (x -= b / 300, 0 > x && (x = 0));
  3328. 0 < x && (f.fillStyle = "#000000", f.globalAlpha = .5 * x, f.fillRect(0, 0, m, r), f.globalAlpha = 1);
  3329. ib = C
  3330.  
  3331. drawStats(f);
  3332. }
  3333.  
  3334. //UPDATE
  3335. function customRender(d) {
  3336. d.save();
  3337. for (var i = 0; i < lines.length; i++) {
  3338. d.beginPath();
  3339.  
  3340. d.lineWidth = 5;
  3341.  
  3342. if (lines[i][4] == 0) {
  3343. d.strokeStyle = "#FF0000";
  3344. } else if (lines[i][4] == 1) {
  3345. d.strokeStyle = "#00FF00";
  3346. } else if (lines[i][4] == 2) {
  3347. d.strokeStyle = "#0000FF";
  3348. } else if (lines[i][4] == 3) {
  3349. d.strokeStyle = "#FF8000";
  3350. } else if (lines[i][4] == 4) {
  3351. d.strokeStyle = "#8A2BE2";
  3352. } else if (lines[i][4] == 5) {
  3353. d.strokeStyle = "#FF69B4";
  3354. } else if (lines[i][4] == 6) {
  3355. d.strokeStyle = "#008080";
  3356. } else if (lines[i][4] == 7) {
  3357. d.strokeStyle = (getDarkBool() ? '#F2FBFF' : '#111111');
  3358. } else {
  3359. d.strokeStyle = "#000000";
  3360. }
  3361.  
  3362. d.moveTo(lines[i][0], lines[i][1]);
  3363. d.lineTo(lines[i][2], lines[i][3]);
  3364.  
  3365. d.stroke();
  3366. }
  3367. d.restore();
  3368. d.save();
  3369. for (var i = 0; i < circles.length; i++) {
  3370. if (circles[i][3] == 0) {
  3371. d.strokeStyle = "#FF0000";
  3372. } else if (circles[i][3] == 1) {
  3373. d.strokeStyle = "#00FF00";
  3374. } else if (circles[i][3] == 2) {
  3375. d.strokeStyle = "#0000FF";
  3376. } else if (circles[i][3] == 3) {
  3377. d.strokeStyle = "#FF8000";
  3378. } else if (circles[i][3] == 4) {
  3379. d.strokeStyle = "#8A2BE2";
  3380. } else if (circles[i][3] == 5) {
  3381. d.strokeStyle = "#FF69B4";
  3382. } else if (circles[i][3] == 6) {
  3383. d.strokeStyle = "#008080";
  3384. } else if (circles[i][3] == 7) {
  3385. d.strokeStyle = (getDarkBool() ? '#F2FBFF' : '#111111');
  3386. } else {
  3387. d.strokeStyle = "#000000";
  3388. }
  3389. d.beginPath();
  3390.  
  3391. d.lineWidth = 10;
  3392. //d.setLineDash([5]);
  3393. d.globalAlpha = 0.3;
  3394.  
  3395. d.arc(circles[i][0], circles[i][1], circles[i][2], 0, 2 * Math.PI, false);
  3396.  
  3397. d.stroke();
  3398. }
  3399. d.restore();
  3400. d.save();
  3401. for (var i = 0; i < dArc.length; i++) {
  3402. if (dArc[i][7] == 0) {
  3403. d.strokeStyle = "#FF0000";
  3404. } else if (dArc[i][7] == 1) {
  3405. d.strokeStyle = "#00FF00";
  3406. } else if (dArc[i][7] == 2) {
  3407. d.strokeStyle = "#0000FF";
  3408. } else if (dArc[i][7] == 3) {
  3409. d.strokeStyle = "#FF8000";
  3410. } else if (dArc[i][7] == 4) {
  3411. d.strokeStyle = "#8A2BE2";
  3412. } else if (dArc[i][7] == 5) {
  3413. d.strokeStyle = "#FF69B4";
  3414. } else if (dArc[i][7] == 6) {
  3415. d.strokeStyle = "#008080";
  3416. } else if (dArc[i][7] == 7) {
  3417. d.strokeStyle = (getDarkBool() ? '#F2FBFF' : '#111111');
  3418. } else {
  3419. d.strokeStyle = "#000000";
  3420. }
  3421.  
  3422. d.beginPath();
  3423.  
  3424. d.lineWidth = 5;
  3425.  
  3426. var ang1 = Math.atan2(dArc[i][1] - dArc[i][5], dArc[i][0] - dArc[i][4]);
  3427. var ang2 = Math.atan2(dArc[i][3] - dArc[i][5], dArc[i][2] - dArc[i][4]);
  3428.  
  3429. d.arc(dArc[i][4], dArc[i][5], dArc[i][6], ang1, ang2, false);
  3430.  
  3431. d.stroke();
  3432. }
  3433. d.restore();
  3434. d.save();
  3435. for (var i = 0; i < dPoints.length; i++) {
  3436. if (dText[i] == "") {
  3437. var radius = 10;
  3438.  
  3439. d.beginPath();
  3440. d.arc(dPoints[i][0], dPoints[i][1], radius, 0, 2 * Math.PI, false);
  3441.  
  3442. if (dPoints[i][2] == 0) {
  3443. d.fillStyle = "black";
  3444. } else if (dPoints[i][2] == 1) {
  3445. d.fillStyle = "yellow";
  3446. } else if (dPoints[i][2] == 2) {
  3447. d.fillStyle = "blue";
  3448. } else if (dPoints[i][2] == 3) {
  3449. d.fillStyle = "red";
  3450. } else if (dPoints[i][2] == 4) {
  3451. d.fillStyle = "#008080";
  3452. } else if (dPoints[i][2] == 5) {
  3453. d.fillStyle = "#FF69B4";
  3454. } else {
  3455. d.fillStyle = "#000000";
  3456. }
  3457.  
  3458. d.fill();
  3459. d.lineWidth = 2;
  3460. d.strokeStyle = '#003300';
  3461. d.stroke();
  3462. } else {
  3463. var text = new va(18, (getDarkBool() ? '#F2FBFF' : '#111111'), true, (getDarkBool() ? '#111111' : '#F2FBFF'));
  3464.  
  3465. text.C(dText[i]);
  3466. var textRender = text.L();
  3467. d.drawImage(textRender, dPoints[i][0] - (textRender.width / 2), dPoints[i][1] - (textRender.height / 2));
  3468. }
  3469.  
  3470. }
  3471. d.restore();
  3472. }
  3473.  
  3474. function drawStats(d) {
  3475. d.save()
  3476.  
  3477. sessionScore = Math.max(getCurrentScore(), sessionScore);
  3478.  
  3479. var botString = window.botList[botIndex].displayText();
  3480.  
  3481. var debugStrings = [];
  3482. debugStrings.push("Bot: " + window.botList[botIndex].name);
  3483. debugStrings.push("Launcher: AposLauncher " + aposLauncherVersion);
  3484. debugStrings.push("T - Bot: " + (!toggle ? "On" : "Off"));
  3485. debugStrings.push("R - Lines: " + (!toggleDraw ? "On" : "Off"));
  3486.  
  3487. for (var i = 0; i < botString.length; i++) {
  3488. debugStrings.push(botString[i]);
  3489. }
  3490.  
  3491. debugStrings.push("");
  3492. debugStrings.push("Best Score: " + ~~(sessionScore / 100));
  3493. debugStrings.push("Best Time: " + bestTime + " seconds");
  3494. debugStrings.push("");
  3495. debugStrings.push(serverIP);
  3496.  
  3497. if (getPlayer().length > 0) {
  3498. var offsetX = -getMapStartX();
  3499. var offsetY = -getMapStartY();
  3500. debugStrings.push("Location: " + Math.floor(getPlayer()[0].x + offsetX) + ", " + Math.floor(getPlayer()[0].y + offsetY));
  3501. }
  3502.  
  3503. var offsetValue = 20;
  3504. var text = new va(18, (getDarkBool() ? '#F2FBFF' : '#111111'));
  3505.  
  3506. for (var i = 0; i < debugStrings.length; i++) {
  3507. text.C(debugStrings[i]);
  3508. var textRender = text.L();
  3509. d.drawImage(textRender, 20, offsetValue);
  3510. offsetValue += textRender.height;
  3511. }
  3512.  
  3513. if (message.length > 0) {
  3514. var mRender = [];
  3515. var mWidth = 0;
  3516. var mHeight = 0;
  3517.  
  3518. for (var i = 0; i < message.length; i++) {
  3519. var mText = new va(28, '#FF0000', true, '#000000');
  3520. mText.C(message[i]);
  3521. mRender.push(mText.L());
  3522.  
  3523. if (mRender[i].width > mWidth) {
  3524. mWidth = mRender[i].width;
  3525. }
  3526. mHeight += mRender[i].height;
  3527. }
  3528.  
  3529. var mX = getWidth() / 2 - mWidth / 2;
  3530. var mY = 20;
  3531.  
  3532. d.globalAlpha = 0.4;
  3533. d.fillStyle = '#000000';
  3534. d.fillRect(mX - 10, mY - 10, mWidth + 20, mHeight + 20);
  3535. d.globalAlpha = 1;
  3536.  
  3537. var mOffset = mY;
  3538. for (var i = 0; i < mRender.length; i++) {
  3539. d.drawImage(mRender[i], getWidth() / 2 - mRender[i].width / 2, mOffset);
  3540. mOffset += mRender[i].height;
  3541. }
  3542. }
  3543.  
  3544. d.restore();
  3545. }
  3546.  
  3547. function Ab() {
  3548. f.fillStyle = ta ? "#111111" : "#F2FBFF";
  3549. f.fillRect(0, 0, m, r);
  3550. f.save();
  3551. f.strokeStyle = ta ? "#AAAAAA" : "#000000";
  3552. f.globalAlpha = .2 * h;
  3553. for (var a = m / h, b = r / h, c = (a / 2 - s) % 50; c < a; c += 50) f.beginPath(), f.moveTo(c * h - .5, 0), f.lineTo(c * h - .5, b * h), f.stroke();
  3554. for (c = (b / 2 - t) % 50; c < b; c += 50) f.beginPath(), f.moveTo(0, c * h - .5), f.lineTo(a * h, c * h - .5), f.stroke();
  3555. f.restore()
  3556. }
  3557.  
  3558. function Cb() {
  3559. if (Qa && Ja.width) {
  3560. var a = m / 5;
  3561. f.drawImage(Ja, 5, 5, a, a)
  3562. }
  3563. }
  3564.  
  3565. function Bb() {
  3566. for (var a = 0, b = 0; b < k.length; b++) a += k[b].q * k[b].q;
  3567. return a
  3568. }
  3569.  
  3570. function ab() {
  3571. z = null;
  3572. if (null != A || 0 != F.length)
  3573. if (null != A || wa) {
  3574. z = document.createElement("canvas");
  3575. var a = z.getContext("2d"),
  3576. b = 60,
  3577. b = null == A ? b + 24 * F.length : b + 180,
  3578. c = Math.min(200, .3 * m) / 200;
  3579. z.width = 200 * c;
  3580. z.height = b * c;
  3581. a.scale(c, c);
  3582. a.globalAlpha = .4;
  3583. a.fillStyle = "#000000";
  3584. a.fillRect(0, 0, 200, b);
  3585. a.globalAlpha =
  3586. 1;
  3587. a.fillStyle = "#FFFFFF";
  3588. c = null;
  3589. c = Z("leaderboard");
  3590. a.font = "30px Ubuntu";
  3591. a.fillText(c, 100 - a.measureText(c).width / 2, 40);
  3592. if (null == A)
  3593. for (a.font = "20px Ubuntu", b = 0; b < F.length; ++b) c = F[b].name || Z("unnamed_cell"), wa || (c = Z("unnamed_cell")), -1 != M.indexOf(F[b].id) ? (k[0].name && (c = k[0].name), a.fillStyle = "#FFAAAA") : a.fillStyle = "#FFFFFF", c = b + 1 + ". " + c, a.fillText(c, 100 - a.measureText(c).width / 2, 70 + 24 * b);
  3594. else
  3595. for (b = c = 0; b < A.length; ++b) {
  3596. var d = c + A[b] * Math.PI * 2;
  3597. a.fillStyle = Db[b + 1];
  3598. a.beginPath();
  3599. a.moveTo(100, 140);
  3600. a.arc(100,
  3601. 140, 80, c, d, !1);
  3602. a.fill();
  3603. c = d
  3604. }
  3605. }
  3606. }
  3607.  
  3608. function Ka(a, b, c, d, e) {
  3609. this.V = a;
  3610. this.x = b;
  3611. this.y = c;
  3612. this.i = d;
  3613. this.b = e
  3614. }
  3615.  
  3616. function da(a, b, c, d, e, p) {
  3617. this.id = a;
  3618. this.s = this.x = b;
  3619. this.t = this.y = c;
  3620. this.r = this.size = d;
  3621. this.color = e;
  3622. this.a = [];
  3623. this.W();
  3624. this.B(p)
  3625. }
  3626.  
  3627. function va(a, b, c, d) {
  3628. a && (this.u = a);
  3629. b && (this.S = b);
  3630. this.U = !!c;
  3631. d && (this.v = d)
  3632. }
  3633.  
  3634. function S(a, b) {
  3635. var c = "1" == e("#helloContainer").attr("data-has-account-data");
  3636. e("#helloContainer").attr("data-has-account-data", "1");
  3637. if (null == b && d.localStorage.loginCache) {
  3638. var l = JSON.parse(d.localStorage.loginCache);
  3639. l.f = a.f;
  3640. l.d = a.d;
  3641. l.e = a.e;
  3642. d.localStorage.loginCache = JSON.stringify(l)
  3643. }
  3644. if (c) {
  3645. var u = +e(".agario-exp-bar .progress-bar-text").first().text().split("/")[0],
  3646. c = +e(".agario-exp-bar .progress-bar-text").first().text().split("/")[1].split(" ")[0],
  3647. l = e(".agario-profile-panel .progress-bar-star").first().text();
  3648. if (l != a.e) S({
  3649. f: c,
  3650. d: c,
  3651. e: l
  3652. }, function() {
  3653. e(".agario-profile-panel .progress-bar-star").text(a.e);
  3654. e(".agario-exp-bar .progress-bar").css("width", "100%");
  3655. e(".progress-bar-star").addClass("animated tada").one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",
  3656. function() {
  3657. e(".progress-bar-star").removeClass("animated tada")
  3658. });
  3659. setTimeout(function() {
  3660. e(".agario-exp-bar .progress-bar-text").text(a.d + "/" + a.d + " XP");
  3661. S({
  3662. f: 0,
  3663. d: a.d,
  3664. e: a.e
  3665. }, function() {
  3666. S(a, b)
  3667. })
  3668. }, 1E3)
  3669. });
  3670. else {
  3671. var p = Date.now(),
  3672. g = function() {
  3673. var c;
  3674. c = (Date.now() - p) / 1E3;
  3675. c = 0 > c ? 0 : 1 < c ? 1 : c;
  3676. c = c * c * (3 - 2 * c);
  3677. e(".agario-exp-bar .progress-bar-text").text(~~(u + (a.f - u) * c) + "/" + a.d + " XP");
  3678. e(".agario-exp-bar .progress-bar").css("width", (88 * (u + (a.f - u) * c) / a.d).toFixed(2) + "%");
  3679. 1 > c ? d.requestAnimationFrame(g) : b && b()
  3680. };
  3681. d.requestAnimationFrame(g)
  3682.  
  3683. }
  3684. } else e(".agario-profile-panel .progress-bar-star").text(a.e),
  3685. e(".agario-exp-bar .progress-bar-text").text(a.f + "/" + a.d + " XP"), e(".agario-exp-bar .progress-bar").css("width", (88 * a.f / a.d).toFixed(2) + "%"), b && b()
  3686.  
  3687. }
  3688.  
  3689. function jb(a) {
  3690. "string" == typeof a && (a = JSON.parse(a));
  3691. Date.now() + 18E5 > a.ja ? e("#helloContainer").attr("data-logged-in", "0") : (d.localStorage.loginCache = JSON.stringify(a), B = a.fa, e(".agario-profile-name").text(a.name), $a(), S({
  3692. f: a.f,
  3693. d: a.d,
  3694. e: a.e
  3695. }), e("#helloContainer").attr("data-logged-in", "1"))
  3696. }
  3697.  
  3698. function Eb(a) {
  3699. a = a.split("\n");
  3700. jb({
  3701. name: a[0],
  3702. ta: a[1],
  3703. fa: a[2],
  3704. ja: 1E3 *
  3705. +a[3],
  3706. e: +a[4],
  3707. f: +a[5],
  3708. d: +a[6]
  3709. });
  3710. console.log("Hello Facebook?");
  3711. }
  3712.  
  3713. function La(a) {
  3714. if ("connected" == a.status) {
  3715. var b = a.authResponse.accessToken;
  3716. d.FB.api("/me/picture?width=180&height=180", function(a) {
  3717. d.localStorage.fbPictureCache = a.data.url;
  3718. e(".agario-profile-picture").attr("src", a.data.url)
  3719. });
  3720. e("#helloContainer").attr("data-logged-in", "1");
  3721. null != B ? e.ajax(ap + "checkToken", {
  3722. error: function() {
  3723. console.log("Facebook Fail!");
  3724. B = null;
  3725. La(a)
  3726. },
  3727. success: function(a) {
  3728. a = a.split("\n");
  3729. S({
  3730. e: +a[0],
  3731. f: +a[1],
  3732. d: +a[2]
  3733. });
  3734. console.log("Facebook connected!");
  3735. },
  3736. dataType: "text",
  3737. method: "POST",
  3738. cache: !1,
  3739. crossDomain: !0,
  3740. data: B
  3741. }) : e.ajax(ap + "facebookLogin", {
  3742. error: function() {
  3743. console.log("You have a Facebook problem!");
  3744. B = null;
  3745. e("#helloContainer").attr("data-logged-in", "0")
  3746. },
  3747. success: Eb,
  3748. dataType: "text",
  3749. method: "POST",
  3750. cache: !1,
  3751. crossDomain: !0,
  3752. data: b
  3753. })
  3754. }
  3755. }
  3756.  
  3757. function Wa(a) {
  3758. Y(":party");
  3759. e("#helloContainer").attr("data-party-state", "4");
  3760. a = decodeURIComponent(a).replace(/.*#/gim, "");
  3761. Ma("#" + d.encodeURIComponent(a));
  3762. e.ajax(ap + "getToken", {
  3763. error: function() {
  3764. e("#helloContainer").attr("data-party-state", "6")
  3765. },
  3766. success: function(b) {
  3767. b = b.split("\n");
  3768. e(".partyToken").val("agar.io/#" +
  3769. d.encodeURIComponent(a));
  3770. e("#helloContainer").attr("data-party-state", "5");
  3771. Y(":party");
  3772. Ca("ws://" + b[0], a)
  3773. },
  3774. dataType: "text",
  3775. method: "POST",
  3776. cache: !1,
  3777. crossDomain: !0,
  3778. data: a
  3779. })
  3780. }
  3781.  
  3782. function Ma(a) {
  3783. d.history && d.history.replaceState && d.history.replaceState({}, d.document.title, a)
  3784. }
  3785. if (!d.agarioNoInit) {
  3786. var Na = d.location.protocol,
  3787. tb = "https:" == Na,
  3788. ap = Na + "//m.agar.io/",
  3789. xa = d.navigator.userAgent;
  3790. if (-1 != xa.indexOf("Android")) d.ga && d.ga("send", "event", "MobileRedirect", "PlayStore"), setTimeout(function() {
  3791. d.location.href = "market://details?id=com.miniclip.agar.io"
  3792. },
  3793. 1E3);
  3794. else if (-1 != xa.indexOf("iPhone") || -1 != xa.indexOf("iPad") || -1 != xa.indexOf("iPod")) d.ga && d.ga("send", "event", "MobileRedirect", "AppStore"), setTimeout(function() {
  3795. d.location.href = "https://itunes.apple.com/app/agar.io/id995999703"
  3796. }, 1E3);
  3797. else {
  3798. var za, f, G, m, r, X = null,
  3799.  
  3800. //UPDATE
  3801. toggle = false,
  3802. toggleDraw = false,
  3803. shootTime = 0,
  3804. splitTime = 0,
  3805. shootCooldown = 100,
  3806. splitCooldown = 100,
  3807. tempPoint = [0, 0, 1],
  3808. dPoints = [],
  3809. circles = [],
  3810. dArc = [],
  3811. dText = [],
  3812. lines = [],
  3813. names = ["BlackHatBot"],
  3814. originalName = names[Math.floor(Math.random() * names.length)],
  3815. sessionScore = 0,
  3816. serverIP = "",
  3817. interNodes = [],
  3818. lifeTimer = new Date(),
  3819. bestTime = 0,
  3820. botIndex = 0,
  3821. reviving = false,
  3822. message = [],
  3823.  
  3824. q = null,
  3825. s = 0,
  3826. t = 0,
  3827. M = [],
  3828. k = [],
  3829. E = {},
  3830. v = [],
  3831. Q = [],
  3832. F = [],
  3833. fa = 0,
  3834. ga = 0,
  3835.  
  3836. //UPDATE
  3837. ia = -1,
  3838. ja = -1,
  3839.  
  3840. zb = 0,
  3841. C = 0,
  3842. ib = 0,
  3843. K = null,
  3844. pa = 0,
  3845. qa = 0,
  3846. ra = 1E4,
  3847. sa = 1E4,
  3848. h = 1,
  3849. y = null,
  3850. kb = !0,
  3851. wa = !0,
  3852. Oa = !1,
  3853. Ha = !1,
  3854. R = 0,
  3855. ta = !1,
  3856. lb = !1,
  3857. aa = s = ~~((pa + ra) / 2),
  3858. ba = t = ~~((qa + sa) / 2),
  3859. ca = 1,
  3860. P = "",
  3861. A = null,
  3862. ya = !1,
  3863. Ga = !1,
  3864. Ea = 0,
  3865. Fa =
  3866. 0,
  3867. na = 0,
  3868. oa = 0,
  3869. mb = 0,
  3870. Db = ["#333333", "#FF3333", "#33FF33", "#3333FF"],
  3871. Ia = !1,
  3872. $ = !1,
  3873. bb = 0,
  3874. B = null,
  3875. J = 1,
  3876. x = 1,
  3877. W = !0,
  3878. Ba = 0,
  3879. Da = {};
  3880. (function() {
  3881. var a = d.location.search;
  3882. "?" == a.charAt(0) && (a = a.slice(1));
  3883. for (var a = a.split("&"), b = 0; b < a.length; b++) {
  3884. var c = a[b].split("=");
  3885. Da[c[0]] = c[1]
  3886. }
  3887. })();
  3888. var Qa = "ontouchstart" in d && /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(d.navigator.userAgent),
  3889. Ja = new Image;
  3890. Ja.src = "img/split.png";
  3891. var nb = document.createElement("canvas");
  3892. if ("undefined" == typeof console || "undefined" ==
  3893. typeof DataView || "undefined" == typeof WebSocket || null == nb || null == nb.getContext || null == d.localStorage) alert("You browser does not support this game, we recommend you to use Firefox to play this");
  3894. else {
  3895. var ka = null;
  3896. d.setNick = function(a) {
  3897. //UPDATE
  3898. originalName = a;
  3899. if (getPlayer().length == 0) {
  3900. lifeTimer = new Date();
  3901. }
  3902.  
  3903. Xa();
  3904. K = a;
  3905. cb();
  3906. R = 0
  3907. };
  3908. d.setRegion = ha;
  3909. d.setSkins = function(a) {
  3910. kb = a
  3911. };
  3912. d.setNames = function(a) {
  3913. wa = a
  3914. };
  3915. d.setDarkTheme = function(a) {
  3916. ta = a
  3917. };
  3918. d.setColors = function(a) {
  3919. Oa = a
  3920. };
  3921. d.setShowMass = function(a) {
  3922. lb = a
  3923. };
  3924. d.spectate = function() {
  3925. K = null;
  3926. H(1);
  3927. Xa()
  3928. };
  3929. d.setGameMode = function(a) {
  3930. a != P && (":party" ==
  3931. P && e("#helloContainer").attr("data-party-state", "0"), Y(a), ":party" != a && I())
  3932. };
  3933. d.setAcid = function(a) {
  3934. Ia = a
  3935. };
  3936. null != d.localStorage && (null == d.localStorage.AB9 && (d.localStorage.AB9 = 0 + ~~(100 * Math.random())), mb = +d.localStorage.AB9, d.ABGroup = mb);
  3937. e.get(Na + "//gc.agar.io", function(a) {
  3938. var b = a.split(" ");
  3939. a = b[0];
  3940. b = b[1] || ""; - 1 == ["UA"].indexOf(a) && ob.push("ussr");
  3941. ea.hasOwnProperty(a) && ("string" == typeof ea[a] ? y || ha(ea[a]) : ea[a].hasOwnProperty(b) && (y || ha(ea[a][b])))
  3942. }, "text");
  3943. d.ga && d.ga("send", "event", "User-Agent", d.navigator.userAgent, {
  3944. nonInteraction: 1
  3945. });
  3946. var la = !1,
  3947. Ya = 0;
  3948. setTimeout(function() {
  3949. la = !0
  3950. }, Math.max(6E4 * Ya, 1E4));
  3951. var ea = {
  3952. AF: "JP-Tokyo",
  3953. AX: "EU-London",
  3954. AL: "EU-London",
  3955. DZ: "EU-London",
  3956. AS: "SG-Singapore",
  3957. AD: "EU-London",
  3958. AO: "EU-London",
  3959. AI: "US-Atlanta",
  3960. AG: "US-Atlanta",
  3961. AR: "BR-Brazil",
  3962. AM: "JP-Tokyo",
  3963. AW: "US-Atlanta",
  3964. AU: "SG-Singapore",
  3965. AT: "EU-London",
  3966. AZ: "JP-Tokyo",
  3967. BS: "US-Atlanta",
  3968. BH: "JP-Tokyo",
  3969. BD: "JP-Tokyo",
  3970. BB: "US-Atlanta",
  3971. BY: "EU-London",
  3972. BE: "EU-London",
  3973. BZ: "US-Atlanta",
  3974. BJ: "EU-London",
  3975. BM: "US-Atlanta",
  3976. BT: "JP-Tokyo",
  3977. BO: "BR-Brazil",
  3978. BQ: "US-Atlanta",
  3979. BA: "EU-London",
  3980. BW: "EU-London",
  3981. BR: "BR-Brazil",
  3982. IO: "JP-Tokyo",
  3983. VG: "US-Atlanta",
  3984. BN: "JP-Tokyo",
  3985. BG: "EU-London",
  3986. BF: "EU-London",
  3987. BI: "EU-London",
  3988. KH: "JP-Tokyo",
  3989. CM: "EU-London",
  3990. CA: "US-Atlanta",
  3991. CV: "EU-London",
  3992. KY: "US-Atlanta",
  3993. CF: "EU-London",
  3994. TD: "EU-London",
  3995. CL: "BR-Brazil",
  3996. CN: "CN-China",
  3997. CX: "JP-Tokyo",
  3998. CC: "JP-Tokyo",
  3999. CO: "BR-Brazil",
  4000. KM: "EU-London",
  4001. CD: "EU-London",
  4002. CG: "EU-London",
  4003. CK: "SG-Singapore",
  4004. CR: "US-Atlanta",
  4005. CI: "EU-London",
  4006. HR: "EU-London",
  4007. CU: "US-Atlanta",
  4008. CW: "US-Atlanta",
  4009. CY: "JP-Tokyo",
  4010. CZ: "EU-London",
  4011. DK: "EU-London",
  4012. DJ: "EU-London",
  4013. DM: "US-Atlanta",
  4014. DO: "US-Atlanta",
  4015. EC: "BR-Brazil",
  4016. EG: "EU-London",
  4017. SV: "US-Atlanta",
  4018. GQ: "EU-London",
  4019. ER: "EU-London",
  4020. EE: "EU-London",
  4021. ET: "EU-London",
  4022. FO: "EU-London",
  4023. FK: "BR-Brazil",
  4024. FJ: "SG-Singapore",
  4025. FI: "EU-London",
  4026. FR: "EU-London",
  4027. GF: "BR-Brazil",
  4028. PF: "SG-Singapore",
  4029. GA: "EU-London",
  4030. GM: "EU-London",
  4031. GE: "JP-Tokyo",
  4032. DE: "EU-London",
  4033. GH: "EU-London",
  4034. GI: "EU-London",
  4035. GR: "EU-London",
  4036. GL: "US-Atlanta",
  4037. GD: "US-Atlanta",
  4038. GP: "US-Atlanta",
  4039. GU: "SG-Singapore",
  4040. GT: "US-Atlanta",
  4041. GG: "EU-London",
  4042. GN: "EU-London",
  4043. GW: "EU-London",
  4044. GY: "BR-Brazil",
  4045. HT: "US-Atlanta",
  4046. VA: "EU-London",
  4047. HN: "US-Atlanta",
  4048. HK: "JP-Tokyo",
  4049. HU: "EU-London",
  4050. IS: "EU-London",
  4051. IN: "JP-Tokyo",
  4052. ID: "JP-Tokyo",
  4053. IR: "JP-Tokyo",
  4054. IQ: "JP-Tokyo",
  4055. IE: "EU-London",
  4056. IM: "EU-London",
  4057. IL: "JP-Tokyo",
  4058. IT: "EU-London",
  4059. JM: "US-Atlanta",
  4060. JP: "JP-Tokyo",
  4061. JE: "EU-London",
  4062. JO: "JP-Tokyo",
  4063. KZ: "JP-Tokyo",
  4064. KE: "EU-London",
  4065. KI: "SG-Singapore",
  4066. KP: "JP-Tokyo",
  4067. KR: "JP-Tokyo",
  4068. KW: "JP-Tokyo",
  4069. KG: "JP-Tokyo",
  4070. LA: "JP-Tokyo",
  4071. LV: "EU-London",
  4072. LB: "JP-Tokyo",
  4073. LS: "EU-London",
  4074. LR: "EU-London",
  4075. LY: "EU-London",
  4076. LI: "EU-London",
  4077. LT: "EU-London",
  4078. LU: "EU-London",
  4079. MO: "JP-Tokyo",
  4080. MK: "EU-London",
  4081. MG: "EU-London",
  4082. MW: "EU-London",
  4083. MY: "JP-Tokyo",
  4084. MV: "JP-Tokyo",
  4085. ML: "EU-London",
  4086. MT: "EU-London",
  4087. MH: "SG-Singapore",
  4088. MQ: "US-Atlanta",
  4089. MR: "EU-London",
  4090. MU: "EU-London",
  4091. YT: "EU-London",
  4092. MX: "US-Atlanta",
  4093. FM: "SG-Singapore",
  4094. MD: "EU-London",
  4095. MC: "EU-London",
  4096. MN: "JP-Tokyo",
  4097. ME: "EU-London",
  4098. MS: "US-Atlanta",
  4099. MA: "EU-London",
  4100. MZ: "EU-London",
  4101. MM: "JP-Tokyo",
  4102. NA: "EU-London",
  4103. NR: "SG-Singapore",
  4104. NP: "JP-Tokyo",
  4105. NL: "EU-London",
  4106. NC: "SG-Singapore",
  4107. NZ: "SG-Singapore",
  4108. NI: "US-Atlanta",
  4109. NE: "EU-London",
  4110. NG: "EU-London",
  4111. NU: "SG-Singapore",
  4112. NF: "SG-Singapore",
  4113. MP: "SG-Singapore",
  4114. NO: "EU-London",
  4115. OM: "JP-Tokyo",
  4116. PK: "JP-Tokyo",
  4117. PW: "SG-Singapore",
  4118. PS: "JP-Tokyo",
  4119. PA: "US-Atlanta",
  4120. PG: "SG-Singapore",
  4121. PY: "BR-Brazil",
  4122. PE: "BR-Brazil",
  4123. PH: "JP-Tokyo",
  4124. PN: "SG-Singapore",
  4125. PL: "EU-London",
  4126. PT: "EU-London",
  4127. PR: "US-Atlanta",
  4128. QA: "JP-Tokyo",
  4129. RE: "EU-London",
  4130. RO: "EU-London",
  4131. RU: "RU-Russia",
  4132. RW: "EU-London",
  4133. BL: "US-Atlanta",
  4134. SH: "EU-London",
  4135. KN: "US-Atlanta",
  4136. LC: "US-Atlanta",
  4137. MF: "US-Atlanta",
  4138. PM: "US-Atlanta",
  4139. VC: "US-Atlanta",
  4140. WS: "SG-Singapore",
  4141. SM: "EU-London",
  4142. ST: "EU-London",
  4143. SA: "EU-London",
  4144. SN: "EU-London",
  4145. RS: "EU-London",
  4146. SC: "EU-London",
  4147. SL: "EU-London",
  4148. SG: "JP-Tokyo",
  4149. SX: "US-Atlanta",
  4150. SK: "EU-London",
  4151. SI: "EU-London",
  4152. SB: "SG-Singapore",
  4153. SO: "EU-London",
  4154. ZA: "EU-London",
  4155. SS: "EU-London",
  4156. ES: "EU-London",
  4157. LK: "JP-Tokyo",
  4158. SD: "EU-London",
  4159. SR: "BR-Brazil",
  4160. SJ: "EU-London",
  4161. SZ: "EU-London",
  4162. SE: "EU-London",
  4163. CH: "EU-London",
  4164. SY: "EU-London",
  4165. TW: "JP-Tokyo",
  4166. TJ: "JP-Tokyo",
  4167. TZ: "EU-London",
  4168. TH: "JP-Tokyo",
  4169. TL: "JP-Tokyo",
  4170. TG: "EU-London",
  4171. TK: "SG-Singapore",
  4172. TO: "SG-Singapore",
  4173. TT: "US-Atlanta",
  4174. TN: "EU-London",
  4175. TR: "TK-Turkey",
  4176. TM: "JP-Tokyo",
  4177. TC: "US-Atlanta",
  4178. TV: "SG-Singapore",
  4179. UG: "EU-London",
  4180. UA: "EU-London",
  4181. AE: "EU-London",
  4182. GB: "EU-London",
  4183. US: "US-Atlanta",
  4184. UM: "SG-Singapore",
  4185. VI: "US-Atlanta",
  4186. UY: "BR-Brazil",
  4187. UZ: "JP-Tokyo",
  4188. VU: "SG-Singapore",
  4189. VE: "BR-Brazil",
  4190. VN: "JP-Tokyo",
  4191. WF: "SG-Singapore",
  4192. EH: "EU-London",
  4193. YE: "JP-Tokyo",
  4194. ZM: "EU-London",
  4195. ZW: "EU-London"
  4196. },
  4197. L = null;
  4198. d.connect = Ca;
  4199.  
  4200. //UPDATE
  4201. /**
  4202. * Tells you if the game is in Dark mode.
  4203. * @return Boolean for dark mode.
  4204. */
  4205. window.getDarkBool = function() {
  4206. return ta;
  4207. }
  4208.  
  4209. /**
  4210. * Tells you if the mass is shown.
  4211. * @return Boolean for player's mass.
  4212. */
  4213. window.getMassBool = function() {
  4214. return lb;
  4215. }
  4216.  
  4217. /**
  4218. * This is a copy of everything that is shown on screen.
  4219. * Normally stuff will time out when off the screen, this
  4220. * memorizes everything that leaves the screen for a little
  4221. * while longer.
  4222. * @return The memory object.
  4223. */
  4224. window.getMemoryCells = function() {
  4225. return interNodes;
  4226. }
  4227.  
  4228. /**
  4229. * [getCellsArray description]
  4230. * @return {[type]} [description]
  4231. */
  4232. window.getCellsArray = function() {
  4233. return v;
  4234. }
  4235.  
  4236. /**
  4237. * [getCellsArray description]
  4238. * @return {[type]} [description]
  4239. */
  4240. window.getCells = function() {
  4241. return E;
  4242. }
  4243.  
  4244. /**
  4245. * Returns an array with all the player's cells.
  4246. * @return Player's cells
  4247. */
  4248. window.getPlayer = function() {
  4249. return k;
  4250. }
  4251.  
  4252. /**
  4253. * The canvas' width.
  4254. * @return Integer Width
  4255. */
  4256. window.getWidth = function() {
  4257. return m;
  4258. }
  4259.  
  4260. /**
  4261. * The canvas' height
  4262. * @return Integer Height
  4263. */
  4264. window.getHeight = function() {
  4265. return r;
  4266. }
  4267.  
  4268. /**
  4269. * Scaling ratio of the canvas. The bigger this ration,
  4270. * the further that you see.
  4271. * @return Screen scaling ratio.
  4272. */
  4273. window.getRatio = function() {
  4274. return h;
  4275. }
  4276.  
  4277. /**
  4278. * [getOffsetX description]
  4279. * @return {[type]} [description]
  4280. */
  4281. window.getOffsetX = function() {
  4282. return aa;
  4283. }
  4284.  
  4285. window.getOffsetY = function() {
  4286. return ba;
  4287. }
  4288.  
  4289. window.getX = function() {
  4290. return s;
  4291. }
  4292.  
  4293. window.getY = function() {
  4294. return t;
  4295. }
  4296.  
  4297. window.getPointX = function() {
  4298. return ia;
  4299. }
  4300.  
  4301. window.getPointY = function() {
  4302. return ja;
  4303. }
  4304.  
  4305. /**
  4306. * The X location of the mouse.
  4307. * @return Integer X
  4308. */
  4309. window.getMouseX = function() {
  4310. return fa;
  4311. }
  4312.  
  4313. /**
  4314. * The Y location of the mouse.
  4315. * @return Integer Y
  4316. */
  4317. window.getMouseY = function() {
  4318. return ga;
  4319. }
  4320.  
  4321. window.getMapStartX = function() {
  4322. return pa;
  4323. }
  4324.  
  4325. window.getMapStartY = function() {
  4326. return qa;
  4327. }
  4328.  
  4329. window.getMapEndX = function() {
  4330. return ra;
  4331. }
  4332.  
  4333. window.getMapEndY = function() {
  4334. return sa;
  4335. }
  4336.  
  4337. window.getScreenDistance = function() {
  4338. var temp = screenDistance();
  4339. return temp;
  4340. }
  4341.  
  4342. /**
  4343. * A timestamp since the last time the server sent any data.
  4344. * @return Last update timestamp
  4345. */
  4346. window.getLastUpdate = function() {
  4347. return C;
  4348. }
  4349.  
  4350. window.getCurrentScore = function() {
  4351. return R;
  4352. }
  4353.  
  4354. /**
  4355. * The game's current mode. (":ffa", ":experimental", ":teams". ":party")
  4356. * @return {[type]} [description]
  4357. */
  4358. window.getMode = function() {
  4359. return P;
  4360. }
  4361.  
  4362. window.getServer = function() {
  4363. return serverIP;
  4364. }
  4365.  
  4366. window.setPoint = function(x, y) {
  4367. ia = x;
  4368. ja = y;
  4369. }
  4370.  
  4371. window.setScore = function(a) {
  4372. sessionScore = a * 100;
  4373. }
  4374.  
  4375. window.setBestTime = function(a) {
  4376. bestTime = a;
  4377. }
  4378.  
  4379. window.best = function(a, b) {
  4380. setScore(a);
  4381. setBestTime(b);
  4382. }
  4383.  
  4384. window.setBotIndex = function(a) {
  4385. console.log("Changing bot");
  4386. botIndex = a;
  4387. }
  4388.  
  4389. window.setMessage = function(a) {
  4390. message = a;
  4391. }
  4392.  
  4393. window.shoot = function() {
  4394. if (!toggle && shootTime + shootCooldown < new Date().getTime()) {
  4395. shootTime = new Date().getTime();
  4396. opCode(21);
  4397. }
  4398. }
  4399.  
  4400. window.split = function() {
  4401.  
  4402. if (!toggle && splitTime + splitCooldown < new Date().getTime()) {
  4403. splitTime = new Date().getTime();
  4404. opCode(17);
  4405. }
  4406. }
  4407.  
  4408. window.updateBotList = function() {
  4409. window.botList = window.botList || [];
  4410.  
  4411. window.jQuery('#locationUnknown').text("");
  4412.  
  4413. window.jQuery('#locationUnknown').append(window.jQuery('<select id="bList" class="form-control" onchange="setBotIndex($(this).val());" />'));
  4414. window.jQuery('#locationUnknown').addClass('form-group');
  4415.  
  4416. for (var i = 0; i < window.botList.length; i++) {
  4417. if (window.botList[i].name == "Human" && window.botList.length > 1) {
  4418. if (botIndex == i) {
  4419. botIndex = (botIndex + 1).mod(window.botList.length);
  4420. }
  4421. continue;
  4422. }
  4423.  
  4424. var bList = window.jQuery('#bList');
  4425. window.jQuery('<option />', {
  4426. value: i,
  4427. text: window.botList[i].name
  4428. }).appendTo(bList);
  4429. }
  4430. }
  4431.  
  4432. var ma = 500,
  4433. eb = -1,
  4434. fb = -1,
  4435. z = null,
  4436. D = 1,
  4437. ua = null,
  4438. Ua = function() {
  4439. var a = Date.now(),
  4440. b = 1E3 / 60;
  4441. return function() {
  4442. d.requestAnimationFrame(Ua);
  4443. var c = Date.now(),
  4444. l = c - a;
  4445. l > b && (a = c - l % b, !T() || 240 > Date.now() - bb ? gb() : console.warn("Skipping draw"), Fb())
  4446. }
  4447. }(),
  4448. U = {},
  4449. ob = "notreallyabot;poland;usa;china;russia;canada;australia;spain;brazil;germany;ukraine;france;sweden;chaplin;north korea;south korea;japan;united kingdom;earth;greece;latvia;lithuania;estonia;finland;norway;cia;maldivas;austria;nigeria;reddit;yaranaika;confederate;9gag;indiana;4chan;italy;bulgaria;tumblr;2ch.hk;hong kong;portugal;jamaica;german empire;mexico;sanik;switzerland;croatia;chile;indonesia;bangladesh;thailand;iran;iraq;peru;moon;botswana;bosnia;netherlands;european union;taiwan;pakistan;hungary;satanist;qing dynasty;matriarchy;patriarchy;feminism;ireland;texas;facepunch;prodota;cambodia;steam;piccolo;ea;india;kc;denmark;quebec;ayy lmao;sealand;bait;tsarist russia;origin;vinesauce;stalin;belgium;luxembourg;stussy;prussia;8ch;argentina;scotland;sir;romania;belarus;wojak;doge;nasa;byzantium;imperial japan;french kingdom;somalia;turkey;mars;pokerface;8;irs;receita federal;facebook".split(";"),
  4450. Gb = ["8", "nasa"],
  4451. Hb = ["m'blob"];
  4452. Ka.prototype = {
  4453. V: null,
  4454. x: 0,
  4455. y: 0,
  4456. i: 0,
  4457. b: 0
  4458. };
  4459. da.prototype = {
  4460. id: 0,
  4461. a: null,
  4462. name: null,
  4463. o: null,
  4464. O: null,
  4465. x: 0,
  4466. y: 0,
  4467. size: 0,
  4468. s: 0,
  4469. t: 0,
  4470. r: 0,
  4471. J: 0,
  4472. K: 0,
  4473. q: 0,
  4474. ba: 0,
  4475. Q: 0,
  4476. sa: 0,
  4477. ia: 0,
  4478. G: !1,
  4479. h: !1,
  4480. n: !1,
  4481. R: !0,
  4482. Y: 0,
  4483. //UPDATE
  4484. updateCode: 0,
  4485. danger: false,
  4486. dangerTimeOut: 0,
  4487. isNotMoving: function() {
  4488. return (this.x == this.s && this.y == this.t);
  4489. },
  4490. isVirus: function() {
  4491. return this.h;
  4492. },
  4493. getUptimeTime: function() {
  4494. return this.Q;
  4495. },
  4496. X: function() {
  4497. var a;
  4498. for (a = 0; a < v.length; a++)
  4499. if (v[a] == this) {
  4500. v.splice(a, 1);
  4501. break
  4502. }
  4503. delete E[this.id];
  4504. a = k.indexOf(this); - 1 != a && (Ha = !0, k.splice(a, 1));
  4505. a = M.indexOf(this.id); - 1 != a && M.splice(a, 1);
  4506. this.G = !0;
  4507. 0 < this.Y && Q.push(this)
  4508. },
  4509. l: function() {
  4510. return Math.max(~~(.3 * this.size), 24)
  4511. },
  4512. B: function(a) {
  4513. if (this.name = a) null ==
  4514. this.o ? this.o = new va(this.l(), "#FFFFFF", !0, "#000000") : this.o.M(this.l()), this.o.C(this.name)
  4515. },
  4516. W: function() {
  4517. for (var a = this.I(); this.a.length > a;) {
  4518. var b = ~~(Math.random() * this.a.length);
  4519. this.a.splice(b, 1)
  4520. }
  4521. for (0 == this.a.length && 0 < a && this.a.push(new Ka(this, this.x, this.y, this.size, Math.random() - .5)); this.a.length < a;) b = ~~(Math.random() * this.a.length), b = this.a[b], this.a.push(new Ka(this, b.x, b.y, b.i, b.b))
  4522. },
  4523. I: function() {
  4524. var a = 10;
  4525. 20 > this.size && (a = 0);
  4526. this.h && (a = 30);
  4527. var b = this.size;
  4528. this.h || (b *= h);
  4529. b *= D;
  4530. this.ba &
  4531. 32 && (b *= .25);
  4532. return ~~Math.max(b, a)
  4533. },
  4534. qa: function() {
  4535. this.W();
  4536. for (var a = this.a, b = a.length, c = 0; c < b; ++c) {
  4537. var d = a[(c - 1 + b) % b].b,
  4538. e = a[(c + 1) % b].b;
  4539. a[c].b += (Math.random() - .5) * (this.n ? 3 : 1);
  4540. a[c].b *= .7;
  4541. 10 < a[c].b && (a[c].b = 10); - 10 > a[c].b && (a[c].b = -10);
  4542. a[c].b = (d + e + 8 * a[c].b) / 10
  4543. }
  4544. for (var p = this, g = this.h ? 0 : (this.id / 1E3 + C / 1E4) % (2 * Math.PI), c = 0; c < b; ++c) {
  4545. var f = a[c].i,
  4546. d = a[(c - 1 + b) % b].i,
  4547. e = a[(c + 1) % b].i;
  4548. if (15 < this.size && null != X && 20 < this.size * h && 0 < this.id) {
  4549. var k = !1,
  4550. w = a[c].x,
  4551. m = a[c].y;
  4552. X.ra(w - 5, m - 5, 10, 10, function(a) {
  4553. a.V != p && 25 > (w -
  4554. a.x) * (w - a.x) + (m - a.y) * (m - a.y) && (k = !0)
  4555. });
  4556. !k && (a[c].x < pa || a[c].y < qa || a[c].x > ra || a[c].y > sa) && (k = !0);
  4557. k && (0 < a[c].b && (a[c].b = 0), a[c].b -= 1)
  4558. }
  4559. f += a[c].b;
  4560. 0 > f && (f = 0);
  4561. f = this.n ? (19 * f + this.size) / 20 : (12 * f + this.size) / 13;
  4562. a[c].i = (d + e + 8 * f) / 10;
  4563. d = 2 * Math.PI / b;
  4564. e = this.a[c].i;
  4565. this.h && 0 == c % 2 && (e += 5);
  4566. a[c].x = this.x + Math.cos(d * c + g) * e;
  4567. a[c].y = this.y + Math.sin(d * c + g) * e
  4568. }
  4569. },
  4570. P: function() {
  4571. if (0 >= this.id) return 1;
  4572. var a;
  4573. a = (C - this.Q) / 120;
  4574. a = 0 > a ? 0 : 1 < a ? 1 : a;
  4575. var b = 0 > a ? 0 : 1 < a ? 1 : a;
  4576. this.l();
  4577. if (this.G && 1 <= b) {
  4578. var c = Q.indexOf(this); - 1 != c && Q.splice(c, 1)
  4579. }
  4580. this.x =
  4581. a * (this.J - this.s) + this.s;
  4582. this.y = a * (this.K - this.t) + this.t;
  4583. this.size = b * (this.q - this.r) + this.r;
  4584. return b
  4585. },
  4586. N: function() {
  4587. return 0 >= this.id ? !0 : this.x + this.size + 40 < s - m / 2 / h || this.y + this.size + 40 < t - r / 2 / h || this.x - this.size - 40 > s + m / 2 / h || this.y - this.size - 40 > t + r / 2 / h ? !1 : !0
  4588. },
  4589. w: function(a) {
  4590. if (this.N()) {
  4591. ++this.Y;
  4592. var b = 0 < this.id && !this.h && !this.n && .4 > h;
  4593. 5 > this.I() && (b = !0);
  4594. if (this.R && !b)
  4595. for (var c = 0; c < this.a.length; c++) this.a[c].i = this.size;
  4596. this.R = b;
  4597. a.save();
  4598. this.ia = C;
  4599. c = this.P();
  4600. this.G && (a.globalAlpha *= 1 - c);
  4601. a.lineWidth =
  4602. 10;
  4603. a.lineCap = "round";
  4604. a.lineJoin = this.h ? "miter" : "round";
  4605. Oa ? (a.fillStyle = "#FFFFFF", a.strokeStyle = "#AAAAAA") : (a.fillStyle = this.color, a.strokeStyle = this.color);
  4606. if (b) a.beginPath(), a.arc(this.x, this.y, this.size + 5, 0, 2 * Math.PI, !1);
  4607. else {
  4608. this.qa();
  4609. a.beginPath();
  4610. var d = this.I();
  4611. a.moveTo(this.a[0].x, this.a[0].y);
  4612. for (c = 1; c <= d; ++c) {
  4613. var e = c % d;
  4614. a.lineTo(this.a[e].x, this.a[e].y)
  4615. }
  4616. }
  4617. a.closePath();
  4618. d = this.name.toLowerCase();
  4619. !this.n && kb && ":teams" != P ? -1 != ob.indexOf(d) ? (U.hasOwnProperty(d) || (U[d] = new Image, (d == "notreallyabot" ? U[d].src = "http://i.imgur.com/q5FdCkx.png" : U[d].src = "skins/" +
  4620. d + ".png")), c = 0 != U[d].width && U[d].complete ? U[d] : null) : c = null : c = null;
  4621. c = (e = c) ? -1 != Hb.indexOf(d) : !1;
  4622. b || a.stroke();
  4623. a.fill();
  4624. null == e || c || (a.save(), a.clip(), a.drawImage(e, this.x - this.size, this.y - this.size, 2 * this.size, 2 * this.size), a.restore());
  4625. (Oa || 15 < this.size) && !b && (a.strokeStyle = "#000000", a.globalAlpha *= .1, a.stroke());
  4626. a.globalAlpha = 1;
  4627. null != e && c && a.drawImage(e, this.x - 2 * this.size, this.y - 2 * this.size, 4 * this.size, 4 * this.size);
  4628. c = -1 != k.indexOf(this);
  4629. b = ~~this.y;
  4630. if (0 != this.id && (wa || c) && this.name && this.o && (null ==
  4631. e || -1 == Gb.indexOf(d))) {
  4632. e = this.o;
  4633. e.C(this.name);
  4634. e.M(this.l());
  4635. d = 0 >= this.id ? 1 : Math.ceil(10 * h) / 10;
  4636. e.ea(d);
  4637. var e = e.L(),
  4638. p = ~~(e.width / d),
  4639. g = ~~(e.height / d);
  4640. a.drawImage(e, ~~this.x - ~~(p / 2), b - ~~(g / 2), p, g);
  4641. b += e.height / 2 / d + 4
  4642. }
  4643. 0 < this.id && lb && (c || 0 == k.length && (!this.h || this.n) && 20 < this.size) && (null == this.O && (this.O = new va(this.l() / 2, "#FFFFFF", !0, "#000000")), c = this.O, c.M(this.l() / 2), c.C(~~(this.size * this.size / 100)), d = Math.ceil(10 * h) / 10, c.ea(d), e = c.L(), p = ~~(e.width / d), g = ~~(e.height / d), a.drawImage(e, ~~this.x - ~~(p / 2),
  4644. b - ~~(g / 2), p, g));
  4645. a.restore()
  4646. }
  4647. }
  4648. };
  4649. va.prototype = {
  4650. F: "",
  4651. S: "#000000",
  4652. U: !1,
  4653. v: "#000000",
  4654. u: 16,
  4655. p: null,
  4656. T: null,
  4657. k: !1,
  4658. D: 1,
  4659. M: function(a) {
  4660. this.u != a && (this.u = a, this.k = !0)
  4661. },
  4662. ea: function(a) {
  4663. this.D != a && (this.D = a, this.k = !0)
  4664. },
  4665. setStrokeColor: function(a) {
  4666. this.v != a && (this.v = a, this.k = !0)
  4667. },
  4668. C: function(a) {
  4669. a != this.F && (this.F = a, this.k = !0)
  4670. },
  4671. L: function() {
  4672. null == this.p && (this.p = document.createElement("canvas"), this.T = this.p.getContext("2d"));
  4673. if (this.k) {
  4674. this.k = !1;
  4675. var a = this.p,
  4676. b = this.T,
  4677. c = this.F,
  4678. d = this.D,
  4679. e = this.u,
  4680. p = e + "px Ubuntu";
  4681. b.font =
  4682. p;
  4683. var g = ~~(.2 * e);
  4684. a.width = (b.measureText(c).width + 6) * d;
  4685. a.height = (e + g) * d;
  4686. b.font = p;
  4687. b.scale(d, d);
  4688. b.globalAlpha = 1;
  4689. b.lineWidth = 3;
  4690. b.strokeStyle = this.v;
  4691. b.fillStyle = this.S;
  4692. this.U && b.strokeText(c, 3, e - g / 2);
  4693. b.fillText(c, 3, e - g / 2)
  4694. }
  4695. return this.p
  4696. }
  4697. };
  4698. Date.now || (Date.now = function() {
  4699. return (new Date).getTime()
  4700. });
  4701. (function() {
  4702. for (var a = ["ms", "moz", "webkit", "o"], b = 0; b < a.length && !d.requestAnimationFrame; ++b) d.requestAnimationFrame = d[a[b] + "RequestAnimationFrame"], d.cancelAnimationFrame = d[a[b] + "CancelAnimationFrame"] || d[a[b] +
  4703. "CancelRequestAnimationFrame"];
  4704. d.requestAnimationFrame || (d.requestAnimationFrame = function(a) {
  4705. return setTimeout(a, 1E3 / 60)
  4706. }, d.cancelAnimationFrame = function(a) {
  4707. clearTimeout(a)
  4708. })
  4709. })();
  4710. var rb = {
  4711. ka: function(a) {
  4712. function b(a, b, c, d, e) {
  4713. this.x = a;
  4714. this.y = b;
  4715. this.j = c;
  4716. this.g = d;
  4717. this.depth = e;
  4718. this.items = [];
  4719. this.c = []
  4720. }
  4721. var c = a.ma || 2,
  4722. d = a.na || 4;
  4723. b.prototype = {
  4724. x: 0,
  4725. y: 0,
  4726. j: 0,
  4727. g: 0,
  4728. depth: 0,
  4729. items: null,
  4730. c: null,
  4731. H: function(a) {
  4732. for (var b = 0; b < this.items.length; ++b) {
  4733. var c = this.items[b];
  4734. if (c.x >= a.x && c.y >= a.y && c.x < a.x + a.j && c.y < a.y + a.g) return !0
  4735. }
  4736. if (0 !=
  4737. this.c.length) {
  4738. var d = this;
  4739. return this.$(a, function(b) {
  4740. return d.c[b].H(a)
  4741. })
  4742. }
  4743. return !1
  4744. },
  4745. A: function(a, b) {
  4746. for (var c = 0; c < this.items.length; ++c) b(this.items[c]);
  4747. if (0 != this.c.length) {
  4748. var d = this;
  4749. this.$(a, function(c) {
  4750. d.c[c].A(a, b)
  4751. })
  4752. }
  4753. },
  4754. m: function(a) {
  4755. 0 != this.c.length ? this.c[this.Z(a)].m(a) : this.items.length >= c && this.depth < d ? (this.ha(), this.c[this.Z(a)].m(a)) : this.items.push(a)
  4756. },
  4757. Z: function(a) {
  4758. return a.x < this.x + this.j / 2 ? a.y < this.y + this.g / 2 ? 0 : 2 : a.y < this.y + this.g / 2 ? 1 : 3
  4759. },
  4760. $: function(a, b) {
  4761. return a.x < this.x + this.j / 2 &&
  4762. (a.y < this.y + this.g / 2 && b(0) || a.y >= this.y + this.g / 2 && b(2)) || a.x >= this.x + this.j / 2 && (a.y < this.y + this.g / 2 && b(1) || a.y >= this.y + this.g / 2 && b(3)) ? !0 : !1
  4763. },
  4764. ha: function() {
  4765. var a = this.depth + 1,
  4766. c = this.j / 2,
  4767. d = this.g / 2;
  4768. this.c.push(new b(this.x, this.y, c, d, a));
  4769. this.c.push(new b(this.x + c, this.y, c, d, a));
  4770. this.c.push(new b(this.x, this.y + d, c, d, a));
  4771. this.c.push(new b(this.x + c, this.y + d, c, d, a));
  4772. a = this.items;
  4773. this.items = [];
  4774. for (c = 0; c < a.length; c++) this.m(a[c])
  4775. },
  4776. clear: function() {
  4777. for (var a = 0; a < this.c.length; a++) this.c[a].clear();
  4778. this.items.length =
  4779. 0;
  4780. this.c.length = 0
  4781. }
  4782. };
  4783. var e = {
  4784. x: 0,
  4785. y: 0,
  4786. j: 0,
  4787. g: 0
  4788. };
  4789. return {
  4790. root: new b(a.ca, a.da, a.oa - a.ca, a.pa - a.da, 0),
  4791. m: function(a) {
  4792. this.root.m(a)
  4793. },
  4794. A: function(a, b) {
  4795. this.root.A(a, b)
  4796. },
  4797. ra: function(a, b, c, d, f) {
  4798. e.x = a;
  4799. e.y = b;
  4800. e.j = c;
  4801. e.g = d;
  4802. this.root.A(e, f)
  4803. },
  4804. H: function(a) {
  4805. return this.root.H(a)
  4806. },
  4807. clear: function() {
  4808. this.root.clear()
  4809. }
  4810. }
  4811. }
  4812. },
  4813. db = function() {
  4814. var a = new da(0, 0, 0, 32, "#ED1C24", ""),
  4815. b = document.createElement("canvas");
  4816. b.width = 32;
  4817. b.height = 32;
  4818. var c = b.getContext("2d");
  4819. return function() {
  4820. 0 < k.length && (a.color = k[0].color, a.B(k[0].name));
  4821. c.clearRect(0,
  4822. 0, 32, 32);
  4823. c.save();
  4824. c.translate(16, 16);
  4825. c.scale(.4, .4);
  4826. a.w(c);
  4827. c.restore();
  4828. var d = document.getElementById("favicon"),
  4829. e = d.cloneNode(!0);
  4830. //UPDATE -- NO IDEA WHAT I JUST DID THERE!
  4831. //e.setAttribute("href", b.toDataURL("image/png"));
  4832. d.parentNode.replaceChild(e, d)
  4833. }
  4834. }();
  4835. e(function() {
  4836. db()
  4837. });
  4838. e(function() {
  4839. +d.localStorage.wannaLogin && (d.localStorage.loginCache && jb(d.localStorage.loginCache), d.localStorage.fbPictureCache && e(".agario-profile-picture").attr("src", d.localStorage.fbPictureCache))
  4840. });
  4841. d.facebookLogin = function() {
  4842. d.localStorage.wannaLogin = 1
  4843. };
  4844. d.fbAsyncInit =
  4845. function() {
  4846. function a() {
  4847. d.localStorage.wannaLogin = 1;
  4848. null == d.FB ? alert("You seem to have something blocking Facebook on your browser, please check for any extensions") : d.FB.login(function(a) {
  4849. La(a)
  4850. }, {
  4851. scope: "public_profile, email"
  4852. })
  4853. }
  4854. d.FB.init({
  4855. appId: "677505792353827",
  4856. cookie: !0,
  4857. xfbml: !0,
  4858. status: !0,
  4859. version: "v2.2"
  4860. });
  4861. d.FB.Event.subscribe("auth.statusChange", function(b) {
  4862. +d.localStorage.wannaLogin && ("connected" == b.status ? La(b) : a())
  4863. });
  4864. d.facebookLogin = a
  4865. };
  4866. d.logout = function() {
  4867. B = null;
  4868. e("#helloContainer").attr("data-logged-in",
  4869. "0");
  4870. e("#helloContainer").attr("data-has-account-data", "0");
  4871. delete d.localStorage.wannaLogin;
  4872. delete d.localStorage.loginCache;
  4873. delete d.localStorage.fbPictureCache;
  4874. I()
  4875. };
  4876. var Fb = function() {
  4877. function a(a, b, c, d, e) {
  4878. var f = b.getContext("2d"),
  4879. h = b.width;
  4880. b = b.height;
  4881. a.color = e;
  4882. a.B(c);
  4883. a.size = d;
  4884. f.save();
  4885. f.translate(h / 2, b / 2);
  4886. a.w(f);
  4887. f.restore()
  4888. }
  4889. var b = new da(0, 0, 0, 32, "#5bc0de", "");
  4890. b.id = -1;
  4891. var c = new da(0, 0, 0, 32, "#5bc0de", "");
  4892. c.id = -1;
  4893. var d = document.createElement("canvas");
  4894. d.getContext("2d");
  4895. d.width = d.height = 70;
  4896. a(c, d,
  4897. "", 26, "#ebc0de");
  4898. return function() {
  4899. e(".cell-spinner").filter(":visible").each(function() {
  4900. var c = e(this),
  4901. f = Date.now(),
  4902. g = this.width,
  4903. h = this.height,
  4904. k = this.getContext("2d");
  4905. k.clearRect(0, 0, g, h);
  4906. k.save();
  4907. k.translate(g / 2, h / 2);
  4908. for (var m = 0; 10 > m; ++m) k.drawImage(d, (.1 * f + 80 * m) % (g + 140) - g / 2 - 70 - 35, h / 2 * Math.sin((.001 * f + m) % Math.PI * 2) - 35, 70, 70);
  4909. k.restore();
  4910. (c = c.attr("data-itr")) && (c = Z(c));
  4911. a(b, this, c || "", +e(this).attr("data-size"), "#5bc0de")
  4912. })
  4913. }
  4914. }();
  4915. d.createParty = function() {
  4916. Y(":party");
  4917. L = function(a) {
  4918. Ma("/#" + d.encodeURIComponent(a));
  4919. e(".partyToken").val("agar.io/#" + d.encodeURIComponent(a));
  4920. e("#helloContainer").attr("data-party-state", "1")
  4921. };
  4922. I()
  4923. };
  4924. d.joinParty = Wa;
  4925. d.cancelParty = function() {
  4926. Ma("/");
  4927. e("#helloContainer").attr("data-party-state", "0");
  4928. Y("");
  4929. I()
  4930. };
  4931. e(function() {
  4932. e(pb)
  4933. })
  4934. }
  4935. }
  4936. }
  4937. })(window, window.jQuery);
  4938.  
  4939. (function(i, s, o, g, r, a, m) {
  4940. i['GoogleAnalyticsObject'] = r;
  4941. i[r] = i[r] || function() {
  4942. (i[r].q = i[r].q || []).push(arguments)
  4943. }, i[r].l = 1 * new Date();
  4944. a = s.createElement(o),
  4945. m = s.getElementsByTagName(o)[0];
  4946. a.async = 1;
  4947. a.src = g;
  4948. m.parentNode.insertBefore(a, m)
  4949. })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'apos');
  4950.  
  4951. apos('create', 'UA-64394184-1', 'auto');
  4952. apos('send', 'pageview');
  4953.  
  4954. window.ignoreStream = false;
  4955. window.refreshTwitch = function() {
  4956. $.ajax({
  4957. url: "https://api.twitch.tv/kraken/streams/apostolique",
  4958. cache: false,
  4959. dataType: "jsonp"
  4960. }).done(function(data) {
  4961. if (data["stream"] == null) {
  4962. //console.log("Apostolique is not online!");
  4963. window.setMessage([]);
  4964. window.onmouseup = function() {};
  4965. window.ignoreStream = false;
  4966. } else {
  4967. //console.log("Apostolique is online!");
  4968. if (!window.ignoreStream) {
  4969. window.setMessage(["twitch.tv/apostolique is online right now!", "Click the screen to open the stream!", "Press E to ignore."]);
  4970. window.onmouseup = function() {
  4971. window.open("http://www.twitch.tv/apostolique");
  4972. };
  4973. }
  4974. }
  4975. }).fail(function() {});
  4976. }
  4977. setInterval(window.refreshTwitch, 60000);
  4978. window.refreshTwitch();
Add Comment
Please, Sign In to add comment