(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.socketCluster = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o maxTimeout) { throw new InvalidArgumentsError('The ' + propertyName + ' value provided exceeded the maximum amount allowed'); } }; verifyDuration('connectTimeout'); verifyDuration('ackTimeout'); verifyDuration('pingTimeout'); this._localEvents = { 'connect': 1, 'connectAbort': 1, 'disconnect': 1, 'message': 1, 'error': 1, 'raw': 1, 'fail': 1, 'kickOut': 1, 'subscribe': 1, 'unsubscribe': 1, 'subscribeStateChange': 1, 'authStateChange': 1, 'authenticate': 1, 'deauthenticate': 1, 'removeAuthToken': 1, 'subscribeRequest': 1 }; this.connectAttempts = 0; this._emitBuffer = new LinkedList(); this._channels = {}; this.options = opts; this._cid = 1; this.options.callIdGenerator = function () { return self._callIdGenerator(); }; if (this.options.autoReconnect) { if (this.options.autoReconnectOptions == null) { this.options.autoReconnectOptions = {}; } // Add properties to the this.options.autoReconnectOptions object. // We assign the reference to a reconnectOptions variable to avoid repetition. var reconnectOptions = this.options.autoReconnectOptions; if (reconnectOptions.initialDelay == null) { reconnectOptions.initialDelay = 10000; } if (reconnectOptions.randomness == null) { reconnectOptions.randomness = 10000; } if (reconnectOptions.multiplier == null) { reconnectOptions.multiplier = 1.5; } if (reconnectOptions.maxDelay == null) { reconnectOptions.maxDelay = 60000; } } if (this.options.subscriptionRetryOptions == null) { this.options.subscriptionRetryOptions = {}; } if (this.options.authEngine) { this.auth = this.options.authEngine; } else { this.auth = new AuthEngine(); } if (this.options.codecEngine) { this.codec = this.options.codecEngine; } else { // Default codec engine this.codec = formatter; } this.options.path = this.options.path.replace(/\/$/, '') + '/'; this.options.query = opts.query || {}; if (typeof this.options.query == 'string') { this.options.query = querystring.parse(this.options.query); } if (this.options.autoConnect) { this.connect(); } this._channelEmitter = new SCEmitter(); if (isBrowser && this.disconnectOnUnload) { var unloadHandler = function () { self.disconnect(); }; if (global.attachEvent) { global.attachEvent('onunload', unloadHandler); } else if (global.addEventListener) { global.addEventListener('beforeunload', unloadHandler, false); } } }; SCSocket.prototype = Object.create(SCEmitter.prototype); SCSocket.CONNECTING = SCSocket.prototype.CONNECTING = SCTransport.prototype.CONNECTING; SCSocket.OPEN = SCSocket.prototype.OPEN = SCTransport.prototype.OPEN; SCSocket.CLOSED = SCSocket.prototype.CLOSED = SCTransport.prototype.CLOSED; SCSocket.AUTHENTICATED = SCSocket.prototype.AUTHENTICATED = 'authenticated'; SCSocket.UNAUTHENTICATED = SCSocket.prototype.UNAUTHENTICATED = 'unauthenticated'; SCSocket.PENDING = SCSocket.prototype.PENDING = 'pending'; SCSocket.ignoreStatuses = scErrors.socketProtocolIgnoreStatuses; SCSocket.errorStatuses = scErrors.socketProtocolErrorStatuses; SCSocket.prototype._privateEventHandlerMap = { '#publish': function (data) { var undecoratedChannelName = this._undecorateChannelName(data.channel); var isSubscribed = this.isSubscribed(undecoratedChannelName, true); if (isSubscribed) { this._channelEmitter.emit(undecoratedChannelName, data.data); } }, '#kickOut': function (data) { var undecoratedChannelName = this._undecorateChannelName(data.channel); var channel = this._channels[undecoratedChannelName]; if (channel) { SCEmitter.prototype.emit.call(this, 'kickOut', data.message, undecoratedChannelName); channel.emit('kickOut', data.message, undecoratedChannelName); this._triggerChannelUnsubscribe(channel); } }, '#setAuthToken': function (data, response) { var self = this; if (data) { var triggerAuthenticate = function (err) { if (err) { // This is a non-fatal error, we don't want to close the connection // because of this but we do want to notify the server and throw an error // on the client. response.error(err); self._onSCError(err); } else { self._changeToAuthenticatedState(data.token); response.end(); } }; this.auth.saveToken(this.options.authTokenName, data.token, {}, triggerAuthenticate); } else { response.error(new InvalidMessageError('No token data provided by #setAuthToken event')); } }, '#removeAuthToken': function (data, response) { var self = this; this.auth.removeToken(this.options.authTokenName, function (err, oldToken) { if (err) { // Non-fatal error - Do not close the connection response.error(err); self._onSCError(err); } else { SCEmitter.prototype.emit.call(self, 'removeAuthToken', oldToken); self._changeToUnauthenticatedState(); response.end(); } }); }, '#disconnect': function (data) { this.transport.close(data.code, data.data); } }; SCSocket.prototype._callIdGenerator = function () { return this._cid++; }; SCSocket.prototype.getState = function () { return this.state; }; SCSocket.prototype.getBytesReceived = function () { return this.transport.getBytesReceived(); }; SCSocket.prototype.deauthenticate = function (callback) { var self = this; this.auth.removeToken(this.options.authTokenName, function (err, oldToken) { if (err) { // Non-fatal error - Do not close the connection self._onSCError(err); } else { self.emit('#removeAuthToken'); SCEmitter.prototype.emit.call(self, 'removeAuthToken', oldToken); self._changeToUnauthenticatedState(); } callback && callback(err); }); }; SCSocket.prototype.connect = SCSocket.prototype.open = function () { var self = this; if (this.state == this.CLOSED) { this.pendingReconnect = false; this.pendingReconnectTimeout = null; clearTimeout(this._reconnectTimeoutRef); this.state = this.CONNECTING; SCEmitter.prototype.emit.call(this, 'connecting'); this._changeToPendingAuthState(); if (this.transport) { this.transport.off(); } this.transport = new SCTransport(this.auth, this.codec, this.options); this.transport.on('open', function (status) { self.state = self.OPEN; self._onSCOpen(status); }); this.transport.on('error', function (err) { self._onSCError(err); }); this.transport.on('close', function (code, data) { self.state = self.CLOSED; self._onSCClose(code, data); }); this.transport.on('openAbort', function (code, data) { self.state = self.CLOSED; self._onSCClose(code, data, true); }); this.transport.on('event', function (event, data, res) { self._onSCEvent(event, data, res); }); } }; SCSocket.prototype.reconnect = function () { this.disconnect(); this.connect(); }; SCSocket.prototype.disconnect = function (code, data) { code = code || 1000; if (typeof code != 'number') { throw new InvalidArgumentsError('If specified, the code argument must be a number'); } if (this.state == this.OPEN || this.state == this.CONNECTING) { this.transport.close(code, data); } else { this.pendingReconnect = false; this.pendingReconnectTimeout = null; clearTimeout(this._reconnectTimeoutRef); } }; SCSocket.prototype._changeToPendingAuthState = function () { if (this.authState != this.PENDING) { var oldState = this.authState; this.authState = this.PENDING; var stateChangeData = { oldState: oldState, newState: this.authState }; SCEmitter.prototype.emit.call(this, 'authStateChange', stateChangeData); } }; SCSocket.prototype._changeToUnauthenticatedState = function () { if (this.authState != this.UNAUTHENTICATED) { var oldState = this.authState; this.authState = this.UNAUTHENTICATED; this.signedAuthToken = null; this.authToken = null; var stateChangeData = { oldState: oldState, newState: this.authState }; SCEmitter.prototype.emit.call(this, 'authStateChange', stateChangeData); if (oldState == this.AUTHENTICATED) { SCEmitter.prototype.emit.call(this, 'deauthenticate'); } SCEmitter.prototype.emit.call(this, 'authTokenChange', this.signedAuthToken); } }; SCSocket.prototype._changeToAuthenticatedState = function (signedAuthToken) { this.signedAuthToken = signedAuthToken; this.authToken = this._extractAuthTokenData(signedAuthToken); if (this.authState != this.AUTHENTICATED) { var oldState = this.authState; this.authState = this.AUTHENTICATED; var stateChangeData = { oldState: oldState, newState: this.authState, signedAuthToken: signedAuthToken, authToken: this.authToken }; this.processPendingSubscriptions(); SCEmitter.prototype.emit.call(this, 'authStateChange', stateChangeData); SCEmitter.prototype.emit.call(this, 'authenticate', signedAuthToken); } SCEmitter.prototype.emit.call(this, 'authTokenChange', signedAuthToken); }; SCSocket.prototype.decodeBase64 = function (encodedString) { var decodedString; if (typeof Buffer == 'undefined') { if (global.atob) { decodedString = global.atob(encodedString); } else { decodedString = base64.decode(encodedString); } } else { var buffer = new Buffer(encodedString, 'base64'); decodedString = buffer.toString('utf8'); } return decodedString; }; SCSocket.prototype.encodeBase64 = function (decodedString) { var encodedString; if (typeof Buffer == 'undefined') { if (global.btoa) { encodedString = global.btoa(decodedString); } else { encodedString = base64.encode(decodedString); } } else { var buffer = new Buffer(decodedString, 'utf8'); encodedString = buffer.toString('base64'); } return encodedString; }; SCSocket.prototype._extractAuthTokenData = function (signedAuthToken) { var tokenParts = (signedAuthToken || '').split('.'); var encodedTokenData = tokenParts[1]; if (encodedTokenData != null) { var tokenData = encodedTokenData; try { tokenData = this.decodeBase64(tokenData); return JSON.parse(tokenData); } catch (e) { return tokenData; } } return null; }; SCSocket.prototype.getAuthToken = function () { return this.authToken; }; SCSocket.prototype.getSignedAuthToken = function () { return this.signedAuthToken; }; // Perform client-initiated authentication by providing an encrypted token string SCSocket.prototype.authenticate = function (signedAuthToken, callback) { var self = this; this._changeToPendingAuthState(); this.emit('#authenticate', signedAuthToken, function (err, authStatus) { if (authStatus && authStatus.authError) { authStatus.authError = scErrors.hydrateError(authStatus.authError); } if (err) { self._changeToUnauthenticatedState(); callback && callback(err, authStatus); } else { self.auth.saveToken(self.options.authTokenName, signedAuthToken, {}, function (err) { callback && callback(err, authStatus); if (err) { self._changeToUnauthenticatedState(); self._onSCError(err); } else { if (authStatus.isAuthenticated) { self._changeToAuthenticatedState(signedAuthToken); } else { self._changeToUnauthenticatedState(); } } }); } }); }; SCSocket.prototype._tryReconnect = function (initialDelay) { var self = this; var exponent = this.connectAttempts++; var reconnectOptions = this.options.autoReconnectOptions; var timeout; if (initialDelay == null || exponent > 0) { var initialTimeout = Math.round(reconnectOptions.initialDelay + (reconnectOptions.randomness || 0) * Math.random()); timeout = Math.round(initialTimeout * Math.pow(reconnectOptions.multiplier, exponent)); } else { timeout = initialDelay; } if (timeout > reconnectOptions.maxDelay) { timeout = reconnectOptions.maxDelay; } clearTimeout(this._reconnectTimeoutRef); this.pendingReconnect = true; this.pendingReconnectTimeout = timeout; this._reconnectTimeoutRef = setTimeout(function () { self.connect(); }, timeout); }; SCSocket.prototype._onSCOpen = function (status) { var self = this; if (status) { this.id = status.id; this.pingTimeout = status.pingTimeout; this.transport.pingTimeout = this.pingTimeout; if (status.isAuthenticated) { this._changeToAuthenticatedState(status.authToken); } else { this._changeToUnauthenticatedState(); } } else { this._changeToUnauthenticatedState(); } this.connectAttempts = 0; if (this.options.autoProcessSubscriptions) { this.processPendingSubscriptions(); } else { this.pendingConnectCallback = true; } // If the user invokes the callback while in autoProcessSubscriptions mode, it // won't break anything - The processPendingSubscriptions() call will be a no-op. SCEmitter.prototype.emit.call(this, 'connect', status, function () { self.processPendingSubscriptions(); }); this._flushEmitBuffer(); }; SCSocket.prototype._onSCError = function (err) { var self = this; // Throw error in different stack frame so that error handling // cannot interfere with a reconnect action. setTimeout(function () { if (self.listeners('error').length < 1) { throw err; } else { SCEmitter.prototype.emit.call(self, 'error', err); } }, 0); }; SCSocket.prototype._suspendSubscriptions = function () { var channel, newState; for (var channelName in this._channels) { if (this._channels.hasOwnProperty(channelName)) { channel = this._channels[channelName]; if (channel.state == channel.SUBSCRIBED || channel.state == channel.PENDING) { newState = channel.PENDING; } else { newState = channel.UNSUBSCRIBED; } this._triggerChannelUnsubscribe(channel, newState); } } }; SCSocket.prototype._onSCClose = function (code, data, openAbort) { var self = this; this.id = null; if (this.transport) { this.transport.off(); } this.pendingReconnect = false; this.pendingReconnectTimeout = null; clearTimeout(this._reconnectTimeoutRef); this._changeToPendingAuthState(); this._suspendSubscriptions(); // Try to reconnect // on server ping timeout (4000) // or on client pong timeout (4001) // or on close without status (1005) // or on handshake failure (4003) // or on socket hung up (1006) if (this.options.autoReconnect) { if (code == 4000 || code == 4001 || code == 1005) { // If there is a ping or pong timeout or socket closes without // status, don't wait before trying to reconnect - These could happen // if the client wakes up after a period of inactivity and in this case we // want to re-establish the connection as soon as possible. this._tryReconnect(0); // Codes 4500 and above will be treated as permanent disconnects. // Socket will not try to auto-reconnect. } else if (code != 1000 && code < 4500) { this._tryReconnect(); } } if (openAbort) { SCEmitter.prototype.emit.call(self, 'connectAbort', code, data); } else { SCEmitter.prototype.emit.call(self, 'disconnect', code, data); } if (!SCSocket.ignoreStatuses[code]) { var failureMessage; if (data) { failureMessage = 'Socket connection failed: ' + data; } else { failureMessage = 'Socket connection failed for unknown reasons'; } var err = new SocketProtocolError(SCSocket.errorStatuses[code] || failureMessage, code); this._onSCError(err); } }; SCSocket.prototype._onSCEvent = function (event, data, res) { var handler = this._privateEventHandlerMap[event]; if (handler) { handler.call(this, data, res); } else { SCEmitter.prototype.emit.call(this, event, data, function () { res && res.callback.apply(res, arguments); }); } }; SCSocket.prototype.decode = function (message) { return this.transport.decode(message); }; SCSocket.prototype.encode = function (object) { return this.transport.encode(object); }; SCSocket.prototype._flushEmitBuffer = function () { var currentNode = this._emitBuffer.head; var nextNode; while (currentNode) { nextNode = currentNode.next; var eventObject = currentNode.data; currentNode.detach(); this.transport.emitObject(eventObject); currentNode = nextNode; } }; SCSocket.prototype._handleEventAckTimeout = function (eventObject, eventNode) { if (eventNode) { eventNode.detach(); } var callback = eventObject.callback; if (callback) { delete eventObject.callback; var error = new TimeoutError("Event response for '" + eventObject.event + "' timed out"); callback.call(eventObject, error, eventObject); } }; SCSocket.prototype._emit = function (event, data, callback) { var self = this; if (this.state == this.CLOSED) { this.connect(); } var eventObject = { event: event, data: data, callback: callback }; var eventNode = new LinkedList.Item(); if (this.options.cloneData) { eventNode.data = clone(eventObject); } else { eventNode.data = eventObject; } eventObject.timeout = setTimeout(function () { self._handleEventAckTimeout(eventObject, eventNode); }, this.ackTimeout); this._emitBuffer.append(eventNode); if (this.state == this.OPEN) { this._flushEmitBuffer(); } }; SCSocket.prototype.send = function (data) { this.transport.send(data); }; SCSocket.prototype.emit = function (event, data, callback) { if (this._localEvents[event] == null) { this._emit(event, data, callback); } else { SCEmitter.prototype.emit.call(this, event, data); } }; SCSocket.prototype.publish = function (channelName, data, callback) { var pubData = { channel: this._decorateChannelName(channelName), data: data }; this.emit('#publish', pubData, callback); }; SCSocket.prototype._triggerChannelSubscribe = function (channel, subscriptionOptions) { var channelName = channel.name; if (channel.state != channel.SUBSCRIBED) { var oldState = channel.state; channel.state = channel.SUBSCRIBED; var stateChangeData = { channel: channelName, oldState: oldState, newState: channel.state, subscriptionOptions: subscriptionOptions }; channel.emit('subscribeStateChange', stateChangeData); channel.emit('subscribe', channelName, subscriptionOptions); SCEmitter.prototype.emit.call(this, 'subscribeStateChange', stateChangeData); SCEmitter.prototype.emit.call(this, 'subscribe', channelName, subscriptionOptions); } }; SCSocket.prototype._triggerChannelSubscribeFail = function (err, channel, subscriptionOptions) { var channelName = channel.name; var meetsAuthRequirements = !channel.waitForAuth || this.authState == this.AUTHENTICATED; if (channel.state != channel.UNSUBSCRIBED && meetsAuthRequirements) { channel.state = channel.UNSUBSCRIBED; channel.emit('subscribeFail', err, channelName, subscriptionOptions); SCEmitter.prototype.emit.call(this, 'subscribeFail', err, channelName, subscriptionOptions); } }; // Cancel any pending subscribe callback SCSocket.prototype._cancelPendingSubscribeCallback = function (channel) { if (channel._pendingSubscriptionCid != null) { this.transport.cancelPendingResponse(channel._pendingSubscriptionCid); delete channel._pendingSubscriptionCid; } }; SCSocket.prototype._decorateChannelName = function (channelName) { if (this.channelPrefix) { channelName = this.channelPrefix + channelName; } return channelName; }; SCSocket.prototype._undecorateChannelName = function (decoratedChannelName) { if (this.channelPrefix && decoratedChannelName.indexOf(this.channelPrefix) == 0) { return decoratedChannelName.replace(this.channelPrefix, ''); } return decoratedChannelName; }; SCSocket.prototype._trySubscribe = function (channel) { var self = this; var meetsAuthRequirements = !channel.waitForAuth || this.authState == this.AUTHENTICATED; // We can only ever have one pending subscribe action at any given time on a channel if (this.state == this.OPEN && !this.pendingConnectCallback && channel._pendingSubscriptionCid == null && meetsAuthRequirements) { var options = { noTimeout: true }; var subscriptionOptions = { channel: this._decorateChannelName(channel.name) }; if (channel.waitForAuth) { options.waitForAuth = true; subscriptionOptions.waitForAuth = options.waitForAuth; } if (channel.data) { subscriptionOptions.data = channel.data; } channel._pendingSubscriptionCid = this.transport.emit( '#subscribe', subscriptionOptions, options, function (err) { delete channel._pendingSubscriptionCid; if (err) { self._triggerChannelSubscribeFail(err, channel, subscriptionOptions); } else { self._triggerChannelSubscribe(channel, subscriptionOptions); } } ); SCEmitter.prototype.emit.call(this, 'subscribeRequest', channel.name, subscriptionOptions); } }; SCSocket.prototype.subscribe = function (channelName, options) { var channel = this._channels[channelName]; if (!channel) { channel = new SCChannel(channelName, this, options); this._channels[channelName] = channel; } else if (options) { channel.setOptions(options); } if (channel.state == channel.UNSUBSCRIBED) { channel.state = channel.PENDING; this._trySubscribe(channel); } return channel; }; SCSocket.prototype._triggerChannelUnsubscribe = function (channel, newState) { var channelName = channel.name; var oldState = channel.state; if (newState) { channel.state = newState; } else { channel.state = channel.UNSUBSCRIBED; } this._cancelPendingSubscribeCallback(channel); if (oldState == channel.SUBSCRIBED) { var stateChangeData = { channel: channelName, oldState: oldState, newState: channel.state }; channel.emit('subscribeStateChange', stateChangeData); channel.emit('unsubscribe', channelName); SCEmitter.prototype.emit.call(this, 'subscribeStateChange', stateChangeData); SCEmitter.prototype.emit.call(this, 'unsubscribe', channelName); } }; SCSocket.prototype._tryUnsubscribe = function (channel) { var self = this; if (this.state == this.OPEN) { var options = { noTimeout: true }; // If there is a pending subscribe action, cancel the callback this._cancelPendingSubscribeCallback(channel); // This operation cannot fail because the TCP protocol guarantees delivery // so long as the connection remains open. If the connection closes, // the server will automatically unsubscribe the socket and thus complete // the operation on the server side. var decoratedChannelName = this._decorateChannelName(channel.name); this.transport.emit('#unsubscribe', decoratedChannelName, options); } }; SCSocket.prototype.unsubscribe = function (channelName) { var channel = this._channels[channelName]; if (channel) { if (channel.state != channel.UNSUBSCRIBED) { this._triggerChannelUnsubscribe(channel); this._tryUnsubscribe(channel); } } }; SCSocket.prototype.channel = function (channelName, options) { var currentChannel = this._channels[channelName]; if (!currentChannel) { currentChannel = new SCChannel(channelName, this, options); this._channels[channelName] = currentChannel; } return currentChannel; }; SCSocket.prototype.destroyChannel = function (channelName) { var channel = this._channels[channelName]; channel.unwatch(); channel.unsubscribe(); delete this._channels[channelName]; }; SCSocket.prototype.subscriptions = function (includePending) { var subs = []; var channel, includeChannel; for (var channelName in this._channels) { if (this._channels.hasOwnProperty(channelName)) { channel = this._channels[channelName]; if (includePending) { includeChannel = channel && (channel.state == channel.SUBSCRIBED || channel.state == channel.PENDING); } else { includeChannel = channel && channel.state == channel.SUBSCRIBED; } if (includeChannel) { subs.push(channelName); } } } return subs; }; SCSocket.prototype.isSubscribed = function (channelName, includePending) { var channel = this._channels[channelName]; if (includePending) { return !!channel && (channel.state == channel.SUBSCRIBED || channel.state == channel.PENDING); } return !!channel && channel.state == channel.SUBSCRIBED; }; SCSocket.prototype.processPendingSubscriptions = function () { var self = this; this.pendingConnectCallback = false; for (var i in this._channels) { if (this._channels.hasOwnProperty(i)) { (function (channel) { if (channel.state == channel.PENDING) { self._trySubscribe(channel); } })(this._channels[i]); } } }; SCSocket.prototype.watch = function (channelName, handler) { if (typeof handler != 'function') { throw new InvalidArgumentsError('No handler function was provided'); } this._channelEmitter.on(channelName, handler); }; SCSocket.prototype.unwatch = function (channelName, handler) { if (handler) { this._channelEmitter.removeListener(channelName, handler); } else { this._channelEmitter.removeAllListeners(channelName); } }; SCSocket.prototype.watchers = function (channelName) { return this._channelEmitter.listeners(channelName); }; module.exports = SCSocket; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) },{"./auth":2,"./response":3,"./sctransport":6,"base-64":8,"buffer":20,"clone":9,"linked-list":12,"querystring":24,"sc-channel":13,"sc-emitter":14,"sc-errors":17,"sc-formatter":18}],5:[function(require,module,exports){ (function (global){ var SCSocket = require('./scsocket'); var scErrors = require('sc-errors'); var InvalidArgumentsError = scErrors.InvalidArgumentsError; var _connections = {}; function getMultiplexId(options) { var protocolPrefix = options.secure ? 'https://' : 'http://'; var queryString = ''; if (options.query) { if (typeof options.query == 'string') { queryString = options.query; } else { var queryArray = []; var queryMap = options.query; for (var key in queryMap) { if (queryMap.hasOwnProperty(key)) { queryArray.push(key + '=' + queryMap[key]); } } if (queryArray.length) { queryString = '?' + queryArray.join('&'); } } } var host; if (options.host) { host = options.host; } else { host = options.hostname + ':' + options.port; } return protocolPrefix + host + options.path + queryString; } function isUrlSecure() { return global.location && location.protocol == 'https:'; } function getPort(options, isSecureDefault) { var isSecure = options.secure == null ? isSecureDefault : options.secure; return options.port || (global.location && location.port ? location.port : isSecure ? 443 : 80); } function connect(options) { var self = this; options = options || {}; if (options.host && options.port) { throw new InvalidArgumentsError('The host option should already include the' + ' port number in the format hostname:port - Because of this, the host and port options' + ' cannot be specified together; use the hostname option instead'); } var isSecureDefault = isUrlSecure(); var opts = { port: getPort(options, isSecureDefault), hostname: global.location && location.hostname, path: '/socketcluster/', secure: isSecureDefault, autoConnect: true, autoReconnect: true, autoProcessSubscriptions: true, connectTimeout: 20000, ackTimeout: 10000, timestampRequests: false, timestampParam: 't', authEngine: null, authTokenName: 'socketCluster.authToken', binaryType: 'arraybuffer', multiplex: true, cloneData: false }; for (var i in options) { if (options.hasOwnProperty(i)) { opts[i] = options[i]; } } var multiplexId = getMultiplexId(opts); if (opts.multiplex === false) { return new SCSocket(opts); } if (_connections[multiplexId]) { _connections[multiplexId].connect(); } else { _connections[multiplexId] = new SCSocket(opts); } return _connections[multiplexId]; } function destroy(options) { var self = this; options = options || {}; var isSecureDefault = isUrlSecure(); var opts = { port: getPort(options, isSecureDefault), hostname: global.location && location.hostname, path: '/socketcluster/', secure: isSecureDefault }; for (var i in options) { if (options.hasOwnProperty(i)) { opts[i] = options[i]; } } var multiplexId = getMultiplexId(opts); var socket = _connections[multiplexId]; if (socket) { socket.disconnect(); } delete _connections[multiplexId]; } module.exports = { connect: connect, destroy: destroy, connections: _connections }; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./scsocket":4,"sc-errors":17}],6:[function(require,module,exports){ (function (global){ var SCEmitter = require('sc-emitter').SCEmitter; var Response = require('./response').Response; var querystring = require('querystring'); var WebSocket; var createWebSocket; if (global.WebSocket) { WebSocket = global.WebSocket; createWebSocket = function (uri, options) { return new WebSocket(uri); }; } else { WebSocket = require('ws'); createWebSocket = function (uri, options) { return new WebSocket(uri, null, options); }; } var scErrors = require('sc-errors'); var TimeoutError = scErrors.TimeoutError; var SCTransport = function (authEngine, codecEngine, options) { this.state = this.CLOSED; this.auth = authEngine; this.codec = codecEngine; this.options = options; this.connectTimeout = options.connectTimeout; this.pingTimeout = options.ackTimeout; this.callIdGenerator = options.callIdGenerator; this._pingTimeoutTicker = null; this._callbackMap = {}; this.open(); }; SCTransport.prototype = Object.create(SCEmitter.prototype); SCTransport.CONNECTING = SCTransport.prototype.CONNECTING = 'connecting'; SCTransport.OPEN = SCTransport.prototype.OPEN = 'open'; SCTransport.CLOSED = SCTransport.prototype.CLOSED = 'closed'; SCTransport.prototype.uri = function () { var query = this.options.query || {}; var schema = this.options.secure ? 'wss' : 'ws'; if (this.options.timestampRequests) { query[this.options.timestampParam] = (new Date()).getTime(); } query = querystring.encode(query); if (query.length) { query = '?' + query; } var host; if (this.options.host) { host = this.options.host; } else { var port = ''; if (this.options.port && ((schema == 'wss' && this.options.port != 443) || (schema == 'ws' && this.options.port != 80))) { port = ':' + this.options.port; } host = this.options.hostname + port; } return schema + '://' + host + this.options.path + query; }; SCTransport.prototype.open = function () { var self = this; this.state = this.CONNECTING; var uri = this.uri(); var wsSocket = createWebSocket(uri, this.options); wsSocket.binaryType = this.options.binaryType; this.socket = wsSocket; wsSocket.onopen = function () { self._onOpen(); }; wsSocket.onclose = function (event) { var code; if (event.code == null) { // This is to handle an edge case in React Native whereby // event.code is undefined when the mobile device is locked. // TODO: This is not perfect since this condition could also apply to // an abnormal close (no close control frame) which would be a 1006. code = 1005; } else { code = event.code; } self._onClose(code, event.reason); }; wsSocket.onmessage = function (message, flags) { self._onMessage(message.data); }; wsSocket.onerror = function (error) { // The onclose event will be called automatically after the onerror event // if the socket is connected - Otherwise, if it's in the middle of // connecting, we want to close it manually with a 1006 - This is necessary // to prevent inconsistent behavior when running the client in Node.js // vs in a browser. if (self.state === self.CONNECTING) { self._onClose(1006); } }; this._connectTimeoutRef = setTimeout(function () { self._onClose(4007); self.socket.close(4007); }, this.connectTimeout); }; SCTransport.prototype._onOpen = function () { var self = this; clearTimeout(this._connectTimeoutRef); this._resetPingTimeout(); this._handshake(function (err, status) { if (err) { self._onError(err); self._onClose(4003); self.socket.close(4003); } else { self.state = self.OPEN; SCEmitter.prototype.emit.call(self, 'open', status); self._resetPingTimeout(); } }); }; SCTransport.prototype._handshake = function (callback) { var self = this; this.auth.loadToken(this.options.authTokenName, function (err, token) { if (err) { callback(err); } else { // Don't wait for this.state to be 'open'. // The underlying WebSocket (this.socket) is already open. var options = { force: true }; self.emit('#handshake', { authToken: token }, options, function (err, status) { if (status) { // Add the token which was used as part of authentication attempt // to the status object. status.authToken = token; if (status.authError) { status.authError = scErrors.hydrateError(status.authError); } } callback(err, status); }); } }); }; SCTransport.prototype._onClose = function (code, data) { delete this.socket.onopen; delete this.socket.onclose; delete this.socket.onmessage; delete this.socket.onerror; clearTimeout(this._connectTimeoutRef); if (this.state == this.OPEN) { this.state = this.CLOSED; SCEmitter.prototype.emit.call(this, 'close', code, data); } else if (this.state == this.CONNECTING) { this.state = this.CLOSED; SCEmitter.prototype.emit.call(this, 'openAbort', code, data); } }; SCTransport.prototype._onMessage = function (message) { SCEmitter.prototype.emit.call(this, 'event', 'message', message); var obj = this.decode(message); // If ping if (obj == '#1') { this._resetPingTimeout(); if (this.socket.readyState == this.socket.OPEN) { this.sendObject('#2'); } } else { var event = obj.event; if (event) { var response = new Response(this, obj.cid); SCEmitter.prototype.emit.call(this, 'event', event, obj.data, response); } else if (obj.rid != null) { var eventObject = this._callbackMap[obj.rid]; if (eventObject) { clearTimeout(eventObject.timeout); delete this._callbackMap[obj.rid]; if (eventObject.callback) { var rehydratedError = scErrors.hydrateError(obj.error); eventObject.callback(rehydratedError, obj.data); } } } else { SCEmitter.prototype.emit.call(this, 'event', 'raw', obj); } } }; SCTransport.prototype._onError = function (err) { SCEmitter.prototype.emit.call(this, 'error', err); }; SCTransport.prototype._resetPingTimeout = function () { var self = this; var now = (new Date()).getTime(); clearTimeout(this._pingTimeoutTicker); this._pingTimeoutTicker = setTimeout(function () { self._onClose(4000); self.socket.close(4000); }, this.pingTimeout); }; SCTransport.prototype.getBytesReceived = function () { return this.socket.bytesReceived; }; SCTransport.prototype.close = function (code, data) { code = code || 1000; if (this.state == this.OPEN) { var packet = { code: code, data: data }; this.emit('#disconnect', packet); this._onClose(code, data); this.socket.close(code); } else if (this.state == this.CONNECTING) { this._onClose(code, data); this.socket.close(code); } }; SCTransport.prototype.emitObject = function (eventObject) { var simpleEventObject = { event: eventObject.event, data: eventObject.data }; if (eventObject.callback) { simpleEventObject.cid = eventObject.cid = this.callIdGenerator(); this._callbackMap[eventObject.cid] = eventObject; } this.sendObject(simpleEventObject); return eventObject.cid || null; }; SCTransport.prototype._handleEventAckTimeout = function (eventObject) { var errorMessage = "Event response for '" + eventObject.event + "' timed out"; var error = new TimeoutError(errorMessage); if (eventObject.cid) { delete this._callbackMap[eventObject.cid]; } var callback = eventObject.callback; delete eventObject.callback; callback.call(eventObject, error, eventObject); }; // The last two optional arguments (a and b) can be options and/or callback SCTransport.prototype.emit = function (event, data, a, b) { var self = this; var callback, options; if (b) { options = a; callback = b; } else { if (a instanceof Function) { options = {}; callback = a; } else { options = a; } } var eventObject = { event: event, data: data, callback: callback }; if (callback && !options.noTimeout) { eventObject.timeout = setTimeout(function () { self._handleEventAckTimeout(eventObject); }, this.options.ackTimeout); } var cid = null; if (this.state == this.OPEN || options.force) { cid = this.emitObject(eventObject); } return cid; }; SCTransport.prototype.cancelPendingResponse = function (cid) { delete this._callbackMap[cid]; }; SCTransport.prototype.decode = function (message) { return this.codec.decode(message); }; SCTransport.prototype.encode = function (object) { return this.codec.encode(object); }; SCTransport.prototype.send = function (data) { if (this.socket.readyState != this.socket.OPEN) { this._onClose(1005); } else { this.socket.send(data); } }; SCTransport.prototype.serializeObject = function (object) { var str, formatError; try { str = this.encode(object); } catch (err) { formatError = err; this._onError(formatError); } if (!formatError) { return str; } return null; }; SCTransport.prototype.sendObject = function (object) { var str = this.serializeObject(object); if (str != null) { this.send(str); } }; module.exports.SCTransport = SCTransport; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./response":3,"querystring":24,"sc-emitter":14,"sc-errors":17,"ws":7}],7:[function(require,module,exports){ var global; if (typeof WorkerGlobalScope !== 'undefined') { global = self; } else { global = typeof window != 'undefined' && window || (function() { return this; })(); } var WebSocket = global.WebSocket || global.MozWebSocket; /** * WebSocket constructor. * * The third `opts` options object gets ignored in web browsers, since it's * non-standard, and throws a TypeError if passed to the constructor. * See: https://github.com/einaros/ws/issues/227 * * @param {String} uri * @param {Array} protocols (optional) * @param {Object} opts (optional) * @api public */ function ws(uri, protocols, opts) { var instance; if (protocols) { instance = new WebSocket(uri, protocols); } else { instance = new WebSocket(uri); } return instance; } if (WebSocket) ws.prototype = WebSocket.prototype; module.exports = WebSocket ? ws : null; },{}],8:[function(require,module,exports){ (function (global){ /*! http://mths.be/base64 v0.1.0 by @mathias | MIT license */ ;(function(root) { // Detect free variables `exports`. var freeExports = typeof exports == 'object' && exports; // Detect free variable `module`. var freeModule = typeof module == 'object' && module && module.exports == freeExports && module; // Detect free variable `global`, from Node.js or Browserified code, and use // it as `root`. var freeGlobal = typeof global == 'object' && global; if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { root = freeGlobal; } /*--------------------------------------------------------------------------*/ var InvalidCharacterError = function(message) { this.message = message; }; InvalidCharacterError.prototype = new Error; InvalidCharacterError.prototype.name = 'InvalidCharacterError'; var error = function(message) { // Note: the error messages used throughout this file match those used by // the native `atob`/`btoa` implementation in Chromium. throw new InvalidCharacterError(message); }; var TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; // http://whatwg.org/html/common-microsyntaxes.html#space-character var REGEX_SPACE_CHARACTERS = /[\t\n\f\r ]/g; // `decode` is designed to be fully compatible with `atob` as described in the // HTML Standard. http://whatwg.org/html/webappapis.html#dom-windowbase64-atob // The optimized base64-decoding algorithm used is based on @atk’s excellent // implementation. https://gist.github.com/atk/1020396 var decode = function(input) { input = String(input) .replace(REGEX_SPACE_CHARACTERS, ''); var length = input.length; if (length % 4 == 0) { input = input.replace(/==?$/, ''); length = input.length; } if ( length % 4 == 1 || // http://whatwg.org/C#alphanumeric-ascii-characters /[^+a-zA-Z0-9/]/.test(input) ) { error( 'Invalid character: the string to be decoded is not correctly encoded.' ); } var bitCounter = 0; var bitStorage; var buffer; var output = ''; var position = -1; while (++position < length) { buffer = TABLE.indexOf(input.charAt(position)); bitStorage = bitCounter % 4 ? bitStorage * 64 + buffer : buffer; // Unless this is the first of a group of 4 characters… if (bitCounter++ % 4) { // …convert the first 8 bits to a single ASCII character. output += String.fromCharCode( 0xFF & bitStorage >> (-2 * bitCounter & 6) ); } } return output; }; // `encode` is designed to be fully compatible with `btoa` as described in the // HTML Standard: http://whatwg.org/html/webappapis.html#dom-windowbase64-btoa var encode = function(input) { input = String(input); if (/[^\0-\xFF]/.test(input)) { // Note: no need to special-case astral symbols here, as surrogates are // matched, and the input is supposed to only contain ASCII anyway. error( 'The string to be encoded contains characters outside of the ' + 'Latin1 range.' ); } var padding = input.length % 3; var output = ''; var position = -1; var a; var b; var c; var d; var buffer; // Make sure any padding is handled outside of the loop. var length = input.length - padding; while (++position < length) { // Read three bytes, i.e. 24 bits. a = input.charCodeAt(position) << 16; b = input.charCodeAt(++position) << 8; c = input.charCodeAt(++position); buffer = a + b + c; // Turn the 24 bits into four chunks of 6 bits each, and append the // matching character for each of them to the output. output += ( TABLE.charAt(buffer >> 18 & 0x3F) + TABLE.charAt(buffer >> 12 & 0x3F) + TABLE.charAt(buffer >> 6 & 0x3F) + TABLE.charAt(buffer & 0x3F) ); } if (padding == 2) { a = input.charCodeAt(position) << 8; b = input.charCodeAt(++position); buffer = a + b; output += ( TABLE.charAt(buffer >> 10) + TABLE.charAt((buffer >> 4) & 0x3F) + TABLE.charAt((buffer << 2) & 0x3F) + '=' ); } else if (padding == 1) { buffer = input.charCodeAt(position); output += ( TABLE.charAt(buffer >> 2) + TABLE.charAt((buffer << 4) & 0x3F) + '==' ); } return output; }; var base64 = { 'encode': encode, 'decode': decode, 'version': '0.1.0' }; // Some AMD build optimizers, like r.js, check for specific condition patterns // like the following: if ( typeof define == 'function' && typeof define.amd == 'object' && define.amd ) { define(function() { return base64; }); } else if (freeExports && !freeExports.nodeType) { if (freeModule) { // in Node.js or RingoJS v0.8.0+ freeModule.exports = base64; } else { // in Narwhal or RingoJS v0.7.0- for (var key in base64) { base64.hasOwnProperty(key) && (freeExports[key] = base64[key]); } } } else { // in Rhino or a web browser root.base64 = base64; } }(this)); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],9:[function(require,module,exports){ (function (Buffer){ var clone = (function() { 'use strict'; function _instanceof(obj, type) { return type != null && obj instanceof type; } var nativeMap; try { nativeMap = Map; } catch(_) { // maybe a reference error because no `Map`. Give it a dummy value that no // value will ever be an instanceof. nativeMap = function() {}; } var nativeSet; try { nativeSet = Set; } catch(_) { nativeSet = function() {}; } var nativePromise; try { nativePromise = Promise; } catch(_) { nativePromise = function() {}; } /** * Clones (copies) an Object using deep copying. * * This function supports circular references by default, but if you are certain * there are no circular references in your object, you can save some CPU time * by calling clone(obj, false). * * Caution: if `circular` is false and `parent` contains circular references, * your program may enter an infinite loop and crash. * * @param `parent` - the object to be cloned * @param `circular` - set to true if the object to be cloned may contain * circular references. (optional - true by default) * @param `depth` - set to a number if the object is only to be cloned to * a particular depth. (optional - defaults to Infinity) * @param `prototype` - sets the prototype to be used when cloning an object. * (optional - defaults to parent prototype). * @param `includeNonEnumerable` - set to true if the non-enumerable properties * should be cloned as well. Non-enumerable properties on the prototype * chain will be ignored. (optional - false by default) */ function clone(parent, circular, depth, prototype, includeNonEnumerable) { if (typeof circular === 'object') { depth = circular.depth; prototype = circular.prototype; includeNonEnumerable = circular.includeNonEnumerable; circular = circular.circular; } // maintain two arrays for circular references, where corresponding parents // and children have the same index var allParents = []; var allChildren = []; var useBuffer = typeof Buffer != 'undefined'; if (typeof circular == 'undefined') circular = true; if (typeof depth == 'undefined') depth = Infinity; // recurse this function so we don't reset allParents and allChildren function _clone(parent, depth) { // cloning null always returns null if (parent === null) return null; if (depth === 0) return parent; var child; var proto; if (typeof parent != 'object') { return parent; } if (_instanceof(parent, nativeMap)) { child = new nativeMap(); } else if (_instanceof(parent, nativeSet)) { child = new nativeSet(); } else if (_instanceof(parent, nativePromise)) { child = new nativePromise(function (resolve, reject) { parent.then(function(value) { resolve(_clone(value, depth - 1)); }, function(err) { reject(_clone(err, depth - 1)); }); }); } else if (clone.__isArray(parent)) { child = []; } else if (clone.__isRegExp(parent)) { child = new RegExp(parent.source, __getRegExpFlags(parent)); if (parent.lastIndex) child.lastIndex = parent.lastIndex; } else if (clone.__isDate(parent)) { child = new Date(parent.getTime()); } else if (useBuffer && Buffer.isBuffer(parent)) { child = new Buffer(parent.length); parent.copy(child); return child; } else if (_instanceof(parent, Error)) { child = Object.create(parent); } else { if (typeof prototype == 'undefined') { proto = Object.getPrototypeOf(parent); child = Object.create(proto); } else { child = Object.create(prototype); proto = prototype; } } if (circular) { var index = allParents.indexOf(parent); if (index != -1) { return allChildren[index]; } allParents.push(parent); allChildren.push(child); } if (_instanceof(parent, nativeMap)) { parent.forEach(function(value, key) { var keyChild = _clone(key, depth - 1); var valueChild = _clone(value, depth - 1); child.set(keyChild, valueChild); }); } if (_instanceof(parent, nativeSet)) { parent.forEach(function(value) { var entryChild = _clone(value, depth - 1); child.add(entryChild); }); } for (var i in parent) { var attrs; if (proto) { attrs = Object.getOwnPropertyDescriptor(proto, i); } if (attrs && attrs.set == null) { continue; } child[i] = _clone(parent[i], depth - 1); } if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(parent); for (var i = 0; i < symbols.length; i++) { // Don't need to worry about cloning a symbol because it is a primitive, // like a number or string. var symbol = symbols[i]; var descriptor = Object.getOwnPropertyDescriptor(parent, symbol); if (descriptor && !descriptor.enumerable && !includeNonEnumerable) { continue; } child[symbol] = _clone(parent[symbol], depth - 1); if (!descriptor.enumerable) { Object.defineProperty(child, symbol, { enumerable: false }); } } } if (includeNonEnumerable) { var allPropertyNames = Object.getOwnPropertyNames(parent); for (var i = 0; i < allPropertyNames.length; i++) { var propertyName = allPropertyNames[i]; var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName); if (descriptor && descriptor.enumerable) { continue; } child[propertyName] = _clone(parent[propertyName], depth - 1); Object.defineProperty(child, propertyName, { enumerable: false }); } } return child; } return _clone(parent, depth); } /** * Simple flat clone using prototype, accepts only objects, usefull for property * override on FLAT configuration object (no nested props). * * USE WITH CAUTION! This may not behave as you wish if you do not know how this * works. */ clone.clonePrototype = function clonePrototype(parent) { if (parent === null) return null; var c = function () {}; c.prototype = parent; return new c(); }; // private utility functions function __objToStr(o) { return Object.prototype.toString.call(o); } clone.__objToStr = __objToStr; function __isDate(o) { return typeof o === 'object' && __objToStr(o) === '[object Date]'; } clone.__isDate = __isDate; function __isArray(o) { return typeof o === 'object' && __objToStr(o) === '[object Array]'; } clone.__isArray = __isArray; function __isRegExp(o) { return typeof o === 'object' && __objToStr(o) === '[object RegExp]'; } clone.__isRegExp = __isRegExp; function __getRegExpFlags(re) { var flags = ''; if (re.global) flags += 'g'; if (re.ignoreCase) flags += 'i'; if (re.multiline) flags += 'm'; return flags; } clone.__getRegExpFlags = __getRegExpFlags; return clone; })(); if (typeof module === 'object' && module.exports) { module.exports = clone; } }).call(this,require("buffer").Buffer) },{"buffer":20}],10:[function(require,module,exports){ /** * Expose `Emitter`. */ module.exports = Emitter; /** * Initialize a new `Emitter`. * * @api public */ function Emitter(obj) { if (obj) return mixin(obj); }; /** * Mixin the emitter properties. * * @param {Object} obj * @return {Object} * @api private */ function mixin(obj) { for (var key in Emitter.prototype) { obj[key] = Emitter.prototype[key]; } return obj; } /** * Listen on the given `event` with `fn`. * * @param {String} event * @param {Function} fn * @return {Emitter} * @api public */ Emitter.prototype.on = Emitter.prototype.addEventListener = function(event, fn){ this._callbacks = this._callbacks || {}; (this._callbacks['$' + event] = this._callbacks['$' + event] || []) .push(fn); return this; }; /** * Adds an `event` listener that will be invoked a single * time then automatically removed. * * @param {String} event * @param {Function} fn * @return {Emitter} * @api public */ Emitter.prototype.once = function(event, fn){ function on() { this.off(event, on); fn.apply(this, arguments); } on.fn = fn; this.on(event, on); return this; }; /** * Remove the given callback for `event` or all * registered callbacks. * * @param {String} event * @param {Function} fn * @return {Emitter} * @api public */ Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function(event, fn){ this._callbacks = this._callbacks || {}; // all if (0 == arguments.length) { this._callbacks = {}; return this; } // specific event var callbacks = this._callbacks['$' + event]; if (!callbacks) return this; // remove all handlers if (1 == arguments.length) { delete this._callbacks['$' + event]; return this; } // remove specific handler var cb; for (var i = 0; i < callbacks.length; i++) { cb = callbacks[i]; if (cb === fn || cb.fn === fn) { callbacks.splice(i, 1); break; } } return this; }; /** * Emit `event` with the given args. * * @param {String} event * @param {Mixed} ... * @return {Emitter} */ Emitter.prototype.emit = function(event){ this._callbacks = this._callbacks || {}; var args = [].slice.call(arguments, 1) , callbacks = this._callbacks['$' + event]; if (callbacks) { callbacks = callbacks.slice(0); for (var i = 0, len = callbacks.length; i < len; ++i) { callbacks[i].apply(this, args); } } return this; }; /** * Return array of callbacks for `event`. * * @param {String} event * @return {Array} * @api public */ Emitter.prototype.listeners = function(event){ this._callbacks = this._callbacks || {}; return this._callbacks['$' + event] || []; }; /** * Check if this emitter has `event` handlers. * * @param {String} event * @return {Boolean} * @api public */ Emitter.prototype.hasListeners = function(event){ return !! this.listeners(event).length; }; },{}],11:[function(require,module,exports){ 'use strict'; /** * Constants. */ var errorMessage; errorMessage = 'An argument without append, prepend, ' + 'or detach methods was given to `List'; /** * Creates a new List: A linked list is a bit like an Array, but * knows nothing about how many items are in it, and knows only about its * first (`head`) and last (`tail`) items. Each item (e.g. `head`, `tail`, * &c.) knows which item comes before or after it (its more like the * implementation of the DOM in JavaScript). * @global * @private * @constructor * @class Represents an instance of List. */ function List(/*items...*/) { if (arguments.length) { return List.from(arguments); } } var ListPrototype; ListPrototype = List.prototype; /** * Creates a new list from the arguments (each a list item) passed in. * @name List.of * @param {...ListItem} [items] - Zero or more items to attach. * @returns {list} - A new instance of List. */ List.of = function (/*items...*/) { return List.from.call(this, arguments); }; /** * Creates a new list from the given array-like object (each a list item) * passed in. * @name List.from * @param {ListItem[]} [items] - The items to append. * @returns {list} - A new instance of List. */ List.from = function (items) { var list = new this(), length, iterator, item; if (items && (length = items.length)) { iterator = -1; while (++iterator < length) { item = items[iterator]; if (item !== null && item !== undefined) { list.append(item); } } } return list; }; /** * List#head * Default to `null`. */ ListPrototype.head = null; /** * List#tail * Default to `null`. */ ListPrototype.tail = null; /** * Returns the list's items as an array. This does *not* detach the items. * @name List#toArray * @returns {ListItem[]} - An array of (still attached) ListItems. */ ListPrototype.toArray = function () { var item = this.head, result = []; while (item) { result.push(item); item = item.next; } return result; }; /** * Prepends the given item to the list: Item will be the new first item * (`head`). * @name List#prepend * @param {ListItem} item - The item to prepend. * @returns {ListItem} - An instance of ListItem (the given item). */ ListPrototype.prepend = function (item) { if (!item) { return false; } if (!item.append || !item.prepend || !item.detach) { throw new Error(errorMessage + '#prepend`.'); } var self, head; // Cache self. self = this; // If self has a first item, defer prepend to the first items prepend // method, and return the result. head = self.head; if (head) { return head.prepend(item); } // ...otherwise, there is no `head` (or `tail`) item yet. // Detach the prependee. item.detach(); // Set the prependees parent list to reference self. item.list = self; // Set self's first item to the prependee, and return the item. self.head = item; return item; }; /** * Appends the given item to the list: Item will be the new last item (`tail`) * if the list had a first item, and its first item (`head`) otherwise. * @name List#append * @param {ListItem} item - The item to append. * @returns {ListItem} - An instance of ListItem (the given item). */ ListPrototype.append = function (item) { if (!item) { return false; } if (!item.append || !item.prepend || !item.detach) { throw new Error(errorMessage + '#append`.'); } var self, head, tail; // Cache self. self = this; // If self has a last item, defer appending to the last items append // method, and return the result. tail = self.tail; if (tail) { return tail.append(item); } // If self has a first item, defer appending to the first items append // method, and return the result. head = self.head; if (head) { return head.append(item); } // ...otherwise, there is no `tail` or `head` item yet. // Detach the appendee. item.detach(); // Set the appendees parent list to reference self. item.list = self; // Set self's first item to the appendee, and return the item. self.head = item; return item; }; /** * Creates a new ListItem: A linked list item is a bit like DOM node: * It knows only about its "parent" (`list`), the item before it (`prev`), * and the item after it (`next`). * @global * @private * @constructor * @class Represents an instance of ListItem. */ function ListItem() {} List.Item = ListItem; var ListItemPrototype = ListItem.prototype; ListItemPrototype.next = null; ListItemPrototype.prev = null; ListItemPrototype.list = null; /** * Detaches the item operated on from its parent list. * @name ListItem#detach * @returns {ListItem} - The item operated on. */ ListItemPrototype.detach = function () { // Cache self, the parent list, and the previous and next items. var self = this, list = self.list, prev = self.prev, next = self.next; // If the item is already detached, return self. if (!list) { return self; } // If self is the last item in the parent list, link the lists last item // to the previous item. if (list.tail === self) { list.tail = prev; } // If self is the first item in the parent list, link the lists first item // to the next item. if (list.head === self) { list.head = next; } // If both the last and first items in the parent list are the same, // remove the link to the last item. if (list.tail === list.head) { list.tail = null; } // If a previous item exists, link its next item to selfs next item. if (prev) { prev.next = next; } // If a next item exists, link its previous item to selfs previous item. if (next) { next.prev = prev; } // Remove links from self to both the next and previous items, and to the // parent list. self.prev = self.next = self.list = null; // Return self. return self; }; /** * Prepends the given item *before* the item operated on. * @name ListItem#prepend * @param {ListItem} item - The item to prepend. * @returns {ListItem} - The item operated on, or false when that item is not * attached. */ ListItemPrototype.prepend = function (item) { if (!item || !item.append || !item.prepend || !item.detach) { throw new Error(errorMessage + 'Item#prepend`.'); } // Cache self, the parent list, and the previous item. var self = this, list = self.list, prev = self.prev; // If self is detached, return false. if (!list) { return false; } // Detach the prependee. item.detach(); // If self has a previous item... if (prev) { // ...link the prependees previous item, to selfs previous item. item.prev = prev; // ...link the previous items next item, to self. prev.next = item; } // Set the prependees next item to self. item.next = self; // Set the prependees parent list to selfs parent list. item.list = list; // Set the previous item of self to the prependee. self.prev = item; // If self is the first item in the parent list, link the lists first item // to the prependee. if (self === list.head) { list.head = item; } // If the the parent list has no last item, link the lists last item to // self. if (!list.tail) { list.tail = self; } // Return the prependee. return item; }; /** * Appends the given item *after* the item operated on. * @name ListItem#append * @param {ListItem} item - The item to append. * @returns {ListItem} - The item operated on, or false when that item is not * attached. */ ListItemPrototype.append = function (item) { // If item is falsey, return false. if (!item || !item.append || !item.prepend || !item.detach) { throw new Error(errorMessage + 'Item#append`.'); } // Cache self, the parent list, and the next item. var self = this, list = self.list, next = self.next; // If self is detached, return false. if (!list) { return false; } // Detach the appendee. item.detach(); // If self has a next item... if (next) { // ...link the appendees next item, to selfs next item. item.next = next; // ...link the next items previous item, to the appendee. next.prev = item; } // Set the appendees previous item to self. item.prev = self; // Set the appendees parent list to selfs parent list. item.list = list; // Set the next item of self to the appendee. self.next = item; // If the the parent list has no last item or if self is the parent lists // last item, link the lists last item to the appendee. if (self === list.tail || !list.tail) { list.tail = item; } // Return the appendee. return item; }; /** * Expose `List`. */ module.exports = List; },{}],12:[function(require,module,exports){ 'use strict'; module.exports = require('./_source/linked-list.js'); },{"./_source/linked-list.js":11}],13:[function(require,module,exports){ var SCEmitter = require('sc-emitter').SCEmitter; var SCChannel = function (name, client, options) { var self = this; SCEmitter.call(this); this.PENDING = 'pending'; this.SUBSCRIBED = 'subscribed'; this.UNSUBSCRIBED = 'unsubscribed'; this.name = name; this.state = this.UNSUBSCRIBED; this.client = client; this.options = options || {}; this.setOptions(this.options); }; SCChannel.prototype = Object.create(SCEmitter.prototype); SCChannel.prototype.setOptions = function (options) { if (!options) { options = {}; } this.waitForAuth = options.waitForAuth || false; if (options.data !== undefined) { this.data = options.data; } }; SCChannel.prototype.getState = function () { return this.state; }; SCChannel.prototype.subscribe = function (options) { this.client.subscribe(this.name, options); }; SCChannel.prototype.unsubscribe = function () { this.client.unsubscribe(this.name); }; SCChannel.prototype.isSubscribed = function (includePending) { return this.client.isSubscribed(this.name, includePending); }; SCChannel.prototype.publish = function (data, callback) { this.client.publish(this.name, data, callback); }; SCChannel.prototype.watch = function (handler) { this.client.watch(this.name, handler); }; SCChannel.prototype.unwatch = function (handler) { this.client.unwatch(this.name, handler); }; SCChannel.prototype.watchers = function () { return this.client.watchers(this.name); }; SCChannel.prototype.destroy = function () { this.client.destroyChannel(this.name); }; module.exports.SCChannel = SCChannel; },{"sc-emitter":14}],14:[function(require,module,exports){ var Emitter = require('component-emitter'); if (!Object.create) { Object.create = require('./objectcreate'); } var SCEmitter = function () { Emitter.call(this); }; SCEmitter.prototype = Object.create(Emitter.prototype); SCEmitter.prototype.emit = function (event) { if (event == 'error') { // To work with sc-domain. // See https://github.com/SocketCluster/sc-domain var domainErrorArgs = ['__domainError']; if (arguments[1] !== undefined) { domainErrorArgs.push(arguments[1]); } Emitter.prototype.emit.apply(this, domainErrorArgs); if (this.domain) { // Emit the error on the domain if it has one. // See https://github.com/joyent/node/blob/ef4344311e19a4f73c031508252b21712b22fe8a/lib/events.js#L78-85 var err = arguments[1]; if (!err) { err = new Error('Uncaught, unspecified "error" event.'); } err.domainEmitter = this; err.domain = this.domain; err.domainThrown = false; this.domain.emit('error', err); } } Emitter.prototype.emit.apply(this, arguments); }; module.exports.SCEmitter = SCEmitter; },{"./objectcreate":15,"component-emitter":10}],15:[function(require,module,exports){ module.exports.create = (function () { function F() {}; return function (o) { if (arguments.length != 1) { throw new Error('Object.create implementation only accepts one parameter.'); } F.prototype = o; return new F(); } })(); },{}],16:[function(require,module,exports){ // Based on https://github.com/dscape/cycle/blob/master/cycle.js module.exports = function decycle(object) { // Make a deep copy of an object or array, assuring that there is at most // one instance of each object or array in the resulting structure. The // duplicate references (which might be forming cycles) are replaced with // an object of the form // {$ref: PATH} // where the PATH is a JSONPath string that locates the first occurance. // So, // var a = []; // a[0] = a; // return JSON.stringify(JSON.decycle(a)); // produces the string '[{"$ref":"$"}]'. // JSONPath is used to locate the unique object. $ indicates the top level of // the object or array. [NUMBER] or [STRING] indicates a child member or // property. var objects = [], // Keep a reference to each unique object or array paths = []; // Keep the path to each unique object or array return (function derez(value, path) { // The derez recurses through the object, producing the deep copy. var i, // The loop counter name, // Property name nu; // The new object or array // typeof null === 'object', so go on if this value is really an object but not // one of the weird builtin objects. if (typeof value === 'object' && value !== null && !(value instanceof Boolean) && !(value instanceof Date) && !(value instanceof Number) && !(value instanceof RegExp) && !(value instanceof String)) { // If the value is an object or array, look to see if we have already // encountered it. If so, return a $ref/path object. This is a hard way, // linear search that will get slower as the number of unique objects grows. for (i = 0; i < objects.length; i += 1) { if (objects[i] === value) { return {$ref: paths[i]}; } } // Otherwise, accumulate the unique value and its path. objects.push(value); paths.push(path); // If it is an array, replicate the array. if (Object.prototype.toString.apply(value) === '[object Array]') { nu = []; for (i = 0; i < value.length; i += 1) { nu[i] = derez(value[i], path + '[' + i + ']'); } } else { // If it is an object, replicate the object. nu = {}; for (name in value) { if (Object.prototype.hasOwnProperty.call(value, name)) { nu[name] = derez(value[name], path + '[' + JSON.stringify(name) + ']'); } } } return nu; } return value; }(object, '$')); }; },{}],17:[function(require,module,exports){ var decycle = require('./decycle'); var isStrict = (function () { return !this; })(); function AuthTokenExpiredError(message, expiry) { this.name = 'AuthTokenExpiredError'; this.message = message; this.expiry = expiry; if (Error.captureStackTrace && !isStrict) { Error.captureStackTrace(this, arguments.callee); } else { this.stack = (new Error()).stack; } }; AuthTokenExpiredError.prototype = Object.create(Error.prototype); function AuthTokenInvalidError(message) { this.name = 'AuthTokenInvalidError'; this.message = message; if (Error.captureStackTrace && !isStrict) { Error.captureStackTrace(this, arguments.callee); } else { this.stack = (new Error()).stack; } }; AuthTokenInvalidError.prototype = Object.create(Error.prototype); function AuthTokenNotBeforeError(message, date) { this.name = 'AuthTokenNotBeforeError'; this.message = message; this.date = date; if (Error.captureStackTrace && !isStrict) { Error.captureStackTrace(this, arguments.callee); } else { this.stack = (new Error()).stack; } }; AuthTokenNotBeforeError.prototype = Object.create(Error.prototype); // For any other auth token error. function AuthTokenError(message) { this.name = 'AuthTokenError'; this.message = message; if (Error.captureStackTrace && !isStrict) { Error.captureStackTrace(this, arguments.callee); } else { this.stack = (new Error()).stack; } }; AuthTokenError.prototype = Object.create(Error.prototype); function SilentMiddlewareBlockedError(message, type) { this.name = 'SilentMiddlewareBlockedError'; this.message = message; this.type = type; if (Error.captureStackTrace && !isStrict) { Error.captureStackTrace(this, arguments.callee); } else { this.stack = (new Error()).stack; } }; SilentMiddlewareBlockedError.prototype = Object.create(Error.prototype); function InvalidActionError(message) { this.name = 'InvalidActionError'; this.message = message; if (Error.captureStackTrace && !isStrict) { Error.captureStackTrace(this, arguments.callee); } else { this.stack = (new Error()).stack; } }; InvalidActionError.prototype = Object.create(Error.prototype); function InvalidArgumentsError(message) { this.name = 'InvalidArgumentsError'; this.message = message; if (Error.captureStackTrace && !isStrict) { Error.captureStackTrace(this, arguments.callee); } else { this.stack = (new Error()).stack; } }; InvalidArgumentsError.prototype = Object.create(Error.prototype); function InvalidOptionsError(message) { this.name = 'InvalidOptionsError'; this.message = message; if (Error.captureStackTrace && !isStrict) { Error.captureStackTrace(this, arguments.callee); } else { this.stack = (new Error()).stack; } }; InvalidOptionsError.prototype = Object.create(Error.prototype); function InvalidMessageError(message) { this.name = 'InvalidMessageError'; this.message = message; if (Error.captureStackTrace && !isStrict) { Error.captureStackTrace(this, arguments.callee); } else { this.stack = (new Error()).stack; } }; InvalidMessageError.prototype = Object.create(Error.prototype); function SocketProtocolError(message, code) { this.name = 'SocketProtocolError'; this.message = message; this.code = code; if (Error.captureStackTrace && !isStrict) { Error.captureStackTrace(this, arguments.callee); } else { this.stack = (new Error()).stack; } }; SocketProtocolError.prototype = Object.create(Error.prototype); function ServerProtocolError(message) { this.name = 'ServerProtocolError'; this.message = message; if (Error.captureStackTrace && !isStrict) { Error.captureStackTrace(this, arguments.callee); } else { this.stack = (new Error()).stack; } }; ServerProtocolError.prototype = Object.create(Error.prototype); function HTTPServerError(message) { this.name = 'HTTPServerError'; this.message = message; if (Error.captureStackTrace && !isStrict) { Error.captureStackTrace(this, arguments.callee); } else { this.stack = (new Error()).stack; } }; HTTPServerError.prototype = Object.create(Error.prototype); function ResourceLimitError(message) { this.name = 'ResourceLimitError'; this.message = message; if (Error.captureStackTrace && !isStrict) { Error.captureStackTrace(this, arguments.callee); } else { this.stack = (new Error()).stack; } }; ResourceLimitError.prototype = Object.create(Error.prototype); function TimeoutError(message) { this.name = 'TimeoutError'; this.message = message; if (Error.captureStackTrace && !isStrict) { Error.captureStackTrace(this, arguments.callee); } else { this.stack = (new Error()).stack; } }; TimeoutError.prototype = Object.create(Error.prototype); function BrokerError(message) { this.name = 'BrokerError'; this.message = message; if (Error.captureStackTrace && !isStrict) { Error.captureStackTrace(this, arguments.callee); } else { this.stack = (new Error()).stack; } }; BrokerError.prototype = Object.create(Error.prototype); function ProcessExitError(message, code) { this.name = 'ProcessExitError'; this.message = message; this.code = code; if (Error.captureStackTrace && !isStrict) { Error.captureStackTrace(this, arguments.callee); } else { this.stack = (new Error()).stack; } }; ProcessExitError.prototype = Object.create(Error.prototype); function UnknownError(message) { this.name = 'UnknownError'; this.message = message; if (Error.captureStackTrace && !isStrict) { Error.captureStackTrace(this, arguments.callee); } else { this.stack = (new Error()).stack; } }; UnknownError.prototype = Object.create(Error.prototype); // Expose all error types module.exports = { AuthTokenExpiredError: AuthTokenExpiredError, AuthTokenInvalidError: AuthTokenInvalidError, AuthTokenNotBeforeError: AuthTokenNotBeforeError, AuthTokenError: AuthTokenError, SilentMiddlewareBlockedError: SilentMiddlewareBlockedError, InvalidActionError: InvalidActionError, InvalidArgumentsError: InvalidArgumentsError, InvalidOptionsError: InvalidOptionsError, InvalidMessageError: InvalidMessageError, SocketProtocolError: SocketProtocolError, ServerProtocolError: ServerProtocolError, HTTPServerError: HTTPServerError, ResourceLimitError: ResourceLimitError, TimeoutError: TimeoutError, BrokerError: BrokerError, ProcessExitError: ProcessExitError, UnknownError: UnknownError }; module.exports.socketProtocolErrorStatuses = { 1001: 'Socket was disconnected', 1002: 'A WebSocket protocol error was encountered', 1003: 'Server terminated socket because it received invalid data', 1005: 'Socket closed without status code', 1006: 'Socket hung up', 1007: 'Message format was incorrect', 1008: 'Encountered a policy violation', 1009: 'Message was too big to process', 1010: 'Client ended the connection because the server did not comply with extension requirements', 1011: 'Server encountered an unexpected fatal condition', 4000: 'Server ping timed out', 4001: 'Client pong timed out', 4002: 'Server failed to sign auth token', 4003: 'Failed to complete handshake', 4004: 'Client failed to save auth token', 4005: 'Did not receive #handshake from client before timeout', 4006: 'Failed to bind socket to message broker', 4007: 'Client connection establishment timed out' }; module.exports.socketProtocolIgnoreStatuses = { 1000: 'Socket closed normally', 1001: 'Socket hung up' }; // Properties related to error domains cannot be serialized. var unserializableErrorProperties = { domain: 1, domainEmitter: 1, domainThrown: 1 }; module.exports.dehydrateError = function (error, includeStackTrace) { var dehydratedError; if (!error || typeof error == 'string') { dehydratedError = error; } else { dehydratedError = { message: error.message }; if (includeStackTrace) { dehydratedError.stack = error.stack; } for (var i in error) { if (!unserializableErrorProperties[i]) { dehydratedError[i] = error[i]; } } } return decycle(dehydratedError); }; module.exports.hydrateError = function (error) { var hydratedError = null; if (error != null) { if (typeof error == 'string') { hydratedError = error; } else { hydratedError = new Error(error.message); for (var i in error) { if (error.hasOwnProperty(i)) { hydratedError[i] = error[i]; } } } } return hydratedError; }; },{"./decycle":16}],18:[function(require,module,exports){ (function (global){ var base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var arrayBufferToBase64 = function (arraybuffer) { var bytes = new Uint8Array(arraybuffer); var len = bytes.length; var base64 = ''; for (var i = 0; i < len; i += 3) { base64 += base64Chars[bytes[i] >> 2]; base64 += base64Chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)]; base64 += base64Chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)]; base64 += base64Chars[bytes[i + 2] & 63]; } if ((len % 3) === 2) { base64 = base64.substring(0, base64.length - 1) + '='; } else if (len % 3 === 1) { base64 = base64.substring(0, base64.length - 2) + '=='; } return base64; }; var binaryToBase64Replacer = function (key, value) { if (global.ArrayBuffer && value instanceof global.ArrayBuffer) { return { base64: true, data: arrayBufferToBase64(value) }; } else if (global.Buffer) { if (value instanceof global.Buffer){ return { base64: true, data: value.toString('base64') }; } // Some versions of Node.js convert Buffers to Objects before they are passed to // the replacer function - Because of this, we need to rehydrate Buffers // before we can convert them to base64 strings. if (value && value.type == 'Buffer' && value.data instanceof Array) { var rehydratedBuffer; if (global.Buffer.from) { rehydratedBuffer = global.Buffer.from(value.data); } else { rehydratedBuffer = new global.Buffer(value.data); } return { base64: true, data: rehydratedBuffer.toString('base64') }; } } return value; }; // Decode the data which was transmitted over the wire to a JavaScript Object in a format which SC understands. // See encode function below for more details. module.exports.decode = function (input) { if (input == null) { return null; } // Leave ping or pong message as is if (input == '#1' || input == '#2') { return input; } var message = input.toString(); try { return JSON.parse(message); } catch (err) {} return message; }; // Encode a raw JavaScript object (which is in the SC protocol format) into a format for // transfering it over the wire. In this case, we just convert it into a simple JSON string. // If you want to create your own custom codec, you can encode the object into any format // (e.g. binary ArrayBuffer or string with any kind of compression) so long as your decode // function is able to rehydrate that object back into its original JavaScript Object format // (which adheres to the SC protocol). // See https://github.com/SocketCluster/socketcluster/blob/master/socketcluster-protocol.md // for details about the SC protocol. module.exports.encode = function (object) { // Leave ping or pong message as is if (object == '#1' || object == '#2') { return object; } return JSON.stringify(object, binaryToBase64Replacer); }; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],19:[function(require,module,exports){ 'use strict' exports.byteLength = byteLength exports.toByteArray = toByteArray exports.fromByteArray = fromByteArray var lookup = [] var revLookup = [] var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' for (var i = 0, len = code.length; i < len; ++i) { lookup[i] = code[i] revLookup[code.charCodeAt(i)] = i } revLookup['-'.charCodeAt(0)] = 62 revLookup['_'.charCodeAt(0)] = 63 function placeHoldersCount (b64) { var len = b64.length if (len % 4 > 0) { throw new Error('Invalid string. Length must be a multiple of 4') } // the number of equal signs (place holders) // if there are two placeholders, than the two characters before it // represent one byte // if there is only one, then the three characters before it represent 2 bytes // this is just a cheap hack to not do indexOf twice return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0 } function byteLength (b64) { // base64 is 4/3 + up to two characters of the original data return b64.length * 3 / 4 - placeHoldersCount(b64) } function toByteArray (b64) { var i, j, l, tmp, placeHolders, arr var len = b64.length placeHolders = placeHoldersCount(b64) arr = new Arr(len * 3 / 4 - placeHolders) // if there are placeholders, only get up to the last complete 4 chars l = placeHolders > 0 ? len - 4 : len var L = 0 for (i = 0, j = 0; i < l; i += 4, j += 3) { tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] arr[L++] = (tmp >> 16) & 0xFF arr[L++] = (tmp >> 8) & 0xFF arr[L++] = tmp & 0xFF } if (placeHolders === 2) { tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) arr[L++] = tmp & 0xFF } else if (placeHolders === 1) { tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) arr[L++] = (tmp >> 8) & 0xFF arr[L++] = tmp & 0xFF } return arr } function tripletToBase64 (num) { return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] } function encodeChunk (uint8, start, end) { var tmp var output = [] for (var i = start; i < end; i += 3) { tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) output.push(tripletToBase64(tmp)) } return output.join('') } function fromByteArray (uint8) { var tmp var len = uint8.length var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes var output = '' var parts = [] var maxChunkLength = 16383 // must be multiple of 3 // go through the array every three bytes, we'll deal with trailing stuff later for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) } // pad the end with zeros, but make sure to not forget the extra bytes if (extraBytes === 1) { tmp = uint8[len - 1] output += lookup[tmp >> 2] output += lookup[(tmp << 4) & 0x3F] output += '==' } else if (extraBytes === 2) { tmp = (uint8[len - 2] << 8) + (uint8[len - 1]) output += lookup[tmp >> 10] output += lookup[(tmp >> 4) & 0x3F] output += lookup[(tmp << 2) & 0x3F] output += '=' } parts.push(output) return parts.join('') } },{}],20:[function(require,module,exports){ /*! * The buffer module from node.js, for the browser. * * @author Feross Aboukhadijeh * @license MIT */ /* eslint-disable no-proto */ 'use strict' var base64 = require('base64-js') var ieee754 = require('ieee754') exports.Buffer = Buffer exports.SlowBuffer = SlowBuffer exports.INSPECT_MAX_BYTES = 50 var K_MAX_LENGTH = 0x7fffffff exports.kMaxLength = K_MAX_LENGTH /** * If `Buffer.TYPED_ARRAY_SUPPORT`: * === true Use Uint8Array implementation (fastest) * === false Print warning and recommend using `buffer` v4.x which has an Object * implementation (most compatible, even IE6) * * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, * Opera 11.6+, iOS 4.2+. * * We report that the browser does not support typed arrays if the are not subclassable * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array` * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support * for __proto__ and has a buggy typed array implementation. */ Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport() if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' && typeof console.error === 'function') { console.error( 'This browser lacks typed array (Uint8Array) support which is required by ' + '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.' ) } function typedArraySupport () { // Can typed array instances can be augmented? try { var arr = new Uint8Array(1) arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} return arr.foo() === 42 } catch (e) { return false } } function createBuffer (length) { if (length > K_MAX_LENGTH) { throw new RangeError('Invalid typed array length') } // Return an augmented `Uint8Array` instance var buf = new Uint8Array(length) buf.__proto__ = Buffer.prototype return buf } /** * The Buffer constructor returns instances of `Uint8Array` that have their * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of * `Uint8Array`, so the returned instances will have all the node `Buffer` methods * and the `Uint8Array` methods. Square bracket notation works as expected -- it * returns a single octet. * * The `Uint8Array` prototype remains unmodified. */ function Buffer (arg, encodingOrOffset, length) { // Common case. if (typeof arg === 'number') { if (typeof encodingOrOffset === 'string') { throw new Error( 'If encoding is specified then the first argument must be a string' ) } return allocUnsafe(arg) } return from(arg, encodingOrOffset, length) } // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 if (typeof Symbol !== 'undefined' && Symbol.species && Buffer[Symbol.species] === Buffer) { Object.defineProperty(Buffer, Symbol.species, { value: null, configurable: true, enumerable: false, writable: false }) } Buffer.poolSize = 8192 // not used by this implementation function from (value, encodingOrOffset, length) { if (typeof value === 'number') { throw new TypeError('"value" argument must not be a number') } if (value instanceof ArrayBuffer) { return fromArrayBuffer(value, encodingOrOffset, length) } if (typeof value === 'string') { return fromString(value, encodingOrOffset) } return fromObject(value) } /** * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError * if value is a number. * Buffer.from(str[, encoding]) * Buffer.from(array) * Buffer.from(buffer) * Buffer.from(arrayBuffer[, byteOffset[, length]]) **/ Buffer.from = function (value, encodingOrOffset, length) { return from(value, encodingOrOffset, length) } // Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug: // https://github.com/feross/buffer/pull/148 Buffer.prototype.__proto__ = Uint8Array.prototype Buffer.__proto__ = Uint8Array function assertSize (size) { if (typeof size !== 'number') { throw new TypeError('"size" argument must be a number') } else if (size < 0) { throw new RangeError('"size" argument must not be negative') } } function alloc (size, fill, encoding) { assertSize(size) if (size <= 0) { return createBuffer(size) } if (fill !== undefined) { // Only pay attention to encoding if it's a string. This // prevents accidentally sending in a number that would // be interpretted as a start offset. return typeof encoding === 'string' ? createBuffer(size).fill(fill, encoding) : createBuffer(size).fill(fill) } return createBuffer(size) } /** * Creates a new filled Buffer instance. * alloc(size[, fill[, encoding]]) **/ Buffer.alloc = function (size, fill, encoding) { return alloc(size, fill, encoding) } function allocUnsafe (size) { assertSize(size) return createBuffer(size < 0 ? 0 : checked(size) | 0) } /** * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. * */ Buffer.allocUnsafe = function (size) { return allocUnsafe(size) } /** * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. */ Buffer.allocUnsafeSlow = function (size) { return allocUnsafe(size) } function fromString (string, encoding) { if (typeof encoding !== 'string' || encoding === '') { encoding = 'utf8' } if (!Buffer.isEncoding(encoding)) { throw new TypeError('"encoding" must be a valid string encoding') } var length = byteLength(string, encoding) | 0 var buf = createBuffer(length) var actual = buf.write(string, encoding) if (actual !== length) { // Writing a hex string, for example, that contains invalid characters will // cause everything after the first invalid character to be ignored. (e.g. // 'abxxcd' will be treated as 'ab') buf = buf.slice(0, actual) } return buf } function fromArrayLike (array) { var length = array.length < 0 ? 0 : checked(array.length) | 0 var buf = createBuffer(length) for (var i = 0; i < length; i += 1) { buf[i] = array[i] & 255 } return buf } function fromArrayBuffer (array, byteOffset, length) { if (byteOffset < 0 || array.byteLength < byteOffset) { throw new RangeError('\'offset\' is out of bounds') } if (array.byteLength < byteOffset + (length || 0)) { throw new RangeError('\'length\' is out of bounds') } var buf if (byteOffset === undefined && length === undefined) { buf = new Uint8Array(array) } else if (length === undefined) { buf = new Uint8Array(array, byteOffset) } else { buf = new Uint8Array(array, byteOffset, length) } // Return an augmented `Uint8Array` instance buf.__proto__ = Buffer.prototype return buf } function fromObject (obj) { if (Buffer.isBuffer(obj)) { var len = checked(obj.length) | 0 var buf = createBuffer(len) if (buf.length === 0) { return buf } obj.copy(buf, 0, 0, len) return buf } if (obj) { if (ArrayBuffer.isView(obj) || 'length' in obj) { if (typeof obj.length !== 'number' || isnan(obj.length)) { return createBuffer(0) } return fromArrayLike(obj) } if (obj.type === 'Buffer' && Array.isArray(obj.data)) { return fromArrayLike(obj.data) } } throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') } function checked (length) { // Note: cannot use `length < K_MAX_LENGTH` here because that fails when // length is NaN (which is otherwise coerced to zero.) if (length >= K_MAX_LENGTH) { throw new RangeError('Attempt to allocate Buffer larger than maximum ' + 'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes') } return length | 0 } function SlowBuffer (length) { if (+length != length) { // eslint-disable-line eqeqeq length = 0 } return Buffer.alloc(+length) } Buffer.isBuffer = function isBuffer (b) { return b != null && b._isBuffer === true } Buffer.compare = function compare (a, b) { if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { throw new TypeError('Arguments must be Buffers') } if (a === b) return 0 var x = a.length var y = b.length for (var i = 0, len = Math.min(x, y); i < len; ++i) { if (a[i] !== b[i]) { x = a[i] y = b[i] break } } if (x < y) return -1 if (y < x) return 1 return 0 } Buffer.isEncoding = function isEncoding (encoding) { switch (String(encoding).toLowerCase()) { case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'latin1': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return true default: return false } } Buffer.concat = function concat (list, length) { if (!Array.isArray(list)) { throw new TypeError('"list" argument must be an Array of Buffers') } if (list.length === 0) { return Buffer.alloc(0) } var i if (length === undefined) { length = 0 for (i = 0; i < list.length; ++i) { length += list[i].length } } var buffer = Buffer.allocUnsafe(length) var pos = 0 for (i = 0; i < list.length; ++i) { var buf = list[i] if (!Buffer.isBuffer(buf)) { throw new TypeError('"list" argument must be an Array of Buffers') } buf.copy(buffer, pos) pos += buf.length } return buffer } function byteLength (string, encoding) { if (Buffer.isBuffer(string)) { return string.length } if (ArrayBuffer.isView(string) || string instanceof ArrayBuffer) { return string.byteLength } if (typeof string !== 'string') { string = '' + string } var len = string.length if (len === 0) return 0 // Use a for loop to avoid recursion var loweredCase = false for (;;) { switch (encoding) { case 'ascii': case 'latin1': case 'binary': return len case 'utf8': case 'utf-8': case undefined: return utf8ToBytes(string).length case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return len * 2 case 'hex': return len >>> 1 case 'base64': return base64ToBytes(string).length default: if (loweredCase) return utf8ToBytes(string).length // assume utf8 encoding = ('' + encoding).toLowerCase() loweredCase = true } } } Buffer.byteLength = byteLength function slowToString (encoding, start, end) { var loweredCase = false // No need to verify that "this.length <= MAX_UINT32" since it's a read-only // property of a typed array. // This behaves neither like String nor Uint8Array in that we set start/end // to their upper/lower bounds if the value passed is out of range. // undefined is handled specially as per ECMA-262 6th Edition, // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. if (start === undefined || start < 0) { start = 0 } // Return early if start > this.length. Done here to prevent potential uint32 // coercion fail below. if (start > this.length) { return '' } if (end === undefined || end > this.length) { end = this.length } if (end <= 0) { return '' } // Force coersion to uint32. This will also coerce falsey/NaN values to 0. end >>>= 0 start >>>= 0 if (end <= start) { return '' } if (!encoding) encoding = 'utf8' while (true) { switch (encoding) { case 'hex': return hexSlice(this, start, end) case 'utf8': case 'utf-8': return utf8Slice(this, start, end) case 'ascii': return asciiSlice(this, start, end) case 'latin1': case 'binary': return latin1Slice(this, start, end) case 'base64': return base64Slice(this, start, end) case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return utf16leSlice(this, start, end) default: if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) encoding = (encoding + '').toLowerCase() loweredCase = true } } } // This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package) // to detect a Buffer instance. It's not possible to use `instanceof Buffer` // reliably in a browserify context because there could be multiple different // copies of the 'buffer' package in use. This method works even for Buffer // instances that were created from another copy of the `buffer` package. // See: https://github.com/feross/buffer/issues/154 Buffer.prototype._isBuffer = true function swap (b, n, m) { var i = b[n] b[n] = b[m] b[m] = i } Buffer.prototype.swap16 = function swap16 () { var len = this.length if (len % 2 !== 0) { throw new RangeError('Buffer size must be a multiple of 16-bits') } for (var i = 0; i < len; i += 2) { swap(this, i, i + 1) } return this } Buffer.prototype.swap32 = function swap32 () { var len = this.length if (len % 4 !== 0) { throw new RangeError('Buffer size must be a multiple of 32-bits') } for (var i = 0; i < len; i += 4) { swap(this, i, i + 3) swap(this, i + 1, i + 2) } return this } Buffer.prototype.swap64 = function swap64 () { var len = this.length if (len % 8 !== 0) { throw new RangeError('Buffer size must be a multiple of 64-bits') } for (var i = 0; i < len; i += 8) { swap(this, i, i + 7) swap(this, i + 1, i + 6) swap(this, i + 2, i + 5) swap(this, i + 3, i + 4) } return this } Buffer.prototype.toString = function toString () { var length = this.length if (length === 0) return '' if (arguments.length === 0) return utf8Slice(this, 0, length) return slowToString.apply(this, arguments) } Buffer.prototype.equals = function equals (b) { if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') if (this === b) return true return Buffer.compare(this, b) === 0 } Buffer.prototype.inspect = function inspect () { var str = '' var max = exports.INSPECT_MAX_BYTES if (this.length > 0) { str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') if (this.length > max) str += ' ... ' } return '' } Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { if (!Buffer.isBuffer(target)) { throw new TypeError('Argument must be a Buffer') } if (start === undefined) { start = 0 } if (end === undefined) { end = target ? target.length : 0 } if (thisStart === undefined) { thisStart = 0 } if (thisEnd === undefined) { thisEnd = this.length } if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { throw new RangeError('out of range index') } if (thisStart >= thisEnd && start >= end) { return 0 } if (thisStart >= thisEnd) { return -1 } if (start >= end) { return 1 } start >>>= 0 end >>>= 0 thisStart >>>= 0 thisEnd >>>= 0 if (this === target) return 0 var x = thisEnd - thisStart var y = end - start var len = Math.min(x, y) var thisCopy = this.slice(thisStart, thisEnd) var targetCopy = target.slice(start, end) for (var i = 0; i < len; ++i) { if (thisCopy[i] !== targetCopy[i]) { x = thisCopy[i] y = targetCopy[i] break } } if (x < y) return -1 if (y < x) return 1 return 0 } // Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, // OR the last index of `val` in `buffer` at offset <= `byteOffset`. // // Arguments: // - buffer - a Buffer to search // - val - a string, Buffer, or number // - byteOffset - an index into `buffer`; will be clamped to an int32 // - encoding - an optional encoding, relevant is val is a string // - dir - true for indexOf, false for lastIndexOf function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { // Empty buffer means no match if (buffer.length === 0) return -1 // Normalize byteOffset if (typeof byteOffset === 'string') { encoding = byteOffset byteOffset = 0 } else if (byteOffset > 0x7fffffff) { byteOffset = 0x7fffffff } else if (byteOffset < -0x80000000) { byteOffset = -0x80000000 } byteOffset = +byteOffset // Coerce to Number. if (isNaN(byteOffset)) { // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer byteOffset = dir ? 0 : (buffer.length - 1) } // Normalize byteOffset: negative offsets start from the end of the buffer if (byteOffset < 0) byteOffset = buffer.length + byteOffset if (byteOffset >= buffer.length) { if (dir) return -1 else byteOffset = buffer.length - 1 } else if (byteOffset < 0) { if (dir) byteOffset = 0 else return -1 } // Normalize val if (typeof val === 'string') { val = Buffer.from(val, encoding) } // Finally, search either indexOf (if dir is true) or lastIndexOf if (Buffer.isBuffer(val)) { // Special case: looking for empty string/buffer always fails if (val.length === 0) { return -1 } return arrayIndexOf(buffer, val, byteOffset, encoding, dir) } else if (typeof val === 'number') { val = val & 0xFF // Search for a byte value [0-255] if (typeof Uint8Array.prototype.indexOf === 'function') { if (dir) { return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) } else { return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) } } return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) } throw new TypeError('val must be string, number or Buffer') } function arrayIndexOf (arr, val, byteOffset, encoding, dir) { var indexSize = 1 var arrLength = arr.length var valLength = val.length if (encoding !== undefined) { encoding = String(encoding).toLowerCase() if (encoding === 'ucs2' || encoding === 'ucs-2' || encoding === 'utf16le' || encoding === 'utf-16le') { if (arr.length < 2 || val.length < 2) { return -1 } indexSize = 2 arrLength /= 2 valLength /= 2 byteOffset /= 2 } } function read (buf, i) { if (indexSize === 1) { return buf[i] } else { return buf.readUInt16BE(i * indexSize) } } var i if (dir) { var foundIndex = -1 for (i = byteOffset; i < arrLength; i++) { if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { if (foundIndex === -1) foundIndex = i if (i - foundIndex + 1 === valLength) return foundIndex * indexSize } else { if (foundIndex !== -1) i -= i - foundIndex foundIndex = -1 } } } else { if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength for (i = byteOffset; i >= 0; i--) { var found = true for (var j = 0; j < valLength; j++) { if (read(arr, i + j) !== read(val, j)) { found = false break } } if (found) return i } } return -1 } Buffer.prototype.includes = function includes (val, byteOffset, encoding) { return this.indexOf(val, byteOffset, encoding) !== -1 } Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { return bidirectionalIndexOf(this, val, byteOffset, encoding, true) } Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { return bidirectionalIndexOf(this, val, byteOffset, encoding, false) } function hexWrite (buf, string, offset, length) { offset = Number(offset) || 0 var remaining = buf.length - offset if (!length) { length = remaining } else { length = Number(length) if (length > remaining) { length = remaining } } // must be an even number of digits var strLen = string.length if (strLen % 2 !== 0) throw new TypeError('Invalid hex string') if (length > strLen / 2) { length = strLen / 2 } for (var i = 0; i < length; ++i) { var parsed = parseInt(string.substr(i * 2, 2), 16) if (isNaN(parsed)) return i buf[offset + i] = parsed } return i } function utf8Write (buf, string, offset, length) { return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) } function asciiWrite (buf, string, offset, length) { return blitBuffer(asciiToBytes(string), buf, offset, length) } function latin1Write (buf, string, offset, length) { return asciiWrite(buf, string, offset, length) } function base64Write (buf, string, offset, length) { return blitBuffer(base64ToBytes(string), buf, offset, length) } function ucs2Write (buf, string, offset, length) { return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) } Buffer.prototype.write = function write (string, offset, length, encoding) { // Buffer#write(string) if (offset === undefined) { encoding = 'utf8' length = this.length offset = 0 // Buffer#write(string, encoding) } else if (length === undefined && typeof offset === 'string') { encoding = offset length = this.length offset = 0 // Buffer#write(string, offset[, length][, encoding]) } else if (isFinite(offset)) { offset = offset >>> 0 if (isFinite(length)) { length = length >>> 0 if (encoding === undefined) encoding = 'utf8' } else { encoding = length length = undefined } } else { throw new Error( 'Buffer.write(string, encoding, offset[, length]) is no longer supported' ) } var remaining = this.length - offset if (length === undefined || length > remaining) length = remaining if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { throw new RangeError('Attempt to write outside buffer bounds') } if (!encoding) encoding = 'utf8' var loweredCase = false for (;;) { switch (encoding) { case 'hex': return hexWrite(this, string, offset, length) case 'utf8': case 'utf-8': return utf8Write(this, string, offset, length) case 'ascii': return asciiWrite(this, string, offset, length) case 'latin1': case 'binary': return latin1Write(this, string, offset, length) case 'base64': // Warning: maxLength not taken into account in base64Write return base64Write(this, string, offset, length) case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return ucs2Write(this, string, offset, length) default: if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) encoding = ('' + encoding).toLowerCase() loweredCase = true } } } Buffer.prototype.toJSON = function toJSON () { return { type: 'Buffer', data: Array.prototype.slice.call(this._arr || this, 0) } } function base64Slice (buf, start, end) { if (start === 0 && end === buf.length) { return base64.fromByteArray(buf) } else { return base64.fromByteArray(buf.slice(start, end)) } } function utf8Slice (buf, start, end) { end = Math.min(buf.length, end) var res = [] var i = start while (i < end) { var firstByte = buf[i] var codePoint = null var bytesPerSequence = (firstByte > 0xEF) ? 4 : (firstByte > 0xDF) ? 3 : (firstByte > 0xBF) ? 2 : 1 if (i + bytesPerSequence <= end) { var secondByte, thirdByte, fourthByte, tempCodePoint switch (bytesPerSequence) { case 1: if (firstByte < 0x80) { codePoint = firstByte } break case 2: secondByte = buf[i + 1] if ((secondByte & 0xC0) === 0x80) { tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) if (tempCodePoint > 0x7F) { codePoint = tempCodePoint } } break case 3: secondByte = buf[i + 1] thirdByte = buf[i + 2] if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { codePoint = tempCodePoint } } break case 4: secondByte = buf[i + 1] thirdByte = buf[i + 2] fourthByte = buf[i + 3] if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { codePoint = tempCodePoint } } } } if (codePoint === null) { // we did not generate a valid codePoint so insert a // replacement char (U+FFFD) and advance only 1 byte codePoint = 0xFFFD bytesPerSequence = 1 } else if (codePoint > 0xFFFF) { // encode to utf16 (surrogate pair dance) codePoint -= 0x10000 res.push(codePoint >>> 10 & 0x3FF | 0xD800) codePoint = 0xDC00 | codePoint & 0x3FF } res.push(codePoint) i += bytesPerSequence } return decodeCodePointsArray(res) } // Based on http://stackoverflow.com/a/22747272/680742, the browser with // the lowest limit is Chrome, with 0x10000 args. // We go 1 magnitude less, for safety var MAX_ARGUMENTS_LENGTH = 0x1000 function decodeCodePointsArray (codePoints) { var len = codePoints.length if (len <= MAX_ARGUMENTS_LENGTH) { return String.fromCharCode.apply(String, codePoints) // avoid extra slice() } // Decode in chunks to avoid "call stack size exceeded". var res = '' var i = 0 while (i < len) { res += String.fromCharCode.apply( String, codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) ) } return res } function asciiSlice (buf, start, end) { var ret = '' end = Math.min(buf.length, end) for (var i = start; i < end; ++i) { ret += String.fromCharCode(buf[i] & 0x7F) } return ret } function latin1Slice (buf, start, end) { var ret = '' end = Math.min(buf.length, end) for (var i = start; i < end; ++i) { ret += String.fromCharCode(buf[i]) } return ret } function hexSlice (buf, start, end) { var len = buf.length if (!start || start < 0) start = 0 if (!end || end < 0 || end > len) end = len var out = '' for (var i = start; i < end; ++i) { out += toHex(buf[i]) } return out } function utf16leSlice (buf, start, end) { var bytes = buf.slice(start, end) var res = '' for (var i = 0; i < bytes.length; i += 2) { res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256)) } return res } Buffer.prototype.slice = function slice (start, end) { var len = this.length start = ~~start end = end === undefined ? len : ~~end if (start < 0) { start += len if (start < 0) start = 0 } else if (start > len) { start = len } if (end < 0) { end += len if (end < 0) end = 0 } else if (end > len) { end = len } if (end < start) end = start var newBuf = this.subarray(start, end) // Return an augmented `Uint8Array` instance newBuf.__proto__ = Buffer.prototype return newBuf } /* * Need to make sure that buffer isn't trying to write out of bounds. */ function checkOffset (offset, ext, length) { if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') } Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) checkOffset(offset, byteLength, this.length) var val = this[offset] var mul = 1 var i = 0 while (++i < byteLength && (mul *= 0x100)) { val += this[offset + i] * mul } return val } Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) { checkOffset(offset, byteLength, this.length) } var val = this[offset + --byteLength] var mul = 1 while (byteLength > 0 && (mul *= 0x100)) { val += this[offset + --byteLength] * mul } return val } Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 1, this.length) return this[offset] } Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 2, this.length) return this[offset] | (this[offset + 1] << 8) } Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 2, this.length) return (this[offset] << 8) | this[offset + 1] } Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 4, this.length) return ((this[offset]) | (this[offset + 1] << 8) | (this[offset + 2] << 16)) + (this[offset + 3] * 0x1000000) } Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 4, this.length) return (this[offset] * 0x1000000) + ((this[offset + 1] << 16) | (this[offset + 2] << 8) | this[offset + 3]) } Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) checkOffset(offset, byteLength, this.length) var val = this[offset] var mul = 1 var i = 0 while (++i < byteLength && (mul *= 0x100)) { val += this[offset + i] * mul } mul *= 0x80 if (val >= mul) val -= Math.pow(2, 8 * byteLength) return val } Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) checkOffset(offset, byteLength, this.length) var i = byteLength var mul = 1 var val = this[offset + --i] while (i > 0 && (mul *= 0x100)) { val += this[offset + --i] * mul } mul *= 0x80 if (val >= mul) val -= Math.pow(2, 8 * byteLength) return val } Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 1, this.length) if (!(this[offset] & 0x80)) return (this[offset]) return ((0xff - this[offset] + 1) * -1) } Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 2, this.length) var val = this[offset] | (this[offset + 1] << 8) return (val & 0x8000) ? val | 0xFFFF0000 : val } Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 2, this.length) var val = this[offset + 1] | (this[offset] << 8) return (val & 0x8000) ? val | 0xFFFF0000 : val } Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 4, this.length) return (this[offset]) | (this[offset + 1] << 8) | (this[offset + 2] << 16) | (this[offset + 3] << 24) } Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 4, this.length) return (this[offset] << 24) | (this[offset + 1] << 16) | (this[offset + 2] << 8) | (this[offset + 3]) } Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 4, this.length) return ieee754.read(this, offset, true, 23, 4) } Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 4, this.length) return ieee754.read(this, offset, false, 23, 4) } Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 8, this.length) return ieee754.read(this, offset, true, 52, 8) } Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 8, this.length) return ieee754.read(this, offset, false, 52, 8) } function checkInt (buf, value, offset, ext, max, min) { if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') if (offset + ext > buf.length) throw new RangeError('Index out of range') } Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { value = +value offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) { var maxBytes = Math.pow(2, 8 * byteLength) - 1 checkInt(this, value, offset, byteLength, maxBytes, 0) } var mul = 1 var i = 0 this[offset] = value & 0xFF while (++i < byteLength && (mul *= 0x100)) { this[offset + i] = (value / mul) & 0xFF } return offset + byteLength } Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { value = +value offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) { var maxBytes = Math.pow(2, 8 * byteLength) - 1 checkInt(this, value, offset, byteLength, maxBytes, 0) } var i = byteLength - 1 var mul = 1 this[offset + i] = value & 0xFF while (--i >= 0 && (mul *= 0x100)) { this[offset + i] = (value / mul) & 0xFF } return offset + byteLength } Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) this[offset] = (value & 0xff) return offset + 1 } Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) this[offset] = (value & 0xff) this[offset + 1] = (value >>> 8) return offset + 2 } Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) this[offset] = (value >>> 8) this[offset + 1] = (value & 0xff) return offset + 2 } Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) this[offset + 3] = (value >>> 24) this[offset + 2] = (value >>> 16) this[offset + 1] = (value >>> 8) this[offset] = (value & 0xff) return offset + 4 } Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) this[offset] = (value >>> 24) this[offset + 1] = (value >>> 16) this[offset + 2] = (value >>> 8) this[offset + 3] = (value & 0xff) return offset + 4 } Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) { var limit = Math.pow(2, (8 * byteLength) - 1) checkInt(this, value, offset, byteLength, limit - 1, -limit) } var i = 0 var mul = 1 var sub = 0 this[offset] = value & 0xFF while (++i < byteLength && (mul *= 0x100)) { if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { sub = 1 } this[offset + i] = ((value / mul) >> 0) - sub & 0xFF } return offset + byteLength } Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) { var limit = Math.pow(2, (8 * byteLength) - 1) checkInt(this, value, offset, byteLength, limit - 1, -limit) } var i = byteLength - 1 var mul = 1 var sub = 0 this[offset + i] = value & 0xFF while (--i >= 0 && (mul *= 0x100)) { if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { sub = 1 } this[offset + i] = ((value / mul) >> 0) - sub & 0xFF } return offset + byteLength } Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) if (value < 0) value = 0xff + value + 1 this[offset] = (value & 0xff) return offset + 1 } Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) this[offset] = (value & 0xff) this[offset + 1] = (value >>> 8) return offset + 2 } Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) this[offset] = (value >>> 8) this[offset + 1] = (value & 0xff) return offset + 2 } Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) this[offset] = (value & 0xff) this[offset + 1] = (value >>> 8) this[offset + 2] = (value >>> 16) this[offset + 3] = (value >>> 24) return offset + 4 } Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) if (value < 0) value = 0xffffffff + value + 1 this[offset] = (value >>> 24) this[offset + 1] = (value >>> 16) this[offset + 2] = (value >>> 8) this[offset + 3] = (value & 0xff) return offset + 4 } function checkIEEE754 (buf, value, offset, ext, max, min) { if (offset + ext > buf.length) throw new RangeError('Index out of range') if (offset < 0) throw new RangeError('Index out of range') } function writeFloat (buf, value, offset, littleEndian, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) { checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) } ieee754.write(buf, value, offset, littleEndian, 23, 4) return offset + 4 } Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { return writeFloat(this, value, offset, true, noAssert) } Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { return writeFloat(this, value, offset, false, noAssert) } function writeDouble (buf, value, offset, littleEndian, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) { checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) } ieee754.write(buf, value, offset, littleEndian, 52, 8) return offset + 8 } Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { return writeDouble(this, value, offset, true, noAssert) } Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { return writeDouble(this, value, offset, false, noAssert) } // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) Buffer.prototype.copy = function copy (target, targetStart, start, end) { if (!start) start = 0 if (!end && end !== 0) end = this.length if (targetStart >= target.length) targetStart = target.length if (!targetStart) targetStart = 0 if (end > 0 && end < start) end = start // Copy 0 bytes; we're done if (end === start) return 0 if (target.length === 0 || this.length === 0) return 0 // Fatal error conditions if (targetStart < 0) { throw new RangeError('targetStart out of bounds') } if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') if (end < 0) throw new RangeError('sourceEnd out of bounds') // Are we oob? if (end > this.length) end = this.length if (target.length - targetStart < end - start) { end = target.length - targetStart + start } var len = end - start var i if (this === target && start < targetStart && targetStart < end) { // descending copy from end for (i = len - 1; i >= 0; --i) { target[i + targetStart] = this[i + start] } } else if (len < 1000) { // ascending copy from start for (i = 0; i < len; ++i) { target[i + targetStart] = this[i + start] } } else { Uint8Array.prototype.set.call( target, this.subarray(start, start + len), targetStart ) } return len } // Usage: // buffer.fill(number[, offset[, end]]) // buffer.fill(buffer[, offset[, end]]) // buffer.fill(string[, offset[, end]][, encoding]) Buffer.prototype.fill = function fill (val, start, end, encoding) { // Handle string cases: if (typeof val === 'string') { if (typeof start === 'string') { encoding = start start = 0 end = this.length } else if (typeof end === 'string') { encoding = end end = this.length } if (val.length === 1) { var code = val.charCodeAt(0) if (code < 256) { val = code } } if (encoding !== undefined && typeof encoding !== 'string') { throw new TypeError('encoding must be a string') } if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { throw new TypeError('Unknown encoding: ' + encoding) } } else if (typeof val === 'number') { val = val & 255 } // Invalid ranges are not set to a default, so can range check early. if (start < 0 || this.length < start || this.length < end) { throw new RangeError('Out of range index') } if (end <= start) { return this } start = start >>> 0 end = end === undefined ? this.length : end >>> 0 if (!val) val = 0 var i if (typeof val === 'number') { for (i = start; i < end; ++i) { this[i] = val } } else { var bytes = Buffer.isBuffer(val) ? val : new Buffer(val, encoding) var len = bytes.length for (i = 0; i < end - start; ++i) { this[i + start] = bytes[i % len] } } return this } // HELPER FUNCTIONS // ================ var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g function base64clean (str) { // Node strips out invalid characters like \n and \t from the string, base64-js does not str = stringtrim(str).replace(INVALID_BASE64_RE, '') // Node converts strings with length < 2 to '' if (str.length < 2) return '' // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not while (str.length % 4 !== 0) { str = str + '=' } return str } function stringtrim (str) { if (str.trim) return str.trim() return str.replace(/^\s+|\s+$/g, '') } function toHex (n) { if (n < 16) return '0' + n.toString(16) return n.toString(16) } function utf8ToBytes (string, units) { units = units || Infinity var codePoint var length = string.length var leadSurrogate = null var bytes = [] for (var i = 0; i < length; ++i) { codePoint = string.charCodeAt(i) // is surrogate component if (codePoint > 0xD7FF && codePoint < 0xE000) { // last char was a lead if (!leadSurrogate) { // no lead yet if (codePoint > 0xDBFF) { // unexpected trail if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) continue } else if (i + 1 === length) { // unpaired lead if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) continue } // valid lead leadSurrogate = codePoint continue } // 2 leads in a row if (codePoint < 0xDC00) { if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) leadSurrogate = codePoint continue } // valid surrogate pair codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 } else if (leadSurrogate) { // valid bmp char, but last char was a lead if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) } leadSurrogate = null // encode utf8 if (codePoint < 0x80) { if ((units -= 1) < 0) break bytes.push(codePoint) } else if (codePoint < 0x800) { if ((units -= 2) < 0) break bytes.push( codePoint >> 0x6 | 0xC0, codePoint & 0x3F | 0x80 ) } else if (codePoint < 0x10000) { if ((units -= 3) < 0) break bytes.push( codePoint >> 0xC | 0xE0, codePoint >> 0x6 & 0x3F | 0x80, codePoint & 0x3F | 0x80 ) } else if (codePoint < 0x110000) { if ((units -= 4) < 0) break bytes.push( codePoint >> 0x12 | 0xF0, codePoint >> 0xC & 0x3F | 0x80, codePoint >> 0x6 & 0x3F | 0x80, codePoint & 0x3F | 0x80 ) } else { throw new Error('Invalid code point') } } return bytes } function asciiToBytes (str) { var byteArray = [] for (var i = 0; i < str.length; ++i) { // Node's code seems to be doing this and not & 0x7F.. byteArray.push(str.charCodeAt(i) & 0xFF) } return byteArray } function utf16leToBytes (str, units) { var c, hi, lo var byteArray = [] for (var i = 0; i < str.length; ++i) { if ((units -= 2) < 0) break c = str.charCodeAt(i) hi = c >> 8 lo = c % 256 byteArray.push(lo) byteArray.push(hi) } return byteArray } function base64ToBytes (str) { return base64.toByteArray(base64clean(str)) } function blitBuffer (src, dst, offset, length) { for (var i = 0; i < length; ++i) { if ((i + offset >= dst.length) || (i >= src.length)) break dst[i + offset] = src[i] } return i } function isnan (val) { return val !== val // eslint-disable-line no-self-compare } },{"base64-js":19,"ieee754":21}],21:[function(require,module,exports){ exports.read = function (buffer, offset, isLE, mLen, nBytes) { var e, m var eLen = nBytes * 8 - mLen - 1 var eMax = (1 << eLen) - 1 var eBias = eMax >> 1 var nBits = -7 var i = isLE ? (nBytes - 1) : 0 var d = isLE ? -1 : 1 var s = buffer[offset + i] i += d e = s & ((1 << (-nBits)) - 1) s >>= (-nBits) nBits += eLen for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} m = e & ((1 << (-nBits)) - 1) e >>= (-nBits) nBits += mLen for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} if (e === 0) { e = 1 - eBias } else if (e === eMax) { return m ? NaN : ((s ? -1 : 1) * Infinity) } else { m = m + Math.pow(2, mLen) e = e - eBias } return (s ? -1 : 1) * m * Math.pow(2, e - mLen) } exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { var e, m, c var eLen = nBytes * 8 - mLen - 1 var eMax = (1 << eLen) - 1 var eBias = eMax >> 1 var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) var i = isLE ? 0 : (nBytes - 1) var d = isLE ? 1 : -1 var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 value = Math.abs(value) if (isNaN(value) || value === Infinity) { m = isNaN(value) ? 1 : 0 e = eMax } else { e = Math.floor(Math.log(value) / Math.LN2) if (value * (c = Math.pow(2, -e)) < 1) { e-- c *= 2 } if (e + eBias >= 1) { value += rt / c } else { value += rt * Math.pow(2, 1 - eBias) } if (value * c >= 2) { e++ c /= 2 } if (e + eBias >= eMax) { m = 0 e = eMax } else if (e + eBias >= 1) { m = (value * c - 1) * Math.pow(2, mLen) e = e + eBias } else { m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) e = 0 } } for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} e = (e << mLen) | m eLen += mLen for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} buffer[offset + i - d] |= s * 128 } },{}],22:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; // If obj.hasOwnProperty has been overridden, then calling // obj.hasOwnProperty(prop) will break. // See: https://github.com/joyent/node/issues/1707 function hasOwnProperty(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } module.exports = function(qs, sep, eq, options) { sep = sep || '&'; eq = eq || '='; var obj = {}; if (typeof qs !== 'string' || qs.length === 0) { return obj; } var regexp = /\+/g; qs = qs.split(sep); var maxKeys = 1000; if (options && typeof options.maxKeys === 'number') { maxKeys = options.maxKeys; } var len = qs.length; // maxKeys <= 0 means that we should not limit keys count if (maxKeys > 0 && len > maxKeys) { len = maxKeys; } for (var i = 0; i < len; ++i) { var x = qs[i].replace(regexp, '%20'), idx = x.indexOf(eq), kstr, vstr, k, v; if (idx >= 0) { kstr = x.substr(0, idx); vstr = x.substr(idx + 1); } else { kstr = x; vstr = ''; } k = decodeURIComponent(kstr); v = decodeURIComponent(vstr); if (!hasOwnProperty(obj, k)) { obj[k] = v; } else if (isArray(obj[k])) { obj[k].push(v); } else { obj[k] = [obj[k], v]; } } return obj; }; var isArray = Array.isArray || function (xs) { return Object.prototype.toString.call(xs) === '[object Array]'; }; },{}],23:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; var stringifyPrimitive = function(v) { switch (typeof v) { case 'string': return v; case 'boolean': return v ? 'true' : 'false'; case 'number': return isFinite(v) ? v : ''; default: return ''; } }; module.exports = function(obj, sep, eq, name) { sep = sep || '&'; eq = eq || '='; if (obj === null) { obj = undefined; } if (typeof obj === 'object') { return map(objectKeys(obj), function(k) { var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; if (isArray(obj[k])) { return map(obj[k], function(v) { return ks + encodeURIComponent(stringifyPrimitive(v)); }).join(sep); } else { return ks + encodeURIComponent(stringifyPrimitive(obj[k])); } }).join(sep); } if (!name) return ''; return encodeURIComponent(stringifyPrimitive(name)) + eq + encodeURIComponent(stringifyPrimitive(obj)); }; var isArray = Array.isArray || function (xs) { return Object.prototype.toString.call(xs) === '[object Array]'; }; function map (xs, f) { if (xs.map) return xs.map(f); var res = []; for (var i = 0; i < xs.length; i++) { res.push(f(xs[i], i)); } return res; } var objectKeys = Object.keys || function (obj) { var res = []; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); } return res; }; },{}],24:[function(require,module,exports){ 'use strict'; exports.decode = exports.parse = require('./decode'); exports.encode = exports.stringify = require('./encode'); },{"./decode":22,"./encode":23}]},{},[1])(1) });