├── .gitignore ├── .jshintrc ├── .travis.yml ├── .zuul.yml ├── CONTRIBUTING.md ├── LICENCE ├── Procfile ├── README.md ├── browser └── index.js ├── demo ├── index.html └── media.html ├── package.json ├── server └── index.js ├── socketpeer.js ├── socketpeer.min.js └── test └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.csv 2 | *.dat 3 | *.floo* 4 | *.gz 5 | *.log 6 | *.out 7 | *.pid 8 | *.seed 9 | build/ 10 | data/ 11 | lib-cov 12 | logs 13 | node_modules 14 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "esnext": true 3 | } 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.10' 4 | env: 5 | global: 6 | - secure: hYrrXu5o3kRv+AGBoTpUT1ybT32j79q4Cq2GnJgtc0ACL1mBut+KbmG1R9NHtcrHhHigRVmZfDmijaU50QgmDjmbCe+D0ZohYXNxd+qhBbN9pNlrx3P5B8HUaiYAH06b+z8PK5qlXmrnkRFkZJGrdvfeJwEXyQmnkbDsj7bWxy0= 7 | - secure: ZXyh5RmQos+QVmIftsALdh/gwbJvAxbfrHTc6J0b2V5GJN2CP6LblVf4YcmddSx1cin0C7uipzoL1pnj7MLaDgpk4LUzIFp852TV+3v7zGLI/TQkdnuMtaOWdk07aw2xKCzMfvyhjKDqy+6QSAhlR84M/n+APZRccPAYQdIM6s0= 8 | -------------------------------------------------------------------------------- /.zuul.yml: -------------------------------------------------------------------------------- 1 | ui: tape 2 | browsers: 3 | - name: chrome 4 | version: latest 5 | - name: firefox 6 | version: latest 7 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributions are very welcome. Before contributing, please note the following: 2 | 3 | * You agree to licence your contributions under the [licence](LICENCE). 4 | * If contributing code, follow [jshint](http://www.jshint.com/) and our other [style-guide conventions](http://mozweb.readthedocs.org/en/latest/index.html). 5 | * When appropriate, please write tests and update the docs (i.e., the [README](README.md)). 6 | 7 | Thank you - and happy contributing! 8 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright © 2015 Chris Van and Matthew Claypotch 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: npm run prod 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SocketPeer 2 | 3 | Simple 1:1 messaging via [WebRTC Data Channels](https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel) and [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API). 4 | 5 | [Read this great **walk-through article**.](https://hacks.mozilla.org/2015/04/peering-through-the-webrtc-fog-with-socketpeer/) 6 | 7 | [**View a live demo** of a project using SocketPeer!](https://socketpeer-test.herokuapp.com/) See the (project's [source code](https://github.com/potch/test-socketpeer)). 8 | 9 | 10 | ## Features 11 | 12 | * concise, [Node.js](https://nodejs.org/)-style API for **[WebRTC](https://en.wikipedia.org/wiki/WebRTC)** peer-to-peer connections 13 | * simple 1:1 peer connection signalling, pairing, and messaging 14 | * fallback WebSocket support if WebRTC Data Channels are unsupported 15 | * automatic reconnection if peer connections prematurely close 16 | * exports as a [UMD](https://github.com/umdjs/umd) module, so the library works everywhere (i.e., using [Browserify](http://browserify.org/), [webpack](https://webpack.js.org/), or included by a ` 22 | 42 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /demo/media.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SocketPeer demo 7 | 15 | 16 | 17 |
18 |

SocketPeer Media demo

19 | 20 | 21 |
22 | 23 | 24 | 44 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "socketpeer", 3 | "description": "simple 1:1 messaging via WebRTC Data Channels and WebSockets", 4 | "version": "1.1.0", 5 | "repository": { 6 | "type": "git", 7 | "url": "git://github.com/cvan/socketpeer.git" 8 | }, 9 | "bugs": { 10 | "url": "https://github.com/cvan/socketpeer/issues" 11 | }, 12 | "dependencies": { 13 | "cross-env": "^4.0.0", 14 | "inherits": "^2.0.1", 15 | "simple-peer": "^4.0.2", 16 | "ws": "^0.7.1", 17 | "xtend": "^4.0.0" 18 | }, 19 | "devDependencies": { 20 | "browserify": "^9.0.3", 21 | "nodemon": "^1.3.7", 22 | "onchange": "^1.0.0", 23 | "release-it": "^2.7.1", 24 | "semistandard": "^10.0.0", 25 | "snazzy": "^7.0.0", 26 | "tape": "^3.5.0", 27 | "uglify-js": "^2.4.17", 28 | "zuul": "^2.1.1" 29 | }, 30 | "keywords": [ 31 | "webrtc", 32 | "p2p", 33 | "data channel", 34 | "data channels", 35 | "data", 36 | "peer", 37 | "stream", 38 | "peer-to-peer", 39 | "data channel stream", 40 | "webrtc stream", 41 | "peer", 42 | "websocket", 43 | "websockets", 44 | "socketpeer" 45 | ], 46 | "license": "MIT", 47 | "main": "server/index.js", 48 | "browser": "browser/index.js", 49 | "scripts": { 50 | "start": "npm run dev", 51 | "predev": "npm run build", 52 | "dev": "cross-env NODE_ENV=development nodemon server", 53 | "preprod": "npm run build", 54 | "prod": "cross-env NODE_ENV=production node server", 55 | "dist": "npm run build", 56 | "build": "npm run browserify && npm run minify", 57 | "browserify": "browserify -s SocketPeer -r ./browser/ -o socketpeer.js", 58 | "minify": "uglifyjs socketpeer.js -c warnings=false -m > socketpeer.min.js", 59 | "prewatch": "npm run build", 60 | "watch": "onchange browser/* -- npm run build", 61 | "lint": "semistandard -v | snazzy || true", 62 | "lint-fix": "semistandard -v --fix | snazzy || true", 63 | "pretest": "npm run lint", 64 | "test": "zuul -- test/*.js", 65 | "pretest-local": "npm run lint", 66 | "test-local": "zuul --local 3001 -- test/*.js", 67 | "release": "release-it", 68 | "release-major": "npm run release -- --increment major", 69 | "release-minor": "npm run release -- --increment minor", 70 | "release-patch": "npm run release -- --increment patch" 71 | }, 72 | "semistandard": { 73 | "ignore": [ 74 | "dist", 75 | "socketpeer*.js" 76 | ] 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | /* jshint node: true */ 2 | 3 | const fs = require('fs'); 4 | const http = require('http'); 5 | const path = require('path'); 6 | const urllib = require('url'); 7 | 8 | const ws = require('ws'); 9 | 10 | const nodeEnv = process.env.NODE_ENV || 'development'; 11 | const WebSocketServer = ws.Server; 12 | 13 | function SocketPeerServer (opts) { 14 | opts = opts || {}; 15 | 16 | if (!opts.httpServer) { 17 | const host = opts.host || process.env.SOCKETPEER_HOST || process.env.HOST || '0.0.0.0'; 18 | const port = opts.port || process.env.SOCKETPEER_PORT || process.env.PORT || 3000; 19 | 20 | opts.httpServer = http.createServer((req, res) => { 21 | var url = urllib.parse(req.url).pathname; 22 | 23 | if (nodeEnv === 'development') { 24 | let stream; 25 | // For demo purposes. 26 | if (url === '/' || url === '/demo/') { 27 | // res.writeHead(200, {'Content-Type': 'text/html'}); 28 | stream = fs.createReadStream(path.join(__dirname, '..', 'demo', 'index.html')); 29 | stream.pipe(res); 30 | } 31 | if (url === '/media/') { 32 | // res.writeHead(200, {'Content-Type': 'text/html'}); 33 | stream = fs.createReadStream(path.join(__dirname, '..', 'demo', 'media.html')); 34 | stream.pipe(res); 35 | } 36 | } 37 | }); 38 | 39 | opts.httpServer.listen(port, host, () => { 40 | console.log('[%s] Server listening on %s:%s', nodeEnv, host, port); 41 | }); 42 | } 43 | 44 | if (typeof opts.serveLibrary === 'undefined' || opts.serveLibrary) { 45 | opts.httpServer.on('request', (req, res) => { 46 | var url = urllib.parse(req.url).pathname; 47 | if (url === '/socketpeer/socketpeer.js') { 48 | res.writeHead(200, {'Content-Type': 'text/javascript'}); 49 | var stream = fs.createReadStream(path.join(__dirname, '..', 'socketpeer.js')); 50 | stream.pipe(res); 51 | } 52 | }); 53 | } 54 | 55 | if (!opts.wsServer) { 56 | opts.wsServer = new WebSocketServer({ 57 | server: opts.httpServer, 58 | path: '/socketpeer/' 59 | }); 60 | } 61 | 62 | var peersWaiting = Object.create(null); 63 | var connections = Object.create(null); 64 | 65 | function closeConnection (pairCode, filter) { 66 | if (!filter) { 67 | // Create a no-op function. 68 | filter = x => x; 69 | } 70 | let matched = false; 71 | connections[pairCode].forEach(conn => { 72 | matched = filter(conn); 73 | if (matched) { 74 | conn.peer = null; 75 | } 76 | }); 77 | if (matched) { 78 | connections[pairCode] = null; 79 | } 80 | } 81 | 82 | function sendMessage (type, data) { 83 | this.send(JSON.stringify({ 84 | type: type, 85 | data: data 86 | })); 87 | } 88 | 89 | opts.wsServer.on('connection', client => { 90 | client.sendMessage = sendMessage.bind(client); 91 | 92 | console.log('Connection'); 93 | 94 | client.on('message', msg => { 95 | console.log('[message] Received message: %s', msg); 96 | 97 | var obj = JSON.parse(msg); 98 | client.emit('message.' + obj.type, obj.data); 99 | }); 100 | 101 | client.on('message.data', data => { 102 | console.log('[pair] Received data:', data); 103 | 104 | if (client.peer) { 105 | client.peer.sendMessage('data', data); 106 | } 107 | }); 108 | 109 | client.on('message.pair', pairCode => { 110 | console.log('[pair] Received pairCode:', pairCode); 111 | 112 | if (connections[pairCode]) { 113 | client.sendMessage('warning', { 114 | message: '`pairCode` "' + pairCode + '" is already in use', 115 | pairCode: pairCode 116 | }); 117 | closeConnection(pairCode, function (clientToCheck) { 118 | return clientToCheck !== client; 119 | }); 120 | } 121 | 122 | client.pairCode = pairCode; 123 | 124 | var waiting = peersWaiting[pairCode]; 125 | 126 | if (waiting && waiting !== client) { 127 | console.log('[pair] Other peer found'); 128 | 129 | client.peer = waiting; 130 | waiting.peer = client; 131 | connections[pairCode] = [client, waiting]; 132 | peersWaiting[pairCode] = null; 133 | waiting.sendMessage('peer.found', {initiator: false}); 134 | client.sendMessage('peer.found', {initiator: true}); 135 | } else { 136 | console.log('[pair] No other peer found'); 137 | // I am waiting for you. 138 | peersWaiting[pairCode] = client; 139 | } 140 | }); 141 | 142 | client.on('message.rtc.signal', data => { 143 | console.log('[rtc.signal] Signal recieved'); 144 | 145 | if (client.peer) { 146 | client.peer.sendMessage('rtc.signal', data); 147 | } else { 148 | console.warn('[rtc.signal] Signal with no peer!'); 149 | } 150 | }); 151 | 152 | client.on('message.rtc.connect', () => { 153 | console.log('[rtc.connect] Received'); 154 | 155 | if (client.peer) { 156 | client.peer.sendMessage('rtc.connect'); 157 | } 158 | }); 159 | 160 | client.on('close', () => { 161 | const pairCode = client.pairCode; 162 | if (pairCode in peersWaiting && peersWaiting[pairCode] === client) { 163 | peersWaiting[pairCode] = null; 164 | } 165 | 166 | if (client.peer) { 167 | peersWaiting[pairCode] = client.peer; 168 | closeConnection(pairCode); 169 | } 170 | }); 171 | }); 172 | 173 | return opts.httpServer; 174 | } 175 | 176 | // Immediately start the server if the server is called directly 177 | // (i.e., not required as a module). 178 | if (require.main === module) { 179 | SocketPeerServer(); 180 | } 181 | 182 | module.exports = SocketPeerServer; 183 | -------------------------------------------------------------------------------- /socketpeer.min.js: -------------------------------------------------------------------------------- 1 | !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.SocketPeer=e()}}(function(){return function e(t,n,r){function i(s,a){if(!n[s]){if(!t[s]){var c="function"==typeof require&&require;if(!a&&c)return c(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var f=n[s]={exports:{}};t[s][0].call(f.exports,function(e){var n=t[s][1][e];return i(n?n:e)},f,f.exports,e,t,n,r)}return n[s].exports}for(var o="function"==typeof require&&require,s=0;s0&&t.emit("reconnect"),t.initiator=e.initiator,e.initiator&&(t._send("rtc.connect"),t._rtcInit())}),t.on("rtc.signal",t._rtcSignal),t.on("rtc.connect",function(){t._rtcInit()}),t.on("busy",function(){t._socketError(new Error('Pair code "'+t.pairCode+'" already in use')),t.socket.close()}),void(t.autoconnect&&setTimeout(function(){t.connect()},0))):new r(e)}var i=e("events"),o=e("inherits"),s=e("xtend/mutable"),a=e("simple-peer"),c=i.EventEmitter;o(r,c),r.prototype.pair=function(e){var t=this;"undefined"!=typeof e&&(t.pairCode=e),t._send("pair",t.pairCode)},r.prototype.connect=function(){var e=this;return e._connections.socket.attempt++,e.socketConnected?void console.warn("Socket already connected"):(e.timeout&&(e._socketConnectTimeout=setTimeout(function(){e.socket.close();var t=new Error("Connection timeout after "+e.timeout+" ms");e.emit("connect_timeout",t),e._socketError(t)},e.timeout)),e.socket=new WebSocket(e.url.replace(/^http/,"ws")),e.socket.onopen=function(){e.pair()},e.socket.onerror=function(t){e._socketError(new Error(t.data||"Unexpected WebSocket error"))},e.socket.onmessage=function(t){var n={};try{n=JSON.parse(t.data)}catch(t){e.emit(new Error("Expected JSON-formatted WebSocket message"))}"data"===n.type?e.emit("data",n.data):e.emit(n.type,n.data)},e.socket.onclose=function(){if(e.socketConnected=!1,e._debug("close"),e.reconnect){var t=e._calcReconnectTimeout(e._connections.socket.attempt);clearTimeout(e._socketReconnectDelayTimeout),e._socketReconnectDelayTimeout=setTimeout(function(){e.connect()},t)}},e.emit("connect_attempt"),void(e._connections.socket.success>0&&e.emit("reconnect_attempt")))},r.prototype._socketError=function(e){var t=this;t._connections.socket.error++,t.emit("error",e),t.emit("connect_error",e),t._connections.socket.success>0&&t.emit("reconnect_error")},r.prototype._calcReconnectTimeout=function(e){var t=this;return Math.min(Math.pow(2,e)*t.reconnectDelay,3e4)},r.prototype._rtcInit=function(){var e=this;return e.rtcConnected?void console.warn("WebRTC peer already connected"):(e.peer=new a({initiator:e.initiator,stream:e.stream}),e.peer.on("connect",function(){clearTimeout(e._rtcReconnectTimeout),e._connections.rtc.success++,e._connections.rtc.attempt=0,e.rtcConnected=!0,e.emit("upgrade")}),e.peer.on("stream",function(t){e.emit("stream",t)}),e.peer.on("error",function(t){e._connections.rtc.error++,e.emit("upgrade_error",t),e.emit("error",t)}),e.peer.on("signal",function(t){e.rtcConnected||e._send("rtc.signal",t)}),e.peer.on("data",function(t){e.emit("data",t)}),e.peer.on("close",function(t){if(e.destroyPeer(),e.socketConnected&&e.reconnect&&e.initiator){var n=e._calcReconnectTimeout(e._connections.rtc.attempt);clearTimeout(e._rtcReconnectTimeout),e._rtcReconnectTimeout=setTimeout(function(){e._send("rtc.connect"),e._rtcInit()},n)}e.emit("downgrade")}),e._connections.rtc.attempt++,void e.emit("upgrade_attempt"))},r.prototype._rtcSignal=function(e){var t=this;t.rtcConnected||!t.peer||t.peer.destroyed||t.peer.signal(e)},r.prototype._send=function(e,t){var n=this;return n.socket?(t=JSON.stringify({type:e,data:t}),n._debug("_send",t),void n.socket.send(t)):void console.warn("Attempted to send message when socket was closed: %s",e)},r.prototype.send=function(e){var t=this;t.rtcConnected?t.peer.send(e):t._send("data",e)},r.prototype.close=function(){var e=this;e.destroyPeer(),e.socket&&e.socket.close()},r.prototype.destroy=function(){var e=this;e.reconnect=!1,e.close(),e.peer=null,e.socket=null,e.socketConnected=!1,e.rtcConnected=!1,clearTimeout(e._socketConnectTimeout),clearTimeout(e._socketReconnectDelayTimeout),clearTimeout(e._rtcReconnectTimeout)},r.prototype.destroyPeer=function(){var e=this;e.peer&&e.peer.destroy(),e.peer=null,e.rtcConnected=!1},r.prototype._debug=function(){var e=this;if(e.debug){var t=Array.prototype.slice.call(arguments);t[0]="["+e.pairCode+"] "+t[0],console.log.apply(console,t)}},t.exports=r},{events:7,inherits:10,"simple-peer":17,"xtend/mutable":34}],1:[function(e,t,n){var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";!function(e){"use strict";function t(e){var t=e.charCodeAt(0);return t===s||t===h?62:t===a||t===l?63:t0)throw new Error("Invalid string. Length must be a multiple of 4");var f=e.length;c="="===e.charAt(f-2)?2:"="===e.charAt(f-1)?1:0,u=new o(3*e.length/4-c),s=c>0?e.length-4:e.length;var h=0;for(r=0,i=0;r>16),n((65280&a)>>8),n(255&a);return 2===c?(a=t(e.charAt(r))<<2|t(e.charAt(r+1))>>4,n(255&a)):1===c&&(a=t(e.charAt(r))<<10|t(e.charAt(r+1))<<4|t(e.charAt(r+2))>>2,n(a>>8&255),n(255&a)),u}function i(e){function t(e){return r.charAt(e)}function n(e){return t(e>>18&63)+t(e>>12&63)+t(e>>6&63)+t(63&e)}var i,o,s,a=e.length%3,c="";for(i=0,s=e.length-a;i>2),c+=t(o<<4&63),c+="==";break;case 2:o=(e[e.length-2]<<8)+e[e.length-1],c+=t(o>>10),c+=t(o>>4&63),c+=t(o<<2&63),c+="="}return c}var o="undefined"!=typeof Uint8Array?Uint8Array:Array,s="+".charCodeAt(0),a="/".charCodeAt(0),c="0".charCodeAt(0),u="a".charCodeAt(0),f="A".charCodeAt(0),h="-".charCodeAt(0),l="_".charCodeAt(0);e.toByteArray=n,e.fromByteArray=i}("undefined"==typeof n?this.base64js={}:n)},{}],2:[function(e,t,n){},{}],3:[function(e,t,n){(function(t){"use strict";function r(){function e(){}try{var t=new Uint8Array(1);return t.foo=function(){return 42},t.constructor=e,42===t.foo()&&t.constructor===e&&"function"==typeof t.subarray&&0===t.subarray(1,1).byteLength}catch(e){return!1}}function i(){return o.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function o(e){return this instanceof o?(o.TYPED_ARRAY_SUPPORT||(this.length=0,this.parent=void 0),"number"==typeof e?s(this,e):"string"==typeof e?a(this,e,arguments.length>1?arguments[1]:"utf8"):c(this,e)):arguments.length>1?new o(e,arguments[1]):new o(e)}function s(e,t){if(e=g(e,t<0?0:0|y(t)),!o.TYPED_ARRAY_SUPPORT)for(var n=0;n>>1;return n&&(e.parent=X),e}function y(e){if(e>=i())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i().toString(16)+" bytes");return 0|e}function b(e,t){if(!(this instanceof b))return new b(e,t);var n=new o(e,t);return delete n.parent,n}function w(e,t){"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"binary":case"raw":case"raws":return n;case"utf8":case"utf-8":return z(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return H(e).length;default:if(r)return z(e).length;t=(""+t).toLowerCase(),r=!0}}function m(e,t,n){var r=!1;if(t|=0,n=void 0===n||n===1/0?this.length:0|n,e||(e="utf8"),t<0&&(t=0),n>this.length&&(n=this.length),n<=t)return"";for(;;)switch(e){case"hex":return x(this,t,n);case"utf8":case"utf-8":return C(this,t,n);case"ascii":return T(this,t,n);case"binary":return I(this,t,n);case"base64":return k(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return B(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function v(e,t,n,r){n=Number(n)||0;var i=e.length-n;r?(r=Number(r),r>i&&(r=i)):r=i;var o=t.length;if(o%2!==0)throw new Error("Invalid hex string");r>o/2&&(r=o/2);for(var s=0;s239?4:o>223?3:o>191?2:1;if(i+a<=n){var c,u,f,h;switch(a){case 1:o<128&&(s=o);break;case 2:c=e[i+1],128===(192&c)&&(h=(31&o)<<6|63&c,h>127&&(s=h));break;case 3:c=e[i+1],u=e[i+2],128===(192&c)&&128===(192&u)&&(h=(15&o)<<12|(63&c)<<6|63&u,h>2047&&(h<55296||h>57343)&&(s=h));break;case 4:c=e[i+1],u=e[i+2],f=e[i+3],128===(192&c)&&128===(192&u)&&128===(192&f)&&(h=(15&o)<<18|(63&c)<<12|(63&u)<<6|63&f,h>65535&&h<1114112&&(s=h))}}null===s?(s=65533,a=1):s>65535&&(s-=65536,r.push(s>>>10&1023|55296),s=56320|1023&s),r.push(s),i+=a}return L(r)}function L(e){var t=e.length;if(t<=K)return String.fromCharCode.apply(String,e);for(var n="",r=0;rr)&&(n=r);for(var i="",o=t;on)throw new RangeError("Trying to access beyond buffer length")}function U(e,t,n,r,i,s){if(!o.isBuffer(e))throw new TypeError("buffer must be a Buffer instance");if(t>i||te.length)throw new RangeError("index out of range")}function j(e,t,n,r){t<0&&(t=65535+t+1);for(var i=0,o=Math.min(e.length-n,2);i>>8*(r?i:1-i)}function P(e,t,n,r){t<0&&(t=4294967295+t+1);for(var i=0,o=Math.min(e.length-n,4);i>>8*(r?i:3-i)&255}function D(e,t,n,r,i,o){if(t>i||te.length)throw new RangeError("index out of range");if(n<0)throw new RangeError("index out of range")}function O(e,t,n,r,i){return i||D(e,t,n,4,3.4028234663852886e38,-3.4028234663852886e38),G.write(e,t,n,r,23,4),n+4}function N(e,t,n,r,i){return i||D(e,t,n,8,1.7976931348623157e308,-1.7976931348623157e308),G.write(e,t,n,r,52,8),n+8}function Y(e){if(e=F(e).replace(ee,""),e.length<2)return"";for(;e.length%4!==0;)e+="=";return e}function F(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function W(e){return e<16?"0"+e.toString(16):e.toString(16)}function z(e,t){t=t||1/0;for(var n,r=e.length,i=null,o=[],s=0;s55295&&n<57344){if(!i){if(n>56319){(t-=3)>-1&&o.push(239,191,189);continue}if(s+1===r){(t-=3)>-1&&o.push(239,191,189);continue}i=n;continue}if(n<56320){(t-=3)>-1&&o.push(239,191,189),i=n;continue}n=(i-55296<<10|n-56320)+65536}else i&&(t-=3)>-1&&o.push(239,191,189);if(i=null,n<128){if((t-=1)<0)break;o.push(n)}else if(n<2048){if((t-=2)<0)break;o.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;o.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return o}function J(e){for(var t=[],n=0;n>8,i=n%256,o.push(i),o.push(r);return o}function H(e){return Z.toByteArray(Y(e))}function $(e,t,n,r){for(var i=0;i=t.length||i>=e.length);i++)t[i+n]=e[i];return i}var Z=e("base64-js"),G=e("ieee754"),V=e("isarray");n.Buffer=o,n.SlowBuffer=b,n.INSPECT_MAX_BYTES=50,o.poolSize=8192;var X={};o.TYPED_ARRAY_SUPPORT=void 0!==t.TYPED_ARRAY_SUPPORT?t.TYPED_ARRAY_SUPPORT:r(),o.TYPED_ARRAY_SUPPORT?(o.prototype.__proto__=Uint8Array.prototype,o.__proto__=Uint8Array):(o.prototype.length=void 0,o.prototype.parent=void 0),o.isBuffer=function(e){return!(null==e||!e._isBuffer)},o.compare=function(e,t){if(!o.isBuffer(e)||!o.isBuffer(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var n=e.length,r=t.length,i=0,s=Math.min(n,r);i0&&(e=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(e+=" ... ")),""},o.prototype.compare=function(e){if(!o.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e?0:o.compare(this,e)},o.prototype.indexOf=function(e,t){function n(e,t,n){for(var r=-1,i=0;n+i2147483647?t=2147483647:t<-2147483648&&(t=-2147483648),t>>=0,0===this.length)return-1;if(t>=this.length)return-1;if(t<0&&(t=Math.max(this.length+t,0)),"string"==typeof e)return 0===e.length?-1:String.prototype.indexOf.call(this,e,t);if(o.isBuffer(e))return n(this,e,t);if("number"==typeof e)return o.TYPED_ARRAY_SUPPORT&&"function"===Uint8Array.prototype.indexOf?Uint8Array.prototype.indexOf.call(this,e,t):n(this,[e],t);throw new TypeError("val must be string, number or Buffer")},o.prototype.get=function(e){return console.log(".get() is deprecated. Access using array indexes instead."),this.readUInt8(e)},o.prototype.set=function(e,t){return console.log(".set() is deprecated. Access using array indexes instead."),this.writeUInt8(e,t)},o.prototype.write=function(e,t,n,r){if(void 0===t)r="utf8",n=this.length,t=0;else if(void 0===n&&"string"==typeof t)r=t,n=this.length,t=0;else if(isFinite(t))t|=0,isFinite(n)?(n|=0,void 0===r&&(r="utf8")):(r=n,n=void 0);else{var i=r;r=t,t=0|n,n=i}var o=this.length-t;if((void 0===n||n>o)&&(n=o),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("attempt to write outside buffer bounds");r||(r="utf8");for(var s=!1;;)switch(r){case"hex":return v(this,e,t,n);case"utf8":case"utf-8":return _(this,e,t,n);case"ascii":return E(this,e,t,n);case"binary":return A(this,e,t,n);case"base64":return S(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return R(this,e,t,n);default:if(s)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),s=!0}},o.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var K=4096;o.prototype.slice=function(e,t){var n=this.length;e=~~e,t=void 0===t?n:~~t,e<0?(e+=n,e<0&&(e=0)):e>n&&(e=n),t<0?(t+=n,t<0&&(t=0)):t>n&&(t=n),t0&&(i*=256);)r+=this[e+--t]*i;return r},o.prototype.readUInt8=function(e,t){return t||M(e,1,this.length),this[e]},o.prototype.readUInt16LE=function(e,t){return t||M(e,2,this.length),this[e]|this[e+1]<<8},o.prototype.readUInt16BE=function(e,t){return t||M(e,2,this.length),this[e]<<8|this[e+1]},o.prototype.readUInt32LE=function(e,t){return t||M(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},o.prototype.readUInt32BE=function(e,t){return t||M(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},o.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||M(e,t,this.length);for(var r=this[e],i=1,o=0;++o=i&&(r-=Math.pow(2,8*t)),r},o.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||M(e,t,this.length);for(var r=t,i=1,o=this[e+--r];r>0&&(i*=256);)o+=this[e+--r]*i;return i*=128,o>=i&&(o-=Math.pow(2,8*t)),o},o.prototype.readInt8=function(e,t){return t||M(e,1,this.length),128&this[e]?(255-this[e]+1)*-1:this[e]},o.prototype.readInt16LE=function(e,t){t||M(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt16BE=function(e,t){t||M(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt32LE=function(e,t){return t||M(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},o.prototype.readInt32BE=function(e,t){return t||M(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},o.prototype.readFloatLE=function(e,t){return t||M(e,4,this.length),G.read(this,e,!0,23,4)},o.prototype.readFloatBE=function(e,t){return t||M(e,4,this.length),G.read(this,e,!1,23,4)},o.prototype.readDoubleLE=function(e,t){return t||M(e,8,this.length),G.read(this,e,!0,52,8)},o.prototype.readDoubleBE=function(e,t){return t||M(e,8,this.length),G.read(this,e,!1,52,8)},o.prototype.writeUIntLE=function(e,t,n,r){e=+e,t|=0,n|=0,r||U(this,e,t,n,Math.pow(2,8*n),0);var i=1,o=0;for(this[t]=255&e;++o=0&&(o*=256);)this[t+i]=e/o&255;return t+n},o.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||U(this,e,t,1,255,0),o.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},o.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||U(this,e,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):j(this,e,t,!0),t+2},o.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||U(this,e,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):j(this,e,t,!1),t+2},o.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||U(this,e,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):P(this,e,t,!0),t+4},o.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||U(this,e,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):P(this,e,t,!1),t+4},o.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);U(this,e,t,n,i-1,-i)}var o=0,s=1,a=e<0?1:0;for(this[t]=255&e;++o>0)-a&255;return t+n},o.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);U(this,e,t,n,i-1,-i)}var o=n-1,s=1,a=e<0?1:0;for(this[t+o]=255&e;--o>=0&&(s*=256);)this[t+o]=(e/s>>0)-a&255;return t+n},o.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||U(this,e,t,1,127,-128),o.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},o.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||U(this,e,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):j(this,e,t,!0),t+2},o.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||U(this,e,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):j(this,e,t,!1),t+2},o.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||U(this,e,t,4,2147483647,-2147483648),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):P(this,e,t,!0),t+4},o.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||U(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):P(this,e,t,!1),t+4},o.prototype.writeFloatLE=function(e,t,n){return O(this,e,t,!0,n)},o.prototype.writeFloatBE=function(e,t,n){return O(this,e,t,!1,n)},o.prototype.writeDoubleLE=function(e,t,n){return N(this,e,t,!0,n)},o.prototype.writeDoubleBE=function(e,t,n){return N(this,e,t,!1,n)},o.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;i--)e[i+t]=this[i+n];else if(s<1e3||!o.TYPED_ARRAY_SUPPORT)for(i=0;i=this.length)throw new RangeError("start out of bounds");if(n<0||n>this.length)throw new RangeError("end out of bounds");var r;if("number"==typeof e)for(r=t;r=31||"undefined"!=typeof navigator&&navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))}function o(e){var t=this.useColors;if(e[0]=(t?"%c":"")+this.namespace+(t?" %c":" ")+e[0]+(t?"%c ":" ")+"+"+n.humanize(this.diff),t){var r="color: "+this.color;e.splice(1,0,r,"color: inherit");var i=0,o=0;e[0].replace(/%[a-zA-Z%]/g,function(e){"%%"!==e&&(i++,"%c"===e&&(o=i))}),e.splice(o,0,r)}}function s(){return"object"==typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function a(e){try{null==e?n.storage.removeItem("debug"):n.storage.debug=e}catch(e){}}function c(){try{return n.storage.debug}catch(e){}if("undefined"!=typeof r&&"env"in r)return r.env.DEBUG}function u(){try{return window.localStorage}catch(e){}}n=t.exports=e("./debug"),n.log=s,n.formatArgs=o,n.save=a,n.load=c,n.useColors=i,n.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:u(),n.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"],n.formatters.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}},n.enable(c())}).call(this,e("_process"))},{"./debug":6,_process:16}],6:[function(e,t,n){function r(e){var t,r=0;for(t in e)r=(r<<5)-r+e.charCodeAt(t),r|=0;return n.colors[Math.abs(r)%n.colors.length]}function i(e){function t(){if(t.enabled){var e=t,r=+new Date,i=r-(u||r);e.diff=i,e.prev=u,e.curr=r,u=r;for(var o=new Array(arguments.length),s=0;s0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())}return this},r.prototype.on=r.prototype.addListener, 2 | r.prototype.once=function(e,t){function n(){this.removeListener(e,n),r||(r=!0,t.apply(this,arguments))}if(!i(t))throw TypeError("listener must be a function");var r=!1;return n.listener=t,this.on(e,n),this},r.prototype.removeListener=function(e,t){var n,r,o,a;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],o=n.length,r=-1,n===t||i(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(s(n)){for(a=o;a-- >0;)if(n[a]===t||n[a].listener&&n[a].listener===t){r=a;break}if(r<0)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],i(n))this.removeListener(e,n);else for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?i(this._events[e])?[this._events[e]]:this._events[e].slice():[]},r.listenerCount=function(e,t){var n;return n=e._events&&e._events[t]?i(e._events[t])?1:e._events[t].length:0}},{}],8:[function(e,t,n){var r=t.exports=function(e,t){if(t||(t=16),void 0===e&&(e=128),e<=0)return"0";for(var n=Math.log(Math.pow(2,e))/Math.log(t),i=2;n===1/0;i*=2)n=Math.log(Math.pow(2,e/i))/Math.log(t)*i;for(var o=n-Math.floor(n),s="",i=0;i=Math.pow(2,e)?r(e,t):s};r.rack=function(e,t,n){var i=function(i){var s=0;do{if(s++>10){if(!n)throw new Error("too many ID collisions, use more bits");e+=n}var a=r(e,t)}while(Object.hasOwnProperty.call(o,a));return o[a]=i,a},o=i.hats={};return i.get=function(e){return i.hats[e]},i.set=function(e,t){return i.hats[e]=t,i},i.bits=e||128,i.base=t||16,i}},{}],9:[function(e,t,n){n.read=function(e,t,n,r,i){var o,s,a=8*i-r-1,c=(1<>1,f=-7,h=n?i-1:0,l=n?-1:1,d=e[t+h];for(h+=l,o=d&(1<<-f)-1,d>>=-f,f+=a;f>0;o=256*o+e[t+h],h+=l,f-=8);for(s=o&(1<<-f)-1,o>>=-f,f+=r;f>0;s=256*s+e[t+h],h+=l,f-=8);if(0===o)o=1-u;else{if(o===c)return s?NaN:(d?-1:1)*(1/0);s+=Math.pow(2,r),o-=u}return(d?-1:1)*s*Math.pow(2,o-r)},n.write=function(e,t,n,r,i,o){var s,a,c,u=8*o-i-1,f=(1<>1,l=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,d=r?0:o-1,p=r?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=f):(s=Math.floor(Math.log(t)/Math.LN2),t*(c=Math.pow(2,-s))<1&&(s--,c*=2),t+=s+h>=1?l/c:l*Math.pow(2,1-h),t*c>=2&&(s++,c/=2),s+h>=f?(a=0,s=f):s+h>=1?(a=(t*c-1)*Math.pow(2,i),s+=h):(a=t*Math.pow(2,h-1)*Math.pow(2,i),s=0));i>=8;e[n+d]=255&a,d+=p,a/=256,i-=8);for(s=s<0;e[n+d]=255&s,d+=p,s/=256,u-=8);e[n+d-p]|=128*g}},{}],10:[function(e,t,n){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},{}],11:[function(e,t,n){function r(e){return!!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function i(e){return"function"==typeof e.readFloatLE&&"function"==typeof e.slice&&r(e.slice(0,0))}t.exports=function(e){return null!=e&&(r(e)||i(e)||!!e._isBuffer)}},{}],12:[function(e,t,n){function r(e){return i(e)||o(e)}function i(e){return e instanceof Int8Array||e instanceof Int16Array||e instanceof Int32Array||e instanceof Uint8Array||e instanceof Uint16Array||e instanceof Uint32Array||e instanceof Float32Array||e instanceof Float64Array}function o(e){return a[s.call(e)]}t.exports=r,r.strict=i,r.loose=o;var s=Object.prototype.toString,a={"[object Int8Array]":!0,"[object Int16Array]":!0,"[object Int32Array]":!0,"[object Uint8Array]":!0,"[object Uint16Array]":!0,"[object Uint32Array]":!0,"[object Float32Array]":!0,"[object Float64Array]":!0}},{}],13:[function(e,t,n){var r={}.toString;t.exports=Array.isArray||function(e){return"[object Array]"==r.call(e)}},{}],14:[function(e,t,n){function r(e){if(e=String(e),!(e.length>1e4)){var t=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(e);if(t){var n=parseFloat(t[1]),r=(t[2]||"ms").toLowerCase();switch(r){case"years":case"year":case"yrs":case"yr":case"y":return n*h;case"days":case"day":case"d":return n*f;case"hours":case"hour":case"hrs":case"hr":case"h":return n*u;case"minutes":case"minute":case"mins":case"min":case"m":return n*c;case"seconds":case"second":case"secs":case"sec":case"s":return n*a;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return n;default:return}}}}function i(e){return e>=f?Math.round(e/f)+"d":e>=u?Math.round(e/u)+"h":e>=c?Math.round(e/c)+"m":e>=a?Math.round(e/a)+"s":e+"ms"}function o(e){return s(e,f,"day")||s(e,u,"hour")||s(e,c,"minute")||s(e,a,"second")||e+" ms"}function s(e,t,n){if(!(e0)return r(e);if("number"===n&&isNaN(e)===!1)return t.long?o(e):i(e);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(e))}},{}],15:[function(e,t,n){function r(e){var t=function(){return t.called?t.value:(t.called=!0,t.value=e.apply(this,arguments))};return t.called=!1,t}function i(e){var t=function(){if(t.called)throw new Error(t.onceError);return t.called=!0,t.value=e.apply(this,arguments)},n=e.name||"Function wrapped with `once`";return t.onceError=n+" shouldn't be called more than once",t.called=!1,t}var o=e("wrappy");t.exports=o(r),t.exports.strict=o(i),r.proto=r(function(){Object.defineProperty(Function.prototype,"once",{value:function(){return r(this)},configurable:!0}),Object.defineProperty(Function.prototype,"onceStrict",{value:function(){return i(this)},configurable:!0})})},{wrappy:33}],16:[function(e,t,n){function r(){if(!a){a=!0;for(var e,t=s.length;t;){e=s,s=[];for(var n=-1;++n1&&(e.sdp=t[0]+"b=AS:1638400"+t[1])}function o(){}t.exports=r;var s,a=e("debug")("simple-peer"),c=e("xtend/mutable"),u=e("hat"),f=e("inherits"),h=e("is-typedarray"),l=e("once"),d=e("stream"),p=e("typedarray-to-buffer");try{s=e("wrtc")}catch(e){s={}}var g="undefined"!=typeof window?window.mozRTCPeerConnection||window.RTCPeerConnection||window.webkitRTCPeerConnection:s.RTCPeerConnection,y="undefined"!=typeof window?window.mozRTCSessionDescription||window.RTCSessionDescription||window.webkitRTCSessionDescription:s.RTCSessionDescription,b="undefined"!=typeof window?window.mozRTCIceCandidate||window.RTCIceCandidate||window.webkitRTCIceCandidate:s.RTCIceCandidate;f(r,d.Duplex),r.config={iceServers:[{url:"stun:23.21.150.121",urls:"stun:23.21.150.121"}]},r.constraints={},r.prototype.send=function(e,t){var n=this;t||(t=o),n._write(e,void 0,t)},r.prototype.signal=function(e){var t=this;if(t.destroyed)throw new Error("cannot signal after peer is destroyed");if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e={}}if(t._debug("signal"),e.sdp&&t._pc.setRemoteDescription(new y(e),function(){"offer"===t._pc.remoteDescription.type&&t._createAnswer()},t._onError.bind(t)),e.candidate)try{t._pc.addIceCandidate(new b(e.candidate),o,t._onError.bind(t))}catch(e){t._destroy(new Error("error adding candidate: "+e.message))}e.sdp||e.candidate||t._destroy(new Error("signal() called with invalid signal data"))},r.prototype.destroy=function(e){var t=this;t._destroy(null,e)},r.prototype._destroy=function(e,t){var n=this;if(!n.destroyed){if(t&&n.once("close",t),n._debug("destroy (error: %s)",e&&e.message),n.destroyed=!0,n.connected=!1,n._pcReady=!1,n._channelReady=!1,n._pc){try{n._pc.close()}catch(e){}n._pc.oniceconnectionstatechange=null,n._pc.onsignalingstatechange=null,n._pc.onicecandidate=null}if(n._channel){try{n._channel.close()}catch(e){}n._channel.onmessage=null,n._channel.onopen=null,n._channel.onclose=null}n._pc=null,n._channel=null,this.readable=this.writable=!1,n._readableState.ended||n.push(null),n._writableState.finished||n.end(),e&&n.emit("error",e),n.emit("close")}},r.prototype._setupData=function(e){var t=this;t._channel=e.channel,t.channelName=t._channel.label,t._channel.binaryType="arraybuffer",t._channel.onmessage=t._onChannelMessage.bind(t),t._channel.onopen=t._onChannelOpen.bind(t),t._channel.onclose=t._onChannelClose.bind(t)},r.prototype._setupVideo=function(e){var t=this;t._pc.addStream(e)},r.prototype._read=function(){},r.prototype._write=function(e,t,r){var i=this;if(i.destroyed)return r(new Error("cannot write after peer is destroyed"));var o=e.length||e.byteLength||e.size;return i.connected?(i._debug("_write: length %d",o),h.strict(e)||e instanceof ArrayBuffer||"string"==typeof e||"undefined"!=typeof Blob&&e instanceof Blob?i._channel.send(e):n.isBuffer(e)?i._channel.send(new Uint8Array(e)):i._channel.send(JSON.stringify(e)),void r(null)):(i._debug("_write before ready: length %d",o),i._buffer.push(e),void r(null))},r.prototype._createOffer=function(){var e=this;e.destroyed||e._pc.createOffer(function(t){if(!e.destroyed){i(t),e._pc.setLocalDescription(t,o,e._onError.bind(e));var n=function(){e.emit("signal",e._pc.localDescription||t)};e.trickle||e._iceComplete?n():e.once("_iceComplete",n)}},e._onError.bind(e),e.offerConstraints)},r.prototype._createAnswer=function(){var e=this;e.destroyed||e._pc.createAnswer(function(t){if(!e.destroyed){i(t),e._pc.setLocalDescription(t,o,e._onError.bind(e));var n=function(){e.emit("signal",e._pc.localDescription||t)};e.trickle||e._iceComplete?n():e.once("_iceComplete",n)}},e._onError.bind(e),e.answerConstraints)},r.prototype._onIceConnectionStateChange=function(){var e=this;if(!e.destroyed){var t=e._pc.iceGatheringState,n=e._pc.iceConnectionState;e.emit("iceConnectionStateChange",t,n),e._debug("iceConnectionStateChange %s %s",t,n),"connected"!==n&&"completed"!==n||(e._pcReady=!0,e._maybeReady()),"disconnected"!==n&&"closed"!==n||e._destroy()}},r.prototype._maybeReady=function(){var e=this;e._debug("maybeReady pc %s channel %s",e._pcReady,e._channelReady),!e.connected&&e._pcReady&&e._channelReady&&(e.connected=!0,e._buffer.forEach(function(t){e.send(t)}),e._buffer=[],e._debug("connect"),e.emit("connect"))},r.prototype._onSignalingStateChange=function(){var e=this;e.destroyed||(e.emit("signalingStateChange",e._pc.signalingState),e._debug("signalingStateChange %s",e._pc.signalingState))},r.prototype._onIceCandidate=function(e){var t=this;t.destroyed||(e.candidate&&t.trickle?t.emit("signal",{candidate:e.candidate}):e.candidate||(t._iceComplete=!0,t.emit("_iceComplete")))},r.prototype._onChannelMessage=function(e){var t=this;if(!t.destroyed){var n=e.data;if(t._debug("on channel message: length %d",n.byteLength||n.length),n instanceof ArrayBuffer)n=p(new Uint8Array(n)),t.push(n);else{try{n=JSON.parse(n)}catch(e){}t.emit("data",n)}}},r.prototype._onChannelOpen=function(){var e=this;e.connected||e.destroyed||(e._debug("on channel open"),e._channelReady=!0,e._maybeReady())},r.prototype._onChannelClose=function(){var e=this;e.destroyed||(e._debug("on channel close"),e._destroy())},r.prototype._onAddStream=function(e){var t=this;t.destroyed||(t._debug("on add stream"),t.emit("stream",e.stream))},r.prototype._onError=function(e){var t=this;t.destroyed||(t._debug("error %s",e.message||e),t._destroy(e))},r.prototype._debug=function(){var e=this,t=[].slice.call(arguments),n=e.channelName&&e.channelName.substring(0,7);t[0]="["+n+"] "+t[0],a.apply(null,t)}}).call(this,{isBuffer:e("../is-buffer/index.js")})},{"../is-buffer/index.js":11,debug:5,hat:8,inherits:10,"is-typedarray":12,once:15,stream:18,"typedarray-to-buffer":31,wrtc:2,"xtend/mutable":34}],18:[function(e,t,n){function r(){i.call(this)}t.exports=r;var i=e("events").EventEmitter,o=e("inherits");o(r,i),r.Readable=e("readable-stream/readable.js"),r.Writable=e("readable-stream/writable.js"),r.Duplex=e("readable-stream/duplex.js"),r.Transform=e("readable-stream/transform.js"),r.PassThrough=e("readable-stream/passthrough.js"),r.Stream=r,r.prototype.pipe=function(e,t){function n(t){e.writable&&!1===e.write(t)&&u.pause&&u.pause()}function r(){u.readable&&u.resume&&u.resume()}function o(){f||(f=!0,e.end())}function s(){f||(f=!0,"function"==typeof e.destroy&&e.destroy())}function a(e){if(c(),0===i.listenerCount(this,"error"))throw e}function c(){u.removeListener("data",n),e.removeListener("drain",r),u.removeListener("end",o),u.removeListener("close",s),u.removeListener("error",a),e.removeListener("error",a),u.removeListener("end",c),u.removeListener("close",c),e.removeListener("close",c)}var u=this;u.on("data",n),e.on("drain",r),e._isStdio||t&&t.end===!1||(u.on("end",o),u.on("close",s));var f=!1;return u.on("error",a),e.on("error",a),u.on("end",c),u.on("close",c),e.on("close",c),e.emit("pipe",u),e}},{events:7,inherits:10,"readable-stream/duplex.js":20,"readable-stream/passthrough.js":26,"readable-stream/readable.js":27,"readable-stream/transform.js":28,"readable-stream/writable.js":29}],19:[function(e,t,n){t.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},{}],20:[function(e,t,n){t.exports=e("./lib/_stream_duplex.js")},{"./lib/_stream_duplex.js":21}],21:[function(e,t,n){(function(n){function r(e){return this instanceof r?(c.call(this,e),u.call(this,e),e&&e.readable===!1&&(this.readable=!1),e&&e.writable===!1&&(this.writable=!1),this.allowHalfOpen=!0,e&&e.allowHalfOpen===!1&&(this.allowHalfOpen=!1),void this.once("end",i)):new r(e)}function i(){this.allowHalfOpen||this._writableState.ended||n.nextTick(this.end.bind(this))}function o(e,t){for(var n=0,r=e.length;n0)if(t.ended&&!i){var a=new Error("stream.push() after EOF");e.emit("error",a)}else if(t.endEmitted&&i){var a=new Error("stream.unshift() after end event");e.emit("error",a)}else!t.decoder||i||r||(n=t.decoder.write(n)),i||(t.reading=!1),t.flowing&&0===t.length&&!t.sync?(e.emit("data",n),e.read(0)):(t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):t.buffer.push(n),t.needReadable&&h(e)),d(e,t);else i||(t.reading=!1);return s(t)}function s(e){return!e.ended&&(e.needReadable||e.length=I)e=I;else{e--;for(var t=1;t<32;t<<=1)e|=e>>t;e++}return e}function c(e,t){return 0===t.length&&t.ended?0:t.objectMode?0===e?0:1:isNaN(e)||C.isNull(e)?t.flowing&&t.buffer.length?t.buffer[0].length:t.length:e<=0?0:(e>t.highWaterMark&&(t.highWaterMark=a(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function u(e,t){var n=null;return C.isBuffer(t)||C.isString(t)||C.isNullOrUndefined(t)||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}function f(e,t){if(t.decoder&&!t.ended){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,h(e)}function h(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(T("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?n.nextTick(function(){l(e)}):l(e))}function l(e){T("emit readable"),e.emit("readable"),w(e)}function d(e,t){t.readingMore||(t.readingMore=!0,n.nextTick(function(){p(e,t)}))}function p(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=i)n=o?r.join(""):S.concat(r,i),r.length=0;else if(e0)throw new Error("endReadable called on non-empty stream");t.endEmitted||(t.ended=!0,n.nextTick(function(){t.endEmitted||0!==t.length||(t.endEmitted=!0,e.readable=!1,e.emit("end"))}))}function _(e,t){for(var n=0,r=e.length;n0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return T("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?v(this):h(this),null;if(e=c(e,t),0===e&&t.ended)return 0===t.length&&v(this),null;var r=t.needReadable;T("need readable",r),(0===t.length||t.length-e0?m(e,t):null,C.isNull(i)&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),n!==e&&t.ended&&0===t.length&&v(this),C.isNull(i)||this.emit("data",i),i},i.prototype._read=function(e){this.emit("error",new Error("not implemented"))},i.prototype.pipe=function(e,t){function r(e){T("onunpipe"),e===h&&o()}function i(){T("onend"),e.end()}function o(){T("cleanup"),e.removeListener("close",c),e.removeListener("finish",u),e.removeListener("drain",y),e.removeListener("error",a),e.removeListener("unpipe",r),h.removeListener("end",i),h.removeListener("end",o),h.removeListener("data",s),!l.awaitDrain||e._writableState&&!e._writableState.needDrain||y()}function s(t){T("ondata");var n=e.write(t);!1===n&&(T("false write response, pause",h._readableState.awaitDrain),h._readableState.awaitDrain++,h.pause())}function a(t){T("onerror",t),f(),e.removeListener("error",a),0===R.listenerCount(e,"error")&&e.emit("error",t)}function c(){e.removeListener("finish",u),f()}function u(){T("onfinish"),e.removeListener("close",c),f()}function f(){T("unpipe"),h.unpipe(e)}var h=this,l=this._readableState;switch(l.pipesCount){case 0:l.pipes=e;break;case 1:l.pipes=[l.pipes,e];break;default:l.pipes.push(e)}l.pipesCount+=1,T("pipe count=%d opts=%j",l.pipesCount,t);var d=(!t||t.end!==!1)&&e!==n.stdout&&e!==n.stderr,p=d?i:o;l.endEmitted?n.nextTick(p):h.once("end",p),e.on("unpipe",r);var y=g(h);return e.on("drain",y),h.on("data",s),e._events&&e._events.error?A(e._events.error)?e._events.error.unshift(a):e._events.error=[a,e._events.error]:e.on("error",a),e.once("close",c),e.once("finish",u),e.emit("pipe",h),l.flowing||(T("pipe resume"),h.resume()),e},i.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this),this);if(!e){var n=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i1){for(var n=[],r=0;r=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,n),this.charReceived+=n,this.charReceived=55296&&r<=56319)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var i=e.length;this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,i),i-=this.charReceived),t+=e.toString(this.encoding,0,i);var i=t.length-1,r=t.charCodeAt(i);if(r>=55296&&r<=56319){var o=this.surrogateSize;return this.charLength+=o,this.charReceived+=o,this.charBuffer.copy(this.charBuffer,o,0,o),e.copy(this.charBuffer,0,0,o),t.substring(0,i)}return t},u.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var n=e[e.length-t];if(1==t&&n>>5==6){this.charLength=2;break}if(t<=2&&n>>4==14){this.charLength=3;break}if(t<=3&&n>>3==30){this.charLength=4;break}}this.charReceived=t},u.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var n=this.charReceived,r=this.charBuffer,i=this.encoding;t+=r.slice(0,n).toString(i)}return t}},{buffer:3}],31:[function(e,t,n){(function(n){var r=e("is-typedarray").strict;t.exports=function(e){if(r(e)){var t=new n(e.buffer);return e.byteLength!==e.buffer.byteLength&&(t=t.slice(e.byteOffset,e.byteOffset+e.byteLength)),t}return new n(e)}}).call(this,e("buffer").Buffer)},{buffer:3,"is-typedarray":32}],32:[function(e,t,n){function r(e){return i(e)||o(e)}function i(e){return e instanceof Int8Array||e instanceof Int16Array||e instanceof Int32Array||e instanceof Uint8Array||e instanceof Uint8ClampedArray||e instanceof Uint16Array||e instanceof Uint32Array||e instanceof Float32Array||e instanceof Float64Array}function o(e){return a[s.call(e)]}t.exports=r,r.strict=i,r.loose=o;var s=Object.prototype.toString,a={"[object Int8Array]":!0,"[object Int16Array]":!0,"[object Int32Array]":!0,"[object Uint8Array]":!0,"[object Uint8ClampedArray]":!0,"[object Uint16Array]":!0,"[object Uint32Array]":!0,"[object Float32Array]":!0,"[object Float64Array]":!0}},{}],33:[function(e,t,n){function r(e,t){function n(){for(var t=new Array(arguments.length),n=0;n