sails.io.js 133 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677
  1. /* eslint-disable */
  2. /**
  3. * To use sails.io.js in an AMD environment (e.g. with require.js),
  4. * replace this file with the sails.io.js file from the root of:
  5. * https://github.com/balderdashy/sails.io.js
  6. * and download a standalone copy of socket.io-client from:
  7. * https://github.com/socketio/socket.io-client
  8. * then follow the instructions at:
  9. * https://github.com/balderdashy/sails.io.js#requirejsamd-usage
  10. */
  11. // socket.io-client version 2.0.3
  12. // https://github.com/socketio/socket.io-client
  13. !function(a,b){"object"==typeof exports&&"object"==typeof module?module.exports=b():"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?exports.io=b():a.io=b()}(this,function(){return function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={exports:{},id:d,loaded:!1};return a[d].call(e.exports,e,e.exports,b),e.loaded=!0,e.exports}var c={};return b.m=a,b.c=c,b.p="",b(0)}([function(a,b,c){"use strict";function d(a,b){"object"===("undefined"==typeof a?"undefined":e(a))&&(b=a,a=void 0),b=b||{};var c,d=f(a),g=d.source,k=d.id,l=d.path,m=j[k]&&l in j[k].nsps,n=b.forceNew||b["force new connection"]||!1===b.multiplex||m;return n?(i("ignoring socket cache for %s",g),c=h(g,b)):(j[k]||(i("new io instance for %s",g),j[k]=h(g,b)),c=j[k]),d.query&&!b.query&&(b.query=d.query),c.socket(d.path,b)}var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},f=c(1),g=c(7),h=c(13),i=c(3)("socket.io-client");a.exports=b=d;var j=b.managers={};b.protocol=g.protocol,b.connect=d,b.Manager=c(13),b.Socket=c(39)},function(a,b,c){(function(b){"use strict";function d(a,c){var d=a;c=c||b.location,null==a&&(a=c.protocol+"//"+c.host),"string"==typeof a&&("/"===a.charAt(0)&&(a="/"===a.charAt(1)?c.protocol+a:c.host+a),/^(https?|wss?):\/\//.test(a)||(f("protocol-less url %s",a),a="undefined"!=typeof c?c.protocol+"//"+a:"https://"+a),f("parse %s",a),d=e(a)),d.port||(/^(http|ws)$/.test(d.protocol)?d.port="80":/^(http|ws)s$/.test(d.protocol)&&(d.port="443")),d.path=d.path||"/";var g=d.host.indexOf(":")!==-1,h=g?"["+d.host+"]":d.host;return d.id=d.protocol+"://"+h+":"+d.port,d.href=d.protocol+"://"+h+(c&&c.port===d.port?"":":"+d.port),d}var e=c(2),f=c(3)("socket.io-client:url");a.exports=d}).call(b,function(){return this}())},function(a,b){var c=/^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,d=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];a.exports=function(a){var b=a,e=a.indexOf("["),f=a.indexOf("]");e!=-1&&f!=-1&&(a=a.substring(0,e)+a.substring(e,f).replace(/:/g,";")+a.substring(f,a.length));for(var g=c.exec(a||""),h={},i=14;i--;)h[d[i]]=g[i]||"";return e!=-1&&f!=-1&&(h.source=b,h.host=h.host.substring(1,h.host.length-1).replace(/;/g,":"),h.authority=h.authority.replace("[","").replace("]","").replace(/;/g,":"),h.ipv6uri=!0),h}},function(a,b,c){(function(d){function e(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type)||"undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)}function f(a){var c=this.useColors;if(a[0]=(c?"%c":"")+this.namespace+(c?" %c":" ")+a[0]+(c?"%c ":" ")+"+"+b.humanize(this.diff),c){var d="color: "+this.color;a.splice(1,0,d,"color: inherit");var e=0,f=0;a[0].replace(/%[a-zA-Z%]/g,function(a){"%%"!==a&&(e++,"%c"===a&&(f=e))}),a.splice(f,0,d)}}function g(){return"object"==typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function h(a){try{null==a?b.storage.removeItem("debug"):b.storage.debug=a}catch(c){}}function i(){var a;try{a=b.storage.debug}catch(c){}return!a&&"undefined"!=typeof d&&"env"in d&&(a=d.env.DEBUG),a}function j(){try{return window.localStorage}catch(a){}}b=a.exports=c(5),b.log=g,b.formatArgs=f,b.save=h,b.load=i,b.useColors=e,b.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:j(),b.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"],b.formatters.j=function(a){try{return JSON.stringify(a)}catch(b){return"[UnexpectedJSONParseError]: "+b.message}},b.enable(i())}).call(b,c(4))},function(a,b){function c(){throw new Error("setTimeout has not been defined")}function d(){throw new Error("clearTimeout has not been defined")}function e(a){if(k===setTimeout)return setTimeout(a,0);if((k===c||!k)&&setTimeout)return k=setTimeout,setTimeout(a,0);try{return k(a,0)}catch(b){try{return k.call(null,a,0)}catch(b){return k.call(this,a,0)}}}function f(a){if(l===clearTimeout)return clearTimeout(a);if((l===d||!l)&&clearTimeout)return l=clearTimeout,clearTimeout(a);try{return l(a)}catch(b){try{return l.call(null,a)}catch(b){return l.call(this,a)}}}function g(){p&&n&&(p=!1,n.length?o=n.concat(o):q=-1,o.length&&h())}function h(){if(!p){var a=e(g);p=!0;for(var b=o.length;b;){for(n=o,o=[];++q<b;)n&&n[q].run();q=-1,b=o.length}n=null,p=!1,f(a)}}function i(a,b){this.fun=a,this.array=b}function j(){}var k,l,m=a.exports={};!function(){try{k="function"==typeof setTimeout?setTimeout:c}catch(a){k=c}try{l="function"==typeof clearTimeout?clearTimeout:d}catch(a){l=d}}();var n,o=[],p=!1,q=-1;m.nextTick=function(a){var b=new Array(arguments.length-1);if(arguments.length>1)for(var c=1;c<arguments.length;c++)b[c-1]=arguments[c];o.push(new i(a,b)),1!==o.length||p||e(h)},i.prototype.run=function(){this.fun.apply(null,this.array)},m.title="browser",m.browser=!0,m.env={},m.argv=[],m.version="",m.versions={},m.on=j,m.addListener=j,m.once=j,m.off=j,m.removeListener=j,m.removeAllListeners=j,m.emit=j,m.prependListener=j,m.prependOnceListener=j,m.listeners=function(a){return[]},m.binding=function(a){throw new Error("process.binding is not supported")},m.cwd=function(){return"/"},m.chdir=function(a){throw new Error("process.chdir is not supported")},m.umask=function(){return 0}},function(a,b,c){function d(a){var c,d=0;for(c in a)d=(d<<5)-d+a.charCodeAt(c),d|=0;return b.colors[Math.abs(d)%b.colors.length]}function e(a){function c(){if(c.enabled){var a=c,d=+new Date,e=d-(j||d);a.diff=e,a.prev=j,a.curr=d,j=d;for(var f=new Array(arguments.length),g=0;g<f.length;g++)f[g]=arguments[g];f[0]=b.coerce(f[0]),"string"!=typeof f[0]&&f.unshift("%O");var h=0;f[0]=f[0].replace(/%([a-zA-Z%])/g,function(c,d){if("%%"===c)return c;h++;var e=b.formatters[d];if("function"==typeof e){var g=f[h];c=e.call(a,g),f.splice(h,1),h--}return c}),b.formatArgs.call(a,f);var i=c.log||b.log||console.log.bind(console);i.apply(a,f)}}return c.namespace=a,c.enabled=b.enabled(a),c.useColors=b.useColors(),c.color=d(a),"function"==typeof b.init&&b.init(c),c}function f(a){b.save(a),b.names=[],b.skips=[];for(var c=("string"==typeof a?a:"").split(/[\s,]+/),d=c.length,e=0;e<d;e++)c[e]&&(a=c[e].replace(/\*/g,".*?"),"-"===a[0]?b.skips.push(new RegExp("^"+a.substr(1)+"$")):b.names.push(new RegExp("^"+a+"$")))}function g(){b.enable("")}function h(a){var c,d;for(c=0,d=b.skips.length;c<d;c++)if(b.skips[c].test(a))return!1;for(c=0,d=b.names.length;c<d;c++)if(b.names[c].test(a))return!0;return!1}function i(a){return a instanceof Error?a.stack||a.message:a}b=a.exports=e.debug=e["default"]=e,b.coerce=i,b.disable=g,b.enable=f,b.enabled=h,b.humanize=c(6),b.names=[],b.skips=[],b.formatters={};var j},function(a,b){function c(a){if(a=String(a),!(a.length>100)){var b=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(a);if(b){var c=parseFloat(b[1]),d=(b[2]||"ms").toLowerCase();switch(d){case"years":case"year":case"yrs":case"yr":case"y":return c*k;case"days":case"day":case"d":return c*j;case"hours":case"hour":case"hrs":case"hr":case"h":return c*i;case"minutes":case"minute":case"mins":case"min":case"m":return c*h;case"seconds":case"second":case"secs":case"sec":case"s":return c*g;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}}}function d(a){return a>=j?Math.round(a/j)+"d":a>=i?Math.round(a/i)+"h":a>=h?Math.round(a/h)+"m":a>=g?Math.round(a/g)+"s":a+"ms"}function e(a){return f(a,j,"day")||f(a,i,"hour")||f(a,h,"minute")||f(a,g,"second")||a+" ms"}function f(a,b,c){if(!(a<b))return a<1.5*b?Math.floor(a/b)+" "+c:Math.ceil(a/b)+" "+c+"s"}var g=1e3,h=60*g,i=60*h,j=24*i,k=365.25*j;a.exports=function(a,b){b=b||{};var f=typeof a;if("string"===f&&a.length>0)return c(a);if("number"===f&&isNaN(a)===!1)return b["long"]?e(a):d(a);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(a))}},function(a,b,c){function d(){}function e(a){var c=""+a.type;return b.BINARY_EVENT!==a.type&&b.BINARY_ACK!==a.type||(c+=a.attachments+"-"),a.nsp&&"/"!==a.nsp&&(c+=a.nsp+","),null!=a.id&&(c+=a.id),null!=a.data&&(c+=JSON.stringify(a.data)),l("encoded %j as %s",a,c),c}function f(a,b){function c(a){var c=o.deconstructPacket(a),d=e(c.packet),f=c.buffers;f.unshift(d),b(f)}o.removeBlobs(a,c)}function g(){this.reconstructor=null}function h(a){var c=0,d={type:Number(a.charAt(0))};if(null==b.types[d.type])return k();if(b.BINARY_EVENT===d.type||b.BINARY_ACK===d.type){for(var e="";"-"!==a.charAt(++c)&&(e+=a.charAt(c),c!=a.length););if(e!=Number(e)||"-"!==a.charAt(c))throw new Error("Illegal attachments");d.attachments=Number(e)}if("/"===a.charAt(c+1))for(d.nsp="";++c;){var f=a.charAt(c);if(","===f)break;if(d.nsp+=f,c===a.length)break}else d.nsp="/";var g=a.charAt(c+1);if(""!==g&&Number(g)==g){for(d.id="";++c;){var f=a.charAt(c);if(null==f||Number(f)!=f){--c;break}if(d.id+=a.charAt(c),c===a.length)break}d.id=Number(d.id)}return a.charAt(++c)&&(d=i(d,a.substr(c))),l("decoded %s as %j",a,d),d}function i(a,b){try{a.data=JSON.parse(b)}catch(c){return k()}return a}function j(a){this.reconPack=a,this.buffers=[]}function k(){return{type:b.ERROR,data:"parser error"}}var l=c(3)("socket.io-parser"),m=c(8),n=c(9),o=c(11),p=c(12);b.protocol=4,b.types=["CONNECT","DISCONNECT","EVENT","ACK","ERROR","BINARY_EVENT","BINARY_ACK"],b.CONNECT=0,b.DISCONNECT=1,b.EVENT=2,b.ACK=3,b.ERROR=4,b.BINARY_EVENT=5,b.BINARY_ACK=6,b.Encoder=d,b.Decoder=g,d.prototype.encode=function(a,c){if(a.type!==b.EVENT&&a.type!==b.ACK||!n(a.data)||(a.type=a.type===b.EVENT?b.BINARY_EVENT:b.BINARY_ACK),l("encoding packet %j",a),b.BINARY_EVENT===a.type||b.BINARY_ACK===a.type)f(a,c);else{var d=e(a);c([d])}},m(g.prototype),g.prototype.add=function(a){var c;if("string"==typeof a)c=h(a),b.BINARY_EVENT===c.type||b.BINARY_ACK===c.type?(this.reconstructor=new j(c),0===this.reconstructor.reconPack.attachments&&this.emit("decoded",c)):this.emit("decoded",c);else{if(!p(a)&&!a.base64)throw new Error("Unknown type: "+a);if(!this.reconstructor)throw new Error("got binary data when not reconstructing a packet");c=this.reconstructor.takeBinaryData(a),c&&(this.reconstructor=null,this.emit("decoded",c))}},g.prototype.destroy=function(){this.reconstructor&&this.reconstructor.finishedReconstruction()},j.prototype.takeBinaryData=function(a){if(this.buffers.push(a),this.buffers.length===this.reconPack.attachments){var b=o.reconstructPacket(this.reconPack,this.buffers);return this.finishedReconstruction(),b}return null},j.prototype.finishedReconstruction=function(){this.reconPack=null,this.buffers=[]}},function(a,b,c){function d(a){if(a)return e(a)}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}a.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks["$"+a]=this._callbacks["$"+a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){this.off(a,c),b.apply(this,arguments)}return c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks["$"+a];if(!c)return this;if(1==arguments.length)return delete this._callbacks["$"+a],this;for(var d,e=0;e<c.length;e++)if(d=c[e],d===b||d.fn===b){c.splice(e,1);break}return this},d.prototype.emit=function(a){this._callbacks=this._callbacks||{};var b=[].slice.call(arguments,1),c=this._callbacks["$"+a];if(c){c=c.slice(0);for(var d=0,e=c.length;d<e;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks["$"+a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},function(a,b,c){(function(b){function d(a){if(!a||"object"!=typeof a)return!1;if(e(a)){for(var c=0,f=a.length;c<f;c++)if(d(a[c]))return!0;return!1}if("function"==typeof b.Buffer&&b.Buffer.isBuffer&&b.Buffer.isBuffer(a)||"function"==typeof b.ArrayBuffer&&a instanceof ArrayBuffer||g&&a instanceof Blob||h&&a instanceof File)return!0;if(a.toJSON&&"function"==typeof a.toJSON&&1===arguments.length)return d(a.toJSON(),!0);for(var i in a)if(Object.prototype.hasOwnProperty.call(a,i)&&d(a[i]))return!0;return!1}var e=c(10),f=Object.prototype.toString,g="function"==typeof b.Blob||"[object BlobConstructor]"===f.call(b.Blob),h="function"==typeof b.File||"[object FileConstructor]"===f.call(b.File);a.exports=d}).call(b,function(){return this}())},function(a,b){var c={}.toString;a.exports=Array.isArray||function(a){return"[object Array]"==c.call(a)}},function(a,b,c){(function(a){function d(a,b){if(!a)return a;if(g(a)){var c={_placeholder:!0,num:b.length};return b.push(a),c}if(f(a)){for(var e=new Array(a.length),h=0;h<a.length;h++)e[h]=d(a[h],b);return e}if("object"==typeof a&&!(a instanceof Date)){var e={};for(var i in a)e[i]=d(a[i],b);return e}return a}function e(a,b){if(!a)return a;if(a&&a._placeholder)return b[a.num];if(f(a))for(var c=0;c<a.length;c++)a[c]=e(a[c],b);else if("object"==typeof a)for(var d in a)a[d]=e(a[d],b);return a}var f=c(10),g=c(12),h=Object.prototype.toString,i="function"==typeof a.Blob||"[object BlobConstructor]"===h.call(a.Blob),j="function"==typeof a.File||"[object FileConstructor]"===h.call(a.File);b.deconstructPacket=function(a){var b=[],c=a.data,e=a;return e.data=d(c,b),e.attachments=b.length,{packet:e,buffers:b}},b.reconstructPacket=function(a,b){return a.data=e(a.data,b),a.attachments=void 0,a},b.removeBlobs=function(a,b){function c(a,h,k){if(!a)return a;if(i&&a instanceof Blob||j&&a instanceof File){d++;var l=new FileReader;l.onload=function(){k?k[h]=this.result:e=this.result,--d||b(e)},l.readAsArrayBuffer(a)}else if(f(a))for(var m=0;m<a.length;m++)c(a[m],m,a);else if("object"==typeof a&&!g(a))for(var n in a)c(a[n],n,a)}var d=0,e=a;c(e),d||b(e)}}).call(b,function(){return this}())},function(a,b){(function(b){function c(a){return b.Buffer&&b.Buffer.isBuffer(a)||b.ArrayBuffer&&a instanceof ArrayBuffer}a.exports=c}).call(b,function(){return this}())},function(a,b,c){"use strict";function d(a,b){if(!(this instanceof d))return new d(a,b);a&&"object"===("undefined"==typeof a?"undefined":e(a))&&(b=a,a=void 0),b=b||{},b.path=b.path||"/socket.io",this.nsps={},this.subs=[],this.opts=b,this.reconnection(b.reconnection!==!1),this.reconnectionAttempts(b.reconnectionAttempts||1/0),this.reconnectionDelay(b.reconnectionDelay||1e3),this.reconnectionDelayMax(b.reconnectionDelayMax||5e3),this.randomizationFactor(b.randomizationFactor||.5),this.backoff=new n({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(null==b.timeout?2e4:b.timeout),this.readyState="closed",this.uri=a,this.connecting=[],this.lastPing=null,this.encoding=!1,this.packetBuffer=[];var c=b.parser||i;this.encoder=new c.Encoder,this.decoder=new c.Decoder,this.autoConnect=b.autoConnect!==!1,this.autoConnect&&this.open()}var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},f=c(14),g=c(39),h=c(8),i=c(7),j=c(41),k=c(42),l=c(3)("socket.io-client:manager"),m=c(37),n=c(43),o=Object.prototype.hasOwnProperty;a.exports=d,d.prototype.emitAll=function(){this.emit.apply(this,arguments);for(var a in this.nsps)o.call(this.nsps,a)&&this.nsps[a].emit.apply(this.nsps[a],arguments)},d.prototype.updateSocketIds=function(){for(var a in this.nsps)o.call(this.nsps,a)&&(this.nsps[a].id=this.generateId(a))},d.prototype.generateId=function(a){return("/"===a?"":a+"#")+this.engine.id},h(d.prototype),d.prototype.reconnection=function(a){return arguments.length?(this._reconnection=!!a,this):this._reconnection},d.prototype.reconnectionAttempts=function(a){return arguments.length?(this._reconnectionAttempts=a,this):this._reconnectionAttempts},d.prototype.reconnectionDelay=function(a){return arguments.length?(this._reconnectionDelay=a,this.backoff&&this.backoff.setMin(a),this):this._reconnectionDelay},d.prototype.randomizationFactor=function(a){return arguments.length?(this._randomizationFactor=a,this.backoff&&this.backoff.setJitter(a),this):this._randomizationFactor},d.prototype.reconnectionDelayMax=function(a){return arguments.length?(this._reconnectionDelayMax=a,this.backoff&&this.backoff.setMax(a),this):this._reconnectionDelayMax},d.prototype.timeout=function(a){return arguments.length?(this._timeout=a,this):this._timeout},d.prototype.maybeReconnectOnOpen=function(){!this.reconnecting&&this._reconnection&&0===this.backoff.attempts&&this.reconnect()},d.prototype.open=d.prototype.connect=function(a,b){if(l("readyState %s",this.readyState),~this.readyState.indexOf("open"))return this;l("opening %s",this.uri),this.engine=f(this.uri,this.opts);var c=this.engine,d=this;this.readyState="opening",this.skipReconnect=!1;var e=j(c,"open",function(){d.onopen(),a&&a()}),g=j(c,"error",function(b){if(l("connect_error"),d.cleanup(),d.readyState="closed",d.emitAll("connect_error",b),a){var c=new Error("Connection error");c.data=b,a(c)}else d.maybeReconnectOnOpen()});if(!1!==this._timeout){var h=this._timeout;l("connect attempt will timeout after %d",h);var i=setTimeout(function(){l("connect attempt timed out after %d",h),e.destroy(),c.close(),c.emit("error","timeout"),d.emitAll("connect_timeout",h)},h);this.subs.push({destroy:function(){clearTimeout(i)}})}return this.subs.push(e),this.subs.push(g),this},d.prototype.onopen=function(){l("open"),this.cleanup(),this.readyState="open",this.emit("open");var a=this.engine;this.subs.push(j(a,"data",k(this,"ondata"))),this.subs.push(j(a,"ping",k(this,"onping"))),this.subs.push(j(a,"pong",k(this,"onpong"))),this.subs.push(j(a,"error",k(this,"onerror"))),this.subs.push(j(a,"close",k(this,"onclose"))),this.subs.push(j(this.decoder,"decoded",k(this,"ondecoded")))},d.prototype.onping=function(){this.lastPing=new Date,this.emitAll("ping")},d.prototype.onpong=function(){this.emitAll("pong",new Date-this.lastPing)},d.prototype.ondata=function(a){this.decoder.add(a)},d.prototype.ondecoded=function(a){this.emit("packet",a)},d.prototype.onerror=function(a){l("error",a),this.emitAll("error",a)},d.prototype.socket=function(a,b){function c(){~m(e.connecting,d)||e.connecting.push(d)}var d=this.nsps[a];if(!d){d=new g(this,a,b),this.nsps[a]=d;var e=this;d.on("connecting",c),d.on("connect",function(){d.id=e.generateId(a)}),this.autoConnect&&c()}return d},d.prototype.destroy=function(a){var b=m(this.connecting,a);~b&&this.connecting.splice(b,1),this.connecting.length||this.close()},d.prototype.packet=function(a){l("writing packet %j",a);var b=this;a.query&&0===a.type&&(a.nsp+="?"+a.query),b.encoding?b.packetBuffer.push(a):(b.encoding=!0,this.encoder.encode(a,function(c){for(var d=0;d<c.length;d++)b.engine.write(c[d],a.options);b.encoding=!1,b.processPacketQueue()}))},d.prototype.processPacketQueue=function(){if(this.packetBuffer.length>0&&!this.encoding){var a=this.packetBuffer.shift();this.packet(a)}},d.prototype.cleanup=function(){l("cleanup");for(var a=this.subs.length,b=0;b<a;b++){var c=this.subs.shift();c.destroy()}this.packetBuffer=[],this.encoding=!1,this.lastPing=null,this.decoder.destroy()},d.prototype.close=d.prototype.disconnect=function(){l("disconnect"),this.skipReconnect=!0,this.reconnecting=!1,"opening"===this.readyState&&this.cleanup(),this.backoff.reset(),this.readyState="closed",this.engine&&this.engine.close()},d.prototype.onclose=function(a){l("onclose"),this.cleanup(),this.backoff.reset(),this.readyState="closed",this.emit("close",a),this._reconnection&&!this.skipReconnect&&this.reconnect()},d.prototype.reconnect=function(){if(this.reconnecting||this.skipReconnect)return this;var a=this;if(this.backoff.attempts>=this._reconnectionAttempts)l("reconnect failed"),this.backoff.reset(),this.emitAll("reconnect_failed"),this.reconnecting=!1;else{var b=this.backoff.duration();l("will wait %dms before reconnect attempt",b),this.reconnecting=!0;var c=setTimeout(function(){a.skipReconnect||(l("attempting reconnect"),a.emitAll("reconnect_attempt",a.backoff.attempts),a.emitAll("reconnecting",a.backoff.attempts),a.skipReconnect||a.open(function(b){b?(l("reconnect attempt error"),a.reconnecting=!1,a.reconnect(),a.emitAll("reconnect_error",b.data)):(l("reconnect success"),a.onreconnect())}))},b);this.subs.push({destroy:function(){clearTimeout(c)}})}},d.prototype.onreconnect=function(){var a=this.backoff.attempts;this.reconnecting=!1,this.backoff.reset(),this.updateSocketIds(),this.emitAll("reconnect",a)}},function(a,b,c){a.exports=c(15)},function(a,b,c){a.exports=c(16),a.exports.parser=c(23)},function(a,b,c){(function(b){function d(a,c){if(!(this instanceof d))return new d(a,c);c=c||{},a&&"object"==typeof a&&(c=a,a=null),a?(a=k(a),c.hostname=a.host,c.secure="https"===a.protocol||"wss"===a.protocol,c.port=a.port,a.query&&(c.query=a.query)):c.host&&(c.hostname=k(c.host).host),this.secure=null!=c.secure?c.secure:b.location&&"https:"===location.protocol,c.hostname&&!c.port&&(c.port=this.secure?"443":"80"),this.agent=c.agent||!1,this.hostname=c.hostname||(b.location?location.hostname:"localhost"),this.port=c.port||(b.location&&location.port?location.port:this.secure?443:80),this.query=c.query||{},"string"==typeof this.query&&(this.query=m.decode(this.query)),this.upgrade=!1!==c.upgrade,this.path=(c.path||"/engine.io").replace(/\/$/,"")+"/",this.forceJSONP=!!c.forceJSONP,this.jsonp=!1!==c.jsonp,this.forceBase64=!!c.forceBase64,this.enablesXDR=!!c.enablesXDR,this.timestampParam=c.timestampParam||"t",this.timestampRequests=c.timestampRequests,this.transports=c.transports||["polling","websocket"],this.transportOptions=c.transportOptions||{},this.readyState="",this.writeBuffer=[],this.prevBufferLen=0,this.policyPort=c.policyPort||843,this.rememberUpgrade=c.rememberUpgrade||!1,this.binaryType=null,this.onlyBinaryUpgrades=c.onlyBinaryUpgrades,this.perMessageDeflate=!1!==c.perMessageDeflate&&(c.perMessageDeflate||{}),!0===this.perMessageDeflate&&(this.perMessageDeflate={}),this.perMessageDeflate&&null==this.perMessageDeflate.threshold&&(this.perMessageDeflate.threshold=1024),this.pfx=c.pfx||null,this.key=c.key||null,this.passphrase=c.passphrase||null,this.cert=c.cert||null,this.ca=c.ca||null,this.ciphers=c.ciphers||null,this.rejectUnauthorized=void 0===c.rejectUnauthorized||c.rejectUnauthorized,this.forceNode=!!c.forceNode;var e="object"==typeof b&&b;e.global===e&&(c.extraHeaders&&Object.keys(c.extraHeaders).length>0&&(this.extraHeaders=c.extraHeaders),c.localAddress&&(this.localAddress=c.localAddress)),this.id=null,this.upgrades=null,this.pingInterval=null,this.pingTimeout=null,this.pingIntervalTimer=null,this.pingTimeoutTimer=null,this.open()}function e(a){var b={};for(var c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b}var f=c(17),g=c(8),h=c(3)("engine.io-client:socket"),i=c(37),j=c(23),k=c(2),l=c(38),m=c(31);a.exports=d,d.priorWebsocketSuccess=!1,g(d.prototype),d.protocol=j.protocol,d.Socket=d,d.Transport=c(22),d.transports=c(17),d.parser=c(23),d.prototype.createTransport=function(a){h('creating transport "%s"',a);var b=e(this.query);b.EIO=j.protocol,b.transport=a;var c=this.transportOptions[a]||{};this.id&&(b.sid=this.id);var d=new f[a]({query:b,socket:this,agent:c.agent||this.agent,hostname:c.hostname||this.hostname,port:c.port||this.port,secure:c.secure||this.secure,path:c.path||this.path,forceJSONP:c.forceJSONP||this.forceJSONP,jsonp:c.jsonp||this.jsonp,forceBase64:c.forceBase64||this.forceBase64,enablesXDR:c.enablesXDR||this.enablesXDR,timestampRequests:c.timestampRequests||this.timestampRequests,timestampParam:c.timestampParam||this.timestampParam,policyPort:c.policyPort||this.policyPort,pfx:c.pfx||this.pfx,key:c.key||this.key,passphrase:c.passphrase||this.passphrase,cert:c.cert||this.cert,ca:c.ca||this.ca,ciphers:c.ciphers||this.ciphers,rejectUnauthorized:c.rejectUnauthorized||this.rejectUnauthorized,perMessageDeflate:c.perMessageDeflate||this.perMessageDeflate,extraHeaders:c.extraHeaders||this.extraHeaders,forceNode:c.forceNode||this.forceNode,localAddress:c.localAddress||this.localAddress,requestTimeout:c.requestTimeout||this.requestTimeout,protocols:c.protocols||void 0});return d},d.prototype.open=function(){var a;if(this.rememberUpgrade&&d.priorWebsocketSuccess&&this.transports.indexOf("websocket")!==-1)a="websocket";else{if(0===this.transports.length){var b=this;return void setTimeout(function(){b.emit("error","No transports available")},0)}a=this.transports[0]}this.readyState="opening";try{a=this.createTransport(a)}catch(c){return this.transports.shift(),void this.open()}a.open(),this.setTransport(a)},d.prototype.setTransport=function(a){h("setting transport %s",a.name);var b=this;this.transport&&(h("clearing existing transport %s",this.transport.name),this.transport.removeAllListeners()),this.transport=a,a.on("drain",function(){b.onDrain()}).on("packet",function(a){b.onPacket(a)}).on("error",function(a){b.onError(a)}).on("close",function(){b.onClose("transport close")})},d.prototype.probe=function(a){function b(){if(m.onlyBinaryUpgrades){var b=!this.supportsBinary&&m.transport.supportsBinary;l=l||b}l||(h('probe transport "%s" opened',a),k.send([{type:"ping",data:"probe"}]),k.once("packet",function(b){if(!l)if("pong"===b.type&&"probe"===b.data){if(h('probe transport "%s" pong',a),m.upgrading=!0,m.emit("upgrading",k),!k)return;d.priorWebsocketSuccess="websocket"===k.name,h('pausing current transport "%s"',m.transport.name),m.transport.pause(function(){l||"closed"!==m.readyState&&(h("changing transport and sending upgrade packet"),j(),m.setTransport(k),k.send([{type:"upgrade"}]),m.emit("upgrade",k),k=null,m.upgrading=!1,m.flush())})}else{h('probe transport "%s" failed',a);var c=new Error("probe error");c.transport=k.name,m.emit("upgradeError",c)}}))}function c(){l||(l=!0,j(),k.close(),k=null)}function e(b){var d=new Error("probe error: "+b);d.transport=k.name,c(),h('probe transport "%s" failed because of error: %s',a,b),m.emit("upgradeError",d)}function f(){e("transport closed")}function g(){e("socket closed")}function i(a){k&&a.name!==k.name&&(h('"%s" works - aborting "%s"',a.name,k.name),c())}function j(){k.removeListener("open",b),k.removeListener("error",e),k.removeListener("close",f),m.removeListener("close",g),m.removeListener("upgrading",i)}h('probing transport "%s"',a);var k=this.createTransport(a,{probe:1}),l=!1,m=this;d.priorWebsocketSuccess=!1,k.once("open",b),k.once("error",e),k.once("close",f),this.once("close",g),this.once("upgrading",i),k.open()},d.prototype.onOpen=function(){if(h("socket open"),this.readyState="open",d.priorWebsocketSuccess="websocket"===this.transport.name,this.emit("open"),this.flush(),"open"===this.readyState&&this.upgrade&&this.transport.pause){h("starting upgrade probes");for(var a=0,b=this.upgrades.length;a<b;a++)this.probe(this.upgrades[a])}},d.prototype.onPacket=function(a){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState)switch(h('socket receive: type "%s", data "%s"',a.type,a.data),this.emit("packet",a),this.emit("heartbeat"),a.type){case"open":this.onHandshake(l(a.data));break;case"pong":this.setPing(),this.emit("pong");break;case"error":var b=new Error("server error");b.code=a.data,this.onError(b);break;case"message":this.emit("data",a.data),this.emit("message",a.data)}else h('packet received with socket readyState "%s"',this.readyState)},d.prototype.onHandshake=function(a){this.emit("handshake",a),this.id=a.sid,this.transport.query.sid=a.sid,this.upgrades=this.filterUpgrades(a.upgrades),this.pingInterval=a.pingInterval,this.pingTimeout=a.pingTimeout,this.onOpen(),"closed"!==this.readyState&&(this.setPing(),this.removeListener("heartbeat",this.onHeartbeat),this.on("heartbeat",this.onHeartbeat))},d.prototype.onHeartbeat=function(a){clearTimeout(this.pingTimeoutTimer);var b=this;b.pingTimeoutTimer=setTimeout(function(){"closed"!==b.readyState&&b.onClose("ping timeout")},a||b.pingInterval+b.pingTimeout)},d.prototype.setPing=function(){var a=this;clearTimeout(a.pingIntervalTimer),a.pingIntervalTimer=setTimeout(function(){h("writing ping packet - expecting pong within %sms",a.pingTimeout),a.ping(),a.onHeartbeat(a.pingTimeout)},a.pingInterval)},d.prototype.ping=function(){var a=this;this.sendPacket("ping",function(){a.emit("ping")})},d.prototype.onDrain=function(){this.writeBuffer.splice(0,this.prevBufferLen),this.prevBufferLen=0,0===this.writeBuffer.length?this.emit("drain"):this.flush()},d.prototype.flush=function(){"closed"!==this.readyState&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length&&(h("flushing %d packets in socket",this.writeBuffer.length),this.transport.send(this.writeBuffer),this.prevBufferLen=this.writeBuffer.length,this.emit("flush"))},d.prototype.write=d.prototype.send=function(a,b,c){return this.sendPacket("message",a,b,c),this},d.prototype.sendPacket=function(a,b,c,d){if("function"==typeof b&&(d=b,b=void 0),"function"==typeof c&&(d=c,c=null),"closing"!==this.readyState&&"closed"!==this.readyState){c=c||{},c.compress=!1!==c.compress;var e={type:a,data:b,options:c};this.emit("packetCreate",e),this.writeBuffer.push(e),d&&this.once("flush",d),this.flush()}},d.prototype.close=function(){function a(){d.onClose("forced close"),h("socket closing - telling transport to close"),d.transport.close()}function b(){d.removeListener("upgrade",b),d.removeListener("upgradeError",b),a()}function c(){d.once("upgrade",b),d.once("upgradeError",b)}if("opening"===this.readyState||"open"===this.readyState){this.readyState="closing";var d=this;this.writeBuffer.length?this.once("drain",function(){this.upgrading?c():a()}):this.upgrading?c():a()}return this},d.prototype.onError=function(a){h("socket error %j",a),d.priorWebsocketSuccess=!1,this.emit("error",a),this.onClose("transport error",a)},d.prototype.onClose=function(a,b){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState){h('socket close with reason: "%s"',a);var c=this;clearTimeout(this.pingIntervalTimer),clearTimeout(this.pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),this.readyState="closed",this.id=null,this.emit("close",a,b),c.writeBuffer=[],c.prevBufferLen=0}},d.prototype.filterUpgrades=function(a){for(var b=[],c=0,d=a.length;c<d;c++)~i(this.transports,a[c])&&b.push(a[c]);return b}}).call(b,function(){return this}())},function(a,b,c){(function(a){function d(b){var c,d=!1,h=!1,i=!1!==b.jsonp;if(a.location){var j="https:"===location.protocol,k=location.port;k||(k=j?443:80),d=b.hostname!==location.hostname||k!==b.port,h=b.secure!==j}if(b.xdomain=d,b.xscheme=h,c=new e(b),"open"in c&&!b.forceJSONP)return new f(b);if(!i)throw new Error("JSONP disabled");return new g(b)}var e=c(18),f=c(20),g=c(34),h=c(35);b.polling=d,b.websocket=h}).call(b,function(){return this}())},function(a,b,c){(function(b){var d=c(19);a.exports=function(a){var c=a.xdomain,e=a.xscheme,f=a.enablesXDR;try{if("undefined"!=typeof XMLHttpRequest&&(!c||d))return new XMLHttpRequest}catch(g){}try{if("undefined"!=typeof XDomainRequest&&!e&&f)return new XDomainRequest}catch(g){}if(!c)try{
  14. return new(b[["Active"].concat("Object").join("X")])("Microsoft.XMLHTTP")}catch(g){}}}).call(b,function(){return this}())},function(a,b){try{a.exports="undefined"!=typeof XMLHttpRequest&&"withCredentials"in new XMLHttpRequest}catch(c){a.exports=!1}},function(a,b,c){(function(b){function d(){}function e(a){if(i.call(this,a),this.requestTimeout=a.requestTimeout,this.extraHeaders=a.extraHeaders,b.location){var c="https:"===location.protocol,d=location.port;d||(d=c?443:80),this.xd=a.hostname!==b.location.hostname||d!==a.port,this.xs=a.secure!==c}}function f(a){this.method=a.method||"GET",this.uri=a.uri,this.xd=!!a.xd,this.xs=!!a.xs,this.async=!1!==a.async,this.data=void 0!==a.data?a.data:null,this.agent=a.agent,this.isBinary=a.isBinary,this.supportsBinary=a.supportsBinary,this.enablesXDR=a.enablesXDR,this.requestTimeout=a.requestTimeout,this.pfx=a.pfx,this.key=a.key,this.passphrase=a.passphrase,this.cert=a.cert,this.ca=a.ca,this.ciphers=a.ciphers,this.rejectUnauthorized=a.rejectUnauthorized,this.extraHeaders=a.extraHeaders,this.create()}function g(){for(var a in f.requests)f.requests.hasOwnProperty(a)&&f.requests[a].abort()}var h=c(18),i=c(21),j=c(8),k=c(32),l=c(3)("engine.io-client:polling-xhr");a.exports=e,a.exports.Request=f,k(e,i),e.prototype.supportsBinary=!0,e.prototype.request=function(a){return a=a||{},a.uri=this.uri(),a.xd=this.xd,a.xs=this.xs,a.agent=this.agent||!1,a.supportsBinary=this.supportsBinary,a.enablesXDR=this.enablesXDR,a.pfx=this.pfx,a.key=this.key,a.passphrase=this.passphrase,a.cert=this.cert,a.ca=this.ca,a.ciphers=this.ciphers,a.rejectUnauthorized=this.rejectUnauthorized,a.requestTimeout=this.requestTimeout,a.extraHeaders=this.extraHeaders,new f(a)},e.prototype.doWrite=function(a,b){var c="string"!=typeof a&&void 0!==a,d=this.request({method:"POST",data:a,isBinary:c}),e=this;d.on("success",b),d.on("error",function(a){e.onError("xhr post error",a)}),this.sendXhr=d},e.prototype.doPoll=function(){l("xhr poll");var a=this.request(),b=this;a.on("data",function(a){b.onData(a)}),a.on("error",function(a){b.onError("xhr poll error",a)}),this.pollXhr=a},j(f.prototype),f.prototype.create=function(){var a={agent:this.agent,xdomain:this.xd,xscheme:this.xs,enablesXDR:this.enablesXDR};a.pfx=this.pfx,a.key=this.key,a.passphrase=this.passphrase,a.cert=this.cert,a.ca=this.ca,a.ciphers=this.ciphers,a.rejectUnauthorized=this.rejectUnauthorized;var c=this.xhr=new h(a),d=this;try{l("xhr open %s: %s",this.method,this.uri),c.open(this.method,this.uri,this.async);try{if(this.extraHeaders){c.setDisableHeaderCheck&&c.setDisableHeaderCheck(!0);for(var e in this.extraHeaders)this.extraHeaders.hasOwnProperty(e)&&c.setRequestHeader(e,this.extraHeaders[e])}}catch(g){}if("POST"===this.method)try{this.isBinary?c.setRequestHeader("Content-type","application/octet-stream"):c.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch(g){}try{c.setRequestHeader("Accept","*/*")}catch(g){}"withCredentials"in c&&(c.withCredentials=!0),this.requestTimeout&&(c.timeout=this.requestTimeout),this.hasXDR()?(c.onload=function(){d.onLoad()},c.onerror=function(){d.onError(c.responseText)}):c.onreadystatechange=function(){if(2===c.readyState){var a;try{a=c.getResponseHeader("Content-Type")}catch(b){}"application/octet-stream"===a&&(c.responseType="arraybuffer")}4===c.readyState&&(200===c.status||1223===c.status?d.onLoad():setTimeout(function(){d.onError(c.status)},0))},l("xhr data %s",this.data),c.send(this.data)}catch(g){return void setTimeout(function(){d.onError(g)},0)}b.document&&(this.index=f.requestsCount++,f.requests[this.index]=this)},f.prototype.onSuccess=function(){this.emit("success"),this.cleanup()},f.prototype.onData=function(a){this.emit("data",a),this.onSuccess()},f.prototype.onError=function(a){this.emit("error",a),this.cleanup(!0)},f.prototype.cleanup=function(a){if("undefined"!=typeof this.xhr&&null!==this.xhr){if(this.hasXDR()?this.xhr.onload=this.xhr.onerror=d:this.xhr.onreadystatechange=d,a)try{this.xhr.abort()}catch(c){}b.document&&delete f.requests[this.index],this.xhr=null}},f.prototype.onLoad=function(){var a;try{var b;try{b=this.xhr.getResponseHeader("Content-Type")}catch(c){}a="application/octet-stream"===b?this.xhr.response||this.xhr.responseText:this.xhr.responseText}catch(c){this.onError(c)}null!=a&&this.onData(a)},f.prototype.hasXDR=function(){return"undefined"!=typeof b.XDomainRequest&&!this.xs&&this.enablesXDR},f.prototype.abort=function(){this.cleanup()},f.requestsCount=0,f.requests={},b.document&&(b.attachEvent?b.attachEvent("onunload",g):b.addEventListener&&b.addEventListener("beforeunload",g,!1))}).call(b,function(){return this}())},function(a,b,c){function d(a){var b=a&&a.forceBase64;k&&!b||(this.supportsBinary=!1),e.call(this,a)}var e=c(22),f=c(31),g=c(23),h=c(32),i=c(33),j=c(3)("engine.io-client:polling");a.exports=d;var k=function(){var a=c(18),b=new a({xdomain:!1});return null!=b.responseType}();h(d,e),d.prototype.name="polling",d.prototype.doOpen=function(){this.poll()},d.prototype.pause=function(a){function b(){j("paused"),c.readyState="paused",a()}var c=this;if(this.readyState="pausing",this.polling||!this.writable){var d=0;this.polling&&(j("we are currently polling - waiting to pause"),d++,this.once("pollComplete",function(){j("pre-pause polling complete"),--d||b()})),this.writable||(j("we are currently writing - waiting to pause"),d++,this.once("drain",function(){j("pre-pause writing complete"),--d||b()}))}else b()},d.prototype.poll=function(){j("polling"),this.polling=!0,this.doPoll(),this.emit("poll")},d.prototype.onData=function(a){var b=this;j("polling got data %s",a);var c=function(a,c,d){return"opening"===b.readyState&&b.onOpen(),"close"===a.type?(b.onClose(),!1):void b.onPacket(a)};g.decodePayload(a,this.socket.binaryType,c),"closed"!==this.readyState&&(this.polling=!1,this.emit("pollComplete"),"open"===this.readyState?this.poll():j('ignoring poll - transport state "%s"',this.readyState))},d.prototype.doClose=function(){function a(){j("writing close packet"),b.write([{type:"close"}])}var b=this;"open"===this.readyState?(j("transport open - closing"),a()):(j("transport not open - deferring close"),this.once("open",a))},d.prototype.write=function(a){var b=this;this.writable=!1;var c=function(){b.writable=!0,b.emit("drain")};g.encodePayload(a,this.supportsBinary,function(a){b.doWrite(a,c)})},d.prototype.uri=function(){var a=this.query||{},b=this.secure?"https":"http",c="";!1!==this.timestampRequests&&(a[this.timestampParam]=i()),this.supportsBinary||a.sid||(a.b64=1),a=f.encode(a),this.port&&("https"===b&&443!==Number(this.port)||"http"===b&&80!==Number(this.port))&&(c=":"+this.port),a.length&&(a="?"+a);var d=this.hostname.indexOf(":")!==-1;return b+"://"+(d?"["+this.hostname+"]":this.hostname)+c+this.path+a}},function(a,b,c){function d(a){this.path=a.path,this.hostname=a.hostname,this.port=a.port,this.secure=a.secure,this.query=a.query,this.timestampParam=a.timestampParam,this.timestampRequests=a.timestampRequests,this.readyState="",this.agent=a.agent||!1,this.socket=a.socket,this.enablesXDR=a.enablesXDR,this.pfx=a.pfx,this.key=a.key,this.passphrase=a.passphrase,this.cert=a.cert,this.ca=a.ca,this.ciphers=a.ciphers,this.rejectUnauthorized=a.rejectUnauthorized,this.forceNode=a.forceNode,this.extraHeaders=a.extraHeaders,this.localAddress=a.localAddress}var e=c(23),f=c(8);a.exports=d,f(d.prototype),d.prototype.onError=function(a,b){var c=new Error(a);return c.type="TransportError",c.description=b,this.emit("error",c),this},d.prototype.open=function(){return"closed"!==this.readyState&&""!==this.readyState||(this.readyState="opening",this.doOpen()),this},d.prototype.close=function(){return"opening"!==this.readyState&&"open"!==this.readyState||(this.doClose(),this.onClose()),this},d.prototype.send=function(a){if("open"!==this.readyState)throw new Error("Transport not open");this.write(a)},d.prototype.onOpen=function(){this.readyState="open",this.writable=!0,this.emit("open")},d.prototype.onData=function(a){var b=e.decodePacket(a,this.socket.binaryType);this.onPacket(b)},d.prototype.onPacket=function(a){this.emit("packet",a)},d.prototype.onClose=function(){this.readyState="closed",this.emit("close")}},function(a,b,c){(function(a){function d(a,c){var d="b"+b.packets[a.type]+a.data.data;return c(d)}function e(a,c,d){if(!c)return b.encodeBase64Packet(a,d);var e=a.data,f=new Uint8Array(e),g=new Uint8Array(1+e.byteLength);g[0]=s[a.type];for(var h=0;h<f.length;h++)g[h+1]=f[h];return d(g.buffer)}function f(a,c,d){if(!c)return b.encodeBase64Packet(a,d);var e=new FileReader;return e.onload=function(){a.data=e.result,b.encodePacket(a,c,!0,d)},e.readAsArrayBuffer(a.data)}function g(a,c,d){if(!c)return b.encodeBase64Packet(a,d);if(r)return f(a,c,d);var e=new Uint8Array(1);e[0]=s[a.type];var g=new v([e.buffer,a.data]);return d(g)}function h(a){try{a=o.decode(a,{strict:!1})}catch(b){return!1}return a}function i(a,b,c){for(var d=new Array(a.length),e=n(a.length,c),f=function(a,c,e){b(c,function(b,c){d[a]=c,e(b,d)})},g=0;g<a.length;g++)f(g,a[g],e)}var j,k=c(24),l=c(9),m=c(25),n=c(26),o=c(27);a&&a.ArrayBuffer&&(j=c(29));var p="undefined"!=typeof navigator&&/Android/i.test(navigator.userAgent),q="undefined"!=typeof navigator&&/PhantomJS/i.test(navigator.userAgent),r=p||q;b.protocol=3;var s=b.packets={open:0,close:1,ping:2,pong:3,message:4,upgrade:5,noop:6},t=k(s),u={type:"error",data:"parser error"},v=c(30);b.encodePacket=function(b,c,f,h){"function"==typeof c&&(h=c,c=!1),"function"==typeof f&&(h=f,f=null);var i=void 0===b.data?void 0:b.data.buffer||b.data;if(a.ArrayBuffer&&i instanceof ArrayBuffer)return e(b,c,h);if(v&&i instanceof a.Blob)return g(b,c,h);if(i&&i.base64)return d(b,h);var j=s[b.type];return void 0!==b.data&&(j+=f?o.encode(String(b.data),{strict:!1}):String(b.data)),h(""+j)},b.encodeBase64Packet=function(c,d){var e="b"+b.packets[c.type];if(v&&c.data instanceof a.Blob){var f=new FileReader;return f.onload=function(){var a=f.result.split(",")[1];d(e+a)},f.readAsDataURL(c.data)}var g;try{g=String.fromCharCode.apply(null,new Uint8Array(c.data))}catch(h){for(var i=new Uint8Array(c.data),j=new Array(i.length),k=0;k<i.length;k++)j[k]=i[k];g=String.fromCharCode.apply(null,j)}return e+=a.btoa(g),d(e)},b.decodePacket=function(a,c,d){if(void 0===a)return u;if("string"==typeof a){if("b"===a.charAt(0))return b.decodeBase64Packet(a.substr(1),c);if(d&&(a=h(a),a===!1))return u;var e=a.charAt(0);return Number(e)==e&&t[e]?a.length>1?{type:t[e],data:a.substring(1)}:{type:t[e]}:u}var f=new Uint8Array(a),e=f[0],g=m(a,1);return v&&"blob"===c&&(g=new v([g])),{type:t[e],data:g}},b.decodeBase64Packet=function(a,b){var c=t[a.charAt(0)];if(!j)return{type:c,data:{base64:!0,data:a.substr(1)}};var d=j.decode(a.substr(1));return"blob"===b&&v&&(d=new v([d])),{type:c,data:d}},b.encodePayload=function(a,c,d){function e(a){return a.length+":"+a}function f(a,d){b.encodePacket(a,!!g&&c,!1,function(a){d(null,e(a))})}"function"==typeof c&&(d=c,c=null);var g=l(a);return c&&g?v&&!r?b.encodePayloadAsBlob(a,d):b.encodePayloadAsArrayBuffer(a,d):a.length?void i(a,f,function(a,b){return d(b.join(""))}):d("0:")},b.decodePayload=function(a,c,d){if("string"!=typeof a)return b.decodePayloadAsBinary(a,c,d);"function"==typeof c&&(d=c,c=null);var e;if(""===a)return d(u,0,1);for(var f,g,h="",i=0,j=a.length;i<j;i++){var k=a.charAt(i);if(":"===k){if(""===h||h!=(f=Number(h)))return d(u,0,1);if(g=a.substr(i+1,f),h!=g.length)return d(u,0,1);if(g.length){if(e=b.decodePacket(g,c,!1),u.type===e.type&&u.data===e.data)return d(u,0,1);var l=d(e,i+f,j);if(!1===l)return}i+=f,h=""}else h+=k}return""!==h?d(u,0,1):void 0},b.encodePayloadAsArrayBuffer=function(a,c){function d(a,c){b.encodePacket(a,!0,!0,function(a){return c(null,a)})}return a.length?void i(a,d,function(a,b){var d=b.reduce(function(a,b){var c;return c="string"==typeof b?b.length:b.byteLength,a+c.toString().length+c+2},0),e=new Uint8Array(d),f=0;return b.forEach(function(a){var b="string"==typeof a,c=a;if(b){for(var d=new Uint8Array(a.length),g=0;g<a.length;g++)d[g]=a.charCodeAt(g);c=d.buffer}b?e[f++]=0:e[f++]=1;for(var h=c.byteLength.toString(),g=0;g<h.length;g++)e[f++]=parseInt(h[g]);e[f++]=255;for(var d=new Uint8Array(c),g=0;g<d.length;g++)e[f++]=d[g]}),c(e.buffer)}):c(new ArrayBuffer(0))},b.encodePayloadAsBlob=function(a,c){function d(a,c){b.encodePacket(a,!0,!0,function(a){var b=new Uint8Array(1);if(b[0]=1,"string"==typeof a){for(var d=new Uint8Array(a.length),e=0;e<a.length;e++)d[e]=a.charCodeAt(e);a=d.buffer,b[0]=0}for(var f=a instanceof ArrayBuffer?a.byteLength:a.size,g=f.toString(),h=new Uint8Array(g.length+1),e=0;e<g.length;e++)h[e]=parseInt(g[e]);if(h[g.length]=255,v){var i=new v([b.buffer,h.buffer,a]);c(null,i)}})}i(a,d,function(a,b){return c(new v(b))})},b.decodePayloadAsBinary=function(a,c,d){"function"==typeof c&&(d=c,c=null);for(var e=a,f=[];e.byteLength>0;){for(var g=new Uint8Array(e),h=0===g[0],i="",j=1;255!==g[j];j++){if(i.length>310)return d(u,0,1);i+=g[j]}e=m(e,2+i.length),i=parseInt(i);var k=m(e,0,i);if(h)try{k=String.fromCharCode.apply(null,new Uint8Array(k))}catch(l){var n=new Uint8Array(k);k="";for(var j=0;j<n.length;j++)k+=String.fromCharCode(n[j])}f.push(k),e=m(e,i)}var o=f.length;f.forEach(function(a,e){d(b.decodePacket(a,c,!0),e,o)})}}).call(b,function(){return this}())},function(a,b){a.exports=Object.keys||function(a){var b=[],c=Object.prototype.hasOwnProperty;for(var d in a)c.call(a,d)&&b.push(d);return b}},function(a,b){a.exports=function(a,b,c){var d=a.byteLength;if(b=b||0,c=c||d,a.slice)return a.slice(b,c);if(b<0&&(b+=d),c<0&&(c+=d),c>d&&(c=d),b>=d||b>=c||0===d)return new ArrayBuffer(0);for(var e=new Uint8Array(a),f=new Uint8Array(c-b),g=b,h=0;g<c;g++,h++)f[h]=e[g];return f.buffer}},function(a,b){function c(a,b,c){function e(a,d){if(e.count<=0)throw new Error("after called too many times");--e.count,a?(f=!0,b(a),b=c):0!==e.count||f||b(null,d)}var f=!1;return c=c||d,e.count=a,0===a?b():e}function d(){}a.exports=c},function(a,b,c){var d;(function(a,e){!function(f){function g(a){for(var b,c,d=[],e=0,f=a.length;e<f;)b=a.charCodeAt(e++),b>=55296&&b<=56319&&e<f?(c=a.charCodeAt(e++),56320==(64512&c)?d.push(((1023&b)<<10)+(1023&c)+65536):(d.push(b),e--)):d.push(b);return d}function h(a){for(var b,c=a.length,d=-1,e="";++d<c;)b=a[d],b>65535&&(b-=65536,e+=u(b>>>10&1023|55296),b=56320|1023&b),e+=u(b);return e}function i(a,b){if(a>=55296&&a<=57343){if(b)throw Error("Lone surrogate U+"+a.toString(16).toUpperCase()+" is not a scalar value");return!1}return!0}function j(a,b){return u(a>>b&63|128)}function k(a,b){if(0==(4294967168&a))return u(a);var c="";return 0==(4294965248&a)?c=u(a>>6&31|192):0==(4294901760&a)?(i(a,b)||(a=65533),c=u(a>>12&15|224),c+=j(a,6)):0==(4292870144&a)&&(c=u(a>>18&7|240),c+=j(a,12),c+=j(a,6)),c+=u(63&a|128)}function l(a,b){b=b||{};for(var c,d=!1!==b.strict,e=g(a),f=e.length,h=-1,i="";++h<f;)c=e[h],i+=k(c,d);return i}function m(){if(t>=s)throw Error("Invalid byte index");var a=255&r[t];if(t++,128==(192&a))return 63&a;throw Error("Invalid continuation byte")}function n(a){var b,c,d,e,f;if(t>s)throw Error("Invalid byte index");if(t==s)return!1;if(b=255&r[t],t++,0==(128&b))return b;if(192==(224&b)){if(c=m(),f=(31&b)<<6|c,f>=128)return f;throw Error("Invalid continuation byte")}if(224==(240&b)){if(c=m(),d=m(),f=(15&b)<<12|c<<6|d,f>=2048)return i(f,a)?f:65533;throw Error("Invalid continuation byte")}if(240==(248&b)&&(c=m(),d=m(),e=m(),f=(7&b)<<18|c<<12|d<<6|e,f>=65536&&f<=1114111))return f;throw Error("Invalid UTF-8 detected")}function o(a,b){b=b||{};var c=!1!==b.strict;r=g(a),s=r.length,t=0;for(var d,e=[];(d=n(c))!==!1;)e.push(d);return h(e)}var p="object"==typeof b&&b,q=("object"==typeof a&&a&&a.exports==p&&a,"object"==typeof e&&e);q.global!==q&&q.window!==q||(f=q);var r,s,t,u=String.fromCharCode,v={version:"2.1.2",encode:l,decode:o};d=function(){return v}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))}(this)}).call(b,c(28)(a),function(){return this}())},function(a,b){a.exports=function(a){return a.webpackPolyfill||(a.deprecate=function(){},a.paths=[],a.children=[],a.webpackPolyfill=1),a}},function(a,b){!function(){"use strict";for(var a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",c=new Uint8Array(256),d=0;d<a.length;d++)c[a.charCodeAt(d)]=d;b.encode=function(b){var c,d=new Uint8Array(b),e=d.length,f="";for(c=0;c<e;c+=3)f+=a[d[c]>>2],f+=a[(3&d[c])<<4|d[c+1]>>4],f+=a[(15&d[c+1])<<2|d[c+2]>>6],f+=a[63&d[c+2]];return e%3===2?f=f.substring(0,f.length-1)+"=":e%3===1&&(f=f.substring(0,f.length-2)+"=="),f},b.decode=function(a){var b,d,e,f,g,h=.75*a.length,i=a.length,j=0;"="===a[a.length-1]&&(h--,"="===a[a.length-2]&&h--);var k=new ArrayBuffer(h),l=new Uint8Array(k);for(b=0;b<i;b+=4)d=c[a.charCodeAt(b)],e=c[a.charCodeAt(b+1)],f=c[a.charCodeAt(b+2)],g=c[a.charCodeAt(b+3)],l[j++]=d<<2|e>>4,l[j++]=(15&e)<<4|f>>2,l[j++]=(3&f)<<6|63&g;return k}}()},function(a,b){(function(b){function c(a){for(var b=0;b<a.length;b++){var c=a[b];if(c.buffer instanceof ArrayBuffer){var d=c.buffer;if(c.byteLength!==d.byteLength){var e=new Uint8Array(c.byteLength);e.set(new Uint8Array(d,c.byteOffset,c.byteLength)),d=e.buffer}a[b]=d}}}function d(a,b){b=b||{};var d=new f;c(a);for(var e=0;e<a.length;e++)d.append(a[e]);return b.type?d.getBlob(b.type):d.getBlob()}function e(a,b){return c(a),new Blob(a,b||{})}var f=b.BlobBuilder||b.WebKitBlobBuilder||b.MSBlobBuilder||b.MozBlobBuilder,g=function(){try{var a=new Blob(["hi"]);return 2===a.size}catch(b){return!1}}(),h=g&&function(){try{var a=new Blob([new Uint8Array([1,2])]);return 2===a.size}catch(b){return!1}}(),i=f&&f.prototype.append&&f.prototype.getBlob;a.exports=function(){return g?h?b.Blob:e:i?d:void 0}()}).call(b,function(){return this}())},function(a,b){b.encode=function(a){var b="";for(var c in a)a.hasOwnProperty(c)&&(b.length&&(b+="&"),b+=encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b},b.decode=function(a){for(var b={},c=a.split("&"),d=0,e=c.length;d<e;d++){var f=c[d].split("=");b[decodeURIComponent(f[0])]=decodeURIComponent(f[1])}return b}},function(a,b){a.exports=function(a,b){var c=function(){};c.prototype=b.prototype,a.prototype=new c,a.prototype.constructor=a}},function(a,b){"use strict";function c(a){var b="";do b=g[a%h]+b,a=Math.floor(a/h);while(a>0);return b}function d(a){var b=0;for(k=0;k<a.length;k++)b=b*h+i[a.charAt(k)];return b}function e(){var a=c(+new Date);return a!==f?(j=0,f=a):a+"."+c(j++)}for(var f,g="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_".split(""),h=64,i={},j=0,k=0;k<h;k++)i[g[k]]=k;e.encode=c,e.decode=d,a.exports=e},function(a,b,c){(function(b){function d(){}function e(a){f.call(this,a),this.query=this.query||{},h||(b.___eio||(b.___eio=[]),h=b.___eio),this.index=h.length;var c=this;h.push(function(a){c.onData(a)}),this.query.j=this.index,b.document&&b.addEventListener&&b.addEventListener("beforeunload",function(){c.script&&(c.script.onerror=d)},!1)}var f=c(21),g=c(32);a.exports=e;var h,i=/\n/g,j=/\\n/g;g(e,f),e.prototype.supportsBinary=!1,e.prototype.doClose=function(){this.script&&(this.script.parentNode.removeChild(this.script),this.script=null),this.form&&(this.form.parentNode.removeChild(this.form),this.form=null,this.iframe=null),f.prototype.doClose.call(this)},e.prototype.doPoll=function(){var a=this,b=document.createElement("script");this.script&&(this.script.parentNode.removeChild(this.script),this.script=null),b.async=!0,b.src=this.uri(),b.onerror=function(b){a.onError("jsonp poll error",b)};var c=document.getElementsByTagName("script")[0];c?c.parentNode.insertBefore(b,c):(document.head||document.body).appendChild(b),this.script=b;var d="undefined"!=typeof navigator&&/gecko/i.test(navigator.userAgent);d&&setTimeout(function(){var a=document.createElement("iframe");document.body.appendChild(a),document.body.removeChild(a)},100)},e.prototype.doWrite=function(a,b){function c(){d(),b()}function d(){if(e.iframe)try{e.form.removeChild(e.iframe)}catch(a){e.onError("jsonp polling iframe removal error",a)}try{var b='<iframe src="javascript:0" name="'+e.iframeId+'">';f=document.createElement(b)}catch(a){f=document.createElement("iframe"),f.name=e.iframeId,f.src="javascript:0"}f.id=e.iframeId,e.form.appendChild(f),e.iframe=f}var e=this;if(!this.form){var f,g=document.createElement("form"),h=document.createElement("textarea"),k=this.iframeId="eio_iframe_"+this.index;g.className="socketio",g.style.position="absolute",g.style.top="-1000px",g.style.left="-1000px",g.target=k,g.method="POST",g.setAttribute("accept-charset","utf-8"),h.name="d",g.appendChild(h),document.body.appendChild(g),this.form=g,this.area=h}this.form.action=this.uri(),d(),a=a.replace(j,"\\\n"),this.area.value=a.replace(i,"\\n");try{this.form.submit()}catch(l){}this.iframe.attachEvent?this.iframe.onreadystatechange=function(){"complete"===e.iframe.readyState&&c()}:this.iframe.onload=c}}).call(b,function(){return this}())},function(a,b,c){(function(b){function d(a){var b=a&&a.forceBase64;b&&(this.supportsBinary=!1),this.perMessageDeflate=a.perMessageDeflate,this.usingBrowserWebSocket=l&&!a.forceNode,this.protocols=a.protocols,this.usingBrowserWebSocket||(n=e),f.call(this,a)}var e,f=c(22),g=c(23),h=c(31),i=c(32),j=c(33),k=c(3)("engine.io-client:websocket"),l=b.WebSocket||b.MozWebSocket;if("undefined"==typeof window)try{e=c(36)}catch(m){}var n=l;n||"undefined"!=typeof window||(n=e),a.exports=d,i(d,f),d.prototype.name="websocket",d.prototype.supportsBinary=!0,d.prototype.doOpen=function(){if(this.check()){var a=this.uri(),b=this.protocols,c={agent:this.agent,perMessageDeflate:this.perMessageDeflate};c.pfx=this.pfx,c.key=this.key,c.passphrase=this.passphrase,c.cert=this.cert,c.ca=this.ca,c.ciphers=this.ciphers,c.rejectUnauthorized=this.rejectUnauthorized,this.extraHeaders&&(c.headers=this.extraHeaders),this.localAddress&&(c.localAddress=this.localAddress);try{this.ws=this.usingBrowserWebSocket?b?new n(a,b):new n(a):new n(a,b,c)}catch(d){return this.emit("error",d)}void 0===this.ws.binaryType&&(this.supportsBinary=!1),this.ws.supports&&this.ws.supports.binary?(this.supportsBinary=!0,this.ws.binaryType="nodebuffer"):this.ws.binaryType="arraybuffer",this.addEventListeners()}},d.prototype.addEventListeners=function(){var a=this;this.ws.onopen=function(){a.onOpen()},this.ws.onclose=function(){a.onClose()},this.ws.onmessage=function(b){a.onData(b.data)},this.ws.onerror=function(b){a.onError("websocket error",b)}},d.prototype.write=function(a){function c(){d.emit("flush"),setTimeout(function(){d.writable=!0,d.emit("drain")},0)}var d=this;this.writable=!1;for(var e=a.length,f=0,h=e;f<h;f++)!function(a){g.encodePacket(a,d.supportsBinary,function(f){if(!d.usingBrowserWebSocket){var g={};if(a.options&&(g.compress=a.options.compress),d.perMessageDeflate){var h="string"==typeof f?b.Buffer.byteLength(f):f.length;h<d.perMessageDeflate.threshold&&(g.compress=!1)}}try{d.usingBrowserWebSocket?d.ws.send(f):d.ws.send(f,g)}catch(i){k("websocket closed before onclose event")}--e||c()})}(a[f])},d.prototype.onClose=function(){f.prototype.onClose.call(this)},d.prototype.doClose=function(){"undefined"!=typeof this.ws&&this.ws.close()},d.prototype.uri=function(){var a=this.query||{},b=this.secure?"wss":"ws",c="";this.port&&("wss"===b&&443!==Number(this.port)||"ws"===b&&80!==Number(this.port))&&(c=":"+this.port),this.timestampRequests&&(a[this.timestampParam]=j()),this.supportsBinary||(a.b64=1),a=h.encode(a),a.length&&(a="?"+a);var d=this.hostname.indexOf(":")!==-1;return b+"://"+(d?"["+this.hostname+"]":this.hostname)+c+this.path+a},d.prototype.check=function(){return!(!n||"__initialize"in n&&this.name===d.prototype.name)}}).call(b,function(){return this}())},function(a,b){},function(a,b){var c=[].indexOf;a.exports=function(a,b){if(c)return a.indexOf(b);for(var d=0;d<a.length;++d)if(a[d]===b)return d;return-1}},function(a,b){(function(b){var c=/^[\],:{}\s]*$/,d=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,e=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,f=/(?:^|:|,)(?:\s*\[)+/g,g=/^\s+/,h=/\s+$/;a.exports=function(a){return"string"==typeof a&&a?(a=a.replace(g,"").replace(h,""),b.JSON&&JSON.parse?JSON.parse(a):c.test(a.replace(d,"@").replace(e,"]").replace(f,""))?new Function("return "+a)():void 0):null}}).call(b,function(){return this}())},function(a,b,c){"use strict";function d(a,b,c){this.io=a,this.nsp=b,this.json=this,this.ids=0,this.acks={},this.receiveBuffer=[],this.sendBuffer=[],this.connected=!1,this.disconnected=!0,c&&c.query&&(this.query=c.query),this.io.autoConnect&&this.open()}var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},f=c(7),g=c(8),h=c(40),i=c(41),j=c(42),k=c(3)("socket.io-client:socket"),l=c(31);a.exports=b=d;var m={connect:1,connect_error:1,connect_timeout:1,connecting:1,disconnect:1,error:1,reconnect:1,reconnect_attempt:1,reconnect_failed:1,reconnect_error:1,reconnecting:1,ping:1,pong:1},n=g.prototype.emit;g(d.prototype),d.prototype.subEvents=function(){if(!this.subs){var a=this.io;this.subs=[i(a,"open",j(this,"onopen")),i(a,"packet",j(this,"onpacket")),i(a,"close",j(this,"onclose"))]}},d.prototype.open=d.prototype.connect=function(){return this.connected?this:(this.subEvents(),this.io.open(),"open"===this.io.readyState&&this.onopen(),this.emit("connecting"),this)},d.prototype.send=function(){var a=h(arguments);return a.unshift("message"),this.emit.apply(this,a),this},d.prototype.emit=function(a){if(m.hasOwnProperty(a))return n.apply(this,arguments),this;var b=h(arguments),c={type:f.EVENT,data:b};return c.options={},c.options.compress=!this.flags||!1!==this.flags.compress,"function"==typeof b[b.length-1]&&(k("emitting packet with ack id %d",this.ids),this.acks[this.ids]=b.pop(),c.id=this.ids++),this.connected?this.packet(c):this.sendBuffer.push(c),delete this.flags,this},d.prototype.packet=function(a){a.nsp=this.nsp,this.io.packet(a)},d.prototype.onopen=function(){if(k("transport is open - connecting"),"/"!==this.nsp)if(this.query){var a="object"===e(this.query)?l.encode(this.query):this.query;k("sending connect packet with query %s",a),this.packet({type:f.CONNECT,query:a})}else this.packet({type:f.CONNECT})},d.prototype.onclose=function(a){k("close (%s)",a),this.connected=!1,this.disconnected=!0,delete this.id,this.emit("disconnect",a)},d.prototype.onpacket=function(a){if(a.nsp===this.nsp)switch(a.type){case f.CONNECT:this.onconnect();break;case f.EVENT:this.onevent(a);break;case f.BINARY_EVENT:this.onevent(a);break;case f.ACK:this.onack(a);break;case f.BINARY_ACK:this.onack(a);break;case f.DISCONNECT:this.ondisconnect();break;case f.ERROR:this.emit("error",a.data)}},d.prototype.onevent=function(a){var b=a.data||[];k("emitting event %j",b),null!=a.id&&(k("attaching ack callback to event"),b.push(this.ack(a.id))),this.connected?n.apply(this,b):this.receiveBuffer.push(b)},d.prototype.ack=function(a){var b=this,c=!1;return function(){if(!c){c=!0;var d=h(arguments);k("sending ack %j",d),b.packet({type:f.ACK,id:a,data:d})}}},d.prototype.onack=function(a){var b=this.acks[a.id];"function"==typeof b?(k("calling ack %s with %j",a.id,a.data),b.apply(this,a.data),delete this.acks[a.id]):k("bad ack %s",a.id)},d.prototype.onconnect=function(){this.connected=!0,this.disconnected=!1,this.emit("connect"),this.emitBuffered()},d.prototype.emitBuffered=function(){var a;for(a=0;a<this.receiveBuffer.length;a++)n.apply(this,this.receiveBuffer[a]);for(this.receiveBuffer=[],a=0;a<this.sendBuffer.length;a++)this.packet(this.sendBuffer[a]);this.sendBuffer=[]},d.prototype.ondisconnect=function(){k("server disconnect (%s)",this.nsp),this.destroy(),this.onclose("io server disconnect")},d.prototype.destroy=function(){if(this.subs){for(var a=0;a<this.subs.length;a++)this.subs[a].destroy();this.subs=null}this.io.destroy(this)},d.prototype.close=d.prototype.disconnect=function(){return this.connected&&(k("performing disconnect (%s)",this.nsp),this.packet({type:f.DISCONNECT})),this.destroy(),this.connected&&this.onclose("io client disconnect"),this},d.prototype.compress=function(a){return this.flags=this.flags||{},this.flags.compress=a,this}},function(a,b){function c(a,b){var c=[];b=b||0;for(var d=b||0;d<a.length;d++)c[d-b]=a[d];return c}a.exports=c},function(a,b){"use strict";function c(a,b,c){return a.on(b,c),{destroy:function(){a.removeListener(b,c)}}}a.exports=c},function(a,b){var c=[].slice;a.exports=function(a,b){if("string"==typeof b&&(b=a[b]),"function"!=typeof b)throw new Error("bind() requires a function");var d=c.call(arguments,2);return function(){return b.apply(a,d.concat(c.call(arguments)))}}},function(a,b){function c(a){a=a||{},this.ms=a.min||100,this.max=a.max||1e4,this.factor=a.factor||2,this.jitter=a.jitter>0&&a.jitter<=1?a.jitter:0,this.attempts=0}a.exports=c,c.prototype.duration=function(){var a=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var b=Math.random(),c=Math.floor(b*this.jitter*a);a=0==(1&Math.floor(10*b))?a-c:a+c}return 0|Math.min(a,this.max)},c.prototype.reset=function(){this.attempts=0},c.prototype.setMin=function(a){this.ms=a},c.prototype.setMax=function(a){this.max=a},c.prototype.setJitter=function(a){this.jitter=a}}])});;
  15. //////////////////////////////////////////////////////////////////////////////////////
  16. // //
  17. // ███████╗ █████╗ ██╗██╗ ███████╗ ██╗ ██████╗ ██╗███████╗ //
  18. // ██╔════╝██╔══██╗██║██║ ██╔════╝ ██║██╔═══██╗ ██║██╔════╝ //
  19. // ███████╗███████║██║██║ ███████╗ ██║██║ ██║ ██║███████╗ //
  20. // ╚════██║██╔══██║██║██║ ╚════██║ ██║██║ ██║ ██ ██║╚════██║ //
  21. // ███████║██║ ██║██║███████╗███████║██╗██║╚██████╔╝██╗╚█████╔╝███████║ //
  22. // ╚══════╝╚═╝ ╚═╝╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═════╝ ╚═╝ ╚════╝ ╚══════╝ //
  23. // //
  24. // ╦╔═╗╦ ╦╔═╗╔═╗╔═╗╦═╗╦╔═╗╔╦╗ ╔═╗╦ ╦╔═╗╔╗╔╔╦╗ ╔═╗╔╦╗╦╔═ //
  25. // ║╠═╣╚╗╔╝╠═╣╚═╗║ ╠╦╝║╠═╝ ║ ║ ║ ║║╣ ║║║ ║ ╚═╗ ║║╠╩╗ //
  26. // ╚╝╩ ╩ ╚╝ ╩ ╩╚═╝╚═╝╩╚═╩╩ ╩ ╚═╝╩═╝╩╚═╝╝╚╝ ╩ ╚═╝═╩╝╩ ╩ //
  27. // ┌─┐┌─┐┬─┐ ┌┐┌┌─┐┌┬┐┌─┐ ┬┌─┐ ┌─┐┌┐┌┌┬┐ ┌┬┐┬ ┬┌─┐ ┌┐ ┬─┐┌─┐┬ ┬┌─┐┌─┐┬─┐ //
  28. // ├┤ │ │├┬┘ ││││ │ ││├┤ │└─┐ ├─┤│││ ││ │ ├─┤├┤ ├┴┐├┬┘│ ││││└─┐├┤ ├┬┘ //
  29. // └ └─┘┴└─ ┘└┘└─┘─┴┘└─┘o└┘└─┘ ┴ ┴┘└┘─┴┘ ┴ ┴ ┴└─┘ └─┘┴└─└─┘└┴┘└─┘└─┘┴└─ //
  30. // //
  31. //////////////////////////////////////////////////////////////////////////////////////
  32. /**
  33. * sails.io.js
  34. * v1.1.13
  35. * ------------------------------------------------------------------------
  36. * JavaScript Client (SDK) for communicating with Sails.
  37. *
  38. * Note that this script is completely optional, but it is handy if you're
  39. * using WebSockets from the browser to talk to your Sails server.
  40. *
  41. * For tips and documentation, visit:
  42. * http://sailsjs.com/documentation/reference/web-sockets/socket-client
  43. * ------------------------------------------------------------------------
  44. *
  45. * This file allows you to send and receive socket.io messages to & from Sails
  46. * by simulating a REST client interface on top of socket.io. It models its API
  47. * after the $.ajax pattern from jQuery you might already be familiar with.
  48. *
  49. * So if you're switching from using AJAX to sockets, instead of:
  50. * `$.post( url, [data], [cb] )`
  51. *
  52. * You would use:
  53. * `socket.post( url, [data], [cb] )`
  54. */
  55. (function() {
  56. // ██████╗ ██████╗ ███╗ ██╗███████╗████████╗ █████╗ ███╗ ██╗████████╗███████╗
  57. // ██╔════╝██╔═══██╗████╗ ██║██╔════╝╚══██╔══╝██╔══██╗████╗ ██║╚══██╔══╝██╔════╝
  58. // ██║ ██║ ██║██╔██╗ ██║███████╗ ██║ ███████║██╔██╗ ██║ ██║ ███████╗
  59. // ██║ ██║ ██║██║╚██╗██║╚════██║ ██║ ██╔══██║██║╚██╗██║ ██║ ╚════██║
  60. // ╚██████╗╚██████╔╝██║ ╚████║███████║ ██║ ██║ ██║██║ ╚████║ ██║ ███████║
  61. // ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝
  62. //
  63. /**
  64. * Constant containing the names of all available options
  65. * for individual sockets.
  66. *
  67. * @type {Array}
  68. */
  69. var SOCKET_OPTIONS = [
  70. 'useCORSRouteToGetCookie',
  71. 'url',
  72. 'multiplex',
  73. 'transports',
  74. 'query',
  75. 'path',
  76. 'headers',
  77. 'initialConnectionHeaders',
  78. 'reconnection',
  79. 'reconnectionAttempts',
  80. 'reconnectionDelay',
  81. 'reconnectionDelayMax',
  82. 'rejectUnauthorized',
  83. 'randomizationFactor',
  84. 'timeout'
  85. ];
  86. /**
  87. * Constant containing the names of properties on `io.sails` which
  88. * may be configured using HTML attributes on the script tag which
  89. * loaded this file.
  90. *
  91. * @type {Array}
  92. *
  93. * (this is unused if loading from node.js)
  94. */
  95. var CONFIGURABLE_VIA_HTML_ATTR = [
  96. 'autoConnect',
  97. 'reconnection',
  98. 'environment',
  99. 'headers',
  100. 'url',
  101. 'transports',
  102. 'path'
  103. ];
  104. /**
  105. * Constant containing the names of querystring
  106. * parameters sent when connecting any SailsSocket.
  107. *
  108. * @type {Dictionary}
  109. */
  110. var CONNECTION_METADATA_PARAMS = {
  111. version: '__sails_io_sdk_version',
  112. platform: '__sails_io_sdk_platform',
  113. language: '__sails_io_sdk_language'
  114. };
  115. /**
  116. * Constant containing metadata about the platform, language, and
  117. * current version of this SDK.
  118. *
  119. * @type {Dictionary}
  120. */
  121. var SDK_INFO = {
  122. version: '1.1.13', // <-- pulled automatically from package.json, do not change!
  123. language: 'javascript',
  124. platform: (function (){
  125. if (typeof module === 'object' && typeof module.exports !== 'undefined') {
  126. return 'node';
  127. }
  128. else {
  129. return 'browser';
  130. }
  131. })()
  132. };
  133. // Build `versionString` (a querystring snippet) by
  134. // combining SDK_INFO and CONNECTION_METADATA_PARAMS.
  135. SDK_INFO.versionString =
  136. CONNECTION_METADATA_PARAMS.version + '=' + SDK_INFO.version + '&' +
  137. CONNECTION_METADATA_PARAMS.platform + '=' + SDK_INFO.platform + '&' +
  138. CONNECTION_METADATA_PARAMS.language + '=' + SDK_INFO.language;
  139. // █████╗ ██████╗ ███████╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗████████╗███╗ ███╗██╗
  140. // ██╔══██╗██╔══██╗██╔════╝██╔═══██╗██╔══██╗██╔══██╗ ██║ ██║╚══██╔══╝████╗ ████║██║
  141. // ███████║██████╔╝███████╗██║ ██║██████╔╝██████╔╝ ███████║ ██║ ██╔████╔██║██║
  142. // ██╔══██║██╔══██╗╚════██║██║ ██║██╔══██╗██╔══██╗ ██╔══██║ ██║ ██║╚██╔╝██║██║
  143. // ██║ ██║██████╔╝███████║╚██████╔╝██║ ██║██████╔╝ ██║ ██║ ██║ ██║ ╚═╝ ██║███████╗
  144. // ╚═╝ ╚═╝╚═════╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚══════╝
  145. //
  146. // █████╗ ████████╗████████╗██████╗ ██╗██████╗ ██╗ ██╗████████╗███████╗███████╗
  147. // ██╔══██╗╚══██╔══╝╚══██╔══╝██╔══██╗██║██╔══██╗██║ ██║╚══██╔══╝██╔════╝██╔════╝
  148. // ███████║ ██║ ██║ ██████╔╝██║██████╔╝██║ ██║ ██║ █████╗ ███████╗
  149. // ██╔══██║ ██║ ██║ ██╔══██╗██║██╔══██╗██║ ██║ ██║ ██╔══╝ ╚════██║
  150. // ██║ ██║ ██║ ██║ ██║ ██║██║██████╔╝╚██████╔╝ ██║ ███████╗███████║
  151. // ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝╚═════╝ ╚═════╝ ╚═╝ ╚══════╝╚══════╝
  152. //
  153. // ███████╗██████╗ ██████╗ ███╗ ███╗ ██╗███████╗ ██████╗██████╗ ██╗██████╗ ████████╗██╗
  154. // ██╔════╝██╔══██╗██╔═══██╗████╗ ████║ ██╔╝██╔════╝██╔════╝██╔══██╗██║██╔══██╗╚══██╔══╝╚██╗
  155. // █████╗ ██████╔╝██║ ██║██╔████╔██║ ██╔╝ ███████╗██║ ██████╔╝██║██████╔╝ ██║ ╚██╗
  156. // ██╔══╝ ██╔══██╗██║ ██║██║╚██╔╝██║ ╚██╗ ╚════██║██║ ██╔══██╗██║██╔═══╝ ██║ ██╔╝
  157. // ██║ ██║ ██║╚██████╔╝██║ ╚═╝ ██║ ╚██╗███████║╚██████╗██║ ██║██║██║ ██║ ██╔╝
  158. // ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ ╚═╝
  159. //
  160. //
  161. // If available, grab the DOM element for the script tag which imported this file.
  162. // (skip this if this SDK is being used outside of the DOM, i.e. in a Node process)
  163. //
  164. // This is used below to parse client-side sails.io.js configuration encoded as
  165. // HTML attributes, as well as grabbing hold of the URL from whence the SDK was fetched.
  166. var thisScriptTag = (function() {
  167. if (
  168. typeof window !== 'object' ||
  169. typeof window.document !== 'object' ||
  170. typeof window.document.getElementsByTagName !== 'function'
  171. ) {
  172. return null;
  173. }
  174. // Return the URL of the last script loaded (i.e. this one)
  175. // (this must run before nextTick; see http://stackoverflow.com/a/2976714/486547)
  176. var allScriptsCurrentlyInDOM = window.document.getElementsByTagName('script');
  177. return allScriptsCurrentlyInDOM[allScriptsCurrentlyInDOM.length - 1];
  178. })();
  179. // Variables to contain src URL and other script tag config (for use below).
  180. var urlThisScriptWasFetchedFrom = '';
  181. var scriptTagConfig = {};
  182. if (thisScriptTag) {
  183. // Save the URL that this script was fetched from.
  184. urlThisScriptWasFetchedFrom = thisScriptTag.src;
  185. // Now parse the most common client-side configuration settings
  186. // from the script tag where they may be encoded as HTML attributes.
  187. //
  188. // Any configuration which may be provided as an HTML attribute may
  189. // also be provided prefixed with `data-`. This is for folks who
  190. // need to support browsers that have issues with nonstandard
  191. // HTML attributes (or if the idea of using nonstandard HTML attributes
  192. // just creeps you out)
  193. //
  194. // If a `data-` prefixed attr is provided, it takes precedence.
  195. // (this is so that if you are already using one of these HTML
  196. // attrs for some reason, you can keep it as-is and override
  197. // it using `data-`. If you are using the `data-` prefixed version
  198. // for some other purpose... well, in that case you'll just have to
  199. // configure programmatically using `io.sails` instead.)
  200. CONFIGURABLE_VIA_HTML_ATTR.forEach(function (configKey){
  201. scriptTagConfig[configKey] = (function (){
  202. // Support 'data-' prefixed or normal attributes.
  203. // (prefixed versions take precedence if provided)
  204. var htmlAttrVal = thisScriptTag.getAttribute( 'data-'+configKey );
  205. if (!htmlAttrVal) {
  206. htmlAttrVal = thisScriptTag.getAttribute( configKey );
  207. }
  208. // The HTML attribute value should always be a string or `null`.
  209. // We'll try to parse it as JSON and use that, but worst case fall back
  210. // to the default situation of it being a string.
  211. if (typeof htmlAttrVal === 'string') {
  212. try { return JSON.parse(htmlAttrVal); } catch (e) { return htmlAttrVal; }
  213. }
  214. // If `null` was returned from getAttribute(), it means that the HTML attribute
  215. // was not specified, so we treat it as undefined (which will cause the property
  216. // to be removed below)
  217. else if (htmlAttrVal === null) {
  218. return undefined;
  219. }
  220. // Any other contingency shouldn't be possible:
  221. // - if no quotes are used in the HTML attribute, it still comes in as a string.
  222. // - if no RHS is provided for the attribute, it still comes in as "" (empty string)
  223. // (but we still handle this with an explicit error just in case--for debugging and support purposes)
  224. else throw new Error('sails.io.js :: Unexpected/invalid script tag configuration for `'+configKey+'`: `'+htmlAttrVal+'` (a `'+typeof htmlAttrVal+'`). Should be a string.');
  225. })();
  226. if (scriptTagConfig[configKey] === undefined){
  227. delete scriptTagConfig[configKey];
  228. }
  229. });
  230. // Now that they've been parsed, do an extremely lean version of
  231. // logical type validation/coercion of provided values.
  232. //////////////////////////////////////////////////////////////////
  233. // `autoConnect`
  234. if (typeof scriptTagConfig.autoConnect !== 'undefined') {
  235. if (scriptTagConfig.autoConnect === '') {
  236. // Special case for empty string. It means `true` (see above).
  237. scriptTagConfig.autoConnect = true;
  238. }
  239. else if (typeof scriptTagConfig.autoConnect !== 'boolean') {
  240. throw new Error('sails.io.js :: Unexpected/invalid configuration for `autoConnect` provided in script tag: `'+scriptTagConfig.autoConnect+'` (a `'+typeof scriptTagConfig.autoConnect+'`). Should be a boolean.');
  241. }
  242. }
  243. // `environment`
  244. if (typeof scriptTagConfig.environment !== 'undefined') {
  245. if (typeof scriptTagConfig.environment !== 'string') {
  246. throw new Error('sails.io.js :: Unexpected/invalid configuration for `environment` provided in script tag: `'+scriptTagConfig.environment+'` (a `'+typeof scriptTagConfig.environment+'`). Should be a string.');
  247. }
  248. }
  249. // `headers`
  250. if (typeof scriptTagConfig.headers !== 'undefined') {
  251. if (typeof scriptTagConfig.headers !== 'object' || Array.isArray(scriptTagConfig.headers)) {
  252. throw new Error('sails.io.js :: Unexpected/invalid configuration for `headers` provided in script tag: `'+scriptTagConfig.headers+'` (a `'+typeof scriptTagConfig.headers+'`). Should be a JSON-compatible dictionary (i.e. `{}`). Don\'t forget those double quotes (""), even on key names! Use single quotes (\'\') to wrap the HTML attribute value; e.g. `headers=\'{"X-Auth": "foo"}\'`');
  253. }
  254. }
  255. // `url`
  256. if (typeof scriptTagConfig.url !== 'undefined') {
  257. if (typeof scriptTagConfig.url !== 'string') {
  258. throw new Error('sails.io.js :: Unexpected/invalid configuration for `url` provided in script tag: `'+scriptTagConfig.url+'` (a `'+typeof scriptTagConfig.url+'`). Should be a string.');
  259. }
  260. }
  261. // OTHER `io.sails` options are NOT CURRENTLY SUPPORTED VIA HTML ATTRIBUTES.
  262. }
  263. // Grab a reference to the global socket.io client (if one is available).
  264. // This is used via closure below to determine which `io` to use when the
  265. // socket.io client instance (`io`) is augmented to become the Sails client
  266. // SDK instance (still `io`).
  267. var _existingGlobalSocketIO = (typeof io !== 'undefined') ? io : undefined;
  268. //////////////////////////////////////////////////////////////
  269. /////
  270. ///// NOW FOR BUNCHES OF:
  271. ///// - PRIVATE FUNCTION DEFINITIONS
  272. ///// - CONSTRUCTORS
  273. ///// - AND METHODS
  274. /////
  275. //////////////////////////////////////////////////////////////
  276. //
  277. // ███████╗ █████╗ ██╗██╗ ███████╗ ██╗ ██████╗ ██████╗██╗ ██╗███████╗███╗ ██╗████████╗
  278. // ██╔════╝██╔══██╗██║██║ ██╔════╝ ██║██╔═══██╗ ██╔════╝██║ ██║██╔════╝████╗ ██║╚══██╔══╝
  279. // ███████╗███████║██║██║ ███████╗█████╗██║██║ ██║█████╗██║ ██║ ██║█████╗ ██╔██╗ ██║ ██║
  280. // ╚════██║██╔══██║██║██║ ╚════██║╚════╝██║██║ ██║╚════╝██║ ██║ ██║██╔══╝ ██║╚██╗██║ ██║
  281. // ███████║██║ ██║██║███████╗███████║ ██║╚██████╔╝ ╚██████╗███████╗██║███████╗██║ ╚████║ ██║
  282. // ╚══════╝╚═╝ ╚═╝╚═╝╚══════╝╚══════╝ ╚═╝ ╚═════╝ ╚═════╝╚══════╝╚═╝╚══════╝╚═╝ ╚═══╝ ╚═╝
  283. //
  284. /**
  285. * SailsIOClient()
  286. *
  287. * Augment the provided Socket.io client object (`io`) with methods for
  288. * talking and listening to one or more Sails backend(s). If no `io` was
  289. * provided (i.e. in a browser setting), then attempt to use the global.
  290. *
  291. * This absorbs implicit `io.sails` configuration, sets a timer for
  292. * automatically connecting a socket (if `io.sails.autoConnect` is enabled)
  293. * and returns the augmented `io`.
  294. *
  295. * Note:
  296. * The automatically-connected socket is exposed as `io.socket`. If this
  297. * socket attempts to bind event listeners or send requests before it is
  298. * connected, it will be queued up and replayed when the connection is
  299. * successfully opened.
  300. *
  301. * @param {SocketIO} io
  302. * @returns {SailsIOClient} [also called `io`]
  303. */
  304. function SailsIOClient(_providedSocketIO) {
  305. // First, determine which `io` we're augmenting.
  306. //
  307. // Prefer the passed-in `io` instance, but fall back to the
  308. // global one if we've got it.
  309. var io;
  310. if (_providedSocketIO) {
  311. io = _providedSocketIO;
  312. }
  313. else {
  314. io = _existingGlobalSocketIO;
  315. }
  316. // (note that for readability, we deliberately do not short circuit or use the tertiary operator above)
  317. // If a socket.io client (`io`) is not available, none of this will work.
  318. if (!io) {
  319. // If node:
  320. if (SDK_INFO.platform === 'node') {
  321. throw new Error('No socket.io client available. When requiring `sails.io.js` from Node.js, a socket.io client (`io`) must be passed in; e.g.:\n```\nvar io = require(\'sails.io.js\')( require(\'socket.io-client\') )\n```\n(see https://github.com/balderdashy/sails.io.js/tree/master/test for more examples)');
  322. }
  323. // Otherwise, this is a web browser:
  324. else {
  325. throw new Error('The Sails socket SDK depends on the socket.io client, but the socket.io global (`io`) was not available when `sails.io.js` loaded. Normally, the socket.io client code is bundled with sails.io.js, so something is a little off. Please check to be sure this version of `sails.io.js` has the minified Socket.io client at the top of the file.');
  326. }
  327. }
  328. // If the chosen socket.io client (`io`) has ALREADY BEEN AUGMENTED by this SDK,
  329. // (i.e. if it already has a `.sails` property) then throw an error.
  330. if (io.sails) {
  331. // If node:
  332. if (SDK_INFO.platform === 'node') {
  333. throw new Error('The provided socket.io client (`io`) has already been augmented into a Sails socket SDK instance (it has `io.sails`).');
  334. }
  335. // Otherwise, this is a web browser:
  336. else {
  337. throw new Error('The socket.io client (`io`) has already been augmented into a Sails socket SDK instance. Usually, this means you are bringing `sails.io.js` onto the page more than once.');
  338. }
  339. }
  340. /**
  341. * A little logger for this library to use internally.
  342. * Basically just a wrapper around `console.log` with
  343. * support for feature-detection.
  344. *
  345. * @api private
  346. * @factory
  347. */
  348. function LoggerFactory(options) {
  349. options = options || {
  350. prefix: true
  351. };
  352. // If `console.log` is not accessible, `log` is a noop.
  353. if (
  354. typeof console !== 'object' ||
  355. typeof console.log !== 'function' ||
  356. typeof console.log.bind !== 'function'
  357. ) {
  358. return function noop() {};
  359. }
  360. return function log() {
  361. var args = Array.prototype.slice.call(arguments);
  362. // All logs are disabled when `io.sails.environment = 'production'`.
  363. if (io.sails.environment === 'production') return;
  364. // Add prefix to log messages (unless disabled)
  365. var PREFIX = '';
  366. if (options.prefix) {
  367. args.unshift(PREFIX);
  368. }
  369. // Call wrapped logger
  370. console.log
  371. .bind(console)
  372. .apply(this, args);
  373. };
  374. }//</LoggerFactory>
  375. // Create a private logger instance
  376. var consolog = LoggerFactory();
  377. consolog.noPrefix = LoggerFactory({
  378. prefix: false
  379. });
  380. /**
  381. * What is the `requestQueue`?
  382. *
  383. * The request queue is used to simplify app-level connection logic--
  384. * i.e. so you don't have to wait for the socket to be connected
  385. * to start trying to synchronize data.
  386. *
  387. * @api private
  388. * @param {SailsSocket} socket
  389. */
  390. function runRequestQueue (socket) {
  391. var queue = socket.requestQueue;
  392. if (!queue) return;
  393. for (var i in queue) {
  394. // Double-check that `queue[i]` will not
  395. // inadvertently discover extra properties attached to the Object
  396. // and/or Array prototype by other libraries/frameworks/tools.
  397. // (e.g. Ember does this. See https://github.com/balderdashy/sails.io.js/pull/5)
  398. var isSafeToDereference = ({}).hasOwnProperty.call(queue, i);
  399. if (isSafeToDereference) {
  400. // Get the arguments that were originally made to the "request" method
  401. var requestArgs = queue[i];
  402. // Call the request method again in the context of the socket, with the original args
  403. socket.request.apply(socket, requestArgs);
  404. }
  405. }
  406. // Now empty the queue to remove it as a source of additional complexity.
  407. socket.requestQueue = null;
  408. }
  409. /**
  410. * Send a JSONP request.
  411. *
  412. * @param {Object} opts [optional]
  413. * @param {Function} cb
  414. * @return {XMLHttpRequest}
  415. */
  416. function jsonp(opts, cb) {
  417. opts = opts || {};
  418. if (typeof window === 'undefined') {
  419. // FUTURE: refactor node usage to live in here
  420. return cb();
  421. }
  422. var scriptEl = document.createElement('script');
  423. window._sailsIoJSConnect = function(response) {
  424. // In rare circumstances our script may have been vaporised.
  425. // Remove it, but only if it still exists
  426. // https://github.com/balderdashy/sails.io.js/issues/92
  427. if (scriptEl && scriptEl.parentNode) {
  428. scriptEl.parentNode.removeChild(scriptEl);
  429. }
  430. cb(response);
  431. };
  432. scriptEl.src = opts.url;
  433. document.getElementsByTagName('head')[0].appendChild(scriptEl);
  434. }
  435. // ██╗███████╗ ██████╗ ███╗ ██╗ ██╗ ██╗███████╗██████╗ ███████╗ ██████╗ ██████╗██╗ ██╗███████╗████████╗
  436. // ██║██╔════╝██╔═══██╗████╗ ██║ ██║ ██║██╔════╝██╔══██╗██╔════╝██╔═══██╗██╔════╝██║ ██╔╝██╔════╝╚══██╔══╝
  437. // ██║███████╗██║ ██║██╔██╗ ██║█████╗██║ █╗ ██║█████╗ ██████╔╝███████╗██║ ██║██║ █████╔╝ █████╗ ██║
  438. // ██ ██║╚════██║██║ ██║██║╚██╗██║╚════╝██║███╗██║██╔══╝ ██╔══██╗╚════██║██║ ██║██║ ██╔═██╗ ██╔══╝ ██║
  439. // ╚█████╔╝███████║╚██████╔╝██║ ╚████║ ╚███╔███╔╝███████╗██████╔╝███████║╚██████╔╝╚██████╗██║ ██╗███████╗ ██║
  440. // ╚════╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═══╝ ╚══╝╚══╝ ╚══════╝╚═════╝ ╚══════╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝
  441. //
  442. // ██████╗ ███████╗███████╗██████╗ ██████╗ ███╗ ██╗███████╗███████╗ ██╗ ██╗██╗ ██╗██████╗ ██╗
  443. // ██╔══██╗██╔════╝██╔════╝██╔══██╗██╔═══██╗████╗ ██║██╔════╝██╔════╝ ██╔╝ ██║██║ ██║██╔══██╗╚██╗
  444. // ██████╔╝█████╗ ███████╗██████╔╝██║ ██║██╔██╗ ██║███████╗█████╗ ██║ ██║██║ █╗ ██║██████╔╝ ██║
  445. // ██╔══██╗██╔══╝ ╚════██║██╔═══╝ ██║ ██║██║╚██╗██║╚════██║██╔══╝ ██║ ██ ██║██║███╗██║██╔══██╗ ██║
  446. // ██║ ██║███████╗███████║██║ ╚██████╔╝██║ ╚████║███████║███████╗ ╚██╗╚█████╔╝╚███╔███╔╝██║ ██║██╔╝
  447. // ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝╚══════╝ ╚═╝ ╚════╝ ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝
  448. //
  449. /**
  450. * The JWR (JSON WebSocket Response) received from a Sails server.
  451. *
  452. * @api public
  453. * @param {Object} responseCtx
  454. * => :body
  455. * => :statusCode
  456. * => :headers
  457. *
  458. * @constructor
  459. */
  460. function JWR(responseCtx) {
  461. this.body = responseCtx.body;
  462. this.headers = responseCtx.headers || {};
  463. this.statusCode = (typeof responseCtx.statusCode === 'undefined') ? 200 : responseCtx.statusCode;
  464. // FUTURE: Replace this typeof short-circuit with an assertion (statusCode should always be set)
  465. if (this.statusCode < 200 || this.statusCode >= 400) {
  466. // Determine the appropriate error message.
  467. var msg;
  468. if (this.statusCode === 0) {
  469. msg = 'The socket request failed.';
  470. }
  471. else {
  472. msg = 'Server responded with a ' + this.statusCode + ' status code';
  473. msg += ':\n```\n' + JSON.stringify(this.body, null, 2) + '\n```';
  474. // (^^Note that we should always be able to rely on socket.io to give us
  475. // non-circular data here, so we don't have to worry about wrapping the
  476. // above in a try...catch)
  477. }
  478. // Now build and attach Error instance.
  479. this.error = new Error(msg);
  480. }
  481. }
  482. JWR.prototype.toString = function() {
  483. return '[ResponseFromSails]' + ' -- ' +
  484. 'Status: ' + this.statusCode + ' -- ' +
  485. 'Headers: ' + this.headers + ' -- ' +
  486. 'Body: ' + this.body;
  487. };
  488. JWR.prototype.toPOJO = function() {
  489. return {
  490. body: this.body,
  491. headers: this.headers,
  492. statusCode: this.statusCode
  493. };
  494. };
  495. JWR.prototype.pipe = function() {
  496. // FUTURE: look at substack's stuff
  497. return new Error('Client-side streaming support not implemented yet.');
  498. };
  499. // ███████╗███╗ ███╗██╗████████╗███████╗██████╗ ██████╗ ███╗ ███╗ ██╗██╗
  500. // ██╔════╝████╗ ████║██║╚══██╔══╝██╔════╝██╔══██╗██╔═══██╗████╗ ████║██╔╝╚██╗
  501. // █████╗ ██╔████╔██║██║ ██║ █████╗ ██████╔╝██║ ██║██╔████╔██║██║ ██║
  502. // ██╔══╝ ██║╚██╔╝██║██║ ██║ ██╔══╝ ██╔══██╗██║ ██║██║╚██╔╝██║██║ ██║
  503. // ███████╗███████╗██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║╚██████╔╝██║ ╚═╝ ██║╚██╗██╔╝
  504. // ╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚═╝
  505. //
  506. /**
  507. * @api private
  508. * @param {SailsSocket} socket [description]
  509. * @param {Object} requestCtx [description]
  510. */
  511. function _emitFrom(socket, requestCtx) {
  512. if (!socket._raw) {
  513. throw new Error('Failed to emit from socket- raw SIO socket is missing.');
  514. }
  515. // Since callback is embedded in requestCtx,
  516. // retrieve it and delete the key before continuing.
  517. var cb = requestCtx.cb;
  518. delete requestCtx.cb;
  519. // Name of the appropriate socket.io listener on the server
  520. // ( === the request method or "verb", e.g. 'get', 'post', 'put', etc. )
  521. var sailsEndpoint = requestCtx.method;
  522. socket._raw.emit(sailsEndpoint, requestCtx, function serverResponded(responseCtx) {
  523. // Send back (emulatedHTTPBody, jsonWebSocketResponse)
  524. if (cb) {
  525. cb(responseCtx.body, new JWR(responseCtx));
  526. }
  527. });
  528. }
  529. // ███████╗ █████╗ ██╗██╗ ███████╗███████╗ ██████╗ ██████╗██╗ ██╗███████╗████████╗
  530. // ██╔════╝██╔══██╗██║██║ ██╔════╝██╔════╝██╔═══██╗██╔════╝██║ ██╔╝██╔════╝╚══██╔══╝
  531. // ███████╗███████║██║██║ ███████╗███████╗██║ ██║██║ █████╔╝ █████╗ ██║
  532. // ╚════██║██╔══██║██║██║ ╚════██║╚════██║██║ ██║██║ ██╔═██╗ ██╔══╝ ██║
  533. // ███████║██║ ██║██║███████╗███████║███████║╚██████╔╝╚██████╗██║ ██╗███████╗ ██║
  534. // ╚══════╝╚═╝ ╚═╝╚═╝╚══════╝╚══════╝╚══════╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝
  535. //
  536. /**
  537. * SailsSocket
  538. *
  539. * A wrapper for an underlying Socket instance that communicates directly
  540. * to the Socket.io server running inside of Sails.
  541. *
  542. * If no `socket` option is provied, SailsSocket will function as a mock. It will queue socket
  543. * requests and event handler bindings, replaying them when the raw underlying socket actually
  544. * connects. This is handy when we don't necessarily have the valid configuration to know
  545. * WHICH SERVER to talk to yet, etc. It is also used by `io.socket` for your convenience.
  546. *
  547. * @constructor
  548. * @api private
  549. *
  550. * ----------------------------------------------------------------------
  551. * Note: This constructor should not be used directly. To obtain a `SailsSocket`
  552. * instance of your very own, run:
  553. * ```
  554. * var mySocket = io.sails.connect();
  555. * ```
  556. * ----------------------------------------------------------------------
  557. */
  558. function SailsSocket (opts){
  559. var self = this;
  560. opts = opts||{};
  561. // Initialize private properties
  562. self._isConnecting = false;
  563. self._mightBeAboutToAutoConnect = false;
  564. // Set up connection options so that they can only be changed when socket is disconnected.
  565. var _opts = {};
  566. SOCKET_OPTIONS.forEach(function(option) {
  567. // Okay to change global headers while socket is connected
  568. if (option == 'headers') {return;}
  569. Object.defineProperty(self, option, {
  570. get: function() {
  571. if (option == 'url') {
  572. return _opts[option] || (self._raw && self._raw.io && self._raw.io.uri);
  573. }
  574. return _opts[option];
  575. },
  576. set: function(value) {
  577. // Don't allow value to be changed while socket is connected
  578. if (self.isConnected() && io.sails.strict !== false && value != _opts[option]) {
  579. throw new Error('Cannot change value of `' + option + '` while socket is connected.');
  580. }
  581. // If socket is attempting to reconnect, stop it.
  582. if (self._raw && self._raw.io && self._raw.io.reconnecting && !self._raw.io.skipReconnect) {
  583. self._raw.io.skipReconnect = true;
  584. consolog('Stopping reconnect; use .reconnect() to connect socket after changing options.');
  585. }
  586. _opts[option] = value;
  587. }
  588. });
  589. });
  590. // Absorb opts into SailsSocket instance
  591. // See http://sailsjs.com/documentation/reference/web-sockets/socket-client/sails-socket/properties
  592. // for description of options
  593. SOCKET_OPTIONS.forEach(function(option) {
  594. self[option] = opts[option];
  595. });
  596. // Set up "eventQueue" to hold event handlers which have not been set on the actual raw socket yet.
  597. self.eventQueue = {};
  598. // Listen for special `parseError` event sent from sockets hook on the backend
  599. // if an error occurs but a valid callback was not received from the client
  600. // (i.e. so the server had no other way to send back the error information)
  601. self.on('sails:parseError', function (err){
  602. consolog('Sails encountered an error parsing a socket message sent from this client, and did not have access to a callback function to respond with.');
  603. consolog('Error details:',err);
  604. });
  605. // FUTURE:
  606. // Listen for a special private message on any connected that allows the server
  607. // to set the environment (giving us 100% certainty that we guessed right)
  608. // However, note that the `console.log`s called before and after connection
  609. // are still forced to rely on our existing heuristics (to disable, tack #production
  610. // onto the URL used to fetch this file.)
  611. }//</SailsSocket>
  612. /**
  613. * `SailsSocket.prototype._connect()`
  614. *
  615. * Begin connecting this socket to the server.
  616. *
  617. * @api private
  618. */
  619. SailsSocket.prototype._connect = function (){
  620. var self = this;
  621. self._isConnecting = true;
  622. // Apply `io.sails` config as defaults
  623. // (now that at least one tick has elapsed)
  624. // See http://sailsjs.com/documentation/reference/web-sockets/socket-client/sails-socket/properties
  625. // for description of options and default values
  626. SOCKET_OPTIONS.forEach(function(option) {
  627. if ('undefined' == typeof self[option]) {
  628. self[option] = io.sails[option];
  629. }
  630. });
  631. // Headers that will be sent with the initial request to /socket.io (Node.js only)
  632. self.extraHeaders = self.initialConnectionHeaders || {};
  633. // For browser usage (currently works with "polling" transport only)
  634. self.transportOptions = self.transportOptions || {};
  635. self.transports.forEach(function(transport) {
  636. self.transportOptions[transport] = self.transportOptions[transport] || {};
  637. self.transportOptions[transport].extraHeaders = self.initialConnectionHeaders || {};
  638. });
  639. // Log a warning if non-Node.js platform attempts to use `initialConnectionHeaders` for anything other than `polling`.
  640. if (self.initialConnectionHeaders && SDK_INFO.platform !== 'node' && self.transports.indexOf('polling') === -1 || self.transports.length > 1) {
  641. if (typeof console === 'object' && typeof console.warn === 'function') {
  642. console.warn('When running in browser, `initialConnectionHeaders` option is only available for the `polling` transport.');
  643. }
  644. }
  645. // Ensure URL has no trailing slash
  646. self.url = self.url ? self.url.replace(/(\/)$/, '') : undefined;
  647. // Mix the current SDK version into the query string in
  648. // the connection request to the server:
  649. if (typeof self.query === 'string') {
  650. // (If provided as a string, trim leading question mark,
  651. // just in case one was provided.)
  652. self.query = self.query.replace(/^\?/, '');
  653. self.query += '&' + SDK_INFO.versionString;
  654. }
  655. else if (self.query && typeof self.query === 'object') {
  656. throw new Error('`query` setting does not currently support configuration as a dictionary (`{}`). Instead, it must be specified as a string like `foo=89&bar=hi`');
  657. }
  658. else if (!self.query) {
  659. self.query = SDK_INFO.versionString;
  660. }
  661. else {
  662. throw new Error('Unexpected data type provided for `query` setting: '+self.query);
  663. }
  664. // Determine whether this is a cross-origin socket by examining the
  665. // hostname and port on the `window.location` object. If it's cross-origin,
  666. // we'll attempt to get a cookie for the domain so that a Sails session can
  667. // be established.
  668. var isXOrigin = (function (){
  669. // If `window` doesn't exist (i.e. being used from Node.js), then
  670. // we won't bother attempting to get a cookie. If you're using sockets
  671. // from Node.js and find you need to share a session between multiple
  672. // socket connections, you'll need to make an HTTP request to the /__getcookie
  673. // endpoint of the Sails server (or any endpoint that returns a set-cookie header)
  674. // and then use the cookie value in the `initialConnectionHeaders` option to
  675. // io.sails.connect()
  676. if (typeof window === 'undefined' || typeof window.location === 'undefined') {
  677. return false;
  678. }
  679. // If `self.url` (aka "target") is falsy, then we don't need to worry about it.
  680. if (typeof self.url !== 'string') { return false; }
  681. // Get information about the "target" (`self.url`)
  682. var targetProtocol = (function (){
  683. try {
  684. targetProtocol = self.url.match(/^([a-z]+:\/\/)/i)[1].toLowerCase();
  685. }
  686. catch (e) {}
  687. targetProtocol = targetProtocol || 'http://';
  688. return targetProtocol;
  689. })();
  690. var isTargetSSL = !!self.url.match('^https');
  691. var targetPort = (function (){
  692. try {
  693. return self.url.match(/^[a-z]+:\/\/[^:]*:([0-9]*)/i)[1];
  694. }
  695. catch (e){}
  696. return isTargetSSL ? '443' : '80';
  697. })();
  698. var targetAfterProtocol = self.url.replace(/^([a-z]+:\/\/)/i, '');
  699. // If target protocol is different than the actual protocol,
  700. // then we'll consider this cross-origin.
  701. if (targetProtocol.replace(/[:\/]/g, '') !== window.location.protocol.replace(/[:\/]/g,'')) {
  702. return true;
  703. }
  704. // If target hostname is different than actual hostname, we'll consider this cross-origin.
  705. var hasSameHostname = targetAfterProtocol.search(window.location.hostname) === 0;
  706. if (!hasSameHostname) {
  707. return true;
  708. }
  709. // If no actual port is explicitly set on the `window.location` object,
  710. // we'll assume either 80 or 443.
  711. var isLocationSSL = window.location.protocol.match(/https/i);
  712. var locationPort = (window.location.port+'') || (isLocationSSL ? '443' : '80');
  713. // Finally, if ports don't match, we'll consider this cross-origin.
  714. if (targetPort !== locationPort) {
  715. return true;
  716. }
  717. // Otherwise, it's the same origin.
  718. return false;
  719. })();
  720. // Prepare to start connecting the socket
  721. (function selfInvoking (cb){
  722. // If this is an attempt at a cross-origin or cross-port
  723. // socket connection via a browswe, send a JSONP request
  724. // first to ensure that a valid cookie is available.
  725. // This can be disabled by setting `io.sails.useCORSRouteToGetCookie`
  726. // to false.
  727. //
  728. // Otherwise, skip the stuff below.
  729. //
  730. if (!(self.useCORSRouteToGetCookie && isXOrigin)) {
  731. return cb();
  732. }
  733. // Figure out the x-origin CORS route
  734. // (Sails provides a default)
  735. var xOriginCookieURL = self.url;
  736. if (typeof self.useCORSRouteToGetCookie === 'string') {
  737. xOriginCookieURL += self.useCORSRouteToGetCookie;
  738. }
  739. else {
  740. xOriginCookieURL += '/__getcookie';
  741. }
  742. // Make the AJAX request (CORS)
  743. jsonp({
  744. url: xOriginCookieURL,
  745. method: 'GET'
  746. }, cb);
  747. })(function goAheadAndActuallyConnect() {
  748. // Now that we're ready to connect, create a raw underlying Socket
  749. // using Socket.io and save it as `_raw` (this will start it connecting)
  750. self._raw = io(self.url, self);
  751. // If the low-level transport throws an error _while connecting_, then set the _isConnecting flag
  752. // to false (since we're no longer connecting with any chance of success anyway).
  753. // Also, in this case (and in dev mode only) log a helpful message.
  754. self._raw.io.engine.transport.on('error', function(err){
  755. if (!self._isConnecting) { return; }
  756. self._isConnecting = false;
  757. // Track this timestamp for use in reconnection messages
  758. // (only relevant if reconnection is enabled.)
  759. self.connectionErrorTimestamp = (new Date()).getTime();
  760. // Development-only message:
  761. consolog('====================================');
  762. consolog('The socket was unable to connect.');
  763. consolog('The server may be offline, or the');
  764. consolog('socket may have failed authorization');
  765. consolog('based on its origin or other factors.');
  766. consolog('You may want to check the values of');
  767. consolog('`sails.config.sockets.onlyAllowOrigins`');
  768. consolog('or (more rarely) `sails.config.sockets.beforeConnect`');
  769. consolog('in your app.');
  770. consolog('More info: https://sailsjs.com/config/sockets');
  771. consolog('For help: https://sailsjs.com/support');
  772. consolog('');
  773. consolog('Technical details:');
  774. consolog(err);
  775. consolog('====================================');
  776. });
  777. // Replay event bindings from the eager socket
  778. self.replay();
  779. /**
  780. * 'connect' event is triggered when the socket establishes a connection
  781. * successfully.
  782. */
  783. self.on('connect', function socketConnected() {
  784. self._isConnecting = false;
  785. consolog.noPrefix(
  786. '\n' +
  787. '\n' +
  788. // ' |> ' + '\n' +
  789. // ' \\___/ '+️
  790. // '\n'+
  791. ' |> Now connected to '+(self.url ? self.url : 'Sails')+'.' + '\n' +
  792. '\\___/ For help, see: http://bit.ly/2q0QDpf' + '\n' +
  793. ' (using sails.io.js '+io.sails.sdk.platform+' SDK @v'+io.sails.sdk.version+')'+ '\n' +
  794. ' Connected at: '+(new Date())+'\n'+
  795. '\n'+
  796. '\n'+
  797. // '\n'+
  798. ''
  799. // ' ⚓︎ (development mode)'
  800. // 'e.g. to send a GET request to Sails via WebSockets, run:'+ '\n' +
  801. // '`io.socket.get("/foo", function serverRespondedWith (body, jwr) { console.log(body); })`'+ '\n' +
  802. );
  803. });
  804. self.on('disconnect', function() {
  805. self.connectionLostTimestamp = (new Date()).getTime();
  806. consolog('====================================');
  807. consolog('Socket was disconnected from Sails.');
  808. consolog('Usually, this is due to one of the following reasons:' + '\n' +
  809. ' -> the server ' + (self.url ? self.url + ' ' : '') + 'was taken down' + '\n' +
  810. ' -> your browser lost internet connectivity');
  811. consolog('====================================');
  812. });
  813. self.on('reconnecting', function(numAttempts) {
  814. consolog(
  815. '\n'+
  816. ' Socket is trying to reconnect to '+(self.url ? self.url : 'Sails')+'...\n'+
  817. '_-|>_- (attempt #' + numAttempts + ')'+'\n'+
  818. '\n'
  819. );
  820. });
  821. self.on('reconnect', function(transport, numAttempts) {
  822. if (!self._isConnecting) {
  823. self.on('connect', runRequestQueue.bind(self, self));
  824. }
  825. var msSinceLastOffline;
  826. var numSecsOffline;
  827. if (self.connectionLostTimestamp){
  828. msSinceLastOffline = ((new Date()).getTime() - self.connectionLostTimestamp);
  829. numSecsOffline = (msSinceLastOffline / 1000);
  830. }
  831. else if (self.connectionErrorTimestamp) {
  832. msSinceLastOffline = ((new Date()).getTime() - self.connectionErrorTimestamp);
  833. numSecsOffline = (msSinceLastOffline / 1000);
  834. }
  835. else {
  836. msSinceLastOffline = '???';
  837. numSecsOffline = '???';
  838. }
  839. consolog(
  840. '\n'+
  841. ' |> Socket reconnected successfully after'+'\n'+
  842. '\\___/ being offline at least ' + numSecsOffline + ' seconds.'+'\n'+
  843. '\n'
  844. );
  845. });
  846. // 'error' event is triggered if connection can not be established.
  847. // (usually because of a failed authorization, which is in turn
  848. // usually due to a missing or invalid cookie)
  849. self.on('error', function failedToConnect(err) {
  850. self._isConnecting = false;
  851. ////////////////////////////////////////////////////////////////////////////////////
  852. // Note:
  853. // In the future, we could provide a separate event for when a socket cannot connect
  854. // due to a failed `beforeConnect` (aka "authorization" if you're old school).
  855. // this could probably be implemented by emitting a special event from the server.
  856. ////////////////////////////////////////////////////////////////////////////////////
  857. consolog(
  858. 'Failed to connect socket (possibly due to failed `beforeConnect` on server)',
  859. 'Error:', err
  860. );
  861. });
  862. });
  863. };
  864. /**
  865. * Reconnect the underlying socket.
  866. *
  867. * @api public
  868. */
  869. SailsSocket.prototype.reconnect = function (){
  870. if (this._isConnecting) {
  871. throw new Error('Cannot connect- socket is already connecting');
  872. }
  873. if (this.isConnected()) {
  874. throw new Error('Cannot connect- socket is already connected');
  875. }
  876. return this._connect();
  877. };
  878. /**
  879. * Disconnect the underlying socket.
  880. *
  881. * @api public
  882. */
  883. SailsSocket.prototype.disconnect = function (){
  884. this._isConnecting = false;
  885. if (!this.isConnected()) {
  886. throw new Error('Cannot disconnect- socket is already disconnected');
  887. }
  888. return this._raw.disconnect();
  889. };
  890. /**
  891. * isConnected
  892. *
  893. * @return {Boolean} whether the socket is connected and able to
  894. * communicate w/ the server.
  895. */
  896. SailsSocket.prototype.isConnected = function () {
  897. if (!this._raw) {
  898. return false;
  899. }
  900. return !!this._raw.connected;
  901. };
  902. /**
  903. * isConnecting
  904. *
  905. * @return {Boolean} whether the socket is in the process of connecting
  906. * to the server.
  907. */
  908. SailsSocket.prototype.isConnecting = function () {
  909. return this._isConnecting;
  910. };
  911. /**
  912. * isConnecting
  913. *
  914. * @return {Boolean} flag that is `true` after a SailsSocket instance is
  915. * initialized but before one tick of the event loop
  916. * has passed (so that it hasn't attempted to connect
  917. * yet, if autoConnect ends up being configured `true`)
  918. */
  919. SailsSocket.prototype.mightBeAboutToAutoConnect = function() {
  920. return this._mightBeAboutToAutoConnect;
  921. };
  922. /**
  923. * [replay description]
  924. * @return {[type]} [description]
  925. */
  926. SailsSocket.prototype.replay = function (){
  927. var self = this;
  928. // Pass events and a reference to the request queue
  929. // off to the self._raw for consumption
  930. for (var evName in self.eventQueue) {
  931. for (var i in self.eventQueue[evName]) {
  932. self._raw.on(evName, self.eventQueue[evName][i]);
  933. }
  934. }
  935. // Bind a one-time function to run the request queue
  936. // when the self._raw connects.
  937. if ( !self.isConnected() ) {
  938. self._raw.once('connect', runRequestQueue.bind(self, self));
  939. }
  940. // Or run it immediately if self._raw is already connected
  941. else {
  942. runRequestQueue(self);
  943. }
  944. return self;
  945. };
  946. /**
  947. * Chainable method to bind an event to the socket.
  948. *
  949. * @param {String} evName [event name]
  950. * @param {Function} fn [event handler function]
  951. * @return {SailsSocket}
  952. */
  953. SailsSocket.prototype.on = function (evName, fn){
  954. // Bind the event to the raw underlying socket if possible.
  955. if (this._raw) {
  956. this._raw.on(evName, fn);
  957. return this;
  958. }
  959. // Otherwise queue the event binding.
  960. if (!this.eventQueue[evName]) {
  961. this.eventQueue[evName] = [fn];
  962. }
  963. else {
  964. this.eventQueue[evName].push(fn);
  965. }
  966. return this;
  967. };
  968. /**
  969. * Chainable method to unbind an event from the socket.
  970. *
  971. * @param {String} evName [event name]
  972. * @param {Function} fn [event handler function]
  973. * @return {SailsSocket}
  974. */
  975. SailsSocket.prototype.off = function (evName, fn){
  976. // Bind the event to the raw underlying socket if possible.
  977. if (this._raw) {
  978. this._raw.off(evName, fn);
  979. return this;
  980. }
  981. // Otherwise queue the event binding.
  982. if (this.eventQueue[evName] && this.eventQueue[evName].indexOf(fn) > -1) {
  983. this.eventQueue[evName].splice(this.eventQueue[evName].indexOf(fn), 1);
  984. }
  985. return this;
  986. };
  987. /**
  988. * Chainable method to unbind all events from the socket.
  989. *
  990. * @return {SailsSocket}
  991. */
  992. SailsSocket.prototype.removeAllListeners = function (){
  993. // Bind the event to the raw underlying socket if possible.
  994. if (this._raw) {
  995. this._raw.removeAllListeners();
  996. return this;
  997. }
  998. // Otherwise queue the event binding.
  999. this.eventQueue = {};
  1000. return this;
  1001. };
  1002. /**
  1003. * Simulate a GET request to sails
  1004. * e.g.
  1005. * `socket.get('/user/3', Stats.populate)`
  1006. *
  1007. * @api public
  1008. * @param {String} url :: destination URL
  1009. * @param {Object} data :: parameters to send with the request [optional]
  1010. * @param {Function} cb :: callback function to call when finished [optional]
  1011. */
  1012. SailsSocket.prototype.get = function(url, data, cb) {
  1013. // `data` is optional
  1014. if (typeof data === 'function') {
  1015. cb = data;
  1016. data = {};
  1017. }
  1018. return this.request({
  1019. method: 'get',
  1020. params: data,
  1021. url: url
  1022. }, cb);
  1023. };
  1024. /**
  1025. * Simulate a POST request to sails
  1026. * e.g.
  1027. * `socket.post('/event', newMeeting, $spinner.hide)`
  1028. *
  1029. * @api public
  1030. * @param {String} url :: destination URL
  1031. * @param {Object} data :: parameters to send with the request [optional]
  1032. * @param {Function} cb :: callback function to call when finished [optional]
  1033. */
  1034. SailsSocket.prototype.post = function(url, data, cb) {
  1035. // `data` is optional
  1036. if (typeof data === 'function') {
  1037. cb = data;
  1038. data = {};
  1039. }
  1040. return this.request({
  1041. method: 'post',
  1042. data: data,
  1043. url: url
  1044. }, cb);
  1045. };
  1046. /**
  1047. * Simulate a PUT request to sails
  1048. * e.g.
  1049. * `socket.post('/event/3', changedFields, $spinner.hide)`
  1050. *
  1051. * @api public
  1052. * @param {String} url :: destination URL
  1053. * @param {Object} data :: parameters to send with the request [optional]
  1054. * @param {Function} cb :: callback function to call when finished [optional]
  1055. */
  1056. SailsSocket.prototype.put = function(url, data, cb) {
  1057. // `data` is optional
  1058. if (typeof data === 'function') {
  1059. cb = data;
  1060. data = {};
  1061. }
  1062. return this.request({
  1063. method: 'put',
  1064. params: data,
  1065. url: url
  1066. }, cb);
  1067. };
  1068. /**
  1069. * Simulate a PATCH request to sails
  1070. * e.g.
  1071. * `socket.patch('/event/3', changedFields, $spinner.hide)`
  1072. *
  1073. * @api public
  1074. * @param {String} url :: destination URL
  1075. * @param {Object} data :: parameters to send with the request [optional]
  1076. * @param {Function} cb :: callback function to call when finished [optional]
  1077. */
  1078. SailsSocket.prototype.patch = function(url, data, cb) {
  1079. // `data` is optional
  1080. if (typeof data === 'function') {
  1081. cb = data;
  1082. data = {};
  1083. }
  1084. return this.request({
  1085. method: 'patch',
  1086. params: data,
  1087. url: url
  1088. }, cb);
  1089. };
  1090. /**
  1091. * Simulate a DELETE request to sails
  1092. * e.g.
  1093. * `socket.delete('/event', $spinner.hide)`
  1094. *
  1095. * @api public
  1096. * @param {String} url :: destination URL
  1097. * @param {Object} data :: parameters to send with the request [optional]
  1098. * @param {Function} cb :: callback function to call when finished [optional]
  1099. */
  1100. SailsSocket.prototype['delete'] = function(url, data, cb) {
  1101. // `data` is optional
  1102. if (typeof data === 'function') {
  1103. cb = data;
  1104. data = {};
  1105. }
  1106. return this.request({
  1107. method: 'delete',
  1108. params: data,
  1109. url: url
  1110. }, cb);
  1111. };
  1112. /**
  1113. * Simulate an HTTP request to sails
  1114. * e.g.
  1115. * ```
  1116. * socket.request({
  1117. * url:'/user',
  1118. * params: {},
  1119. * method: 'POST',
  1120. * headers: {}
  1121. * }, function (responseBody, JWR) {
  1122. * // ...
  1123. * });
  1124. * ```
  1125. *
  1126. * @api public
  1127. * @option {String} url :: destination URL
  1128. * @option {Object} params :: parameters to send with the request [optional]
  1129. * @option {Object} headers:: headers to send with the request [optional]
  1130. * @option {Function} cb :: callback function to call when finished [optional]
  1131. * @option {String} method :: HTTP request method [optional]
  1132. */
  1133. SailsSocket.prototype.request = function(options, cb) {
  1134. var usage =
  1135. 'Usage:\n'+
  1136. 'socket.request( options, [fnToCallWhenComplete] )\n\n'+
  1137. 'options.url :: e.g. "/foo/bar"'+'\n'+
  1138. 'options.method :: e.g. "get", "post", "put", or "delete", etc.'+'\n'+
  1139. 'options.params :: e.g. { emailAddress: "mike@example.com" }'+'\n'+
  1140. 'options.headers :: e.g. { "x-my-custom-header": "some string" }';
  1141. // Old usage:
  1142. // var usage = 'Usage:\n socket.'+(options.method||'request')+'('+
  1143. // ' destinationURL, [dataToSend], [fnToCallWhenComplete] )';
  1144. // Validate options and callback
  1145. if (typeof cb !== 'undefined' && typeof cb !== 'function') {
  1146. throw new Error('Invalid callback function!\n' + usage);
  1147. }
  1148. if (typeof options !== 'object' || typeof options.url !== 'string') {
  1149. throw new Error('Invalid or missing URL!\n' + usage);
  1150. }
  1151. if (options.method && typeof options.method !== 'string') {
  1152. throw new Error('Invalid `method` provided (should be a string like "post" or "put")\n' + usage);
  1153. }
  1154. if (options.headers && typeof options.headers !== 'object') {
  1155. throw new Error('Invalid `headers` provided (should be a dictionary with string values)\n' + usage);
  1156. }
  1157. if (options.params && typeof options.params !== 'object') {
  1158. throw new Error('Invalid `params` provided (should be a dictionary with JSON-serializable values)\n' + usage);
  1159. }
  1160. if (options.data && typeof options.data !== 'object') {
  1161. throw new Error('Invalid `data` provided (should be a dictionary with JSON-serializable values)\n' + usage);
  1162. }
  1163. // Accept either `params` or `data` for backwards compatibility (but not both!)
  1164. if (options.data && options.params) {
  1165. throw new Error('Cannot specify both `params` and `data`! They are aliases of each other.\n' + usage);
  1166. }
  1167. else if (options.data) {
  1168. options.params = options.data;
  1169. delete options.data;
  1170. }
  1171. // If this socket is not connected yet, queue up this request
  1172. // instead of sending it.
  1173. // (so it can be replayed when the socket comes online.)
  1174. if ( ! this.isConnected() ) {
  1175. // If no queue array exists for this socket yet, create it.
  1176. this.requestQueue = this.requestQueue || [];
  1177. this.requestQueue.push([options, cb]);
  1178. return;
  1179. }
  1180. // Otherwise, our socket is connected, so continue prepping
  1181. // the request.
  1182. // Default headers to an empty object
  1183. options.headers = options.headers || {};
  1184. // Build a simulated request object
  1185. // (and sanitize/marshal options along the way)
  1186. var requestCtx = {
  1187. method: (options.method || 'get').toLowerCase(),
  1188. headers: options.headers,
  1189. data: options.params || options.data || {},
  1190. // Remove trailing slashes and spaces to make packets smaller.
  1191. url: options.url.replace(/^(.+)\/*\s*$/, '$1'),
  1192. cb: cb
  1193. };
  1194. // Merge global headers in, if there are any.
  1195. if (this.headers && 'object' === typeof this.headers) {
  1196. for (var header in this.headers) {
  1197. if (!options.headers.hasOwnProperty(header)) {
  1198. options.headers[header] = this.headers[header];
  1199. }
  1200. }
  1201. }
  1202. // Send the request.
  1203. _emitFrom(this, requestCtx);
  1204. };
  1205. /**
  1206. * Socket.prototype._request
  1207. *
  1208. * Simulate HTTP over Socket.io.
  1209. *
  1210. * @api private
  1211. * @param {[type]} options [description]
  1212. * @param {Function} cb [description]
  1213. */
  1214. SailsSocket.prototype._request = function(options, cb) {
  1215. throw new Error('`_request()` was a private API deprecated as of v0.11 of the sails.io.js client. Use `.request()` instead.');
  1216. };
  1217. // ██╗ ██████╗ ███████╗ █████╗ ██╗██╗ ███████╗
  1218. // ██║██╔═══██╗ ██╔════╝██╔══██╗██║██║ ██╔════╝
  1219. // ██║██║ ██║ ███████╗███████║██║██║ ███████╗
  1220. // ██║██║ ██║ ╚════██║██╔══██║██║██║ ╚════██║
  1221. // ██║╚██████╔╝██╗███████║██║ ██║██║███████╗███████║
  1222. // ╚═╝ ╚═════╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═╝╚══════╝╚══════╝
  1223. //
  1224. // Set an `io.sails` object that may be used for configuration before the
  1225. // first socket connects (i.e. to allow auto-connect behavior to be
  1226. // prevented by setting `io.sails.autoConnect` in an inline script
  1227. // directly after the script tag which loaded this file).
  1228. // ┌─┐┌─┐┌┬┐ ┬ ┬┌─┐ ╔╦╗╔═╗╔═╗╔═╗╦ ╦╦ ╔╦╗╔═╗ ┌─┐┌─┐┬─┐ ┬┌─┐ ┌─┐┌─┐┬┬ ┌─┐
  1229. // └─┐├┤ │ │ │├─┘ ║║║╣ ╠╣ ╠═╣║ ║║ ║ ╚═╗ ├┤ │ │├┬┘ ││ │ └─┐├─┤││ └─┐
  1230. // └─┘└─┘ ┴ └─┘┴ ═╩╝╚═╝╚ ╩ ╩╚═╝╩═╝╩ ╚═╝ └ └─┘┴└─ ┴└─┘o└─┘┴ ┴┴┴─┘└─┘
  1231. io.sails = {
  1232. // Whether to automatically connect a socket and save it as `io.socket`.
  1233. autoConnect: true,
  1234. // Whether to automatically try to reconnect after connection is lost
  1235. reconnection: false,
  1236. // The route (path) to hit to get a x-origin (CORS) cookie
  1237. // (or true to use the default: '/__getcookie')
  1238. useCORSRouteToGetCookie: true,
  1239. // The environment we're running in.
  1240. // (logs are not displayed when this is set to 'production')
  1241. //
  1242. // Defaults to development unless this script was fetched from a URL
  1243. // that ends in `*.min.js` or '#production' (may also be manually overridden.)
  1244. //
  1245. environment: urlThisScriptWasFetchedFrom.match(/(\#production|\.min\.js)/g) ? 'production' : 'development',
  1246. // The version of this sails.io.js client SDK
  1247. sdk: SDK_INFO,
  1248. // Transports to use when communicating with the server, in the order they will be tried
  1249. transports: ['websocket']
  1250. };
  1251. // ┌─┐─┐ ┬┌┬┐┌─┐┌┐┌┌┬┐ ┬┌─┐ ┌─┐┌─┐┬┬ ┌─┐ ┌┬┐┌─┐┌─┐┌─┐┬ ┬┬ ┌┬┐┌─┐
  1252. // ├┤ ┌┴┬┘ │ ├┤ │││ ││ ││ │ └─┐├─┤││ └─┐ ││├┤ ├┤ ├─┤│ ││ │ └─┐
  1253. // └─┘┴ └─ ┴ └─┘┘└┘─┴┘ ┴└─┘o└─┘┴ ┴┴┴─┘└─┘ ─┴┘└─┘└ ┴ ┴└─┘┴─┘┴ └─┘
  1254. // ┬ ┬┬┌┬┐┬ ┬ ┌┬┐┬ ┬┌─┐ ╦ ╦╔╦╗╔╦╗╦ ╔═╗╔╦╗╔╦╗╦═╗╦╔╗ ╦ ╦╔╦╗╔═╗╔═╗
  1255. // ││││ │ ├─┤ │ ├─┤├┤ ╠═╣ ║ ║║║║ ╠═╣ ║ ║ ╠╦╝║╠╩╗║ ║ ║ ║╣ ╚═╗
  1256. // └┴┘┴ ┴ ┴ ┴ ┴ ┴ ┴└─┘ ╩ ╩ ╩ ╩ ╩╩═╝ ╩ ╩ ╩ ╩ ╩╚═╩╚═╝╚═╝ ╩ ╚═╝╚═╝
  1257. // ┌─┐┬─┐┌─┐┌┬┐ ┌┬┐┬ ┬┌─┐ ┌─┐┌─┐┬─┐┬┌─┐┌┬┐ ┌┬┐┌─┐┌─┐
  1258. // ├┤ ├┬┘│ ││││ │ ├─┤├┤ └─┐│ ├┬┘│├─┘ │ │ ├─┤│ ┬
  1259. // └ ┴└─└─┘┴ ┴ ┴ ┴ ┴└─┘ └─┘└─┘┴└─┴┴ ┴ ┴ ┴ ┴└─┘
  1260. //
  1261. // Now fold in config provided as HTML attributes on the script tag:
  1262. // (note that if `io.sails.*` is changed after this script, those changes
  1263. // will still take precedence)
  1264. CONFIGURABLE_VIA_HTML_ATTR.forEach(function (configKey){
  1265. if (typeof scriptTagConfig[configKey] !== 'undefined') {
  1266. io.sails[configKey] = scriptTagConfig[configKey];
  1267. }
  1268. });
  1269. //////////////////////////////////////////////////////////////////////////////
  1270. // Note that the new HTML attribute configuration style may eventually
  1271. // completely replace the original approach of setting `io.sails` properties,
  1272. // since the new strategy is easier to reason about. Also, it would allow us
  1273. // to remove the timeout below someday.
  1274. //////////////////////////////////////////////////////////////////////////////
  1275. // ┬┌─┐ ┌─┐┌─┐┬┬ ┌─┐ ╔═╗╔═╗╔╗╔╔╗╔╔═╗╔═╗╔╦╗ / \
  1276. // ││ │ └─┐├─┤││ └─┐ ║ ║ ║║║║║║║║╣ ║ ║ / /
  1277. // ┴└─┘o└─┘┴ ┴┴┴─┘└─┘o╚═╝╚═╝╝╚╝╝╚╝╚═╝╚═╝ ╩ \ /
  1278. /**
  1279. * Add `io.sails.connect` function as a wrapper for the built-in `io()` aka `io.connect()`
  1280. * method, returning a SailsSocket. This special function respects the configured io.sails
  1281. * connection URL, as well as sending other identifying information (most importantly, the
  1282. * current version of this SDK).
  1283. *
  1284. * @param {String} url [optional]
  1285. * @param {Object} opts [optional]
  1286. * @return {Socket}
  1287. */
  1288. io.sails.connect = function(url, opts) {
  1289. // Make URL optional
  1290. if ('object' === typeof url) {
  1291. opts = url;
  1292. url = null;
  1293. }
  1294. // Default opts to empty object
  1295. opts = opts || {};
  1296. // If explicit connection url is specified, save it to options
  1297. opts.url = url || opts.url || undefined;
  1298. // Instantiate and return a new SailsSocket- and try to connect immediately.
  1299. var socket = new SailsSocket(opts);
  1300. socket._connect();
  1301. return socket;
  1302. };
  1303. // ██╗ ██████╗ ███████╗ ██████╗ ██████╗██╗ ██╗███████╗████████╗
  1304. // ██║██╔═══██╗ ██╔════╝██╔═══██╗██╔════╝██║ ██╔╝██╔════╝╚══██╔══╝
  1305. // ██║██║ ██║ ███████╗██║ ██║██║ █████╔╝ █████╗ ██║
  1306. // ██║██║ ██║ ╚════██║██║ ██║██║ ██╔═██╗ ██╔══╝ ██║
  1307. // ██║╚██████╔╝██╗███████║╚██████╔╝╚██████╗██║ ██╗███████╗ ██║
  1308. // ╚═╝ ╚═════╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝
  1309. //
  1310. // io.socket
  1311. //
  1312. // The eager instance of Socket which will automatically try to connect
  1313. // using the host that this js file was served from.
  1314. //
  1315. // This can be disabled or configured by setting properties on `io.sails.*` within the
  1316. // first cycle of the event loop.
  1317. //
  1318. // Build `io.socket` so it exists
  1319. // (note that this DOES NOT start the connection process)
  1320. io.socket = new SailsSocket();
  1321. //
  1322. // This socket is not connected yet, and has not even _started_ connecting.
  1323. //
  1324. // But in the mean time, this eager socket will be queue events bound by the user
  1325. // before the first cycle of the event loop (using `.on()`), which will later
  1326. // be rebound on the raw underlying socket.
  1327. // ┌─┐┌─┐┌┬┐ ┌─┐┬ ┬┌┬┐┌─┐ ┌─┐┌─┐┌┐┌┌┐┌┌─┐┌─┐┌┬┐ ┌┬┐┬┌┬┐┌─┐┬─┐
  1328. // └─┐├┤ │ ├─┤│ │ │ │ │───│ │ │││││││├┤ │ │ │ ││││├┤ ├┬┘
  1329. // └─┘└─┘ ┴ ┴ ┴└─┘ ┴ └─┘ └─┘└─┘┘└┘┘└┘└─┘└─┘ ┴ ┴ ┴┴ ┴└─┘┴└─
  1330. // If configured to do so, start auto-connecting after the first cycle of the event loop
  1331. // has completed (to allow time for this behavior to be configured/disabled
  1332. // by specifying properties on `io.sails`)
  1333. // Indicate that the autoConnect timer has started.
  1334. io.socket._mightBeAboutToAutoConnect = true;
  1335. setTimeout(function() {
  1336. // Indicate that the autoConect timer fired.
  1337. io.socket._mightBeAboutToAutoConnect = false;
  1338. // If autoConnect is disabled, delete the eager socket (io.socket) and bail out.
  1339. if (io.sails.autoConnect === false || io.sails.autoconnect === false) {
  1340. delete io.socket;
  1341. return;
  1342. }
  1343. // consolog('Eagerly auto-connecting socket to Sails... (requests will be queued in the mean-time)');
  1344. io.socket._connect();
  1345. }, 0); // </setTimeout>
  1346. // Return the `io` object.
  1347. return io;
  1348. } //</SailsIOClient>
  1349. //
  1350. /////////////////////////////////////////////////////////////////////////////////
  1351. ///// </bunches of private function definitions, constructors, and methods>
  1352. /////////////////////////////////////////////////////////////////////////////////
  1353. // ███████╗██╗ ██╗██████╗ ██████╗ ███████╗███████╗ ███████╗██████╗ ██╗ ██╗
  1354. // ██╔════╝╚██╗██╔╝██╔══██╗██╔═══██╗██╔════╝██╔════╝ ██╔════╝██╔══██╗██║ ██╔╝
  1355. // █████╗ ╚███╔╝ ██████╔╝██║ ██║███████╗█████╗ ███████╗██║ ██║█████╔╝
  1356. // ██╔══╝ ██╔██╗ ██╔═══╝ ██║ ██║╚════██║██╔══╝ ╚════██║██║ ██║██╔═██╗
  1357. // ███████╗██╔╝ ██╗██║ ╚██████╔╝███████║███████╗ ███████║██████╔╝██║ ██╗
  1358. // ╚══════╝╚═╝ ╚═╝╚═╝ ╚═════╝ ╚══════╝╚══════╝ ╚══════╝╚═════╝ ╚═╝ ╚═╝
  1359. //
  1360. // Add CommonJS support to allow this client SDK to be used from Node.js.
  1361. if (SDK_INFO.platform === 'node') {
  1362. module.exports = SailsIOClient;
  1363. }
  1364. // Add AMD support, registering this client SDK as an anonymous module.
  1365. else if (typeof define === 'function' && define.amd) {
  1366. define([], function() {
  1367. return SailsIOClient;
  1368. });
  1369. }
  1370. else {
  1371. // Otherwise, try to instantiate the client using the global `io`:
  1372. SailsIOClient();
  1373. // Note:
  1374. // If you are modifying this file manually to wrap an existing socket.io client
  1375. // (e.g. to prevent pollution of the global namespace), you can replace the global
  1376. // `io` with your own `io` instance above.
  1377. }
  1378. })();
  1379. ;
  1380. /* eslint-enable */