rtcdemo/js/libs/peer.js
2014-09-10 21:35:35 +04:30

1 line
38 KiB
JavaScript

/*! peerjs.min.js build:0.3.9, production. Copyright(c) 2013 Michelle Bu <michelle@michellebu.com> */(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(){this.bufferBuilder=new n}function s(e){var t=e.charCodeAt(0);return t<=2047?"00":t<=65535?"000":t<=2097151?"0000":t<=67108863?"00000":"000000"}function o(e){return e.length>600?(new Blob([e])).size:e.replace(/[^\u0000-\u007F]/g,s).length}function u(){this._events={}}function f(e,t){if(!(this instanceof f))return new f(e);this._dc=e,h.debug=t,this._outgoing={},this._incoming={},this._received={},this._window=1e3,this._mtu=500,this._interval=0,this._count=0,this._queue=[],this._setupDC()}function p(e,t){if(!(this instanceof p))return new p(e,t);u.call(this),e&&e.constructor==Object?(t=e,e=undefined):e&&(e=e.toString()),t=h.extend({debug:0,host:h.CLOUD_HOST,port:h.CLOUD_PORT,key:"peerjs",path:"/",token:h.randomToken(),config:h.defaultConfig},t),this.options=t,t.host==="/"&&(t.host=window.location.hostname),t.path[0]!=="/"&&(t.path="/"+t.path),t.path[t.path.length-1]!=="/"&&(t.path+="/"),t.secure===undefined&&t.host!==h.CLOUD_HOST&&(t.secure=h.isSecure()),t.logFunction&&h.setLogFunction(t.logFunction),h.setLogLevel(t.debug);if(!h.supports.audioVideo&&!h.supports.data){this._delayedAbort("browser-incompatible","The current browser does not support WebRTC");return}if(!h.validateId(e)){this._delayedAbort("invalid-id",'ID "'+e+'" is invalid');return}if(!h.validateKey(t.key)){this._delayedAbort("invalid-key",'API KEY "'+t.key+'" is invalid');return}if(t.secure&&t.host==="0.peerjs.com"){this._delayedAbort("ssl-unavailable","The cloud server currently does not support HTTPS. Please run your own PeerServer to use HTTPS.");return}this.destroyed=!1,this.disconnected=!1,this.open=!1,this.connections={},this._lostMessages={},this._initializeServerConnection(),e?this._initialize(e):this._retrieveId()}function d(e,t,n){if(!(this instanceof d))return new d(e,t,n);u.call(this),this.options=h.extend({serialization:"binary",reliable:!1},n),this.open=!1,this.type="data",this.peer=e,this.provider=t,this.id=this.options.connectionId||d._idPrefix+h.randomToken(),this.label=this.options.label||this.id,this.metadata=this.options.metadata,this.serialization=this.options.serialization,this.reliable=this.options.reliable,this._buffer=[],this._buffering=!1,this.bufferSize=0,this._chunkedData={},this.options._payload&&(this._peerBrowser=this.options._payload.browser),m.startConnection(this,this.options._payload||{originator:!0})}function v(e,t,n){if(!(this instanceof v))return new v(e,t,n);u.call(this),this.options=h.extend({},n),this.open=!1,this.type="media",this.peer=e,this.provider=t,this.metadata=this.options.metadata,this.localStream=this.options._stream,this.id=this.options.connectionId||v._idPrefix+h.randomToken(),this.localStream&&m.startConnection(this,{_stream:this.localStream,originator:!0})}function g(e,t,n,r,i){if(!(this instanceof g))return new g(e,t,n,r,i);u.call(this),this.disconnected=!1,this._queue=[];var s=e?"https://":"http://",o=e?"wss://":"ws://";this._httpUrl=s+t+":"+n+r+i,this._wsUrl=o+t+":"+n+r+"peerjs?key="+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<r;n++)e.append(this._parts[n]);return e.getBlob()}return new Blob(this._parts)},e.BinaryPack={unpack:function(e){var t=new r(e);return t.unpack()},pack:function(e){var t=new i;t.pack(e);var n=t.getBuffer();return n}},r.prototype.unpack=function(){var e=this.unpack_uint8();if(e<128){var t=e;return t}if((e^224)<32){var n=(e^224)-32;return n}var r;if((r=e^160)<=15)return this.unpack_raw(r);if((r=e^176)<=15)return this.unpack_string(r);if((r=e^144)<=15)return this.unpack_array(r);if((r=e^128)<=15)return this.unpack_map(r);switch(e){case 192:return null;case 193:return undefined;case 194:return!1;case 195:return!0;case 202:return this.unpack_float();case 203:return this.unpack_double();case 204:return this.unpack_uint8();case 205:return this.unpack_uint16();case 206:return this.unpack_uint32();case 207:return this.unpack_uint64();case 208:return this.unpack_int8();case 209:return this.unpack_int16();case 210:return this.unpack_int32();case 211:return this.unpack_int64();case 212:return undefined;case 213:return undefined;case 214:return undefined;case 215:return undefined;case 216:return r=this.unpack_uint16(),this.unpack_string(r);case 217:return r=this.unpack_uint32(),this.unpack_string(r);case 218:return r=this.unpack_uint16(),this.unpack_raw(r);case 219:return r=this.unpack_uint32(),this.unpack_raw(r);case 220:return r=this.unpack_uint16(),this.unpack_array(r);case 221:return r=this.unpack_uint32(),this.unpack_array(r);case 222:return r=this.unpack_uint16(),this.unpack_map(r);case 223:return r=this.unpack_uint32(),this.unpack_map(r)}},r.prototype.unpack_uint8=function(){var e=this.dataView[this.index]&255;return this.index++,e},r.prototype.unpack_uint16=function(){var e=this.read(2),t=(e[0]&255)*256+(e[1]&255);return this.index+=2,t},r.prototype.unpack_uint32=function(){var e=this.read(4),t=((e[0]*256+e[1])*256+e[2])*256+e[3];return this.index+=4,t},r.prototype.unpack_uint64=function(){var e=this.read(8),t=((((((e[0]*256+e[1])*256+e[2])*256+e[3])*256+e[4])*256+e[5])*256+e[6])*256+e[7];return this.index+=8,t},r.prototype.unpack_int8=function(){var e=this.unpack_uint8();return e<128?e:e-256},r.prototype.unpack_int16=function(){var e=this.unpack_uint16();return e<32768?e:e-65536},r.prototype.unpack_int32=function(){var e=this.unpack_uint32();return e<Math.pow(2,31)?e:e-Math.pow(2,32)},r.prototype.unpack_int64=function(){var e=this.unpack_uint64();return e<Math.pow(2,63)?e:e-Math.pow(2,64)},r.prototype.unpack_raw=function(e){if(this.length<this.index+e)throw new Error("BinaryPackFailure: index is out of range "+this.index+" "+e+" "+this.length);var t=this.dataBuffer.slice(this.index,this.index+e);return this.index+=e,t},r.prototype.unpack_string=function(e){var t=this.read(e),n=0,r="",i,s;while(n<e)i=t[n],i<128?(r+=String.fromCharCode(i),n++):(i^192)<32?(s=(i^192)<<6|t[n+1]&63,r+=String.fromCharCode(s),n+=2):(s=(i&15)<<12|(t[n+1]&63)<<6|t[n+2]&63,r+=String.fromCharCode(s),n+=3);return this.index+=e,r},r.prototype.unpack_array=function(e){var t=new Array(e);for(var n=0;n<e;n++)t[n]=this.unpack();return t},r.prototype.unpack_map=function(e){var t={};for(var n=0;n<e;n++){var r=this.unpack(),i=this.unpack();t[r]=i}return t},r.prototype.unpack_float=function(){var e=this.unpack_uint32(),t=e>>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.getBuffer=function(){return this.bufferBuilder.getBuffer()},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(new Uint8Array(e.buffer)):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())}}}this.bufferBuilder.flush()},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=o(e);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<t;n++)this.pack(e[n])},i.prototype.pack_integer=function(e){if(-32<=e&&e<=127)this.bufferBuilder.append(e&255);else if(0<=e&&e<=255)this.bufferBuilder.append(204),this.pack_uint8(e);else if(-128<=e&&e<=127)this.bufferBuilder.append(208),this.pack_int8(e);else if(0<=e&&e<=65535)this.bufferBuilder.append(205),this.pack_uint16(e);else if(-32768<=e&&e<=32767)this.bufferBuilder.append(209),this.pack_int16(e);else if(0<=e&&e<=4294967295)this.bufferBuilder.append(206),this.pack_uint32(e);else if(-2147483648<=e&&e<=2147483647)this.bufferBuilder.append(210),this.pack_int32(e);else if(-0x8000000000000000<=e&&e<=0x8000000000000000)this.bufferBuilder.append(211),this.pack_int64(e);else{if(!(0<=e&&e<=0x10000000000000000))throw new Error("Invalid integer");this.bufferBuilder.append(207),this.pack_uint64(e)}},i.prototype.pack_double=function(e){var t=0;e<0&&(t=1,e=-e);var n=Math.floor(Math.log(e)/Math.LN2),r=e/Math.pow(2,n)-1,i=Math.floor(r*Math.pow(2,52)),s=Math.pow(2,32),o=t<<31|n+1023<<20|i/s&1048575,u=i%s;this.bufferBuilder.append(203),this.pack_int32(o),this.pack_int32(u)},i.prototype.pack_object=function(e){var t=Object.keys(e),n=t.length;if(n<=15)this.pack_uint8(128+n);else if(n<=65535)this.bufferBuilder.append(222),this.pack_uint16(n);else{if(!(n<=4294967295))throw new Error("Invalid length");this.bufferBuilder.append(223),this.pack_uint32(n)}for(var r in e)e.hasOwnProperty(r)&&(this.pack(r),this.pack(e[r]))},i.prototype.pack_uint8=function(e){this.bufferBuilder.append(e)},i.prototype.pack_uint16=function(e){this.bufferBuilder.append(e>>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 a=Array.isArray;u.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]?a(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,this},u.prototype.on=u.prototype.addListener,u.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},u.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(a(r)){var i=-1;for(var s=0,o=r.length;s<o;s++)if(r[s]===t||r[s].listener&&r[s].listener===t){i=s;break}if(i<0)return this;r.splice(i,1),r.length==0&&delete this._events[e]}else(r===t||r.listener&&r.listener===t)&&delete this._events[e];return this},u.prototype.off=u.prototype.removeListener,u.prototype.removeAllListeners=function(e){return arguments.length===0?(this._events={},this):(e&&this._events&&this._events[e]&&(this._events[e]=null),this)},u.prototype.listeners=function(e){return this._events[e]||(this._events[e]=[]),a(this._events[e])||(this._events[e]=[this._events[e]]),this._events[e]},u.prototype.emit=function(e){var e=arguments[0],t=this._events[e];if(!t)return!1;if(typeof t=="function"){switch(arguments.length){case 1:t.call(this);break;case 2:t.call(this,arguments[1]);break;case 3:t.call(this,arguments[1],arguments[2]);break;default:var n=arguments.length,r=new Array(n-1);for(var i=1;i<n;i++)r[i-1]=arguments[i];t.apply(this,r)}return!0}if(a(t)){var n=arguments.length,r=new Array(n-1);for(var i=1;i<n;i++)r[i-1]=arguments[i];var s=t.slice();for(var i=0,n=s.length;i<n;i++)s[i].apply(this,r);return!0}return!1},f.prototype.send=function(e){var t=h.pack(e);if(t.size<this._mtu){this._handleSend(["no",t]);return}this._outgoing[this._count]={ack:0,chunks:this._chunk(t)},h.debug&&(this._outgoing[this._count].timer=new Date),this._sendWindowedChunks(this._count),this._count+=1},f.prototype._setupInterval=function(){var e=this;this._timeout=setInterval(function(){var t=e._queue.shift();if(t._multiple)for(var n=0,r=t.length;n<r;n+=1)e._intervalSend(t[n]);else e._intervalSend(t)},this._interval)},f.prototype._intervalSend=function(e){var t=this;e=h.pack(e),h.blobToBinaryString(e,function(e){t._dc.send(e)}),t._queue.length===0&&(clearTimeout(t._timeout),t._timeout=null)},f.prototype._processAcks=function(){for(var e in this._outgoing)this._outgoing.hasOwnProperty(e)&&this._sendWindowedChunks(e)},f.prototype._handleSend=function(e){var t=!0;for(var n=0,r=this._queue.length;n<r;n+=1){var i=this._queue[n];i===e?t=!1:i._multiple&&i.indexOf(e)!==-1&&(t=!1)}t&&(this._queue.push(e),this._timeout||this._setupInterval())},f.prototype._setupDC=function(){var e=this;this._dc.onmessage=function(t){var n=t.data,r=n.constructor;if(r===String){var i=h.binaryStringToArrayBuffer(n);n=h.unpack(i),e._handleMessage(n)}}},f.prototype._handleMessage=function(e){var t=e[1],n=this._incoming[t],r=this._outgoing[t],i;switch(e[0]){case"no":var s=t;!s||this.onmessage(h.unpack(s));break;case"end":i=n,this._received[t]=e[2];if(!i)break;this._ack(t);break;case"ack":i=r;if(!!i){var o=e[2];i.ack=Math.max(o,i.ack),i.ack>=i.chunks.length?(h.log("Time: ",new Date-i.timer),delete this._outgoing[t]):this._processAcks()}break;case"chunk":i=n;if(!i){var u=this._received[t];if(u===!0)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)}},f.prototype._chunk=function(e){var t=[],n=e.size,r=0;while(r<n){var i=Math.min(n,r+this._mtu),s=e.slice(r,i),o={payload:s};t.push(o),r=i}return h.log("Created",t.length,"chunks."),t},f.prototype._ack=function(e){var t=this._incoming[e].ack;this._received[e]===t[2]&&(this._complete(e),this._received[e]=!0),this._handleSend(t)},f.prototype._calculateNextAck=function(e){var t=this._incoming[e],n=t.chunks;for(var r=0,i=n.length;r<i;r+=1)if(n[r]===undefined){t.ack[2]=r;return}t.ack[2]=n.length},f.prototype._sendWindowedChunks=function(e){h.log("sendWindowedChunks for: ",e);var t=this._outgoing[e],n=t.chunks,r=[],i=Math.min(t.ack+this._window,n.length);for(var s=t.ack;s<i;s+=1)if(!n[s].sent||s===t.ack)n[s].sent=!0,r.push(["chunk",e,s,n[s].payload]);t.ack+this._window>=n.length&&r.push(["end",e,n.length]),r._multiple=!0,this._handleSend(r)},f.prototype._complete=function(e){h.log("Completed called for",e);var t=this,n=this._incoming[e].chunks,r=new Blob(n);h.blobToArrayBuffer(r,function(e){t.onmessage(h.unpack(e))}),delete this._incoming[e]},f.higherBandwidthSDP=function(e){var t=navigator.appVersion.match(/Chrome\/(.*?) /);if(t){t=parseInt(t[1].split(".").shift());if(t<31){var n=e.split("b=AS:30"),r="b=AS:102400";if(n.length>1)return n[0]+r+n[1]}}return e},f.prototype.onmessage=function(e){},e.Reliable=f,e.RTCSessionDescription=window.RTCSessionDescription||window.mozRTCSessionDescription,e.RTCPeerConnection=window.RTCPeerConnection||window.mozRTCPeerConnection||window.webkitRTCPeerConnection,e.RTCIceCandidate=window.RTCIceCandidate||window.mozRTCIceCandidate;var l={iceServers:[{url:"stun:stun.l.google.com:19302"}]},c=1,h={noop:function(){},CLOUD_HOST:"0.peerjs.com",CLOUD_PORT:9e3,chunkedBrowsers:{Chrome:1},chunkedMTU:16300,logLevel:0,setLogLevel:function(e){var t=parseInt(e,10);isNaN(parseInt(e,10))?h.logLevel=e?3:0:h.logLevel=t,h.log=h.warn=h.error=h.noop,h.logLevel>0&&(h.error=h._printWith("ERROR")),h.logLevel>1&&(h.warn=h._printWith("WARNING")),h.logLevel>2&&(h.log=h._print)},setLogFunction:function(e){e.constructor!==Function?h.warn("The log function you passed in is not a function. Defaulting to regular logs."):h._print=e},_printWith:function(e){return function(){var t=Array.prototype.slice.call(arguments);t.unshift(e),h._print.apply(h,t)}},_print:function(){var e=!1,t=Array.prototype.slice.call(arguments);t.unshift("PeerJS: ");for(var n=0,r=t.length;n<r;n++)t[n]instanceof Error&&(t[n]="("+t[n].name+") "+t[n].message,e=!0);e?console.error.apply(console,t):console.log.apply(console,t)},defaultConfig:l,browser:function(){return window.mozRTCPeerConnection?"Firefox":window.webkitRTCPeerConnection?"Chrome":window.RTCPeerConnection?"Supported":"Unsupported"}(),supports:function(){if(typeof RTCPeerConnection=="undefined")return{};var e=!0,t=!0,n=!1,r=!1,i=!!window.webkitRTCPeerConnection,s,o;try{s=new RTCPeerConnection(l,{optional:[{RtpDataChannels:!0}]})}catch(u){e=!1,t=!1}if(e)try{o=s.createDataChannel("_PEERJSTEST")}catch(u){e=!1}if(e){try{o.binaryType="blob",n=!0}catch(u){}var a=new RTCPeerConnection(l,{});try{var f=a.createDataChannel("_PEERJSRELIABLETEST",{});r=f.reliable}catch(u){}a.close()}t&&(t=!!s.addStream);if(!i&&e){var c=new RTCPeerConnection(l,{optional:[{RtpDataChannels:!0}]});c.onnegotiationneeded=function(){i=!0,h&&h.supports&&(h.supports.onnegotiationneeded=!0)};var p=c.createDataChannel("_PEERJSNEGOTIATIONTEST");setTimeout(function(){c.close()},1e3)}return s&&s.close(),{audioVideo:t,data:e,binaryBlob:n,binary:r,reliable:r,sctp:r,onnegotiationneeded:i}}(),validateId:function(e){return!e||/^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.exec(e)},validateKey:function(e){return!e||/^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.exec(e)},debug:!1,inherits:function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},extend:function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e},pack:BinaryPack.pack,unpack:BinaryPack.unpack,log:function(){if(h.debug){var e=!1,t=Array.prototype.slice.call(arguments);t.unshift("PeerJS: ");for(var n=0,r=t.length;n<r;n++)t[n]instanceof Error&&(t[n]="("+t[n].name+") "+t[n].message,e=!0);e?console.error.apply(console,t):console.log.apply(console,t)}},setZeroTimeout:function(e){function r(r){t.push(r),e.postMessage(n,"*")}function i(r){r.source==e&&r.data==n&&(r.stopPropagation&&r.stopPropagation(),t.length&&t.shift()())}var t=[],n="zero-timeout-message";return e.addEventListener?e.addEventListener("message",i,!0):e.attachEvent&&e.attachEvent("onmessage",i),r}(this),chunk:function(e){var t=[],n=e.size,r=index=0,i=Math.ceil(n/h.chunkedMTU);while(r<n){var s=Math.min(n,r+h.chunkedMTU),o=e.slice(r,s),u={__peerData:c,n:index,data:o,total:i};t.push(u),r=s,index+=1}return c+=1,t},blobToArrayBuffer:function(e,t){var n=new FileReader;n.onload=function(e){t(e.target.result)},n.readAsArrayBuffer(e)},blobToBinaryString:function(e,t){var n=new FileReader;n.onload=function(e){t(e.target.result)},n.readAsBinaryString(e)},binaryStringToArrayBuffer:function(e){var t=new Uint8Array(e.length);for(var n=0;n<e.length;n++)t[n]=e.charCodeAt(n)&255;return t.buffer},randomToken:function(){return Math.random().toString(36).substr(2)},isSecure:function(){return location.protocol==="https:"}};e.util=h,h.inherits(p,u),p.prototype._initializeServerConnection=function(){var e=this;this.socket=new g(this.options.secure,this.options.host,this.options.port,this.options.path,this.options.key),this.socket.on("message",function(t){e._handleMessage(t)}),this.socket.on("error",function(t){e._abort("socket-error",t)}),this.socket.on("disconnected",function(){e.disconnected||(e.emitError("network","Lost connection to server."),e.disconnect())}),this.socket.on("close",function(){e.disconnected||e._abort("socket-closed","Underlying socket is already closed.")})},p.prototype._retrieveId=function(e){var t=this,n=new XMLHttpRequest,r=this.options.secure?"https://":"http://",i=r+this.options.host+":"+this.options.port+this.options.path+this.options.key+"/id",s="?ts="+(new Date).getTime()+""+Math.random();i+=s,n.open("get",i,!0),n.onerror=function(e){h.error("Error retrieving ID",e);var n="";t.options.path==="/"&&t.options.host!==h.CLOUD_HOST&&(n=" If you passed in a `path` to your self-hosted PeerServer, you'll also need to pass in that same path when creating a new Peer."),t._abort("server-error","Could not get an ID from the server."+n)},n.onreadystatechange=function(){if(n.readyState!==4)return;if(n.status!==200){n.onerror();return}t._initialize(n.responseText)},n.send(null)},p.prototype._initialize=function(e){this.id=e,this.socket.start(this.id,this.options.token)},p.prototype._handleMessage=function(e){var t=e.type,n=e.payload,r=e.src;switch(t){case"OPEN":this.emit("open",this.id),this.open=!0;break;case"ERROR":this._abort("server-error",n.msg);break;case"ID-TAKEN":this._abort("unavailable-id","ID `"+this.id+"` is taken");break;case"INVALID-KEY":this._abort("invalid-key",'API KEY "'+this.options.key+'" is invalid');break;case"LEAVE":h.log("Received leave message from",r),this._cleanupPeer(r);break;case"EXPIRE":this.emitError("peer-unavailable","Could not connect to peer "+r);break;case"OFFER":var i=n.connectionId,s=this.getConnection(r,i);if(s)h.warn("Offer received for existing Connection ID:",i);else{if(n.type==="media"){var s=new v(r,this,{connectionId:i,_payload:n,metadata:n.metadata});this._addConnection(r,s),this.emit("call",s)}else{if(n.type!=="data"){h.warn("Received malformed connection type:",n.type);return}s=new d(r,this,{connectionId:i,_payload:n,metadata:n.metadata,label:n.label,serialization:n.serialization,reliable:n.reliable}),this._addConnection(r,s),this.emit("connection",s)}var o=this._getMessages(i);for(var u=0,a=o.length;u<a;u+=1)s.handleMessage(o[u])}break;default:if(!n){h.warn("You received a malformed message from "+r+" of type "+t);return}var f=n.connectionId,s=this.getConnection(r,f);s&&s.pc?s.handleMessage(e):f?this._storeMessage(f,e):h.warn("You received an unrecognized message:",e)}},p.prototype._storeMessage=function(e,t){this._lostMessages[e]||(this._lostMessages[e]=[]),this._lostMessages[e].push(t)},p.prototype._getMessages=function(e){var t=this._lostMessages[e];return t?(delete this._lostMessages[e],t):[]},p.prototype.connect=function(e,t){if(this.disconnected){h.warn("You cannot connect to a new Peer because you called .disconnect() on this Peer and ended your connection with the server. You can create a new Peer to reconnect, or call reconnect on this peer if you believe its ID to still be available."),this.emitError("disconnected","Cannot connect to new Peer after disconnecting from server.");return}var n=new d(e,this,t);return this._addConnection(e,n),n},p.prototype.call=function(e,t,n){if(this.disconnected){h.warn("You cannot connect to a new Peer because you called .disconnect() on this Peer and ended your connection with the server. You can create a new Peer to reconnect."),this.emitError("disconnected","Cannot connect to new Peer after disconnecting from server.");return}if(!t){h.error("To call a peer, you must provide a stream from your browser's `getUserMedia`.");return}n=n||{},n._stream=t;var r=new v(e,this,n);return this._addConnection(e,r),r},p.prototype._addConnection=function(e,t){this.connections[e]||(this.connections[e]=[]),this.connections[e].push(t)},p.prototype.getConnection=function(e,t){var n=this.connections[e];if(!n)return null;for(var r=0,i=n.length;r<i;r++)if(n[r].id===t)return n[r];return null},p.prototype._delayedAbort=function(e,t){var n=this;h.setZeroTimeout(function(){n._abort(e,t)})},p.prototype._abort=function(e,t){h.error("Aborting!"),this._lastServerId?this.disconnect():this.destroy(),this.emitError(e,t)},p.prototype.emitError=function(e,t){h.error("Error:",t),typeof t=="string"&&(t=new Error(t)),t.type=e,this.emit("error",t)},p.prototype.destroy=function(){this.destroyed||(this._cleanup(),this.disconnect(),this.destroyed=!0)},p.prototype._cleanup=function(){if(this.connections){var e=Object.keys(this.connections);for(var t=0,n=e.length;t<n;t++)this._cleanupPeer(e[t])}this.emit("close")},p.prototype._cleanupPeer=function(e){var t=this.connections[e];for(var n=0,r=t.length;n<r;n+=1)t[n].close()},p.prototype.disconnect=function(){var e=this;h.setZeroTimeout(function(){e.disconnected||(e.disconnected=!0,e.open=!1,e.socket&&e.socket.close(),e.emit("disconnected",e.id),e._lastServerId=e.id,e.id=null)})},p.prototype.reconnect=function(){if(this.disconnected&&!this.destroyed)h.log("Attempting reconnection to server with ID "+this._lastServerId),this.disconnected=!1,this._initializeServerConnection(),this._initialize(this._lastServerId);else{if(this.destroyed)throw new Error("This peer cannot reconnect to the server. It has already been destroyed.");if(!!this.disconnected||!!this.open)throw new Error("Peer "+this.id+" cannot reconnect because it is not disconnected from the server!");h.error("In a hurry? We're still trying to make the initial connection!")}},p.prototype.listAllPeers=function(e){e=e||function(){};var t=this,n=new XMLHttpRequest,r=this.options.secure?"https://":"http://",i=r+this.options.host+":"+this.options.port+this.options.path+this.options.key+"/peers",s="?ts="+(new Date).getTime()+""+Math.random();i+=s,n.open("get",i,!0),n.onerror=function(n){t._abort("server-error","Could not get peers from the server."),e([])},n.onreadystatechange=function(){if(n.readyState!==4)return;if(n.status===401){var r="";throw t.options.host!==h.CLOUD_HOST?r="It looks like you're using the cloud server. You can email team@peerjs.com to enable peer listing for your API key.":r="You need to enable `allow_discovery` on your self-hosted PeerServer to use this feature.",new Error("It doesn't look like you have permission to list peers IDs. "+r)}n.status!==200?e([]):e(JSON.parse(n.responseText))},n.send(null)},e.Peer=p,h.inherits(d,u),d._idPrefix="dc_",d.prototype.initialize=function(e){this._dc=this.dataChannel=e,this._configureDataChannel()},d.prototype._configureDataChannel=function(){var e=this;h.supports.sctp&&(this._dc.binaryType="arraybuffer"),this._dc.onopen=function(){h.log("Data channel connection success"),e.open=!0,e.emit("open")},!h.supports.sctp&&this.reliable&&(this._reliable=new f(this._dc,h.debug)),this._reliable?this._reliable.onmessage=function(t){e.emit("data",t)}:this._dc.onmessage=function(t){e._handleDataMessage(t)},this._dc.onclose=function(t){h.log("DataChannel closed for:",e.peer),e.close()}},d.prototype._handleDataMessage=function(e){var t=this,n=e.data,r=n.constructor;if(this.serialization==="binary"||this.serialization==="binary-utf8"){if(r===Blob){h.blobToArrayBuffer(n,function(e){n=h.unpack(e),t.emit("data",n)});return}if(r===ArrayBuffer)n=h.unpack(n);else if(r===String){var i=h.binaryStringToArrayBuffer(n);n=h.unpack(i)}}else this.serialization==="json"&&(n=JSON.parse(n));if(n.__peerData){var s=n.__peerData,o=this._chunkedData[s]||{data:[],count:0,total:n.total};o.data[n.n]=n.data,o.count+=1,o.total===o.count&&(delete this._chunkedData[s],n=new Blob(o.data),this._handleDataMessage({data:n})),this._chunkedData[s]=o;return}this.emit("data",n)},d.prototype.close=function(){if(!this.open)return;this.open=!1,m.cleanup(this),this.emit("close")},d.prototype.send=function(e,t){if(!this.open){this.emit("error",new Error("Connection is not open. You should listen for the `open` event before sending messages."));return}if(this._reliable){this._reliable.send(e);return}var n=this;if(this.serialization==="json")this._bufferedSend(JSON.stringify(e));else if(this.serialization==="binary"||this.serialization==="binary-utf8"){var r=h.pack(e),i=h.chunkedBrowsers[this._peerBrowser]||h.chunkedBrowsers[h.browser];if(i&&!t&&r.size>h.chunkedMTU){this._sendChunks(r);return}h.supports.sctp?h.supports.binaryBlob?this._bufferedSend(r):h.blobToArrayBuffer(r,function(e){n._bufferedSend(e)}):h.blobToBinaryString(r,function(e){n._bufferedSend(e)})}else this._bufferedSend(e)},d.prototype._bufferedSend=function(e){if(this._buffering||!this._trySend(e))this._buffer.push(e),this.bufferSize=this._buffer.length},d.prototype._trySend=function(e){try{this._dc.send(e)}catch(t){this._buffering=!0;var n=this;return setTimeout(function(){n._buffering=!1,n._tryBuffer()},100),!1}return!0},d.prototype._tryBuffer=function(){if(this._buffer.length===0)return;var e=this._buffer[0];this._trySend(e)&&(this._buffer.shift(),this.bufferSize=this._buffer.length,this._tryBuffer())},d.prototype._sendChunks=function(e){var t=h.chunk(e);for(var n=0,r=t.length;n<r;n+=1){var e=t[n];this.send(e,!0)}},d.prototype.handleMessage=function(e){var t=e.payload;switch(e.type){case"ANSWER":this._peerBrowser=t.browser,m.handleSDP(e.type,this,t.sdp);break;case"CANDIDATE":m.handleCandidate(this,t.candidate);break;default:h.warn("Unrecognized message type:",e.type,"from peer:",this.peer)}},h.inherits(v,u),v._idPrefix="mc_",v.prototype.addStream=function(e){h.log("Receiving stream",e),this.remoteStream=e,this.emit("stream",e)},v.prototype.handleMessage=function(e){var t=e.payload;switch(e.type){case"ANSWER":m.handleSDP(e.type,this,t.sdp),this.open=!0;break;case"CANDIDATE":m.handleCandidate(this,t.candidate);break;default:h.warn("Unrecognized message type:",e.type,"from peer:",this.peer)}},v.prototype.answer=function(e){if(this.localStream){h.warn("Local stream already exists on this MediaConnection. Are you answering a call twice?");return}this.options._payload._stream=e,this.localStream=e,m.startConnection(this,this.options._payload);var t=this.provider._getMessages(this.id);for(var n=0,r=t.length;n<r;n+=1)this.handleMessage(t[n]);this.open=!0},v.prototype.close=function(){if(!this.open)return;this.open=!1,m.cleanup(this),this.emit("close")};var m={pcs:{data:{},media:{}},queue:[]};m._idPrefix="pc_",m.startConnection=function(e,t){var n=m._getPeerConnection(e,t);e.type==="media"&&t._stream&&n.addStream(t._stream),e.pc=e.peerConnection=n;if(t.originator){if(e.type==="data"){var r={};h.supports.sctp||(r={reliable:t.reliable});var i=n.createDataChannel(e.label,r);e.initialize(i)}h.supports.onnegotiationneeded||m._makeOffer(e)}else m.handleSDP("OFFER",e,t.sdp)},m._getPeerConnection=function(e,t){m.pcs[e.type]||h.error(e.type+" is not a valid connection type. Maybe you overrode the `type` property somewhere."),m.pcs[e.type][e.peer]||(m.pcs[e.type][e.peer]={});var n=m.pcs[e.type][e.peer],r;t.pc&&(r=m.pcs[e.type][e.peer][t.pc]);if(!r||r.signalingState!=="stable")r=m._startPeerConnection(e);return r},m._startPeerConnection=function(e){h.log("Creating RTCPeerConnection.");var t=m._idPrefix+h.randomToken(),n={};e.type==="data"&&!h.supports.sctp?n={optional:[{RtpDataChannels:!0}]}:e.type==="media"&&(n={optional:[{DtlsSrtpKeyAgreement:!0}]});var r=new RTCPeerConnection(e.provider.options.config,n);return m.pcs[e.type][e.peer][t]=r,m._setupListeners(e,r,t),r},m._setupListeners=function(e,t,n){var r=e.peer,i=e.id,s=e.provider;h.log("Listening for ICE candidates."),t.onicecandidate=function(t){t.candidate&&(h.log("Received ICE candidates for:",e.peer),s.socket.send({type:"CANDIDATE",payload:{candidate:t.candidate,type:e.type,connectionId:e.id},dst:r}))},t.oniceconnectionstatechange=function(){switch(t.iceConnectionState){case"disconnected":case"failed":h.log("iceConnectionState is disconnected, closing connections to "+r),e.close();break;case"completed":t.onicecandidate=h.noop}},t.onicechange=t.oniceconnectionstatechange,h.log("Listening for `negotiationneeded`"),t.onnegotiationneeded=function(){h.log("`negotiationneeded` triggered"),t.signalingState=="stable"?m._makeOffer(e):h.log("onnegotiationneeded triggered when not stable. Is another connection being established?")},h.log("Listening for data channel"),t.ondatachannel=function(e){h.log("Received data channel");var t=e.channel,n=s.getConnection(r,i);n.initialize(t)},h.log("Listening for remote stream"),t.onaddstream=function(e){h.log("Received remote stream");var t=e.stream;s.getConnection(r,i).addStream(t)}},m.cleanup=function(e){h.log("Cleaning up PeerConnection to "+e.peer);var t=e.pc;!!t&&(t.readyState!=="closed"||t.signalingState!=="closed")&&(t.close(),e.pc=null)},m._makeOffer=function(e){var t=e.pc;t.createOffer(function(n){h.log("Created offer."),!h.supports.sctp&&e.type==="data"&&e.reliable&&(n.sdp=f.higherBandwidthSDP(n.sdp)),t.setLocalDescription(n,function(){h.log("Set localDescription: offer","for:",e.peer),e.provider.socket.send({type:"OFFER",payload:{sdp:n,type:e.type,label:e.label,connectionId:e.id,reliable:e.reliable,serialization:e.serialization,metadata:e.metadata,browser:h.browser},dst:e.peer})},function(t){e.provider.emitError("webrtc",t),h.log("Failed to setLocalDescription, ",t)})},function(t){e.provider.emitError("webrtc",t),h.log("Failed to createOffer, ",t)},e.options.constraints)},m._makeAnswer=function(e){var t=e.pc;t.createAnswer(function(n){h.log("Created answer."),!h.supports.sctp&&e.type==="data"&&e.reliable&&(n.sdp=f.higherBandwidthSDP(n.sdp)),t.setLocalDescription(n,function(){h.log("Set localDescription: answer","for:",e.peer),e.provider.socket.send({type:"ANSWER",payload:{sdp:n,type:e.type,connectionId:e.id,browser:h.browser},dst:e.peer})},function(t){e.provider.emitError("webrtc",t),h.log("Failed to setLocalDescription, ",t)})},function(t){e.provider.emitError("webrtc",t),h.log("Failed to create answer, ",t)})},m.handleSDP=function(e,t,n){n=new RTCSessionDescription(n);var r=t.pc;h.log("Setting remote description",n),r.setRemoteDescription(n,function(){h.log("Set remoteDescription:",e,"for:",t.peer),e==="OFFER"&&m._makeAnswer(t)},function(e){t.provider.emitError("webrtc",e),h.log("Failed to setRemoteDescription, ",e)})},m.handleCandidate=function(e,t){var n=t.candidate,r=t.sdpMLineIndex;e.pc.addIceCandidate(new RTCIceCandidate({sdpMLineIndex:r,candidate:n})),h.log("Added ICE candidate for:",e.peer)},h.inherits(g,u),g.prototype.start=function(e,t){this.id=e,this._httpUrl+="/"+e+"/"+t,this._wsUrl+="&id="+e+"&token="+t,this._startXhrStream(),this._startWebSocket()},g.prototype._startWebSocket=function(e){var t=this;if(this._socket)return;this._socket=new WebSocket(this._wsUrl),this._socket.onmessage=function(e){try{var n=JSON.parse(e.data);t.emit("message",n)}catch(r){h.log("Invalid server message",e.data);return}},this._socket.onclose=function(e){h.log("Socket closed."),t.disconnected=!0,t.emit("disconnected")},this._socket.onopen=function(){t._timeout&&(clearTimeout(t._timeout),setTimeout(function(){t._http.abort(),t._http=null},5e3)),t._sendQueuedMessages(),h.log("Socket open")}},g.prototype._startXhrStream=function(e){try{var t=this;this._http=new XMLHttpRequest,this._http._index=1,this._http._streamIndex=e||0,this._http.open("post",this._httpUrl+"/id?i="+this._http._streamIndex,!0),this._http.onreadystatechange=function(){this.readyState==2&&this.old?(this.old.abort(),delete this.old):this.readyState>2&&this.status===200&&this.responseText?t._handleStream(this):this.status!==200&&(clearTimeout(t._timeout),t.emit("disconnected"))},this._http.send(null),this._setHTTPTimeout()}catch(n){h.log("XMLHttpRequest not available; defaulting to WebSockets")}},g.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){h.log("Invalid server message",s);return}this.emit("message",s)}}},g.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)},g.prototype._wsOpen=function(){return this._socket&&this._socket.readyState==1},g.prototype._sendQueuedMessages=function(){for(var e=0,t=this._queue.length;e<t;e+=1)this.send(this._queue[e])},g.prototype.send=function(e){if(this.disconnected)return;if(!this.id){this._queue.push(e);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)}},g.prototype.close=function(){!this.disconnected&&this._wsOpen()&&(this._socket.close(),this.disconnected=!0)}})(this)