/*! peerjs.min.js build:0.2.1, production. Copyright(c) 2013 Michelle Bu */(function(e){function n(){this._pieces=[],this._parts=[]}function r(e){this.index=0,this.dataBuffer=e,this.dataView=new Uint8Array(this.dataBuffer),this.length=this.dataBuffer.byteLength}function i(e){this.utf8=e,this.bufferBuilder=new n}function s(){this._events={}}function a(e,t){if(!(this instanceof a))return new a(e);this._dc=e,u.debug=t,this._outgoing={},this._incoming={},this._received={},this._window=1e3,this._mtu=500,this._interval=10,this._count=0,this._queue=[],this._setupDC()}function h(e,t){e&&e.constructor==Object&&(t=e,e=undefined);if(!(this instanceof h))return new h(e,t);s.call(this);if(!u.isBrowserCompatible()){this._abort("browser-incompatible","The current browser does not support WebRTC DataChannels");return}t.host==="/"&&(t.host=window.location.hostname),t=u.extend({debug:!1,host:"0.peerjs.com",port:9e3,key:"peerjs",config:{iceServers:[{url:"stun:stun.l.google.com:19302"}]}},t),this._options=t,u.debug=t.debug;var n=this;if(e&&!/^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.exec(e)){u.setZeroTimeout(function(){n._abort("invalid-id",'ID "'+e+'" is invalid')});return}if(t.key&&!/^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.exec(t.key)){u.setZeroTimeout(function(){n._abort("invalid-key",'API KEY "'+t.key+'" is invalid')});return}this.destroyed=!1,this.disconnected=!1,this.connections={},this.managers={},this._queued=[],e?(this.id=e,this._init()):(this.id=null,this._getId())}function p(e,t,n){if(!(this instanceof p))return new p(e,t,n);s.call(this),n=u.extend({reliable:!1,serialization:"binary"},n),this.open=!1,this.label=n.label,this.metadata=n.metadata,this.serialization=n.serialization,this.peer=e,this._isReliable=n.reliable,this._dc=t,!this._dc||this._configureDataChannel()}function d(e,t,n,r){if(!(this instanceof d))return new d(e,t,n,r);s.call(this),r=u.extend({config:{iceServers:[{url:"stun:stun.l.google.com:19302"}]}},r),this._options=r,this.open=!0,this.id=e,this.peer=t,this.pc=null,this.labels={},this._default=0,this.connections={},this._queued=[],this._socket=n,!this.id||this.initialize()}function v(e,t,n,r){if(!(this instanceof v))return new v(e,t,n,r);s.call(this),this._id=r;var i=u.randomToken();this.disconnected=!1,this._httpUrl="http://"+e+":"+t+"/"+n+"/"+r+"/"+i,this._wsUrl="ws://"+e+":"+t+"/peerjs?key="+n+"&id="+r+"&token="+i}var t={};t.useBlobBuilder=function(){try{return new Blob([]),!1}catch(e){return!0}}(),t.useArrayBufferView=!t.useBlobBuilder&&function(){try{return(new Blob([new Uint8Array([])])).size===0}catch(e){return!0}}(),e.binaryFeatures=t,e.BlobBuilder=window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder||window.BlobBuilder,n.prototype.append=function(e){typeof e=="number"?this._pieces.push(e):(this._flush(),this._parts.push(e))},n.prototype._flush=function(){if(this._pieces.length>0){var e=new Uint8Array(this._pieces);t.useArrayBufferView||(e=e.buffer),this._parts.push(e),this._pieces=[]}},n.prototype.getBuffer=function(){this._flush();if(t.useBlobBuilder){var e=new BlobBuilder;for(var n=0,r=this._parts.length;n>31,n=(e>>23&255)-127,r=e&8388607|8388608;return(t==0?1:-1)*r*Math.pow(2,n-23)},r.prototype.unpack_double=function(){var e=this.unpack_uint32(),t=this.unpack_uint32(),n=e>>31,r=(e>>20&2047)-1023,i=e&1048575|1048576,s=i*Math.pow(2,r-20)+t*Math.pow(2,r-52);return(n==0?1:-1)*s},r.prototype.read=function(e){var t=this.index;if(t+e<=this.length)return this.dataView.subarray(t,t+e);throw new Error("BinaryPackFailure: read index out of range")},i.prototype.pack=function(e){var n=typeof e;if(n=="string")this.pack_string(e);else if(n=="number")Math.floor(e)===e?this.pack_integer(e):this.pack_double(e);else if(n=="boolean")e===!0?this.bufferBuilder.append(195):e===!1&&this.bufferBuilder.append(194);else if(n=="undefined")this.bufferBuilder.append(192);else{if(n!="object")throw new Error('Type "'+n+'" not yet supported');if(e===null)this.bufferBuilder.append(192);else{var r=e.constructor;if(r==Array)this.pack_array(e);else if(r==Blob||r==File)this.pack_bin(e);else if(r==ArrayBuffer)t.useArrayBufferView?this.pack_bin(new Uint8Array(e)):this.pack_bin(e);else if("BYTES_PER_ELEMENT"in e)t.useArrayBufferView?this.pack_bin(e):this.pack_bin(e.buffer);else if(r==Object)this.pack_object(e);else if(r==Date)this.pack_string(e.toString());else{if(typeof e.toBinaryPack!="function")throw new Error('Type "'+r.toString()+'" not yet supported');this.bufferBuilder.append(e.toBinaryPack())}}}return this.bufferBuilder.getBuffer()},i.prototype.pack_bin=function(e){var t=e.length||e.byteLength||e.size;if(t<=15)this.pack_uint8(160+t);else if(t<=65535)this.bufferBuilder.append(218),this.pack_uint16(t);else{if(!(t<=4294967295))throw new Error("Invalid length");this.bufferBuilder.append(219),this.pack_uint32(t)}this.bufferBuilder.append(e)},i.prototype.pack_string=function(e){var t;if(this.utf8){var n=new Blob([e]);t=n.size}else t=e.length;if(t<=15)this.pack_uint8(176+t);else if(t<=65535)this.bufferBuilder.append(216),this.pack_uint16(t);else{if(!(t<=4294967295))throw new Error("Invalid length");this.bufferBuilder.append(217),this.pack_uint32(t)}this.bufferBuilder.append(e)},i.prototype.pack_array=function(e){var t=e.length;if(t<=15)this.pack_uint8(144+t);else if(t<=65535)this.bufferBuilder.append(220),this.pack_uint16(t);else{if(!(t<=4294967295))throw new Error("Invalid length");this.bufferBuilder.append(221),this.pack_uint32(t)}for(var n=0;n>8),this.bufferBuilder.append(e&255)},i.prototype.pack_uint32=function(e){var t=e&4294967295;this.bufferBuilder.append((t&4278190080)>>>24),this.bufferBuilder.append((t&16711680)>>>16),this.bufferBuilder.append((t&65280)>>>8),this.bufferBuilder.append(t&255)},i.prototype.pack_uint64=function(e){var t=e/Math.pow(2,32),n=e%Math.pow(2,32);this.bufferBuilder.append((t&4278190080)>>>24),this.bufferBuilder.append((t&16711680)>>>16),this.bufferBuilder.append((t&65280)>>>8),this.bufferBuilder.append(t&255),this.bufferBuilder.append((n&4278190080)>>>24),this.bufferBuilder.append((n&16711680)>>>16),this.bufferBuilder.append((n&65280)>>>8),this.bufferBuilder.append(n&255)},i.prototype.pack_int8=function(e){this.bufferBuilder.append(e&255)},i.prototype.pack_int16=function(e){this.bufferBuilder.append((e&65280)>>8),this.bufferBuilder.append(e&255)},i.prototype.pack_int32=function(e){this.bufferBuilder.append(e>>>24&255),this.bufferBuilder.append((e&16711680)>>>16),this.bufferBuilder.append((e&65280)>>>8),this.bufferBuilder.append(e&255)},i.prototype.pack_int64=function(e){var t=Math.floor(e/Math.pow(2,32)),n=e%Math.pow(2,32);this.bufferBuilder.append((t&4278190080)>>>24),this.bufferBuilder.append((t&16711680)>>>16),this.bufferBuilder.append((t&65280)>>>8),this.bufferBuilder.append(t&255),this.bufferBuilder.append((n&4278190080)>>>24),this.bufferBuilder.append((n&16711680)>>>16),this.bufferBuilder.append((n&65280)>>>8),this.bufferBuilder.append(n&255)};var o=Array.isArray;s.prototype.addListener=function(e,t,n,r){if("function"!=typeof t)throw new Error("addListener only takes instances of Function");return this.emit("newListener",e,typeof t.listener=="function"?t.listener:t),this._events[e]?o(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,this},s.prototype.on=s.prototype.addListener,s.prototype.once=function(e,t,n){function i(){r.removeListener(e,i),t.apply(this,arguments)}if("function"!=typeof t)throw new Error(".once only takes instances of Function");var r=this;return i.listener=t,r.on(e,i),this},s.prototype.removeListener=function(e,t,n){if("function"!=typeof t)throw new Error("removeListener only takes instances of Function");if(!this._events[e])return this;var r=this._events[e];if(o(r)){var i=-1;for(var s=0,u=r.length;s1){var n=e[1].split(".")[0];return parseInt(n)>=this.chromeVersion}if(this.firefoxCompatible&&(t=navigator.userAgent.split("Firefox/"))&&t.length>1){var n=t[1].split(".")[0];return parseInt(n)>=this.firefoxVersion}return!1}};a.prototype.send=function(e){var t=u.pack(e);if(t.size=i.chunks.length?(u.log("Time: ",new Date-i.timer),delete this._outgoing[t]):this._processAcks()}break;case"chunk":i=n;if(!i){if(this._received[t]!==undefined)break;i={ack:["ack",t,0],chunks:[]},this._incoming[t]=i}var a=e[2],f=e[3];i.chunks[a]=new Uint8Array(f),a===i.ack[2]&&this._calculateNextAck(t),this._ack(t);break;default:this._handleSend(e)}},a.prototype._chunk=function(e){var t=[],n=e.size,r=0;while(r=n.length-1&&r.push(["end",e,n.length]),r._multiple=!0,this._handleSend(r)},a.prototype._complete=function(e){u.log("Complete",e);var t=this,n=this._incoming[e].chunks,r=new Blob(n);u.blobToArrayBuffer(r,function(e){u.log("Calling onmessage with complete message"),t.onmessage(u.unpack(e))}),delete this._incoming[e]},a.higherBandwidthSDP=function(e){var t=e.split("b=AS:30"),n="b=AS:102400";return t[0]+n+t[1]},e.Reliable=a;var f=null,l=null,c=null;navigator.mozGetUserMedia?(u.browserisms="Firefox",RTCSessionDescription=window.mozRTCSessionDescription,f=window.mozRTCPeerConnection,l=navigator.mozGetUserMedia.bind(navigator)):navigator.webkitGetUserMedia&&(u.browserisms="Webkit",f=window.webkitRTCPeerConnection,l=navigator.webkitGetUserMedia.bind(navigator)),e.RTCSessionDescription=RTCSessionDescription,e.RTCPeerConnection=f,e.getUserMedia=l,u.inherits(h,s),h.prototype._getId=function(e){var t=this;try{var n=new XMLHttpRequest,r="http://"+this._options.host+":"+this._options.port+"/"+this._options.key+"/id",i="?ts="+(new Date).getTime()+""+Math.random();r+=i,n.open("get",r,!0),n.onreadystatechange=function(){n.readyState===4&&(t.id=n.responseText,t._init())},n.send(null)}catch(s){this._abort("server-error","Could not get an ID from the server")}},h.prototype._init=function(){var e=this;this._socket=new v(this._options.host,this._options.port,this._options.key,this.id),this._socket.on("message",function(t){e._handleServerJSONMessage(t)}),this._socket.on("error",function(t){u.log(t),e._abort("socket-error",t)}),this._socket.on("close",function(){var t="Underlying socket has closed";u.log("error",t),e._abort("socket-closed",t)}),this._socket.start()},h.prototype._handleServerJSONMessage=function(e){var t=e.src,n=this.managers[t],r=e.payload;switch(e.type){case"OPEN":this._processQueue(),this.emit("open",this.id);break;case"ERROR":u.log(r.msg),this._abort("server-error",r.msg);break;case"ID-TAKEN":this._abort("unavailable-id","ID `"+this.id+"` is taken");break;case"OFFER":var i={sdp:r.sdp,labels:r.labels,config:this._options.config},n=this.managers[t];n||(n=new d(this.id,t,this._socket,i),this._attachManagerListeners(n),this.managers[t]=n,this.connections[t]={}),n.update(i.labels),n.handleSDP(r.sdp,e.type);break;case"EXPIRE":n&&(n.close(),n.emit("error",new Error("Could not connect to peer "+n.peer)));break;case"ANSWER":n&&n.handleSDP(r.sdp,e.type);break;case"CANDIDATE":n&&n.handleCandidate(r);break;case"LEAVE":n&&n.handleLeave();break;case"INVALID-KEY":this._abort("invalid-key",'API KEY "'+this._key+'" is invalid');break;case"PORT":default:u.log("Unrecognized message type:",e.type)}},h.prototype._processQueue=function(){while(this._queued.length>0){var e=this._queued.pop();e.initialize(this.id,this._socket)}},h.prototype._attachManagerListeners=function(e){var t=this;e.on("connection",function(e){t.connections[e.peer][e.label]=e,t.emit("connection",e)}),e.on("close",function(){!t.managers[e.peer]||delete t.managers[e.peer]}),e.on("error",function(e){t.emit("error",e)})},h.prototype._abort=function(e,t){var n=new Error(t);n.type=e,this.destroy(),this.emit("error",n)},h.prototype._cleanup=function(){var e=this;if(!!this.managers){var t=Object.keys(this.managers);for(var n=0,r=t.length;n2&&this.status==200&&!!this.responseText&&t._handleStream(this)},this._http.send(null),this._setHTTPTimeout()}catch(n){u.log("XMLHttpRequest not available; defaulting to WebSockets")}},v.prototype._handleStream=function(e){var t=e.responseText.split("\n");if(!!e._buffer)while(e._buffer.length>0){var n=e._buffer.shift(),r=t[n];try{r=JSON.parse(r)}catch(i){e._buffer.shift(n);break}this.emit("message",r)}var s=t[e._index];if(!!s){e._index+=1;if(e._index===t.length)e._buffer||(e._buffer=[]),e._buffer.push(e._index-1);else{try{s=JSON.parse(s)}catch(i){u.log("Invalid server message",s);return}this.emit("message",s)}}},v.prototype._setHTTPTimeout=function(){var e=this;this._timeout=setTimeout(function(){var t=e._http;e._wsOpen()?t.abort():(e._startXhrStream(t._streamIndex+1),e._http.old=t)},25e3)},v.prototype._wsOpen=function(){return!!this._socket&&this._socket.readyState==1},v.prototype.send=function(e){if(this.disconnected)return;if(!e.type){this.emit("error","Invalid message");return}var t=JSON.stringify(e);if(this._wsOpen())this._socket.send(t);else{var n=new XMLHttpRequest,r=this._httpUrl+"/"+e.type.toLowerCase();n.open("post",r,!0),n.setRequestHeader("Content-Type","application/json"),n.send(t)}},v.prototype.close=function(){!this.disconnected&&this._wsOpen()&&(this._socket.close(),this.disconnected=!0)}})(this)