Files

5299 lines
144 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
(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<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var SCSocket = require('./lib/scsocket');
var SCSocketCreator = require('./lib/scsocketcreator');
module.exports.SCSocketCreator = SCSocketCreator;
module.exports.SCSocket = SCSocket;
module.exports.SCEmitter = require('sc-emitter').SCEmitter;
module.exports.connect = function (options) {
return SCSocketCreator.connect(options);
};
module.exports.destroy = function (options) {
return SCSocketCreator.destroy(options);
};
module.exports.connections = SCSocketCreator.connections;
module.exports.version = '5.5.2';
},{"./lib/scsocket":4,"./lib/scsocketcreator":5,"sc-emitter":14}],2:[function(require,module,exports){
(function (global){
var AuthEngine = function () {
this._internalStorage = {};
};
AuthEngine.prototype._isLocalStorageEnabled = function () {
var err;
try {
// Some browsers will throw an error here if localStorage is disabled.
global.localStorage;
// Safari, in Private Browsing Mode, looks like it supports localStorage but all calls to setItem
// throw QuotaExceededError. We're going to detect this and avoid hard to debug edge cases.
global.localStorage.setItem('__scLocalStorageTest', 1);
global.localStorage.removeItem('__scLocalStorageTest');
} catch (e) {
err = e;
}
return !err;
};
AuthEngine.prototype.saveToken = function (name, token, options, callback) {
if (this._isLocalStorageEnabled() && global.localStorage) {
global.localStorage.setItem(name, token);
} else {
this._internalStorage[name] = token;
}
callback && callback(null, token);
};
AuthEngine.prototype.removeToken = function (name, callback) {
var token;
this.loadToken(name, function (err, authToken) {
token = authToken;
});
if (this._isLocalStorageEnabled() && global.localStorage) {
global.localStorage.removeItem(name);
}
delete this._internalStorage[name];
callback && callback(null, token);
};
AuthEngine.prototype.loadToken = function (name, callback) {
var token;
if (this._isLocalStorageEnabled() && global.localStorage) {
token = global.localStorage.getItem(name);
} else {
token = this._internalStorage[name] || null;
}
callback(null, token);
};
module.exports.AuthEngine = AuthEngine;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],3:[function(require,module,exports){
var scErrors = require('sc-errors');
var InvalidActionError = scErrors.InvalidActionError;
var Response = function (socket, id) {
this.socket = socket;
this.id = id;
this.sent = false;
};
Response.prototype._respond = function (responseData) {
if (this.sent) {
throw new InvalidActionError('Response ' + this.id + ' has already been sent');
} else {
this.sent = true;
this.socket.send(this.socket.encode(responseData));
}
};
Response.prototype.end = function (data) {
if (this.id) {
var responseData = {
rid: this.id
};
if (data !== undefined) {
responseData.data = data;
}
this._respond(responseData);
}
};
Response.prototype.error = function (error, data) {
if (this.id) {
var err = scErrors.dehydrateError(error);
var responseData = {
rid: this.id,
error: err
};
if (data !== undefined) {
responseData.data = data;
}
this._respond(responseData);
}
};
Response.prototype.callback = function (error, data) {
if (error) {
this.error(error, data);
} else {
this.end(data);
}
};
module.exports.Response = Response;
},{"sc-errors":17}],4:[function(require,module,exports){
(function (global,Buffer){
var SCEmitter = require('sc-emitter').SCEmitter;
var SCChannel = require('sc-channel').SCChannel;
var Response = require('./response').Response;
var AuthEngine = require('./auth').AuthEngine;
var formatter = require('sc-formatter');
var SCTransport = require('./sctransport').SCTransport;
var querystring = require('querystring');
var LinkedList = require('linked-list');
var base64 = require('base-64');
var clone = require('clone');
var scErrors = require('sc-errors');
var InvalidArgumentsError = scErrors.InvalidArgumentsError;
var InvalidMessageError = scErrors.InvalidMessageError;
var SocketProtocolError = scErrors.SocketProtocolError;
var TimeoutError = scErrors.TimeoutError;
var isBrowser = typeof window != 'undefined';
var SCSocket = function (opts) {
var self = this;
SCEmitter.call(this);
this.id = null;
this.state = this.CLOSED;
this.authState = this.PENDING;
this.signedAuthToken = null;
this.authToken = null;
this.pendingReconnect = false;
this.pendingReconnectTimeout = null;
this.pendingConnectCallback = false;
this.connectTimeout = opts.connectTimeout;
this.ackTimeout = opts.ackTimeout;
this.channelPrefix = opts.channelPrefix || null;
this.disconnectOnUnload = opts.disconnectOnUnload == null ? true : opts.disconnectOnUnload;
// pingTimeout will be ackTimeout at the start, but it will
// be updated with values provided by the 'connect' event
this.pingTimeout = this.ackTimeout;
var maxTimeout = Math.pow(2, 31) - 1;
var verifyDuration = function (propertyName) {
if (self[propertyName] > 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 <feross@feross.org> <http://feross.org>
* @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 ' + str + '>'
}
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)
});