diff --git a/CHANGELOG.md b/CHANGELOG.md index 44c08d4d83..9651a08d96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ This contains only the most important and/or user-facing changes; for a full changelog, see the commit history. +## [1.0.4](https://github.com/ably/ably-js/tree/1.0.4) (2017-04-24) + +- Have the default logHandler on node log timestamps (https://github.com/ably/ably-js/issues/399) + +- Don't require Ably-protocol-level heartbeats by default on node (https://github.com/ably/ably-js/pull/398) + +- Cherry-pick syncComplete fn->bool and other changes and fixes from 0.9 branch that didn't make it into 1.0.0 + ## [1.0.3](https://github.com/ably/ably-js/tree/1.0.3) (2017-04-17) - Improved NativeScript supprot [\#392](https://github.com/ably/ably-js/pull/392) diff --git a/README.md b/README.md index c6d4247795..723b215e91 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A Javascript client library for [Ably Realtime](https://www.ably.io), a realtime data delivery platform. -## Version: 1.0.3 +## Version: 1.0.4 This repo contains the Ably Javascript client library, for the browser (including IE8+), Nodejs, React Native, NativeScript and Cordova. diff --git a/bower.json b/bower.json index 73a2bbd06d..6afb607276 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "Ably", - "version": "1.0.3", + "version": "1.0.4", "homepage": "https://www.ably.io/", "authors": [ "Paddy Byers ", diff --git a/browser/fragments/license.js b/browser/fragments/license.js index 3760ba2c06..0f2e361176 100644 --- a/browser/fragments/license.js +++ b/browser/fragments/license.js @@ -1,7 +1,7 @@ /** * @license Copyright 2017, Ably * - * Ably JavaScript Library v1.0.3 + * Ably JavaScript Library v1.0.4 * https://github.com/ably/ably-js * * Ably Realtime Messaging diff --git a/browser/static/ably-commonjs.js b/browser/static/ably-commonjs.js index e4b7b96ed7..3934d4af19 100644 --- a/browser/static/ably-commonjs.js +++ b/browser/static/ably-commonjs.js @@ -1,7 +1,7 @@ /** * @license Copyright 2017, Ably * - * Ably JavaScript Library v1.0.3 + * Ably JavaScript Library v1.0.4 * https://github.com/ably/ably-js * * Ably Realtime Messaging @@ -4079,7 +4079,7 @@ Defaults.TIMEOUTS = { }; Defaults.httpMaxRetryCount = 3; -Defaults.version = '1.0.3'; +Defaults.version = '1.0.4'; Defaults.libstring = Platform.libver + Defaults.version; Defaults.apiVersion = '1.0'; @@ -4402,6 +4402,10 @@ var Logger = (function() { consoleLogger = function() {}; } + function pad(str, three) { + return ('000' + str).slice(-2-(three || 0)); + } + var LOG_NONE = 0, LOG_ERROR = 1, LOG_MAJOR = 2, @@ -4412,7 +4416,11 @@ var Logger = (function() { LOG_DEBUG = LOG_MICRO; var logLevel = LOG_DEFAULT; - var logHandler = consoleLogger; + var logHandler = Platform.logTimestamps ? + function(msg) { + var time = new Date(); + consoleLogger(pad(time.getHours()) + ':' + pad(time.getMinutes()) + ':' + pad(time.getSeconds()) + '.' + pad(time.getMilliseconds(), true) + ' ' + msg); + } : consoleLogger; /* public constructor */ function Logger(args) {} @@ -5815,6 +5823,7 @@ var ConnectionManager = (function() { this.host = null; this.lastAutoReconnectAttempt = null; this.lastActivity = null; + this.mostRecentMsgId = null; Logger.logAction(Logger.LOG_MINOR, 'Realtime.ConnectionManager()', 'started'); Logger.logAction(Logger.LOG_MICRO, 'Realtime.ConnectionManager()', 'requested transports = [' + (options.transports || Defaults.defaultTransports) + ']'); @@ -7069,6 +7078,12 @@ var ConnectionManager = (function() { this.realtime.connection.serial = this.connectionSerial = connectionSerial; this.realtime.connection.recoveryKey = this.connectionKey + ':' + connectionSerial; } + var msgId = message.id; + if(msgId && (msgId === this.mostRecentMsgId)) { + Logger.logAction(Logger.LOG_ERROR, 'ConnectionManager.onChannelMessage() received message with different connectionSerial, but same message id as a previous; discarding; id = ' + msgId); + return; + } + this.mostRecentMsgId = msgId; this.realtime.channels.onChannelMessage(message); } else { // Message came in on a defunct transport. Allow only acks, nacks, & errors for outstanding @@ -7285,10 +7300,7 @@ var Transport = (function() { if (Logger.shouldLog(Logger.LOG_MICRO)) { Logger.logAction(Logger.LOG_MICRO, 'Transport.onProtocolMessage()', 'received on ' + this.shortName + ': ' + ProtocolMessage.stringify(message)); } - this.lastActivity = this.connectionManager.lastActivity = Utils.now(); - if(this.maxIdleInterval) { - this.setIdleTimer(); - } + this.onActivity(); switch(message.action) { case actions.HEARTBEAT: @@ -7347,7 +7359,7 @@ var Transport = (function() { var maxPromisedIdle = message.connectionDetails.maxIdleInterval; if(maxPromisedIdle) { this.maxIdleInterval = maxPromisedIdle + this.timeouts.realtimeRequestTimeout; - this.setIdleTimer(); + this.onActivity(); } /* else Realtime declines to guarantee any maximum idle interval - CD2h */ }; @@ -7396,7 +7408,10 @@ var Transport = (function() { this.off(); }; - Transport.prototype.setIdleTimer = function(timeout) { + Transport.prototype.onActivity = function(timeout) { + if(!this.maxIdleInterval) { return; } + + this.lastActivity = this.connectionManager.lastActivity = Utils.now(); var self = this; if(!this.idleTimer) { this.idleTimer = setTimeout(function() { @@ -7414,7 +7429,7 @@ var Transport = (function() { Logger.logAction(Logger.LOG_ERROR, 'Transport.onIdleTimerExpire()', msg); this.disconnect(new ErrorInfo(msg, 80003, 408)); } else { - this.setIdleTimer(timeRemaining + 10); + this.onActivity(timeRemaining + 10); } }; @@ -7495,7 +7510,7 @@ var WebSocketTransport = (function() { if(wsConnection.on) { /* node; browsers currently don't have a general eventemitter and can't detect * pings. Also, no need to reply with a pong explicitly, ws lib handles that */ - wsConnection.on('ping', function() { self.setIdleTimer() }); + wsConnection.on('ping', function() { self.onActivity(); }); } } catch(e) { Logger.logAction(Logger.LOG_ERROR, 'WebSocketTransport.connect()', 'Unexpected exception creating websocket: err = ' + (e.stack || e.message)); @@ -7510,7 +7525,15 @@ var WebSocketTransport = (function() { Logger.logAction(Logger.LOG_ERROR, 'WebSocketTransport.send()', 'No socket connection'); return; } - wsConnection.send(ProtocolMessage.serialize(message, this.params.format)); + try { + wsConnection.send(ProtocolMessage.serialize(message, this.params.format)); + } catch (e) { + var msg = 'Exception from ws connection when trying to send: ' + Utils.inspectError(e); + Logger.logAction(Logger.LOG_ERROR, 'WebSocketTransport.send()', msg); + /* Don't try to request a disconnect, that'll just involve sending data + * down the websocket again. Just finish the transport. */ + this.finish('disconnected', new ErrorInfo(msg, 50000, 500)); + } }; WebSocketTransport.prototype.onWsData = function(data) { @@ -7695,9 +7718,7 @@ var CometTransport = (function() { err = err || new ErrorInfo('Request cancelled', 80000, 400); } self.recvRequest = null; - if(this.maxIdleInterval) { - this.setIdleTimer(); - } + self.onActivity(); if(err) { if(err.code) { /* A protocol error received from realtime. TODO: once realtime @@ -7860,11 +7881,9 @@ var CometTransport = (function() { }); recvRequest.on('complete', function(err) { self.recvRequest = null; - if(this.maxIdleInterval) { - /* A request completing must be considered activity, as realtime sends - * heartbeats every 15s since a request began, not every 15s absolutely */ - this.setIdleTimer(); - } + /* A request completing must be considered activity, as realtime sends + * heartbeats every 15s since a request began, not every 15s absolutely */ + self.onActivity(); if(err) { if(err.code) { /* A protocol error received from realtime. TODO: once realtime @@ -10152,6 +10171,7 @@ var RealtimePresence = (function() { function RealtimePresence(channel, options) { Presence.call(this, channel); + this.syncComplete = false; this.members = new PresenceMap(this); this._myMembers = new PresenceMap(this); this.subscriptions = new EventEmitter(); @@ -10532,10 +10552,6 @@ var RealtimePresence = (function() { this.subscriptions.off(event, listener); }; - RealtimePresence.prototype.syncComplete = function() { - return !this.members.syncInProgress; - }; - function PresenceMap(presence) { EventEmitter.call(this); this.presence = presence; @@ -10647,7 +10663,7 @@ var RealtimePresence = (function() { /* we might be called multiple times while a sync is in progress */ if(!this.syncInProgress) { this.residualMembers = Utils.copy(map); - this.syncInProgress = true; + this.setInProgress(true); } }; @@ -10672,7 +10688,7 @@ var RealtimePresence = (function() { this.residualMembers = null; /* finish, notifying any waiters */ - this.syncInProgress = false; + this.setInProgress(false); } this.emit('sync'); }; @@ -10689,10 +10705,16 @@ var RealtimePresence = (function() { PresenceMap.prototype.clear = function(callback) { this.map = {}; - this.syncInProgress = false; + this.setInProgress(false); this.residualMembers = null; }; + PresenceMap.prototype.setInProgress = function(inProgress) { + Logger.logAction(Logger.LOG_MICRO, 'PresenceMap.setInProgress()', 'inProgress = ' + inProgress); + this.syncInProgress = inProgress; + this.presence.syncComplete = !inProgress; + }; + return RealtimePresence; })(); diff --git a/browser/static/ably-commonjs.noencryption.js b/browser/static/ably-commonjs.noencryption.js index 00f8cbb3fb..aff756c08a 100644 --- a/browser/static/ably-commonjs.noencryption.js +++ b/browser/static/ably-commonjs.noencryption.js @@ -1,7 +1,7 @@ /** * @license Copyright 2017, Ably * - * Ably JavaScript Library v1.0.3 + * Ably JavaScript Library v1.0.4 * https://github.com/ably/ably-js * * Ably Realtime Messaging @@ -2647,7 +2647,7 @@ Defaults.TIMEOUTS = { }; Defaults.httpMaxRetryCount = 3; -Defaults.version = '1.0.3'; +Defaults.version = '1.0.4'; Defaults.libstring = Platform.libver + Defaults.version; Defaults.apiVersion = '1.0'; @@ -2970,6 +2970,10 @@ var Logger = (function() { consoleLogger = function() {}; } + function pad(str, three) { + return ('000' + str).slice(-2-(three || 0)); + } + var LOG_NONE = 0, LOG_ERROR = 1, LOG_MAJOR = 2, @@ -2980,7 +2984,11 @@ var Logger = (function() { LOG_DEBUG = LOG_MICRO; var logLevel = LOG_DEFAULT; - var logHandler = consoleLogger; + var logHandler = Platform.logTimestamps ? + function(msg) { + var time = new Date(); + consoleLogger(pad(time.getHours()) + ':' + pad(time.getMinutes()) + ':' + pad(time.getSeconds()) + '.' + pad(time.getMilliseconds(), true) + ' ' + msg); + } : consoleLogger; /* public constructor */ function Logger(args) {} @@ -4383,6 +4391,7 @@ var ConnectionManager = (function() { this.host = null; this.lastAutoReconnectAttempt = null; this.lastActivity = null; + this.mostRecentMsgId = null; Logger.logAction(Logger.LOG_MINOR, 'Realtime.ConnectionManager()', 'started'); Logger.logAction(Logger.LOG_MICRO, 'Realtime.ConnectionManager()', 'requested transports = [' + (options.transports || Defaults.defaultTransports) + ']'); @@ -5637,6 +5646,12 @@ var ConnectionManager = (function() { this.realtime.connection.serial = this.connectionSerial = connectionSerial; this.realtime.connection.recoveryKey = this.connectionKey + ':' + connectionSerial; } + var msgId = message.id; + if(msgId && (msgId === this.mostRecentMsgId)) { + Logger.logAction(Logger.LOG_ERROR, 'ConnectionManager.onChannelMessage() received message with different connectionSerial, but same message id as a previous; discarding; id = ' + msgId); + return; + } + this.mostRecentMsgId = msgId; this.realtime.channels.onChannelMessage(message); } else { // Message came in on a defunct transport. Allow only acks, nacks, & errors for outstanding @@ -5853,10 +5868,7 @@ var Transport = (function() { if (Logger.shouldLog(Logger.LOG_MICRO)) { Logger.logAction(Logger.LOG_MICRO, 'Transport.onProtocolMessage()', 'received on ' + this.shortName + ': ' + ProtocolMessage.stringify(message)); } - this.lastActivity = this.connectionManager.lastActivity = Utils.now(); - if(this.maxIdleInterval) { - this.setIdleTimer(); - } + this.onActivity(); switch(message.action) { case actions.HEARTBEAT: @@ -5915,7 +5927,7 @@ var Transport = (function() { var maxPromisedIdle = message.connectionDetails.maxIdleInterval; if(maxPromisedIdle) { this.maxIdleInterval = maxPromisedIdle + this.timeouts.realtimeRequestTimeout; - this.setIdleTimer(); + this.onActivity(); } /* else Realtime declines to guarantee any maximum idle interval - CD2h */ }; @@ -5964,7 +5976,10 @@ var Transport = (function() { this.off(); }; - Transport.prototype.setIdleTimer = function(timeout) { + Transport.prototype.onActivity = function(timeout) { + if(!this.maxIdleInterval) { return; } + + this.lastActivity = this.connectionManager.lastActivity = Utils.now(); var self = this; if(!this.idleTimer) { this.idleTimer = setTimeout(function() { @@ -5982,7 +5997,7 @@ var Transport = (function() { Logger.logAction(Logger.LOG_ERROR, 'Transport.onIdleTimerExpire()', msg); this.disconnect(new ErrorInfo(msg, 80003, 408)); } else { - this.setIdleTimer(timeRemaining + 10); + this.onActivity(timeRemaining + 10); } }; @@ -6063,7 +6078,7 @@ var WebSocketTransport = (function() { if(wsConnection.on) { /* node; browsers currently don't have a general eventemitter and can't detect * pings. Also, no need to reply with a pong explicitly, ws lib handles that */ - wsConnection.on('ping', function() { self.setIdleTimer() }); + wsConnection.on('ping', function() { self.onActivity(); }); } } catch(e) { Logger.logAction(Logger.LOG_ERROR, 'WebSocketTransport.connect()', 'Unexpected exception creating websocket: err = ' + (e.stack || e.message)); @@ -6078,7 +6093,15 @@ var WebSocketTransport = (function() { Logger.logAction(Logger.LOG_ERROR, 'WebSocketTransport.send()', 'No socket connection'); return; } - wsConnection.send(ProtocolMessage.serialize(message, this.params.format)); + try { + wsConnection.send(ProtocolMessage.serialize(message, this.params.format)); + } catch (e) { + var msg = 'Exception from ws connection when trying to send: ' + Utils.inspectError(e); + Logger.logAction(Logger.LOG_ERROR, 'WebSocketTransport.send()', msg); + /* Don't try to request a disconnect, that'll just involve sending data + * down the websocket again. Just finish the transport. */ + this.finish('disconnected', new ErrorInfo(msg, 50000, 500)); + } }; WebSocketTransport.prototype.onWsData = function(data) { @@ -6263,9 +6286,7 @@ var CometTransport = (function() { err = err || new ErrorInfo('Request cancelled', 80000, 400); } self.recvRequest = null; - if(this.maxIdleInterval) { - this.setIdleTimer(); - } + self.onActivity(); if(err) { if(err.code) { /* A protocol error received from realtime. TODO: once realtime @@ -6428,11 +6449,9 @@ var CometTransport = (function() { }); recvRequest.on('complete', function(err) { self.recvRequest = null; - if(this.maxIdleInterval) { - /* A request completing must be considered activity, as realtime sends - * heartbeats every 15s since a request began, not every 15s absolutely */ - this.setIdleTimer(); - } + /* A request completing must be considered activity, as realtime sends + * heartbeats every 15s since a request began, not every 15s absolutely */ + self.onActivity(); if(err) { if(err.code) { /* A protocol error received from realtime. TODO: once realtime @@ -8720,6 +8739,7 @@ var RealtimePresence = (function() { function RealtimePresence(channel, options) { Presence.call(this, channel); + this.syncComplete = false; this.members = new PresenceMap(this); this._myMembers = new PresenceMap(this); this.subscriptions = new EventEmitter(); @@ -9100,10 +9120,6 @@ var RealtimePresence = (function() { this.subscriptions.off(event, listener); }; - RealtimePresence.prototype.syncComplete = function() { - return !this.members.syncInProgress; - }; - function PresenceMap(presence) { EventEmitter.call(this); this.presence = presence; @@ -9215,7 +9231,7 @@ var RealtimePresence = (function() { /* we might be called multiple times while a sync is in progress */ if(!this.syncInProgress) { this.residualMembers = Utils.copy(map); - this.syncInProgress = true; + this.setInProgress(true); } }; @@ -9240,7 +9256,7 @@ var RealtimePresence = (function() { this.residualMembers = null; /* finish, notifying any waiters */ - this.syncInProgress = false; + this.setInProgress(false); } this.emit('sync'); }; @@ -9257,10 +9273,16 @@ var RealtimePresence = (function() { PresenceMap.prototype.clear = function(callback) { this.map = {}; - this.syncInProgress = false; + this.setInProgress(false); this.residualMembers = null; }; + PresenceMap.prototype.setInProgress = function(inProgress) { + Logger.logAction(Logger.LOG_MICRO, 'PresenceMap.setInProgress()', 'inProgress = ' + inProgress); + this.syncInProgress = inProgress; + this.presence.syncComplete = !inProgress; + }; + return RealtimePresence; })(); diff --git a/browser/static/ably-nativescript.js b/browser/static/ably-nativescript.js index 7c54210170..5bbae6769a 100644 --- a/browser/static/ably-nativescript.js +++ b/browser/static/ably-nativescript.js @@ -1,7 +1,7 @@ /** * @license Copyright 2017, Ably * - * Ably JavaScript Library v1.0.3 + * Ably JavaScript Library v1.0.4 * https://github.com/ably/ably-js * * Ably Realtime Messaging @@ -4021,7 +4021,7 @@ Defaults.TIMEOUTS = { }; Defaults.httpMaxRetryCount = 3; -Defaults.version = '1.0.3'; +Defaults.version = '1.0.4'; Defaults.libstring = Platform.libver + Defaults.version; Defaults.apiVersion = '1.0'; @@ -4344,6 +4344,10 @@ var Logger = (function() { consoleLogger = function() {}; } + function pad(str, three) { + return ('000' + str).slice(-2-(three || 0)); + } + var LOG_NONE = 0, LOG_ERROR = 1, LOG_MAJOR = 2, @@ -4354,7 +4358,11 @@ var Logger = (function() { LOG_DEBUG = LOG_MICRO; var logLevel = LOG_DEFAULT; - var logHandler = consoleLogger; + var logHandler = Platform.logTimestamps ? + function(msg) { + var time = new Date(); + consoleLogger(pad(time.getHours()) + ':' + pad(time.getMinutes()) + ':' + pad(time.getSeconds()) + '.' + pad(time.getMilliseconds(), true) + ' ' + msg); + } : consoleLogger; /* public constructor */ function Logger(args) {} @@ -5757,6 +5765,7 @@ var ConnectionManager = (function() { this.host = null; this.lastAutoReconnectAttempt = null; this.lastActivity = null; + this.mostRecentMsgId = null; Logger.logAction(Logger.LOG_MINOR, 'Realtime.ConnectionManager()', 'started'); Logger.logAction(Logger.LOG_MICRO, 'Realtime.ConnectionManager()', 'requested transports = [' + (options.transports || Defaults.defaultTransports) + ']'); @@ -7011,6 +7020,12 @@ var ConnectionManager = (function() { this.realtime.connection.serial = this.connectionSerial = connectionSerial; this.realtime.connection.recoveryKey = this.connectionKey + ':' + connectionSerial; } + var msgId = message.id; + if(msgId && (msgId === this.mostRecentMsgId)) { + Logger.logAction(Logger.LOG_ERROR, 'ConnectionManager.onChannelMessage() received message with different connectionSerial, but same message id as a previous; discarding; id = ' + msgId); + return; + } + this.mostRecentMsgId = msgId; this.realtime.channels.onChannelMessage(message); } else { // Message came in on a defunct transport. Allow only acks, nacks, & errors for outstanding @@ -7227,10 +7242,7 @@ var Transport = (function() { if (Logger.shouldLog(Logger.LOG_MICRO)) { Logger.logAction(Logger.LOG_MICRO, 'Transport.onProtocolMessage()', 'received on ' + this.shortName + ': ' + ProtocolMessage.stringify(message)); } - this.lastActivity = this.connectionManager.lastActivity = Utils.now(); - if(this.maxIdleInterval) { - this.setIdleTimer(); - } + this.onActivity(); switch(message.action) { case actions.HEARTBEAT: @@ -7289,7 +7301,7 @@ var Transport = (function() { var maxPromisedIdle = message.connectionDetails.maxIdleInterval; if(maxPromisedIdle) { this.maxIdleInterval = maxPromisedIdle + this.timeouts.realtimeRequestTimeout; - this.setIdleTimer(); + this.onActivity(); } /* else Realtime declines to guarantee any maximum idle interval - CD2h */ }; @@ -7338,7 +7350,10 @@ var Transport = (function() { this.off(); }; - Transport.prototype.setIdleTimer = function(timeout) { + Transport.prototype.onActivity = function(timeout) { + if(!this.maxIdleInterval) { return; } + + this.lastActivity = this.connectionManager.lastActivity = Utils.now(); var self = this; if(!this.idleTimer) { this.idleTimer = setTimeout(function() { @@ -7356,7 +7371,7 @@ var Transport = (function() { Logger.logAction(Logger.LOG_ERROR, 'Transport.onIdleTimerExpire()', msg); this.disconnect(new ErrorInfo(msg, 80003, 408)); } else { - this.setIdleTimer(timeRemaining + 10); + this.onActivity(timeRemaining + 10); } }; @@ -7437,7 +7452,7 @@ var WebSocketTransport = (function() { if(wsConnection.on) { /* node; browsers currently don't have a general eventemitter and can't detect * pings. Also, no need to reply with a pong explicitly, ws lib handles that */ - wsConnection.on('ping', function() { self.setIdleTimer() }); + wsConnection.on('ping', function() { self.onActivity(); }); } } catch(e) { Logger.logAction(Logger.LOG_ERROR, 'WebSocketTransport.connect()', 'Unexpected exception creating websocket: err = ' + (e.stack || e.message)); @@ -7452,7 +7467,15 @@ var WebSocketTransport = (function() { Logger.logAction(Logger.LOG_ERROR, 'WebSocketTransport.send()', 'No socket connection'); return; } - wsConnection.send(ProtocolMessage.serialize(message, this.params.format)); + try { + wsConnection.send(ProtocolMessage.serialize(message, this.params.format)); + } catch (e) { + var msg = 'Exception from ws connection when trying to send: ' + Utils.inspectError(e); + Logger.logAction(Logger.LOG_ERROR, 'WebSocketTransport.send()', msg); + /* Don't try to request a disconnect, that'll just involve sending data + * down the websocket again. Just finish the transport. */ + this.finish('disconnected', new ErrorInfo(msg, 50000, 500)); + } }; WebSocketTransport.prototype.onWsData = function(data) { @@ -7637,9 +7660,7 @@ var CometTransport = (function() { err = err || new ErrorInfo('Request cancelled', 80000, 400); } self.recvRequest = null; - if(this.maxIdleInterval) { - this.setIdleTimer(); - } + self.onActivity(); if(err) { if(err.code) { /* A protocol error received from realtime. TODO: once realtime @@ -7802,11 +7823,9 @@ var CometTransport = (function() { }); recvRequest.on('complete', function(err) { self.recvRequest = null; - if(this.maxIdleInterval) { - /* A request completing must be considered activity, as realtime sends - * heartbeats every 15s since a request began, not every 15s absolutely */ - this.setIdleTimer(); - } + /* A request completing must be considered activity, as realtime sends + * heartbeats every 15s since a request began, not every 15s absolutely */ + self.onActivity(); if(err) { if(err.code) { /* A protocol error received from realtime. TODO: once realtime @@ -10094,6 +10113,7 @@ var RealtimePresence = (function() { function RealtimePresence(channel, options) { Presence.call(this, channel); + this.syncComplete = false; this.members = new PresenceMap(this); this._myMembers = new PresenceMap(this); this.subscriptions = new EventEmitter(); @@ -10474,10 +10494,6 @@ var RealtimePresence = (function() { this.subscriptions.off(event, listener); }; - RealtimePresence.prototype.syncComplete = function() { - return !this.members.syncInProgress; - }; - function PresenceMap(presence) { EventEmitter.call(this); this.presence = presence; @@ -10589,7 +10605,7 @@ var RealtimePresence = (function() { /* we might be called multiple times while a sync is in progress */ if(!this.syncInProgress) { this.residualMembers = Utils.copy(map); - this.syncInProgress = true; + this.setInProgress(true); } }; @@ -10614,7 +10630,7 @@ var RealtimePresence = (function() { this.residualMembers = null; /* finish, notifying any waiters */ - this.syncInProgress = false; + this.setInProgress(false); } this.emit('sync'); }; @@ -10631,10 +10647,16 @@ var RealtimePresence = (function() { PresenceMap.prototype.clear = function(callback) { this.map = {}; - this.syncInProgress = false; + this.setInProgress(false); this.residualMembers = null; }; + PresenceMap.prototype.setInProgress = function(inProgress) { + Logger.logAction(Logger.LOG_MICRO, 'PresenceMap.setInProgress()', 'inProgress = ' + inProgress); + this.syncInProgress = inProgress; + this.presence.syncComplete = !inProgress; + }; + return RealtimePresence; })(); diff --git a/browser/static/ably-reactnative.js b/browser/static/ably-reactnative.js index 325c33f11f..f1897f343c 100644 --- a/browser/static/ably-reactnative.js +++ b/browser/static/ably-reactnative.js @@ -1,7 +1,7 @@ /** * @license Copyright 2017, Ably * - * Ably JavaScript Library v1.0.3 + * Ably JavaScript Library v1.0.4 * https://github.com/ably/ably-js * * Ably Realtime Messaging @@ -4050,7 +4050,7 @@ Defaults.TIMEOUTS = { }; Defaults.httpMaxRetryCount = 3; -Defaults.version = '1.0.3'; +Defaults.version = '1.0.4'; Defaults.libstring = Platform.libver + Defaults.version; Defaults.apiVersion = '1.0'; @@ -4373,6 +4373,10 @@ var Logger = (function() { consoleLogger = function() {}; } + function pad(str, three) { + return ('000' + str).slice(-2-(three || 0)); + } + var LOG_NONE = 0, LOG_ERROR = 1, LOG_MAJOR = 2, @@ -4383,7 +4387,11 @@ var Logger = (function() { LOG_DEBUG = LOG_MICRO; var logLevel = LOG_DEFAULT; - var logHandler = consoleLogger; + var logHandler = Platform.logTimestamps ? + function(msg) { + var time = new Date(); + consoleLogger(pad(time.getHours()) + ':' + pad(time.getMinutes()) + ':' + pad(time.getSeconds()) + '.' + pad(time.getMilliseconds(), true) + ' ' + msg); + } : consoleLogger; /* public constructor */ function Logger(args) {} @@ -5786,6 +5794,7 @@ var ConnectionManager = (function() { this.host = null; this.lastAutoReconnectAttempt = null; this.lastActivity = null; + this.mostRecentMsgId = null; Logger.logAction(Logger.LOG_MINOR, 'Realtime.ConnectionManager()', 'started'); Logger.logAction(Logger.LOG_MICRO, 'Realtime.ConnectionManager()', 'requested transports = [' + (options.transports || Defaults.defaultTransports) + ']'); @@ -7040,6 +7049,12 @@ var ConnectionManager = (function() { this.realtime.connection.serial = this.connectionSerial = connectionSerial; this.realtime.connection.recoveryKey = this.connectionKey + ':' + connectionSerial; } + var msgId = message.id; + if(msgId && (msgId === this.mostRecentMsgId)) { + Logger.logAction(Logger.LOG_ERROR, 'ConnectionManager.onChannelMessage() received message with different connectionSerial, but same message id as a previous; discarding; id = ' + msgId); + return; + } + this.mostRecentMsgId = msgId; this.realtime.channels.onChannelMessage(message); } else { // Message came in on a defunct transport. Allow only acks, nacks, & errors for outstanding @@ -7256,10 +7271,7 @@ var Transport = (function() { if (Logger.shouldLog(Logger.LOG_MICRO)) { Logger.logAction(Logger.LOG_MICRO, 'Transport.onProtocolMessage()', 'received on ' + this.shortName + ': ' + ProtocolMessage.stringify(message)); } - this.lastActivity = this.connectionManager.lastActivity = Utils.now(); - if(this.maxIdleInterval) { - this.setIdleTimer(); - } + this.onActivity(); switch(message.action) { case actions.HEARTBEAT: @@ -7318,7 +7330,7 @@ var Transport = (function() { var maxPromisedIdle = message.connectionDetails.maxIdleInterval; if(maxPromisedIdle) { this.maxIdleInterval = maxPromisedIdle + this.timeouts.realtimeRequestTimeout; - this.setIdleTimer(); + this.onActivity(); } /* else Realtime declines to guarantee any maximum idle interval - CD2h */ }; @@ -7367,7 +7379,10 @@ var Transport = (function() { this.off(); }; - Transport.prototype.setIdleTimer = function(timeout) { + Transport.prototype.onActivity = function(timeout) { + if(!this.maxIdleInterval) { return; } + + this.lastActivity = this.connectionManager.lastActivity = Utils.now(); var self = this; if(!this.idleTimer) { this.idleTimer = setTimeout(function() { @@ -7385,7 +7400,7 @@ var Transport = (function() { Logger.logAction(Logger.LOG_ERROR, 'Transport.onIdleTimerExpire()', msg); this.disconnect(new ErrorInfo(msg, 80003, 408)); } else { - this.setIdleTimer(timeRemaining + 10); + this.onActivity(timeRemaining + 10); } }; @@ -7466,7 +7481,7 @@ var WebSocketTransport = (function() { if(wsConnection.on) { /* node; browsers currently don't have a general eventemitter and can't detect * pings. Also, no need to reply with a pong explicitly, ws lib handles that */ - wsConnection.on('ping', function() { self.setIdleTimer() }); + wsConnection.on('ping', function() { self.onActivity(); }); } } catch(e) { Logger.logAction(Logger.LOG_ERROR, 'WebSocketTransport.connect()', 'Unexpected exception creating websocket: err = ' + (e.stack || e.message)); @@ -7481,7 +7496,15 @@ var WebSocketTransport = (function() { Logger.logAction(Logger.LOG_ERROR, 'WebSocketTransport.send()', 'No socket connection'); return; } - wsConnection.send(ProtocolMessage.serialize(message, this.params.format)); + try { + wsConnection.send(ProtocolMessage.serialize(message, this.params.format)); + } catch (e) { + var msg = 'Exception from ws connection when trying to send: ' + Utils.inspectError(e); + Logger.logAction(Logger.LOG_ERROR, 'WebSocketTransport.send()', msg); + /* Don't try to request a disconnect, that'll just involve sending data + * down the websocket again. Just finish the transport. */ + this.finish('disconnected', new ErrorInfo(msg, 50000, 500)); + } }; WebSocketTransport.prototype.onWsData = function(data) { @@ -7666,9 +7689,7 @@ var CometTransport = (function() { err = err || new ErrorInfo('Request cancelled', 80000, 400); } self.recvRequest = null; - if(this.maxIdleInterval) { - this.setIdleTimer(); - } + self.onActivity(); if(err) { if(err.code) { /* A protocol error received from realtime. TODO: once realtime @@ -7831,11 +7852,9 @@ var CometTransport = (function() { }); recvRequest.on('complete', function(err) { self.recvRequest = null; - if(this.maxIdleInterval) { - /* A request completing must be considered activity, as realtime sends - * heartbeats every 15s since a request began, not every 15s absolutely */ - this.setIdleTimer(); - } + /* A request completing must be considered activity, as realtime sends + * heartbeats every 15s since a request began, not every 15s absolutely */ + self.onActivity(); if(err) { if(err.code) { /* A protocol error received from realtime. TODO: once realtime @@ -10123,6 +10142,7 @@ var RealtimePresence = (function() { function RealtimePresence(channel, options) { Presence.call(this, channel); + this.syncComplete = false; this.members = new PresenceMap(this); this._myMembers = new PresenceMap(this); this.subscriptions = new EventEmitter(); @@ -10503,10 +10523,6 @@ var RealtimePresence = (function() { this.subscriptions.off(event, listener); }; - RealtimePresence.prototype.syncComplete = function() { - return !this.members.syncInProgress; - }; - function PresenceMap(presence) { EventEmitter.call(this); this.presence = presence; @@ -10618,7 +10634,7 @@ var RealtimePresence = (function() { /* we might be called multiple times while a sync is in progress */ if(!this.syncInProgress) { this.residualMembers = Utils.copy(map); - this.syncInProgress = true; + this.setInProgress(true); } }; @@ -10643,7 +10659,7 @@ var RealtimePresence = (function() { this.residualMembers = null; /* finish, notifying any waiters */ - this.syncInProgress = false; + this.setInProgress(false); } this.emit('sync'); }; @@ -10660,10 +10676,16 @@ var RealtimePresence = (function() { PresenceMap.prototype.clear = function(callback) { this.map = {}; - this.syncInProgress = false; + this.setInProgress(false); this.residualMembers = null; }; + PresenceMap.prototype.setInProgress = function(inProgress) { + Logger.logAction(Logger.LOG_MICRO, 'PresenceMap.setInProgress()', 'inProgress = ' + inProgress); + this.syncInProgress = inProgress; + this.presence.syncComplete = !inProgress; + }; + return RealtimePresence; })(); diff --git a/browser/static/ably.d.ts b/browser/static/ably.d.ts index e1d5840db6..c795c3b8f3 100644 --- a/browser/static/ably.d.ts +++ b/browser/static/ably.d.ts @@ -319,7 +319,7 @@ declare namespace ablyLib { } class RealtimePresence { - syncComplete: () => boolean; + syncComplete: boolean; get: (Params: realtimePresenceGetCallback | RealtimePresenceParams, callback?: realtimePresenceGetCallback) => void; history: (ParamsOrCallback: RealtimePresenceHistoryParams | paginatedResultCallback, callback?: paginatedResultCallback) => void; subscribe: (presenceOrCallback: PresenceAction | messageCallback, listener?: messageCallback) => void; diff --git a/browser/static/ably.js b/browser/static/ably.js index 511a3ce228..266517fab0 100644 --- a/browser/static/ably.js +++ b/browser/static/ably.js @@ -1,7 +1,7 @@ /** * @license Copyright 2017, Ably * - * Ably JavaScript Library v1.0.3 + * Ably JavaScript Library v1.0.4 * https://github.com/ably/ably-js * * Ably Realtime Messaging @@ -4090,7 +4090,7 @@ Defaults.TIMEOUTS = { }; Defaults.httpMaxRetryCount = 3; -Defaults.version = '1.0.3'; +Defaults.version = '1.0.4'; Defaults.libstring = Platform.libver + Defaults.version; Defaults.apiVersion = '1.0'; @@ -4413,6 +4413,10 @@ var Logger = (function() { consoleLogger = function() {}; } + function pad(str, three) { + return ('000' + str).slice(-2-(three || 0)); + } + var LOG_NONE = 0, LOG_ERROR = 1, LOG_MAJOR = 2, @@ -4423,7 +4427,11 @@ var Logger = (function() { LOG_DEBUG = LOG_MICRO; var logLevel = LOG_DEFAULT; - var logHandler = consoleLogger; + var logHandler = Platform.logTimestamps ? + function(msg) { + var time = new Date(); + consoleLogger(pad(time.getHours()) + ':' + pad(time.getMinutes()) + ':' + pad(time.getSeconds()) + '.' + pad(time.getMilliseconds(), true) + ' ' + msg); + } : consoleLogger; /* public constructor */ function Logger(args) {} @@ -5826,6 +5834,7 @@ var ConnectionManager = (function() { this.host = null; this.lastAutoReconnectAttempt = null; this.lastActivity = null; + this.mostRecentMsgId = null; Logger.logAction(Logger.LOG_MINOR, 'Realtime.ConnectionManager()', 'started'); Logger.logAction(Logger.LOG_MICRO, 'Realtime.ConnectionManager()', 'requested transports = [' + (options.transports || Defaults.defaultTransports) + ']'); @@ -7080,6 +7089,12 @@ var ConnectionManager = (function() { this.realtime.connection.serial = this.connectionSerial = connectionSerial; this.realtime.connection.recoveryKey = this.connectionKey + ':' + connectionSerial; } + var msgId = message.id; + if(msgId && (msgId === this.mostRecentMsgId)) { + Logger.logAction(Logger.LOG_ERROR, 'ConnectionManager.onChannelMessage() received message with different connectionSerial, but same message id as a previous; discarding; id = ' + msgId); + return; + } + this.mostRecentMsgId = msgId; this.realtime.channels.onChannelMessage(message); } else { // Message came in on a defunct transport. Allow only acks, nacks, & errors for outstanding @@ -7296,10 +7311,7 @@ var Transport = (function() { if (Logger.shouldLog(Logger.LOG_MICRO)) { Logger.logAction(Logger.LOG_MICRO, 'Transport.onProtocolMessage()', 'received on ' + this.shortName + ': ' + ProtocolMessage.stringify(message)); } - this.lastActivity = this.connectionManager.lastActivity = Utils.now(); - if(this.maxIdleInterval) { - this.setIdleTimer(); - } + this.onActivity(); switch(message.action) { case actions.HEARTBEAT: @@ -7358,7 +7370,7 @@ var Transport = (function() { var maxPromisedIdle = message.connectionDetails.maxIdleInterval; if(maxPromisedIdle) { this.maxIdleInterval = maxPromisedIdle + this.timeouts.realtimeRequestTimeout; - this.setIdleTimer(); + this.onActivity(); } /* else Realtime declines to guarantee any maximum idle interval - CD2h */ }; @@ -7407,7 +7419,10 @@ var Transport = (function() { this.off(); }; - Transport.prototype.setIdleTimer = function(timeout) { + Transport.prototype.onActivity = function(timeout) { + if(!this.maxIdleInterval) { return; } + + this.lastActivity = this.connectionManager.lastActivity = Utils.now(); var self = this; if(!this.idleTimer) { this.idleTimer = setTimeout(function() { @@ -7425,7 +7440,7 @@ var Transport = (function() { Logger.logAction(Logger.LOG_ERROR, 'Transport.onIdleTimerExpire()', msg); this.disconnect(new ErrorInfo(msg, 80003, 408)); } else { - this.setIdleTimer(timeRemaining + 10); + this.onActivity(timeRemaining + 10); } }; @@ -7506,7 +7521,7 @@ var WebSocketTransport = (function() { if(wsConnection.on) { /* node; browsers currently don't have a general eventemitter and can't detect * pings. Also, no need to reply with a pong explicitly, ws lib handles that */ - wsConnection.on('ping', function() { self.setIdleTimer() }); + wsConnection.on('ping', function() { self.onActivity(); }); } } catch(e) { Logger.logAction(Logger.LOG_ERROR, 'WebSocketTransport.connect()', 'Unexpected exception creating websocket: err = ' + (e.stack || e.message)); @@ -7521,7 +7536,15 @@ var WebSocketTransport = (function() { Logger.logAction(Logger.LOG_ERROR, 'WebSocketTransport.send()', 'No socket connection'); return; } - wsConnection.send(ProtocolMessage.serialize(message, this.params.format)); + try { + wsConnection.send(ProtocolMessage.serialize(message, this.params.format)); + } catch (e) { + var msg = 'Exception from ws connection when trying to send: ' + Utils.inspectError(e); + Logger.logAction(Logger.LOG_ERROR, 'WebSocketTransport.send()', msg); + /* Don't try to request a disconnect, that'll just involve sending data + * down the websocket again. Just finish the transport. */ + this.finish('disconnected', new ErrorInfo(msg, 50000, 500)); + } }; WebSocketTransport.prototype.onWsData = function(data) { @@ -7706,9 +7729,7 @@ var CometTransport = (function() { err = err || new ErrorInfo('Request cancelled', 80000, 400); } self.recvRequest = null; - if(this.maxIdleInterval) { - this.setIdleTimer(); - } + self.onActivity(); if(err) { if(err.code) { /* A protocol error received from realtime. TODO: once realtime @@ -7871,11 +7892,9 @@ var CometTransport = (function() { }); recvRequest.on('complete', function(err) { self.recvRequest = null; - if(this.maxIdleInterval) { - /* A request completing must be considered activity, as realtime sends - * heartbeats every 15s since a request began, not every 15s absolutely */ - this.setIdleTimer(); - } + /* A request completing must be considered activity, as realtime sends + * heartbeats every 15s since a request began, not every 15s absolutely */ + self.onActivity(); if(err) { if(err.code) { /* A protocol error received from realtime. TODO: once realtime @@ -10163,6 +10182,7 @@ var RealtimePresence = (function() { function RealtimePresence(channel, options) { Presence.call(this, channel); + this.syncComplete = false; this.members = new PresenceMap(this); this._myMembers = new PresenceMap(this); this.subscriptions = new EventEmitter(); @@ -10543,10 +10563,6 @@ var RealtimePresence = (function() { this.subscriptions.off(event, listener); }; - RealtimePresence.prototype.syncComplete = function() { - return !this.members.syncInProgress; - }; - function PresenceMap(presence) { EventEmitter.call(this); this.presence = presence; @@ -10658,7 +10674,7 @@ var RealtimePresence = (function() { /* we might be called multiple times while a sync is in progress */ if(!this.syncInProgress) { this.residualMembers = Utils.copy(map); - this.syncInProgress = true; + this.setInProgress(true); } }; @@ -10683,7 +10699,7 @@ var RealtimePresence = (function() { this.residualMembers = null; /* finish, notifying any waiters */ - this.syncInProgress = false; + this.setInProgress(false); } this.emit('sync'); }; @@ -10700,10 +10716,16 @@ var RealtimePresence = (function() { PresenceMap.prototype.clear = function(callback) { this.map = {}; - this.syncInProgress = false; + this.setInProgress(false); this.residualMembers = null; }; + PresenceMap.prototype.setInProgress = function(inProgress) { + Logger.logAction(Logger.LOG_MICRO, 'PresenceMap.setInProgress()', 'inProgress = ' + inProgress); + this.syncInProgress = inProgress; + this.presence.syncComplete = !inProgress; + }; + return RealtimePresence; })(); diff --git a/browser/static/ably.min.js b/browser/static/ably.min.js index 85d83aeb6d..8b46966938 100644 --- a/browser/static/ably.min.js +++ b/browser/static/ably.min.js @@ -1,7 +1,7 @@ /* Copyright 2017, Ably - Ably JavaScript Library v1.0.3 + Ably JavaScript Library v1.0.4 https://github.com/ably/ably-js Ably Realtime Messaging @@ -9,299 +9,301 @@ Released under the Apache Licence v2.0 */ -(function(){var Y=window.Ably=this,x=x||function(d,c){var b={},a=b.lib={},e=a.Base=function(){function a(){}return{extend:function(b){a.prototype=this;var g=new a;b&&g.mixIn(b);g.hasOwnProperty("init")||(g.init=function(){g.$super.init.apply(this,arguments)});g.init.prototype=g;g.$super=this;return g},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b]);a.hasOwnProperty("toString")&&(this.toString= -a.toString)},clone:function(){return this.init.prototype.extend(this)}}}(),m=a.WordArray=e.extend({init:function(a,b){a=this.words=a||[];this.sigBytes=b!=c?b:4*a.length},toString:function(a){return(a||k).stringify(this)},concat:function(a){var b=this.words,g=a.words,e=this.sigBytes;a=a.sigBytes;this.clamp();if(e%4)for(var n=0;n>>2]|=(g[n>>>2]>>>24-n%4*8&255)<<24-(e+n)%4*8;else if(65535>>2]=g[n>>>2];else b.push.apply(b,g);this.sigBytes+=a;return this}, -clamp:function(){var a=this.words,b=this.sigBytes;a[b>>>2]&=4294967295<<32-b%4*8;a.length=d.ceil(b/4)},clone:function(){var a=e.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var b=[],g=function(a){var b=987654321;return function(){b=36969*(b&65535)+(b>>16)&4294967295;a=18E3*(a&65535)+(a>>16)&4294967295;var g=(b<<16)+a&4294967295,g=g/4294967296+.5;return g*(.5>>2]>>>24-e%4*8&255;g.push((n>>>4).toString(16));g.push((n&15).toString(16))}return g.join("")},parse:function(a){for(var b=a.length,g=[],e=0;e>>3]|=parseInt(a.substr(e,2),16)<<24-e%8*4;return new m.init(g,b/2)}},p=f.Latin1={stringify:function(a){var b=a.words;a=a.sigBytes;for(var g=[],e=0;e>>2]>>>24-e%4*8&255));return g.join("")}, -parse:function(a){for(var b=a.length,g=[],e=0;e>>2]|=(a.charCodeAt(e)&255)<<24-e%4*8;return new m.init(g,b)}},n=f.Utf8={stringify:function(a){try{return decodeURIComponent(escape(p.stringify(a)))}catch(b){throw Error("Malformed UTF-8 data");}},parse:function(a){return p.parse(unescape(encodeURIComponent(a)))}},g=a.BufferedBlockAlgorithm=e.extend({reset:function(){this._data=new m.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=n.parse(a));this._data.concat(a);this._nDataBytes+= -a.sigBytes},_process:function(a){var b=this._data,g=b.words,e=b.sigBytes,n=this.blockSize,f=e/(4*n),f=a?d.ceil(f):d.max((f|0)-this._minBufferSize,0);a=f*n;e=d.min(4*a,e);if(a){for(var k=0;ke;)a(g)&&(8>e&&(m[e]=b(d.pow(g,.5))),f[e]=b(d.pow(g,1/3)),e++),g++})();var k=[],b=b.SHA256=e.extend({_doReset:function(){this._hash=new a.init(m.slice(0))},_doProcessBlock:function(a,b){for(var g=this._hash.words,e=g[0],d=g[1],c=g[2],m=g[3],l=g[4],h=g[5],T=g[6],Z=g[7],H=0;64>H;H++){if(16>H)k[H]=a[b+H]|0;else{var M=k[H-15],A=k[H-2];k[H]=((M<<25|M>>>7)^(M<<14|M>>>18)^M>>>3)+k[H-7]+((A<<15|A>>>17)^(A<<13|A>>>19)^A>>> -10)+k[H-16]}M=Z+((l<<26|l>>>6)^(l<<21|l>>>11)^(l<<7|l>>>25))+(l&h^~l&T)+f[H]+k[H];A=((e<<30|e>>>2)^(e<<19|e>>>13)^(e<<10|e>>>22))+(e&d^e&c^d&c);Z=T;T=h;h=l;l=m+M|0;m=c;c=d;d=e;e=M+A|0}g[0]=g[0]+e|0;g[1]=g[1]+d|0;g[2]=g[2]+c|0;g[3]=g[3]+m|0;g[4]=g[4]+l|0;g[5]=g[5]+h|0;g[6]=g[6]+T|0;g[7]=g[7]+Z|0},_doFinalize:function(){var a=this._data,b=a.words,g=8*this._nDataBytes,e=8*a.sigBytes;b[e>>>5]|=128<<24-e%32;b[(e+64>>>9<<4)+14]=d.floor(g/4294967296);b[(e+64>>>9<<4)+15]=g;a.sigBytes=4*b.length;this._process(); -return this._hash},clone:function(){var a=e.clone.call(this);a._hash=this._hash.clone();return a}});c.SHA256=e._createHelper(b);c.HmacSHA256=e._createHmacHelper(b)})(Math);(function(){var d=x,c=d.enc.Utf8;d.algo.HMAC=d.lib.Base.extend({init:function(b,a){b=this._hasher=new b.init;"string"==typeof a&&(a=c.parse(a));var e=b.blockSize,d=4*e;a.sigBytes>d&&(a=b.finalize(a));a.clamp();for(var f=this._oKey=a.clone(),k=this._iKey=a.clone(),p=f.words,n=k.words,g=0;g>>2]>>>24-f%4*8&255)<<16|(a[f+1>>>2]>>>24-(f+1)%4*8&255)<< -8|a[f+2>>>2]>>>24-(f+2)%4*8&255,c=0;4>c&&f+.75*c>>6*(3-c)&63));if(a=d.charAt(64))for(;b.length%4;)b.push(a);return b.join("")},parse:function(b){var a=b.length,e=this._map,d=e.charAt(64);d&&(d=b.indexOf(d),-1!=d&&(a=d));for(var d=[],f=0,k=0;k>>6-k%4*2;d[f>>>2]|=(p|n)<<24-f%4*8;f++}return c.create(d,f)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}})();x.lib.Cipher||function(d){var c= -x,b=c.lib,a=b.Base,e=b.WordArray,m=b.BufferedBlockAlgorithm,f=c.enc.Base64,k=c.algo.EvpKDF,p=b.Cipher=m.extend({cfg:a.extend(),createEncryptor:function(a,b){return this.create(this._ENC_XFORM_MODE,a,b)},createDecryptor:function(a,b){return this.create(this._DEC_XFORM_MODE,a,b)},init:function(a,b,g){this.cfg=this.cfg.extend(g);this._xformMode=a;this._key=b;this.reset()},reset:function(){m.reset.call(this);this._doReset()},process:function(a){this._append(a);return this._process()},finalize:function(a){a&& -this._append(a);return this._doFinalize()},keySize:4,ivSize:4,_ENC_XFORM_MODE:1,_DEC_XFORM_MODE:2,_createHelper:function(){return function(a){return{encrypt:function(b,g,e){return("string"==typeof g?C:v).encrypt(a,b,g,e)},decrypt:function(b,g,e){return("string"==typeof g?C:v).decrypt(a,b,g,e)}}}}()});b.StreamCipher=p.extend({_doFinalize:function(){return this._process(!0)},blockSize:1});var n=c.mode={},g=b.BlockCipherMode=a.extend({createEncryptor:function(a,b){return this.Encryptor.create(a,b)}, -createDecryptor:function(a,b){return this.Decryptor.create(a,b)},init:function(a,b){this._cipher=a;this._iv=b}}),n=n.CBC=function(){function a(b,g,e){var n=this._iv;n?this._iv=d:n=this._prevBlock;for(var f=0;f>>2]&255}};b.BlockCipher=p.extend({cfg:p.cfg.extend({mode:n,padding:u}),reset:function(){p.reset.call(this);var a=this.cfg,b=a.iv,a=a.mode;if(this._xformMode==this._ENC_XFORM_MODE)var g=a.createEncryptor;else g=a.createDecryptor,this._minBufferSize= -1;this._mode=g.call(a,this,b&&b.words)},_doProcessBlock:function(a,b){this._mode.processBlock(a,b)},_doFinalize:function(){var a=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){a.pad(this._data,this.blockSize);var b=this._process(!0)}else b=this._process(!0),a.unpad(b);return b},blockSize:4});var t=b.CipherParams=a.extend({init:function(a){this.mixIn(a)},toString:function(a){return(a||this.formatter).stringify(this)}}),n=(c.format={}).OpenSSL={stringify:function(a){var b=a.ciphertext;a= -a.salt;return(a?e.create([1398893684,1701076831]).concat(a).concat(b):b).toString(f)},parse:function(a){a=f.parse(a);var b=a.words;if(1398893684==b[0]&&1701076831==b[1]){var g=e.create(b.slice(2,4));b.splice(0,4);a.sigBytes-=16}return t.create({ciphertext:a,salt:g})}},v=b.SerializableCipher=a.extend({cfg:a.extend({format:n}),encrypt:function(a,b,g,e){e=this.cfg.extend(e);var n=a.createEncryptor(g,e);b=n.finalize(b);n=n.cfg;return t.create({ciphertext:b,key:g,iv:n.iv,algorithm:a,mode:n.mode,padding:n.padding, -blockSize:a.blockSize,formatter:e.format})},decrypt:function(a,b,g,e){e=this.cfg.extend(e);b=this._parse(b,e.format);return a.createDecryptor(g,e).finalize(b.ciphertext)},_parse:function(a,b){return"string"==typeof a?b.parse(a,this):a}}),c=(c.kdf={}).OpenSSL={execute:function(a,b,g,n){n||(n=e.random(8));a=k.create({keySize:b+g}).compute(a,n);g=e.create(a.words.slice(b),4*g);a.sigBytes=4*b;return t.create({key:a,iv:g,salt:n})}},C=b.PasswordBasedCipher=v.extend({cfg:v.cfg.extend({kdf:c}),encrypt:function(a, -b,g,e){e=this.cfg.extend(e);g=e.kdf.execute(g,a.keySize,a.ivSize);e.iv=g.iv;a=v.encrypt.call(this,a,b,g.key,e);a.mixIn(g);return a},decrypt:function(a,b,g,e){e=this.cfg.extend(e);b=this._parse(b,e.format);g=e.kdf.execute(g,a.keySize,a.ivSize,b.salt);e.iv=g.iv;return v.decrypt.call(this,a,b,g.key,e)}})}();(function(){var d=x,c=d.lib.BlockCipher,b=d.algo,a=[],e=[],m=[],f=[],k=[],p=[],n=[],g=[],u=[],t=[];(function(){for(var b=[],d=0;256>d;d++)b[d]=128>d?d<<1:d<<1^283;for(var c=0,l=0,d=0;256>d;d++){var v= -l^l<<1^l<<2^l<<3^l<<4,v=v>>>8^v&255^99;a[c]=v;e[v]=c;var h=b[c],r=b[h],A=b[r],q=257*b[v]^16843008*v;m[c]=q<<24|q>>>8;f[c]=q<<16|q>>>16;k[c]=q<<8|q>>>24;p[c]=q;q=16843009*A^65537*r^257*h^16843008*c;n[v]=q<<24|q>>>8;g[v]=q<<16|q>>>16;u[v]=q<<8|q>>>24;t[v]=q;c?(c=h^b[b[b[A^h]]],l^=b[b[l]]):c=l=1}})();var v=[0,1,2,4,8,16,32,64,128,27,54],b=b.AES=c.extend({_doReset:function(){for(var b=this._key,e=b.words,f=b.sigBytes/4,b=4*((this._nRounds=f+6)+1),c=this._keySchedule=[],d=0;d>>24]<<24|a[k>>>16&255]<<16|a[k>>>8&255]<<8|a[k&255]):(k=k<<8|k>>>24,k=a[k>>>24]<<24|a[k>>>16&255]<<16|a[k>>>8&255]<<8|a[k&255],k^=v[d/f|0]<<24);c[d]=c[d-f]^k}e=this._invKeySchedule=[];for(f=0;ff||4>=d?k:n[a[k>>>24]]^g[a[k>>>16&255]]^u[a[k>>>8&255]]^t[a[k&255]]},encryptBlock:function(b,g){this._doCryptBlock(b,g,this._keySchedule,m,f,k,p,a)},decryptBlock:function(a,b){var f=a[b+1];a[b+1]=a[b+3];a[b+3]=f;this._doCryptBlock(a,b,this._invKeySchedule, -n,g,u,t,e);f=a[b+1];a[b+1]=a[b+3];a[b+3]=f},_doCryptBlock:function(a,b,g,e,n,f,k,d){for(var c=this._nRounds,u=a[b]^g[0],p=a[b+1]^g[1],m=a[b+2]^g[2],t=a[b+3]^g[3],l=4,v=1;v>>24]^n[p>>>16&255]^f[m>>>8&255]^k[t&255]^g[l++],r=e[p>>>24]^n[m>>>16&255]^f[t>>>8&255]^k[u&255]^g[l++],q=e[m>>>24]^n[t>>>16&255]^f[u>>>8&255]^k[p&255]^g[l++],t=e[t>>>24]^n[u>>>16&255]^f[p>>>8&255]^k[m&255]^g[l++],u=h,p=r,m=q;h=(d[u>>>24]<<24|d[p>>>16&255]<<16|d[m>>>8&255]<<8|d[t&255])^g[l++];r=(d[p>>>24]<<24|d[m>>> -16&255]<<16|d[t>>>8&255]<<8|d[u&255])^g[l++];q=(d[m>>>24]<<24|d[t>>>16&255]<<16|d[u>>>8&255]<<8|d[p&255])^g[l++];t=(d[t>>>24]<<24|d[u>>>16&255]<<16|d[p>>>8&255]<<8|d[m&255])^g[l++];a[b]=h;a[b+1]=r;a[b+2]=q;a[b+3]=t},keySize:8});d.AES=c._createHelper(b)})();(function(){if("undefined"!==typeof ArrayBuffer){var d=x.lib.WordArray,c=d.init;(d.init=function(b){if(b instanceof ArrayBuffer)b=new Uint8Array(b);else if(b instanceof Int8Array||"undefined"!==typeof Uint8ClampedArray&&b instanceof Uint8ClampedArray|| -b instanceof Int16Array||b instanceof Uint16Array||b instanceof Int32Array||b instanceof Uint32Array||"undefined"!==typeof Float32Array&&b instanceof Float32Array||"undefined"!==typeof Float64Array&&b instanceof Float64Array)b=new Uint8Array(b.buffer,b.byteOffset,b.byteLength);if(b instanceof Uint8Array){for(var a=b.byteLength,e=[],d=0;d>>2]|=b[d]<<24-d%4*8;c.call(this,e,a)}else c.apply(this,arguments)}).prototype=d}})();var da=function(){function d(){}d.addListener=function(d,b,a){d.addEventListener? -d.addEventListener(b,a,!1):d.attachEvent("on"+b,function(){a.apply(d,arguments)})};d.removeListener=function(d,b,a){d.removeEventListener?d.removeEventListener(b,a,!1):d.detachEvent("on"+b,function(){a.apply(d,arguments)})};d.addMessageListener=function(c,b){d.addListener(c,"message",b)};d.removeMessageListener=function(c,b){d.removeListener(c,"message",b)};d.addUnloadListener=function(c){d.addListener(window,"unload",c)};return d}(),ea=function(){function d(a,b,e){for(var d=0,f=e.length;dk)a.setUint8(b++,k>>>0&127|0);else if(2048>k)a.setUint8(b++,k>>>6&31|192),a.setUint8(b++,k>>>0&63|128);else if(65536>k)a.setUint8(b++,k>>>12&15|224),a.setUint8(b++,k>>>6&63|128),a.setUint8(b++,k>>>0&63|128);else if(1114112>k)a.setUint8(b++,k>>>18&7|240),a.setUint8(b++,k>>>12&63|128),a.setUint8(b++,k>>>6&63|128),a.setUint8(b++,k>>>0&63|128);else throw Error("bad codepoint "+k);}}function c(a,b,e){var d="",f=b;for(b+=e;ff)b+=1;else if(2048>f)b+=2;else if(65536>f)b+=3;else if(1114112> -f)b+=4;else throw Error("bad codepoint "+f);}return b}function a(a,b){this.offset=b||0;this.view=a}function e(a,b){return h.keysArray(a,!0).filter(function(e){e=a[e];return(!b||void 0!==e&&null!==e)&&("function"!==typeof e||!!e.toJSON)})}function m(a,g,f,k){var c=typeof a;if("string"===c){var l=b(a);if(32>l)return g.setUint8(f,l|160),d(g,f+1,a),1+l;if(256>l)return g.setUint8(f,217),g.setUint8(f+1,l),d(g,f+2,a),2+l;if(65536>l)return g.setUint8(f,218),g.setUint16(f+1,l),d(g,f+3,a),3+l;if(4294967296> -l)return g.setUint8(f,219),g.setUint32(f+1,l),d(g,f+5,a),5+l}if(a instanceof ArrayBuffer){l=a.byteLength;if(256>l)return g.setUint8(f,196),g.setUint8(f+1,l),(new Uint8Array(g.buffer)).set(new Uint8Array(a),f+2),2+l;if(65536>l)return g.setUint8(f,197),g.setUint16(f+1,l),(new Uint8Array(g.buffer)).set(new Uint8Array(a),f+3),3+l;if(4294967296>l)return g.setUint8(f,198),g.setUint32(f+1,l),(new Uint8Array(g.buffer)).set(new Uint8Array(a),f+5),5+l}if("number"===c){if(Math.floor(a)!==a)return g.setUint8(f, -203),g.setFloat64(f+1,a),9;if(0<=a){if(128>a)return g.setUint8(f,a),1;if(256>a)return g.setUint8(f,204),g.setUint8(f+1,a),2;if(65536>a)return g.setUint8(f,205),g.setUint16(f+1,a),3;if(4294967296>a)return g.setUint8(f,206),g.setUint32(f+1,a),5;if(1.8446744073709552E19>a)return g.setUint8(f,207),f+=1,1.8446744073709552E19>a?(g.setUint32(f,Math.floor(a*p)),g.setInt32(f+4,a&-1)):(g.setUint32(f,4294967295),g.setUint32(f+4,4294967295)),9;throw Error("Number too big 0x"+a.toString(16));}if(-32<=a)return g.setInt8(f, -a),1;if(-128<=a)return g.setUint8(f,208),g.setInt8(f+1,a),2;if(-32768<=a)return g.setUint8(f,209),g.setInt16(f+1,a),3;if(-2147483648<=a)return g.setUint8(f,210),g.setInt32(f+1,a),5;if(-9223372036854775808<=a)return g.setUint8(f,211),f+=1,0x7fffffffffffffff>a?(g.setInt32(f,Math.floor(a*p)),g.setInt32(f+4,a&-1)):(g.setUint32(f,2147483647),g.setUint32(f+4,2147483647)),9;throw Error("Number too small -0x"+(-a).toString(16).substr(1));}if("undefined"===c){if(k)return 0;g.setUint8(f,212);g.setUint8(f+1, -0);g.setUint8(f+2,0);return 3}if(null===a){if(k)return 0;g.setUint8(f,192);return 1}if("boolean"===c)return g.setUint8(f,a?195:194),1;if("function"===typeof a.toJSON)return m(a.toJSON(),g,f,k);if("object"===c){var c=0,h=Array.isArray(a);if(h)l=a.length;else var ca=e(a,k),l=ca.length;16>l?(g.setUint8(f,l|(h?144:128)),c=1):65536>l?(g.setUint8(f,h?220:222),g.setUint16(f+1,l),c=3):4294967296>l&&(g.setUint8(f,h?221:223),g.setUint32(f+1,l),c=5);if(h)for(h=0;hk)return 1+k;if(256>k)return 2+k;if(65536>k)return 3+k;if(4294967296>k)return 5+k}if(a instanceof ArrayBuffer){k=a.byteLength;if(256>k)return 2+k;if(65536>k)return 3+k;if(4294967296>k)return 5+k}if("number"===d){if(Math.floor(a)!==a)return 9;if(0<=a){if(128>a)return 1;if(256>a)return 2;if(65536>a)return 3;if(4294967296>a)return 5; -if(1.8446744073709552E19>a)return 9;throw Error("Number too big 0x"+a.toString(16));}if(-32<=a)return 1;if(-128<=a)return 2;if(-32768<=a)return 3;if(-2147483648<=a)return 5;if(-9223372036854775808<=a)return 9;throw Error("Number too small -0x"+a.toString(16).substr(1));}if("boolean"===d)return 1;if(null===a)return g?0:1;if(void 0===a)return g?0:3;if("function"===typeof a.toJSON)return f(a.toJSON(),g);if("object"===d){d=0;if(Array.isArray(a))for(var k=a.length,c=0;ck)return 1+d;if(65536>k)return 3+d;if(4294967296>k)return 5+d;throw Error("Array or object too long 0x"+k.toString(16));}if("function"===d)return 0;throw Error("Unknown type "+d);}var k={inspect:function(a){if(void 0===a)return"undefined";var b,e;a instanceof ArrayBuffer?(e="ArrayBuffer",b=new DataView(a)):a instanceof DataView&&(e="DataView",b=a);if(!b)return JSON.stringify(a);for(var f=[],d=0;d"}};k.utf8Write=d;k.utf8Read=c;k.utf8ByteCount=b;k.encode=function(a,b){var e=f(a,b);if(0!=e){var e=new ArrayBuffer(e),d=new DataView(e);m(a,d,0,b);return e}};k.decode=function(b){var e=new DataView(b),e=new a(e),f=e.parse();if(e.offset!==b.byteLength)throw Error(b.byteLength-e.offset+" trailing bytes");return f};var p=1/4294967296;a.prototype.map=function(a){for(var b={},e=0;e>>2]|=(h[n>>>2]>>>24-n%4*8&255)<<24-(d+n)%4*8;else if(65535>>2]=h[n>>>2];else b.push.apply(b,h);this.sigBytes+=a;return this}, +clamp:function(){var a=this.words,b=this.sigBytes;a[b>>>2]&=4294967295<<32-b%4*8;a.length=c.ceil(b/4)},clone:function(){var a=d.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var b=[],h=function(a){var b=987654321;return function(){b=36969*(b&65535)+(b>>16)&4294967295;a=18E3*(a&65535)+(a>>16)&4294967295;var h=(b<<16)+a&4294967295,h=h/4294967296+.5;return h*(.5>>2]>>>24-d%4*8&255;h.push((n>>>4).toString(16));h.push((n&15).toString(16))}return h.join("")},parse:function(a){for(var b=a.length,h=[],d=0;d>>3]|=parseInt(a.substr(d,2),16)<<24-d%8*4;return new l.init(h,b/2)}},q=f.Latin1={stringify:function(a){var b=a.words;a=a.sigBytes;for(var h=[],d=0;d>>2]>>>24-d%4*8&255));return h.join("")}, +parse:function(a){for(var b=a.length,h=[],d=0;d>>2]|=(a.charCodeAt(d)&255)<<24-d%4*8;return new l.init(h,b)}},n=f.Utf8={stringify:function(a){try{return decodeURIComponent(escape(q.stringify(a)))}catch(b){throw Error("Malformed UTF-8 data");}},parse:function(a){return q.parse(unescape(encodeURIComponent(a)))}},h=a.BufferedBlockAlgorithm=d.extend({reset:function(){this._data=new l.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=n.parse(a));this._data.concat(a);this._nDataBytes+= +a.sigBytes},_process:function(a){var b=this._data,h=b.words,d=b.sigBytes,n=this.blockSize,f=d/(4*n),f=a?c.ceil(f):c.max((f|0)-this._minBufferSize,0);a=f*n;d=c.min(4*a,d);if(a){for(var m=0;md;)a(h)&&(8>d&&(l[d]=b(c.pow(h,.5))),f[d]=b(c.pow(h,1/3)),d++),h++})();var m=[],b=b.SHA256=d.extend({_doReset:function(){this._hash=new a.init(l.slice(0))},_doProcessBlock:function(a,b){for(var h=this._hash.words,d=h[0],c=h[1],e=h[2],l=h[3],g=h[4],k=h[5],U=h[6],aa=h[7],H=0;64>H;H++){if(16>H)m[H]=a[b+H]|0;else{var N=m[H-15],A=m[H-2];m[H]=((N<<25|N>>>7)^(N<<14|N>>>18)^N>>>3)+m[H-7]+((A<<15|A>>>17)^(A<<13|A>>>19)^A>>> +10)+m[H-16]}N=aa+((g<<26|g>>>6)^(g<<21|g>>>11)^(g<<7|g>>>25))+(g&k^~g&U)+f[H]+m[H];A=((d<<30|d>>>2)^(d<<19|d>>>13)^(d<<10|d>>>22))+(d&c^d&e^c&e);aa=U;U=k;k=g;g=l+N|0;l=e;e=c;c=d;d=N+A|0}h[0]=h[0]+d|0;h[1]=h[1]+c|0;h[2]=h[2]+e|0;h[3]=h[3]+l|0;h[4]=h[4]+g|0;h[5]=h[5]+k|0;h[6]=h[6]+U|0;h[7]=h[7]+aa|0},_doFinalize:function(){var a=this._data,b=a.words,h=8*this._nDataBytes,d=8*a.sigBytes;b[d>>>5]|=128<<24-d%32;b[(d+64>>>9<<4)+14]=c.floor(h/4294967296);b[(d+64>>>9<<4)+15]=h;a.sigBytes=4*b.length;this._process(); +return this._hash},clone:function(){var a=d.clone.call(this);a._hash=this._hash.clone();return a}});g.SHA256=d._createHelper(b);g.HmacSHA256=d._createHmacHelper(b)})(Math);(function(){var c=D,g=c.enc.Utf8;c.algo.HMAC=c.lib.Base.extend({init:function(b,a){b=this._hasher=new b.init;"string"==typeof a&&(a=g.parse(a));var d=b.blockSize,c=4*d;a.sigBytes>c&&(a=b.finalize(a));a.clamp();for(var f=this._oKey=a.clone(),m=this._iKey=a.clone(),e=f.words,n=m.words,h=0;h>>2]>>>24-f%4*8&255)<<16|(a[f+1>>>2]>>>24-(f+1)%4*8&255)<< +8|a[f+2>>>2]>>>24-(f+2)%4*8&255,e=0;4>e&&f+.75*e>>6*(3-e)&63));if(a=c.charAt(64))for(;b.length%4;)b.push(a);return b.join("")},parse:function(b){var a=b.length,d=this._map,c=d.charAt(64);c&&(c=b.indexOf(c),-1!=c&&(a=c));for(var c=[],f=0,m=0;m>>6-m%4*2;c[f>>>2]|=(e|n)<<24-f%4*8;f++}return g.create(c,f)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}})();D.lib.Cipher||function(c){var g= +D,b=g.lib,a=b.Base,d=b.WordArray,l=b.BufferedBlockAlgorithm,f=g.enc.Base64,m=g.algo.EvpKDF,q=b.Cipher=l.extend({cfg:a.extend(),createEncryptor:function(a,b){return this.create(this._ENC_XFORM_MODE,a,b)},createDecryptor:function(a,b){return this.create(this._DEC_XFORM_MODE,a,b)},init:function(a,b,h){this.cfg=this.cfg.extend(h);this._xformMode=a;this._key=b;this.reset()},reset:function(){l.reset.call(this);this._doReset()},process:function(a){this._append(a);return this._process()},finalize:function(a){a&& +this._append(a);return this._doFinalize()},keySize:4,ivSize:4,_ENC_XFORM_MODE:1,_DEC_XFORM_MODE:2,_createHelper:function(){return function(a){return{encrypt:function(b,h,d){return("string"==typeof h?C:v).encrypt(a,b,h,d)},decrypt:function(b,h,d){return("string"==typeof h?C:v).decrypt(a,b,h,d)}}}}()});b.StreamCipher=q.extend({_doFinalize:function(){return this._process(!0)},blockSize:1});var n=g.mode={},h=b.BlockCipherMode=a.extend({createEncryptor:function(a,b){return this.Encryptor.create(a,b)}, +createDecryptor:function(a,b){return this.Decryptor.create(a,b)},init:function(a,b){this._cipher=a;this._iv=b}}),n=n.CBC=function(){function a(b,h,d){var n=this._iv;n?this._iv=c:n=this._prevBlock;for(var f=0;f>>2]&255}};b.BlockCipher=q.extend({cfg:q.cfg.extend({mode:n,padding:u}),reset:function(){q.reset.call(this);var a=this.cfg,b=a.iv,a=a.mode;if(this._xformMode==this._ENC_XFORM_MODE)var h=a.createEncryptor;else h=a.createDecryptor,this._minBufferSize= +1;this._mode=h.call(a,this,b&&b.words)},_doProcessBlock:function(a,b){this._mode.processBlock(a,b)},_doFinalize:function(){var a=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){a.pad(this._data,this.blockSize);var b=this._process(!0)}else b=this._process(!0),a.unpad(b);return b},blockSize:4});var t=b.CipherParams=a.extend({init:function(a){this.mixIn(a)},toString:function(a){return(a||this.formatter).stringify(this)}}),n=(g.format={}).OpenSSL={stringify:function(a){var b=a.ciphertext;a= +a.salt;return(a?d.create([1398893684,1701076831]).concat(a).concat(b):b).toString(f)},parse:function(a){a=f.parse(a);var b=a.words;if(1398893684==b[0]&&1701076831==b[1]){var h=d.create(b.slice(2,4));b.splice(0,4);a.sigBytes-=16}return t.create({ciphertext:a,salt:h})}},v=b.SerializableCipher=a.extend({cfg:a.extend({format:n}),encrypt:function(a,b,h,d){d=this.cfg.extend(d);var n=a.createEncryptor(h,d);b=n.finalize(b);n=n.cfg;return t.create({ciphertext:b,key:h,iv:n.iv,algorithm:a,mode:n.mode,padding:n.padding, +blockSize:a.blockSize,formatter:d.format})},decrypt:function(a,b,h,d){d=this.cfg.extend(d);b=this._parse(b,d.format);return a.createDecryptor(h,d).finalize(b.ciphertext)},_parse:function(a,b){return"string"==typeof a?b.parse(a,this):a}}),g=(g.kdf={}).OpenSSL={execute:function(a,b,h,n){n||(n=d.random(8));a=m.create({keySize:b+h}).compute(a,n);h=d.create(a.words.slice(b),4*h);a.sigBytes=4*b;return t.create({key:a,iv:h,salt:n})}},C=b.PasswordBasedCipher=v.extend({cfg:v.cfg.extend({kdf:g}),encrypt:function(a, +b,h,d){d=this.cfg.extend(d);h=d.kdf.execute(h,a.keySize,a.ivSize);d.iv=h.iv;a=v.encrypt.call(this,a,b,h.key,d);a.mixIn(h);return a},decrypt:function(a,b,h,d){d=this.cfg.extend(d);b=this._parse(b,d.format);h=d.kdf.execute(h,a.keySize,a.ivSize,b.salt);d.iv=h.iv;return v.decrypt.call(this,a,b,h.key,d)}})}();(function(){var c=D,g=c.lib.BlockCipher,b=c.algo,a=[],d=[],l=[],f=[],m=[],q=[],n=[],h=[],u=[],t=[];(function(){for(var b=[],c=0;256>c;c++)b[c]=128>c?c<<1:c<<1^283;for(var e=0,g=0,c=0;256>c;c++){var v= +g^g<<1^g<<2^g<<3^g<<4,v=v>>>8^v&255^99;a[e]=v;d[v]=e;var k=b[e],r=b[k],A=b[r],p=257*b[v]^16843008*v;l[e]=p<<24|p>>>8;f[e]=p<<16|p>>>16;m[e]=p<<8|p>>>24;q[e]=p;p=16843009*A^65537*r^257*k^16843008*e;n[v]=p<<24|p>>>8;h[v]=p<<16|p>>>16;u[v]=p<<8|p>>>24;t[v]=p;e?(e=k^b[b[b[A^k]]],g^=b[b[g]]):e=g=1}})();var v=[0,1,2,4,8,16,32,64,128,27,54],b=b.AES=g.extend({_doReset:function(){for(var b=this._key,d=b.words,f=b.sigBytes/4,b=4*((this._nRounds=f+6)+1),c=this._keySchedule=[],m=0;m>>24]<<24|a[e>>>16&255]<<16|a[e>>>8&255]<<8|a[e&255]):(e=e<<8|e>>>24,e=a[e>>>24]<<24|a[e>>>16&255]<<16|a[e>>>8&255]<<8|a[e&255],e^=v[m/f|0]<<24);c[m]=c[m-f]^e}d=this._invKeySchedule=[];for(f=0;ff||4>=m?e:n[a[e>>>24]]^h[a[e>>>16&255]]^u[a[e>>>8&255]]^t[a[e&255]]},encryptBlock:function(b,h){this._doCryptBlock(b,h,this._keySchedule,l,f,m,q,a)},decryptBlock:function(a,b){var f=a[b+1];a[b+1]=a[b+3];a[b+3]=f;this._doCryptBlock(a,b,this._invKeySchedule, +n,h,u,t,d);f=a[b+1];a[b+1]=a[b+3];a[b+3]=f},_doCryptBlock:function(a,b,h,d,n,f,m,c){for(var e=this._nRounds,u=a[b]^h[0],q=a[b+1]^h[1],l=a[b+2]^h[2],t=a[b+3]^h[3],g=4,v=1;v>>24]^n[q>>>16&255]^f[l>>>8&255]^m[t&255]^h[g++],r=d[q>>>24]^n[l>>>16&255]^f[t>>>8&255]^m[u&255]^h[g++],p=d[l>>>24]^n[t>>>16&255]^f[u>>>8&255]^m[q&255]^h[g++],t=d[t>>>24]^n[u>>>16&255]^f[q>>>8&255]^m[l&255]^h[g++],u=k,q=r,l=p;k=(c[u>>>24]<<24|c[q>>>16&255]<<16|c[l>>>8&255]<<8|c[t&255])^h[g++];r=(c[q>>>24]<<24|c[l>>> +16&255]<<16|c[t>>>8&255]<<8|c[u&255])^h[g++];p=(c[l>>>24]<<24|c[t>>>16&255]<<16|c[u>>>8&255]<<8|c[q&255])^h[g++];t=(c[t>>>24]<<24|c[u>>>16&255]<<16|c[q>>>8&255]<<8|c[l&255])^h[g++];a[b]=k;a[b+1]=r;a[b+2]=p;a[b+3]=t},keySize:8});c.AES=g._createHelper(b)})();(function(){if("undefined"!==typeof ArrayBuffer){var c=D.lib.WordArray,g=c.init;(c.init=function(b){if(b instanceof ArrayBuffer)b=new Uint8Array(b);else if(b instanceof Int8Array||"undefined"!==typeof Uint8ClampedArray&&b instanceof Uint8ClampedArray|| +b instanceof Int16Array||b instanceof Uint16Array||b instanceof Int32Array||b instanceof Uint32Array||"undefined"!==typeof Float32Array&&b instanceof Float32Array||"undefined"!==typeof Float64Array&&b instanceof Float64Array)b=new Uint8Array(b.buffer,b.byteOffset,b.byteLength);if(b instanceof Uint8Array){for(var a=b.byteLength,d=[],c=0;c>>2]|=b[c]<<24-c%4*8;g.call(this,d,a)}else g.apply(this,arguments)}).prototype=c}})();var ea=function(){function c(){}c.addListener=function(c,b,a){c.addEventListener? +c.addEventListener(b,a,!1):c.attachEvent("on"+b,function(){a.apply(c,arguments)})};c.removeListener=function(c,b,a){c.removeEventListener?c.removeEventListener(b,a,!1):c.detachEvent("on"+b,function(){a.apply(c,arguments)})};c.addMessageListener=function(g,b){c.addListener(g,"message",b)};c.removeMessageListener=function(g,b){c.removeListener(g,"message",b)};c.addUnloadListener=function(g){c.addListener(window,"unload",g)};return c}(),fa=function(){function c(a,b,d){for(var f=0,m=d.length;fe)a.setUint8(b++,e>>>0&127|0);else if(2048>e)a.setUint8(b++,e>>>6&31|192),a.setUint8(b++,e>>>0&63|128);else if(65536>e)a.setUint8(b++,e>>>12&15|224),a.setUint8(b++,e>>>6&63|128),a.setUint8(b++,e>>>0&63|128);else if(1114112>e)a.setUint8(b++,e>>>18&7|240),a.setUint8(b++,e>>>12&63|128),a.setUint8(b++,e>>>6&63|128),a.setUint8(b++,e>>>0&63|128);else throw Error("bad codepoint "+e);}}function g(a,b,d){var f="",c=b;for(b+=d;cc)b+=1;else if(2048>c)b+=2;else if(65536>c)b+=3;else if(1114112> +c)b+=4;else throw Error("bad codepoint "+c);}return b}function a(a,b){this.offset=b||0;this.view=a}function d(a,b){return k.keysArray(a,!0).filter(function(d){d=a[d];return(!b||void 0!==d&&null!==d)&&("function"!==typeof d||!!d.toJSON)})}function l(a,h,f,m){var g=typeof a;if("string"===g){var k=b(a);if(32>k)return h.setUint8(f,k|160),c(h,f+1,a),1+k;if(256>k)return h.setUint8(f,217),h.setUint8(f+1,k),c(h,f+2,a),2+k;if(65536>k)return h.setUint8(f,218),h.setUint16(f+1,k),c(h,f+3,a),3+k;if(4294967296> +k)return h.setUint8(f,219),h.setUint32(f+1,k),c(h,f+5,a),5+k}if(a instanceof ArrayBuffer){k=a.byteLength;if(256>k)return h.setUint8(f,196),h.setUint8(f+1,k),(new Uint8Array(h.buffer)).set(new Uint8Array(a),f+2),2+k;if(65536>k)return h.setUint8(f,197),h.setUint16(f+1,k),(new Uint8Array(h.buffer)).set(new Uint8Array(a),f+3),3+k;if(4294967296>k)return h.setUint8(f,198),h.setUint32(f+1,k),(new Uint8Array(h.buffer)).set(new Uint8Array(a),f+5),5+k}if("number"===g){if(Math.floor(a)!==a)return h.setUint8(f, +203),h.setFloat64(f+1,a),9;if(0<=a){if(128>a)return h.setUint8(f,a),1;if(256>a)return h.setUint8(f,204),h.setUint8(f+1,a),2;if(65536>a)return h.setUint8(f,205),h.setUint16(f+1,a),3;if(4294967296>a)return h.setUint8(f,206),h.setUint32(f+1,a),5;if(1.8446744073709552E19>a)return h.setUint8(f,207),f+=1,1.8446744073709552E19>a?(h.setUint32(f,Math.floor(a*q)),h.setInt32(f+4,a&-1)):(h.setUint32(f,4294967295),h.setUint32(f+4,4294967295)),9;throw Error("Number too big 0x"+a.toString(16));}if(-32<=a)return h.setInt8(f, +a),1;if(-128<=a)return h.setUint8(f,208),h.setInt8(f+1,a),2;if(-32768<=a)return h.setUint8(f,209),h.setInt16(f+1,a),3;if(-2147483648<=a)return h.setUint8(f,210),h.setInt32(f+1,a),5;if(-9223372036854775808<=a)return h.setUint8(f,211),f+=1,0x7fffffffffffffff>a?(h.setInt32(f,Math.floor(a*q)),h.setInt32(f+4,a&-1)):(h.setUint32(f,2147483647),h.setUint32(f+4,2147483647)),9;throw Error("Number too small -0x"+(-a).toString(16).substr(1));}if("undefined"===g){if(m)return 0;h.setUint8(f,212);h.setUint8(f+1, +0);h.setUint8(f+2,0);return 3}if(null===a){if(m)return 0;h.setUint8(f,192);return 1}if("boolean"===g)return h.setUint8(f,a?195:194),1;if("function"===typeof a.toJSON)return l(a.toJSON(),h,f,m);if("object"===g){var g=0,G=Array.isArray(a);if(G)k=a.length;else var da=d(a,m),k=da.length;16>k?(h.setUint8(f,k|(G?144:128)),g=1):65536>k?(h.setUint8(f,G?220:222),h.setUint16(f+1,k),g=3):4294967296>k&&(h.setUint8(f,G?221:223),h.setUint32(f+1,k),g=5);if(G)for(G=0;Gm)return 1+m;if(256>m)return 2+m;if(65536>m)return 3+m;if(4294967296>m)return 5+m}if(a instanceof ArrayBuffer){m=a.byteLength;if(256>m)return 2+m;if(65536>m)return 3+m;if(4294967296>m)return 5+m}if("number"===c){if(Math.floor(a)!==a)return 9;if(0<=a){if(128>a)return 1;if(256>a)return 2;if(65536>a)return 3;if(4294967296>a)return 5; +if(1.8446744073709552E19>a)return 9;throw Error("Number too big 0x"+a.toString(16));}if(-32<=a)return 1;if(-128<=a)return 2;if(-32768<=a)return 3;if(-2147483648<=a)return 5;if(-9223372036854775808<=a)return 9;throw Error("Number too small -0x"+a.toString(16).substr(1));}if("boolean"===c)return 1;if(null===a)return h?0:1;if(void 0===a)return h?0:3;if("function"===typeof a.toJSON)return f(a.toJSON(),h);if("object"===c){c=0;if(Array.isArray(a))for(var m=a.length,e=0;em)return 1+c;if(65536>m)return 3+c;if(4294967296>m)return 5+c;throw Error("Array or object too long 0x"+m.toString(16));}if("function"===c)return 0;throw Error("Unknown type "+c);}var m={inspect:function(a){if(void 0===a)return"undefined";var b,d;a instanceof ArrayBuffer?(d="ArrayBuffer",b=new DataView(a)):a instanceof DataView&&(d="DataView",b=a);if(!b)return JSON.stringify(a);for(var f=[],c=0;c"}};m.utf8Write=c;m.utf8Read=g;m.utf8ByteCount=b;m.encode=function(a,b){var d=f(a,b);if(0!=d){var d=new ArrayBuffer(d),c=new DataView(d);l(a,c,0,b);return d}};m.decode=function(b){var d=new DataView(b),d=new a(d),f=d.parse();if(d.offset!==b.byteLength)throw Error(b.byteLength-d.offset+" trailing bytes");return f};var q=1/4294967296;a.prototype.map=function(a){for(var b={},d=0;d>>2]>>>24-n%4*8&255;return b}throw Error("BufferUtils.toArrayBuffer expected a buffer"); -};b.toWordArray=function(b){return d(b)?b:a.create(b)};b.base64Encode=function(a){if(c(a)){var b="";a=new Uint8Array(a);for(var e=a.byteLength,m=e%3,e=e-m,g,u,t,h,C=0;C>18,u=(h&258048)>>12,t=(h&4032)>>6,h&=63,b+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[g]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[u]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[t]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[h]; -1==m?(h=a[e],b+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(h&252)>>2]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(h&3)<<4]+"=="):2==m&&(h=a[e]<<8|a[e+1],b+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(h&64512)>>10]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(h&1008)>>4]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(h&15)<<2]+"=");return b}if(d(a))return x.enc.Base64.stringify(a)}; -b.base64Decode=function(a){if(e&&m){a=m(a);for(var b=a.length,d=new Uint8Array(b),c=0;c=b}var b=function(){};d.get=function(a,e,m,f,k){k=k||b;var p="function"==typeof e?e:function(b){return a.baseUri(b)+e},n;n=(n=a.connection)&&"connected"== -n.state?[n.connectionManager.host]:q.getHosts(a.options);if(1==n.length)d.getUri(a,p(n[0]),m,f,k);else{var g=function(b){d.getUri(a,p(b.shift()),m,f,function(a){a&&c(a)&&b.length?g(b):k.apply(null,arguments)})};g(n)}};d.getUri=function(a,e,c,f,k){d.Request(a,e,c,f,null,k||b)};d.post=function(a,e,m,f,k,p){p=p||b;var n="function"==typeof e?e:function(b){return a.baseUri(b)+e},g;g=(g=a.connection)&&"connected"==g.state?[g.connectionManager.host]:q.getHosts(a.options);if(1==g.length)d.postUri(a,n(g[0]), -m,f,k,p);else{var u=function(b){d.postUri(a,n(b.shift()),m,f,k,function(a){a&&c(a)&&b.length?u(b):p.apply(null,arguments)})};u(g)}};d.postUri=function(a,e,c,f,k,p){d.Request(a,e,c,k,f,p||b)};d.supportsAuthHeaders=!1;d.supportsLinkHeaders=!1;return d}(),ia=function(){function d(){this.buffer=[]}function c(a){this._input=a;this._index=-1;this._buffer=[]}function b(a){this._input=a;this._index=-1;this._buffer=[]}d.prototype.append=function(a){this.buffer.push(a);return this};d.prototype.toString=function(){return this.buffer.join("")}; -var a={codex:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(b){var m=new d,f=a.codex;for(b=new c(b);b.moveNext();){var k=b.current;b.moveNext();var p=b.current;b.moveNext();var n=b.current,g=k>>2,k=(k&3)<<4|p>>4,u=(p&15)<<2|n>>6,t=n&63;isNaN(p)?u=t=64:isNaN(n)&&(t=64);m.append(f.charAt(g)+f.charAt(k)+f.charAt(u)+f.charAt(t))}return m.toString()},decode:function(a){var c=new d;for(a=new b(a);a.moveNext();){var f=a.current;if(128>f)c.append(String.fromCharCode(f)); -else if(191f){a.moveNext();var k=a.current;c.append(String.fromCharCode((f&31)<<6|k&63))}else a.moveNext(),k=a.current,a.moveNext(),c.append(String.fromCharCode((f&15)<<12|(k&63)<<6|a.current&63))}return c.toString()}};c.prototype={current:Number.NaN,moveNext:function(){if(0=this._input.length-1)return this.current=Number.NaN,!1;var a=this._input.charCodeAt(++this._index);13==a&&10==this._input.charCodeAt(this._index+ -1)&&(a=10,this._index+=2);128>a?this.current=a:(127a?this.current=a>>6|192:(this.current=a>>12|224,this._buffer.push(a>>6&63|128)),this._buffer.push(a&63|128));return!0}};b.prototype={current:64,moveNext:function(){if(0=this._input.length-1)return this.current=64,!1;var b=a.codex.indexOf(this._input.charAt(++this._index)),d=a.codex.indexOf(this._input.charAt(++this._index)),c=a.codex.indexOf(this._input.charAt(++this._index)), -k=a.codex.indexOf(this._input.charAt(++this._index)),p=(c&3)<<6|k;this.current=b<<2|d>>4;64!=c&&this._buffer.push((d&15)<<4|c>>2);64!=k&&this._buffer.push(p);return!0}};return a}();q.protocolVersion=1;q.ENVIRONMENT="";q.REST_HOST="rest.ably.io";q.REALTIME_HOST="realtime.ably.io";q.FALLBACK_HOSTS=["A.ably-realtime.com","B.ably-realtime.com","C.ably-realtime.com","D.ably-realtime.com","E.ably-realtime.com"];q.PORT=80;q.TLS_PORT=443;q.TIMEOUTS={disconnectedRetryTimeout:15E3,suspendedRetryTimeout:3E4, -httpRequestTimeout:15E3,channelRetryTimeout:15E3,connectionStateTtl:12E4,realtimeRequestTimeout:1E4,recvTimeout:9E4,preferenceConnectTimeout:6E3,parallelUpgradeDelay:4E3};q.httpMaxRetryCount=3;q.version="1.0.3";q.libstring=y.libver+q.version;q.apiVersion="1.0";q.getHost=function(d,c,b){return c=b?c==d.restHost&&d.realtimeHost||c||d.realtimeHost:c||d.restHost};q.getPort=function(d,c){return c||d.tls?d.tlsPort:d.port};q.getHttpScheme=function(d){return d.tls?"https://":"http://"};q.getHosts=function(d){var c= -[d.restHost],b=d.fallbackHosts;d="undefined"!==typeof d.httpMaxRetryCount?d.httpMaxRetryCount:q.httpMaxRetryCount;b&&(c=c.concat(h.arrChooseN(b,d)));return c};q.normaliseOptions=function(d){d.host&&(c.deprecated("host","restHost"),d.restHost=d.host);d.wsHost&&(c.deprecated("wsHost","realtimeHost"),d.realtimeHost=d.wsHost);d.queueEvents&&(c.deprecated("queueEvents","queueMessages"),d.queueMessages=d.queueEvents);!0===d.recover&&(c.deprecated("{recover: true}","{recover: function(lastConnectionDetails, cb) { cb(true); }}"), -d.recover=function(a,b){b(!0)});"function"===typeof d.recover&&!0===d.closeOnUnload&&(c.logAction(LOG_ERROR,"Defaults.normaliseOptions","closeOnUnload was true and a session recovery function was set - these are mutually exclusive, so unsetting the latter"),d.recover=null);d.transports&&h.arrIn(d.transports,"xhr")&&(c.deprecated('transports: ["xhr"]','transports: ["xhr_streaming"]'),h.arrDeleteValue(d.transports,"xhr"),d.transports.push("xhr_streaming"));"queueMessages"in d||(d.queueMessages=!0); -var l=!1;if(d.restHost)d.realtimeHost=d.realtimeHost||d.restHost;else{var b=d.environment&&String(d.environment).toLowerCase()||q.ENVIRONMENT,l=!b||"production"===b;d.restHost=l?q.REST_HOST:b+"-"+q.REST_HOST;d.realtimeHost=l?q.REALTIME_HOST:b+"-"+q.REALTIME_HOST}d.fallbackHosts=l||d.fallbackHostsUseDefault?q.FALLBACK_HOSTS:d.fallbackHosts;d.port=d.port||q.PORT;d.tlsPort=d.tlsPort||q.TLS_PORT;"tls"in d||(d.tls=!0);d.timeouts={};for(var a in q.TIMEOUTS)d.timeouts[a]=d[a]||q.TIMEOUTS[a];d.useBinaryProtocol= -"useBinaryProtocol"in d?y.supportsBinary&&d.useBinaryProtocol:y.preferBinary;return d};var z=function(){function d(){this.any=[];this.events={};this.anyOnce=[];this.eventsOnce={}}function l(a,b,d){try{b.apply(a,d)}catch(f){c.logAction(c.LOG_ERROR,"EventEmitter.emit()","Unexpected listener exception: "+f+"; stack = "+f.stack)}}function b(a,e,d){var c,k,p,n;for(n=0;n=d?null:c.slice(0,d).join("/"),b.data=k}}};d.fromResponseBody=function(b,a,e){e&&(b="msgpack"==e?l.decode(b):JSON.parse(String(b)));for(e=0;eh.arrIndexOf(p, -b.shortName)}function l(a,b,c,e,d){this.options=a;this.host=b;this.mode=c;this.connectionKey=e;this.connectionSerial=d;this.format=a.useBinaryProtocol?"msgpack":"json"}function b(a,d){z.call(this);this.realtime=a;this.options=d;var f=d.timeouts,k=this;this.states={initialized:{state:"initialized",terminal:!1,queueEvents:!0,sendEvents:!1,failState:"disconnected"},connecting:{state:"connecting",terminal:!1,queueEvents:!0,sendEvents:!1,retryDelay:f.preferenceConnectTimeout+f.realtimeRequestTimeout,failState:"disconnected"}, -connected:{state:"connected",terminal:!1,queueEvents:!1,sendEvents:!0,failState:"disconnected"},synchronizing:{state:"connected",terminal:!1,queueEvents:!0,sendEvents:!1,forceQueueEvents:!0,failState:"disconnected"},disconnected:{state:"disconnected",terminal:!1,queueEvents:!0,sendEvents:!1,retryDelay:f.disconnectedRetryTimeout,failState:"disconnected"},suspended:{state:"suspended",terminal:!1,queueEvents:!1,sendEvents:!1,retryDelay:f.suspendedRetryTimeout,failState:"suspended"},closing:{state:"closing", -terminal:!1,queueEvents:!1,sendEvents:!1,retryDelay:f.realtimeRequestTimeout,failState:"closed"},closed:{state:"closed",terminal:!0,queueEvents:!1,sendEvents:!1,failState:"closed"},failed:{state:"failed",terminal:!0,queueEvents:!1,sendEvents:!1,failState:"failed"}};this.state=this.states.initialized;this.errorReason=null;this.queuedMessages=new fa;this.msgSerial=0;this.connectionSerial=this.connectionKey=this.connectionId=void 0;this.connectionStateTtl=f.connectionStateTtl;this.maxIdleInterval=null; -this.transports=h.intersect(d.transports||q.defaultTransports,b.supportedTransports);this.baseTransport=h.intersect(q.baseTransportOrder,this.transports)[0];this.upgradeTransports=h.intersect(this.transports,q.upgradeTransports);this.transportHostBlacklist={};this.transportPreference=null;this.httpHosts=q.getHosts(d);this.activeProtocol=null;this.proposedTransports=[];this.pendingTransports=[];this.lastActivity=this.lastAutoReconnectAttempt=this.host=null;c.logAction(c.LOG_MINOR,"Realtime.ConnectionManager()", -"started");c.logAction(c.LOG_MICRO,"Realtime.ConnectionManager()","requested transports = ["+(d.transports||q.defaultTransports)+"]");c.logAction(c.LOG_MICRO,"Realtime.ConnectionManager()","available transports = ["+this.transports+"]");c.logAction(c.LOG_MICRO,"Realtime.ConnectionManager()","http hosts = ["+this.httpHosts+"]");if(!this.transports.length)throw c.logAction(c.LOG_ERROR,"realtime.ConnectionManager()","no requested transports available"),Error("no requested transports available");if(f= -y.addEventListener)e&&"function"===typeof d.recover&&f("beforeunload",this.persistConnection.bind(this)),!0===d.closeOnUnload&&f("beforeunload",function(){k.requestState({state:"closing"})}),f("online",function(){if(k.state==k.states.disconnected||k.state==k.states.suspended)c.logAction(c.LOG_MINOR,"ConnectionManager caught browser \u2018online\u2019 event","reattempting connection"),k.requestState({state:"connecting"})}),f("offline",function(){k.state==k.states.connected&&(c.logAction(c.LOG_MINOR, -"ConnectionManager caught browser \u2018offline\u2019 event","disconnecting active transport"),k.disconnectAllTransports())})}var a=!("undefined"===typeof J||!J.get),e=!("undefined"===typeof J||!J.getSession),m=w.Action,f=ga.PendingMessage,k=function(){},p=q.transportPreferenceOrder,n=p[p.length-1];l.prototype.getConnectParams=function(a){a=a?h.copy(a):{};var b=this.options;switch(this.mode){case "upgrade":a.upgrade=this.connectionKey;break;case "resume":a.resume=this.connectionKey;void 0!==this.connectionSerial&& -(a.connection_serial=this.connectionSerial);break;case "recover":var c=b.recover.split(":");c&&(a.recover=c[0],a.connection_serial=c[1])}void 0!==b.clientId&&(a.clientId=b.clientId);!1===b.echoMessages&&(a.echo="false");void 0!==this.format&&(a.format=this.format);void 0!==this.stream&&(a.stream=this.stream);void 0!==this.heartbeats&&(a.heartbeats=this.heartbeats);void 0!==b.transportParams&&h.mixin(a,b.transportParams);a.v=q.apiVersion;a.lib=q.libstring;return a};h.inherits(b,z);b.supportedTransports= -{};b.prototype.getTransportParams=function(a){var b=this;(function(a){if(b.connectionKey)a("resume");else if("string"===typeof b.options.recover)a("recover");else{var g=b.options.recover,d=e&&J.getSession("ably-connection-recovery");d&&"function"===typeof g?(c.logAction(c.LOG_MINOR,"ConnectionManager.getTransportParams()","Calling clientOptions-provided recover function with last session data"),g(d,function(c){c?(b.options.recover=d.recoveryKey,a("recover")):a("clean")})):a("clean")}})(function(e){c.logAction(c.LOG_MINOR, -"ConnectionManager.getTransportParams()","Transport recovery mode = "+e+("clean"==e?"":"; connectionKey = "+b.connectionKey+"; connectionSerial = "+b.connectionSerial));a(new l(b.options,null,e,b.connectionKey,b.connectionSerial))})};b.prototype.tryATransport=function(a,e,d){var f=this,k=a.host;c.logAction(c.LOG_MICRO,"ConnectionManager.tryATransport()","trying "+e);k in this.transportHostBlacklist&&h.arrIn(this.transportHostBlacklist[k],e)?c.logAction(c.LOG_MINOR,"ConnectionManager.tryATransport()", -e+" transport is blacklisted for host "+a.host):b.supportedTransports[e].tryConnect(this,this.realtime.auth,a,function(b,k){var n=f.state;n==f.states.closing||n==f.states.closed||n==f.states.failed?(k&&(c.logAction(c.LOG_MINOR,"ConnectionManager.tryATransport()","connection "+n.state+" while we were attempting the transport; closing "+k),k.close()),d(!0)):b?(c.logAction(c.LOG_MINOR,"ConnectionManager.tryATransport()","transport "+e+" "+b.event+", err: "+b.error.toString()),N.isTokenErr(b.error)?f.realtime.auth._forceNewToken(null, -null,function(b){b?f.actOnErrorFromAuthorize(b):f.tryATransport(a,e,d)}):"failed"===b.event?(f.notifyState({state:"failed",error:b.error}),d(!0)):"disconnected"===b.event&&d(!1)):(c.logAction(c.LOG_MICRO,"ConnectionManager.chooseTransportForHost()","viable transport "+e+"; setting pending"),f.setTransportPending(k,a),d(null,k))})};b.prototype.setTransportPending=function(a,b){var e=b.mode;c.logAction(c.LOG_MINOR,"ConnectionManager.setTransportPending()","transport = "+a+"; mode = "+e);h.arrDeleteValue(this.proposedTransports, -a);this.pendingTransports.push(a);var d=this;a.once("connected",function(c,f,k,p,m){"upgrade"==e&&d.activeProtocol?a.shortName!==n&&h.arrIn(d.getUpgradePossibilities(),n)?setTimeout(function(){d.scheduleTransportActivation(c,a,f,k,p,m)},d.options.timeouts.parallelUpgradeDelay):d.scheduleTransportActivation(c,a,f,k,p,m):(d.activateTransport(c,a,f,k,p,m),h.nextTick(function(){d.connectImpl(b)}));"recover"===e&&d.options.recover&&(d.options.recover=null,d.unpersistConnection())});a.on(["disconnected", -"closed","failed"],function(b){d.deactivateTransport(a,this.event,b)});this.emit("transport.pending",a)};b.prototype.scheduleTransportActivation=function(a,b,e,f,k,n){var p=this,m=this.activeProtocol&&this.activeProtocol.getTransport(),l=function(){b.disconnect();h.arrDeleteValue(p.pendingTransports,b)};this.state!==this.states.connected&&this.state!==this.states.connecting?(c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Current connection state ("+this.state.state+(this.state=== -this.states.synchronizing?", but with an upgrade already in progress":"")+") is not valid to upgrade in; abandoning upgrade to "+b.shortName),l()):m&&!d(b,m)?(c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Proposed transport "+b.shortName+" is no better than current active transport "+m.shortName+" - abandoning upgrade"),l()):(c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Scheduling transport upgrade; transport = "+b),this.realtime.channels.onceNopending(function(d){var m; -if(d)c.logAction(c.LOG_ERROR,"ConnectionManager.scheduleTransportActivation()","Unable to activate transport; transport = "+b+"; err = "+d);else if(b.isConnected){if(p.state===p.states.connected)c.logAction(c.LOG_MICRO,"ConnectionManager.scheduleTransportActivation()","Currently connected, so temporarily pausing events until the upgrade is complete"),p.state=p.states.synchronizing,m=p.activeProtocol;else if(p.state!==p.states.connecting){c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()", -"Current connection state ("+p.state.state+(p.state===p.states.synchronizing?", but with an upgrade already in progress":"")+") is not valid to upgrade in; abandoning upgrade to "+b.shortName);l();return}var h=(d=k!==p.connectionId)?f:p.connectionSerial;d&&c.logAction(c.LOG_ERROR,"ConnectionManager.scheduleTransportActivation()","Upgrade resulted in new connectionId; resetting library connectionSerial from "+p.connectionSerial+" to "+h+"; upgrade error was "+a);c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()", -"Syncing transport; transport = "+b);p.sync(b,function(d,f,k){if(d)p.state===p.states.synchronizing&&(c.logAction(c.LOG_ERROR,"ConnectionManager.scheduleTransportActivation()","Unexpected error attempting to sync transport; transport = "+b+"; err = "+d),p.disconnectAllTransports());else if(d=function(){c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Activating transport; transport = "+b);p.activateTransport(a,b,e,f,k,n);p.state===p.states.synchronizing?(c.logAction(c.LOG_MICRO, -"ConnectionManager.scheduleTransportActivation()","Pre-upgrade protocol idle, sending queued messages on upgraded transport; transport = "+b),p.state=p.states.connected):c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Pre-upgrade protocol idle, but state is now "+p.state.state+", so leaving unchanged");p.state.sendEvents&&p.sendQueuedMessages()},m)m.onceIdle(d);else d()})}else c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Proposed transport "+ -b.shortName+"is no longer connected; abandoning upgrade"),l()}))};b.prototype.activateTransport=function(a,b,e,d,f,k){c.logAction(c.LOG_MINOR,"ConnectionManager.activateTransport()","transport = "+b);a&&c.logAction(c.LOG_ERROR,"ConnectionManager.activateTransport()","error = "+a);e&&c.logAction(c.LOG_MICRO,"ConnectionManager.activateTransport()","connectionKey = "+e);void 0!==d&&c.logAction(c.LOG_MICRO,"ConnectionManager.activateTransport()","connectionSerial = "+d);f&&c.logAction(c.LOG_MICRO,"ConnectionManager.activateTransport()", -"connectionId = "+f);k&&c.logAction(c.LOG_MICRO,"ConnectionManager.activateTransport()","connectionDetails = "+JSON.stringify(k));this.persistTransportPreference(b);var n=this.state,p=this.states.connected.state;c.logAction(c.LOG_MINOR,"ConnectionManager.activateTransport()","current state = "+n.state);if(n.state==this.states.closing.state||n.state==this.states.closed.state||n.state==this.states.failed.state)return c.logAction(c.LOG_MINOR,"ConnectionManager.activateTransport()","Disconnecting transport and abandoning"), -b.disconnect(),!1;h.arrDeleteValue(this.pendingTransports,b);if(!b.isConnected)return c.logAction(c.LOG_MINOR,"ConnectionManager.activateTransport()","Declining to activate transport "+b+" since it appears to no longer be connected"),!1;var m=this.activeProtocol;this.activeProtocol=new ga(b);this.host=b.params.host;e&&this.connectionKey!=e&&this.setConnection(f,e,d);this.onConnectionDetailsUpdate(k,b);var l=this;h.nextTick(function(){b.on("connected",function(a,c,e,g,d){l.onConnectionDetailsUpdate(d, -b);l.emit("update",new R(p,p,null,a))})});n.state===this.states.connected.state?a&&(this.errorReason=this.realtime.connection.errorReason=a,this.emit("update",new R(p,p,null,a))):(this.notifyState({state:"connected",error:a}),this.errorReason=this.realtime.connection.errorReason=a||null);this.emit("transport.active",b,e,b.params);m&&(0this.connectionStateTtl+this.maxIdleInterval&&(c.logAction(c.LOG_MINOR,"ConnectionManager.checkConnectionStateFreshness()","Last known activity from realtime was "+a+"ms ago; discarding connection state"),this.clearConnection(),this.states.connecting.failState="suspended",this.states.connecting.queueEvents=!1)}};b.prototype.persistConnection=function(){if(e&&this.connectionKey&&void 0!==this.connectionSerial){var a= -{recoveryKey:this.connectionKey+":"+this.connectionSerial,disconnectedAt:h.now(),location:window.location,clientId:this.realtime.auth.clientId};e&&J.setSession("ably-connection-recovery",a)}};b.prototype.unpersistConnection=function(){e&&J.removeSession("ably-connection-recovery")};b.prototype.getStateError=function(){return K[this.state.state]};b.prototype.activeState=function(){return this.state.queueEvents||this.state.sendEvents};b.prototype.enactStateChange=function(a){c.logAction("failed"=== -a.current?c.LOG_ERROR:c.LOG_MAJOR,"Connection state",a.current+(a.reason?"; reason: "+a.reason.message+", code: "+a.reason.code:""));c.logAction(c.LOG_MINOR,"ConnectionManager.enactStateChange","setting new state: "+a.current+"; reason = "+(a.reason&&a.reason.message));var b=this.state=this.states[a.current];a.reason&&(this.errorReason=a.reason,this.realtime.connection.errorReason=a.reason);(b.terminal||"suspended"===b.state)&&this.clearConnection();this.emit("connectionstate",a)};b.prototype.startTransitionTimer= -function(a){c.logAction(c.LOG_MINOR,"ConnectionManager.startTransitionTimer()","transitionState: "+a.state);this.transitionTimer&&(c.logAction(c.LOG_MINOR,"ConnectionManager.startTransitionTimer()","clearing already-running timer"),clearTimeout(this.transitionTimer));var b=this;this.transitionTimer=setTimeout(function(){b.transitionTimer&&(b.transitionTimer=null,c.logAction(c.LOG_MINOR,"ConnectionManager "+a.state+" timer expired","requesting new state: "+a.failState),b.notifyState({state:a.failState}))}, -a.retryDelay)};b.prototype.cancelTransitionTimer=function(){c.logAction(c.LOG_MINOR,"ConnectionManager.cancelTransitionTimer()","");this.transitionTimer&&(clearTimeout(this.transitionTimer),this.transitionTimer=null)};b.prototype.startSuspendTimer=function(){var a=this;this.suspendTimer||(this.suspendTimer=setTimeout(function(){a.suspendTimer&&(a.suspendTimer=null,c.logAction(c.LOG_MINOR,"ConnectionManager suspend timer expired","requesting new state: suspended"),a.states.connecting.failState="suspended", -a.states.connecting.queueEvents=!1,a.notifyState({state:"suspended"}))},this.connectionStateTtl))};b.prototype.checkSuspendTimer=function(a){"disconnected"!==a&&"suspended"!==a&&"connecting"!==a&&this.cancelSuspendTimer()};b.prototype.cancelSuspendTimer=function(){this.states.connecting.failState="disconnected";this.states.connecting.queueEvents=!0;this.suspendTimer&&(clearTimeout(this.suspendTimer),this.suspendTimer=null)};b.prototype.startRetryTimer=function(a){var b=this;this.retryTimer=setTimeout(function(){c.logAction(c.LOG_MINOR, -"ConnectionManager retry timer expired","retrying");b.retryTimer=null;b.requestState({state:"connecting"})},a)};b.prototype.cancelRetryTimer=function(){this.retryTimer&&(clearTimeout(this.retryTimer),this.retryTimer=null)};b.prototype.notifyState=function(a){var b=a.state,e=this,d="disconnected"===b&&(this.state===this.states.connected||this.state===this.states.synchronizing||this.state===this.states.connecting&&a.error&&N.isTokenErr(a.error));c.logAction(c.LOG_MINOR,"ConnectionManager.notifyState()", -"new state: "+b+(d?"; will retry connection immediately":""));if(b!=this.state.state&&(this.cancelTransitionTimer(),this.cancelRetryTimer(),this.checkSuspendTimer(a.state),!this.state.terminal)){var f=this.states[a.state];a=new R(this.state.state,f.state,f.retryDelay,a.error||K[f.state]);if(d){var k=function(){e.state===e.states.disconnected&&(e.lastAutoReconnectAttempt=h.now(),e.requestState({state:"connecting"}))},n=this.lastAutoReconnectAttempt&&h.now()-this.lastAutoReconnectAttempt+1;n&&1E3>n? -(c.logAction(c.LOG_MICRO,"ConnectionManager.notifyState()","Last reconnect attempt was only "+n+"ms ago, waiting another "+(1E3-n)+"ms before trying again"),setTimeout(k,1E3-n)):h.nextTick(k)}else"disconnected"!==b&&"suspended"!==b||this.startRetryTimer(f.retryDelay);("disconnected"===b&&!d||"suspended"===b||f.terminal)&&h.nextTick(function(){e.disconnectAllTransports()});"connected"!=b||this.activeProtocol||c.logAction(c.LOG_ERROR,"ConnectionManager.notifyState()","Broken invariant: attempted to go into connected state, but there is no active protocol"); -this.enactStateChange(a);this.state.sendEvents?this.sendQueuedMessages():this.state.queueEvents||(this.realtime.channels.propogateConnectionInterruption(b,a.reason),this.failQueuedMessages(a.reason))}};b.prototype.requestState=function(a){var b=a.state,e=this;c.logAction(c.LOG_MINOR,"ConnectionManager.requestState()","requested state: "+b+"; current state: "+this.state.state);if(b!=this.state.state&&(this.cancelTransitionTimer(),this.cancelRetryTimer(),this.checkSuspendTimer(b),"connecting"!=b||"connected"!= -this.state.state)&&("closing"!=b||"closed"!=this.state.state)){var d=this.states[b];a=new R(this.state.state,d.state,null,a.error||K[d.state]);this.enactStateChange(a);"connecting"==b&&h.nextTick(function(){e.startConnect()});"closing"==b&&this.closeImpl()}};b.prototype.startConnect=function(){if(this.state!==this.states.connecting)c.logAction(c.LOG_MINOR,"ConnectionManager.startConnect()","Must be in connecting state to connect, but was "+this.state.state);else{var a=this.realtime.auth,b=this,e= -function(){b.checkConnectionStateFreshness();b.getTransportParams(function(a){b.connectImpl(a)})};c.logAction(c.LOG_MINOR,"ConnectionManager.startConnect()","starting connection");this.startSuspendTimer();this.startTransitionTimer(this.states.connecting);if("basic"===a.method)e();else{var d=function(a){a?b.actOnErrorFromAuthorize(a):e()};this.errorReason&&N.isTokenErr(this.errorReason)?a._forceNewToken(null,null,d):a._ensureValidAuthCredentials(d)}}};b.prototype.connectImpl=function(a){var b=this.state.state; +1),this.offset+=3,this.str(a);case 219:return a=this.view.getUint32(this.offset+1),this.offset+=5,this.str(a);case 220:return a=this.view.getUint16(this.offset+1),this.offset+=3,this.array(a);case 221:return a=this.view.getUint32(this.offset+1),this.offset+=5,this.array(a);case 222:return a=this.view.getUint16(this.offset+1),this.offset+=3,this.map(a);case 223:return a=this.view.getUint32(this.offset+1),this.offset+=5,this.map(a)}throw Error("Unknown type 0x"+a.toString(16));};return m}();"object"!== +typeof window&&console.log("Warning: this distribution of Ably is intended for browsers. On nodejs, please use the 'ably' package on npm");var w={libver:"js-web-",noUpgrade:navigator&&navigator.userAgent.toString().match(/MSIE\s8\.0/),binaryType:"arraybuffer",WebSocket:window.WebSocket||window.MozWebSocket,xhrSupported:window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest,streamingSupported:!0,useProtocolHeartbeats:!0,createHmac:null,msgpack:fa,supportsBinary:!!window.TextDecoder,preferBinary:!1, +ArrayBuffer:window.ArrayBuffer,atob:window.atob,nextTick:function(c){setTimeout(c,0)},addEventListener:window.addEventListener,inspect:JSON.stringify,getRandomValues:function(c){return function(g,b){c.getRandomValues(g);b(null)}}(window.crypto||window.msCrypto)},V=function(){function e(){}function g(){this.key=this.mode=this.keyLength=this.algorithm=null}function b(a,b,d){this.algorithm=a.algorithm+"-"+String(a.keyLength)+"-"+a.mode;this.cjsAlgorithm=a.algorithm.toUpperCase().replace(/-\d+$/,""); +this.key=B.toWordArray(a.key);d&&(this.iv=B.toWordArray(d).clone());this.blockLengthWords=b}var a=D.lib.WordArray,d;if("undefined"!==typeof Uint32Array&&w.getRandomValues){var l=new Uint32Array(4);d=function(a,b){var d=a/4,h=4==d?l:new Uint32Array(d);w.getRandomValues(h,function(a){b(a,B.toWordArray(h))})}}else d=function(b,d){c.logAction(c.LOG_MAJOR,"Ably.Crypto.generateRandom()","Warning: the browser you are using does not support secure cryptographically secure randomness generation; falling back to insecure Math.random()"); +for(var f=b/4,h=Array(f),e=0;e>>2]>>>24-n%4*8&255;return b}throw Error("BufferUtils.toArrayBuffer expected a buffer"); +};b.toWordArray=function(b){return c(b)?b:a.create(b)};b.base64Encode=function(a){if(g(a)){var b="";a=new Uint8Array(a);for(var d=a.byteLength,l=d%3,d=d-l,h,u,t,k,C=0;C>18,u=(k&258048)>>12,t=(k&4032)>>6,k&=63,b+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[h]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[u]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[t]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[k]; +1==l?(k=a[d],b+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(k&252)>>2]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(k&3)<<4]+"=="):2==l&&(k=a[d]<<8|a[d+1],b+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(k&64512)>>10]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(k&1008)>>4]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(k&15)<<2]+"=");return b}if(c(a))return D.enc.Base64.stringify(a)}; +b.base64Decode=function(a){if(d&&l){a=l(a);for(var b=a.length,c=new Uint8Array(b),e=0;e=b}var b=function(){};c.get=function(a,d,l,f,m){m=m||b;var q="function"==typeof d?d:function(b){return a.baseUri(b)+d},n;n=(n=a.connection)&&"connected"== +n.state?[n.connectionManager.host]:p.getHosts(a.options);if(1==n.length)c.getUri(a,q(n[0]),l,f,m);else{var h=function(b){c.getUri(a,q(b.shift()),l,f,function(a){a&&g(a)&&b.length?h(b):m.apply(null,arguments)})};h(n)}};c.getUri=function(a,d,l,f,m){c.Request(a,d,l,f,null,m||b)};c.post=function(a,d,l,f,m,q){q=q||b;var n="function"==typeof d?d:function(b){return a.baseUri(b)+d},h;h=(h=a.connection)&&"connected"==h.state?[h.connectionManager.host]:p.getHosts(a.options);if(1==h.length)c.postUri(a,n(h[0]), +l,f,m,q);else{var u=function(b){c.postUri(a,n(b.shift()),l,f,m,function(a){a&&g(a)&&b.length?u(b):q.apply(null,arguments)})};u(h)}};c.postUri=function(a,d,l,f,m,q){c.Request(a,d,l,m,f,q||b)};c.supportsAuthHeaders=!1;c.supportsLinkHeaders=!1;return c}(),ja=function(){function c(){this.buffer=[]}function g(a){this._input=a;this._index=-1;this._buffer=[]}function b(a){this._input=a;this._index=-1;this._buffer=[]}c.prototype.append=function(a){this.buffer.push(a);return this};c.prototype.toString=function(){return this.buffer.join("")}; +var a={codex:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(b){var l=new c,f=a.codex;for(b=new g(b);b.moveNext();){var m=b.current;b.moveNext();var q=b.current;b.moveNext();var n=b.current,h=m>>2,m=(m&3)<<4|q>>4,u=(q&15)<<2|n>>6,t=n&63;isNaN(q)?u=t=64:isNaN(n)&&(t=64);l.append(f.charAt(h)+f.charAt(m)+f.charAt(u)+f.charAt(t))}return l.toString()},decode:function(a){var l=new c;for(a=new b(a);a.moveNext();){var f=a.current;if(128>f)l.append(String.fromCharCode(f)); +else if(191f){a.moveNext();var m=a.current;l.append(String.fromCharCode((f&31)<<6|m&63))}else a.moveNext(),m=a.current,a.moveNext(),l.append(String.fromCharCode((f&15)<<12|(m&63)<<6|a.current&63))}return l.toString()}};g.prototype={current:Number.NaN,moveNext:function(){if(0=this._input.length-1)return this.current=Number.NaN,!1;var a=this._input.charCodeAt(++this._index);13==a&&10==this._input.charCodeAt(this._index+ +1)&&(a=10,this._index+=2);128>a?this.current=a:(127a?this.current=a>>6|192:(this.current=a>>12|224,this._buffer.push(a>>6&63|128)),this._buffer.push(a&63|128));return!0}};b.prototype={current:64,moveNext:function(){if(0=this._input.length-1)return this.current=64,!1;var b=a.codex.indexOf(this._input.charAt(++this._index)),c=a.codex.indexOf(this._input.charAt(++this._index)),f=a.codex.indexOf(this._input.charAt(++this._index)), +m=a.codex.indexOf(this._input.charAt(++this._index)),e=(f&3)<<6|m;this.current=b<<2|c>>4;64!=f&&this._buffer.push((c&15)<<4|f>>2);64!=m&&this._buffer.push(e);return!0}};return a}();p.protocolVersion=1;p.ENVIRONMENT="";p.REST_HOST="rest.ably.io";p.REALTIME_HOST="realtime.ably.io";p.FALLBACK_HOSTS=["A.ably-realtime.com","B.ably-realtime.com","C.ably-realtime.com","D.ably-realtime.com","E.ably-realtime.com"];p.PORT=80;p.TLS_PORT=443;p.TIMEOUTS={disconnectedRetryTimeout:15E3,suspendedRetryTimeout:3E4, +httpRequestTimeout:15E3,channelRetryTimeout:15E3,connectionStateTtl:12E4,realtimeRequestTimeout:1E4,recvTimeout:9E4,preferenceConnectTimeout:6E3,parallelUpgradeDelay:4E3};p.httpMaxRetryCount=3;p.version="1.0.4";p.libstring=w.libver+p.version;p.apiVersion="1.0";p.getHost=function(c,g,b){return g=b?g==c.restHost&&c.realtimeHost||g||c.realtimeHost:g||c.restHost};p.getPort=function(c,g){return g||c.tls?c.tlsPort:c.port};p.getHttpScheme=function(c){return c.tls?"https://":"http://"};p.getHosts=function(c){var g= +[c.restHost],b=c.fallbackHosts;c="undefined"!==typeof c.httpMaxRetryCount?c.httpMaxRetryCount:p.httpMaxRetryCount;b&&(g=g.concat(k.arrChooseN(b,c)));return g};p.normaliseOptions=function(e){e.host&&(c.deprecated("host","restHost"),e.restHost=e.host);e.wsHost&&(c.deprecated("wsHost","realtimeHost"),e.realtimeHost=e.wsHost);e.queueEvents&&(c.deprecated("queueEvents","queueMessages"),e.queueMessages=e.queueEvents);!0===e.recover&&(c.deprecated("{recover: true}","{recover: function(lastConnectionDetails, cb) { cb(true); }}"), +e.recover=function(a,b){b(!0)});"function"===typeof e.recover&&!0===e.closeOnUnload&&(c.logAction(LOG_ERROR,"Defaults.normaliseOptions","closeOnUnload was true and a session recovery function was set - these are mutually exclusive, so unsetting the latter"),e.recover=null);e.transports&&k.arrIn(e.transports,"xhr")&&(c.deprecated('transports: ["xhr"]','transports: ["xhr_streaming"]'),k.arrDeleteValue(e.transports,"xhr"),e.transports.push("xhr_streaming"));"queueMessages"in e||(e.queueMessages=!0); +var g=!1;if(e.restHost)e.realtimeHost=e.realtimeHost||e.restHost;else{var b=e.environment&&String(e.environment).toLowerCase()||p.ENVIRONMENT,g=!b||"production"===b;e.restHost=g?p.REST_HOST:b+"-"+p.REST_HOST;e.realtimeHost=g?p.REALTIME_HOST:b+"-"+p.REALTIME_HOST}e.fallbackHosts=g||e.fallbackHostsUseDefault?p.FALLBACK_HOSTS:e.fallbackHosts;e.port=e.port||p.PORT;e.tlsPort=e.tlsPort||p.TLS_PORT;"tls"in e||(e.tls=!0);e.timeouts={};for(var a in p.TIMEOUTS)e.timeouts[a]=e[a]||p.TIMEOUTS[a];e.useBinaryProtocol= +"useBinaryProtocol"in e?w.supportsBinary&&e.useBinaryProtocol:w.preferBinary;return e};var z=function(){function e(){this.any=[];this.events={};this.anyOnce=[];this.eventsOnce={}}function g(a,b,e){try{b.apply(a,e)}catch(f){c.logAction(c.LOG_ERROR,"EventEmitter.emit()","Unexpected listener exception: "+f+"; stack = "+f.stack)}}function b(a,d,c){var f,m,e,n;for(n=0;n=e?null:c.slice(0,e).join("/"),b.data=m}}};e.fromResponseBody=function(b,a,d){d&&(b="msgpack"==d?g.decode(b):JSON.parse(String(b)));for(d=0;dk.arrIndexOf(q,b.shortName)}function g(a,b,c,d,f){this.options=a;this.host=b;this.mode=c;this.connectionKey=d;this.connectionSerial=f;this.format=a.useBinaryProtocol?"msgpack": +"json"}function b(a,f){z.call(this);this.realtime=a;this.options=f;var e=f.timeouts,m=this;this.states={initialized:{state:"initialized",terminal:!1,queueEvents:!0,sendEvents:!1,failState:"disconnected"},connecting:{state:"connecting",terminal:!1,queueEvents:!0,sendEvents:!1,retryDelay:e.preferenceConnectTimeout+e.realtimeRequestTimeout,failState:"disconnected"},connected:{state:"connected",terminal:!1,queueEvents:!1,sendEvents:!0,failState:"disconnected"},synchronizing:{state:"connected",terminal:!1, +queueEvents:!0,sendEvents:!1,forceQueueEvents:!0,failState:"disconnected"},disconnected:{state:"disconnected",terminal:!1,queueEvents:!0,sendEvents:!1,retryDelay:e.disconnectedRetryTimeout,failState:"disconnected"},suspended:{state:"suspended",terminal:!1,queueEvents:!1,sendEvents:!1,retryDelay:e.suspendedRetryTimeout,failState:"suspended"},closing:{state:"closing",terminal:!1,queueEvents:!1,sendEvents:!1,retryDelay:e.realtimeRequestTimeout,failState:"closed"},closed:{state:"closed",terminal:!0,queueEvents:!1, +sendEvents:!1,failState:"closed"},failed:{state:"failed",terminal:!0,queueEvents:!1,sendEvents:!1,failState:"failed"}};this.state=this.states.initialized;this.errorReason=null;this.queuedMessages=new ga;this.msgSerial=0;this.connectionSerial=this.connectionKey=this.connectionId=void 0;this.connectionStateTtl=e.connectionStateTtl;this.maxIdleInterval=null;this.transports=k.intersect(f.transports||p.defaultTransports,b.supportedTransports);this.baseTransport=k.intersect(p.baseTransportOrder,this.transports)[0]; +this.upgradeTransports=k.intersect(this.transports,p.upgradeTransports);this.transportHostBlacklist={};this.transportPreference=null;this.httpHosts=p.getHosts(f);this.activeProtocol=null;this.proposedTransports=[];this.pendingTransports=[];this.mostRecentMsgId=this.lastActivity=this.lastAutoReconnectAttempt=this.host=null;c.logAction(c.LOG_MINOR,"Realtime.ConnectionManager()","started");c.logAction(c.LOG_MICRO,"Realtime.ConnectionManager()","requested transports = ["+(f.transports||p.defaultTransports)+ +"]");c.logAction(c.LOG_MICRO,"Realtime.ConnectionManager()","available transports = ["+this.transports+"]");c.logAction(c.LOG_MICRO,"Realtime.ConnectionManager()","http hosts = ["+this.httpHosts+"]");if(!this.transports.length)throw c.logAction(c.LOG_ERROR,"realtime.ConnectionManager()","no requested transports available"),Error("no requested transports available");if(e=w.addEventListener)d&&"function"===typeof f.recover&&e("beforeunload",this.persistConnection.bind(this)),!0===f.closeOnUnload&&e("beforeunload", +function(){m.requestState({state:"closing"})}),e("online",function(){if(m.state==m.states.disconnected||m.state==m.states.suspended)c.logAction(c.LOG_MINOR,"ConnectionManager caught browser \u2018online\u2019 event","reattempting connection"),m.requestState({state:"connecting"})}),e("offline",function(){m.state==m.states.connected&&(c.logAction(c.LOG_MINOR,"ConnectionManager caught browser \u2018offline\u2019 event","disconnecting active transport"),m.disconnectAllTransports())})}var a=!("undefined"=== +typeof K||!K.get),d=!("undefined"===typeof K||!K.getSession),l=y.Action,f=ha.PendingMessage,m=function(){},q=p.transportPreferenceOrder,n=q[q.length-1];g.prototype.getConnectParams=function(a){a=a?k.copy(a):{};var b=this.options;switch(this.mode){case "upgrade":a.upgrade=this.connectionKey;break;case "resume":a.resume=this.connectionKey;void 0!==this.connectionSerial&&(a.connection_serial=this.connectionSerial);break;case "recover":var c=b.recover.split(":");c&&(a.recover=c[0],a.connection_serial= +c[1])}void 0!==b.clientId&&(a.clientId=b.clientId);!1===b.echoMessages&&(a.echo="false");void 0!==this.format&&(a.format=this.format);void 0!==this.stream&&(a.stream=this.stream);void 0!==this.heartbeats&&(a.heartbeats=this.heartbeats);void 0!==b.transportParams&&k.mixin(a,b.transportParams);a.v=p.apiVersion;a.lib=p.libstring;return a};k.inherits(b,z);b.supportedTransports={};b.prototype.getTransportParams=function(a){var b=this;(function(a){if(b.connectionKey)a("resume");else if("string"===typeof b.options.recover)a("recover"); +else{var h=b.options.recover,f=d&&K.getSession("ably-connection-recovery");f&&"function"===typeof h?(c.logAction(c.LOG_MINOR,"ConnectionManager.getTransportParams()","Calling clientOptions-provided recover function with last session data"),h(f,function(c){c?(b.options.recover=f.recoveryKey,a("recover")):a("clean")})):a("clean")}})(function(d){c.logAction(c.LOG_MINOR,"ConnectionManager.getTransportParams()","Transport recovery mode = "+d+("clean"==d?"":"; connectionKey = "+b.connectionKey+"; connectionSerial = "+ +b.connectionSerial));a(new g(b.options,null,d,b.connectionKey,b.connectionSerial))})};b.prototype.tryATransport=function(a,d,f){var e=this,m=a.host;c.logAction(c.LOG_MICRO,"ConnectionManager.tryATransport()","trying "+d);m in this.transportHostBlacklist&&k.arrIn(this.transportHostBlacklist[m],d)?c.logAction(c.LOG_MINOR,"ConnectionManager.tryATransport()",d+" transport is blacklisted for host "+a.host):b.supportedTransports[d].tryConnect(this,this.realtime.auth,a,function(b,m){var n=e.state;n==e.states.closing|| +n==e.states.closed||n==e.states.failed?(m&&(c.logAction(c.LOG_MINOR,"ConnectionManager.tryATransport()","connection "+n.state+" while we were attempting the transport; closing "+m),m.close()),f(!0)):b?(c.logAction(c.LOG_MINOR,"ConnectionManager.tryATransport()","transport "+d+" "+b.event+", err: "+b.error.toString()),O.isTokenErr(b.error)?e.realtime.auth._forceNewToken(null,null,function(b){b?e.actOnErrorFromAuthorize(b):e.tryATransport(a,d,f)}):"failed"===b.event?(e.notifyState({state:"failed",error:b.error}), +f(!0)):"disconnected"===b.event&&f(!1)):(c.logAction(c.LOG_MICRO,"ConnectionManager.chooseTransportForHost()","viable transport "+d+"; setting pending"),e.setTransportPending(m,a),f(null,m))})};b.prototype.setTransportPending=function(a,b){var d=b.mode;c.logAction(c.LOG_MINOR,"ConnectionManager.setTransportPending()","transport = "+a+"; mode = "+d);k.arrDeleteValue(this.proposedTransports,a);this.pendingTransports.push(a);var f=this;a.once("connected",function(c,e,m,l,q){"upgrade"==d&&f.activeProtocol? +a.shortName!==n&&k.arrIn(f.getUpgradePossibilities(),n)?setTimeout(function(){f.scheduleTransportActivation(c,a,e,m,l,q)},f.options.timeouts.parallelUpgradeDelay):f.scheduleTransportActivation(c,a,e,m,l,q):(f.activateTransport(c,a,e,m,l,q),k.nextTick(function(){f.connectImpl(b)}));"recover"===d&&f.options.recover&&(f.options.recover=null,f.unpersistConnection())});a.on(["disconnected","closed","failed"],function(b){f.deactivateTransport(a,this.event,b)});this.emit("transport.pending",a)};b.prototype.scheduleTransportActivation= +function(a,b,d,f,m,n){var l=this,q=this.activeProtocol&&this.activeProtocol.getTransport(),g=function(){b.disconnect();k.arrDeleteValue(l.pendingTransports,b)};this.state!==this.states.connected&&this.state!==this.states.connecting?(c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Current connection state ("+this.state.state+(this.state===this.states.synchronizing?", but with an upgrade already in progress":"")+") is not valid to upgrade in; abandoning upgrade to "+b.shortName), +g()):q&&!e(b,q)?(c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Proposed transport "+b.shortName+" is no better than current active transport "+q.shortName+" - abandoning upgrade"),g()):(c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Scheduling transport upgrade; transport = "+b),this.realtime.channels.onceNopending(function(e){var q;if(e)c.logAction(c.LOG_ERROR,"ConnectionManager.scheduleTransportActivation()","Unable to activate transport; transport = "+ +b+"; err = "+e);else if(b.isConnected){if(l.state===l.states.connected)c.logAction(c.LOG_MICRO,"ConnectionManager.scheduleTransportActivation()","Currently connected, so temporarily pausing events until the upgrade is complete"),l.state=l.states.synchronizing,q=l.activeProtocol;else if(l.state!==l.states.connecting){c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Current connection state ("+l.state.state+(l.state===l.states.synchronizing?", but with an upgrade already in progress": +"")+") is not valid to upgrade in; abandoning upgrade to "+b.shortName);g();return}var k=(e=m!==l.connectionId)?f:l.connectionSerial;e&&c.logAction(c.LOG_ERROR,"ConnectionManager.scheduleTransportActivation()","Upgrade resulted in new connectionId; resetting library connectionSerial from "+l.connectionSerial+" to "+k+"; upgrade error was "+a);c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Syncing transport; transport = "+b);l.sync(b,function(f,e,m){if(f)l.state===l.states.synchronizing&& +(c.logAction(c.LOG_ERROR,"ConnectionManager.scheduleTransportActivation()","Unexpected error attempting to sync transport; transport = "+b+"; err = "+f),l.disconnectAllTransports());else if(f=function(){c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Activating transport; transport = "+b);l.activateTransport(a,b,d,e,m,n);l.state===l.states.synchronizing?(c.logAction(c.LOG_MICRO,"ConnectionManager.scheduleTransportActivation()","Pre-upgrade protocol idle, sending queued messages on upgraded transport; transport = "+ +b),l.state=l.states.connected):c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Pre-upgrade protocol idle, but state is now "+l.state.state+", so leaving unchanged");l.state.sendEvents&&l.sendQueuedMessages()},q)q.onceIdle(f);else f()})}else c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Proposed transport "+b.shortName+"is no longer connected; abandoning upgrade"),g()}))};b.prototype.activateTransport=function(a,b,d,f,e,m){c.logAction(c.LOG_MINOR, +"ConnectionManager.activateTransport()","transport = "+b);a&&c.logAction(c.LOG_ERROR,"ConnectionManager.activateTransport()","error = "+a);d&&c.logAction(c.LOG_MICRO,"ConnectionManager.activateTransport()","connectionKey = "+d);void 0!==f&&c.logAction(c.LOG_MICRO,"ConnectionManager.activateTransport()","connectionSerial = "+f);e&&c.logAction(c.LOG_MICRO,"ConnectionManager.activateTransport()","connectionId = "+e);m&&c.logAction(c.LOG_MICRO,"ConnectionManager.activateTransport()","connectionDetails = "+ +JSON.stringify(m));this.persistTransportPreference(b);var n=this.state,l=this.states.connected.state;c.logAction(c.LOG_MINOR,"ConnectionManager.activateTransport()","current state = "+n.state);if(n.state==this.states.closing.state||n.state==this.states.closed.state||n.state==this.states.failed.state)return c.logAction(c.LOG_MINOR,"ConnectionManager.activateTransport()","Disconnecting transport and abandoning"),b.disconnect(),!1;k.arrDeleteValue(this.pendingTransports,b);if(!b.isConnected)return c.logAction(c.LOG_MINOR, +"ConnectionManager.activateTransport()","Declining to activate transport "+b+" since it appears to no longer be connected"),!1;var q=this.activeProtocol;this.activeProtocol=new ha(b);this.host=b.params.host;d&&this.connectionKey!=d&&this.setConnection(e,d,f);this.onConnectionDetailsUpdate(m,b);var g=this;k.nextTick(function(){b.on("connected",function(a,c,d,h,f){g.onConnectionDetailsUpdate(f,b);g.emit("update",new S(l,l,null,a))})});n.state===this.states.connected.state?a&&(this.errorReason=this.realtime.connection.errorReason= +a,this.emit("update",new S(l,l,null,a))):(this.notifyState({state:"connected",error:a}),this.errorReason=this.realtime.connection.errorReason=a||null);this.emit("transport.active",b,d,b.params);q&&(0this.connectionStateTtl+this.maxIdleInterval&&(c.logAction(c.LOG_MINOR,"ConnectionManager.checkConnectionStateFreshness()","Last known activity from realtime was "+a+"ms ago; discarding connection state"),this.clearConnection(),this.states.connecting.failState="suspended",this.states.connecting.queueEvents=!1)}};b.prototype.persistConnection=function(){if(d&&this.connectionKey&&void 0!==this.connectionSerial){var a={recoveryKey:this.connectionKey+ +":"+this.connectionSerial,disconnectedAt:k.now(),location:window.location,clientId:this.realtime.auth.clientId};d&&K.setSession("ably-connection-recovery",a)}};b.prototype.unpersistConnection=function(){d&&K.removeSession("ably-connection-recovery")};b.prototype.getStateError=function(){return L[this.state.state]};b.prototype.activeState=function(){return this.state.queueEvents||this.state.sendEvents};b.prototype.enactStateChange=function(a){c.logAction("failed"===a.current?c.LOG_ERROR:c.LOG_MAJOR, +"Connection state",a.current+(a.reason?"; reason: "+a.reason.message+", code: "+a.reason.code:""));c.logAction(c.LOG_MINOR,"ConnectionManager.enactStateChange","setting new state: "+a.current+"; reason = "+(a.reason&&a.reason.message));var b=this.state=this.states[a.current];a.reason&&(this.errorReason=a.reason,this.realtime.connection.errorReason=a.reason);(b.terminal||"suspended"===b.state)&&this.clearConnection();this.emit("connectionstate",a)};b.prototype.startTransitionTimer=function(a){c.logAction(c.LOG_MINOR, +"ConnectionManager.startTransitionTimer()","transitionState: "+a.state);this.transitionTimer&&(c.logAction(c.LOG_MINOR,"ConnectionManager.startTransitionTimer()","clearing already-running timer"),clearTimeout(this.transitionTimer));var b=this;this.transitionTimer=setTimeout(function(){b.transitionTimer&&(b.transitionTimer=null,c.logAction(c.LOG_MINOR,"ConnectionManager "+a.state+" timer expired","requesting new state: "+a.failState),b.notifyState({state:a.failState}))},a.retryDelay)};b.prototype.cancelTransitionTimer= +function(){c.logAction(c.LOG_MINOR,"ConnectionManager.cancelTransitionTimer()","");this.transitionTimer&&(clearTimeout(this.transitionTimer),this.transitionTimer=null)};b.prototype.startSuspendTimer=function(){var a=this;this.suspendTimer||(this.suspendTimer=setTimeout(function(){a.suspendTimer&&(a.suspendTimer=null,c.logAction(c.LOG_MINOR,"ConnectionManager suspend timer expired","requesting new state: suspended"),a.states.connecting.failState="suspended",a.states.connecting.queueEvents=!1,a.notifyState({state:"suspended"}))}, +this.connectionStateTtl))};b.prototype.checkSuspendTimer=function(a){"disconnected"!==a&&"suspended"!==a&&"connecting"!==a&&this.cancelSuspendTimer()};b.prototype.cancelSuspendTimer=function(){this.states.connecting.failState="disconnected";this.states.connecting.queueEvents=!0;this.suspendTimer&&(clearTimeout(this.suspendTimer),this.suspendTimer=null)};b.prototype.startRetryTimer=function(a){var b=this;this.retryTimer=setTimeout(function(){c.logAction(c.LOG_MINOR,"ConnectionManager retry timer expired", +"retrying");b.retryTimer=null;b.requestState({state:"connecting"})},a)};b.prototype.cancelRetryTimer=function(){this.retryTimer&&(clearTimeout(this.retryTimer),this.retryTimer=null)};b.prototype.notifyState=function(a){var b=a.state,d=this,f="disconnected"===b&&(this.state===this.states.connected||this.state===this.states.synchronizing||this.state===this.states.connecting&&a.error&&O.isTokenErr(a.error));c.logAction(c.LOG_MINOR,"ConnectionManager.notifyState()","new state: "+b+(f?"; will retry connection immediately": +""));if(b!=this.state.state&&(this.cancelTransitionTimer(),this.cancelRetryTimer(),this.checkSuspendTimer(a.state),!this.state.terminal)){var e=this.states[a.state];a=new S(this.state.state,e.state,e.retryDelay,a.error||L[e.state]);if(f){var m=function(){d.state===d.states.disconnected&&(d.lastAutoReconnectAttempt=k.now(),d.requestState({state:"connecting"}))},n=this.lastAutoReconnectAttempt&&k.now()-this.lastAutoReconnectAttempt+1;n&&1E3>n?(c.logAction(c.LOG_MICRO,"ConnectionManager.notifyState()", +"Last reconnect attempt was only "+n+"ms ago, waiting another "+(1E3-n)+"ms before trying again"),setTimeout(m,1E3-n)):k.nextTick(m)}else"disconnected"!==b&&"suspended"!==b||this.startRetryTimer(e.retryDelay);("disconnected"===b&&!f||"suspended"===b||e.terminal)&&k.nextTick(function(){d.disconnectAllTransports()});"connected"!=b||this.activeProtocol||c.logAction(c.LOG_ERROR,"ConnectionManager.notifyState()","Broken invariant: attempted to go into connected state, but there is no active protocol"); +this.enactStateChange(a);this.state.sendEvents?this.sendQueuedMessages():this.state.queueEvents||(this.realtime.channels.propogateConnectionInterruption(b,a.reason),this.failQueuedMessages(a.reason))}};b.prototype.requestState=function(a){var b=a.state,d=this;c.logAction(c.LOG_MINOR,"ConnectionManager.requestState()","requested state: "+b+"; current state: "+this.state.state);if(b!=this.state.state&&(this.cancelTransitionTimer(),this.cancelRetryTimer(),this.checkSuspendTimer(b),"connecting"!=b||"connected"!= +this.state.state)&&("closing"!=b||"closed"!=this.state.state)){var f=this.states[b];a=new S(this.state.state,f.state,null,a.error||L[f.state]);this.enactStateChange(a);"connecting"==b&&k.nextTick(function(){d.startConnect()});"closing"==b&&this.closeImpl()}};b.prototype.startConnect=function(){if(this.state!==this.states.connecting)c.logAction(c.LOG_MINOR,"ConnectionManager.startConnect()","Must be in connecting state to connect, but was "+this.state.state);else{var a=this.realtime.auth,b=this,d= +function(){b.checkConnectionStateFreshness();b.getTransportParams(function(a){b.connectImpl(a)})};c.logAction(c.LOG_MINOR,"ConnectionManager.startConnect()","starting connection");this.startSuspendTimer();this.startTransitionTimer(this.states.connecting);if("basic"===a.method)d();else{var f=function(a){a?b.actOnErrorFromAuthorize(a):d()};this.errorReason&&O.isTokenErr(this.errorReason)?a._forceNewToken(null,null,f):a._ensureValidAuthCredentials(f)}}};b.prototype.connectImpl=function(a){var b=this.state.state; b!==this.states.connecting.state&&b!==this.states.connected.state?c.logAction(c.LOG_MINOR,"ConnectionManager.connectImpl()","Must be in connecting state to connect (or connected to upgrade), but was "+b):this.pendingTransports.length?c.logAction(c.LOG_MINOR,"ConnectionManager.connectImpl()","Transports "+this.pendingTransports[0].toString()+" currently pending; taking no action"):b==this.states.connected.state?this.upgradeIfNeeded(a):1=b?(a="No activity seen from realtime in "+a+"ms; assuming connection has dropped",c.logAction(c.LOG_ERROR,"Transport.onIdleTimerExpire()", -a),this.disconnect(new r(a,80003,408))):this.setIdleTimer(b+10)};d.prototype.onAuthUpdated=function(){};return d}();(function(){function d(b,a,c){this.shortName="web_socket";c.heartbeats=y.useProtocolHeartbeats;Q.call(this,b,a,c);this.wsHost=q.getHost(c.options,c.host,!0)}var l=y.WebSocket;h.inherits(d,Q);d.isAvailable=function(){return!!l};d.isAvailable()&&(O.supportedTransports.web_socket=d);d.tryConnect=function(b,a,e,m){var f=new d(b,a,e),k=function(a){m({event:this.event,error:a})};f.on(["failed", -"disconnected"],k);f.on("wsopen",function(){c.logAction(c.LOG_MINOR,"WebSocketTransport.tryConnect()","viable transport "+f);f.off(["failed","disconnected"],k);m(null,f)});f.connect()};d.prototype.createWebSocket=function(b,a){var c=0;if(a)for(var d in a)b+=(c++?"&":"?")+d+"="+a[d];this.uri=b;return new l(b)};d.prototype.toString=function(){return"WebSocketTransport; uri="+this.uri};d.prototype.connect=function(){c.logAction(c.LOG_MINOR,"WebSocketTransport.connect()","starting");Q.prototype.connect.call(this); -var b=this,a=this.params,e=a.options,d=(e.tls?"wss://":"ws://")+this.wsHost+":"+q.getPort(e)+"/";c.logAction(c.LOG_MINOR,"WebSocketTransport.connect()","uri: "+d);this.auth.getAuthParams(function(e,k){var p="",n;for(n in k)p+=" "+n+": "+k[n]+";";c.logAction(c.LOG_MINOR,"WebSocketTransport.connect()","authParams:"+p+" err: "+e);if(e)b.disconnect(e);else{p=a.getConnectParams(k);try{var g=b.wsConnection=b.createWebSocket(d,p);g.binaryType=y.binaryType;g.onopen=function(){b.onWsOpen()};g.onclose=function(a){b.onWsClose(a)}; -g.onmessage=function(a){b.onWsData(a.data)};g.onerror=function(a){b.onWsError(a)};if(g.on)g.on("ping",function(){b.setIdleTimer()})}catch(h){c.logAction(c.LOG_ERROR,"WebSocketTransport.connect()","Unexpected exception creating websocket: err = "+(h.stack||h.message)),b.disconnect(h)}}})};d.prototype.send=function(b){var a=this.wsConnection;a?a.send(w.serialize(b,this.params.format)):c.logAction(c.LOG_ERROR,"WebSocketTransport.send()","No socket connection")};d.prototype.onWsData=function(b){c.logAction(c.LOG_MICRO, -"WebSocketTransport.onWsData()","data received; length = "+b.length+"; type = "+typeof b);try{this.onProtocolMessage(w.deserialize(b,this.format))}catch(a){c.logAction(c.LOG_ERROR,"WebSocketTransport.onWsData()","Unexpected exception handing channel message: "+a.stack)}};d.prototype.onWsOpen=function(){c.logAction(c.LOG_MINOR,"WebSocketTransport.onWsOpen()","opened WebSocket");this.emit("wsopen")};d.prototype.onWsClose=function(b){var a;"object"==typeof b?(a=b.wasClean,b=b.code):a=1E3==b;delete this.wsConnection; -a?(c.logAction(c.LOG_MINOR,"WebSocketTransport.onWsClose()","Cleanly closed WebSocket"),a=new r("Websocket closed",80003,400)):(b="Unclean disconnection of WebSocket ; code = "+b,a=new r(b,80003,400),c.logAction(c.LOG_ERROR,"WebSocketTransport.onWsClose()",b));this.finish("disconnected",a);this.emit("disposed")};d.prototype.onWsError=function(b){c.logAction(c.LOG_ERROR,"WebSocketTransport.onError()","Unexpected error from WebSocket: "+b.message);var a=this;h.nextTick(function(){a.disconnect(b)})}; -d.prototype.dispose=function(){c.logAction(c.LOG_MINOR,"WebSocketTransport.dispose()","");var b=this.wsConnection;b&&(b.onmessage=function(){},delete this.wsConnection,h.nextTick(function(){c.logAction(c.LOG_MICRO,"WebSocketTransport.dispose()","closing websocket");b.close()}))};return d})();var L=function(){function d(a,b,c){a&&a.server&&-1a.code)?[w.fromValues({action:w.Action.ERROR,error:a})]:[w.fromValues({action:w.Action.DISCONNECTED,error:a})]}function b(a,b,c){c.format=void 0;c.heartbeats=!0;Q.call(this,a,b,c);this.stream="stream"in c?c.stream:!0;this.pendingItems=this.pendingCallback=this.recvRequest=this.sendRequest=null;this.disposed=!1}h.inherits(b,Q);b.REQ_SEND=0;b.REQ_RECV=1;b.REQ_RECV_POLL=2;b.REQ_RECV_STREAM=3; -b.prototype.connect=function(){c.logAction(c.LOG_MINOR,"CometTransport.connect()","starting");Q.prototype.connect.call(this);var a=this,b=this.params,m=b.options,f=q.getHost(m,b.host),b=q.getPort(m);this.baseUri=(m.tls?"https://":"http://")+f+":"+b+"/comet/";var k=this.baseUri+"connect";c.logAction(c.LOG_MINOR,"CometTransport.connect()","uri: "+k);this.auth.getAuthParams(function(b,e){if(b)a.disconnect(b);else{a.authParams=e;var g=a.params.getConnectParams(e);"stream"in g&&(a.stream=g.stream);c.logAction(c.LOG_MINOR, -"CometTransport.connect()","connectParams:"+h.toQueryString(g));var m=!1,g=a.recvRequest=a.createRequest(k,null,g,null,a.stream?3:1);g.on("data",function(b){a.recvRequest&&(m||(m=!0,a.emit("preconnect")),a.onData(b))});g.on("complete",function(b,c,e){d(e,f,a.connectionManager);a.recvRequest||(b=b||new r("Request cancelled",8E4,400));a.recvRequest=null;this.maxIdleInterval&&this.setIdleTimer();if(b)if(b.code)a.onData(l(b));else a.disconnect(b);else h.nextTick(function(){a.recv()})});g.exec()}})};b.prototype.requestClose= -function(){c.logAction(c.LOG_MINOR,"CometTransport.requestClose()");this._requestCloseOrDisconnect(!0)};b.prototype.requestDisconnect=function(){c.logAction(c.LOG_MINOR,"CometTransport.requestDisconnect()");this._requestCloseOrDisconnect(!1)};b.prototype._requestCloseOrDisconnect=function(a){var b=a?this.closeUri:this.disconnectUri;if(b){var d=this,b=this.createRequest(b,null,this.authParams,null,0);b.on("complete",function(b){b&&(c.logAction(c.LOG_ERROR,"CometTransport.request"+(a?"Close()":"Disconnect()"), -"request returned err = "+b),d.finish("disconnected",b))});b.exec()}};b.prototype.dispose=function(){c.logAction(c.LOG_MINOR,"CometTransport.dispose()","");if(!this.disposed){this.disposed=!0;this.recvRequest&&(c.logAction(c.LOG_MINOR,"CometTransport.dispose()","aborting recv request"),this.recvRequest.abort(),this.recvRequest=null);this.finish("disconnected",K.disconnected);var a=this;h.nextTick(function(){a.emit("disposed")})}};b.prototype.onConnect=function(a){if(!this.disposed){var b=a.connectionKey; -Q.prototype.onConnect.call(this,a);b=this.baseUri+b;c.logAction(c.LOG_MICRO,"CometTransport.onConnect()","baseUri = "+b+"; connectionKey = "+a.connectionKey);this.sendUri=b+"/send";this.recvUri=b+"/recv";this.closeUri=b+"/close";this.disconnectUri=b+"/disconnect"}};b.prototype.send=function(a){if(this.sendRequest)this.pendingItems=this.pendingItems||[],this.pendingItems.push(a);else{var b=this.pendingItems||[];b.push(a);this.pendingItems=null;this.sendItems(b)}};b.prototype.sendAnyPending=function(){var a= -this.pendingItems;a&&(this.pendingItems=null,this.sendItems(a))};b.prototype.sendItems=function(a){var b=this;a=this.sendRequest=b.createRequest(b.sendUri,null,b.authParams,this.encodeRequest(a),0);a.on("complete",function(a,d){a&&c.logAction(c.LOG_ERROR,"CometTransport.sendItems()","on complete: err = "+JSON.stringify(a));b.sendRequest=null;if(d)b.onData(d);else if(a&&a.code)b.onData(l(a));else b.disconnect(a);b.pendingItems&&h.nextTick(function(){b.sendRequest||b.sendAnyPending()})});a.exec()}; -b.prototype.recv=function(){if(!this.recvRequest&&this.isConnected){var a=this,b=this.recvRequest=this.createRequest(this.recvUri,null,this.authParams,null,a.stream?3:2);b.on("data",function(b){a.onData(b)});b.on("complete",function(b){a.recvRequest=null;this.maxIdleInterval&&this.setIdleTimer();if(b)if(b.code)a.onData(l(b));else a.disconnect(b);else h.nextTick(function(){a.recv()})});b.exec()}};b.prototype.onData=function(a){try{var b=this.decodeResponse(a);if(b&&b.length)for(a=0;al||300<=l?(c=c&&c.error,c||(c=Error(String(res)),c.statusCode=l),a(c)):a(null,c,d,!0,l))}}}function a(a){var b=[];if(a)for(var c in a)b.push(c+"="+a[c]);return b.join("&")} -function e(b,e,d,n){return function(g,m,h,l,C){g?c.logAction(c.LOG_MICRO,"Resource."+e+"()","Received Error; "+(d+(n?"?":"")+a(n))+"; Error: "+JSON.stringify(g)):c.logAction(c.LOG_MICRO,"Resource."+e+"()","Received; "+(d+(n?"?":"")+a(n))+"; Headers: "+a(h)+"; StatusCode: "+C+"; Body: "+(B.isBuffer(m)?m.toString():m));b&&b(g,m,h,l,C)}}var m=y.msgpack;d.get=function(d,k,p,n,g,m){function h(b,e){c.shouldLog(c.LOG_MICRO)&&c.logAction(c.LOG_MICRO,"Resource.get()","Sending; "+(k+(e?"?":"")+a(e)));D.get(d, -k,b,e,function(a,b,c,e,g){a&&N.isTokenErr(a)?d.auth.authorize(null,null,function(a){a?m(a):l(d,p,n,m,h)}):m(a,b,c,e,g)})}c.shouldLog(c.LOG_MICRO)&&(m=e(m,"get",k,n));g&&(m=m&&b(m,g),(n=n||{}).envelope=g);l(d,p,n,m,h)};d.post=function(d,k,p,n,g,h,t){function v(b,e){if(c.shouldLog(c.LOG_MICRO)){var h=p;if(0<(b["content-type"]||"").indexOf("msgpack"))try{p=m.decode(p)}catch(u){c.logAction(c.LOG_MICRO,"Resource.post()","Sending MsgPack Decoding Error: "+JSON.stringify(u))}c.logAction(c.LOG_MICRO,"Resource.post()", -"Sending; "+(k+(e?"?":"")+a(e))+"; Body: "+h)}D.post(d,k,b,p,e,function(a,b,c,e,k){a&&N.isTokenErr(a)?d.auth.authorize(null,null,function(a){a?t(a):l(d,n,g,t,v)}):t(a,b,c,e,k)})}c.shouldLog(c.LOG_MICRO)&&(t=e(t,"post",k,g));h&&(t=b(t,h),g.envelope=h);l(d,n,g,t,v)};return d}(),S=function(){function d(a,b,c,d,k,p){this.rest=a;this.path=b;this.headers=c;this.envelope=d;this.bodyHandler=k;this.useHttpPaginatedResponse=p||!1}function l(a,b,c){this.resource=a;this.items=b;if(c){var d=this;"first"in c&& -(this.first=function(a){d.get(c.first,a)});"current"in c&&(this.current=function(a){d.get(c.current,a)});this.next=function(a){"next"in c?d.get(c.next,a):a(null,null)};this.hasNext=function(){return"next"in c};this.isLast=function(){return!this.hasNext()}}}function b(a,b,c,d,k){l.call(this,a,b,k);this.statusCode=d;this.success=300>d&&200<=d;this.headers=c}d.prototype.get=function(a,b){var c=this;W.get(c.rest,c.path,c.headers,a,c.envelope,function(a,d,p,n,g){c.handlePage(a,d,p,n,g,b)})};d.prototype.post= -function(a,b,c){var d=this;W.post(d.rest,d.path,b,d.headers,a,d.envelope,function(a,b,e,g,h){c&&d.handlePage(a,b,e,g,h,c)})};d.prototype.handlePage=function(a,e,d,f,k,p){if(a)c.logAction(c.LOG_ERROR,"PaginatedResource.handlePage()","Unexpected error getting resource: err = "+JSON.stringify(a)),p(a);else{var n,g,u;try{n=this.bodyHandler(e,d,f)}catch(t){p(t);return}if(d&&(g=d.Link||d.link)){a=g;"string"==typeof a&&(a=a.split(","));e={};for(f=0;f;\s*rel="(\w+)"$/))&& -(u=(u=g[1].match(/^\.\/(\w+)\?(.*)$/))&&h.parseQueryString(u[2]))&&(e[g[2]]=u);u=e}this.useHttpPaginatedResponse?p(null,new b(this,n,d,k,u)):p(null,new l(this,n,u))}};l.prototype.get=function(a,b){var c=this.resource;W.get(c.rest,c.path,c.headers,a,c.envelope,function(a,d,p,n,g){c.handlePage(a,d,p,n,g,b)})};h.inherits(b,l);return d}(),N=function(){function d(){}function l(a){if(!a)return"";"string"==typeof a&&(a=JSON.parse(a));var b={},c=h.keysArray(a,!0);if(!c)return"";c.sort();for(var e=0;em){e(new r("authUrl response exceeded max permitted length",40170,401));return}try{b=JSON.parse(b)}catch(g){e(new r("Unexpected error processing authURL response; err = "+g.message,40170,401));return}}e(null,b)}else e(new r("authUrl responded with unacceptable content-type "+a+", should be either text/plain or application/json",40170,401));else e(new r("authUrl response is missing a content-type header", -40170,401))};c.logAction(c.LOG_MICRO,"Auth.requestToken().tokenRequestCallback","Sending; "+b.authUrl+"; Params: "+JSON.stringify(f));b.authMethod&&"post"===b.authMethod.toLowerCase()?(d=d||{},d["content-type"]="application/x-www-form-urlencoded",f=h.toQueryString(f).slice(1),D.postUri(v,b.authUrl,d,f,{},g)):D.getUri(v,b.authUrl,d||{},f,g)};else if(b.key){var C=this;c.logAction(c.LOG_MINOR,"Auth.requestToken()","using token auth with client-side signing");t=function(a,c){C.createTokenRequest(a,b, -c)}}else{c.logAction(c.LOG_ERROR,"Auth.requestToken()","Need a new token, but authOptions does not include any way to request one");f(new r("Need a new token, but authOptions does not include any way to request one",40101,401));return}"capability"in a&&(a.capability=l(a.capability));var v=this.client,q=function(a,d){var f=a.keyName,g=function(a){return v.baseUri(a)+"/keys/"+f+"/requestToken"},p=h.defaultPostHeaders(k);b.requestHeaders&&h.mixin(p,b.requestHeaders);c.logAction(c.LOG_MICRO,"Auth.requestToken().requestToken", -"Sending POST; "+g+"; Token params: "+JSON.stringify(a));a="msgpack"==k?e.encode(a,!0):JSON.stringify(a);D.post(v,g,p,a,null,d)},w=!1,y=this.client.options.timeouts.realtimeRequestTimeout,z=setTimeout(function(){w=!0;var a="Token request callback timed out after "+y/1E3+" seconds";c.logAction(c.LOG_ERROR,"Auth.requestToken()",a);f(new r(a,40170,401))},y);t(a,function(a,b){if(!w)if(clearTimeout(z),a)c.logAction(c.LOG_ERROR,"Auth.requestToken()","token request signing call returned error; err = "+h.inspectError(a)), -a&&a.code||(a=new r(h.inspectError(a),40170,401)),f(a);else if("string"===typeof b)384m?f(new r("Token request/details object exceeded max permitted stringified size (was "+ -d+" bytes)",40170,401)):"issued"in b?f(null,b):"keyName"in b?q(b,function(a,b,d,p){a?(c.logAction(c.LOG_ERROR,"Auth.requestToken()","token request API call returned error; err = "+h.inspectError(a)),f(a)):(p||(b="msgpack"==k?e.decode(b):JSON.parse(b)),c.logAction(c.LOG_MINOR,"Auth.getToken()","token received"),f(null,b))}):(d="Expected token request callback to call back with a token string, token request object, or token details object",c.logAction(c.LOG_ERROR,"Auth.requestToken()",d),f(new r(d, -40170,401)))})};a.prototype.createTokenRequest=function(a,b,e){"function"!=typeof a||e?"function"!=typeof b||e||(e=b,b=null):(e=a,b=a=null);b=b||this.authOptions;a=a||h.copy(this.tokenParams);var d=b.key;if(d){var d=d.split(":"),k=d[0],m=d[1];if(m)if(""===a.clientId)e(new r("clientId can\u2019t be an empty string",40012,400));else{a.capability=l(a.capability);var C=h.mixin({keyName:k},a),q=a.clientId||"",w=a.ttl||"",y=a.capability,z=this;(function(a){C.timestamp?a():z.getTimestamp(b&&b.queryTime, -function(b,c){b?e(b):(C.timestamp=c,a())})})(function(){var a=C.nonce||(C.nonce=("000000"+Math.floor(1E16*Math.random())).slice(-16)),a=C.keyName+"\n"+w+"\n"+y+"\n"+q+"\n"+C.timestamp+"\n"+a+"\n";C.mac=C.mac||f(a,m);c.logAction(c.LOG_MINOR,"Auth.getTokenRequest()","generated signed request");e(null,C)})}else e(Error("Invalid key specified"))}else e(Error("No key specified"))};a.prototype.getAuthParams=function(a){"basic"==this.method?a(null,{key:this.key}):this._ensureValidAuthCredentials(function(b, -c){b?a(b):a(null,{access_token:c.token})})};a.prototype.getAuthHeaders=function(a){"basic"==this.method?a(null,{authorization:"Basic "+this.basicKey}):this._ensureValidAuthCredentials(function(b,c){b?a(b):a(null,{authorization:"Bearer "+k(c.token)})})};a.prototype.getTimestamp=function(a,b){isNaN(parseInt(this.client.serverTimeOffset))&&(a||this.authOptions.queryTime)?this.client.time(function(a,c){a?b(a):b(null,c)}):b(null,h.now()+(this.client.serverTimeOffset||0))};a.prototype._saveBasicOptions= -function(a){this.method="basic";this.key=a.key;this.basicKey=k(a.key);this.authOptions=a||{};"clientId"in a&&this._userSetClientId(a.clientId)};a.prototype._saveTokenOptions=function(a,b){this.method="token";a&&(this.tokenParams=a);b&&(b.token&&(b.tokenDetails="string"===typeof b.token?{token:b.token}:b.token),b.tokenDetails&&(this.tokenDetails=b.tokenDetails),"clientId"in b&&this._userSetClientId(b.clientId),this.authOptions=b)};a.prototype._ensureValidAuthCredentials=function(a){var b=this,e=this.tokenDetails, -d=function(){b.requestToken(b.tokenParams,b.authOptions,function(c,e){c?a(c):a(null,b.tokenDetails=e)})};e?this._tokenClientIdMismatch(e.clientId)?a(new r("Mismatch between clientId in token ("+e.clientId+") and current clientId ("+this.clientId+")",40102,401)):this.getTimestamp(b.authOptions&&b.authOptions.queryTime,function(f,k){f&&a(f);void 0===e.expires||e.expires>=k?(c.logAction(c.LOG_MINOR,"Auth.getToken()","using cached token; expires = "+e.expires),a(null,e)):(c.logAction(c.LOG_MINOR,"Auth.getToken()", -"deleting expired token"),b.tokenDetails=null,d())}):d()};a.prototype._userSetClientId=function(a){if("string"!==typeof a&&null!==a)throw new r("clientId must be either a string or null",40012,400);if("*"===a)throw new r('Can\u2019t use "*" as a clientId as that string is reserved. (To change the default token request behaviour to use a wildcard clientId, instantiate the library with {defaultTokenParams: {clientId: "*"}}), or if calling authorize(), pass it in as a tokenParam: authorize({clientId: "*"}, authOptions)', +function(a,b){var d=this.activeProtocol&&b===this.activeProtocol.getTransport(),f=k.arrIn(this.pendingTransports,b)&&this.state==this.states.synchronizing;if(d||f)d=a.connectionSerial,d<=this.connectionSerial?c.logAction(c.LOG_MICRO,"ConnectionManager.onChannelMessage() received message with connectionSerial "+d+", but current connectionSerial is "+this.connectionSerial+"; assuming message is a duplicate and discarding it"):(void 0!==d&&(this.realtime.connection.serial=this.connectionSerial=d,this.realtime.connection.recoveryKey= +this.connectionKey+":"+d),(d=a.id)&&d===this.mostRecentMsgId?c.logAction(c.LOG_ERROR,"ConnectionManager.onChannelMessage() received message with different connectionSerial, but same message id as a previous; discarding; id = "+d):(this.mostRecentMsgId=d,this.realtime.channels.onChannelMessage(a)));else if(-1=b)a="No activity seen from realtime in "+a+"ms; assuming connection has dropped",c.logAction(c.LOG_ERROR,"Transport.onIdleTimerExpire()",a),this.disconnect(new r(a,80003,408));else this.onActivity(b+10)};e.prototype.onAuthUpdated=function(){};return e}();(function(){function e(b,a,c){this.shortName="web_socket";c.heartbeats=w.useProtocolHeartbeats;R.call(this,b,a,c);this.wsHost=p.getHost(c.options,c.host, +!0)}var g=w.WebSocket;k.inherits(e,R);e.isAvailable=function(){return!!g};e.isAvailable()&&(P.supportedTransports.web_socket=e);e.tryConnect=function(b,a,d,l){var f=new e(b,a,d),m=function(a){l({event:this.event,error:a})};f.on(["failed","disconnected"],m);f.on("wsopen",function(){c.logAction(c.LOG_MINOR,"WebSocketTransport.tryConnect()","viable transport "+f);f.off(["failed","disconnected"],m);l(null,f)});f.connect()};e.prototype.createWebSocket=function(b,a){var c=0;if(a)for(var e in a)b+=(c++? +"&":"?")+e+"="+a[e];this.uri=b;return new g(b)};e.prototype.toString=function(){return"WebSocketTransport; uri="+this.uri};e.prototype.connect=function(){c.logAction(c.LOG_MINOR,"WebSocketTransport.connect()","starting");R.prototype.connect.call(this);var b=this,a=this.params,d=a.options,e=(d.tls?"wss://":"ws://")+this.wsHost+":"+p.getPort(d)+"/";c.logAction(c.LOG_MINOR,"WebSocketTransport.connect()","uri: "+e);this.auth.getAuthParams(function(d,m){var q="",n;for(n in m)q+=" "+n+": "+m[n]+";";c.logAction(c.LOG_MINOR, +"WebSocketTransport.connect()","authParams:"+q+" err: "+d);if(d)b.disconnect(d);else{q=a.getConnectParams(m);try{var h=b.wsConnection=b.createWebSocket(e,q);h.binaryType=w.binaryType;h.onopen=function(){b.onWsOpen()};h.onclose=function(a){b.onWsClose(a)};h.onmessage=function(a){b.onWsData(a.data)};h.onerror=function(a){b.onWsError(a)};if(h.on)h.on("ping",function(){b.onActivity()})}catch(g){c.logAction(c.LOG_ERROR,"WebSocketTransport.connect()","Unexpected exception creating websocket: err = "+(g.stack|| +g.message)),b.disconnect(g)}}})};e.prototype.send=function(b){var a=this.wsConnection;if(a)try{a.send(y.serialize(b,this.params.format))}catch(d){b="Exception from ws connection when trying to send: "+k.inspectError(d),c.logAction(c.LOG_ERROR,"WebSocketTransport.send()",b),this.finish("disconnected",new r(b,5E4,500))}else c.logAction(c.LOG_ERROR,"WebSocketTransport.send()","No socket connection")};e.prototype.onWsData=function(b){c.logAction(c.LOG_MICRO,"WebSocketTransport.onWsData()","data received; length = "+ +b.length+"; type = "+typeof b);try{this.onProtocolMessage(y.deserialize(b,this.format))}catch(a){c.logAction(c.LOG_ERROR,"WebSocketTransport.onWsData()","Unexpected exception handing channel message: "+a.stack)}};e.prototype.onWsOpen=function(){c.logAction(c.LOG_MINOR,"WebSocketTransport.onWsOpen()","opened WebSocket");this.emit("wsopen")};e.prototype.onWsClose=function(b){var a;"object"==typeof b?(a=b.wasClean,b=b.code):a=1E3==b;delete this.wsConnection;a?(c.logAction(c.LOG_MINOR,"WebSocketTransport.onWsClose()", +"Cleanly closed WebSocket"),a=new r("Websocket closed",80003,400)):(b="Unclean disconnection of WebSocket ; code = "+b,a=new r(b,80003,400),c.logAction(c.LOG_ERROR,"WebSocketTransport.onWsClose()",b));this.finish("disconnected",a);this.emit("disposed")};e.prototype.onWsError=function(b){c.logAction(c.LOG_ERROR,"WebSocketTransport.onError()","Unexpected error from WebSocket: "+b.message);var a=this;k.nextTick(function(){a.disconnect(b)})};e.prototype.dispose=function(){c.logAction(c.LOG_MINOR,"WebSocketTransport.dispose()", +"");var b=this.wsConnection;b&&(b.onmessage=function(){},delete this.wsConnection,k.nextTick(function(){c.logAction(c.LOG_MICRO,"WebSocketTransport.dispose()","closing websocket");b.close()}))};return e})();var M=function(){function e(a,b,c){a&&a.server&&-1a.code)?[y.fromValues({action:y.Action.ERROR,error:a})]:[y.fromValues({action:y.Action.DISCONNECTED,error:a})]}function b(a,b,c){c.format=void 0;c.heartbeats=!0;R.call(this,a,b,c);this.stream="stream"in c?c.stream:!0;this.pendingItems=this.pendingCallback=this.recvRequest=this.sendRequest=null;this.disposed=!1}k.inherits(b,R);b.REQ_SEND=0;b.REQ_RECV=1;b.REQ_RECV_POLL=2;b.REQ_RECV_STREAM=3;b.prototype.connect=function(){c.logAction(c.LOG_MINOR,"CometTransport.connect()","starting"); +R.prototype.connect.call(this);var a=this,b=this.params,l=b.options,f=p.getHost(l,b.host),b=p.getPort(l);this.baseUri=(l.tls?"https://":"http://")+f+":"+b+"/comet/";var m=this.baseUri+"connect";c.logAction(c.LOG_MINOR,"CometTransport.connect()","uri: "+m);this.auth.getAuthParams(function(b,d){if(b)a.disconnect(b);else{a.authParams=d;var h=a.params.getConnectParams(d);"stream"in h&&(a.stream=h.stream);c.logAction(c.LOG_MINOR,"CometTransport.connect()","connectParams:"+k.toQueryString(h));var l=!1, +h=a.recvRequest=a.createRequest(m,null,h,null,a.stream?3:1);h.on("data",function(b){a.recvRequest&&(l||(l=!0,a.emit("preconnect")),a.onData(b))});h.on("complete",function(b,c,d){e(d,f,a.connectionManager);a.recvRequest||(b=b||new r("Request cancelled",8E4,400));a.recvRequest=null;a.onActivity();if(b)if(b.code)a.onData(g(b));else a.disconnect(b);else k.nextTick(function(){a.recv()})});h.exec()}})};b.prototype.requestClose=function(){c.logAction(c.LOG_MINOR,"CometTransport.requestClose()");this._requestCloseOrDisconnect(!0)}; +b.prototype.requestDisconnect=function(){c.logAction(c.LOG_MINOR,"CometTransport.requestDisconnect()");this._requestCloseOrDisconnect(!1)};b.prototype._requestCloseOrDisconnect=function(a){var b=a?this.closeUri:this.disconnectUri;if(b){var e=this,b=this.createRequest(b,null,this.authParams,null,0);b.on("complete",function(b){b&&(c.logAction(c.LOG_ERROR,"CometTransport.request"+(a?"Close()":"Disconnect()"),"request returned err = "+b),e.finish("disconnected",b))});b.exec()}};b.prototype.dispose=function(){c.logAction(c.LOG_MINOR, +"CometTransport.dispose()","");if(!this.disposed){this.disposed=!0;this.recvRequest&&(c.logAction(c.LOG_MINOR,"CometTransport.dispose()","aborting recv request"),this.recvRequest.abort(),this.recvRequest=null);this.finish("disconnected",L.disconnected);var a=this;k.nextTick(function(){a.emit("disposed")})}};b.prototype.onConnect=function(a){if(!this.disposed){var b=a.connectionKey;R.prototype.onConnect.call(this,a);b=this.baseUri+b;c.logAction(c.LOG_MICRO,"CometTransport.onConnect()","baseUri = "+ +b+"; connectionKey = "+a.connectionKey);this.sendUri=b+"/send";this.recvUri=b+"/recv";this.closeUri=b+"/close";this.disconnectUri=b+"/disconnect"}};b.prototype.send=function(a){if(this.sendRequest)this.pendingItems=this.pendingItems||[],this.pendingItems.push(a);else{var b=this.pendingItems||[];b.push(a);this.pendingItems=null;this.sendItems(b)}};b.prototype.sendAnyPending=function(){var a=this.pendingItems;a&&(this.pendingItems=null,this.sendItems(a))};b.prototype.sendItems=function(a){var b=this; +a=this.sendRequest=b.createRequest(b.sendUri,null,b.authParams,this.encodeRequest(a),0);a.on("complete",function(a,f){a&&c.logAction(c.LOG_ERROR,"CometTransport.sendItems()","on complete: err = "+JSON.stringify(a));b.sendRequest=null;if(f)b.onData(f);else if(a&&a.code)b.onData(g(a));else b.disconnect(a);b.pendingItems&&k.nextTick(function(){b.sendRequest||b.sendAnyPending()})});a.exec()};b.prototype.recv=function(){if(!this.recvRequest&&this.isConnected){var a=this,b=this.recvRequest=this.createRequest(this.recvUri, +null,this.authParams,null,a.stream?3:2);b.on("data",function(b){a.onData(b)});b.on("complete",function(b){a.recvRequest=null;a.onActivity();if(b)if(b.code)a.onData(g(b));else a.disconnect(b);else k.nextTick(function(){a.recv()})});b.exec()}};b.prototype.onData=function(a){try{var b=this.decodeResponse(a);if(b&&b.length)for(a=0;ak||300<=k?(c=c&&c.error,c||(c=Error(String(res)),c.statusCode=k),a(c)):a(null,c,e,!0,k))}}}function a(a){var b=[];if(a)for(var c in a)b.push(c+"="+a[c]);return b.join("&")}function d(b,d,e,n){return function(h,l,g,k,C){h?c.logAction(c.LOG_MICRO,"Resource."+d+"()", +"Received Error; "+(e+(n?"?":"")+a(n))+"; Error: "+JSON.stringify(h)):c.logAction(c.LOG_MICRO,"Resource."+d+"()","Received; "+(e+(n?"?":"")+a(n))+"; Headers: "+a(g)+"; StatusCode: "+C+"; Body: "+(B.isBuffer(l)?l.toString():l));b&&b(h,l,g,k,C)}}var l=w.msgpack;e.get=function(f,e,l,n,h,k){function t(b,d){c.shouldLog(c.LOG_MICRO)&&c.logAction(c.LOG_MICRO,"Resource.get()","Sending; "+(e+(d?"?":"")+a(d)));x.get(f,e,b,d,function(a,b,c,d,e){a&&O.isTokenErr(a)?f.auth.authorize(null,null,function(a){a?k(a): +g(f,l,n,k,t)}):k(a,b,c,d,e)})}c.shouldLog(c.LOG_MICRO)&&(k=d(k,"get",e,n));h&&(k=k&&b(k,h),(n=n||{}).envelope=h);g(f,l,n,k,t)};e.post=function(f,e,q,n,h,k,t){function v(b,d){if(c.shouldLog(c.LOG_MICRO)){var k=q;if(0<(b["content-type"]||"").indexOf("msgpack"))try{q=l.decode(q)}catch(u){c.logAction(c.LOG_MICRO,"Resource.post()","Sending MsgPack Decoding Error: "+JSON.stringify(u))}c.logAction(c.LOG_MICRO,"Resource.post()","Sending; "+(e+(d?"?":"")+a(d))+"; Body: "+k)}x.post(f,e,b,q,d,function(a,b,c, +d,e){a&&O.isTokenErr(a)?f.auth.authorize(null,null,function(a){a?t(a):g(f,n,h,t,v)}):t(a,b,c,d,e)})}c.shouldLog(c.LOG_MICRO)&&(t=d(t,"post",e,h));k&&(t=b(t,k),h.envelope=k);g(f,n,h,t,v)};return e}(),T=function(){function e(a,b,c,f,e,q){this.rest=a;this.path=b;this.headers=c;this.envelope=f;this.bodyHandler=e;this.useHttpPaginatedResponse=q||!1}function g(a,b,c){this.resource=a;this.items=b;if(c){var f=this;"first"in c&&(this.first=function(a){f.get(c.first,a)});"current"in c&&(this.current=function(a){f.get(c.current, +a)});this.next=function(a){"next"in c?f.get(c.next,a):a(null,null)};this.hasNext=function(){return"next"in c};this.isLast=function(){return!this.hasNext()}}}function b(a,b,c,f,e){g.call(this,a,b,e);this.statusCode=f;this.success=300>f&&200<=f;this.headers=c}e.prototype.get=function(a,b){var c=this;X.get(c.rest,c.path,c.headers,a,c.envelope,function(a,e,q,n,h){c.handlePage(a,e,q,n,h,b)})};e.prototype.post=function(a,b,c){var f=this;X.post(f.rest,f.path,b,f.headers,a,f.envelope,function(a,b,d,e,g){c&& +f.handlePage(a,b,d,e,g,c)})};e.prototype.handlePage=function(a,d,e,f,m,q){if(a)c.logAction(c.LOG_ERROR,"PaginatedResource.handlePage()","Unexpected error getting resource: err = "+JSON.stringify(a)),q(a);else{var n,h,u;try{n=this.bodyHandler(d,e,f)}catch(t){q(t);return}if(e&&(h=e.Link||e.link)){a=h;"string"==typeof a&&(a=a.split(","));d={};for(f=0;f;\s*rel="(\w+)"$/))&&(u=(u=h[1].match(/^\.\/(\w+)\?(.*)$/))&&k.parseQueryString(u[2]))&&(d[h[2]]=u);u=d}this.useHttpPaginatedResponse? +q(null,new b(this,n,e,m,u)):q(null,new g(this,n,u))}};g.prototype.get=function(a,b){var c=this.resource;X.get(c.rest,c.path,c.headers,a,c.envelope,function(a,e,q,n,h){c.handlePage(a,e,q,n,h,b)})};k.inherits(b,g);return e}(),O=function(){function e(){}function g(a){if(!a)return"";"string"==typeof a&&(a=JSON.parse(a));var b={},c=k.keysArray(a,!0);if(!c)return"";c.sort();for(var d=0;dl){d(new r("authUrl response exceeded max permitted length",40170,401));return}try{b=JSON.parse(b)}catch(h){d(new r("Unexpected error processing authURL response; err = "+h.message,40170,401));return}}d(null,b)}else d(new r("authUrl responded with unacceptable content-type "+a+", should be either text/plain or application/json",40170,401));else d(new r("authUrl response is missing a content-type header", +40170,401))};c.logAction(c.LOG_MICRO,"Auth.requestToken().tokenRequestCallback","Sending; "+b.authUrl+"; Params: "+JSON.stringify(e));b.authMethod&&"post"===b.authMethod.toLowerCase()?(f=f||{},f["content-type"]="application/x-www-form-urlencoded",e=k.toQueryString(e).slice(1),x.postUri(v,b.authUrl,f,e,{},h)):x.getUri(v,b.authUrl,f||{},e,h)};else if(b.key){var C=this;c.logAction(c.LOG_MINOR,"Auth.requestToken()","using token auth with client-side signing");t=function(a,c){C.createTokenRequest(a,b, +c)}}else{c.logAction(c.LOG_ERROR,"Auth.requestToken()","Need a new token, but authOptions does not include any way to request one");f(new r("Need a new token, but authOptions does not include any way to request one",40101,401));return}"capability"in a&&(a.capability=g(a.capability));var v=this.client,p=function(a,f){var e=a.keyName,h=function(a){return v.baseUri(a)+"/keys/"+e+"/requestToken"},l=k.defaultPostHeaders(m);b.requestHeaders&&k.mixin(l,b.requestHeaders);c.logAction(c.LOG_MICRO,"Auth.requestToken().requestToken", +"Sending POST; "+h+"; Token params: "+JSON.stringify(a));a="msgpack"==m?d.encode(a,!0):JSON.stringify(a);x.post(v,h,l,a,null,f)},w=!1,y=this.client.options.timeouts.realtimeRequestTimeout,z=setTimeout(function(){w=!0;var a="Token request callback timed out after "+y/1E3+" seconds";c.logAction(c.LOG_ERROR,"Auth.requestToken()",a);f(new r(a,40170,401))},y);t(a,function(a,b){if(!w)if(clearTimeout(z),a)c.logAction(c.LOG_ERROR,"Auth.requestToken()","token request signing call returned error; err = "+k.inspectError(a)), +a&&a.code||(a=new r(k.inspectError(a),40170,401)),f(a);else if("string"===typeof b)384l?f(new r("Token request/details object exceeded max permitted stringified size (was "+ +e+" bytes)",40170,401)):"issued"in b?f(null,b):"keyName"in b?p(b,function(a,b,e,l){a?(c.logAction(c.LOG_ERROR,"Auth.requestToken()","token request API call returned error; err = "+k.inspectError(a)),f(a)):(l||(b="msgpack"==m?d.decode(b):JSON.parse(b)),c.logAction(c.LOG_MINOR,"Auth.getToken()","token received"),f(null,b))}):(e="Expected token request callback to call back with a token string, token request object, or token details object",c.logAction(c.LOG_ERROR,"Auth.requestToken()",e),f(new r(e, +40170,401)))})};a.prototype.createTokenRequest=function(a,b,d){"function"!=typeof a||d?"function"!=typeof b||d||(d=b,b=null):(d=a,b=a=null);b=b||this.authOptions;a=a||k.copy(this.tokenParams);var e=b.key;if(e){var e=e.split(":"),m=e[0],l=e[1];if(l)if(""===a.clientId)d(new r("clientId can\u2019t be an empty string",40012,400));else{a.capability=g(a.capability);var C=k.mixin({keyName:m},a),p=a.clientId||"",w=a.ttl||"",y=a.capability,z=this;(function(a){C.timestamp?a():z.getTimestamp(b&&b.queryTime, +function(b,c){b?d(b):(C.timestamp=c,a())})})(function(){var a=C.nonce||(C.nonce=("000000"+Math.floor(1E16*Math.random())).slice(-16)),a=C.keyName+"\n"+w+"\n"+y+"\n"+p+"\n"+C.timestamp+"\n"+a+"\n";C.mac=C.mac||f(a,l);c.logAction(c.LOG_MINOR,"Auth.getTokenRequest()","generated signed request");d(null,C)})}else d(Error("Invalid key specified"))}else d(Error("No key specified"))};a.prototype.getAuthParams=function(a){"basic"==this.method?a(null,{key:this.key}):this._ensureValidAuthCredentials(function(b, +c){b?a(b):a(null,{access_token:c.token})})};a.prototype.getAuthHeaders=function(a){"basic"==this.method?a(null,{authorization:"Basic "+this.basicKey}):this._ensureValidAuthCredentials(function(b,c){b?a(b):a(null,{authorization:"Bearer "+m(c.token)})})};a.prototype.getTimestamp=function(a,b){isNaN(parseInt(this.client.serverTimeOffset))&&(a||this.authOptions.queryTime)?this.client.time(function(a,c){a?b(a):b(null,c)}):b(null,k.now()+(this.client.serverTimeOffset||0))};a.prototype._saveBasicOptions= +function(a){this.method="basic";this.key=a.key;this.basicKey=m(a.key);this.authOptions=a||{};"clientId"in a&&this._userSetClientId(a.clientId)};a.prototype._saveTokenOptions=function(a,b){this.method="token";a&&(this.tokenParams=a);b&&(b.token&&(b.tokenDetails="string"===typeof b.token?{token:b.token}:b.token),b.tokenDetails&&(this.tokenDetails=b.tokenDetails),"clientId"in b&&this._userSetClientId(b.clientId),this.authOptions=b)};a.prototype._ensureValidAuthCredentials=function(a){var b=this,d=this.tokenDetails, +f=function(){b.requestToken(b.tokenParams,b.authOptions,function(c,d){c?a(c):a(null,b.tokenDetails=d)})};d?this._tokenClientIdMismatch(d.clientId)?a(new r("Mismatch between clientId in token ("+d.clientId+") and current clientId ("+this.clientId+")",40102,401)):this.getTimestamp(b.authOptions&&b.authOptions.queryTime,function(e,m){e&&a(e);void 0===d.expires||d.expires>=m?(c.logAction(c.LOG_MINOR,"Auth.getToken()","using cached token; expires = "+d.expires),a(null,d)):(c.logAction(c.LOG_MINOR,"Auth.getToken()", +"deleting expired token"),b.tokenDetails=null,f())}):f()};a.prototype._userSetClientId=function(a){if("string"!==typeof a&&null!==a)throw new r("clientId must be either a string or null",40012,400);if("*"===a)throw new r('Can\u2019t use "*" as a clientId as that string is reserved. (To change the default token request behaviour to use a wildcard clientId, instantiate the library with {defaultTokenParams: {clientId: "*"}}), or if calling authorize(), pass it in as a tokenParam: authorize({clientId: "*"}, authOptions)', 40012,400);if(a=this._uncheckedSetClientId(a))throw a;};a.prototype._uncheckedSetClientId=function(a){if(this._tokenClientIdMismatch(a)){a="Unexpected clientId mismatch: client has "+this.clientId+", requested "+a;var b=new r(a,40102,401);c.logAction(c.LOG_ERROR,"Auth._uncheckedSetClientId()",a);return b}if("*"===a)this.tokenParams.clientId=a;else return this.clientId=this.tokenParams.clientId=a,null};a.prototype._tokenClientIdMismatch=function(a){return this.clientId&&a&&"*"!==a&&this.clientId!== -a};a.isTokenErr=function(a){return a.code&&40140<=a.code&&40150>a.code};return a}(),G=function(){function d(a){if(!(this instanceof d))return new d(a);if(!a){var b="no options provided";c.logAction(c.LOG_ERROR,"Rest()",b);throw Error(b);}"string"==typeof a&&(a=-1==a.indexOf(":")?{token:a}:{key:a});this.options=q.normaliseOptions(a);if(a.key){b=a.key.match(/^([^:\s]+):([^:.\s]+)$/);if(!b)throw b="invalid key parameter",c.logAction(c.LOG_ERROR,"Rest()",b),Error(b);a.keyName=b[1];a.keySecret=b[2]}if("clientId"in -a){if("string"!==typeof a.clientId&&null!==a.clientId)throw new r("clientId must be either a string or null",40012,400);if("*"===a.clientId)throw new r('Can\u2019t use "*" as a clientId as that string is reserved. (To change the default token request behaviour to use a wildcard clientId, use {defaultTokenParams: {clientId: "*"}})',40012,400);}a.log&&c.setLog(a.log.level,a.log.handler);c.logAction(c.LOG_MINOR,"Rest()","started");this.baseUri=this.authority=function(b){return q.getHttpScheme(a)+b+":"+ -q.getPort(a,!1)};this.serverTimeOffset=null;this.auth=new N(this,a);this.channels=new l(this)}function l(a){this.rest=a;this.attached={}}var b=function(){};d.prototype.stats=function(a,c){void 0===c&&("function"==typeof a?(c=a,a=null):c=b);var d=h.copy(h.defaultGetHeaders()),f=D.supportsLinkHeaders?void 0:"json";this.options.headers&&h.mixin(d,this.options.headers);(new S(this,"/stats",d,f,function(a,b,c){a=c?a:JSON.parse(a);for(b=0;bb.timestamp;var c=a.parseId(),d=b.parseId();return c.msgSerial===d.msgSerial?c.index>d.index:c.msgSerial>d.msgSerial}var m=function(){};h.inherits(b,V);b.prototype.enter=function(a,b){if(d(this))throw new r("clientId must be specified to enter a presence channel",40012,400);this._enterOrUpdateClient(void 0,a,b,"enter")};b.prototype.update=function(a,b){if(d(this))throw new r("clientId must be specified to update presence data", -40012,400);this._enterOrUpdateClient(void 0,a,b,"update")};b.prototype.enterClient=function(a,b,c){this._enterOrUpdateClient(a,b,c,"enter")};b.prototype.updateClient=function(a,b,c){this._enterOrUpdateClient(a,b,c,"update")};b.prototype._enterOrUpdateClient=function(a,b,d,e){d||("function"===typeof b?(d=b,b=null):d=m);var g=this.channel;if(g.connectionManager.activeState()){c.logAction(c.LOG_MICRO,"RealtimePresence."+e+"Client()",e+"ing; channel = "+g.name+", client = "+a||"(implicit) "+this.channel.realtime.auth.clientId); -var h=F.fromValues({action:e,data:b});a&&(h.clientId=a);var l=this;F.encode(h,g.channelOptions,function(a){if(a)d(a);else switch(g.state){case "attached":g.sendPresence(h,d);break;case "initialized":case "detached":g.autonomousAttach();case "attaching":l.pendingPresence.push({presence:h,callback:d});break;default:a=new r("Unable to "+e+" presence channel (incompatible state)",90001),a.code=90001,d(a)}})}else d(g.connectionManager.getStateError())};b.prototype.leave=function(a,b){if(d(this))throw new r("clientId must have been specified to enter or leave a presence channel", -40012,400);this.leaveClient(void 0,a,b)};b.prototype.leaveClient=function(a,b,d){d||("function"===typeof b?(d=b,b=null):d=m);var e=this.channel;if(e.connectionManager.activeState())switch(c.logAction(c.LOG_MICRO,"RealtimePresence.leaveClient()","leaving; channel = "+this.channel.name+", client = "+a),b=F.fromValues({action:"leave",data:b}),a&&(b.clientId=a),e.state){case "attached":e.sendPresence(b,d);break;case "attaching":this.pendingPresence.push({presence:b,callback:d});break;case "initialized":case "failed":a= -new r("Unable to leave presence channel (incompatible state)",90001);d(a);break;default:d(K.failed)}else d(e.connectionManager.getStateError())};b.prototype.get=function(){function a(b){d(null,c?b.list(c):b.values())}var b=Array.prototype.slice.call(arguments);1==b.length&&"function"==typeof b[0]&&b.unshift(null);var c=b[0],d=b[1]||m,e=!c||("waitForSync"in c?c.waitForSync:!0);if("suspended"===this.channel.state)e?d(r.fromValues({statusCode:400,code:91005,message:"Presence state is out of sync due to channel being in the SUSPENDED state"})): -a(this.members);else{var h=this;l(this.channel,d,function(){var b=h.members;e?b.waitSync(function(){a(b)}):a(b)})}};b.prototype.history=function(a,b){c.logAction(c.LOG_MICRO,"RealtimePresence.history()","channel = "+this.name);void 0===b&&("function"==typeof a?(b=a,a=null):b=m);a&&a.untilAttach&&("attached"===this.channel.state?(delete a.untilAttach,a.from_serial=this.channel.attachSerial):b(new r("option untilAttach requires the channel to be attached, was: "+this.channel.state,4E4,400)));V.prototype._history.call(this, -a,b)};b.prototype.setPresence=function(a,b,d){c.logAction(c.LOG_MICRO,"RealtimePresence.setPresence()","received presence for "+a.length+" participants; syncChannelSerial = "+d);var e,g,h=this.members,l=this._myMembers,m=[],r=this.channel.connectionManager.connectionId;b&&(this.members.startSync(),d&&(g=d.match(/^[\w\-]+:(.*)$/))&&(e=g[1]));for(d=0;dc)&&0!==q.status){if(void 0===x)if(x=q.status,1223===x&&(x=204),clearTimeout(e),E=400>x,204==x)d.complete(null,null,null,null,x);else{var f;if(f=3==d.requestMode&&E)f=q,f=f.getResponseHeader&&f.getResponseHeader("transfer-encoding")&&!f.getResponseHeader("content-length");D=f}if(3==c&&D)a();else if(4==c)if(D)b();else a:{try{var l=q.getResponseHeader&&q.getResponseHeader("content-type"),m,u=l?0<=l.indexOf("application/json"):"text"==q.responseType;A=u?q.responseText:q.response; -u&&(A=String(A),A.length&&(A=JSON.parse(A)),G=!0);if(void 0!==A.response)x=A.statusCode,E=400>x,m=A.headers,A=A.response;else{for(var t=h.trim(q.getAllResponseHeaders()).split("\r\n"),c={},l=0;la.statusCode||h.isArray(b)?l.complete(null,b,a.headers,a.statusCode):(a=b.error||new r("Error response received from server",null,a.statusCode),l.complete(a)):l.complete(new r("Invalid server response: no envelope detected",null,500))}else l.complete(null,a)};this.timer=setTimeout(function(){l.abort()},this.requestMode==L.REQ_SEND?this.timeouts.httpRequestTimeout: -this.timeouts.recvTimeout);f.insertBefore(d,f.firstChild)};l.prototype.complete=function(a,b,c,d){c=c||{};this.requestComplete||(this.requestComplete=!0,b&&(c["content-type"]="string"==typeof b?"text/plain":"application/json",this.emit("data",b)),this.emit("complete",a,b,c,!0,d),this.dispose())};l.prototype.abort=function(){this.dispose()};l.prototype.dispose=function(){var b=this.timer;b&&(clearTimeout(b),this.timer=null);b=this.script;b.parentNode&&b.parentNode.removeChild(b);delete a[this.id]; -this.emit("disposed")};D.Request||(D.Request=function(a,b,c,d,e,f){var k=p(b,c,d,e,L.REQ_SEND,a&&a.options.timeouts);k.once("complete",f);h.nextTick(function(){k.exec()});return k},D.checkConnectivity=function(a){var b=q.jsonpInternetUpUrl;if(k)k.push(a);else{k=[a];c.logAction(c.LOG_MICRO,"(JSONP)Http.checkConnectivity()","Sending; "+b);var d=new l("isTheInternetUp",b,null,null,null,L.REQ_SEND,q.TIMEOUTS);d.once("complete",function(a,b){var d=!a&&b;c.logAction(c.LOG_MICRO,"(JSONP)Http.checkConnectivity()", -"Result: "+d);for(var e=0;ea.code};return a}(),I=function(){function e(a){if(!(this instanceof e))return new e(a);if(!a){var b="no options provided";c.logAction(c.LOG_ERROR,"Rest()",b);throw Error(b);}"string"==typeof a&&(a=-1==a.indexOf(":")?{token:a}:{key:a});this.options=p.normaliseOptions(a);if(a.key){b=a.key.match(/^([^:\s]+):([^:.\s]+)$/);if(!b)throw b="invalid key parameter",c.logAction(c.LOG_ERROR,"Rest()",b),Error(b);a.keyName=b[1];a.keySecret=b[2]}if("clientId"in +a){if("string"!==typeof a.clientId&&null!==a.clientId)throw new r("clientId must be either a string or null",40012,400);if("*"===a.clientId)throw new r('Can\u2019t use "*" as a clientId as that string is reserved. (To change the default token request behaviour to use a wildcard clientId, use {defaultTokenParams: {clientId: "*"}})',40012,400);}a.log&&c.setLog(a.log.level,a.log.handler);c.logAction(c.LOG_MINOR,"Rest()","started");this.baseUri=this.authority=function(b){return p.getHttpScheme(a)+b+":"+ +p.getPort(a,!1)};this.serverTimeOffset=null;this.auth=new O(this,a);this.channels=new g(this)}function g(a){this.rest=a;this.attached={}}var b=function(){};e.prototype.stats=function(a,c){void 0===c&&("function"==typeof a?(c=a,a=null):c=b);var e=k.copy(k.defaultGetHeaders()),f=x.supportsLinkHeaders?void 0:"json";this.options.headers&&k.mixin(e,this.options.headers);(new T(this,"/stats",e,f,function(a,b,c){a=c?a:JSON.parse(a);for(b=0;bb.timestamp;var c=a.parseId(),d=b.parseId();return c.msgSerial===d.msgSerial?c.index>d.index:c.msgSerial>d.msgSerial}var l=function(){};k.inherits(b,W);b.prototype.enter=function(a,b){if(e(this))throw new r("clientId must be specified to enter a presence channel",40012,400);this._enterOrUpdateClient(void 0,a,b,"enter")};b.prototype.update=function(a,b){if(e(this))throw new r("clientId must be specified to update presence data", +40012,400);this._enterOrUpdateClient(void 0,a,b,"update")};b.prototype.enterClient=function(a,b,c){this._enterOrUpdateClient(a,b,c,"enter")};b.prototype.updateClient=function(a,b,c){this._enterOrUpdateClient(a,b,c,"update")};b.prototype._enterOrUpdateClient=function(a,b,d,e){d||("function"===typeof b?(d=b,b=null):d=l);var h=this.channel;if(h.connectionManager.activeState()){c.logAction(c.LOG_MICRO,"RealtimePresence."+e+"Client()",e+"ing; channel = "+h.name+", client = "+a||"(implicit) "+this.channel.realtime.auth.clientId); +var g=F.fromValues({action:e,data:b});a&&(g.clientId=a);var k=this;F.encode(g,h.channelOptions,function(a){if(a)d(a);else switch(h.state){case "attached":h.sendPresence(g,d);break;case "initialized":case "detached":h.autonomousAttach();case "attaching":k.pendingPresence.push({presence:g,callback:d});break;default:a=new r("Unable to "+e+" presence channel (incompatible state)",90001),a.code=90001,d(a)}})}else d(h.connectionManager.getStateError())};b.prototype.leave=function(a,b){if(e(this))throw new r("clientId must have been specified to enter or leave a presence channel", +40012,400);this.leaveClient(void 0,a,b)};b.prototype.leaveClient=function(a,b,d){d||("function"===typeof b?(d=b,b=null):d=l);var e=this.channel;if(e.connectionManager.activeState())switch(c.logAction(c.LOG_MICRO,"RealtimePresence.leaveClient()","leaving; channel = "+this.channel.name+", client = "+a),b=F.fromValues({action:"leave",data:b}),a&&(b.clientId=a),e.state){case "attached":e.sendPresence(b,d);break;case "attaching":this.pendingPresence.push({presence:b,callback:d});break;case "initialized":case "failed":a= +new r("Unable to leave presence channel (incompatible state)",90001);d(a);break;default:d(L.failed)}else d(e.connectionManager.getStateError())};b.prototype.get=function(){function a(b){d(null,c?b.list(c):b.values())}var b=Array.prototype.slice.call(arguments);1==b.length&&"function"==typeof b[0]&&b.unshift(null);var c=b[0],d=b[1]||l,e=!c||("waitForSync"in c?c.waitForSync:!0);if("suspended"===this.channel.state)e?d(r.fromValues({statusCode:400,code:91005,message:"Presence state is out of sync due to channel being in the SUSPENDED state"})): +a(this.members);else{var k=this;g(this.channel,d,function(){var b=k.members;e?b.waitSync(function(){a(b)}):a(b)})}};b.prototype.history=function(a,b){c.logAction(c.LOG_MICRO,"RealtimePresence.history()","channel = "+this.name);void 0===b&&("function"==typeof a?(b=a,a=null):b=l);a&&a.untilAttach&&("attached"===this.channel.state?(delete a.untilAttach,a.from_serial=this.channel.attachSerial):b(new r("option untilAttach requires the channel to be attached, was: "+this.channel.state,4E4,400)));W.prototype._history.call(this, +a,b)};b.prototype.setPresence=function(a,b,d){c.logAction(c.LOG_MICRO,"RealtimePresence.setPresence()","received presence for "+a.length+" participants; syncChannelSerial = "+d);var e,h,g=this.members,k=this._myMembers,l=[],r=this.channel.connectionManager.connectionId;b&&(this.members.startSync(),d&&(h=d.match(/^[\w\-]+:(.*)$/))&&(e=h[1]));for(d=0;dc)&&0!==p.status){if(void 0===x)if(x=p.status,1223===x&&(x=204),clearTimeout(e),D=400>x,204==x)d.complete(null,null,null,null,x);else{var f;if(f=3==d.requestMode&&D)f=p,f=f.getResponseHeader&&f.getResponseHeader("transfer-encoding")&&!f.getResponseHeader("content-length");B=f}if(3==c&&B)a();else if(4==c)if(B)b();else a:{try{var g=p.getResponseHeader&&p.getResponseHeader("content-type"),l, +u=g?0<=g.indexOf("application/json"):"text"==p.responseType;A=u?p.responseText:p.response;u&&(A=String(A),A.length&&(A=JSON.parse(A)),F=!0);if(void 0!==A.response)x=A.statusCode,D=400>x,l=A.headers,A=A.response;else{for(var t=k.trim(p.getAllResponseHeaders()).split("\r\n"),c={},g=0;ga.statusCode||k.isArray(b)?l.complete(null,b,a.headers,a.statusCode):(a=b.error||new r("Error response received from server",null,a.statusCode),l.complete(a)):l.complete(new r("Invalid server response: no envelope detected",null,500))}else l.complete(null, +a)};this.timer=setTimeout(function(){l.abort()},this.requestMode==M.REQ_SEND?this.timeouts.httpRequestTimeout:this.timeouts.recvTimeout);f.insertBefore(d,f.firstChild)};g.prototype.complete=function(a,b,c,d){c=c||{};this.requestComplete||(this.requestComplete=!0,b&&(c["content-type"]="string"==typeof b?"text/plain":"application/json",this.emit("data",b)),this.emit("complete",a,b,c,!0,d),this.dispose())};g.prototype.abort=function(){this.dispose()};g.prototype.dispose=function(){var b=this.timer;b&& +(clearTimeout(b),this.timer=null);b=this.script;b.parentNode&&b.parentNode.removeChild(b);delete a[this.id];this.emit("disposed")};x.Request||(x.Request=function(a,b,c,d,e,f){var g=q(b,c,d,e,M.REQ_SEND,a&&a.options.timeouts);g.once("complete",f);k.nextTick(function(){g.exec()});return g},x.checkConnectivity=function(a){var b=p.jsonpInternetUpUrl;if(m)m.push(a);else{m=[a];c.logAction(c.LOG_MICRO,"(JSONP)Http.checkConnectivity()","Sending; "+b);var d=new g("isTheInternetUp",b,null,null,null,M.REQ_SEND, +p.TIMEOUTS);d.once("complete",function(a,b){var d=!a&&b;c.logAction(c.LOG_MICRO,"(JSONP)Http.checkConnectivity()","Result: "+d);for(var e=0;e>>2]>>>24-p%4*8&255;return b}throw Error("BufferUtils.toArrayBuffer expected a buffer");};b.toWordArray=function(b){return c(b)?b:a.create(b)};b.base64Encode=function(a){if(l(a)){var b="";a=new Uint8Array(a);for(var e=a.byteLength,k=e%3,e=e-k,h,u,y,g,t=0;t>18,u=(g&258048)>>12,y=(g&4032)>>6,g&=63,b+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[h]+ -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[u]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[y]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[g];1==k?(g=a[e],b+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(g&252)>>2]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(g&3)<<4]+"=="):2==k&&(g=a[e]<<8|a[e+1],b+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(g&64512)>>10]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(g& -1008)>>4]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(g&15)<<2]+"=");return b}if(c(a))return G.enc.Base64.stringify(a)};b.base64Decode=function(a){if(e&&k){a=k(a);for(var b=a.length,c=new Uint8Array(b),d=0;d=b}var b=function(){};c.get=function(a,e,k, -f,m){m=m||b;var n="function"==typeof e?e:function(b){return a.baseUri(b)+e},p;p=(p=a.connection)&&"connected"==p.state?[p.connectionManager.host]:r.getHosts(a.options);if(1==p.length)c.getUri(a,n(p[0]),k,f,m);else{var h=function(b){c.getUri(a,n(b.shift()),k,f,function(a){a&&l(a)&&b.length?h(b):m.apply(null,arguments)})};h(p)}};c.getUri=function(a,e,k,f,m){c.Request(a,e,k,f,null,m||b)};c.post=function(a,e,k,f,m,n){n=n||b;var p="function"==typeof e?e:function(b){return a.baseUri(b)+e},h;h=(h=a.connection)&& -"connected"==h.state?[h.connectionManager.host]:r.getHosts(a.options);if(1==h.length)c.postUri(a,p(h[0]),k,f,m,n);else{var u=function(b){c.postUri(a,p(b.shift()),k,f,m,function(a){a&&l(a)&&b.length?u(b):n.apply(null,arguments)})};u(h)}};c.postUri=function(a,e,k,f,m,n){c.Request(a,e,k,m,f,n||b)};c.supportsAuthHeaders=!1;c.supportsLinkHeaders=!1;return c}(),ga=function(){function c(){this.buffer=[]}function l(a){this._input=a;this._index=-1;this._buffer=[]}function b(a){this._input=a;this._index=-1; -this._buffer=[]}c.prototype.append=function(a){this.buffer.push(a);return this};c.prototype.toString=function(){return this.buffer.join("")};var a={codex:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(b){var k=new c,f=a.codex;for(b=new l(b);b.moveNext();){var m=b.current;b.moveNext();var n=b.current;b.moveNext();var p=b.current,h=m>>2,m=(m&3)<<4|n>>4,u=(n&15)<<2|p>>6,y=p&63;isNaN(n)?u=y=64:isNaN(p)&&(y=64);k.append(f.charAt(h)+f.charAt(m)+f.charAt(u)+f.charAt(y))}return k.toString()}, -decode:function(a){var k=new c;for(a=new b(a);a.moveNext();){var f=a.current;if(128>f)k.append(String.fromCharCode(f));else if(191f){a.moveNext();var m=a.current;k.append(String.fromCharCode((f&31)<<6|m&63))}else a.moveNext(),m=a.current,a.moveNext(),k.append(String.fromCharCode((f&15)<<12|(m&63)<<6|a.current&63))}return k.toString()}};l.prototype={current:Number.NaN,moveNext:function(){if(0=this._input.length- +a.toString(16));};return m}();"object"!==typeof window&&console.log("Warning: this distribution of Ably is intended for browsers. On nodejs, please use the 'ably' package on npm");var y={libver:"js-web-",noUpgrade:navigator&&navigator.userAgent.toString().match(/MSIE\s8\.0/),binaryType:"arraybuffer",WebSocket:window.WebSocket||window.MozWebSocket,xhrSupported:window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest,streamingSupported:!0,useProtocolHeartbeats:!0,createHmac:null,msgpack:ca,supportsBinary:!!window.TextDecoder, +preferBinary:!1,ArrayBuffer:window.ArrayBuffer,atob:window.atob,nextTick:function(c){setTimeout(c,0)},addEventListener:window.addEventListener,inspect:JSON.stringify,getRandomValues:function(c){return function(h,b){c.getRandomValues(h);b(null)}}(window.crypto||window.msCrypto)},K=function(){function c(){}function h(a){return a?window.sessionStorage:window.localStorage}function b(a,b,d,c){b={value:b};d&&(b.expires=l.now()+d);return h(c).setItem(a,JSON.stringify(b))}function a(a,b){var d=h(b).getItem(a); +if(!d)return null;d=JSON.parse(d);return d.expires&&d.expires>>2]>>>24-n%4*8&255;return b}throw Error("BufferUtils.toArrayBuffer expected a buffer");};b.toWordArray=function(b){return c(b)?b:a.create(b)};b.base64Encode=function(a){if(h(a)){var b="";a=new Uint8Array(a);for(var d=a.byteLength,g=d%3,d=d-g,k,u,w,l,t=0;t>18,u=(l&258048)>>12,w=(l&4032)>>6,l&=63,b+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[k]+ +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[u]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[w]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[l];1==g?(l=a[d],b+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(l&252)>>2]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(l&3)<<4]+"=="):2==g&&(l=a[d]<<8|a[d+1],b+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(l&64512)>>10]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(l& +1008)>>4]+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(l&15)<<2]+"=");return b}if(c(a))return G.enc.Base64.stringify(a)};b.base64Decode=function(a){if(d&&g){a=g(a);for(var b=a.length,c=new Uint8Array(b),e=0;e=b}var b=function(){};c.get=function(a,d,g, +f,m){m=m||b;var q="function"==typeof d?d:function(b){return a.baseUri(b)+d},n;n=(n=a.connection)&&"connected"==n.state?[n.connectionManager.host]:r.getHosts(a.options);if(1==n.length)c.getUri(a,q(n[0]),g,f,m);else{var k=function(b){c.getUri(a,q(b.shift()),g,f,function(a){a&&h(a)&&b.length?k(b):m.apply(null,arguments)})};k(n)}};c.getUri=function(a,d,g,f,m){c.Request(a,d,g,f,null,m||b)};c.post=function(a,d,g,f,m,q){q=q||b;var n="function"==typeof d?d:function(b){return a.baseUri(b)+d},k;k=(k=a.connection)&& +"connected"==k.state?[k.connectionManager.host]:r.getHosts(a.options);if(1==k.length)c.postUri(a,n(k[0]),g,f,m,q);else{var u=function(b){c.postUri(a,n(b.shift()),g,f,m,function(a){a&&h(a)&&b.length?u(b):q.apply(null,arguments)})};u(k)}};c.postUri=function(a,d,g,f,m,q){c.Request(a,d,g,m,f,q||b)};c.supportsAuthHeaders=!1;c.supportsLinkHeaders=!1;return c}(),ga=function(){function c(){this.buffer=[]}function h(a){this._input=a;this._index=-1;this._buffer=[]}function b(a){this._input=a;this._index=-1; +this._buffer=[]}c.prototype.append=function(a){this.buffer.push(a);return this};c.prototype.toString=function(){return this.buffer.join("")};var a={codex:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(b){var g=new c,f=a.codex;for(b=new h(b);b.moveNext();){var m=b.current;b.moveNext();var q=b.current;b.moveNext();var n=b.current,k=m>>2,m=(m&3)<<4|q>>4,u=(q&15)<<2|n>>6,w=n&63;isNaN(q)?u=w=64:isNaN(n)&&(w=64);g.append(f.charAt(k)+f.charAt(m)+f.charAt(u)+f.charAt(w))}return g.toString()}, +decode:function(a){var g=new c;for(a=new b(a);a.moveNext();){var f=a.current;if(128>f)g.append(String.fromCharCode(f));else if(191f){a.moveNext();var m=a.current;g.append(String.fromCharCode((f&31)<<6|m&63))}else a.moveNext(),m=a.current,a.moveNext(),g.append(String.fromCharCode((f&15)<<12|(m&63)<<6|a.current&63))}return g.toString()}};h.prototype={current:Number.NaN,moveNext:function(){if(0=this._input.length- 1)return this.current=Number.NaN,!1;var a=this._input.charCodeAt(++this._index);13==a&&10==this._input.charCodeAt(this._index+1)&&(a=10,this._index+=2);128>a?this.current=a:(127a?this.current=a>>6|192:(this.current=a>>12|224,this._buffer.push(a>>6&63|128)),this._buffer.push(a&63|128));return!0}};b.prototype={current:64,moveNext:function(){if(0=this._input.length-1)return this.current=64,!1;var b=a.codex.indexOf(this._input.charAt(++this._index)), -c=a.codex.indexOf(this._input.charAt(++this._index)),f=a.codex.indexOf(this._input.charAt(++this._index)),d=a.codex.indexOf(this._input.charAt(++this._index)),n=(f&3)<<6|d;this.current=b<<2|c>>4;64!=f&&this._buffer.push((c&15)<<4|f>>2);64!=d&&this._buffer.push(n);return!0}};return a}();r.protocolVersion=1;r.ENVIRONMENT="";r.REST_HOST="rest.ably.io";r.REALTIME_HOST="realtime.ably.io";r.FALLBACK_HOSTS=["A.ably-realtime.com","B.ably-realtime.com","C.ably-realtime.com","D.ably-realtime.com","E.ably-realtime.com"]; -r.PORT=80;r.TLS_PORT=443;r.TIMEOUTS={disconnectedRetryTimeout:15E3,suspendedRetryTimeout:3E4,httpRequestTimeout:15E3,channelRetryTimeout:15E3,connectionStateTtl:12E4,realtimeRequestTimeout:1E4,recvTimeout:9E4,preferenceConnectTimeout:6E3,parallelUpgradeDelay:4E3};r.httpMaxRetryCount=3;r.version="1.0.3";r.libstring=w.libver+r.version;r.apiVersion="1.0";r.getHost=function(c,l,b){return l=b?l==c.restHost&&c.realtimeHost||l||c.realtimeHost:l||c.restHost};r.getPort=function(c,l){return l||c.tls?c.tlsPort: -c.port};r.getHttpScheme=function(c){return c.tls?"https://":"http://"};r.getHosts=function(c){var l=[c.restHost],b=c.fallbackHosts;c="undefined"!==typeof c.httpMaxRetryCount?c.httpMaxRetryCount:r.httpMaxRetryCount;b&&(l=l.concat(g.arrChooseN(b,c)));return l};r.normaliseOptions=function(d){d.host&&(c.deprecated("host","restHost"),d.restHost=d.host);d.wsHost&&(c.deprecated("wsHost","realtimeHost"),d.realtimeHost=d.wsHost);d.queueEvents&&(c.deprecated("queueEvents","queueMessages"),d.queueMessages=d.queueEvents); -!0===d.recover&&(c.deprecated("{recover: true}","{recover: function(lastConnectionDetails, cb) { cb(true); }}"),d.recover=function(a,b){b(!0)});"function"===typeof d.recover&&!0===d.closeOnUnload&&(c.logAction(LOG_ERROR,"Defaults.normaliseOptions","closeOnUnload was true and a session recovery function was set - these are mutually exclusive, so unsetting the latter"),d.recover=null);d.transports&&g.arrIn(d.transports,"xhr")&&(c.deprecated('transports: ["xhr"]','transports: ["xhr_streaming"]'),g.arrDeleteValue(d.transports, -"xhr"),d.transports.push("xhr_streaming"));"queueMessages"in d||(d.queueMessages=!0);var l=!1;if(d.restHost)d.realtimeHost=d.realtimeHost||d.restHost;else{var b=d.environment&&String(d.environment).toLowerCase()||r.ENVIRONMENT,l=!b||"production"===b;d.restHost=l?r.REST_HOST:b+"-"+r.REST_HOST;d.realtimeHost=l?r.REALTIME_HOST:b+"-"+r.REALTIME_HOST}d.fallbackHosts=l||d.fallbackHostsUseDefault?r.FALLBACK_HOSTS:d.fallbackHosts;d.port=d.port||r.PORT;d.tlsPort=d.tlsPort||r.TLS_PORT;"tls"in d||(d.tls=!0); -d.timeouts={};for(var a in r.TIMEOUTS)d.timeouts[a]=d[a]||r.TIMEOUTS[a];d.useBinaryProtocol="useBinaryProtocol"in d?w.supportsBinary&&d.useBinaryProtocol:w.preferBinary;return d};var x=function(){function d(){this.any=[];this.events={};this.anyOnce=[];this.eventsOnce={}}function l(a,b,d){try{b.apply(a,d)}catch(f){c.logAction(c.LOG_ERROR,"EventEmitter.emit()","Unexpected listener exception: "+f+"; stack = "+f.stack)}}function b(a,e,c){var f,d,n,p;for(p=0;p=d?null:c.slice(0,d).join("/"),b.data=m}}};d.fromResponseBody=function(b,a,e){e&&(b="msgpack"==e?l.decode(b):JSON.parse(String(b)));for(e=0;eg.arrIndexOf(n,b.shortName)}function l(a,b,c,e,f){this.options=a;this.host=b;this.mode=c;this.connectionKey=e;this.connectionSerial=f;this.format=a.useBinaryProtocol?"msgpack": -"json"}function b(a,f){x.call(this);this.realtime=a;this.options=f;var d=f.timeouts,n=this;this.states={initialized:{state:"initialized",terminal:!1,queueEvents:!0,sendEvents:!1,failState:"disconnected"},connecting:{state:"connecting",terminal:!1,queueEvents:!0,sendEvents:!1,retryDelay:d.preferenceConnectTimeout+d.realtimeRequestTimeout,failState:"disconnected"},connected:{state:"connected",terminal:!1,queueEvents:!1,sendEvents:!0,failState:"disconnected"},synchronizing:{state:"connected",terminal:!1, -queueEvents:!0,sendEvents:!1,forceQueueEvents:!0,failState:"disconnected"},disconnected:{state:"disconnected",terminal:!1,queueEvents:!0,sendEvents:!1,retryDelay:d.disconnectedRetryTimeout,failState:"disconnected"},suspended:{state:"suspended",terminal:!1,queueEvents:!1,sendEvents:!1,retryDelay:d.suspendedRetryTimeout,failState:"suspended"},closing:{state:"closing",terminal:!1,queueEvents:!1,sendEvents:!1,retryDelay:d.realtimeRequestTimeout,failState:"closed"},closed:{state:"closed",terminal:!0,queueEvents:!1, -sendEvents:!1,failState:"closed"},failed:{state:"failed",terminal:!0,queueEvents:!1,sendEvents:!1,failState:"failed"}};this.state=this.states.initialized;this.errorReason=null;this.queuedMessages=new da;this.msgSerial=0;this.connectionSerial=this.connectionKey=this.connectionId=void 0;this.connectionStateTtl=d.connectionStateTtl;this.maxIdleInterval=null;this.transports=g.intersect(f.transports||r.defaultTransports,b.supportedTransports);this.baseTransport=g.intersect(r.baseTransportOrder,this.transports)[0]; -this.upgradeTransports=g.intersect(this.transports,r.upgradeTransports);this.transportHostBlacklist={};this.transportPreference=null;this.httpHosts=r.getHosts(f);this.activeProtocol=null;this.proposedTransports=[];this.pendingTransports=[];this.lastActivity=this.lastAutoReconnectAttempt=this.host=null;c.logAction(c.LOG_MINOR,"Realtime.ConnectionManager()","started");c.logAction(c.LOG_MICRO,"Realtime.ConnectionManager()","requested transports = ["+(f.transports||r.defaultTransports)+"]");c.logAction(c.LOG_MICRO, -"Realtime.ConnectionManager()","available transports = ["+this.transports+"]");c.logAction(c.LOG_MICRO,"Realtime.ConnectionManager()","http hosts = ["+this.httpHosts+"]");if(!this.transports.length)throw c.logAction(c.LOG_ERROR,"realtime.ConnectionManager()","no requested transports available"),Error("no requested transports available");if(d=w.addEventListener)e&&"function"===typeof f.recover&&d("beforeunload",this.persistConnection.bind(this)),!0===f.closeOnUnload&&d("beforeunload",function(){n.requestState({state:"closing"})}), -d("online",function(){if(n.state==n.states.disconnected||n.state==n.states.suspended)c.logAction(c.LOG_MINOR,"ConnectionManager caught browser \u2018online\u2019 event","reattempting connection"),n.requestState({state:"connecting"})}),d("offline",function(){n.state==n.states.connected&&(c.logAction(c.LOG_MINOR,"ConnectionManager caught browser \u2018offline\u2019 event","disconnecting active transport"),n.disconnectAllTransports())})}var a=!("undefined"===typeof K||!K.get),e=!("undefined"===typeof K|| -!K.getSession),k=v.Action,f=ea.PendingMessage,m=function(){},n=r.transportPreferenceOrder,p=n[n.length-1];l.prototype.getConnectParams=function(a){a=a?g.copy(a):{};var b=this.options;switch(this.mode){case "upgrade":a.upgrade=this.connectionKey;break;case "resume":a.resume=this.connectionKey;void 0!==this.connectionSerial&&(a.connection_serial=this.connectionSerial);break;case "recover":var c=b.recover.split(":");c&&(a.recover=c[0],a.connection_serial=c[1])}void 0!==b.clientId&&(a.clientId=b.clientId); -!1===b.echoMessages&&(a.echo="false");void 0!==this.format&&(a.format=this.format);void 0!==this.stream&&(a.stream=this.stream);void 0!==this.heartbeats&&(a.heartbeats=this.heartbeats);void 0!==b.transportParams&&g.mixin(a,b.transportParams);a.v=r.apiVersion;a.lib=r.libstring;return a};g.inherits(b,x);b.supportedTransports={};b.prototype.getTransportParams=function(a){var b=this;(function(a){if(b.connectionKey)a("resume");else if("string"===typeof b.options.recover)a("recover");else{var h=b.options.recover, -f=e&&K.getSession("ably-connection-recovery");f&&"function"===typeof h?(c.logAction(c.LOG_MINOR,"ConnectionManager.getTransportParams()","Calling clientOptions-provided recover function with last session data"),h(f,function(c){c?(b.options.recover=f.recoveryKey,a("recover")):a("clean")})):a("clean")}})(function(e){c.logAction(c.LOG_MINOR,"ConnectionManager.getTransportParams()","Transport recovery mode = "+e+("clean"==e?"":"; connectionKey = "+b.connectionKey+"; connectionSerial = "+b.connectionSerial)); -a(new l(b.options,null,e,b.connectionKey,b.connectionSerial))})};b.prototype.tryATransport=function(a,e,f){var d=this,n=a.host;c.logAction(c.LOG_MICRO,"ConnectionManager.tryATransport()","trying "+e);n in this.transportHostBlacklist&&g.arrIn(this.transportHostBlacklist[n],e)?c.logAction(c.LOG_MINOR,"ConnectionManager.tryATransport()",e+" transport is blacklisted for host "+a.host):b.supportedTransports[e].tryConnect(this,this.realtime.auth,a,function(b,n){var p=d.state;p==d.states.closing||p==d.states.closed|| -p==d.states.failed?(n&&(c.logAction(c.LOG_MINOR,"ConnectionManager.tryATransport()","connection "+p.state+" while we were attempting the transport; closing "+n),n.close()),f(!0)):b?(c.logAction(c.LOG_MINOR,"ConnectionManager.tryATransport()","transport "+e+" "+b.event+", err: "+b.error.toString()),N.isTokenErr(b.error)?d.realtime.auth._forceNewToken(null,null,function(b){b?d.actOnErrorFromAuthorize(b):d.tryATransport(a,e,f)}):"failed"===b.event?(d.notifyState({state:"failed",error:b.error}),f(!0)): -"disconnected"===b.event&&f(!1)):(c.logAction(c.LOG_MICRO,"ConnectionManager.chooseTransportForHost()","viable transport "+e+"; setting pending"),d.setTransportPending(n,a),f(null,n))})};b.prototype.setTransportPending=function(a,b){var e=b.mode;c.logAction(c.LOG_MINOR,"ConnectionManager.setTransportPending()","transport = "+a+"; mode = "+e);g.arrDeleteValue(this.proposedTransports,a);this.pendingTransports.push(a);var f=this;a.once("connected",function(c,d,n,k,m){"upgrade"==e&&f.activeProtocol?a.shortName!== -p&&g.arrIn(f.getUpgradePossibilities(),p)?setTimeout(function(){f.scheduleTransportActivation(c,a,d,n,k,m)},f.options.timeouts.parallelUpgradeDelay):f.scheduleTransportActivation(c,a,d,n,k,m):(f.activateTransport(c,a,d,n,k,m),g.nextTick(function(){f.connectImpl(b)}));"recover"===e&&f.options.recover&&(f.options.recover=null,f.unpersistConnection())});a.on(["disconnected","closed","failed"],function(b){f.deactivateTransport(a,this.event,b)});this.emit("transport.pending",a)};b.prototype.scheduleTransportActivation= -function(a,b,e,f,n,p){var k=this,m=this.activeProtocol&&this.activeProtocol.getTransport(),l=function(){b.disconnect();g.arrDeleteValue(k.pendingTransports,b)};this.state!==this.states.connected&&this.state!==this.states.connecting?(c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Current connection state ("+this.state.state+(this.state===this.states.synchronizing?", but with an upgrade already in progress":"")+") is not valid to upgrade in; abandoning upgrade to "+b.shortName), -l()):m&&!d(b,m)?(c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Proposed transport "+b.shortName+" is no better than current active transport "+m.shortName+" - abandoning upgrade"),l()):(c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Scheduling transport upgrade; transport = "+b),this.realtime.channels.onceNopending(function(d){var m;if(d)c.logAction(c.LOG_ERROR,"ConnectionManager.scheduleTransportActivation()","Unable to activate transport; transport = "+ -b+"; err = "+d);else if(b.isConnected){if(k.state===k.states.connected)c.logAction(c.LOG_MICRO,"ConnectionManager.scheduleTransportActivation()","Currently connected, so temporarily pausing events until the upgrade is complete"),k.state=k.states.synchronizing,m=k.activeProtocol;else if(k.state!==k.states.connecting){c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Current connection state ("+k.state.state+(k.state===k.states.synchronizing?", but with an upgrade already in progress": -"")+") is not valid to upgrade in; abandoning upgrade to "+b.shortName);l();return}var g=(d=n!==k.connectionId)?f:k.connectionSerial;d&&c.logAction(c.LOG_ERROR,"ConnectionManager.scheduleTransportActivation()","Upgrade resulted in new connectionId; resetting library connectionSerial from "+k.connectionSerial+" to "+g+"; upgrade error was "+a);c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Syncing transport; transport = "+b);k.sync(b,function(f,d,n){if(f)k.state===k.states.synchronizing&& -(c.logAction(c.LOG_ERROR,"ConnectionManager.scheduleTransportActivation()","Unexpected error attempting to sync transport; transport = "+b+"; err = "+f),k.disconnectAllTransports());else if(f=function(){c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Activating transport; transport = "+b);k.activateTransport(a,b,e,d,n,p);k.state===k.states.synchronizing?(c.logAction(c.LOG_MICRO,"ConnectionManager.scheduleTransportActivation()","Pre-upgrade protocol idle, sending queued messages on upgraded transport; transport = "+ -b),k.state=k.states.connected):c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Pre-upgrade protocol idle, but state is now "+k.state.state+", so leaving unchanged");k.state.sendEvents&&k.sendQueuedMessages()},m)m.onceIdle(f);else f()})}else c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Proposed transport "+b.shortName+"is no longer connected; abandoning upgrade"),l()}))};b.prototype.activateTransport=function(a,b,e,f,d,n){c.logAction(c.LOG_MINOR, -"ConnectionManager.activateTransport()","transport = "+b);a&&c.logAction(c.LOG_ERROR,"ConnectionManager.activateTransport()","error = "+a);e&&c.logAction(c.LOG_MICRO,"ConnectionManager.activateTransport()","connectionKey = "+e);void 0!==f&&c.logAction(c.LOG_MICRO,"ConnectionManager.activateTransport()","connectionSerial = "+f);d&&c.logAction(c.LOG_MICRO,"ConnectionManager.activateTransport()","connectionId = "+d);n&&c.logAction(c.LOG_MICRO,"ConnectionManager.activateTransport()","connectionDetails = "+ -JSON.stringify(n));this.persistTransportPreference(b);var k=this.state,p=this.states.connected.state;c.logAction(c.LOG_MINOR,"ConnectionManager.activateTransport()","current state = "+k.state);if(k.state==this.states.closing.state||k.state==this.states.closed.state||k.state==this.states.failed.state)return c.logAction(c.LOG_MINOR,"ConnectionManager.activateTransport()","Disconnecting transport and abandoning"),b.disconnect(),!1;g.arrDeleteValue(this.pendingTransports,b);if(!b.isConnected)return c.logAction(c.LOG_MINOR, -"ConnectionManager.activateTransport()","Declining to activate transport "+b+" since it appears to no longer be connected"),!1;var m=this.activeProtocol;this.activeProtocol=new ea(b);this.host=b.params.host;e&&this.connectionKey!=e&&this.setConnection(d,e,f);this.onConnectionDetailsUpdate(n,b);var l=this;g.nextTick(function(){b.on("connected",function(a,c,e,h,f){l.onConnectionDetailsUpdate(f,b);l.emit("update",new S(p,p,null,a))})});k.state===this.states.connected.state?a&&(this.errorReason=this.realtime.connection.errorReason= -a,this.emit("update",new S(p,p,null,a))):(this.notifyState({state:"connected",error:a}),this.errorReason=this.realtime.connection.errorReason=a||null);this.emit("transport.active",b,e,b.params);m&&(0this.connectionStateTtl+this.maxIdleInterval&&(c.logAction(c.LOG_MINOR,"ConnectionManager.checkConnectionStateFreshness()","Last known activity from realtime was "+a+"ms ago; discarding connection state"),this.clearConnection(),this.states.connecting.failState="suspended",this.states.connecting.queueEvents=!1)}};b.prototype.persistConnection=function(){if(e&&this.connectionKey&&void 0!==this.connectionSerial){var a={recoveryKey:this.connectionKey+ -":"+this.connectionSerial,disconnectedAt:g.now(),location:window.location,clientId:this.realtime.auth.clientId};e&&K.setSession("ably-connection-recovery",a)}};b.prototype.unpersistConnection=function(){e&&K.removeSession("ably-connection-recovery")};b.prototype.getStateError=function(){return L[this.state.state]};b.prototype.activeState=function(){return this.state.queueEvents||this.state.sendEvents};b.prototype.enactStateChange=function(a){c.logAction("failed"===a.current?c.LOG_ERROR:c.LOG_MAJOR, -"Connection state",a.current+(a.reason?"; reason: "+a.reason.message+", code: "+a.reason.code:""));c.logAction(c.LOG_MINOR,"ConnectionManager.enactStateChange","setting new state: "+a.current+"; reason = "+(a.reason&&a.reason.message));var b=this.state=this.states[a.current];a.reason&&(this.errorReason=a.reason,this.realtime.connection.errorReason=a.reason);(b.terminal||"suspended"===b.state)&&this.clearConnection();this.emit("connectionstate",a)};b.prototype.startTransitionTimer=function(a){c.logAction(c.LOG_MINOR, -"ConnectionManager.startTransitionTimer()","transitionState: "+a.state);this.transitionTimer&&(c.logAction(c.LOG_MINOR,"ConnectionManager.startTransitionTimer()","clearing already-running timer"),clearTimeout(this.transitionTimer));var b=this;this.transitionTimer=setTimeout(function(){b.transitionTimer&&(b.transitionTimer=null,c.logAction(c.LOG_MINOR,"ConnectionManager "+a.state+" timer expired","requesting new state: "+a.failState),b.notifyState({state:a.failState}))},a.retryDelay)};b.prototype.cancelTransitionTimer= -function(){c.logAction(c.LOG_MINOR,"ConnectionManager.cancelTransitionTimer()","");this.transitionTimer&&(clearTimeout(this.transitionTimer),this.transitionTimer=null)};b.prototype.startSuspendTimer=function(){var a=this;this.suspendTimer||(this.suspendTimer=setTimeout(function(){a.suspendTimer&&(a.suspendTimer=null,c.logAction(c.LOG_MINOR,"ConnectionManager suspend timer expired","requesting new state: suspended"),a.states.connecting.failState="suspended",a.states.connecting.queueEvents=!1,a.notifyState({state:"suspended"}))}, -this.connectionStateTtl))};b.prototype.checkSuspendTimer=function(a){"disconnected"!==a&&"suspended"!==a&&"connecting"!==a&&this.cancelSuspendTimer()};b.prototype.cancelSuspendTimer=function(){this.states.connecting.failState="disconnected";this.states.connecting.queueEvents=!0;this.suspendTimer&&(clearTimeout(this.suspendTimer),this.suspendTimer=null)};b.prototype.startRetryTimer=function(a){var b=this;this.retryTimer=setTimeout(function(){c.logAction(c.LOG_MINOR,"ConnectionManager retry timer expired", -"retrying");b.retryTimer=null;b.requestState({state:"connecting"})},a)};b.prototype.cancelRetryTimer=function(){this.retryTimer&&(clearTimeout(this.retryTimer),this.retryTimer=null)};b.prototype.notifyState=function(a){var b=a.state,e=this,f="disconnected"===b&&(this.state===this.states.connected||this.state===this.states.synchronizing||this.state===this.states.connecting&&a.error&&N.isTokenErr(a.error));c.logAction(c.LOG_MINOR,"ConnectionManager.notifyState()","new state: "+b+(f?"; will retry connection immediately": -""));if(b!=this.state.state&&(this.cancelTransitionTimer(),this.cancelRetryTimer(),this.checkSuspendTimer(a.state),!this.state.terminal)){var d=this.states[a.state];a=new S(this.state.state,d.state,d.retryDelay,a.error||L[d.state]);if(f){var n=function(){e.state===e.states.disconnected&&(e.lastAutoReconnectAttempt=g.now(),e.requestState({state:"connecting"}))},k=this.lastAutoReconnectAttempt&&g.now()-this.lastAutoReconnectAttempt+1;k&&1E3>k?(c.logAction(c.LOG_MICRO,"ConnectionManager.notifyState()", -"Last reconnect attempt was only "+k+"ms ago, waiting another "+(1E3-k)+"ms before trying again"),setTimeout(n,1E3-k)):g.nextTick(n)}else"disconnected"!==b&&"suspended"!==b||this.startRetryTimer(d.retryDelay);("disconnected"===b&&!f||"suspended"===b||d.terminal)&&g.nextTick(function(){e.disconnectAllTransports()});"connected"!=b||this.activeProtocol||c.logAction(c.LOG_ERROR,"ConnectionManager.notifyState()","Broken invariant: attempted to go into connected state, but there is no active protocol"); -this.enactStateChange(a);this.state.sendEvents?this.sendQueuedMessages():this.state.queueEvents||(this.realtime.channels.propogateConnectionInterruption(b,a.reason),this.failQueuedMessages(a.reason))}};b.prototype.requestState=function(a){var b=a.state,e=this;c.logAction(c.LOG_MINOR,"ConnectionManager.requestState()","requested state: "+b+"; current state: "+this.state.state);if(b!=this.state.state&&(this.cancelTransitionTimer(),this.cancelRetryTimer(),this.checkSuspendTimer(b),"connecting"!=b||"connected"!= -this.state.state)&&("closing"!=b||"closed"!=this.state.state)){var f=this.states[b];a=new S(this.state.state,f.state,null,a.error||L[f.state]);this.enactStateChange(a);"connecting"==b&&g.nextTick(function(){e.startConnect()});"closing"==b&&this.closeImpl()}};b.prototype.startConnect=function(){if(this.state!==this.states.connecting)c.logAction(c.LOG_MINOR,"ConnectionManager.startConnect()","Must be in connecting state to connect, but was "+this.state.state);else{var a=this.realtime.auth,b=this,e= -function(){b.checkConnectionStateFreshness();b.getTransportParams(function(a){b.connectImpl(a)})};c.logAction(c.LOG_MINOR,"ConnectionManager.startConnect()","starting connection");this.startSuspendTimer();this.startTransitionTimer(this.states.connecting);if("basic"===a.method)e();else{var f=function(a){a?b.actOnErrorFromAuthorize(a):e()};this.errorReason&&N.isTokenErr(this.errorReason)?a._forceNewToken(null,null,f):a._ensureValidAuthCredentials(f)}}};b.prototype.connectImpl=function(a){var b=this.state.state; +c=a.codex.indexOf(this._input.charAt(++this._index)),f=a.codex.indexOf(this._input.charAt(++this._index)),m=a.codex.indexOf(this._input.charAt(++this._index)),e=(f&3)<<6|m;this.current=b<<2|c>>4;64!=f&&this._buffer.push((c&15)<<4|f>>2);64!=m&&this._buffer.push(e);return!0}};return a}();r.protocolVersion=1;r.ENVIRONMENT="";r.REST_HOST="rest.ably.io";r.REALTIME_HOST="realtime.ably.io";r.FALLBACK_HOSTS=["A.ably-realtime.com","B.ably-realtime.com","C.ably-realtime.com","D.ably-realtime.com","E.ably-realtime.com"]; +r.PORT=80;r.TLS_PORT=443;r.TIMEOUTS={disconnectedRetryTimeout:15E3,suspendedRetryTimeout:3E4,httpRequestTimeout:15E3,channelRetryTimeout:15E3,connectionStateTtl:12E4,realtimeRequestTimeout:1E4,recvTimeout:9E4,preferenceConnectTimeout:6E3,parallelUpgradeDelay:4E3};r.httpMaxRetryCount=3;r.version="1.0.4";r.libstring=y.libver+r.version;r.apiVersion="1.0";r.getHost=function(c,h,b){return h=b?h==c.restHost&&c.realtimeHost||h||c.realtimeHost:h||c.restHost};r.getPort=function(c,h){return h||c.tls?c.tlsPort: +c.port};r.getHttpScheme=function(c){return c.tls?"https://":"http://"};r.getHosts=function(c){var h=[c.restHost],b=c.fallbackHosts;c="undefined"!==typeof c.httpMaxRetryCount?c.httpMaxRetryCount:r.httpMaxRetryCount;b&&(h=h.concat(l.arrChooseN(b,c)));return h};r.normaliseOptions=function(e){e.host&&(c.deprecated("host","restHost"),e.restHost=e.host);e.wsHost&&(c.deprecated("wsHost","realtimeHost"),e.realtimeHost=e.wsHost);e.queueEvents&&(c.deprecated("queueEvents","queueMessages"),e.queueMessages=e.queueEvents); +!0===e.recover&&(c.deprecated("{recover: true}","{recover: function(lastConnectionDetails, cb) { cb(true); }}"),e.recover=function(a,b){b(!0)});"function"===typeof e.recover&&!0===e.closeOnUnload&&(c.logAction(LOG_ERROR,"Defaults.normaliseOptions","closeOnUnload was true and a session recovery function was set - these are mutually exclusive, so unsetting the latter"),e.recover=null);e.transports&&l.arrIn(e.transports,"xhr")&&(c.deprecated('transports: ["xhr"]','transports: ["xhr_streaming"]'),l.arrDeleteValue(e.transports, +"xhr"),e.transports.push("xhr_streaming"));"queueMessages"in e||(e.queueMessages=!0);var h=!1;if(e.restHost)e.realtimeHost=e.realtimeHost||e.restHost;else{var b=e.environment&&String(e.environment).toLowerCase()||r.ENVIRONMENT,h=!b||"production"===b;e.restHost=h?r.REST_HOST:b+"-"+r.REST_HOST;e.realtimeHost=h?r.REALTIME_HOST:b+"-"+r.REALTIME_HOST}e.fallbackHosts=h||e.fallbackHostsUseDefault?r.FALLBACK_HOSTS:e.fallbackHosts;e.port=e.port||r.PORT;e.tlsPort=e.tlsPort||r.TLS_PORT;"tls"in e||(e.tls=!0); +e.timeouts={};for(var a in r.TIMEOUTS)e.timeouts[a]=e[a]||r.TIMEOUTS[a];e.useBinaryProtocol="useBinaryProtocol"in e?y.supportsBinary&&e.useBinaryProtocol:y.preferBinary;return e};var x=function(){function e(){this.any=[];this.events={};this.anyOnce=[];this.eventsOnce={}}function h(a,b,e){try{b.apply(a,e)}catch(f){c.logAction(c.LOG_ERROR,"EventEmitter.emit()","Unexpected listener exception: "+f+"; stack = "+f.stack)}}function b(a,d,c){var f,m,e,n;for(n=0;n=g?null:c.slice(0,g).join("/"),b.data=m}}};e.fromResponseBody=function(b,a,d){d&&(b="msgpack"==d?h.decode(b):JSON.parse(String(b)));for(d=0;dl.arrIndexOf(q, +b.shortName)}function h(a,b,c,d,f){this.options=a;this.host=b;this.mode=c;this.connectionKey=d;this.connectionSerial=f;this.format=a.useBinaryProtocol?"msgpack":"json"}function b(a,f){x.call(this);this.realtime=a;this.options=f;var g=f.timeouts,m=this;this.states={initialized:{state:"initialized",terminal:!1,queueEvents:!0,sendEvents:!1,failState:"disconnected"},connecting:{state:"connecting",terminal:!1,queueEvents:!0,sendEvents:!1,retryDelay:g.preferenceConnectTimeout+g.realtimeRequestTimeout,failState:"disconnected"}, +connected:{state:"connected",terminal:!1,queueEvents:!1,sendEvents:!0,failState:"disconnected"},synchronizing:{state:"connected",terminal:!1,queueEvents:!0,sendEvents:!1,forceQueueEvents:!0,failState:"disconnected"},disconnected:{state:"disconnected",terminal:!1,queueEvents:!0,sendEvents:!1,retryDelay:g.disconnectedRetryTimeout,failState:"disconnected"},suspended:{state:"suspended",terminal:!1,queueEvents:!1,sendEvents:!1,retryDelay:g.suspendedRetryTimeout,failState:"suspended"},closing:{state:"closing", +terminal:!1,queueEvents:!1,sendEvents:!1,retryDelay:g.realtimeRequestTimeout,failState:"closed"},closed:{state:"closed",terminal:!0,queueEvents:!1,sendEvents:!1,failState:"closed"},failed:{state:"failed",terminal:!0,queueEvents:!1,sendEvents:!1,failState:"failed"}};this.state=this.states.initialized;this.errorReason=null;this.queuedMessages=new da;this.msgSerial=0;this.connectionSerial=this.connectionKey=this.connectionId=void 0;this.connectionStateTtl=g.connectionStateTtl;this.maxIdleInterval=null; +this.transports=l.intersect(f.transports||r.defaultTransports,b.supportedTransports);this.baseTransport=l.intersect(r.baseTransportOrder,this.transports)[0];this.upgradeTransports=l.intersect(this.transports,r.upgradeTransports);this.transportHostBlacklist={};this.transportPreference=null;this.httpHosts=r.getHosts(f);this.activeProtocol=null;this.proposedTransports=[];this.pendingTransports=[];this.mostRecentMsgId=this.lastActivity=this.lastAutoReconnectAttempt=this.host=null;c.logAction(c.LOG_MINOR, +"Realtime.ConnectionManager()","started");c.logAction(c.LOG_MICRO,"Realtime.ConnectionManager()","requested transports = ["+(f.transports||r.defaultTransports)+"]");c.logAction(c.LOG_MICRO,"Realtime.ConnectionManager()","available transports = ["+this.transports+"]");c.logAction(c.LOG_MICRO,"Realtime.ConnectionManager()","http hosts = ["+this.httpHosts+"]");if(!this.transports.length)throw c.logAction(c.LOG_ERROR,"realtime.ConnectionManager()","no requested transports available"),Error("no requested transports available"); +if(g=y.addEventListener)d&&"function"===typeof f.recover&&g("beforeunload",this.persistConnection.bind(this)),!0===f.closeOnUnload&&g("beforeunload",function(){m.requestState({state:"closing"})}),g("online",function(){if(m.state==m.states.disconnected||m.state==m.states.suspended)c.logAction(c.LOG_MINOR,"ConnectionManager caught browser \u2018online\u2019 event","reattempting connection"),m.requestState({state:"connecting"})}),g("offline",function(){m.state==m.states.connected&&(c.logAction(c.LOG_MINOR, +"ConnectionManager caught browser \u2018offline\u2019 event","disconnecting active transport"),m.disconnectAllTransports())})}var a=!("undefined"===typeof K||!K.get),d=!("undefined"===typeof K||!K.getSession),g=v.Action,f=ea.PendingMessage,m=function(){},q=r.transportPreferenceOrder,n=q[q.length-1];h.prototype.getConnectParams=function(a){a=a?l.copy(a):{};var b=this.options;switch(this.mode){case "upgrade":a.upgrade=this.connectionKey;break;case "resume":a.resume=this.connectionKey;void 0!==this.connectionSerial&& +(a.connection_serial=this.connectionSerial);break;case "recover":var c=b.recover.split(":");c&&(a.recover=c[0],a.connection_serial=c[1])}void 0!==b.clientId&&(a.clientId=b.clientId);!1===b.echoMessages&&(a.echo="false");void 0!==this.format&&(a.format=this.format);void 0!==this.stream&&(a.stream=this.stream);void 0!==this.heartbeats&&(a.heartbeats=this.heartbeats);void 0!==b.transportParams&&l.mixin(a,b.transportParams);a.v=r.apiVersion;a.lib=r.libstring;return a};l.inherits(b,x);b.supportedTransports= +{};b.prototype.getTransportParams=function(a){var b=this;(function(a){if(b.connectionKey)a("resume");else if("string"===typeof b.options.recover)a("recover");else{var k=b.options.recover,f=d&&K.getSession("ably-connection-recovery");f&&"function"===typeof k?(c.logAction(c.LOG_MINOR,"ConnectionManager.getTransportParams()","Calling clientOptions-provided recover function with last session data"),k(f,function(c){c?(b.options.recover=f.recoveryKey,a("recover")):a("clean")})):a("clean")}})(function(d){c.logAction(c.LOG_MINOR, +"ConnectionManager.getTransportParams()","Transport recovery mode = "+d+("clean"==d?"":"; connectionKey = "+b.connectionKey+"; connectionSerial = "+b.connectionSerial));a(new h(b.options,null,d,b.connectionKey,b.connectionSerial))})};b.prototype.tryATransport=function(a,d,f){var g=this,m=a.host;c.logAction(c.LOG_MICRO,"ConnectionManager.tryATransport()","trying "+d);m in this.transportHostBlacklist&&l.arrIn(this.transportHostBlacklist[m],d)?c.logAction(c.LOG_MINOR,"ConnectionManager.tryATransport()", +d+" transport is blacklisted for host "+a.host):b.supportedTransports[d].tryConnect(this,this.realtime.auth,a,function(b,m){var e=g.state;e==g.states.closing||e==g.states.closed||e==g.states.failed?(m&&(c.logAction(c.LOG_MINOR,"ConnectionManager.tryATransport()","connection "+e.state+" while we were attempting the transport; closing "+m),m.close()),f(!0)):b?(c.logAction(c.LOG_MINOR,"ConnectionManager.tryATransport()","transport "+d+" "+b.event+", err: "+b.error.toString()),N.isTokenErr(b.error)?g.realtime.auth._forceNewToken(null, +null,function(b){b?g.actOnErrorFromAuthorize(b):g.tryATransport(a,d,f)}):"failed"===b.event?(g.notifyState({state:"failed",error:b.error}),f(!0)):"disconnected"===b.event&&f(!1)):(c.logAction(c.LOG_MICRO,"ConnectionManager.chooseTransportForHost()","viable transport "+d+"; setting pending"),g.setTransportPending(m,a),f(null,m))})};b.prototype.setTransportPending=function(a,b){var d=b.mode;c.logAction(c.LOG_MINOR,"ConnectionManager.setTransportPending()","transport = "+a+"; mode = "+d);l.arrDeleteValue(this.proposedTransports, +a);this.pendingTransports.push(a);var f=this;a.once("connected",function(c,g,m,e,q){"upgrade"==d&&f.activeProtocol?a.shortName!==n&&l.arrIn(f.getUpgradePossibilities(),n)?setTimeout(function(){f.scheduleTransportActivation(c,a,g,m,e,q)},f.options.timeouts.parallelUpgradeDelay):f.scheduleTransportActivation(c,a,g,m,e,q):(f.activateTransport(c,a,g,m,e,q),l.nextTick(function(){f.connectImpl(b)}));"recover"===d&&f.options.recover&&(f.options.recover=null,f.unpersistConnection())});a.on(["disconnected", +"closed","failed"],function(b){f.deactivateTransport(a,this.event,b)});this.emit("transport.pending",a)};b.prototype.scheduleTransportActivation=function(a,b,d,f,g,m){var n=this,q=this.activeProtocol&&this.activeProtocol.getTransport(),h=function(){b.disconnect();l.arrDeleteValue(n.pendingTransports,b)};this.state!==this.states.connected&&this.state!==this.states.connecting?(c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Current connection state ("+this.state.state+(this.state=== +this.states.synchronizing?", but with an upgrade already in progress":"")+") is not valid to upgrade in; abandoning upgrade to "+b.shortName),h()):q&&!e(b,q)?(c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Proposed transport "+b.shortName+" is no better than current active transport "+q.shortName+" - abandoning upgrade"),h()):(c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Scheduling transport upgrade; transport = "+b),this.realtime.channels.onceNopending(function(e){var q; +if(e)c.logAction(c.LOG_ERROR,"ConnectionManager.scheduleTransportActivation()","Unable to activate transport; transport = "+b+"; err = "+e);else if(b.isConnected){if(n.state===n.states.connected)c.logAction(c.LOG_MICRO,"ConnectionManager.scheduleTransportActivation()","Currently connected, so temporarily pausing events until the upgrade is complete"),n.state=n.states.synchronizing,q=n.activeProtocol;else if(n.state!==n.states.connecting){c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()", +"Current connection state ("+n.state.state+(n.state===n.states.synchronizing?", but with an upgrade already in progress":"")+") is not valid to upgrade in; abandoning upgrade to "+b.shortName);h();return}var l=(e=g!==n.connectionId)?f:n.connectionSerial;e&&c.logAction(c.LOG_ERROR,"ConnectionManager.scheduleTransportActivation()","Upgrade resulted in new connectionId; resetting library connectionSerial from "+n.connectionSerial+" to "+l+"; upgrade error was "+a);c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()", +"Syncing transport; transport = "+b);n.sync(b,function(f,g,e){if(f)n.state===n.states.synchronizing&&(c.logAction(c.LOG_ERROR,"ConnectionManager.scheduleTransportActivation()","Unexpected error attempting to sync transport; transport = "+b+"; err = "+f),n.disconnectAllTransports());else if(f=function(){c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Activating transport; transport = "+b);n.activateTransport(a,b,d,g,e,m);n.state===n.states.synchronizing?(c.logAction(c.LOG_MICRO, +"ConnectionManager.scheduleTransportActivation()","Pre-upgrade protocol idle, sending queued messages on upgraded transport; transport = "+b),n.state=n.states.connected):c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Pre-upgrade protocol idle, but state is now "+n.state.state+", so leaving unchanged");n.state.sendEvents&&n.sendQueuedMessages()},q)q.onceIdle(f);else f()})}else c.logAction(c.LOG_MINOR,"ConnectionManager.scheduleTransportActivation()","Proposed transport "+ +b.shortName+"is no longer connected; abandoning upgrade"),h()}))};b.prototype.activateTransport=function(a,b,d,f,g,m){c.logAction(c.LOG_MINOR,"ConnectionManager.activateTransport()","transport = "+b);a&&c.logAction(c.LOG_ERROR,"ConnectionManager.activateTransport()","error = "+a);d&&c.logAction(c.LOG_MICRO,"ConnectionManager.activateTransport()","connectionKey = "+d);void 0!==f&&c.logAction(c.LOG_MICRO,"ConnectionManager.activateTransport()","connectionSerial = "+f);g&&c.logAction(c.LOG_MICRO,"ConnectionManager.activateTransport()", +"connectionId = "+g);m&&c.logAction(c.LOG_MICRO,"ConnectionManager.activateTransport()","connectionDetails = "+JSON.stringify(m));this.persistTransportPreference(b);var e=this.state,n=this.states.connected.state;c.logAction(c.LOG_MINOR,"ConnectionManager.activateTransport()","current state = "+e.state);if(e.state==this.states.closing.state||e.state==this.states.closed.state||e.state==this.states.failed.state)return c.logAction(c.LOG_MINOR,"ConnectionManager.activateTransport()","Disconnecting transport and abandoning"), +b.disconnect(),!1;l.arrDeleteValue(this.pendingTransports,b);if(!b.isConnected)return c.logAction(c.LOG_MINOR,"ConnectionManager.activateTransport()","Declining to activate transport "+b+" since it appears to no longer be connected"),!1;var q=this.activeProtocol;this.activeProtocol=new ea(b);this.host=b.params.host;d&&this.connectionKey!=d&&this.setConnection(g,d,f);this.onConnectionDetailsUpdate(m,b);var h=this;l.nextTick(function(){b.on("connected",function(a,c,d,k,f){h.onConnectionDetailsUpdate(f, +b);h.emit("update",new S(n,n,null,a))})});e.state===this.states.connected.state?a&&(this.errorReason=this.realtime.connection.errorReason=a,this.emit("update",new S(n,n,null,a))):(this.notifyState({state:"connected",error:a}),this.errorReason=this.realtime.connection.errorReason=a||null);this.emit("transport.active",b,d,b.params);q&&(0this.connectionStateTtl+this.maxIdleInterval&&(c.logAction(c.LOG_MINOR,"ConnectionManager.checkConnectionStateFreshness()","Last known activity from realtime was "+a+"ms ago; discarding connection state"),this.clearConnection(),this.states.connecting.failState="suspended",this.states.connecting.queueEvents=!1)}};b.prototype.persistConnection=function(){if(d&&this.connectionKey&&void 0!==this.connectionSerial){var a= +{recoveryKey:this.connectionKey+":"+this.connectionSerial,disconnectedAt:l.now(),location:window.location,clientId:this.realtime.auth.clientId};d&&K.setSession("ably-connection-recovery",a)}};b.prototype.unpersistConnection=function(){d&&K.removeSession("ably-connection-recovery")};b.prototype.getStateError=function(){return L[this.state.state]};b.prototype.activeState=function(){return this.state.queueEvents||this.state.sendEvents};b.prototype.enactStateChange=function(a){c.logAction("failed"=== +a.current?c.LOG_ERROR:c.LOG_MAJOR,"Connection state",a.current+(a.reason?"; reason: "+a.reason.message+", code: "+a.reason.code:""));c.logAction(c.LOG_MINOR,"ConnectionManager.enactStateChange","setting new state: "+a.current+"; reason = "+(a.reason&&a.reason.message));var b=this.state=this.states[a.current];a.reason&&(this.errorReason=a.reason,this.realtime.connection.errorReason=a.reason);(b.terminal||"suspended"===b.state)&&this.clearConnection();this.emit("connectionstate",a)};b.prototype.startTransitionTimer= +function(a){c.logAction(c.LOG_MINOR,"ConnectionManager.startTransitionTimer()","transitionState: "+a.state);this.transitionTimer&&(c.logAction(c.LOG_MINOR,"ConnectionManager.startTransitionTimer()","clearing already-running timer"),clearTimeout(this.transitionTimer));var b=this;this.transitionTimer=setTimeout(function(){b.transitionTimer&&(b.transitionTimer=null,c.logAction(c.LOG_MINOR,"ConnectionManager "+a.state+" timer expired","requesting new state: "+a.failState),b.notifyState({state:a.failState}))}, +a.retryDelay)};b.prototype.cancelTransitionTimer=function(){c.logAction(c.LOG_MINOR,"ConnectionManager.cancelTransitionTimer()","");this.transitionTimer&&(clearTimeout(this.transitionTimer),this.transitionTimer=null)};b.prototype.startSuspendTimer=function(){var a=this;this.suspendTimer||(this.suspendTimer=setTimeout(function(){a.suspendTimer&&(a.suspendTimer=null,c.logAction(c.LOG_MINOR,"ConnectionManager suspend timer expired","requesting new state: suspended"),a.states.connecting.failState="suspended", +a.states.connecting.queueEvents=!1,a.notifyState({state:"suspended"}))},this.connectionStateTtl))};b.prototype.checkSuspendTimer=function(a){"disconnected"!==a&&"suspended"!==a&&"connecting"!==a&&this.cancelSuspendTimer()};b.prototype.cancelSuspendTimer=function(){this.states.connecting.failState="disconnected";this.states.connecting.queueEvents=!0;this.suspendTimer&&(clearTimeout(this.suspendTimer),this.suspendTimer=null)};b.prototype.startRetryTimer=function(a){var b=this;this.retryTimer=setTimeout(function(){c.logAction(c.LOG_MINOR, +"ConnectionManager retry timer expired","retrying");b.retryTimer=null;b.requestState({state:"connecting"})},a)};b.prototype.cancelRetryTimer=function(){this.retryTimer&&(clearTimeout(this.retryTimer),this.retryTimer=null)};b.prototype.notifyState=function(a){var b=a.state,d=this,f="disconnected"===b&&(this.state===this.states.connected||this.state===this.states.synchronizing||this.state===this.states.connecting&&a.error&&N.isTokenErr(a.error));c.logAction(c.LOG_MINOR,"ConnectionManager.notifyState()", +"new state: "+b+(f?"; will retry connection immediately":""));if(b!=this.state.state&&(this.cancelTransitionTimer(),this.cancelRetryTimer(),this.checkSuspendTimer(a.state),!this.state.terminal)){var g=this.states[a.state];a=new S(this.state.state,g.state,g.retryDelay,a.error||L[g.state]);if(f){var m=function(){d.state===d.states.disconnected&&(d.lastAutoReconnectAttempt=l.now(),d.requestState({state:"connecting"}))},e=this.lastAutoReconnectAttempt&&l.now()-this.lastAutoReconnectAttempt+1;e&&1E3>e? +(c.logAction(c.LOG_MICRO,"ConnectionManager.notifyState()","Last reconnect attempt was only "+e+"ms ago, waiting another "+(1E3-e)+"ms before trying again"),setTimeout(m,1E3-e)):l.nextTick(m)}else"disconnected"!==b&&"suspended"!==b||this.startRetryTimer(g.retryDelay);("disconnected"===b&&!f||"suspended"===b||g.terminal)&&l.nextTick(function(){d.disconnectAllTransports()});"connected"!=b||this.activeProtocol||c.logAction(c.LOG_ERROR,"ConnectionManager.notifyState()","Broken invariant: attempted to go into connected state, but there is no active protocol"); +this.enactStateChange(a);this.state.sendEvents?this.sendQueuedMessages():this.state.queueEvents||(this.realtime.channels.propogateConnectionInterruption(b,a.reason),this.failQueuedMessages(a.reason))}};b.prototype.requestState=function(a){var b=a.state,d=this;c.logAction(c.LOG_MINOR,"ConnectionManager.requestState()","requested state: "+b+"; current state: "+this.state.state);if(b!=this.state.state&&(this.cancelTransitionTimer(),this.cancelRetryTimer(),this.checkSuspendTimer(b),"connecting"!=b||"connected"!= +this.state.state)&&("closing"!=b||"closed"!=this.state.state)){var f=this.states[b];a=new S(this.state.state,f.state,null,a.error||L[f.state]);this.enactStateChange(a);"connecting"==b&&l.nextTick(function(){d.startConnect()});"closing"==b&&this.closeImpl()}};b.prototype.startConnect=function(){if(this.state!==this.states.connecting)c.logAction(c.LOG_MINOR,"ConnectionManager.startConnect()","Must be in connecting state to connect, but was "+this.state.state);else{var a=this.realtime.auth,b=this,d= +function(){b.checkConnectionStateFreshness();b.getTransportParams(function(a){b.connectImpl(a)})};c.logAction(c.LOG_MINOR,"ConnectionManager.startConnect()","starting connection");this.startSuspendTimer();this.startTransitionTimer(this.states.connecting);if("basic"===a.method)d();else{var f=function(a){a?b.actOnErrorFromAuthorize(a):d()};this.errorReason&&N.isTokenErr(this.errorReason)?a._forceNewToken(null,null,f):a._ensureValidAuthCredentials(f)}}};b.prototype.connectImpl=function(a){var b=this.state.state; b!==this.states.connecting.state&&b!==this.states.connected.state?c.logAction(c.LOG_MINOR,"ConnectionManager.connectImpl()","Must be in connecting state to connect (or connected to upgrade), but was "+b):this.pendingTransports.length?c.logAction(c.LOG_MINOR,"ConnectionManager.connectImpl()","Transports "+this.pendingTransports[0].toString()+" currently pending; taking no action"):b==this.states.connected.state?this.upgradeIfNeeded(a):1=b?(a="No activity seen from realtime in "+a+"ms; assuming connection has dropped",c.logAction(c.LOG_ERROR,"Transport.onIdleTimerExpire()", -a),this.disconnect(new q(a,80003,408))):this.setIdleTimer(b+10)};d.prototype.onAuthUpdated=function(){};return d}();(function(){function d(b,a,c){this.shortName="web_socket";c.heartbeats=w.useProtocolHeartbeats;Q.call(this,b,a,c);this.wsHost=r.getHost(c.options,c.host,!0)}var l=w.WebSocket;g.inherits(d,Q);d.isAvailable=function(){return!!l};d.isAvailable()&&(O.supportedTransports.web_socket=d);d.tryConnect=function(b,a,e,k){var f=new d(b,a,e),m=function(a){k({event:this.event,error:a})};f.on(["failed", -"disconnected"],m);f.on("wsopen",function(){c.logAction(c.LOG_MINOR,"WebSocketTransport.tryConnect()","viable transport "+f);f.off(["failed","disconnected"],m);k(null,f)});f.connect()};d.prototype.createWebSocket=function(b,a){var c=0;if(a)for(var d in a)b+=(c++?"&":"?")+d+"="+a[d];this.uri=b;return new l(b)};d.prototype.toString=function(){return"WebSocketTransport; uri="+this.uri};d.prototype.connect=function(){c.logAction(c.LOG_MINOR,"WebSocketTransport.connect()","starting");Q.prototype.connect.call(this); -var b=this,a=this.params,e=a.options,d=(e.tls?"wss://":"ws://")+this.wsHost+":"+r.getPort(e)+"/";c.logAction(c.LOG_MINOR,"WebSocketTransport.connect()","uri: "+d);this.auth.getAuthParams(function(e,m){var n="",p;for(p in m)n+=" "+p+": "+m[p]+";";c.logAction(c.LOG_MINOR,"WebSocketTransport.connect()","authParams:"+n+" err: "+e);if(e)b.disconnect(e);else{n=a.getConnectParams(m);try{var h=b.wsConnection=b.createWebSocket(d,n);h.binaryType=w.binaryType;h.onopen=function(){b.onWsOpen()};h.onclose=function(a){b.onWsClose(a)}; -h.onmessage=function(a){b.onWsData(a.data)};h.onerror=function(a){b.onWsError(a)};if(h.on)h.on("ping",function(){b.setIdleTimer()})}catch(l){c.logAction(c.LOG_ERROR,"WebSocketTransport.connect()","Unexpected exception creating websocket: err = "+(l.stack||l.message)),b.disconnect(l)}}})};d.prototype.send=function(b){var a=this.wsConnection;a?a.send(v.serialize(b,this.params.format)):c.logAction(c.LOG_ERROR,"WebSocketTransport.send()","No socket connection")};d.prototype.onWsData=function(b){c.logAction(c.LOG_MICRO, -"WebSocketTransport.onWsData()","data received; length = "+b.length+"; type = "+typeof b);try{this.onProtocolMessage(v.deserialize(b,this.format))}catch(a){c.logAction(c.LOG_ERROR,"WebSocketTransport.onWsData()","Unexpected exception handing channel message: "+a.stack)}};d.prototype.onWsOpen=function(){c.logAction(c.LOG_MINOR,"WebSocketTransport.onWsOpen()","opened WebSocket");this.emit("wsopen")};d.prototype.onWsClose=function(b){var a;"object"==typeof b?(a=b.wasClean,b=b.code):a=1E3==b;delete this.wsConnection; -a?(c.logAction(c.LOG_MINOR,"WebSocketTransport.onWsClose()","Cleanly closed WebSocket"),a=new q("Websocket closed",80003,400)):(b="Unclean disconnection of WebSocket ; code = "+b,a=new q(b,80003,400),c.logAction(c.LOG_ERROR,"WebSocketTransport.onWsClose()",b));this.finish("disconnected",a);this.emit("disposed")};d.prototype.onWsError=function(b){c.logAction(c.LOG_ERROR,"WebSocketTransport.onError()","Unexpected error from WebSocket: "+b.message);var a=this;g.nextTick(function(){a.disconnect(b)})}; -d.prototype.dispose=function(){c.logAction(c.LOG_MINOR,"WebSocketTransport.dispose()","");var b=this.wsConnection;b&&(b.onmessage=function(){},delete this.wsConnection,g.nextTick(function(){c.logAction(c.LOG_MICRO,"WebSocketTransport.dispose()","closing websocket");b.close()}))};return d})();var M=function(){function d(a,b,c){a&&a.server&&-1a.code)?[v.fromValues({action:v.Action.ERROR,error:a})]:[v.fromValues({action:v.Action.DISCONNECTED,error:a})]}function b(a,b,c){c.format=void 0;c.heartbeats=!0;Q.call(this,a,b,c);this.stream="stream"in c?c.stream:!0;this.pendingItems=this.pendingCallback=this.recvRequest=this.sendRequest=null;this.disposed=!1}g.inherits(b,Q);b.REQ_SEND=0;b.REQ_RECV=1;b.REQ_RECV_POLL=2;b.REQ_RECV_STREAM=3; -b.prototype.connect=function(){c.logAction(c.LOG_MINOR,"CometTransport.connect()","starting");Q.prototype.connect.call(this);var a=this,b=this.params,k=b.options,f=r.getHost(k,b.host),b=r.getPort(k);this.baseUri=(k.tls?"https://":"http://")+f+":"+b+"/comet/";var m=this.baseUri+"connect";c.logAction(c.LOG_MINOR,"CometTransport.connect()","uri: "+m);this.auth.getAuthParams(function(b,e){if(b)a.disconnect(b);else{a.authParams=e;var h=a.params.getConnectParams(e);"stream"in h&&(a.stream=h.stream);c.logAction(c.LOG_MINOR, -"CometTransport.connect()","connectParams:"+g.toQueryString(h));var k=!1,h=a.recvRequest=a.createRequest(m,null,h,null,a.stream?3:1);h.on("data",function(b){a.recvRequest&&(k||(k=!0,a.emit("preconnect")),a.onData(b))});h.on("complete",function(b,c,e){d(e,f,a.connectionManager);a.recvRequest||(b=b||new q("Request cancelled",8E4,400));a.recvRequest=null;this.maxIdleInterval&&this.setIdleTimer();if(b)if(b.code)a.onData(l(b));else a.disconnect(b);else g.nextTick(function(){a.recv()})});h.exec()}})};b.prototype.requestClose= -function(){c.logAction(c.LOG_MINOR,"CometTransport.requestClose()");this._requestCloseOrDisconnect(!0)};b.prototype.requestDisconnect=function(){c.logAction(c.LOG_MINOR,"CometTransport.requestDisconnect()");this._requestCloseOrDisconnect(!1)};b.prototype._requestCloseOrDisconnect=function(a){var b=a?this.closeUri:this.disconnectUri;if(b){var d=this,b=this.createRequest(b,null,this.authParams,null,0);b.on("complete",function(b){b&&(c.logAction(c.LOG_ERROR,"CometTransport.request"+(a?"Close()":"Disconnect()"), -"request returned err = "+b),d.finish("disconnected",b))});b.exec()}};b.prototype.dispose=function(){c.logAction(c.LOG_MINOR,"CometTransport.dispose()","");if(!this.disposed){this.disposed=!0;this.recvRequest&&(c.logAction(c.LOG_MINOR,"CometTransport.dispose()","aborting recv request"),this.recvRequest.abort(),this.recvRequest=null);this.finish("disconnected",L.disconnected);var a=this;g.nextTick(function(){a.emit("disposed")})}};b.prototype.onConnect=function(a){if(!this.disposed){var b=a.connectionKey; -Q.prototype.onConnect.call(this,a);b=this.baseUri+b;c.logAction(c.LOG_MICRO,"CometTransport.onConnect()","baseUri = "+b+"; connectionKey = "+a.connectionKey);this.sendUri=b+"/send";this.recvUri=b+"/recv";this.closeUri=b+"/close";this.disconnectUri=b+"/disconnect"}};b.prototype.send=function(a){if(this.sendRequest)this.pendingItems=this.pendingItems||[],this.pendingItems.push(a);else{var b=this.pendingItems||[];b.push(a);this.pendingItems=null;this.sendItems(b)}};b.prototype.sendAnyPending=function(){var a= -this.pendingItems;a&&(this.pendingItems=null,this.sendItems(a))};b.prototype.sendItems=function(a){var b=this;a=this.sendRequest=b.createRequest(b.sendUri,null,b.authParams,this.encodeRequest(a),0);a.on("complete",function(a,f){a&&c.logAction(c.LOG_ERROR,"CometTransport.sendItems()","on complete: err = "+JSON.stringify(a));b.sendRequest=null;if(f)b.onData(f);else if(a&&a.code)b.onData(l(a));else b.disconnect(a);b.pendingItems&&g.nextTick(function(){b.sendRequest||b.sendAnyPending()})});a.exec()}; -b.prototype.recv=function(){if(!this.recvRequest&&this.isConnected){var a=this,b=this.recvRequest=this.createRequest(this.recvUri,null,this.authParams,null,a.stream?3:2);b.on("data",function(b){a.onData(b)});b.on("complete",function(b){a.recvRequest=null;this.maxIdleInterval&&this.setIdleTimer();if(b)if(b.code)a.onData(l(b));else a.disconnect(b);else g.nextTick(function(){a.recv()})});b.exec()}};b.prototype.onData=function(a){try{var b=this.decodeResponse(a);if(b&&b.length)for(a=0;ag||300<=g?(c=c&&c.error,c||(c=Error(String(res)),c.statusCode=g),a(c)):a(null,c,d,!0,g))}}}function a(a){var b=[];if(a)for(var c in a)b.push(c+"="+a[c]);return b.join("&")} -function e(b,e,d,p){return function(h,k,l,g,t){h?c.logAction(c.LOG_MICRO,"Resource."+e+"()","Received Error; "+(d+(p?"?":"")+a(p))+"; Error: "+JSON.stringify(h)):c.logAction(c.LOG_MICRO,"Resource."+e+"()","Received; "+(d+(p?"?":"")+a(p))+"; Headers: "+a(l)+"; StatusCode: "+t+"; Body: "+(B.isBuffer(k)?k.toString():k));b&&b(h,k,l,g,t)}}var k=w.msgpack;d.get=function(f,d,n,p,h,k){function g(b,e){c.shouldLog(c.LOG_MICRO)&&c.logAction(c.LOG_MICRO,"Resource.get()","Sending; "+(d+(e?"?":"")+a(e)));A.get(f, -d,b,e,function(a,b,c,e,d){a&&N.isTokenErr(a)?f.auth.authorize(null,null,function(a){a?k(a):l(f,n,p,k,g)}):k(a,b,c,e,d)})}c.shouldLog(c.LOG_MICRO)&&(k=e(k,"get",d,p));h&&(k=k&&b(k,h),(p=p||{}).envelope=h);l(f,n,p,k,g)};d.post=function(f,d,n,p,h,g,y){function q(b,e){if(c.shouldLog(c.LOG_MICRO)){var g=n;if(0<(b["content-type"]||"").indexOf("msgpack"))try{n=k.decode(n)}catch(u){c.logAction(c.LOG_MICRO,"Resource.post()","Sending MsgPack Decoding Error: "+JSON.stringify(u))}c.logAction(c.LOG_MICRO,"Resource.post()", -"Sending; "+(d+(e?"?":"")+a(e))+"; Body: "+g)}A.post(f,d,b,n,e,function(a,b,c,e,d){a&&N.isTokenErr(a)?f.auth.authorize(null,null,function(a){a?y(a):l(f,p,h,y,q)}):y(a,b,c,e,d)})}c.shouldLog(c.LOG_MICRO)&&(y=e(y,"post",d,h));g&&(y=b(y,g),h.envelope=g);l(f,p,h,y,q)};return d}(),T=function(){function d(a,b,c,f,d,n){this.rest=a;this.path=b;this.headers=c;this.envelope=f;this.bodyHandler=d;this.useHttpPaginatedResponse=n||!1}function l(a,b,c){this.resource=a;this.items=b;if(c){var f=this;"first"in c&& -(this.first=function(a){f.get(c.first,a)});"current"in c&&(this.current=function(a){f.get(c.current,a)});this.next=function(a){"next"in c?f.get(c.next,a):a(null,null)};this.hasNext=function(){return"next"in c};this.isLast=function(){return!this.hasNext()}}}function b(a,b,c,f,d){l.call(this,a,b,d);this.statusCode=f;this.success=300>f&&200<=f;this.headers=c}d.prototype.get=function(a,b){var c=this;V.get(c.rest,c.path,c.headers,a,c.envelope,function(a,d,n,p,h){c.handlePage(a,d,n,p,h,b)})};d.prototype.post= -function(a,b,c){var f=this;V.post(f.rest,f.path,b,f.headers,a,f.envelope,function(a,b,e,d,g){c&&f.handlePage(a,b,e,d,g,c)})};d.prototype.handlePage=function(a,e,d,f,m,n){if(a)c.logAction(c.LOG_ERROR,"PaginatedResource.handlePage()","Unexpected error getting resource: err = "+JSON.stringify(a)),n(a);else{var p,h,u;try{p=this.bodyHandler(e,d,f)}catch(y){n(y);return}if(d&&(h=d.Link||d.link)){a=h;"string"==typeof a&&(a=a.split(","));e={};for(f=0;f;\s*rel="(\w+)"$/))&& -(u=(u=h[1].match(/^\.\/(\w+)\?(.*)$/))&&g.parseQueryString(u[2]))&&(e[h[2]]=u);u=e}this.useHttpPaginatedResponse?n(null,new b(this,p,d,m,u)):n(null,new l(this,p,u))}};l.prototype.get=function(a,b){var c=this.resource;V.get(c.rest,c.path,c.headers,a,c.envelope,function(a,d,n,p,h){c.handlePage(a,d,n,p,h,b)})};g.inherits(b,l);return d}(),N=function(){function d(){}function l(a){if(!a)return"";"string"==typeof a&&(a=JSON.parse(a));var b={},c=g.keysArray(a,!0);if(!c)return"";c.sort();for(var e=0;ek){e(new q("authUrl response exceeded max permitted length",40170,401));return}try{b=JSON.parse(b)}catch(h){e(new q("Unexpected error processing authURL response; err = "+h.message,40170,401));return}}e(null,b)}else e(new q("authUrl responded with unacceptable content-type "+a+", should be either text/plain or application/json",40170,401));else e(new q("authUrl response is missing a content-type header", -40170,401))};c.logAction(c.LOG_MICRO,"Auth.requestToken().tokenRequestCallback","Sending; "+b.authUrl+"; Params: "+JSON.stringify(d));b.authMethod&&"post"===b.authMethod.toLowerCase()?(f=f||{},f["content-type"]="application/x-www-form-urlencoded",d=g.toQueryString(d).slice(1),A.postUri(R,b.authUrl,f,d,{},h)):A.getUri(R,b.authUrl,f||{},d,h)};else if(b.key){var t=this;c.logAction(c.LOG_MINOR,"Auth.requestToken()","using token auth with client-side signing");y=function(a,c){t.createTokenRequest(a,b, -c)}}else{c.logAction(c.LOG_ERROR,"Auth.requestToken()","Need a new token, but authOptions does not include any way to request one");f(new q("Need a new token, but authOptions does not include any way to request one",40101,401));return}"capability"in a&&(a.capability=l(a.capability));var R=this.client,r=function(a,f){var d=a.keyName,h=function(a){return R.baseUri(a)+"/keys/"+d+"/requestToken"},n=g.defaultPostHeaders(m);b.requestHeaders&&g.mixin(n,b.requestHeaders);c.logAction(c.LOG_MICRO,"Auth.requestToken().requestToken", -"Sending POST; "+h+"; Token params: "+JSON.stringify(a));a="msgpack"==m?e.encode(a,!0):JSON.stringify(a);A.post(R,h,n,a,null,f)},v=!1,x=this.client.options.timeouts.realtimeRequestTimeout,w=setTimeout(function(){v=!0;var a="Token request callback timed out after "+x/1E3+" seconds";c.logAction(c.LOG_ERROR,"Auth.requestToken()",a);f(new q(a,40170,401))},x);y(a,function(a,b){if(!v)if(clearTimeout(w),a)c.logAction(c.LOG_ERROR,"Auth.requestToken()","token request signing call returned error; err = "+g.inspectError(a)), -a&&a.code||(a=new q(g.inspectError(a),40170,401)),f(a);else if("string"===typeof b)384k?f(new q("Token request/details object exceeded max permitted stringified size (was "+ -d+" bytes)",40170,401)):"issued"in b?f(null,b):"keyName"in b?r(b,function(a,b,d,n){a?(c.logAction(c.LOG_ERROR,"Auth.requestToken()","token request API call returned error; err = "+g.inspectError(a)),f(a)):(n||(b="msgpack"==m?e.decode(b):JSON.parse(b)),c.logAction(c.LOG_MINOR,"Auth.getToken()","token received"),f(null,b))}):(d="Expected token request callback to call back with a token string, token request object, or token details object",c.logAction(c.LOG_ERROR,"Auth.requestToken()",d),f(new q(d, -40170,401)))})};a.prototype.createTokenRequest=function(a,b,e){"function"!=typeof a||e?"function"!=typeof b||e||(e=b,b=null):(e=a,b=a=null);b=b||this.authOptions;a=a||g.copy(this.tokenParams);var d=b.key;if(d){var d=d.split(":"),k=d[0],m=d[1];if(m)if(""===a.clientId)e(new q("clientId can\u2019t be an empty string",40012,400));else{a.capability=l(a.capability);var t=g.mixin({keyName:k},a),r=a.clientId||"",v=a.ttl||"",x=a.capability,w=this;(function(a){t.timestamp?a():w.getTimestamp(b&&b.queryTime, -function(b,c){b?e(b):(t.timestamp=c,a())})})(function(){var a=t.nonce||(t.nonce=("000000"+Math.floor(1E16*Math.random())).slice(-16)),a=t.keyName+"\n"+v+"\n"+x+"\n"+r+"\n"+t.timestamp+"\n"+a+"\n";t.mac=t.mac||f(a,m);c.logAction(c.LOG_MINOR,"Auth.getTokenRequest()","generated signed request");e(null,t)})}else e(Error("Invalid key specified"))}else e(Error("No key specified"))};a.prototype.getAuthParams=function(a){"basic"==this.method?a(null,{key:this.key}):this._ensureValidAuthCredentials(function(b, -c){b?a(b):a(null,{access_token:c.token})})};a.prototype.getAuthHeaders=function(a){"basic"==this.method?a(null,{authorization:"Basic "+this.basicKey}):this._ensureValidAuthCredentials(function(b,c){b?a(b):a(null,{authorization:"Bearer "+m(c.token)})})};a.prototype.getTimestamp=function(a,b){isNaN(parseInt(this.client.serverTimeOffset))&&(a||this.authOptions.queryTime)?this.client.time(function(a,c){a?b(a):b(null,c)}):b(null,g.now()+(this.client.serverTimeOffset||0))};a.prototype._saveBasicOptions= -function(a){this.method="basic";this.key=a.key;this.basicKey=m(a.key);this.authOptions=a||{};"clientId"in a&&this._userSetClientId(a.clientId)};a.prototype._saveTokenOptions=function(a,b){this.method="token";a&&(this.tokenParams=a);b&&(b.token&&(b.tokenDetails="string"===typeof b.token?{token:b.token}:b.token),b.tokenDetails&&(this.tokenDetails=b.tokenDetails),"clientId"in b&&this._userSetClientId(b.clientId),this.authOptions=b)};a.prototype._ensureValidAuthCredentials=function(a){var b=this,e=this.tokenDetails, -d=function(){b.requestToken(b.tokenParams,b.authOptions,function(c,e){c?a(c):a(null,b.tokenDetails=e)})};e?this._tokenClientIdMismatch(e.clientId)?a(new q("Mismatch between clientId in token ("+e.clientId+") and current clientId ("+this.clientId+")",40102,401)):this.getTimestamp(b.authOptions&&b.authOptions.queryTime,function(f,k){f&&a(f);void 0===e.expires||e.expires>=k?(c.logAction(c.LOG_MINOR,"Auth.getToken()","using cached token; expires = "+e.expires),a(null,e)):(c.logAction(c.LOG_MINOR,"Auth.getToken()", -"deleting expired token"),b.tokenDetails=null,d())}):d()};a.prototype._userSetClientId=function(a){if("string"!==typeof a&&null!==a)throw new q("clientId must be either a string or null",40012,400);if("*"===a)throw new q('Can\u2019t use "*" as a clientId as that string is reserved. (To change the default token request behaviour to use a wildcard clientId, instantiate the library with {defaultTokenParams: {clientId: "*"}}), or if calling authorize(), pass it in as a tokenParam: authorize({clientId: "*"}, authOptions)', -40012,400);if(a=this._uncheckedSetClientId(a))throw a;};a.prototype._uncheckedSetClientId=function(a){if(this._tokenClientIdMismatch(a)){a="Unexpected clientId mismatch: client has "+this.clientId+", requested "+a;var b=new q(a,40102,401);c.logAction(c.LOG_ERROR,"Auth._uncheckedSetClientId()",a);return b}if("*"===a)this.tokenParams.clientId=a;else return this.clientId=this.tokenParams.clientId=a,null};a.prototype._tokenClientIdMismatch=function(a){return this.clientId&&a&&"*"!==a&&this.clientId!== -a};a.isTokenErr=function(a){return a.code&&40140<=a.code&&40150>a.code};return a}(),I=function(){function d(a){if(!(this instanceof d))return new d(a);if(!a){var b="no options provided";c.logAction(c.LOG_ERROR,"Rest()",b);throw Error(b);}"string"==typeof a&&(a=-1==a.indexOf(":")?{token:a}:{key:a});this.options=r.normaliseOptions(a);if(a.key){b=a.key.match(/^([^:\s]+):([^:.\s]+)$/);if(!b)throw b="invalid key parameter",c.logAction(c.LOG_ERROR,"Rest()",b),Error(b);a.keyName=b[1];a.keySecret=b[2]}if("clientId"in -a){if("string"!==typeof a.clientId&&null!==a.clientId)throw new q("clientId must be either a string or null",40012,400);if("*"===a.clientId)throw new q('Can\u2019t use "*" as a clientId as that string is reserved. (To change the default token request behaviour to use a wildcard clientId, use {defaultTokenParams: {clientId: "*"}})',40012,400);}a.log&&c.setLog(a.log.level,a.log.handler);c.logAction(c.LOG_MINOR,"Rest()","started");this.baseUri=this.authority=function(b){return r.getHttpScheme(a)+b+":"+ -r.getPort(a,!1)};this.serverTimeOffset=null;this.auth=new N(this,a);this.channels=new l(this)}function l(a){this.rest=a;this.attached={}}var b=function(){};d.prototype.stats=function(a,c){void 0===c&&("function"==typeof a?(c=a,a=null):c=b);var d=g.copy(g.defaultGetHeaders()),f=A.supportsLinkHeaders?void 0:"json";this.options.headers&&g.mixin(d,this.options.headers);(new T(this,"/stats",d,f,function(a,b,c){a=c?a:JSON.parse(a);for(b=0;bb.timestamp;var c=a.parseId(),d=b.parseId();return c.msgSerial===d.msgSerial?c.index>d.index:c.msgSerial>d.msgSerial}var k=function(){};g.inherits(b,U);b.prototype.enter=function(a,b){if(d(this))throw new q("clientId must be specified to enter a presence channel",40012,400);this._enterOrUpdateClient(void 0,a,b,"enter")};b.prototype.update=function(a,b){if(d(this))throw new q("clientId must be specified to update presence data", -40012,400);this._enterOrUpdateClient(void 0,a,b,"update")};b.prototype.enterClient=function(a,b,c){this._enterOrUpdateClient(a,b,c,"enter")};b.prototype.updateClient=function(a,b,c){this._enterOrUpdateClient(a,b,c,"update")};b.prototype._enterOrUpdateClient=function(a,b,d,e){d||("function"===typeof b?(d=b,b=null):d=k);var h=this.channel;if(h.connectionManager.activeState()){c.logAction(c.LOG_MICRO,"RealtimePresence."+e+"Client()",e+"ing; channel = "+h.name+", client = "+a||"(implicit) "+this.channel.realtime.auth.clientId); -var g=E.fromValues({action:e,data:b});a&&(g.clientId=a);var l=this;E.encode(g,h.channelOptions,function(a){if(a)d(a);else switch(h.state){case "attached":h.sendPresence(g,d);break;case "initialized":case "detached":h.autonomousAttach();case "attaching":l.pendingPresence.push({presence:g,callback:d});break;default:a=new q("Unable to "+e+" presence channel (incompatible state)",90001),a.code=90001,d(a)}})}else d(h.connectionManager.getStateError())};b.prototype.leave=function(a,b){if(d(this))throw new q("clientId must have been specified to enter or leave a presence channel", -40012,400);this.leaveClient(void 0,a,b)};b.prototype.leaveClient=function(a,b,d){d||("function"===typeof b?(d=b,b=null):d=k);var e=this.channel;if(e.connectionManager.activeState())switch(c.logAction(c.LOG_MICRO,"RealtimePresence.leaveClient()","leaving; channel = "+this.channel.name+", client = "+a),b=E.fromValues({action:"leave",data:b}),a&&(b.clientId=a),e.state){case "attached":e.sendPresence(b,d);break;case "attaching":this.pendingPresence.push({presence:b,callback:d});break;case "initialized":case "failed":a= -new q("Unable to leave presence channel (incompatible state)",90001);d(a);break;default:d(L.failed)}else d(e.connectionManager.getStateError())};b.prototype.get=function(){function a(b){d(null,c?b.list(c):b.values())}var b=Array.prototype.slice.call(arguments);1==b.length&&"function"==typeof b[0]&&b.unshift(null);var c=b[0],d=b[1]||k,e=!c||("waitForSync"in c?c.waitForSync:!0);if("suspended"===this.channel.state)e?d(q.fromValues({statusCode:400,code:91005,message:"Presence state is out of sync due to channel being in the SUSPENDED state"})): -a(this.members);else{var g=this;l(this.channel,d,function(){var b=g.members;e?b.waitSync(function(){a(b)}):a(b)})}};b.prototype.history=function(a,b){c.logAction(c.LOG_MICRO,"RealtimePresence.history()","channel = "+this.name);void 0===b&&("function"==typeof a?(b=a,a=null):b=k);a&&a.untilAttach&&("attached"===this.channel.state?(delete a.untilAttach,a.from_serial=this.channel.attachSerial):b(new q("option untilAttach requires the channel to be attached, was: "+this.channel.state,4E4,400)));U.prototype._history.call(this, -a,b)};b.prototype.setPresence=function(a,b,d){c.logAction(c.LOG_MICRO,"RealtimePresence.setPresence()","received presence for "+a.length+" participants; syncChannelSerial = "+d);var e,h,g=this.members,l=this._myMembers,k=[],q=this.channel.connectionManager.connectionId;b&&(this.members.startSync(),d&&(h=d.match(/^[\w\-]+:(.*)$/))&&(e=h[1]));for(d=0;dc)&&0!==t.status){if(void 0===C)if(C=t.status,1223===C&&(C=204),clearTimeout(e),B=400>C,204==C)d.complete(null,null,null,null,C);else{var f;if(f=3==d.requestMode&&B)f=t,f=f.getResponseHeader&&f.getResponseHeader("transfer-encoding")&&!f.getResponseHeader("content-length");A=f}if(3==c&&A)a();else if(4==c)if(A)b();else a:{try{var l=t.getResponseHeader&&t.getResponseHeader("content-type"),k,r=l?0<=l.indexOf("application/json"):"text"==t.responseType;z=r?t.responseText:t.response; -r&&(z=String(z),z.length&&(z=JSON.parse(z)),E=!0);if(void 0!==z.response)C=z.statusCode,B=400>C,k=z.headers,z=z.response;else{for(var u=g.trim(t.getAllResponseHeaders()).split("\r\n"),c={},l=0;la.statusCode||g.isArray(b)?l.complete(null,b,a.headers,a.statusCode):(a=b.error||new q("Error response received from server",null,a.statusCode),l.complete(a)):l.complete(new q("Invalid server response: no envelope detected",null,500))}else l.complete(null,a)};this.timer=setTimeout(function(){l.abort()},this.requestMode==M.REQ_SEND?this.timeouts.httpRequestTimeout: -this.timeouts.recvTimeout);f.insertBefore(d,f.firstChild)};l.prototype.complete=function(a,b,c,d){c=c||{};this.requestComplete||(this.requestComplete=!0,b&&(c["content-type"]="string"==typeof b?"text/plain":"application/json",this.emit("data",b)),this.emit("complete",a,b,c,!0,d),this.dispose())};l.prototype.abort=function(){this.dispose()};l.prototype.dispose=function(){var b=this.timer;b&&(clearTimeout(b),this.timer=null);b=this.script;b.parentNode&&b.parentNode.removeChild(b);delete a[this.id]; -this.emit("disposed")};A.Request||(A.Request=function(a,b,c,d,e,f){var k=n(b,c,d,e,M.REQ_SEND,a&&a.options.timeouts);k.once("complete",f);g.nextTick(function(){k.exec()});return k},A.checkConnectivity=function(a){var b=r.jsonpInternetUpUrl;if(m)m.push(a);else{m=[a];c.logAction(c.LOG_MICRO,"(JSONP)Http.checkConnectivity()","Sending; "+b);var d=new l("isTheInternetUp",b,null,null,null,M.REQ_SEND,r.TIMEOUTS);d.once("complete",function(a,b){var d=!a&&b;c.logAction(c.LOG_MICRO,"(JSONP)Http.checkConnectivity()", -"Result: "+d);for(var e=0;e=b)a="No activity seen from realtime in "+a+"ms; assuming connection has dropped",c.logAction(c.LOG_ERROR,"Transport.onIdleTimerExpire()",a),this.disconnect(new p(a,80003,408));else this.onActivity(b+10)};e.prototype.onAuthUpdated=function(){};return e}();(function(){function e(b,a,c){this.shortName="web_socket";c.heartbeats=y.useProtocolHeartbeats;Q.call(this,b,a,c);this.wsHost=r.getHost(c.options,c.host, +!0)}var h=y.WebSocket;l.inherits(e,Q);e.isAvailable=function(){return!!h};e.isAvailable()&&(O.supportedTransports.web_socket=e);e.tryConnect=function(b,a,d,g){var f=new e(b,a,d),m=function(a){g({event:this.event,error:a})};f.on(["failed","disconnected"],m);f.on("wsopen",function(){c.logAction(c.LOG_MINOR,"WebSocketTransport.tryConnect()","viable transport "+f);f.off(["failed","disconnected"],m);g(null,f)});f.connect()};e.prototype.createWebSocket=function(b,a){var c=0;if(a)for(var g in a)b+=(c++? +"&":"?")+g+"="+a[g];this.uri=b;return new h(b)};e.prototype.toString=function(){return"WebSocketTransport; uri="+this.uri};e.prototype.connect=function(){c.logAction(c.LOG_MINOR,"WebSocketTransport.connect()","starting");Q.prototype.connect.call(this);var b=this,a=this.params,d=a.options,g=(d.tls?"wss://":"ws://")+this.wsHost+":"+r.getPort(d)+"/";c.logAction(c.LOG_MINOR,"WebSocketTransport.connect()","uri: "+g);this.auth.getAuthParams(function(d,m){var e="",n;for(n in m)e+=" "+n+": "+m[n]+";";c.logAction(c.LOG_MINOR, +"WebSocketTransport.connect()","authParams:"+e+" err: "+d);if(d)b.disconnect(d);else{e=a.getConnectParams(m);try{var k=b.wsConnection=b.createWebSocket(g,e);k.binaryType=y.binaryType;k.onopen=function(){b.onWsOpen()};k.onclose=function(a){b.onWsClose(a)};k.onmessage=function(a){b.onWsData(a.data)};k.onerror=function(a){b.onWsError(a)};if(k.on)k.on("ping",function(){b.onActivity()})}catch(h){c.logAction(c.LOG_ERROR,"WebSocketTransport.connect()","Unexpected exception creating websocket: err = "+(h.stack|| +h.message)),b.disconnect(h)}}})};e.prototype.send=function(b){var a=this.wsConnection;if(a)try{a.send(v.serialize(b,this.params.format))}catch(d){b="Exception from ws connection when trying to send: "+l.inspectError(d),c.logAction(c.LOG_ERROR,"WebSocketTransport.send()",b),this.finish("disconnected",new p(b,5E4,500))}else c.logAction(c.LOG_ERROR,"WebSocketTransport.send()","No socket connection")};e.prototype.onWsData=function(b){c.logAction(c.LOG_MICRO,"WebSocketTransport.onWsData()","data received; length = "+ +b.length+"; type = "+typeof b);try{this.onProtocolMessage(v.deserialize(b,this.format))}catch(a){c.logAction(c.LOG_ERROR,"WebSocketTransport.onWsData()","Unexpected exception handing channel message: "+a.stack)}};e.prototype.onWsOpen=function(){c.logAction(c.LOG_MINOR,"WebSocketTransport.onWsOpen()","opened WebSocket");this.emit("wsopen")};e.prototype.onWsClose=function(b){var a;"object"==typeof b?(a=b.wasClean,b=b.code):a=1E3==b;delete this.wsConnection;a?(c.logAction(c.LOG_MINOR,"WebSocketTransport.onWsClose()", +"Cleanly closed WebSocket"),a=new p("Websocket closed",80003,400)):(b="Unclean disconnection of WebSocket ; code = "+b,a=new p(b,80003,400),c.logAction(c.LOG_ERROR,"WebSocketTransport.onWsClose()",b));this.finish("disconnected",a);this.emit("disposed")};e.prototype.onWsError=function(b){c.logAction(c.LOG_ERROR,"WebSocketTransport.onError()","Unexpected error from WebSocket: "+b.message);var a=this;l.nextTick(function(){a.disconnect(b)})};e.prototype.dispose=function(){c.logAction(c.LOG_MINOR,"WebSocketTransport.dispose()", +"");var b=this.wsConnection;b&&(b.onmessage=function(){},delete this.wsConnection,l.nextTick(function(){c.logAction(c.LOG_MICRO,"WebSocketTransport.dispose()","closing websocket");b.close()}))};return e})();var M=function(){function e(a,b,c){a&&a.server&&-1a.code)?[v.fromValues({action:v.Action.ERROR,error:a})]:[v.fromValues({action:v.Action.DISCONNECTED,error:a})]}function b(a,b,c){c.format=void 0;c.heartbeats=!0;Q.call(this,a,b,c);this.stream="stream"in c?c.stream:!0;this.pendingItems=this.pendingCallback=this.recvRequest=this.sendRequest=null;this.disposed=!1}l.inherits(b,Q);b.REQ_SEND=0;b.REQ_RECV=1;b.REQ_RECV_POLL=2;b.REQ_RECV_STREAM=3;b.prototype.connect=function(){c.logAction(c.LOG_MINOR,"CometTransport.connect()","starting"); +Q.prototype.connect.call(this);var a=this,b=this.params,g=b.options,f=r.getHost(g,b.host),b=r.getPort(g);this.baseUri=(g.tls?"https://":"http://")+f+":"+b+"/comet/";var m=this.baseUri+"connect";c.logAction(c.LOG_MINOR,"CometTransport.connect()","uri: "+m);this.auth.getAuthParams(function(b,d){if(b)a.disconnect(b);else{a.authParams=d;var k=a.params.getConnectParams(d);"stream"in k&&(a.stream=k.stream);c.logAction(c.LOG_MINOR,"CometTransport.connect()","connectParams:"+l.toQueryString(k));var g=!1, +k=a.recvRequest=a.createRequest(m,null,k,null,a.stream?3:1);k.on("data",function(b){a.recvRequest&&(g||(g=!0,a.emit("preconnect")),a.onData(b))});k.on("complete",function(b,c,d){e(d,f,a.connectionManager);a.recvRequest||(b=b||new p("Request cancelled",8E4,400));a.recvRequest=null;a.onActivity();if(b)if(b.code)a.onData(h(b));else a.disconnect(b);else l.nextTick(function(){a.recv()})});k.exec()}})};b.prototype.requestClose=function(){c.logAction(c.LOG_MINOR,"CometTransport.requestClose()");this._requestCloseOrDisconnect(!0)}; +b.prototype.requestDisconnect=function(){c.logAction(c.LOG_MINOR,"CometTransport.requestDisconnect()");this._requestCloseOrDisconnect(!1)};b.prototype._requestCloseOrDisconnect=function(a){var b=a?this.closeUri:this.disconnectUri;if(b){var g=this,b=this.createRequest(b,null,this.authParams,null,0);b.on("complete",function(b){b&&(c.logAction(c.LOG_ERROR,"CometTransport.request"+(a?"Close()":"Disconnect()"),"request returned err = "+b),g.finish("disconnected",b))});b.exec()}};b.prototype.dispose=function(){c.logAction(c.LOG_MINOR, +"CometTransport.dispose()","");if(!this.disposed){this.disposed=!0;this.recvRequest&&(c.logAction(c.LOG_MINOR,"CometTransport.dispose()","aborting recv request"),this.recvRequest.abort(),this.recvRequest=null);this.finish("disconnected",L.disconnected);var a=this;l.nextTick(function(){a.emit("disposed")})}};b.prototype.onConnect=function(a){if(!this.disposed){var b=a.connectionKey;Q.prototype.onConnect.call(this,a);b=this.baseUri+b;c.logAction(c.LOG_MICRO,"CometTransport.onConnect()","baseUri = "+ +b+"; connectionKey = "+a.connectionKey);this.sendUri=b+"/send";this.recvUri=b+"/recv";this.closeUri=b+"/close";this.disconnectUri=b+"/disconnect"}};b.prototype.send=function(a){if(this.sendRequest)this.pendingItems=this.pendingItems||[],this.pendingItems.push(a);else{var b=this.pendingItems||[];b.push(a);this.pendingItems=null;this.sendItems(b)}};b.prototype.sendAnyPending=function(){var a=this.pendingItems;a&&(this.pendingItems=null,this.sendItems(a))};b.prototype.sendItems=function(a){var b=this; +a=this.sendRequest=b.createRequest(b.sendUri,null,b.authParams,this.encodeRequest(a),0);a.on("complete",function(a,f){a&&c.logAction(c.LOG_ERROR,"CometTransport.sendItems()","on complete: err = "+JSON.stringify(a));b.sendRequest=null;if(f)b.onData(f);else if(a&&a.code)b.onData(h(a));else b.disconnect(a);b.pendingItems&&l.nextTick(function(){b.sendRequest||b.sendAnyPending()})});a.exec()};b.prototype.recv=function(){if(!this.recvRequest&&this.isConnected){var a=this,b=this.recvRequest=this.createRequest(this.recvUri, +null,this.authParams,null,a.stream?3:2);b.on("data",function(b){a.onData(b)});b.on("complete",function(b){a.recvRequest=null;a.onActivity();if(b)if(b.code)a.onData(h(b));else a.disconnect(b);else l.nextTick(function(){a.recv()})});b.exec()}};b.prototype.onData=function(a){try{var b=this.decodeResponse(a);if(b&&b.length)for(a=0;ah||300<=h?(c=c&&c.error,c||(c=Error(String(res)),c.statusCode=h),a(c)):a(null,c,k,!0,h))}}}function a(a){var b=[];if(a)for(var c in a)b.push(c+"="+a[c]);return b.join("&")}function d(b,d,g,e){return function(k,h,l,p,t){k?c.logAction(c.LOG_MICRO,"Resource."+d+"()", +"Received Error; "+(g+(e?"?":"")+a(e))+"; Error: "+JSON.stringify(k)):c.logAction(c.LOG_MICRO,"Resource."+d+"()","Received; "+(g+(e?"?":"")+a(e))+"; Headers: "+a(l)+"; StatusCode: "+t+"; Body: "+(B.isBuffer(h)?h.toString():h));b&&b(k,h,l,p,t)}}var g=y.msgpack;e.get=function(f,g,e,n,k,l){function w(b,d){c.shouldLog(c.LOG_MICRO)&&c.logAction(c.LOG_MICRO,"Resource.get()","Sending; "+(g+(d?"?":"")+a(d)));A.get(f,g,b,d,function(a,b,c,d,k){a&&N.isTokenErr(a)?f.auth.authorize(null,null,function(a){a?l(a): +h(f,e,n,l,w)}):l(a,b,c,d,k)})}c.shouldLog(c.LOG_MICRO)&&(l=d(l,"get",g,n));k&&(l=l&&b(l,k),(n=n||{}).envelope=k);h(f,e,n,l,w)};e.post=function(f,e,q,n,k,l,w){function p(b,d){if(c.shouldLog(c.LOG_MICRO)){var l=q;if(0<(b["content-type"]||"").indexOf("msgpack"))try{q=g.decode(q)}catch(u){c.logAction(c.LOG_MICRO,"Resource.post()","Sending MsgPack Decoding Error: "+JSON.stringify(u))}c.logAction(c.LOG_MICRO,"Resource.post()","Sending; "+(e+(d?"?":"")+a(d))+"; Body: "+l)}A.post(f,e,b,q,d,function(a,b,c, +d,g){a&&N.isTokenErr(a)?f.auth.authorize(null,null,function(a){a?w(a):h(f,n,k,w,p)}):w(a,b,c,d,g)})}c.shouldLog(c.LOG_MICRO)&&(w=d(w,"post",e,k));l&&(w=b(w,l),k.envelope=l);h(f,n,k,w,p)};return e}(),T=function(){function e(a,b,c,f,e,q){this.rest=a;this.path=b;this.headers=c;this.envelope=f;this.bodyHandler=e;this.useHttpPaginatedResponse=q||!1}function h(a,b,c){this.resource=a;this.items=b;if(c){var f=this;"first"in c&&(this.first=function(a){f.get(c.first,a)});"current"in c&&(this.current=function(a){f.get(c.current, +a)});this.next=function(a){"next"in c?f.get(c.next,a):a(null,null)};this.hasNext=function(){return"next"in c};this.isLast=function(){return!this.hasNext()}}}function b(a,b,c,f,e){h.call(this,a,b,e);this.statusCode=f;this.success=300>f&&200<=f;this.headers=c}e.prototype.get=function(a,b){var c=this;V.get(c.rest,c.path,c.headers,a,c.envelope,function(a,e,q,n,k){c.handlePage(a,e,q,n,k,b)})};e.prototype.post=function(a,b,c){var f=this;V.post(f.rest,f.path,b,f.headers,a,f.envelope,function(a,b,d,k,e){c&& +f.handlePage(a,b,d,k,e,c)})};e.prototype.handlePage=function(a,d,e,f,m,q){if(a)c.logAction(c.LOG_ERROR,"PaginatedResource.handlePage()","Unexpected error getting resource: err = "+JSON.stringify(a)),q(a);else{var n,k,u;try{n=this.bodyHandler(d,e,f)}catch(w){q(w);return}if(e&&(k=e.Link||e.link)){a=k;"string"==typeof a&&(a=a.split(","));d={};for(f=0;f;\s*rel="(\w+)"$/))&&(u=(u=k[1].match(/^\.\/(\w+)\?(.*)$/))&&l.parseQueryString(u[2]))&&(d[k[2]]=u);u=d}this.useHttpPaginatedResponse? +q(null,new b(this,n,e,m,u)):q(null,new h(this,n,u))}};h.prototype.get=function(a,b){var c=this.resource;V.get(c.rest,c.path,c.headers,a,c.envelope,function(a,e,q,n,k){c.handlePage(a,e,q,n,k,b)})};l.inherits(b,h);return e}(),N=function(){function e(){}function h(a){if(!a)return"";"string"==typeof a&&(a=JSON.parse(a));var b={},c=l.keysArray(a,!0);if(!c)return"";c.sort();for(var d=0;dg){d(new p("authUrl response exceeded max permitted length",40170,401));return}try{b=JSON.parse(b)}catch(k){d(new p("Unexpected error processing authURL response; err = "+k.message,40170,401));return}}d(null,b)}else d(new p("authUrl responded with unacceptable content-type "+a+", should be either text/plain or application/json",40170,401));else d(new p("authUrl response is missing a content-type header", +40170,401))};c.logAction(c.LOG_MICRO,"Auth.requestToken().tokenRequestCallback","Sending; "+b.authUrl+"; Params: "+JSON.stringify(e));b.authMethod&&"post"===b.authMethod.toLowerCase()?(f=f||{},f["content-type"]="application/x-www-form-urlencoded",e=l.toQueryString(e).slice(1),A.postUri(R,b.authUrl,f,e,{},k)):A.getUri(R,b.authUrl,f||{},e,k)};else if(b.key){var t=this;c.logAction(c.LOG_MINOR,"Auth.requestToken()","using token auth with client-side signing");w=function(a,c){t.createTokenRequest(a,b, +c)}}else{c.logAction(c.LOG_ERROR,"Auth.requestToken()","Need a new token, but authOptions does not include any way to request one");f(new p("Need a new token, but authOptions does not include any way to request one",40101,401));return}"capability"in a&&(a.capability=h(a.capability));var R=this.client,r=function(a,f){var e=a.keyName,k=function(a){return R.baseUri(a)+"/keys/"+e+"/requestToken"},g=l.defaultPostHeaders(m);b.requestHeaders&&l.mixin(g,b.requestHeaders);c.logAction(c.LOG_MICRO,"Auth.requestToken().requestToken", +"Sending POST; "+k+"; Token params: "+JSON.stringify(a));a="msgpack"==m?d.encode(a,!0):JSON.stringify(a);A.post(R,k,g,a,null,f)},v=!1,y=this.client.options.timeouts.realtimeRequestTimeout,x=setTimeout(function(){v=!0;var a="Token request callback timed out after "+y/1E3+" seconds";c.logAction(c.LOG_ERROR,"Auth.requestToken()",a);f(new p(a,40170,401))},y);w(a,function(a,b){if(!v)if(clearTimeout(x),a)c.logAction(c.LOG_ERROR,"Auth.requestToken()","token request signing call returned error; err = "+l.inspectError(a)), +a&&a.code||(a=new p(l.inspectError(a),40170,401)),f(a);else if("string"===typeof b)384g?f(new p("Token request/details object exceeded max permitted stringified size (was "+ +e+" bytes)",40170,401)):"issued"in b?f(null,b):"keyName"in b?r(b,function(a,b,e,g){a?(c.logAction(c.LOG_ERROR,"Auth.requestToken()","token request API call returned error; err = "+l.inspectError(a)),f(a)):(g||(b="msgpack"==m?d.decode(b):JSON.parse(b)),c.logAction(c.LOG_MINOR,"Auth.getToken()","token received"),f(null,b))}):(e="Expected token request callback to call back with a token string, token request object, or token details object",c.logAction(c.LOG_ERROR,"Auth.requestToken()",e),f(new p(e, +40170,401)))})};a.prototype.createTokenRequest=function(a,b,d){"function"!=typeof a||d?"function"!=typeof b||d||(d=b,b=null):(d=a,b=a=null);b=b||this.authOptions;a=a||l.copy(this.tokenParams);var e=b.key;if(e){var e=e.split(":"),g=e[0],m=e[1];if(m)if(""===a.clientId)d(new p("clientId can\u2019t be an empty string",40012,400));else{a.capability=h(a.capability);var t=l.mixin({keyName:g},a),r=a.clientId||"",v=a.ttl||"",y=a.capability,x=this;(function(a){t.timestamp?a():x.getTimestamp(b&&b.queryTime, +function(b,c){b?d(b):(t.timestamp=c,a())})})(function(){var a=t.nonce||(t.nonce=("000000"+Math.floor(1E16*Math.random())).slice(-16)),a=t.keyName+"\n"+v+"\n"+y+"\n"+r+"\n"+t.timestamp+"\n"+a+"\n";t.mac=t.mac||f(a,m);c.logAction(c.LOG_MINOR,"Auth.getTokenRequest()","generated signed request");d(null,t)})}else d(Error("Invalid key specified"))}else d(Error("No key specified"))};a.prototype.getAuthParams=function(a){"basic"==this.method?a(null,{key:this.key}):this._ensureValidAuthCredentials(function(b, +c){b?a(b):a(null,{access_token:c.token})})};a.prototype.getAuthHeaders=function(a){"basic"==this.method?a(null,{authorization:"Basic "+this.basicKey}):this._ensureValidAuthCredentials(function(b,c){b?a(b):a(null,{authorization:"Bearer "+m(c.token)})})};a.prototype.getTimestamp=function(a,b){isNaN(parseInt(this.client.serverTimeOffset))&&(a||this.authOptions.queryTime)?this.client.time(function(a,c){a?b(a):b(null,c)}):b(null,l.now()+(this.client.serverTimeOffset||0))};a.prototype._saveBasicOptions= +function(a){this.method="basic";this.key=a.key;this.basicKey=m(a.key);this.authOptions=a||{};"clientId"in a&&this._userSetClientId(a.clientId)};a.prototype._saveTokenOptions=function(a,b){this.method="token";a&&(this.tokenParams=a);b&&(b.token&&(b.tokenDetails="string"===typeof b.token?{token:b.token}:b.token),b.tokenDetails&&(this.tokenDetails=b.tokenDetails),"clientId"in b&&this._userSetClientId(b.clientId),this.authOptions=b)};a.prototype._ensureValidAuthCredentials=function(a){var b=this,d=this.tokenDetails, +f=function(){b.requestToken(b.tokenParams,b.authOptions,function(c,d){c?a(c):a(null,b.tokenDetails=d)})};d?this._tokenClientIdMismatch(d.clientId)?a(new p("Mismatch between clientId in token ("+d.clientId+") and current clientId ("+this.clientId+")",40102,401)):this.getTimestamp(b.authOptions&&b.authOptions.queryTime,function(e,g){e&&a(e);void 0===d.expires||d.expires>=g?(c.logAction(c.LOG_MINOR,"Auth.getToken()","using cached token; expires = "+d.expires),a(null,d)):(c.logAction(c.LOG_MINOR,"Auth.getToken()", +"deleting expired token"),b.tokenDetails=null,f())}):f()};a.prototype._userSetClientId=function(a){if("string"!==typeof a&&null!==a)throw new p("clientId must be either a string or null",40012,400);if("*"===a)throw new p('Can\u2019t use "*" as a clientId as that string is reserved. (To change the default token request behaviour to use a wildcard clientId, instantiate the library with {defaultTokenParams: {clientId: "*"}}), or if calling authorize(), pass it in as a tokenParam: authorize({clientId: "*"}, authOptions)', +40012,400);if(a=this._uncheckedSetClientId(a))throw a;};a.prototype._uncheckedSetClientId=function(a){if(this._tokenClientIdMismatch(a)){a="Unexpected clientId mismatch: client has "+this.clientId+", requested "+a;var b=new p(a,40102,401);c.logAction(c.LOG_ERROR,"Auth._uncheckedSetClientId()",a);return b}if("*"===a)this.tokenParams.clientId=a;else return this.clientId=this.tokenParams.clientId=a,null};a.prototype._tokenClientIdMismatch=function(a){return this.clientId&&a&&"*"!==a&&this.clientId!== +a};a.isTokenErr=function(a){return a.code&&40140<=a.code&&40150>a.code};return a}(),I=function(){function e(a){if(!(this instanceof e))return new e(a);if(!a){var b="no options provided";c.logAction(c.LOG_ERROR,"Rest()",b);throw Error(b);}"string"==typeof a&&(a=-1==a.indexOf(":")?{token:a}:{key:a});this.options=r.normaliseOptions(a);if(a.key){b=a.key.match(/^([^:\s]+):([^:.\s]+)$/);if(!b)throw b="invalid key parameter",c.logAction(c.LOG_ERROR,"Rest()",b),Error(b);a.keyName=b[1];a.keySecret=b[2]}if("clientId"in +a){if("string"!==typeof a.clientId&&null!==a.clientId)throw new p("clientId must be either a string or null",40012,400);if("*"===a.clientId)throw new p('Can\u2019t use "*" as a clientId as that string is reserved. (To change the default token request behaviour to use a wildcard clientId, use {defaultTokenParams: {clientId: "*"}})',40012,400);}a.log&&c.setLog(a.log.level,a.log.handler);c.logAction(c.LOG_MINOR,"Rest()","started");this.baseUri=this.authority=function(b){return r.getHttpScheme(a)+b+":"+ +r.getPort(a,!1)};this.serverTimeOffset=null;this.auth=new N(this,a);this.channels=new h(this)}function h(a){this.rest=a;this.attached={}}var b=function(){};e.prototype.stats=function(a,c){void 0===c&&("function"==typeof a?(c=a,a=null):c=b);var e=l.copy(l.defaultGetHeaders()),f=A.supportsLinkHeaders?void 0:"json";this.options.headers&&l.mixin(e,this.options.headers);(new T(this,"/stats",e,f,function(a,b,c){a=c?a:JSON.parse(a);for(b=0;bb.timestamp;var c=a.parseId(),d=b.parseId();return c.msgSerial===d.msgSerial?c.index>d.index:c.msgSerial>d.msgSerial}var g=function(){};l.inherits(b,U);b.prototype.enter=function(a,b){if(e(this))throw new p("clientId must be specified to enter a presence channel",40012,400);this._enterOrUpdateClient(void 0,a,b,"enter")};b.prototype.update=function(a,b){if(e(this))throw new p("clientId must be specified to update presence data", +40012,400);this._enterOrUpdateClient(void 0,a,b,"update")};b.prototype.enterClient=function(a,b,c){this._enterOrUpdateClient(a,b,c,"enter")};b.prototype.updateClient=function(a,b,c){this._enterOrUpdateClient(a,b,c,"update")};b.prototype._enterOrUpdateClient=function(a,b,d,e){d||("function"===typeof b?(d=b,b=null):d=g);var k=this.channel;if(k.connectionManager.activeState()){c.logAction(c.LOG_MICRO,"RealtimePresence."+e+"Client()",e+"ing; channel = "+k.name+", client = "+a||"(implicit) "+this.channel.realtime.auth.clientId); +var h=E.fromValues({action:e,data:b});a&&(h.clientId=a);var l=this;E.encode(h,k.channelOptions,function(a){if(a)d(a);else switch(k.state){case "attached":k.sendPresence(h,d);break;case "initialized":case "detached":k.autonomousAttach();case "attaching":l.pendingPresence.push({presence:h,callback:d});break;default:a=new p("Unable to "+e+" presence channel (incompatible state)",90001),a.code=90001,d(a)}})}else d(k.connectionManager.getStateError())};b.prototype.leave=function(a,b){if(e(this))throw new p("clientId must have been specified to enter or leave a presence channel", +40012,400);this.leaveClient(void 0,a,b)};b.prototype.leaveClient=function(a,b,d){d||("function"===typeof b?(d=b,b=null):d=g);var e=this.channel;if(e.connectionManager.activeState())switch(c.logAction(c.LOG_MICRO,"RealtimePresence.leaveClient()","leaving; channel = "+this.channel.name+", client = "+a),b=E.fromValues({action:"leave",data:b}),a&&(b.clientId=a),e.state){case "attached":e.sendPresence(b,d);break;case "attaching":this.pendingPresence.push({presence:b,callback:d});break;case "initialized":case "failed":a= +new p("Unable to leave presence channel (incompatible state)",90001);d(a);break;default:d(L.failed)}else d(e.connectionManager.getStateError())};b.prototype.get=function(){function a(b){d(null,c?b.list(c):b.values())}var b=Array.prototype.slice.call(arguments);1==b.length&&"function"==typeof b[0]&&b.unshift(null);var c=b[0],d=b[1]||g,e=!c||("waitForSync"in c?c.waitForSync:!0);if("suspended"===this.channel.state)e?d(p.fromValues({statusCode:400,code:91005,message:"Presence state is out of sync due to channel being in the SUSPENDED state"})): +a(this.members);else{var l=this;h(this.channel,d,function(){var b=l.members;e?b.waitSync(function(){a(b)}):a(b)})}};b.prototype.history=function(a,b){c.logAction(c.LOG_MICRO,"RealtimePresence.history()","channel = "+this.name);void 0===b&&("function"==typeof a?(b=a,a=null):b=g);a&&a.untilAttach&&("attached"===this.channel.state?(delete a.untilAttach,a.from_serial=this.channel.attachSerial):b(new p("option untilAttach requires the channel to be attached, was: "+this.channel.state,4E4,400)));U.prototype._history.call(this, +a,b)};b.prototype.setPresence=function(a,b,d){c.logAction(c.LOG_MICRO,"RealtimePresence.setPresence()","received presence for "+a.length+" participants; syncChannelSerial = "+d);var e,k,g=this.members,h=this._myMembers,l=[],p=this.channel.connectionManager.connectionId;b&&(this.members.startSync(),d&&(k=d.match(/^[\w\-]+:(.*)$/))&&(e=k[1]));for(d=0;dc)&&0!==t.status){if(void 0===C)if(C=t.status,1223===C&&(C=204),clearTimeout(e),B=400>C,204==C)d.complete(null,null,null,null,C);else{var f;if(f=3==d.requestMode&&B)f=t,f=f.getResponseHeader&&f.getResponseHeader("transfer-encoding")&&!f.getResponseHeader("content-length");A=f}if(3==c&&A)a();else if(4==c)if(A)b();else a:{try{var g=t.getResponseHeader&&t.getResponseHeader("content-type"),h,r=g?0<=g.indexOf("application/json"):"text"==t.responseType;z=r?t.responseText:t.response; +r&&(z=String(z),z.length&&(z=JSON.parse(z)),E=!0);if(void 0!==z.response)C=z.statusCode,B=400>C,h=z.headers,z=z.response;else{for(var u=l.trim(t.getAllResponseHeaders()).split("\r\n"),c={},g=0;ga.statusCode||l.isArray(b)?h.complete(null,b,a.headers,a.statusCode):(a=b.error||new p("Error response received from server",null,a.statusCode),h.complete(a)):h.complete(new p("Invalid server response: no envelope detected",null,500))}else h.complete(null,a)};this.timer=setTimeout(function(){h.abort()},this.requestMode==M.REQ_SEND?this.timeouts.httpRequestTimeout: +this.timeouts.recvTimeout);f.insertBefore(d,f.firstChild)};h.prototype.complete=function(a,b,c,d){c=c||{};this.requestComplete||(this.requestComplete=!0,b&&(c["content-type"]="string"==typeof b?"text/plain":"application/json",this.emit("data",b)),this.emit("complete",a,b,c,!0,d),this.dispose())};h.prototype.abort=function(){this.dispose()};h.prototype.dispose=function(){var b=this.timer;b&&(clearTimeout(b),this.timer=null);b=this.script;b.parentNode&&b.parentNode.removeChild(b);delete a[this.id]; +this.emit("disposed")};A.Request||(A.Request=function(a,b,c,d,e,f){var g=q(b,c,d,e,M.REQ_SEND,a&&a.options.timeouts);g.once("complete",f);l.nextTick(function(){g.exec()});return g},A.checkConnectivity=function(a){var b=r.jsonpInternetUpUrl;if(m)m.push(a);else{m=[a];c.logAction(c.LOG_MICRO,"(JSONP)Http.checkConnectivity()","Sending; "+b);var d=new h("isTheInternetUp",b,null,null,null,M.REQ_SEND,r.TIMEOUTS);d.once("complete",function(a,b){var d=!a&&b;c.logAction(c.LOG_MICRO,"(JSONP)Http.checkConnectivity()", +"Result: "+d);for(var e=0;e