<commit_before>var Connection = require('./connection');
var JID = require('./jid').JID;
var ltx = require('ltx');
var sasl = require('./sasl');
var sys = require('sys');
var Buffer = require('buffer').Buffer;
var SRV = require('./srv');

var NS_CLIENT = 'jabber:client';
var NS_XMPP_SASL = 'urn:ietf:params:xml:ns:xmpp-sasl';
var NS_XMPP_BIND = 'urn:ietf:params:xml:ns:xmpp-bind';
var NS_XMPP_SESSION = 'urn:ietf:params:xml:ns:xmpp-session';

var STATE_PREAUTH = 0,
    STATE_AUTH = 1,
    STATE_AUTHED = 2,
    STATE_BIND = 3,
    STATE_SESSION = 4,
    STATE_ONLINE = 5;
var IQID_SESSION = 'sess',
    IQID_BIND = 'bind';

/**
 * params:
 *   jid: String (required)
 *   password: String (required)
 *   host: String (optional)
 *   port: Number (optional)
 */
function Client(params) {
    var self = this;
    Connection.Connection.call(this);

    if (typeof params.jid == 'string')
        this.jid = new JID(params.jid);
    else
        this.jid = params.jid;
    this.password = params.password;
    this.api_key = params.api_key;
    this.secret_key = params.secret_key;
    this.session_key = params.session_key;
    this.xmlns[''] = NS_CLIENT;
    this.xmppVersion = "1.0";
    this.streamTo = this.jid.domain;
    this.state = STATE_PREAUTH;
    this.addListener('rawStanza', this.onRawStanza);

    if (params.host) {
        this.socket.connect(params.port || 5222, params.host);
        this.socket.on('connect', function() {
            self.startParser();
            self.startStream();
        });
    } else {
        var attempt = SRV.connect(this.socket,
                                  ['_xmpp-client._tcp'], this.jid.domain, 5222);
        attempt.addListener('connect', function() {
            self.startParser();
            self.startStream();
        });
        attempt.addListener('error', function(e) {
            self.emit('error', e);
        });
    }

    // it's us who must restart after starttls
    this.socket.addListener('secure', function() {
        self.startStream();
    });
    this.socket.addListener('end', function() {
        self.state = STATE_PREAUTH;
    });
}

sys.inherits(Client, Connection.Connection);
exports.Client = Client;

Client.prototype.onRawStanza = function(stanza) {
    /* Actually, we shouldn't wait for <stream:features/> if
       this.streamAttrs.version is missing, but who uses pre-XMPP-1.0
       these days anyway? */
    if (this.state != STATE_ONLINE &&
        stanza.is('features', Connection.NS_STREAM)) {
        this.streamFeatures = stanza;
        this.useFeatures();
    } else if (this.state == STATE_AUTH) {
        if (stanza.is('challenge', NS_XMPP_SASL)) {
            var challengeMsg = decode64(stanza.getText());
            var responseMsg = encode64(<commit_msg>Emit on socket end connection.<commit_after>var Connection = require('./connection');
var JID = require('./jid').JID;
var ltx = require('ltx');
var sasl = require('./sasl');
var sys = require('sys');
var Buffer = require('buffer').Buffer;
var SRV = require('./srv');

var NS_CLIENT = 'jabber:client';
var NS_XMPP_SASL = 'urn:ietf:params:xml:ns:xmpp-sasl';
var NS_XMPP_BIND = 'urn:ietf:params:xml:ns:xmpp-bind';
var NS_XMPP_SESSION = 'urn:ietf:params:xml:ns:xmpp-session';

var STATE_PREAUTH = 0,
    STATE_AUTH = 1,
    STATE_AUTHED = 2,
    STATE_BIND = 3,
    STATE_SESSION = 4,
    STATE_ONLINE = 5;
var IQID_SESSION = 'sess',
    IQID_BIND = 'bind';

/**
 * params:
 *   jid: String (required)
 *   password: String (required)
 *   host: String (optional)
 *   port: Number (optional)
 */
function Client(params) {
    var self = this;
    Connection.Connection.call(this);

    if (typeof params.jid == 'string')
        this.jid = new JID(params.jid);
    else
        this.jid = params.jid;
    this.password = params.password;
    this.api_key = params.api_key;
    this.secret_key = params.secret_key;
    this.session_key = params.session_key;
    this.xmlns[''] = NS_CLIENT;
    this.xmppVersion = "1.0";
    this.streamTo = this.jid.domain;
    this.state = STATE_PREAUTH;
    this.addListener('rawStanza', this.onRawStanza);

    if (params.host) {
        this.socket.connect(params.port || 5222, params.host);
        this.socket.on('connect', function() {
            self.startParser();
            self.startStream();
        });
    } else {
        var attempt = SRV.connect(this.socket,
                                  ['_xmpp-client._tcp'], this.jid.domain, 5222);
        attempt.addListener('connect', function() {
            self.startParser();
            self.startStream();
        });
        attempt.addListener('error', function(e) {
            self.emit('error', e);
        });
    }

    // it's us who must restart after starttls
    this.socket.addListener('secure', function() {
        self.startStream();
    });
    this.socket.addListener('end', function() {
        self.state = STATE_PREAUTH;
        self.emit('offline');
    });
}

sys.inherits(Client, Connection.Connection);
exports.Client = Client;

Client.prototype.onRawStanza = function(stanza) {
    /* Actually, we shouldn't wait for <stream:features/> if
       this.streamAttrs.version is missing, but who uses pre-XMPP-1.0
       these days anyway? */
    if (this.state != STATE_ONLINE &&
        stanza.is('features', Connection.NS_STREAM)) {
        this.streamFeatures = stanza;
        this.useFeatures();
    } else if (this.state == STATE_AUTH) {
        if (stanza.is('challenge', NS_XMPP_SASL)) {
            var challengeMsg = decode64(stanza.getText());
            var responseMsg = encode64(
{'fraction_non_alphanumeric': 0.14818132951084034, 'fraction_numerical': 0.007883891775667442, 'mean_word_length': 2.7213333333333334, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3053813', 'n_tokens_mistral': 1896, 'n_tokens_neox': 1829, 'n_words': 364}