(function(e){if("function"==typeof bootstrap)bootstrap("xmpp",e);else if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else if("undefined"!=typeof ses){if(!ses.ok())return;ses.makeXMPP=e}else"undefined"!=typeof window?window.XMPP=e():global.XMPP=e()})(function(){var define,ses,bootstrap,module,exports; return (function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s 0) { this.parts.bare = this.jid.slice(0, split); } else { this.parts.bare = this.jid; } return this.parts.bare; }, get resource() { if (this.parts.resource) { return this.parts.resource; } var split = this.jid.indexOf('/'); if (split > 0) { this.parts.resource = this.jid.slice(split + 1); } else { this.parts.resource = ''; } return this.parts.resource; }, get local() { if (this.parts.local) { return this.parts.local; } var bare = this.bare; var split = bare.indexOf('@'); if (split > 0) { this.parts.local = bare.slice(0, split); } else { this.parts.local = bare; } return this.parts.local; }, get domain() { if (this.parts.domain) { return this.parts.domain; } var bare = this.bare; var split = bare.indexOf('@'); if (split > 0) { this.parts.domain = bare.slice(split + 1); } else { this.parts.domain = bare; } return this.parts.domain; } }; module.exports = JID; },{}],4:[function(require,module,exports){ require('../stanza/attention'); module.exports = function (client) { client.disco.addFeature('urn:xmpp:attention:0'); client.getAttention = function (jid, opts) { opts = opts || {}; opts.to = jid; opts.type = 'headline'; opts.attention = true; client.sendMessage(opts); }; client.on('message', function (msg) { if (msg._extensions._attention) { client.emit('attention', msg); } }); }; },{"../stanza/attention":22}],5:[function(require,module,exports){ var stanzas = require('../stanza/avatar'); module.exports = function (client) { client.disco.addFeature('urn:xmpp:avatar:metadata+notify'); client.on('pubsubEvent', function (msg) { if (!msg.event._extensions.updated) return; if (msg.event.updated.node !== 'urn:xmpp:avatar:metadata') return; client.emit('avatar', { jid: msg.from, avatars: msg.event.updated.published[0].avatars }); }); client.publishAvatar = function (id, data, cb) { client.publish(null, 'urn:xmpp:avatar:data', { id: id, avatarData: data }, cb); }; client.useAvatars = function (info, cb) { client.publish(null, 'urn:xmpp:avatar:metadata', { id: 'current', avatars: info }, cb); }; client.getAvatar = function (jid, id, cb) { client.getItem(jid, 'urn:xmpp:avatar:data', id, cb); }; }; },{"../stanza/avatar":23}],6:[function(require,module,exports){ var stanzas = require('../stanza/carbons'); module.exports = function (client) { client.disco.addFeature('urn:xmpp:carbons:2'); client.enableCarbons = function (cb) { this.sendIq({ type: 'set', enableCarbons: true }, cb); }; client.disableCarbons = function (cb) { this.sendIq({ type: 'set', disableCarbons: true }, cb); }; client.on('message', function (msg) { if (msg._extensions.carbonSent) { return client.emit('carbon:sent', msg); } if (msg._extensions.carbonReceived) { return client.emit('carbon:received', msg); } }); }; },{"../stanza/carbons":26}],7:[function(require,module,exports){ var stanzas = require('../stanza/chatstates'); module.exports = function (client) { client.disco.addFeature('http://jabber.org/protocol/chatstates'); client.on('message', function (msg) { if (msg.chatState) { client.emit('chatState', { to: msg.to, from: msg.from, chatState: msg.chatState }); } }); }; },{"../stanza/chatstates":27}],8:[function(require,module,exports){ var stanzas = require('../stanza/replace'); module.exports = function (client) { client.disco.addFeature('urn:xmpp:message-correct:0'); client.on('message', function (msg) { if (msg.replace) { client.emit('replace', msg); client.emit('replace:' + msg.id, msg); } }); }; },{"../stanza/replace":41}],9:[function(require,module,exports){ var stanzas = require('../stanza/delayed'); module.exports = function (client) { client.disco.addFeature('urn:xmpp:delay'); }; },{"../stanza/delayed":29}],10:[function(require,module,exports){ /*global unescape, escape */ var _ = require('../../vendor/lodash'); var crypto = require('crypto'); require('../stanza/disco'); require('../stanza/caps'); var UTF8 = { encode: function (s) { return unescape(encodeURIComponent(s)); }, decode: function (s) { return decodeURIComponent(escape(s)); } }; function verifyVerString(info, hash, check) { if (hash === 'sha-1') { hash = 'sha1'; } var computed = generateVerString(info, hash); return computed && computed == check; } function generateVerString(info, hash) { var S = ''; var features = info.features.sort(); var identities = []; var formTypes = {}; var formOrder = []; _.forEach(info.identities, function (identity) { identities.push([ identity.category || '', identity.type || '', identity.lang || '', identity.name || '' ].join('/')); }); var idLen = identities.length; var featureLen = features.length; identities = _.unique(identities, true); features = _.unique(features, true); if (featureLen != features.length || idLen != identities.length) { return false; } S += identities.join('<') + '<'; S += features.join('<') + '<'; var illFormed = false; _.forEach(info.extensions, function (ext) { var fields = ext.fields; for (var i = 0, len = fields.length; i < len; i++) { if (fields[i].name == 'FORM_TYPE' && fields[i].type == 'hidden') { var name = fields[i].value; if (formTypes[name]) { illFormed = true; return; } formTypes[name] = ext; formOrder.push(name); return; } } }); if (illFormed) { return false; } formOrder.sort(); _.forEach(formOrder, function (name) { var ext = formTypes[name]; var fields = {}; var fieldOrder = []; S += '<' + name; _.forEach(ext.fields, function (field) { var fieldName = field.name; if (fieldName != 'FORM_TYPE') { var values = field.value || ''; if (typeof values != 'object') { values = values.split('\n'); } fields[fieldName] = values.sort(); fieldOrder.push(fieldName); } }); fieldOrder.sort(); _.forEach(fieldOrder, function (fieldName) { S += '<' + fieldName; _.forEach(fields[fieldName], function (val) { S += '<' + val; }); }); }); if (hash === 'sha-1') { hash = 'sha1'; } var ver = crypto.createHash(hash).update(UTF8.encode(S)).digest('base64'); var padding = 4 - ver.length % 4; if (padding === 4) { padding = 0; } for (var i = 0; i < padding; i++) { ver += '='; } return ver; } function Disco(client) { this.features = {}; this.identities = {}; this.extensions = {}; this.items = {}; this.caps = {}; } Disco.prototype = { constructor: { value: Disco }, addFeature: function (feature, node) { node = node || ''; if (!this.features[node]) { this.features[node] = []; } this.features[node].push(feature); }, addIdentity: function (identity, node) { node = node || ''; if (!this.identities[node]) { this.identities[node] = []; } this.identities[node].push(identity); }, addItem: function (item, node) { node = node || ''; if (!this.items[node]) { this.items[node] = []; } this.items[node].push(item); }, addExtension: function (form, node) { node = node || ''; if (!this.extensions[node]) { this.extensions[node] = []; } this.extensions[node].push(form); } }; module.exports = function (client) { client.disco = new Disco(client); client.disco.addFeature('http://jabber.org/protocol/disco#info'); client.disco.addIdentity({ category: 'client', type: 'web' }); client.getDiscoInfo = function (jid, node, cb) { this.sendIq({ to: jid, type: 'get', discoInfo: { node: node } }, cb); }; client.getDiscoItems = function (jid, node, cb) { this.sendIq({ to: jid, type: 'get', discoItems: { node: node } }, cb); }; client.updateCaps = function () { var node = this.config.capsNode || 'https://stanza.io'; var data = JSON.parse(JSON.stringify({ identities: this.disco.identities[''], features: this.disco.features[''], extensions: this.disco.extensions[''] })); var ver = generateVerString(data, 'sha-1'); this.disco.caps = { node: node, hash: 'sha-1', ver: ver }; node = node + '#' + ver; this.disco.features[node] = data.features; this.disco.identities[node] = data.identities; this.disco.extensions[node] = data.extensions; return client.getCurrentCaps(); }; client.getCurrentCaps = function () { var caps = client.disco.caps; if (!caps.ver) { return {ver: null, discoInfo: null}; } var node = caps.node + '#' + caps.ver; return { ver: caps.ver, discoInfo: { identities: client.disco.identities[node], features: client.disco.features[node], extensions: client.disco.extensions[node] } }; }; client.on('presence', function (pres) { if (pres._extensions.caps) { client.emit('disco:caps', pres); } }); client.on('iq:get:discoInfo', function (iq) { var node = iq.discoInfo.node; var reportedNode = iq.discoInfo.node; if (node === client.disco.caps.node + '#' + client.disco.caps.ver) { reportedNode = node; node = ''; } client.sendIq(iq.resultReply({ discoInfo: { node: reportedNode, identities: client.disco.identities[node] || [], features: client.disco.features[node] || [], extensions: client.disco.extensions[node] || [] } })); }); client.on('iq:get:discoItems', function (iq) { var node = iq.discoInfo.node; client.sendIq(iq.resultReply({ discoItems: { node: node, items: client.disco.items[node] || [] } })); }); client.verifyVerString = verifyVerString; client.generateVerString = generateVerString; }; },{"../../vendor/lodash":92,"../stanza/caps":25,"../stanza/disco":30,"crypto":61}],11:[function(require,module,exports){ var stanzas = require('../stanza/forwarded'); module.exports = function (client) { client.disco.addFeature('urn:xmpp:forward:0'); }; },{"../stanza/forwarded":32}],12:[function(require,module,exports){ var stanzas = require('../stanza/idle'); module.exports = function (client) { client.disco.addFeature('urn:xmpp:idle:0'); }; },{"../stanza/idle":33}],13:[function(require,module,exports){ require('../stanza/visibility'); module.exports = function (client) { client.goInvisible = function (cb) { this.sendIq({ type: 'set', invisible: true }); }; client.goVisible = function (cb) { this.sendIq({ type: 'set', visible: true }); }; }; },{"../stanza/visibility":52}],14:[function(require,module,exports){ var stanzas = require('../stanza/mam'); module.exports = function (client) { client.disco.addFeature('urn:xmpp:mam:tmp'); client.getHistory = function (opts, cb) { var self = this; var queryid = this.nextId(); opts = opts || {}; opts.queryid = queryid; var mamResults = []; this.on('mam:' + queryid, 'session', function (msg) { mamResults.push(msg); }); cb = cb || function () {}; this.sendIq({ type: 'get', id: queryid, mamQuery: opts }, function (err, resp) { if (err) { cb(err); } else { self.off('mam:' + queryid); resp.mamQuery.results = mamResults; cb(null, resp); } }); }; client.getHistoryPreferences = function (cb) { client.sendIq({ type: 'get', mamPrefs: {} }, cb); }; client.setHistoryPreferences = function (opts, cb) { client.sendIq({ type: 'set', mamPrefs: opts }, cb); }; client.on('message', function (msg) { if (msg._extensions.mam) { client.emit('mam:' + msg.mam.queryid, msg); } }); }; },{"../stanza/mam":35}],15:[function(require,module,exports){ require('../stanza/muc'); module.exports = function (client) { client.joinRoom = function (room, nick, opts) { opts = opts || {}; opts.to = room + '/' + nick; opts.caps = this.disco.caps; opts.joinMuc = opts.joinMuc || {}; this.sendPresence(opts); }; client.leaveRoom = function (room, nick, opts) { opts = opts || {}; opts.to = room + '/' + nick; opts.type = 'unavailable'; this.sendPresence(opts); }; }; },{"../stanza/muc":37}],16:[function(require,module,exports){ var stanzas = require('../stanza/pubsub'); module.exports = function (client) { client.on('message', function (msg) { if (msg._extensions.event) { client.emit('pubsubEvent', msg); } }); client.subscribeToNode = function (jid, opts, cb) { client.sendIq({ type: 'set', to: jid, pubsub: { subscribe: { node: opts.node, jid: opts.jid || client.jid } } }, cb); }; client.unsubscribeFromNode = function (jid, opts, cb) { client.sendIq({ type: 'set', to: jid, pubsub: { unsubscribe: { node: opts.node, jid: opts.jid || client.jid.split('/')[0] } } }, cb); }; client.publish = function (jid, node, item, cb) { client.sendIq({ type: 'set', to: jid, pubsub: { publish: { node: node, item: item } } }, cb); }; client.getItem = function (jid, node, id, cb) { client.sendIq({ type: 'get', to: jid, pubsub: { retrieve: { node: node, item: id } } }, cb); }; client.getItems = function (jid, node, opts, cb) { opts = opts || {}; opts.node = node; client.sendIq({ type: 'get', to: jid, pubsub: { retrieve: { node: node, max: opts.max }, rsm: opts.rsm } }, cb); }; client.retract = function (jid, node, id, notify, cb) { client.sendIq({ type: 'set', to: jid, pubsub: { retract: { node: node, notify: notify, id: id } } }, cb); }; client.purgeNode = function (jid, node, cb) { client.sendIq({ type: 'set', to: jid, pubsubOwner: { purge: node } }, cb); }; client.deleteNode = function (jid, node, cb) { client.sendIq({ type: 'set', to: jid, pubsubOwner: { del: node } }, cb); }; client.createNode = function (jid, node, config, cb) { var cmd = { type: 'set', to: jid, pubsubOwner: { create: node } }; if (config) { cmd.pubsubOwner.config = {form: config}; } client.sendIq(cmd, cb); }; }; },{"../stanza/pubsub":39}],17:[function(require,module,exports){ var stanzas = require('../stanza/receipts'); module.exports = function (client) { client.disco.addFeature('urn:xmpp:receipts'); client.on('message', function (msg) { var ackTypes = { normal: true, chat: true, headline: true }; if (ackTypes[msg.type] && msg.requestReceipt && !msg._extensions.receipt) { client.sendMessage({ to: msg.from, receipt: { id: msg.id }, id: msg.id }); } if (msg._extensions.receipt) { client.emit('receipt:' + msg.receipt.id); } }); }; },{"../stanza/receipts":40}],18:[function(require,module,exports){ var stanzas = require('../stanza/time'); module.exports = function (client) { client.disco.addFeature('urn:xmpp:time'); client.getTime = function (jid, cb) { this.sendIq({ to: jid, type: 'get', time: true }, cb); }; client.on('iq:get:time', function (iq) { var time = new Date(); client.sendIq(iq.resultReply({ time: { utc: time, tzo: time.getTimezoneOffset() } })); }); }; },{"../stanza/time":50}],19:[function(require,module,exports){ require('../stanza/version'); module.exports = function (client) { client.disco.addFeature('jabber:iq:version'); client.on('iq:get:version', function (iq) { client.sendIq(iq.resultReply({ version: client.config.version || { name: 'stanza.io' } })); }); client.getSoftwareVersion = function (jid, cb) { this.sendIq({ to: jid, type: 'get', version: {} }, cb); }; }; },{"../stanza/version":51}],20:[function(require,module,exports){ var uuid = require('node-uuid'); // normalize environment var RTCPeerConnection = null; var RTCSessionDescription = null; var RTCIceCandidate = null; var getUserMedia = null; var attachMediaStream = null; var reattachMediaStream = null; var browser = null; var webRTCSupport = true; if (navigator.mozGetUserMedia) { browser = "firefox"; // The RTCPeerConnection object. RTCPeerConnection = window.mozRTCPeerConnection; // The RTCSessionDescription object. RTCSessionDescription = window.mozRTCSessionDescription; // The RTCIceCandidate object. RTCIceCandidate = window.mozRTCIceCandidate; // Get UserMedia (only difference is the prefix). // Code from Adam Barth. getUserMedia = navigator.mozGetUserMedia.bind(navigator); // Attach a media stream to an element. attachMediaStream = function (element, stream) { element.mozSrcObject = stream; element.play(); }; reattachMediaStream = function (to, from) { to.mozSrcObject = from.mozSrcObject; to.play(); }; // Fake get{Video,Audio}Tracks MediaStream.prototype.getVideoTracks = function () { return []; }; MediaStream.prototype.getAudioTracks = function () { return []; }; } else if (navigator.webkitGetUserMedia) { browser = "chrome"; // The RTCPeerConnection object. RTCPeerConnection = window.webkitRTCPeerConnection; // Get UserMedia (only difference is the prefix). // Code from Adam Barth. getUserMedia = navigator.webkitGetUserMedia.bind(navigator); // Attach a media stream to an element. attachMediaStream = function (element, stream) { element.autoplay = true; element.src = webkitURL.createObjectURL(stream); }; reattachMediaStream = function (to, from) { to.src = from.src; }; // The representation of tracks in a stream is changed in M26. // Unify them for earlier Chrome versions in the coexisting period. if (!webkitMediaStream.prototype.getVideoTracks) { webkitMediaStream.prototype.getVideoTracks = function () { return this.videoTracks; }; webkitMediaStream.prototype.getAudioTracks = function () { return this.audioTracks; }; } // New syntax of getXXXStreams method in M26. if (!window.webkitRTCPeerConnection.prototype.getLocalStreams) { window.webkitRTCPeerConnection.prototype.getLocalStreams = function () { return this.localStreams; }; window.webkitRTCPeerConnection.prototype.getRemoteStreams = function () { return this.remoteStreams; }; } } else { webRTCSupport = false; } function WebRTC(client) { var self = this; this.client = client; this.peerConnectionConfig = { iceServers: browser == 'firefox' ? [{url: 'stun:124.124.124.2'}] : [{url: 'stun:stun.l.google.com:19302'}] }; this.peerConnectionConstraints = { optional: [{DtlsSrtpKeyAgreement: true}] }; this.media = { audio: true, video: { mandatory: {}, optional: [] } }; this.sessions = {}; this.peerSessions = {}; this.attachMediaStream = attachMediaStream; // check for support if (!webRTCSupport) { client.emit('webrtc:unsupported'); return self; } else { client.emit('webrtc:supported'); client.disco.addFeature('http://stanza.io/protocol/sox'); client.on('message', function (msg) { if (msg.type !== 'error' && msg._extensions.sox) { var session; var fullId = msg.from + ':' + msg.sox.sid; if (msg.sox.type === 'offer') { console.log('got an offer'); session = new Peer(client, msg.from, msg.sox.sid); self.sessions[fullId] = session; if (!self.peerSessions[msg.from]) { self.peerSessions[msg.from] = []; } self.peerSessions[msg.from].push(fullId); } else if (msg.sox.type === 'answer') { console.log('got an answer'); session = self.sessions[fullId]; if (session) { console.log('Setting remote description'); session.conn.setRemoteDescription(new RTCSessionDescription({ type: 'answer', sdp: msg.sox.sdp })); } } else if (msg.sox.type === 'candidate') { session = self.sessions[fullId]; if (session) { console.log('Adding new ICE candidate'); session.conn.addIceCandidate(new RTCIceCandidate({ sdpMLineIndex: msg.sox.label, candidate: msg.sox.sdp })); } } client.emit('webrtc:' + msg.sox.type, msg); } }); } } WebRTC.prototype = { constructor: { value: WebRTC }, testReadiness: function () { var self = this; if (this.localStream && this.client.sessionStarted) { // This timeout is a workaround for the strange no-audio bug // as described here: https://code.google.com/p/webrtc/issues/detail?id=1525 // remove timeout when this is fixed. setTimeout(function () { self.client.emit('webrtc:ready'); }, 1000); } }, startLocalMedia: function (element) { var self = this; getUserMedia(this.media, function (stream) { attachMediaStream(element, stream); self.localStream = stream; self.testReadiness(); }, function () { throw new Error('Failed to get access to local media.'); }); }, offerSession: function (peer) { var self = this; var sid = uuid.v4(); var session = new Peer(this.client, peer, sid); this.sessions[peer + ':' + sid] = session; if (!this.peerSessions[peer]) { this.peerSessions[peer] = []; } this.peerSessions[peer].push(peer + ':' + sid); session.conn.createOffer(function (sdp) { console.log('Setting local description'); session.conn.setLocalDescription(sdp); console.log('Sending offer'); self.client.sendMessage({ to: peer, sox: { type: 'offer', sid: sid, sdp: sdp.sdp } }); }, null, this.mediaConstraints); }, acceptSession: function (offerMsg) { var self = this; var session = self.sessions[offerMsg.from + ':' + offerMsg.sox.sid]; if (session) { console.log('Setting remote description'); session.conn.setRemoteDescription(new RTCSessionDescription({ type: 'offer', sdp: offerMsg.sox.sdp })); session.conn.createAnswer(function (sdp) { console.log('Setting local description'); session.conn.setLocalDescription(sdp); console.log('Sending answer'); self.client.sendMessage({ to: session.jid, sox: { type: 'answer', sid: session.sid, sdp: sdp.sdp } }); }, null, this.mediaConstraints); } }, declineSession: function (offerMsg) { this.endSession(offerMsg.from, offerMsg.sox.sid); }, endSession: function (peer, sid) { var session = this.sessions[peer + ':' + sid]; if (session) { var fullId = peer + ':' + sid; var index = this.peerSessions[peer].indexOf(fullId); if (index != -1) { this.peerSessions.splice(index, 1); } this.sessions[fullId] = undefined; session.conn.close(); this.client.emit('webrtc:stream:removed', { sid: session.sid, peer: session.jid }); this.client.sendMessage({ to: peer, sox: { type: 'end', sid: sid } }); } }, // Audio controls mute: function () { this._audioEnabled(false); this.client.emit('webrtc:audio:off'); }, unmute: function () { this._audioEnabled(true); this.client.emit('webrtc:audio:on'); }, // Video controls pauseVideo: function () { this._videoEnabled(false); this.client.emit('webrtc:video:off'); }, resumeVideo: function () { this._videoEnabled(true); this.client.emit('webrtc:video:on'); }, // Combined controls pause: function () { this.mute(); this.pauseVideo(); }, resume: function () { this.unmute(); this.resumeVideo(); }, // Internal methods for enabling/disabling audio/video _audioEnabled: function (bool) { this.localStream.getAudioTracks().forEach(function (track) { track.enabled = !!bool; }); }, _videoEnabled: function (bool) { this.localStream.getVideoTracks().forEach(function (track) { track.enabled = !!bool; }); } }; function Peer(client, jid, sid) { var self = this; this.client = client; this.jid = jid; this.sid = sid; this.closed = false; this.conn = new RTCPeerConnection(client.webrtc.peerConnectionConfig, client.webrtc.peerConnectionConstraints); this.conn.addStream(client.webrtc.localStream); this.conn.onicecandidate = function (event) { if (self.closed) return; if (event.candidate) { console.log('Sending candidate'); self.client.sendMessage({ mto: self.jid, sox: { type: 'candidate', sid: self.sid, label: event.candidate.sdpMLineIndex, id: event.candidate.sdpMid, sdp: event.candidate.candidate } }); } else { console.log('End of ICE candidates'); } }; this.conn.onaddstream = function (event) { self.client.emit('webrtc:stream:added', { stream: event.stream, sid: self.sid, peer: self.jid }); }; this.conn.onremovestream = function (event) { self.client.emit('webrtc:stream:removed', { sid: self.sid, peer: self.jid }); }; this.mediaConstraints = { mandatory: { OfferToReceiveAudio: true, OfferToReceiveVideo: true } }; } Peer.prototype = { constructor: { value: Peer } }; module.exports = function (client) { client.webrtc = new WebRTC(client); }; },{"node-uuid":77}],21:[function(require,module,exports){ var SM = require('./stanza/sm'); var MAX_SEQ = Math.pow(2, 32); function mod(v, n) { return ((v % n) + n) % n; } function StreamManagement(conn) { this.conn = conn; this.id = false; this.allowResume = true; this.started = false; this.lastAck = 0; this.handled = 0; this.windowSize = 1; this.windowCount = 0; this.unacked = []; } StreamManagement.prototype = { constructor: { value: StreamManagement }, enable: function () { var enable = new SM.Enable(); enable.resume = this.allowResume; this.conn.send(enable); this.handled = 0; this.started = true; }, resume: function () { var resume = new SM.Resume({ h: this.handled, previd: this.id }); this.conn.send(resume); this.started = true; }, enabled: function (resp) { this.id = resp.id; }, resumed: function (resp) { this.id = resp.id; if (resp.h) { this.process(resp, true); } }, failed: function (resp) { this.started = false; this.id = false; this.lastAck = 0; this.handled = 0; this.windowCount = 0; this.unacked = []; }, ack: function () { this.conn.send(new SM.Ack({ h: this.handled })); }, request: function () { this.conn.send(new SM.Request()); }, process: function (ack, resend) { var self = this; var numAcked = mod(ack.h - this.lastAck, MAX_SEQ); for (var i = 0; i < numAcked && this.unacked.length > 0; i++) { this.conn.emit('stanza:acked', this.unacked.shift()); } if (resend) { var resendUnacked = this.unacked; this.unacked = []; resendUnacked.forEach(function (stanza) { self.conn.send(stanza); }); } this.lastAck = ack.h; }, track: function (stanza) { var name = stanza._name; var acceptable = { message: true, presence: true, iq: true }; if (this.started && acceptable[name]) { this.unacked.push(stanza); this.windowCount += 1; if (this.windowCount == this.windowSize) { this.request(); this.windowCount = 0; } } }, handle: function (stanza) { if (this.started) { this.handled = mod(this.handled + 1, MAX_SEQ); } } }; module.exports = StreamManagement; },{"./stanza/sm":46}],22:[function(require,module,exports){ var stanza = require('jxt'); var Message = require('./message'); function Attention(data, xml) { return stanza.init(this, xml, data); } Attention.prototype = { constructor: { value: Attention }, NS: 'urn:xmpp:attention:0', EL: 'attention', _name: '_attention', toString: stanza.toString, toJSON: undefined }; Message.prototype.__defineGetter__('attention', function () { return !!this._extensions._attention; }); Message.prototype.__defineSetter__('attention', function (value) { if (value) { this._attention = true; } else if (this._extensions._attention) { this.xml.removeChild(this._extensions._attention.xml); delete this._extensions._attention; } }); stanza.extend(Message, Attention); module.exports = Attention; },{"./message":36,"jxt":75}],23:[function(require,module,exports){ var _ = require('../../vendor/lodash'); var stanza = require('jxt'); var Item = require('./pubsub').Item; var EventItem = require('./pubsub').EventItem; function getAvatarData() { return stanza.getSubText(this.xml, 'urn:xmpp:avatar:data', 'data'); } function setAvatarData(value) { stanza.setSubText(this.xml, 'urn:xmpp:avatar:data', 'data', value); stanza.setSubAttribute(this.xml, 'urn:xmpp:avatar:data', 'data', 'xmlns', 'urn:xmpp:avatar:data'); } function getAvatars() { var metadata = stanza.find(this.xml, 'urn:xmpp:avatar:metadata', 'metadata'); var results = []; if (metadata.length) { var avatars = stanza.find(metadata[0], 'urn:xmpp:avatar:metadata', 'info'); _.forEach(avatars, function (info) { results.push(new Avatar({}, info)); }); } return results; } function setAvatars(value) { var metadata = stanza.findOrCreate(this.xml, 'urn:xmpp:avatar:metadata', 'metadata'); stanza.setAttribute(metadata, 'xmlns', 'urn:xmpp:avatar:metadata'); _.forEach(value, function (info) { var avatar = new Avatar(info); metadata.appendChild(avatar.xml); }); } Item.prototype.__defineGetter__('avatarData', getAvatarData); Item.prototype.__defineSetter__('avatarData', setAvatarData); EventItem.prototype.__defineGetter__('avatarData', getAvatarData); EventItem.prototype.__defineSetter__('avatarData', setAvatarData); Item.prototype.__defineGetter__('avatars', getAvatars); Item.prototype.__defineSetter__('avatars', setAvatars); EventItem.prototype.__defineGetter__('avatars', getAvatars); EventItem.prototype.__defineSetter__('avatars', setAvatars); function Avatar(data, xml) { return stanza.init(this, xml, data); } Avatar.prototype = { constructor: { value: Avatar }, _name: 'avatars', NS: 'urn:xmpp:avatar:metadata', EL: 'info', toString: stanza.toString, toJSON: stanza.toJSON, get id() { return stanza.getAttribute(this.xml, 'id'); }, set id(value) { stanza.setAttribute(this.xml, 'id', value); }, get bytes() { return stanza.getAttribute(this.xml, 'bytes'); }, set bytes(value) { stanza.setAttribute(this.xml, 'bytes', value); }, get height() { return stanza.getAttribute(this.xml, 'height'); }, set height(value) { stanza.setAttribute(this.xml, 'height', value); }, get width() { return stanza.getAttribute(this.xml, 'width'); }, set width(value) { stanza.setAttribute(this.xml, 'width', value); }, get type() { return stanza.getAttribute(this.xml, 'type', 'image/png'); }, set type(value) { stanza.setAttribute(this.xml, 'type', value); }, get url() { return stanza.getAttribute(this.xml, 'url'); }, set url(value) { stanza.setAttribute(this.xml, 'url', value); } }; module.exports = Avatar; },{"../../vendor/lodash":92,"./pubsub":39,"jxt":75}],24:[function(require,module,exports){ var stanza = require('jxt'); var Iq = require('./iq'); var StreamFeatures = require('./streamFeatures'); var JID = require('../jid'); function Bind(data, xml) { return stanza.init(this, xml, data); } Bind.prototype = { constructor: { value: Bind }, _name: 'bind', NS: 'urn:ietf:params:xml:ns:xmpp-bind', EL: 'bind', toString: stanza.toString, toJSON: stanza.toJSON, get resource() { return stanza.getSubText(this.xml, this.NS, 'resource'); }, set resource(value) { stanza.setSubText(this.xml, this.NS, 'resource', value); }, get jid() { return new JID(stanza.getSubText(this.xml, this.NS, 'jid')); }, set jid(value) { stanza.setSubText(this.xml, this.NS, 'jid', value.toString()); } }; stanza.extend(Iq, Bind); stanza.extend(StreamFeatures, Bind); module.exports = Bind; },{"../jid":3,"./iq":34,"./streamFeatures":49,"jxt":75}],25:[function(require,module,exports){ var stanza = require('jxt'); var Presence = require('./presence'); var StreamFeatures = require('./streamFeatures'); function Caps(data, xml) { return stanza.init(this, xml, data); } Caps.prototype = { constructor: { value: Caps }, NS: 'http://jabber.org/protocol/caps', EL: 'c', _name: 'caps', toString: stanza.toString, toJSON: stanza.toJSON, get ver() { return stanza.getAttribute(this.xml, 'ver'); }, set ver(value) { stanza.setAttribute(this.xml, 'ver', value); }, get node() { return stanza.getAttribute(this.xml, 'node'); }, set node(value) { stanza.setAttribute(this.xml, 'node', value); }, get hash() { return stanza.getAttribute(this.xml, 'hash'); }, set hash(value) { stanza.setAttribute(this.xml, 'hash', value); }, get ext() { return stanza.getAttribute(this.xml, 'ext'); }, set ext(value) { stanza.setAttribute(this.xml, 'ext', value); } }; stanza.extend(Presence, Caps); stanza.extend(StreamFeatures, Caps); module.exports = Caps; },{"./presence":38,"./streamFeatures":49,"jxt":75}],26:[function(require,module,exports){ var stanza = require('jxt'); var Message = require('./message'); var Iq = require('./iq'); var Forwarded = require('./forwarded'); function Sent(data, xml) { return stanza.init(this, xml, data); } Sent.prototype = { constructor: { value: Sent }, NS: 'urn:xmpp:carbons:2', EL: 'sent', _name: 'carbonSent', _eventname: 'carbon:sent', toString: stanza.toString, toJSON: stanza.toJSON }; function Received(data, xml) { return stanza.init(this, xml, data); } Received.prototype = { constructor: { value: Received }, NS: 'urn:xmpp:carbons:2', EL: 'received', _name: 'carbonReceived', _eventname: 'carbon:received', toString: stanza.toString, toJSON: stanza.toJSON }; function Private(data, xml) { return stanza.init(this, xml, data); } Private.prototype = { constructor: { value: Private }, NS: 'urn:xmpp:carbons:2', EL: 'private', _name: 'carbonPrivate', _eventname: 'carbon:private', toString: stanza.toString, toJSON: stanza.toJSON }; function Enable(data, xml) { return stanza.init(this, xml, data); } Enable.prototype = { constructor: { value: Enable }, NS: 'urn:xmpp:carbons:2', EL: 'enable', _name: 'enableCarbons', toString: stanza.toString, toJSON: stanza.toJSON }; function Disable(data, xml) { return stanza.init(this, xml, data); } Disable.prototype = { constructor: { value: Disable }, NS: 'urn:xmpp:carbons:2', EL: 'disable', _name: 'disableCarbons', toString: stanza.toString, toJSON: stanza.toJSON }; stanza.extend(Sent, Forwarded); stanza.extend(Received, Forwarded); stanza.extend(Message, Sent); stanza.extend(Message, Received); stanza.extend(Message, Private); stanza.extend(Iq, Enable); stanza.extend(Iq, Disable); exports.Sent = Sent; exports.Received = Received; exports.Private = Private; exports.Enable = Enable; exports.Disable = Disable; },{"./forwarded":32,"./iq":34,"./message":36,"jxt":75}],27:[function(require,module,exports){ var stanza = require('jxt'); var Message = require('./message'); function ChatStateActive(data, xml) { return stanza.init(this, xml, data); } ChatStateActive.prototype = { constructor: { value: ChatStateActive }, NS: 'http://jabber.org/protocol/chatstates', EL: 'active', _name: 'chatStateActive', _eventname: 'chat:active', toString: stanza.toString, toJSON: undefined }; function ChatStateComposing(data, xml) { return stanza.init(this, xml, data); } ChatStateComposing.prototype = { constructor: { value: ChatStateComposing }, NS: 'http://jabber.org/protocol/chatstates', EL: 'composing', _name: 'chatStateComposing', _eventname: 'chat:composing', toString: stanza.toString, toJSON: undefined }; function ChatStatePaused(data, xml) { return stanza.init(this, xml, data); } ChatStatePaused.prototype = { constructor: { value: ChatStatePaused }, NS: 'http://jabber.org/protocol/chatstates', EL: 'paused', _name: 'chatStatePaused', _eventname: 'chat:paused', toString: stanza.toString, toJSON: undefined }; function ChatStateInactive(data, xml) { return stanza.init(this, xml, data); } ChatStateInactive.prototype = { constructor: { value: ChatStateInactive }, NS: 'http://jabber.org/protocol/chatstates', EL: 'inactive', _name: 'chatStateInactive', _eventname: 'chat:inactive', toString: stanza.toString, toJSON: undefined }; function ChatStateGone(data, xml) { return stanza.init(this, xml, data); } ChatStateGone.prototype = { constructor: { value: ChatStateGone }, NS: 'http://jabber.org/protocol/chatstates', EL: 'gone', _name: 'chatStateGone', _eventname: 'chat:gone', toString: stanza.toString, toJSON: undefined }; stanza.extend(Message, ChatStateActive); stanza.extend(Message, ChatStateComposing); stanza.extend(Message, ChatStatePaused); stanza.extend(Message, ChatStateInactive); stanza.extend(Message, ChatStateGone); Message.prototype.__defineGetter__('chatState', function () { var self = this; var states = ['Active', 'Composing', 'Paused', 'Inactive', 'Gone']; for (var i = 0; i < states.length; i++) { if (self._extensions['chatState' + states[i]]) { return states[i].toLowerCase(); } } return ''; }); Message.prototype.__defineSetter__('chatState', function (value) { var self = this; var states = ['Active', 'Composing', 'Paused', 'Inactive', 'Gone']; states.forEach(function (state) { if (self._extensions['chatState' + state]) { self.xml.removeChild(self._extensions['chatState' + state].xml); delete self._extensions['chatState' + state]; } }); if (value) { this['chatState' + value.charAt(0).toUpperCase() + value.slice(1)]; } }); },{"./message":36,"jxt":75}],28:[function(require,module,exports){ var _ = require('../../vendor/lodash'); var stanza = require('jxt'); var Message = require('./message'); function DataForm(data, xml) { return stanza.init(this, xml, data); } DataForm.prototype = { constructor: { value: DataForm }, NS: 'jabber:x:data', EL: 'x', _name: 'form', toString: stanza.toString, toJSON: stanza.toJSON, get title() { return stanza.getSubText(this.xml, this.NS, 'title'); }, set title(value) { stanza.setSubText(this.xml, this.NS, 'title', value); }, get instructions() { return stanza.getMultiSubText(this.xml, this.NS, 'title').join('\n'); }, set instructions(value) { stanza.setMultiSubText(this.xml, this.NS, 'title', value.split('\n')); }, get type() { return stanza.getAttribute(this.xml, 'type', 'form'); }, set type(value) { stanza.setAttribute(this.xml, 'type', value); }, get fields() { var fields = stanza.find(this.xml, this.NS, 'field'); var results = []; _.forEach(fields, function (field) { results.push(new Field({}, field).toJSON()); }); return results; }, set fields(value) { var self = this; _.forEach(value, function (field) { self.addField(field); }); }, addField: function (opts) { var field = new Field(opts); this.xml.appendChild(field.xml); }, }; function Field(data, xml) { stanza.init(this, xml, data); this._type = data.type || this.type; return this; } Field.prototype = { constructor: { value: Field }, NS: 'jabber:x:data', EL: 'field', toString: stanza.toString, toJSON: stanza.toJSON, get type() { return stanza.getAttribute(this.xml, 'type', 'text-single'); }, set type(value) { this._type = value; stanza.setAttribute(this.xml, 'type', value); }, get name() { return stanza.getAttribute(this.xml, 'var'); }, set name(value) { stanza.setAttribute(this.xml, 'var', value); }, get desc() { return stanza.getSubText(this.xml, this.NS, 'desc'); }, set desc(value) { stanza.setSubText(this.xml, this.NS, 'desc', value); }, get value() { var vals = stanza.getMultiSubText(this.xml, this.NS, 'value'); if (this._type === 'boolean') { return vals[0] === '1' || vals[0] === 'true'; } if (vals.length > 1) { if (this._type === 'text-multi') { return vals.join('\n'); } return vals; } return vals[0]; }, set value(value) { if (this._type === 'boolean') { stanza.setSubText(this.xml, this.NS, 'value', value ? '1' : '0'); } else { if (this._type === 'text-multi') { value = value.split('\n'); } stanza.setMultiSubText(this.xml, this.NS, 'value', value); } }, get required() { var req = stanza.find(this.xml, this.NS, 'required'); return req.length > 0; }, set required(value) { var reqs = stanza.find(this.xml, this.NS, 'required'); if (value && reqs.length === 0) { var req = document.createElementNS(this.NS, 'required'); this.xml.appendChild(req); } else if (!value && reqs.length > 0) { _.forEach(reqs, function (req) { this.xml.removeChild(req); }); } }, get label() { return stanza.getAttribute(this.xml, 'label'); }, set label(value) { stanza.setAttribute(this.xml, 'label', value); }, get options() { var self = this; return stanza.getMultiSubText(this.xml, this.NS, 'option', function (sub) { return stanza.getSubText(sub, self.NS, 'value'); }); }, set options(value) { var self = this; stanza.setMultiSubText(this.xml, this.NS, 'option', value, function (val) { var opt = document.createElementNS(self.NS, 'option'); var value = document.createElementNS(self.NS, 'value'); opt.appendChild(value); value.textContent = val; self.xml.appendChild(opt); }); } }; stanza.extend(Message, DataForm); exports.DataForm = DataForm; exports.Field = Field; },{"../../vendor/lodash":92,"./message":36,"jxt":75}],29:[function(require,module,exports){ var stanza = require('jxt'); var Message = require('./message'); var Presence = require('./presence'); var JID = require('../jid'); function DelayedDelivery(data, xml) { return stanza.init(this, xml, data); } DelayedDelivery.prototype = { constructor: { value: DelayedDelivery }, NS: 'urn:xmpp:delay', EL: 'delay', _name: 'delay', toString: stanza.toString, toJSON: stanza.toJSON, get from() { return new JID(stanza.getAttribute(this.xml, 'from')); }, set from(value) { stanza.setAttribute(this.xml, 'from', value.toString()); }, get stamp() { return new Date(stanza.getAttribute(this.xml, 'stamp') || Date.now()); }, set stamp(value) { stanza.setAttribute(this.xml, 'stamp', value.toISOString()); }, get reason() { return this.xml.textContent || ''; }, set reason(value) { this.xml.textContent = value; } }; stanza.extend(Message, DelayedDelivery); stanza.extend(Presence, DelayedDelivery); module.exports = DelayedDelivery; },{"../jid":3,"./message":36,"./presence":38,"jxt":75}],30:[function(require,module,exports){ var _ = require('../../vendor/lodash'); var stanza = require('jxt'); var Iq = require('./iq'); var RSM = require('./rsm'); var DataForm = require('./dataforms').DataForm; var JID = require('../jid'); function DiscoInfo(data, xml) { return stanza.init(this, xml, data); } DiscoInfo.prototype = { constructor: { value: DiscoInfo }, _name: 'discoInfo', NS: 'http://jabber.org/protocol/disco#info', EL: 'query', toString: stanza.toString, toJSON: stanza.toJSON, get node() { return stanza.getAttribute(this.xml, 'node'); }, set node(value) { stanza.setAttribute(this.xml, 'node', value); }, get identities() { var result = []; var identities = stanza.find(this.xml, this.NS, 'identity'); identities.forEach(function (identity) { result.push({ category: stanza.getAttribute(identity, 'category'), type: stanza.getAttribute(identity, 'type'), lang: identity.getAttributeNS(stanza.XML_NS, 'lang'), name: stanza.getAttribute(identity, 'name') }); }); return result; }, set identities(values) { var self = this; var existing = stanza.find(this.xml, this.NS, 'identity'); existing.forEach(function (item) { self.xml.removeChild(item); }); values.forEach(function (value) { var identity = document.createElementNS(self.NS, 'identity'); stanza.setAttribute(identity, 'category', value.category); stanza.setAttribute(identity, 'type', value.type); stanza.setAttribute(identity, 'name', value.name); if (value.lang) { identity.setAttributeNS(stanza.XML_NS, 'lang', value.lang); } self.xml.appendChild(identity); }); }, get features() { var result = []; var features = stanza.find(this.xml, this.NS, 'feature'); features.forEach(function (feature) { result.push(feature.getAttribute('var')); }); return result; }, set features(values) { var self = this; var existing = stanza.find(this.xml, this.NS, 'feature'); existing.forEach(function (item) { self.xml.removeChild(item); }); values.forEach(function (value) { var feature = document.createElementNS(self.NS, 'feature'); feature.setAttribute('var', value); self.xml.appendChild(feature); }); }, get extensions() { var self = this; var result = []; var forms = stanza.find(this.xml, DataForm.NS, DataForm.EL); forms.forEach(function (form) { var ext = new DataForm({}, form); result.push(ext.toJSON()); }); }, set extensions(value) { var self = this; var forms = stanza.find(this.xml, DataForm.NS, DataForm.EL); forms.forEach(function (form) { self.xml.removeChild(form); }); value.forEach(function (ext) { var form = new DataForm(ext); self.xml.appendChild(form.xml); }); } }; function DiscoItems(data, xml) { return stanza.init(this, xml, data); } DiscoItems.prototype = { constructor: { value: DiscoInfo }, _name: 'discoItems', NS: 'http://jabber.org/protocol/disco#items', EL: 'query', toString: stanza.toString, toJSON: stanza.toJSON, get node() { return stanza.getAttribute(this.xml, 'node'); }, set node(value) { stanza.setAttribute(this.xml, 'node', value); }, get items() { var result = []; var items = stanza.find(this.xml, this.NS, 'item'); items.forEach(function (item) { result.push({ jid: new JID(stanza.getAttribute(item, 'jid')), node: stanza.getAttribute(item, 'node'), name: stanza.getAttribute(item, 'name') }); }); return result; }, set items(values) { var self = this; var existing = stanza.find(this.xml, this.NS, 'item'); existing.forEach(function (item) { self.xml.removeChild(item); }); values.forEach(function (value) { var item = document.createElementNS(self.NS, 'item'); stanza.setAttribute(item, 'jid', value.jid.toString()); stanza.setAttribute(item, 'node', value.node); stanza.setAttribute(item, 'name', value.name); self.xml.appendChild(item); }); } }; stanza.extend(Iq, DiscoInfo); stanza.extend(Iq, DiscoItems); stanza.extend(DiscoItems, RSM); exports.DiscoInfo = DiscoInfo; exports.DiscoItems = DiscoItems; },{"../../vendor/lodash":92,"../jid":3,"./dataforms":28,"./iq":34,"./rsm":43,"jxt":75}],31:[function(require,module,exports){ var _ = require('../../vendor/lodash'); var stanza = require('jxt'); var Message = require('./message'); var Presence = require('./presence'); var Iq = require('./iq'); var JID = require('../jid'); function Error(data, xml) { return stanza.init(this, xml, data); } Error.prototype = { constructor: { value: Error }, _name: 'error', NS: 'jabber:client', EL: 'error', _ERR_NS: 'urn:ietf:params:xml:ns:xmpp-stanzas', _CONDITIONS: [ 'bad-request', 'conflict', 'feature-not-implemented', 'forbidden', 'gone', 'internal-server-error', 'item-not-found', 'jid-malformed', 'not-acceptable', 'not-allowed', 'not-authorized', 'payment-required', 'recipient-unavailable', 'redirect', 'registration-required', 'remote-server-not-found', 'remote-server-timeout', 'resource-constraint', 'service-unavailable', 'subscription-required', 'undefined-condition', 'unexpected-request' ], toString: stanza.toString, toJSON: stanza.toJSON, get lang() { if (this.parent) { return this.parent.lang; } return ''; }, get condition() { var self = this; var result = []; this._CONDITIONS.forEach(function (condition) { var exists = stanza.find(self.xml, self._ERR_NS, condition); if (exists.length) { result.push(exists[0].tagName); } }); return result[0] || ''; }, set condition(value) { var self = this; this._CONDITIONS.forEach(function (condition) { var exists = stanza.find(self.xml, self._ERR_NS, condition); if (exists.length) { self.xml.removeChild(exists[0]); } }); if (value) { var condition = document.createElementNS(this._ERR_NS, value); condition.setAttribute('xmlns', this._ERR_NS); this.xml.appendChild(condition); } }, get gone() { return stanza.getSubText(this.xml, this._ERR_NS, 'gone'); }, set gone(value) { this.condition = 'gone'; stanza.setSubText(this.xml, this._ERR_NS, 'gone', value); }, get redirect() { return stanza.getSubText(this.xml, this._ERR_NS, 'redirect'); }, set redirect(value) { this.condition = 'redirect'; stanza.setSubText(this.xml, this._ERR_NS, 'redirect', value); }, get code() { return stanza.getAttribute(this.xml, 'code'); }, set code(value) { stanza.setAttribute(this.xml, 'code', value); }, get type() { return stanza.getAttribute(this.xml, 'type'); }, set type(value) { stanza.setAttribute(this.xml, 'type', value); }, get by() { return new JID(stanza.getAttribute(this.xml, 'by')); }, set by(value) { stanza.setAttribute(this.xml, 'by', value.toString()); }, get $text() { return stanza.getSubLangText(this.xml, this._ERR_NS, 'text', this.lang); }, set text(value) { stanza.setSubLangText(this.xml, this._ERR_NS, 'text', value, this.lang); }, get text() { var text = this.$text; return text[this.lang] || ''; }, }; stanza.extend(Message, Error); stanza.extend(Presence, Error); stanza.extend(Iq, Error); module.exports = Error; },{"../../vendor/lodash":92,"../jid":3,"./iq":34,"./message":36,"./presence":38,"jxt":75}],32:[function(require,module,exports){ var stanza = require('jxt'); var Message = require('./message'); var Presence = require('./presence'); var Iq = require('./iq'); var DelayedDelivery = require('./delayed'); function Forwarded(data, xml) { return stanza.init(this, xml, data); } Forwarded.prototype = { constructor: { value: Forwarded }, NS: 'urn:xmpp:forward:0', EL: 'forwarded', _name: 'forwarded', _eventname: 'forward', toString: stanza.toString, toJSON: stanza.toJSON }; stanza.extend(Message, Forwarded); stanza.extend(Forwarded, Message); stanza.extend(Forwarded, Presence); stanza.extend(Forwarded, Iq); stanza.extend(Forwarded, DelayedDelivery); module.exports = Forwarded; },{"./delayed":29,"./iq":34,"./message":36,"./presence":38,"jxt":75}],33:[function(require,module,exports){ var stanza = require('jxt'); var Presence = require('./presence'); function Idle(data, xml) { return stanza.init(this, xml, data); } Idle.prototype = { constructor: { value: Idle }, NS: 'urn:xmpp:idle:0', EL: 'idle', _name: 'idle', toString: stanza.toString, toJSON: stanza.toJSON, get since() { return new Date(stanza.getAttribute(this.xml, 'since') || Date.now()); }, set since(value) { stanza.setAttribute(this.xml, 'since', value.toISOString()); } }; stanza.extend(Presence, Idle); module.exports = Idle; },{"./presence":38,"jxt":75}],34:[function(require,module,exports){ var stanza = require('jxt'); var JID = require('../jid'); function Iq(data, xml) { return stanza.init(this, xml, data); } Iq.prototype = { constructor: { value: Iq }, _name: 'iq', NS: 'jabber:client', EL: 'iq', toString: stanza.toString, toJSON: stanza.toJSON, resultReply: function (data) { data.to = this.from; data.id = this.id; data.type = 'result'; return new Iq(data); }, errorReply: function (data) { data.to = this.from; data.id = this.id; data.type = 'error'; return new Iq(data); }, get lang() { return this.xml.getAttributeNS(stanza.XML_NS, 'lang') || ''; }, set lang(value) { this.xml.setAttributeNS(stanza.XML_NS, 'lang', value); }, get id() { return stanza.getAttribute(this.xml, 'id'); }, set id(value) { stanza.setAttribute(this.xml, 'id', value); }, get to() { return new JID(stanza.getAttribute(this.xml, 'to')); }, set to(value) { stanza.setAttribute(this.xml, 'to', value.toString()); }, get from() { return new JID(stanza.getAttribute(this.xml, 'from')); }, set from(value) { stanza.setAttribute(this.xml, 'from', value.toString()); }, get type() { return stanza.getAttribute(this.xml, 'type'); }, set type(value) { stanza.setAttribute(this.xml, 'type', value); } }; stanza.topLevel(Iq); module.exports = Iq; },{"../jid":3,"jxt":75}],35:[function(require,module,exports){ var stanza = require('jxt'); var Message = require('./message'); var Iq = require('./iq'); var Forwarded = require('./forwarded'); var RSM = require('./rsm'); var JID = require('../jid'); function MAMQuery(data, xml) { return stanza.init(this, xml, data); } MAMQuery.prototype = { constructor: { value: MAMQuery }, NS: 'urn:xmpp:mam:tmp', EL: 'query', _name: 'mamQuery', toString: stanza.toString, toJSON: stanza.toJSON, get queryid() { return stanza.getAttribute(this.xml, 'queryid'); }, set queryid(value) { stanza.setAttribute(this.xml, 'queryid', value); }, get start() { return new Date(stanza.getSubText(this.xml, this.NS, 'start') || Date.now()); }, set start(value) { stanza.setSubText(this.xml, this.NS, 'start', value.toISOString()); }, get end() { return new Date(stanza.getSubText(this.xml, this.NS, 'end') || Date.now()); }, set end(value) { stanza.setSubText(this.xml, this.NS, 'end', value.toISOString()); } }; MAMQuery.prototype.__defineGetter__('with', function () { return stanza.getSubText(this.xml, this.NS, 'with'); }); MAMQuery.prototype.__defineSetter__('with', function (value) { stanza.setSubText(this.xml, this.NS, 'with', value); }); function Result(data, xml) { return stanza.init(this, xml, data); } Result.prototype = { constructor: { value: Result }, NS: 'urn:xmpp:mam:tmp', EL: 'result', _name: 'mam', _eventname: 'mam:result', toString: stanza.toString, toJSON: stanza.toJSON, get queryid() { return stanza.getAttribute(this.xml, 'queryid'); }, set queryid(value) { stanza.setAttribute(this.xml, 'queryid', value); }, get id() { return stanza.getAttribute(this.xml, 'id'); }, set id(value) { stanza.setAttribute(this.xml, 'id', value); } }; function Prefs(data, xml) { return stanza.init(this, xml, data); } Prefs.prototype = { constructor: { value: Prefs }, NS: 'urn:xmpp:mam:tmp', EL: 'prefs', _name: 'mamPrefs', toString: stanza.toString, toJSON: stanza.toJSON, get defaultCondition() { return stanza.getAttribute(this.xml, 'default'); }, set defaultCondition(value) { stanza.setAttribute(this.xml, 'default', value); }, get always() { var results = []; var container = stanza.find(this.xml, this.NS, 'always'); if (container.length === 0) { return results; } container = container[0]; var jids = stanza.getMultiSubText(container, this.NS, 'jid'); jids.forEach(function (jid) { results.push(new JID(jid.textContent)); }); return results; }, set always(value) { if (value.length > 0) { var container = stanza.find(this.xml, this.NS, 'always'); stanza.setMultiSubText(container, this.NS, 'jid', value); } }, get never() { var results = []; var container = stanza.find(this.xml, this.NS, 'always'); if (container.length === 0) { return results; } container = container[0]; var jids = stanza.getMultiSubText(container, this.NS, 'jid'); jids.forEach(function (jid) { results.push(new JID(jid.textContent)); }); return results; }, set never(value) { if (value.length > 0) { var container = stanza.find(this.xml, this.NS, 'never'); stanza.setMultiSubText(container, this.NS, 'jid', value); } } }; Message.prototype.__defineGetter__('archived', function () { var archives = stanza.find(this.xml, this.NS, 'archived'); var results = []; archives.forEach(function (archive) { results.push({ by: new JID(stanza.getAttribute(archive, 'by')), id: stanza.getAttribute(archive, 'id') }); }); return results; }); stanza.extend(Iq, MAMQuery); stanza.extend(Iq, Prefs); stanza.extend(Message, Result); stanza.extend(Result, Forwarded); stanza.extend(MAMQuery, RSM); exports.MAMQuery = MAMQuery; exports.Result = Result; },{"../jid":3,"./forwarded":32,"./iq":34,"./message":36,"./rsm":43,"jxt":75}],36:[function(require,module,exports){ var _ = require('../../vendor/lodash'); var stanza = require('jxt'); var JID = require('../jid'); function Message(data, xml) { return stanza.init(this, xml, data); } Message.prototype = { constructor: { value: Message }, _name: 'message', NS: 'jabber:client', EL: 'message', toString: stanza.toString, toJSON: stanza.toJSON, get lang() { return this.xml.getAttributeNS(stanza.XML_NS, 'lang') || ''; }, set lang(value) { this.xml.setAttributeNS(stanza.XML_NS, 'lang', value); }, get id() { return stanza.getAttribute(this.xml, 'id'); }, set id(value) { stanza.setAttribute(this.xml, 'id', value); }, get to() { return new JID(stanza.getAttribute(this.xml, 'to')); }, set to(value) { stanza.setAttribute(this.xml, 'to', value.toString()); }, get from() { return new JID(stanza.getAttribute(this.xml, 'from')); }, set from(value) { stanza.setAttribute(this.xml, 'from', value.toString()); }, get type() { return stanza.getAttribute(this.xml, 'type', 'normal'); }, set type(value) { stanza.setAttribute(this.xml, 'type', value); }, get body() { var bodies = this.$body; return bodies[this.lang] || ''; }, get $body() { return stanza.getSubLangText(this.xml, this.NS, 'body', this.lang); }, set body(value) { stanza.setSubLangText(this.xml, this.NS, 'body', value, this.lang); }, get thread() { return stanza.getSubText(this.xml, this.NS, 'thread'); }, set thread(value) { stanza.setSubText(this.xml, this.NS, 'thread', value); }, get parentThread() { return stanza.getSubAttribute(this.xml, this.NS, 'thread', 'parent'); }, set parentThread(value) { stanza.setSubAttribute(this.xml, this.NS, 'thread', 'parent', value); } }; stanza.topLevel(Message); module.exports = Message; },{"../../vendor/lodash":92,"../jid":3,"jxt":75}],37:[function(require,module,exports){ var stanza = require('jxt'); var Message = require('./message'); var Presence = require('./presence'); var Iq = require('./iq'); function MUCJoin(data, xml) { return stanza.init(this, xml, data); } MUCJoin.prototype = { constructor: { value: MUCJoin }, NS: 'http://jabber.org/protocol/muc', EL: 'x', _name: 'joinMuc', toString: stanza.toString, toJSON: stanza.toJSON, get password() { return stanza.getSubText(this.xml, this.NS, 'password'); }, set password(value) { stanza.setSubText(this.xml, this.NS, 'password', value); }, get history() { var result = {}; var hist = stanza.find(this.xml, this.NS, 'history'); if (!hist.length) { return {}; } hist = hist[0]; var maxchars = hist.getAttribute('maxchars') || ''; var maxstanzas = hist.getAttribute('maxstanas') || ''; var seconds = hist.getAttribute('seconds') || ''; var since = hist.getAttribute('since') || ''; if (maxchars) { result.maxchars = parseInt(maxchars, 10); } if (maxstanzas) { result.maxstanzas = parseInt(maxstanzas, 10); } if (seconds) { result.seconds = parseInt(seconds, 10); } if (since) { result.since = new Date(since); } }, set history(opts) { var existing = stanza.find(this.xml, this.NS, 'history'); if (existing.length) { for (var i = 0; i < existing.length; i++) { this.xml.removeChild(existing[i]); } } var hist = document.createElementNS(this.NS, 'history'); this.xml.appendChild(hist); if (opts.maxchars) { hist.setAttribute('' + opts.maxchars); } if (opts.maxstanzas) { hist.setAttribute('' + opts.maxstanzas); } if (opts.seconds) { hist.setAttribute('' + opts.seconds); } if (opts.since) { hist.setAttribute(opts.since.toISOString()); } } }; stanza.extend(Presence, MUCJoin); exports.MUCJoin = MUCJoin; },{"./iq":34,"./message":36,"./presence":38,"jxt":75}],38:[function(require,module,exports){ var _ = require('../../vendor/lodash'); var stanza = require('jxt'); var JID = require('../jid'); function Presence(data, xml) { return stanza.init(this, xml, data); } Presence.prototype = { constructor: { value: Presence }, _name: 'presence', NS: 'jabber:client', EL: 'presence', toString: stanza.toString, toJSON: stanza.toJSON, get lang() { return this.xml.getAttributeNS(stanza.XML_NS, 'lang') || ''; }, set lang(value) { this.xml.setAttributeNS(stanza.XML_NS, 'lang', value); }, get id() { return stanza.getAttribute(this.xml, 'id'); }, set id(value) { stanza.setAttribute(this.xml, 'id', value); }, get to() { return new JID(stanza.getAttribute(this.xml, 'to')); }, set to(value) { stanza.setAttribute(this.xml, 'to', value.toString()); }, get from() { return new JID(stanza.getAttribute(this.xml, 'from')); }, set from(value) { stanza.setAttribute(this.xml, 'from', value.toString()); }, get type() { return stanza.getAttribute(this.xml, 'type', 'available'); }, set type(value) { if (value === 'available') { value = false; } stanza.setAttribute(this.xml, 'type', value); }, get status() { var statuses = this.$status; return statuses[this.lang] || ''; }, get $status() { return stanza.getSubLangText(this.xml, this.NS, 'status', this.lang); }, set status(value) { stanza.setSubLangText(this.xml, this.NS, 'status', value, this.lang); }, get priority() { return stanza.getSubText(this.xml, this.NS, 'priority'); }, set priority(value) { stanza.setSubText(this.xml, this.NS, 'priority', value); }, get show() { return stanza.getSubText(this.xml, this.NS, 'show'); }, set show(value) { stanza.setSubText(this.xml, this.NS, 'show', value); } }; stanza.topLevel(Presence); module.exports = Presence; },{"../../vendor/lodash":92,"../jid":3,"jxt":75}],39:[function(require,module,exports){ var _ = require('../../vendor/lodash'); var stanza = require('jxt'); var Iq = require('./iq'); var Message = require('./message'); var Form = require('./dataforms').DataForm; var RSM = require('./rsm'); var JID = require('../jid'); function Pubsub(data, xml) { return stanza.init(this, xml, data); } Pubsub.prototype = { constructor: { value: Pubsub }, _name: 'pubsub', NS: 'http://jabber.org/protocol/pubsub', EL: 'pubsub', toString: stanza.toString, toJSON: stanza.toJSON, get publishOptions() { var conf = stanza.find(this.xml, this.NS, 'publish-options'); if (conf.length && conf[0].childNodes.length) { return new Form({}, conf[0].childNodes[0]); } }, set publishOptions(value) { var conf = stanza.findOrCreate(this.xml, this.NS, 'publish-options'); if (value) { var form = new Form(value); conf.appendChild(form.xml); } } }; function PubsubOwner(data, xml) { return stanza.init(this, xml, data); } PubsubOwner.prototype = { constructor: { value: PubsubOwner }, _name: 'pubsubOwner', NS: 'http://jabber.org/protocol/pubsub#owner', EL: 'pubsub', toString: stanza.toString, toJSON: stanza.toJSON, get create() { return stanza.getSubAttribute(this.xml, this.NS, 'create', 'node'); }, set create(value) { stanza.setSubAttribute(this.xml, this.NS, 'create', 'node', value); }, get purge() { return stanza.getSubAttribute(this.xml, this.NS, 'purge', 'node'); }, set purge(value) { stanza.setSubAttribute(this.xml, this.NS, 'purge', 'node', value); }, get del() { return stanza.getSubAttribute(this.xml, this.NS, 'delete', 'node'); }, set del(value) { stanza.setSubAttribute(this.xml, this.NS, 'delete', 'node', value); }, get redirect() { var del = stanza.find(this.xml, this.NS, 'delete'); if (del.length) { return stanza.getSubAttribute(del, this.NS, 'redirect', 'uri'); } return ''; }, set redirect(value) { var del = stanza.findOrCreate(this.xml, this.NS, 'delete'); stanza.setSubAttribute(del, this.NS, 'redirect', 'uri', value); } }; function Configure(data, xml) { return stanza.init(this, xml, data); } Configure.prototype = { constructor: { value: Configure }, _name: 'config', NS: 'http://jabber.org/protocol/pubsub#owner', EL: 'configure', toString: stanza.toString, toJSON: stanza.toJSON, get node() { return stanza.getAttribute(this.xml, 'node'); }, set node(value) { stanza.setAttribute(this.xml, 'node', value); } }; function Event(data, xml) { return stanza.init(this, xml, data); } Event.prototype = { constructor: { value: Event }, _name: 'event', NS: 'http://jabber.org/protocol/pubsub#event', EL: 'event', toString: stanza.toString, toJSON: stanza.toJSON }; function Subscribe(data, xml) { return stanza.init(this, xml, data); } Subscribe.prototype = { constructor: { value: Subscribe }, _name: 'subscribe', NS: 'http://jabber.org/protocol/pubsub', EL: 'subscribe', toString: stanza.toString, toJSON: stanza.toJSON, get node() { return stanza.getAttribute(this.xml, 'node'); }, set node(value) { stanza.setAttribute(this.xml, 'node', value); }, get jid() { return new JID(stanza.getAttribute(this.xml, 'jid')); }, set jid(value) { stanza.setAttribute(this.xml, 'jid', value.toString()); } }; function Subscription(data, xml) { return stanza.init(this, xml, data); } Subscription.prototype = { constructor: { value: Subscription }, _name: 'subscription', NS: 'http://jabber.org/protocol/pubsub', EL: 'subscription', toString: stanza.toString, toJSON: stanza.toJSON, get node() { return stanza.getAttribute(this.xml, 'node'); }, set node(value) { stanza.setAttribute(this.xml, 'node', value); }, get jid() { return new JID(stanza.getAttribute(this.xml, 'jid')); }, set jid(value) { stanza.setAttribute(this.xml, 'jid', value.toString()); }, get subid() { return stanza.getAttribute(this.xml, 'subid'); }, set subid(value) { stanza.setAttribute(this.xml, 'subid', value); }, get type() { return stanza.getAttribute(this.xml, 'subscription'); }, set type(value) { stanza.setAttribute(this.xml, 'subscription', value); } }; function Unsubscribe(data, xml) { return stanza.init(this, xml, data); } Unsubscribe.prototype = { constructor: { value: Unsubscribe }, _name: 'unsubscribe', NS: 'http://jabber.org/protocol/pubsub', EL: 'unsubscribe', toString: stanza.toString, toJSON: stanza.toJSON, get node() { return stanza.getAttribute(this.xml, 'node'); }, set node(value) { stanza.setAttribute(this.xml, 'node', value); }, get jid() { return new JID(stanza.getAttribute(this.xml, 'jid')); }, set jid(value) { stanza.setAttribute(this.xml, 'jid', value.toString()); } }; function Publish(data, xml) { return stanza.init(this, xml, data); } Publish.prototype = { constructor: { value: Publish }, _name: 'publish', NS: 'http://jabber.org/protocol/pubsub', EL: 'publish', toString: stanza.toString, toJSON: stanza.toJSON, get node() { return stanza.getAttribute(this.xml, 'node'); }, set node(value) { stanza.setAttribute(this.xml, 'node', value); }, get item() { var items = this.items; if (items.length) { return items[0]; } }, set item(value) { this.items = [value]; } }; function Retract(data, xml) { return stanza.init(this, xml, data); } Retract.prototype = { constructor: { value: Retract }, _name: 'retract', NS: 'http://jabber.org/protocol/pubsub', EL: 'retract', toString: stanza.toString, toJSON: stanza.toJSON, get node() { return stanza.getAttribute(this.xml, 'node'); }, set node(value) { stanza.setAttribute(this.xml, 'node', value); }, get notify() { var notify = stanza.getAttribute(this.xml, 'notify'); return notify === 'true' || notify === '1'; }, set notify(value) { if (value) { value = '1'; } stanza.setAttribute(this.xml, 'notify', value); }, get id() { return stanza.getSubAttribute(this.xml, this.NS, 'item', 'id'); }, set id(value) { stanza.setSubAttribute(this.xml, this.NS, 'item', 'id', value); } }; function Retrieve(data, xml) { return stanza.init(this, xml, data); } Retrieve.prototype = { constructor: { value: Retrieve }, _name: 'retrieve', NS: 'http://jabber.org/protocol/pubsub', EL: 'items', toString: stanza.toString, toJSON: stanza.toJSON, get node() { return stanza.getAttribute(this.xml, 'node'); }, set node(value) { stanza.setAttribute(this.xml, 'node', value); }, get max() { return stanza.getAttribute(this.xml, 'max_items'); }, set max(value) { stanza.setAttribute(this.xml, 'max_items', value); } }; function Item(data, xml) { return stanza.init(this, xml, data); } Item.prototype = { constructor: { value: Item }, _name: 'item', NS: 'http://jabber.org/protocol/pubsub', EL: 'item', toString: stanza.toString, toJSON: stanza.toJSON, get id() { return stanza.getAttribute(this.xml, 'id'); }, set id(value) { stanza.setAttribute(this.xml, 'id', value); } }; function EventItems(data, xml) { return stanza.init(this, xml, data); } EventItems.prototype = { constructor: { value: EventItems }, _name: 'updated', NS: 'http://jabber.org/protocol/pubsub#event', EL: 'items', toString: stanza.toString, toJSON: function () { var json = stanza.toJSON.apply(this); var items = []; _.forEach(json.published, function (item) { items.push(item.toJSON()); }); json.published = items; return json; }, get node() { return stanza.getAttribute(this.xml, 'node'); }, set node(value) { stanza.setAttribute(this.xml, 'node', value); }, get published() { var results = []; var items = stanza.find(this.xml, this.NS, 'item'); _.forEach(items, function (xml) { results.push(new EventItem({}, xml)); }); return results; }, set published(value) { var self = this; _.forEach(value, function (data) { var item = new EventItem(data); this.xml.appendChild(item.xml); }); }, get retracted() { var results = []; var retracted = stanza.find(this.xml, this.NS, 'retract'); _.forEach(retracted, function (xml) { results.push(xml.getAttribute('id')); }); return results; }, set retracted(value) { var self = this; _.forEach(value, function (id) { var retracted = document.createElementNS(self.NS, 'retract'); retracted.setAttribute('id', id); this.xml.appendChild(retracted); }); } }; function EventItem(data, xml) { return stanza.init(this, xml, data); } EventItem.prototype = { constructor: { value: EventItem }, _name: 'eventItem', NS: 'http://jabber.org/protocol/pubsub#event', EL: 'item', toString: stanza.toString, toJSON: stanza.toJSON, get id() { return stanza.getAttribute(this.xml, 'id'); }, set id(value) { stanza.setAttribute(this.xml, 'id', value); }, get node() { return stanza.getAttribute(this.xml, 'node'); }, set node(value) { stanza.setAttribute(this.xml, 'node', value); }, get publisher() { return stanza.getAttribute(this.xml, 'publisher'); }, set publisher(value) { stanza.setAttribute(this.xml, 'publisher', value); } }; stanza.extend(Pubsub, Subscribe); stanza.extend(Pubsub, Unsubscribe); stanza.extend(Pubsub, Publish); stanza.extend(Pubsub, Retrieve); stanza.extend(Pubsub, Subscription); stanza.extend(PubsubOwner, Configure); stanza.extend(Publish, Item); stanza.extend(Configure, Form); stanza.extend(Pubsub, RSM); stanza.extend(Event, EventItems); stanza.extend(Message, Event); stanza.extend(Iq, Pubsub); stanza.extend(Iq, PubsubOwner); exports.Pubsub = Pubsub; exports.Item = Item; exports.EventItem = EventItem; },{"../../vendor/lodash":92,"../jid":3,"./dataforms":28,"./iq":34,"./message":36,"./rsm":43,"jxt":75}],40:[function(require,module,exports){ var stanza = require('jxt'); var Message = require('./message'); function Request(data, xml) { return stanza.init(this, xml, data); } Request.prototype = { constructor: { value: Request }, NS: 'urn:xmpp:receipts', EL: 'request', _name: '_requestReceipt', toString: stanza.toString, toJSON: undefined }; function Received(data, xml) { return stanza.init(this, xml, data); } Received.prototype = { constructor: { value: Received }, NS: 'urn:xmpp:receipts', EL: 'received', _name: 'receipt', toString: stanza.toString, toJSON: stanza.toJSON, get id() { return stanza.getAttribute(this.xml, 'id'); }, set id(value) { stanza.setAttribute(this.xml, 'id', value); } }; Message.prototype.__defineGetter__('requestReceipt', function () { return !!this._extensions._requestReceipt; }); Message.prototype.__defineSetter__('requestReceipt', function (value) { if (value) { this._requestReceipt = true; } else if (this._extensions._requestReceipt) { this.xml.removeChild(this._extensions._requestReceipt.xml); delete this._extensions._requestReceipt; } }); stanza.extend(Message, Received); stanza.extend(Message, Request); exports.Request = Request; exports.Received = Received; },{"./message":36,"jxt":75}],41:[function(require,module,exports){ var stanza = require('jxt'); var Message = require('./message'); function Replace(data, xml) { return stanza.init(this, xml, data); } Replace.prototype = { constructor: { value: Replace }, NS: 'urn:xmpp:message-correct:0', EL: 'replace', _name: '_replace', toString: stanza.toString, toJSON: undefined, get id() { return stanza.getAttribute(this.xml, 'id'); }, set id(value) { stanza.setAttribute(this.xml, 'id', value); } }; stanza.extend(Message, Replace); Message.prototype.__defineGetter__('replace', function () { if (this._extensions._replace) { return this._replace.id; } return ''; }); Message.prototype.__defineSetter__('replace', function (value) { if (value) { this._replace.id = value; } else if (this._extensions._replace) { this.xml.removeChild(this._extensions._replace.xml); delete this._extensions._replace; } }); module.exports = Replace; },{"./message":36,"jxt":75}],42:[function(require,module,exports){ var _ = require('../../vendor/lodash'); var stanza = require('jxt'); var Iq = require('./iq'); var JID = require('../jid'); function Roster(data, xml) { return stanza.init(this, xml, data); } Roster.prototype = { constructor: { value: Roster }, _name: 'roster', NS: 'jabber:iq:roster', EL: 'query', toString: stanza.toString, toJSON: stanza.toJSON, get ver() { return stanza.getAttribute(this.xml, 'ver'); }, set ver(value) { var force = (value === ''); stanza.setAttribute(this.xml, 'ver', value, force); }, get items() { var self = this; var items = stanza.find(this.xml, this.NS, 'item'); if (!items.length) { return []; } var results = []; items.forEach(function (item) { var data = { jid: new JID(stanza.getAttribute(item, 'jid', '')), name: stanza.getAttribute(item, 'name', undefined), subscription: stanza.getAttribute(item, 'subscription', 'none'), ask: stanza.getAttribute(item, 'ask', undefined), groups: [] }; var groups = stanza.find(item, self.NS, 'group'); groups.forEach(function (group) { data.groups.push(group.textContent); }); results.push(data); }); return results; }, set items(values) { var self = this; values.forEach(function (value) { var item = document.createElementNS(self.NS, 'item'); stanza.setAttribute(item, 'jid', value.jid.toString()); stanza.setAttribute(item, 'name', value.name); stanza.setAttribute(item, 'subscription', value.subscription); stanza.setAttribute(item, 'ask', value.ask); (value.groups || []).forEach(function (name) { var group = document.createElementNS(self.NS, 'group'); group.textContent = name; item.appendChild(group); }); self.xml.appendChild(item); }); } }; stanza.extend(Iq, Roster); module.exports = Roster; },{"../../vendor/lodash":92,"../jid":3,"./iq":34,"jxt":75}],43:[function(require,module,exports){ var stanza = require('jxt'); function RSM(data, xml) { return stanza.init(this, xml, data); } RSM.prototype = { constructor: { value: RSM }, NS: 'http://jabber.org/protocol/rsm', EL: 'set', _name: 'rsm', toString: stanza.toString, toJSON: stanza.toJSON, get after() { return stanza.getSubText(this.xml, this.NS, 'after'); }, set after(value) { stanza.setSubText(this.xml, this.NS, 'after', value); }, get before() { return stanza.getSubText(this.xml, this.NS, 'before'); }, set before(value) { if (value === true) { stanza.findOrCreate(this.xml, this.NS, 'before'); } else { stanza.setSubText(this.xml, this.NS, 'before', value); } }, get count() { return parseInt(stanza.getSubText(this.xml, this.NS, 'count') || '0', 10); }, set count(value) { stanza.setSubText(this.xml, this.NS, 'count', value.toString()); }, get first() { return stanza.getSubText(this.xml, this.NS, 'first'); }, set first(value) { stanza.setSubText(this.xml, this.NS, 'first', value); }, get firstIndex() { return stanza.getSubAttribute(this.xml, this.NS, 'first', 'index'); }, set firstIndex(value) { stanza.setSubAttribute(this.xml, this.NS, 'first', 'index', value); }, get index() { return stanza.getSubText(this.xml, this.NS, 'index'); }, set index(value) { stanza.setSubText(this.xml, this.NS, 'index', value); }, get last() { return stanza.getSubText(this.xml, this.NS, 'last'); }, set last(value) { stanza.setSubText(this.xml, this.NS, 'last', value); }, get max() { return stanza.getSubText(this.xml, this.NS, 'max'); }, set max(value) { stanza.setSubText(this.xml, this.NS, 'max', value.toString()); } }; module.exports = RSM; },{"jxt":75}],44:[function(require,module,exports){ var stanza = require('jxt'); var _ = require('../../vendor/lodash'); var StreamFeatures = require('./streamFeatures'); function Mechanisms(data, xml) { return stanza.init(this, xml, data); } Mechanisms.prototype = { constructor: { value: Mechanisms }, _name: 'sasl', NS: 'urn:ietf:params:xml:ns:xmpp-sasl', EL: 'mechanisms', toString: stanza.toString, toJSON: stanza.toJSON, required: true, get mechanisms() { var result = []; var mechs = stanza.find(this.xml, this.NS, 'mechanism'); mechs.forEach(function (mech) { result.push(mech.textContent); }); return result; }, set mechanisms(value) { var self = this; var mechs = stanza.find(this.xml, this.NS, 'mechanism'); mechs.forEach(function (mech) { self.xml.remove(mech); }); value.forEach(function (name) { var mech = document.createElementNS(self.NS, 'mechanism'); mech.textContent = name; self.xml.appendChild(mech); }); } }; function Auth(data, xml) { return stanza.init(this, xml, data); } Auth.prototype = { constructor: { value: Auth }, _name: 'saslAuth', _eventname: 'sasl:auth', NS: 'urn:ietf:params:xml:ns:xmpp-sasl', EL: 'auth', toString: stanza.toString, toJSON: stanza.toJSON, get value() { if (this.xml.textContent && this.xml.textContent != '=') { return atob(this.xml.textContent); } return ''; }, set value(value) { this.xml.textContent = btoa(value) || '='; }, get mechanism() { return stanza.getAttribute(this.xml, 'mechanism'); }, set mechanism(value) { stanza.setAttribute(this.xml, 'mechanism', value); } }; function Challenge(data, xml) { return stanza.init(this, xml, data); } Challenge.prototype = { constructor: { value: Challenge }, _name: 'saslChallenge', _eventname: 'sasl:challenge', NS: 'urn:ietf:params:xml:ns:xmpp-sasl', EL: 'challenge', toString: stanza.toString, toJSON: stanza.toJSON, get value() { if (this.xml.textContent && this.xml.textContent != '=') { return atob(this.xml.textContent); } return ''; }, set value(value) { this.xml.textContent = btoa(value) || '='; } }; function Response(data, xml) { return stanza.init(this, xml, data); } Response.prototype = { constructor: { value: Response }, _name: 'saslResponse', _eventname: 'sasl:response', NS: 'urn:ietf:params:xml:ns:xmpp-sasl', EL: 'response', toString: stanza.toString, toJSON: stanza.toJSON, get value() { if (this.xml.textContent && this.xml.textContent != '=') { return atob(this.xml.textContent); } return ''; }, set value(value) { this.xml.textContent = btoa(value) || '='; } }; function Success(data, xml) { return stanza.init(this, xml, data); } Success.prototype = { constructor: { value: Success }, _name: 'saslSuccess', _eventname: 'sasl:success', NS: 'urn:ietf:params:xml:ns:xmpp-sasl', EL: 'success', toString: stanza.toString, toJSON: stanza.toJSON, get value() { if (this.xml.textContent && this.xml.textContent != '=') { return atob(this.xml.textContent); } return ''; }, set value(value) { this.xml.textContent = btoa(value) || '='; } }; function Failure(data, xml) { return stanza.init(this, xml, data); } Failure.prototype = { constructor: { value: Success }, _CONDITIONS: [ 'aborted', 'account-disabled', 'credentials-expired', 'encryption-required', 'incorrect-encoding', 'invalid-authzid', 'invalid-mechanism', 'malformed-request', 'mechanism-too-weak', 'not-authorized', 'temporary-auth-failure', ], _name: 'saslFailure', _eventname: 'sasl:failure', NS: 'urn:ietf:params:xml:ns:xmpp-sasl', EL: 'failure', toString: stanza.toString, toJSON: stanza.toJSON, get lang() { return this._lang || ''; }, set lang(value) { this._lang = value; }, get condition() { var self = this; var result = []; this._CONDITIONS.forEach(function (condition) { var exists = stanza.find(self.xml, this.NS, condition); if (exists.length) { result.push(exists[0].tagName); } }); return result[0] || ''; }, set condition(value) { var self = this; this._CONDITIONS.forEach(function (condition) { var exists = stanza.find(self.xml, self.NS, condition); if (exists.length) { self.xml.removeChild(exists[0]); } }); if (value) { var condition = document.createElementNS(this.NS, value); condition.setAttribute('xmlns', this.NS); this.xml.appendChild(condition); } }, get text() { var text = this.$text; return text[this.lang] || ''; }, get $text() { return stanza.getSubLangText(this.xml, this.NS, 'text', this.lang); }, set text(value) { stanza.setSubLangText(this.xml, this.NS, 'text', value, this.lang); } }; function Abort(data, xml) { return stanza.init(this, xml, data); } Abort.prototype = { constructor: { value: Abort }, _name: 'saslAbort', _eventname: 'sasl:abort', NS: 'urn:ietf:params:xml:ns:xmpp-sasl', EL: 'abort', toString: stanza.toString, toJSON: stanza.toJSON }; stanza.extend(StreamFeatures, Mechanisms, 'sasl'); stanza.topLevel(Auth); stanza.topLevel(Challenge); stanza.topLevel(Response); stanza.topLevel(Success); stanza.topLevel(Failure); stanza.topLevel(Abort); exports.Mechanisms = Mechanisms; exports.Auth = Auth; exports.Challenge = Challenge; exports.Response = Response; exports.Success = Success; exports.Failure = Failure; exports.Abort = Abort; },{"../../vendor/lodash":92,"./streamFeatures":49,"jxt":75}],45:[function(require,module,exports){ var stanza = require('jxt'); var Iq = require('./iq'); var StreamFeatures = require('./streamFeatures'); function Session(data, xml) { return stanza.init(this, xml, data); } Session.prototype = { constructor: { value: Session }, _name: 'session', NS: 'urn:ietf:params:xml:ns:xmpp-session', EL: 'session', toString: stanza.toString, toJSON: stanza.toJSON }; stanza.extend(StreamFeatures, Session); stanza.extend(Iq, Session); module.exports = Session; },{"./iq":34,"./streamFeatures":49,"jxt":75}],46:[function(require,module,exports){ var stanza = require('jxt'); var StreamFeatures = require('./streamFeatures'); function SMFeature(data, xml) { return stanza.init(this, xml, data); } SMFeature.prototype = { constructor: { value: SMFeature }, _name: 'streamManagement', NS: 'urn:xmpp:sm:3', EL: 'sm', toString: stanza.toString, toJSON: stanza.toJSON }; function Enable(data, xml) { return stanza.init(this, xml, data); } Enable.prototype = { constructor: { value: Enable }, _name: 'smEnable', _eventname: 'stream:management:enable', NS: 'urn:xmpp:sm:3', EL: 'enable', toString: stanza.toString, toJSON: stanza.toJSON, get resume() { return stanza.getBoolAttribute(this.xml, 'resume'); }, set resume(val) { stanza.setBoolAttribute(this.xml, 'resume', val); } }; function Enabled(data, xml) { return stanza.init(this, xml, data); } Enabled.prototype = { constructor: { value: Enabled }, _name: 'smEnabled', _eventname: 'stream:management:enabled', NS: 'urn:xmpp:sm:3', EL: 'enabled', toString: stanza.toString, toJSON: stanza.toJSON, get id() { return stanza.getAttribute(this.xml, 'id'); }, set id(value) { stanza.setAttribute(this.xml, 'id', value); }, get resume() { return stanza.getBoolAttribute(this.xml, 'resume'); }, set resume(val) { stanza.setBoolAttribute(this.xml, 'resume', val); } }; function Resume(data, xml) { return stanza.init(this, xml, data); } Resume.prototype = { constructor: { value: Resume }, _name: 'smResume', _eventname: 'stream:management:resume', NS: 'urn:xmpp:sm:3', EL: 'resume', toString: stanza.toString, toJSON: stanza.toJSON, get h() { return parseInt(stanza.getAttribute(this.xml, 'h', '0'), 10); }, set h(value) { stanza.setAttribute(this.xml, 'h', '' + value); }, get previd() { return stanza.getAttribute(this.xml, 'previd'); }, set previd(value) { stanza.setAttribute(this.xml, 'previd', value); } }; function Resumed(data, xml) { return stanza.init(this, xml, data); } Resumed.prototype = { constructor: { value: Resumed }, _name: 'smResumed', _eventname: 'stream:management:resumed', NS: 'urn:xmpp:sm:3', EL: 'resumed', toString: stanza.toString, toJSON: stanza.toJSON, get h() { return parseInt(stanza.getAttribute(this.xml, 'h', '0'), 10); }, set h(value) { stanza.setAttribute(this.xml, 'h', '' + value); }, get previd() { return stanza.getAttribute(this.xml, 'previd'); }, set previd(value) { stanza.setAttribute(this.xml, 'previd', value); } }; function Failed(data, xml) { return stanza.init(this, xml, data); } Failed.prototype = { constructor: { value: Failed }, _name: 'smFailed', _eventname: 'stream:management:failed', NS: 'urn:xmpp:sm:3', EL: 'failed', toString: stanza.toString, toJSON: stanza.toJSON }; function Ack(data, xml) { return stanza.init(this, xml, data); } Ack.prototype = { constructor: { value: Ack }, _name: 'smAck', _eventname: 'stream:management:ack', NS: 'urn:xmpp:sm:3', EL: 'a', toString: stanza.toString, toJSON: stanza.toJSON, get h() { return parseInt(stanza.getAttribute(this.xml, 'h', '0'), 10); }, set h(value) { stanza.setAttribute(this.xml, 'h', '' + value); } }; function Request(data, xml) { return stanza.init(this, xml, data); } Request.prototype = { constructor: { value: Request }, _name: 'smRequest', _eventname: 'stream:management:request', NS: 'urn:xmpp:sm:3', EL: 'r', toString: stanza.toString, toJSON: stanza.toJSON }; stanza.extend(StreamFeatures, SMFeature); stanza.topLevel(Ack); stanza.topLevel(Request); stanza.topLevel(Enable); stanza.topLevel(Enabled); stanza.topLevel(Resume); stanza.topLevel(Resumed); stanza.topLevel(Failed); exports.SMFeature = SMFeature; exports.Enable = Enable; exports.Enabled = Enabled; exports.Resume = Resume; exports.Resumed = Resumed; exports.Failed = Failed; exports.Ack = Ack; exports.Request = Request; },{"./streamFeatures":49,"jxt":75}],47:[function(require,module,exports){ var stanza = require('jxt'); var JID = require('../jid'); function Stream(data, xml) { return stanza.init(this, xml, data); } Stream.prototype = { constructor: { value: Stream }, _name: 'stream', NS: 'http://etherx.jabber.org/streams', EL: 'stream', toString: stanza.toString, toJSON: stanza.toJSON, get lang() { return this.xml.getAttributeNS(stanza.XML_NS, 'lang') || ''; }, set lang(value) { this.xml.setAttributeNS(stanza.XML_NS, 'lang', value); }, get id() { return stanza.getAttribute(this.xml, 'id'); }, set id(value) { stanza.setAttribute(this.xml, 'id', value); }, get version() { return stanza.getAttribute(this.xml, 'version', '1.0'); }, set version(value) { stanza.setAttribute(this.xml, 'version', value); }, get to() { return new JID(stanza.getAttribute(this.xml, 'to')); }, set to(value) { stanza.setAttribute(this.xml, 'to', value.toString()); }, get from() { return new JID(stanza.getAttribute(this.xml, 'from')); }, set from(value) { stanza.setAttribute(this.xml, 'from', value.toString()); } }; module.exports = Stream; },{"../jid":3,"jxt":75}],48:[function(require,module,exports){ var _ = require('../../vendor/lodash'); var stanza = require('jxt'); function StreamError(data, xml) { return stanza.init(this, xml, data); } StreamError.prototype = { constructor: { value: StreamError }, _name: 'streamError', NS: 'http://etherx.jabber.org/streams', EL: 'error', _ERR_NS: 'urn:ietf:params:xml:ns:xmpp-streams', _CONDITIONS: [ 'bad-format', 'bad-namespace-prefix', 'conflict', 'connection-timeout', 'host-gone', 'host-unknown', 'improper-addressing', 'internal-server-error', 'invalid-from', 'invalid-namespace', 'invalid-xml', 'not-authorized', 'not-well-formed', 'policy-violation', 'remote-connection-failed', 'reset', 'resource-constraint', 'restricted-xml', 'see-other-host', 'system-shutdown', 'undefined-condition', 'unsupported-encoding', 'unsupported-feature', 'unsupported-stanza-type', 'unsupported-version' ], toString: stanza.toString, toJSON: stanza.toJSON, get lang() { return this._lang || ''; }, set lang(value) { this._lang = value; }, get condition() { var self = this; var result = []; this._CONDITIONS.forEach(function (condition) { var exists = stanza.find(self.xml, self._ERR_NS, condition); if (exists.length) { result.push(exists[0].tagName); } }); return result[0] || ''; }, set condition(value) { var self = this; this._CONDITIONS.forEach(function (condition) { var exists = stanza.find(self.xml, self._ERR_NS, condition); if (exists.length) { self.xml.removeChild(exists[0]); } }); if (value) { var condition = document.createElementNS(this._ERR_NS, value); condition.setAttribute('xmlns', this._ERR_NS); this.xml.appendChild(condition); } }, get seeOtherHost() { return stanza.getSubText(this.xml, this._ERR_NS, 'see-other-host'); }, set seeOtherHost(value) { this.condition = 'see-other-host'; stanza.setSubText(this.xml, this._ERR_NS, 'see-other-host', value); }, get text() { var text = this.$text; return text[this.lang] || ''; }, get $text() { return stanza.getSubLangText(this.xml, this._ERR_NS, 'text', this.lang); }, set text(value) { stanza.setSubLangText(this.xml, this._ERR_NS, 'text', value, this.lang); } }; stanza.topLevel(StreamError); module.exports = StreamError; },{"../../vendor/lodash":92,"jxt":75}],49:[function(require,module,exports){ var stanza = require('jxt'); function StreamFeatures(data, xml) { return stanza.init(this, xml, data); } StreamFeatures.prototype = { constructor: { value: StreamFeatures }, _name: 'streamFeatures', NS: 'http://etherx.jabber.org/streams', EL: 'features', _FEATURES: [], toString: stanza.toString, toJSON: stanza.toJSON, get features() { return this._extensions; } }; stanza.topLevel(StreamFeatures); module.exports = StreamFeatures; },{"jxt":75}],50:[function(require,module,exports){ var stanza = require('jxt'); var Iq = require('./iq'); function EntityTime(data, xml) { return stanza.init(this, xml, data); } EntityTime.prototype = { constructor: { value: EntityTime }, NS: 'urn:xmpp:time', EL: 'time', _name: 'time', toString: stanza.toString, toJSON: stanza.toJSON, get tzo() { var split, hrs, min; var sign = -1; var formatted = stanza.getSubText(this.xml, this.NS, 'tzo'); if (!formatted) { return 0; } if (formatted.charAt(0) === '-') { sign = 1; formatted.slice(1); } split = formatted.split(':'); hrs = parseInt(split[0], 10); min = parseInt(split[1], 10); return (hrs * 60 + min) * sign; }, set tzo(value) { var hrs, min; var formatted = '-'; if (typeof value === 'number') { if (value < 0) { value = -value; formatted = '+'; } hrs = value / 60; min = value % 60; formatted += (hrs < 10 ? '0' : '') + hrs + ':' + (min < 10 ? '0' : '') + min; } else { formatted = value; } stanza.setSubText(this.xml, this.NS, 'tzo', formatted); }, get utc() { var stamp = stanza.getSubText(this.xml, this.NS, 'utc'); if (stamp) { return new Date(stamp || Date.now()); } return ''; }, set utc(value) { stanza.setSubText(this.xml, this.NS, 'utc', value.toISOString()); } }; stanza.extend(Iq, EntityTime); module.exports = EntityTime; },{"./iq":34,"jxt":75}],51:[function(require,module,exports){ var stanza = require('jxt'); var Iq = require('./iq'); function Version(data, xml) { return stanza.init(this, xml, data); } Version.prototype = { constructor: { value: Version }, NS: 'jabber:iq:version', EL: 'query', _name: 'version', toString: stanza.toString, toJSON: stanza.toJSON, get name() { return stanza.getSubText(this.xml, this.NS, 'name'); }, set name(value) { stanza.setSubText(this.xml, this.NS, 'name', value); }, get version() { return stanza.getSubText(this.xml, this.NS, 'version'); }, set version(value) { stanza.setSubText(this.xml, this.NS, 'version', value); }, get os() { return stanza.getSubText(this.xml, this.NS, 'os'); }, set os(value) { stanza.setSubText(this.xml, this.NS, 'os', value); } }; stanza.extend(Iq, Version); module.exports = Version; },{"./iq":34,"jxt":75}],52:[function(require,module,exports){ var stanza = require('jxt'); var Iq = require('./iq'); function Visible(data, xml) { return stanza.init(this, xml, data); } Visible.prototype = { constructor: { value: Visible }, NS: 'urn:xmpp:invisible:0', EL: 'visible', _name: '_visible', toString: stanza.toString, toJSON: undefined }; function Invisible(data, xml) { return stanza.init(this, xml, data); } Invisible.prototype = { constructor: { value: Invisible }, NS: 'urn:xmpp:invisible:0', EL: 'invisible', _name: '_invisible', toString: stanza.toString, toJSON: undefined }; Iq.prototype.__defineGetter__('visible', function () { return !!this._extensions._visible; }); Iq.prototype.__defineSetter__('visible', function (value) { if (value) { this._visible = true; } else if (this._extensions._visible) { this.xml.removeChild(this._extensions._visible.xml); delete this._extensions._visible; } }); Iq.prototype.__defineGetter__('invisible', function () { return !!this._extensions._invisible; }); Iq.prototype.__defineSetter__('invisible', function (value) { if (value) { this._invisible = true; } else if (this._extensions._invisible) { this.xml.removeChild(this._extensions._invisible.xml); delete this._extensions._invisible; } }); stanza.extend(Iq, Visible); stanza.extend(Iq, Invisible); exports.Visible = Visible; exports.Invisible = Invisible; },{"./iq":34,"jxt":75}],53:[function(require,module,exports){ var WildEmitter = require('wildemitter'); var _ = require('../vendor/lodash'); var async = require('async'); var Stream = require('./stanza/stream'); var Message = require('./stanza/message'); var Presence = require('./stanza/presence'); var Iq = require('./stanza/iq'); var StreamManagement = require('./sm'); var uuid = require('node-uuid'); function WSConnection() { var self = this; WildEmitter.call(this); self.sm = new StreamManagement(self); self.sendQueue = async.queue(function (data, cb) { if (self.conn) { self.emit('raw:outgoing', data); self.sm.track(data); if (typeof data !== 'string') { data = data.toString(); } self.conn.send(data); } cb(); }, 1); function wrap(data) { var result = [self.streamStart, data, self.streamEnd].join(''); return result; } function parse(data) { var nodes = (self.parser.parseFromString(data, 'application/xml')).childNodes; for (var i = 0; i < nodes.length; i++) { if (nodes[i].nodeType === 1) { return nodes[i]; } } } self.on('connected', function () { self.send([ '' ].join(' ')); }); self.on('raw:incoming', function (data) { var streamData, ended; data = data.trim(); data = data.replace(/^(\s*<\?.*\?>\s*)*/, ''); if (data === '') { return; } if (data.match(self.streamEnd)) { return self.disconnect(); } else if (self.hasStream) { try { streamData = new Stream({}, parse(wrap(data))); } catch (e) { return self.disconnect(); } } else { // Inspect start of stream element to get NS prefix name var parts = data.match(/^<(\S+:)?(\S+) /); self.streamStart = data; self.streamEnd = ''; ended = false; try { streamData = new Stream({}, parse(data + self.streamEnd)); } catch (e) { try { streamData = new Stream({}, parse(data)); ended = true; } catch (e2) { return self.disconnect(); } } self.hasStream = true; self.stream = streamData; self.emit('stream:start', streamData); } _.each(streamData._extensions, function (stanzaObj) { if (!stanzaObj.lang) { stanzaObj.lang = self.stream.lang; } if (stanzaObj._name === 'message' || stanzaObj._name === 'presence' || stanzaObj._name === 'iq') { self.sm.handle(stanzaObj); self.emit('stanza', stanzaObj); } self.emit(stanzaObj._eventname || stanzaObj._name, stanzaObj); self.emit('stream:data', stanzaObj); if (stanzaObj.id) { self.emit('id:' + stanzaObj.id, stanzaObj); } }); if (ended) { self.emit('stream:end'); } }); } WSConnection.prototype = Object.create(WildEmitter.prototype, { constructor: { value: WSConnection } }); WSConnection.prototype.connect = function (opts) { var self = this; self.config = opts; self.hasStream = false; self.streamStart = ''; self.streamEnd = ''; self.parser = new DOMParser(); self.serializer = new XMLSerializer(); self.conn = new WebSocket(opts.wsURL, 'xmpp'); self.conn.onopen = function () { self.emit('connected', self); }; self.conn.onclose = function () { self.emit('disconnected', self); }; self.conn.onmessage = function (wsMsg) { self.emit('raw:incoming', wsMsg.data); }; }; WSConnection.prototype.disconnect = function () { if (this.conn) { if (this.hasStream) { this.conn.send(''); this.emit('raw:outgoing', ''); this.emit('stream:end'); } this.hasStream = false; this.conn.close(); this.stream = undefined; this.conn = undefined; } }; WSConnection.prototype.restart = function () { var self = this; self.hasStream = false; self.send([ '' ].join(' ')); }; WSConnection.prototype.send = function (data) { this.sendQueue.push(data); }; module.exports = WSConnection; },{"../vendor/lodash":92,"./sm":21,"./stanza/iq":34,"./stanza/message":36,"./stanza/presence":38,"./stanza/stream":47,"async":54,"node-uuid":77,"wildemitter":91}],54:[function(require,module,exports){ var process=require("__browserify_process");/*global setImmediate: false, setTimeout: false, console: false */ (function () { var async = {}; // global on the server, window in the browser var root, previous_async; root = this; if (root != null) { previous_async = root.async; } async.noConflict = function () { root.async = previous_async; return async; }; function only_once(fn) { var called = false; return function() { if (called) throw new Error("Callback was already called."); called = true; fn.apply(root, arguments); } } //// cross-browser compatiblity functions //// var _each = function (arr, iterator) { if (arr.forEach) { return arr.forEach(iterator); } for (var i = 0; i < arr.length; i += 1) { iterator(arr[i], i, arr); } }; var _map = function (arr, iterator) { if (arr.map) { return arr.map(iterator); } var results = []; _each(arr, function (x, i, a) { results.push(iterator(x, i, a)); }); return results; }; var _reduce = function (arr, iterator, memo) { if (arr.reduce) { return arr.reduce(iterator, memo); } _each(arr, function (x, i, a) { memo = iterator(memo, x, i, a); }); return memo; }; var _keys = function (obj) { if (Object.keys) { return Object.keys(obj); } var keys = []; for (var k in obj) { if (obj.hasOwnProperty(k)) { keys.push(k); } } return keys; }; //// exported async module functions //// //// nextTick implementation with browser-compatible fallback //// if (typeof process === 'undefined' || !(process.nextTick)) { if (typeof setImmediate === 'function') { async.nextTick = function (fn) { // not a direct alias for IE10 compatibility setImmediate(fn); }; async.setImmediate = async.nextTick; } else { async.nextTick = function (fn) { setTimeout(fn, 0); }; async.setImmediate = async.nextTick; } } else { async.nextTick = process.nextTick; if (typeof setImmediate !== 'undefined') { async.setImmediate = setImmediate; } else { async.setImmediate = async.nextTick; } } async.each = function (arr, iterator, callback) { callback = callback || function () {}; if (!arr.length) { return callback(); } var completed = 0; _each(arr, function (x) { iterator(x, only_once(function (err) { if (err) { callback(err); callback = function () {}; } else { completed += 1; if (completed >= arr.length) { callback(null); } } })); }); }; async.forEach = async.each; async.eachSeries = function (arr, iterator, callback) { callback = callback || function () {}; if (!arr.length) { return callback(); } var completed = 0; var iterate = function () { iterator(arr[completed], function (err) { if (err) { callback(err); callback = function () {}; } else { completed += 1; if (completed >= arr.length) { callback(null); } else { iterate(); } } }); }; iterate(); }; async.forEachSeries = async.eachSeries; async.eachLimit = function (arr, limit, iterator, callback) { var fn = _eachLimit(limit); fn.apply(null, [arr, iterator, callback]); }; async.forEachLimit = async.eachLimit; var _eachLimit = function (limit) { return function (arr, iterator, callback) { callback = callback || function () {}; if (!arr.length || limit <= 0) { return callback(); } var completed = 0; var started = 0; var running = 0; (function replenish () { if (completed >= arr.length) { return callback(); } while (running < limit && started < arr.length) { started += 1; running += 1; iterator(arr[started - 1], function (err) { if (err) { callback(err); callback = function () {}; } else { completed += 1; running -= 1; if (completed >= arr.length) { callback(); } else { replenish(); } } }); } })(); }; }; var doParallel = function (fn) { return function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [async.each].concat(args)); }; }; var doParallelLimit = function(limit, fn) { return function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [_eachLimit(limit)].concat(args)); }; }; var doSeries = function (fn) { return function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [async.eachSeries].concat(args)); }; }; var _asyncMap = function (eachfn, arr, iterator, callback) { var results = []; arr = _map(arr, function (x, i) { return {index: i, value: x}; }); eachfn(arr, function (x, callback) { iterator(x.value, function (err, v) { results[x.index] = v; callback(err); }); }, function (err) { callback(err, results); }); }; async.map = doParallel(_asyncMap); async.mapSeries = doSeries(_asyncMap); async.mapLimit = function (arr, limit, iterator, callback) { return _mapLimit(limit)(arr, iterator, callback); }; var _mapLimit = function(limit) { return doParallelLimit(limit, _asyncMap); }; // reduce only has a series version, as doing reduce in parallel won't // work in many situations. async.reduce = function (arr, memo, iterator, callback) { async.eachSeries(arr, function (x, callback) { iterator(memo, x, function (err, v) { memo = v; callback(err); }); }, function (err) { callback(err, memo); }); }; // inject alias async.inject = async.reduce; // foldl alias async.foldl = async.reduce; async.reduceRight = function (arr, memo, iterator, callback) { var reversed = _map(arr, function (x) { return x; }).reverse(); async.reduce(reversed, memo, iterator, callback); }; // foldr alias async.foldr = async.reduceRight; var _filter = function (eachfn, arr, iterator, callback) { var results = []; arr = _map(arr, function (x, i) { return {index: i, value: x}; }); eachfn(arr, function (x, callback) { iterator(x.value, function (v) { if (v) { results.push(x); } callback(); }); }, function (err) { callback(_map(results.sort(function (a, b) { return a.index - b.index; }), function (x) { return x.value; })); }); }; async.filter = doParallel(_filter); async.filterSeries = doSeries(_filter); // select alias async.select = async.filter; async.selectSeries = async.filterSeries; var _reject = function (eachfn, arr, iterator, callback) { var results = []; arr = _map(arr, function (x, i) { return {index: i, value: x}; }); eachfn(arr, function (x, callback) { iterator(x.value, function (v) { if (!v) { results.push(x); } callback(); }); }, function (err) { callback(_map(results.sort(function (a, b) { return a.index - b.index; }), function (x) { return x.value; })); }); }; async.reject = doParallel(_reject); async.rejectSeries = doSeries(_reject); var _detect = function (eachfn, arr, iterator, main_callback) { eachfn(arr, function (x, callback) { iterator(x, function (result) { if (result) { main_callback(x); main_callback = function () {}; } else { callback(); } }); }, function (err) { main_callback(); }); }; async.detect = doParallel(_detect); async.detectSeries = doSeries(_detect); async.some = function (arr, iterator, main_callback) { async.each(arr, function (x, callback) { iterator(x, function (v) { if (v) { main_callback(true); main_callback = function () {}; } callback(); }); }, function (err) { main_callback(false); }); }; // any alias async.any = async.some; async.every = function (arr, iterator, main_callback) { async.each(arr, function (x, callback) { iterator(x, function (v) { if (!v) { main_callback(false); main_callback = function () {}; } callback(); }); }, function (err) { main_callback(true); }); }; // all alias async.all = async.every; async.sortBy = function (arr, iterator, callback) { async.map(arr, function (x, callback) { iterator(x, function (err, criteria) { if (err) { callback(err); } else { callback(null, {value: x, criteria: criteria}); } }); }, function (err, results) { if (err) { return callback(err); } else { var fn = function (left, right) { var a = left.criteria, b = right.criteria; return a < b ? -1 : a > b ? 1 : 0; }; callback(null, _map(results.sort(fn), function (x) { return x.value; })); } }); }; async.auto = function (tasks, callback) { callback = callback || function () {}; var keys = _keys(tasks); if (!keys.length) { return callback(null); } var results = {}; var listeners = []; var addListener = function (fn) { listeners.unshift(fn); }; var removeListener = function (fn) { for (var i = 0; i < listeners.length; i += 1) { if (listeners[i] === fn) { listeners.splice(i, 1); return; } } }; var taskComplete = function () { _each(listeners.slice(0), function (fn) { fn(); }); }; addListener(function () { if (_keys(results).length === keys.length) { callback(null, results); callback = function () {}; } }); _each(keys, function (k) { var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; var taskCallback = function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } if (err) { var safeResults = {}; _each(_keys(results), function(rkey) { safeResults[rkey] = results[rkey]; }); safeResults[k] = args; callback(err, safeResults); // stop subsequent errors hitting callback multiple times callback = function () {}; } else { results[k] = args; async.setImmediate(taskComplete); } }; var requires = task.slice(0, Math.abs(task.length - 1)) || []; var ready = function () { return _reduce(requires, function (a, x) { return (a && results.hasOwnProperty(x)); }, true) && !results.hasOwnProperty(k); }; if (ready()) { task[task.length - 1](taskCallback, results); } else { var listener = function () { if (ready()) { removeListener(listener); task[task.length - 1](taskCallback, results); } }; addListener(listener); } }); }; async.waterfall = function (tasks, callback) { callback = callback || function () {}; if (tasks.constructor !== Array) { var err = new Error('First argument to waterfall must be an array of functions'); return callback(err); } if (!tasks.length) { return callback(); } var wrapIterator = function (iterator) { return function (err) { if (err) { callback.apply(null, arguments); callback = function () {}; } else { var args = Array.prototype.slice.call(arguments, 1); var next = iterator.next(); if (next) { args.push(wrapIterator(next)); } else { args.push(callback); } async.setImmediate(function () { iterator.apply(null, args); }); } }; }; wrapIterator(async.iterator(tasks))(); }; var _parallel = function(eachfn, tasks, callback) { callback = callback || function () {}; if (tasks.constructor === Array) { eachfn.map(tasks, function (fn, callback) { if (fn) { fn(function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } callback.call(null, err, args); }); } }, callback); } else { var results = {}; eachfn.each(_keys(tasks), function (k, callback) { tasks[k](function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } results[k] = args; callback(err); }); }, function (err) { callback(err, results); }); } }; async.parallel = function (tasks, callback) { _parallel({ map: async.map, each: async.each }, tasks, callback); }; async.parallelLimit = function(tasks, limit, callback) { _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback); }; async.series = function (tasks, callback) { callback = callback || function () {}; if (tasks.constructor === Array) { async.mapSeries(tasks, function (fn, callback) { if (fn) { fn(function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } callback.call(null, err, args); }); } }, callback); } else { var results = {}; async.eachSeries(_keys(tasks), function (k, callback) { tasks[k](function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } results[k] = args; callback(err); }); }, function (err) { callback(err, results); }); } }; async.iterator = function (tasks) { var makeCallback = function (index) { var fn = function () { if (tasks.length) { tasks[index].apply(null, arguments); } return fn.next(); }; fn.next = function () { return (index < tasks.length - 1) ? makeCallback(index + 1): null; }; return fn; }; return makeCallback(0); }; async.apply = function (fn) { var args = Array.prototype.slice.call(arguments, 1); return function () { return fn.apply( null, args.concat(Array.prototype.slice.call(arguments)) ); }; }; var _concat = function (eachfn, arr, fn, callback) { var r = []; eachfn(arr, function (x, cb) { fn(x, function (err, y) { r = r.concat(y || []); cb(err); }); }, function (err) { callback(err, r); }); }; async.concat = doParallel(_concat); async.concatSeries = doSeries(_concat); async.whilst = function (test, iterator, callback) { if (test()) { iterator(function (err) { if (err) { return callback(err); } async.whilst(test, iterator, callback); }); } else { callback(); } }; async.doWhilst = function (iterator, test, callback) { iterator(function (err) { if (err) { return callback(err); } if (test()) { async.doWhilst(iterator, test, callback); } else { callback(); } }); }; async.until = function (test, iterator, callback) { if (!test()) { iterator(function (err) { if (err) { return callback(err); } async.until(test, iterator, callback); }); } else { callback(); } }; async.doUntil = function (iterator, test, callback) { iterator(function (err) { if (err) { return callback(err); } if (!test()) { async.doUntil(iterator, test, callback); } else { callback(); } }); }; async.queue = function (worker, concurrency) { if (concurrency === undefined) { concurrency = 1; } function _insert(q, data, pos, callback) { if(data.constructor !== Array) { data = [data]; } _each(data, function(task) { var item = { data: task, callback: typeof callback === 'function' ? callback : null }; if (pos) { q.tasks.unshift(item); } else { q.tasks.push(item); } if (q.saturated && q.tasks.length === concurrency) { q.saturated(); } async.setImmediate(q.process); }); } var workers = 0; var q = { tasks: [], concurrency: concurrency, saturated: null, empty: null, drain: null, push: function (data, callback) { _insert(q, data, false, callback); }, unshift: function (data, callback) { _insert(q, data, true, callback); }, process: function () { if (workers < q.concurrency && q.tasks.length) { var task = q.tasks.shift(); if (q.empty && q.tasks.length === 0) { q.empty(); } workers += 1; var next = function () { workers -= 1; if (task.callback) { task.callback.apply(task, arguments); } if (q.drain && q.tasks.length + workers === 0) { q.drain(); } q.process(); }; var cb = only_once(next); worker(task.data, cb); } }, length: function () { return q.tasks.length; }, running: function () { return workers; } }; return q; }; async.cargo = function (worker, payload) { var working = false, tasks = []; var cargo = { tasks: tasks, payload: payload, saturated: null, empty: null, drain: null, push: function (data, callback) { if(data.constructor !== Array) { data = [data]; } _each(data, function(task) { tasks.push({ data: task, callback: typeof callback === 'function' ? callback : null }); if (cargo.saturated && tasks.length === payload) { cargo.saturated(); } }); async.setImmediate(cargo.process); }, process: function process() { if (working) return; if (tasks.length === 0) { if(cargo.drain) cargo.drain(); return; } var ts = typeof payload === 'number' ? tasks.splice(0, payload) : tasks.splice(0); var ds = _map(ts, function (task) { return task.data; }); if(cargo.empty) cargo.empty(); working = true; worker(ds, function () { working = false; var args = arguments; _each(ts, function (data) { if (data.callback) { data.callback.apply(null, args); } }); process(); }); }, length: function () { return tasks.length; }, running: function () { return working; } }; return cargo; }; var _console_fn = function (name) { return function (fn) { var args = Array.prototype.slice.call(arguments, 1); fn.apply(null, args.concat([function (err) { var args = Array.prototype.slice.call(arguments, 1); if (typeof console !== 'undefined') { if (err) { if (console.error) { console.error(err); } } else if (console[name]) { _each(args, function (x) { console[name](x); }); } } }])); }; }; async.log = _console_fn('log'); async.dir = _console_fn('dir'); /*async.info = _console_fn('info'); async.warn = _console_fn('warn'); async.error = _console_fn('error');*/ async.memoize = function (fn, hasher) { var memo = {}; var queues = {}; hasher = hasher || function (x) { return x; }; var memoized = function () { var args = Array.prototype.slice.call(arguments); var callback = args.pop(); var key = hasher.apply(null, args); if (key in memo) { callback.apply(null, memo[key]); } else if (key in queues) { queues[key].push(callback); } else { queues[key] = [callback]; fn.apply(null, args.concat([function () { memo[key] = arguments; var q = queues[key]; delete queues[key]; for (var i = 0, l = q.length; i < l; i++) { q[i].apply(null, arguments); } }])); } }; memoized.memo = memo; memoized.unmemoized = fn; return memoized; }; async.unmemoize = function (fn) { return function () { return (fn.unmemoized || fn).apply(null, arguments); }; }; async.times = function (count, iterator, callback) { var counter = []; for (var i = 0; i < count; i++) { counter.push(i); } return async.map(counter, iterator, callback); }; async.timesSeries = function (count, iterator, callback) { var counter = []; for (var i = 0; i < count; i++) { counter.push(i); } return async.mapSeries(counter, iterator, callback); }; async.compose = function (/* functions... */) { var fns = Array.prototype.reverse.call(arguments); return function () { var that = this; var args = Array.prototype.slice.call(arguments); var callback = args.pop(); async.reduce(fns, args, function (newargs, fn, cb) { fn.apply(that, newargs.concat([function () { var err = arguments[0]; var nextargs = Array.prototype.slice.call(arguments, 1); cb(err, nextargs); }])) }, function (err, results) { callback.apply(that, [err].concat(results)); }); }; }; var _applyEach = function (eachfn, fns /*args...*/) { var go = function () { var that = this; var args = Array.prototype.slice.call(arguments); var callback = args.pop(); return eachfn(fns, function (fn, cb) { fn.apply(that, args.concat([cb])); }, callback); }; if (arguments.length > 2) { var args = Array.prototype.slice.call(arguments, 2); return go.apply(this, args); } else { return go; } }; async.applyEach = doParallel(_applyEach); async.applyEachSeries = doSeries(_applyEach); async.forever = function (fn, callback) { function next(err) { if (err) { if (callback) { return callback(err); } throw err; } fn(next); } next(); }; // AMD / RequireJS if (typeof define !== 'undefined' && define.amd) { define([], function () { return async; }); } // Node.js else if (typeof module !== 'undefined' && module.exports) { module.exports = async; } // included directly via