<commit_before>'use strict';
/*
 * ***** BEGIN LICENSE BLOCK *****
 * Copyright (c) 2011-2012 VMware, Inc.
 *
 * For the license see COPYING.
 * ***** END LICENSE BLOCK *****
 */

var utils = require('./utils');
var REventTarget = require('./reventtarget');
var SimpleEvent = require('./SimpleEvent');
var InfoReceiver = require('./info-receiver');
var InfoReceiverIframe = require('./info-receiver-iframe');
var InfoReceiverFake = require('./info-receiver-fake');
var FacadeJS = require('./facade');
var JSON3 = require('json3');
var XHRLocalObject = require('./xhr-local');
var XHRCorsObject = require('./xhr-cors');
var XDRObject = require('./xdr');

function SockJS(url, dep_protocols_whitelist, options) {
    if (!(this instanceof SockJS)) {
        // makes `new` optional
        return new SockJS(url, dep_protocols_whitelist, options);
    }

    var that = this, protocols_whitelist;
    that._options = {devel: false, debug: false, protocols_whitelist: [],
                     info: undefined, rtt: undefined};
    if (options) {
        utils.objectExtend(that._options, options);
    }
    that._base_url = utils.amendUrl(url);
    that._server = that._options.server || utils.random_number_string(1000);
    if (that._options.protocols_whitelist &&
        that._options.protocols_whitelist.length) {
        protocols_whitelist = that._options.protocols_whitelist;
    } else {
        // Deprecated API
        if (typeof dep_protocols_whitelist === 'string' &&
            dep_protocols_whitelist.length > 0) {
            protocols_whitelist = [dep_protocols_whitelist];
        } else if (utils.isArray(dep_protocols_whitelist)) {
            protocols_whitelist = dep_protocols_whitelist;
        } else {
            protocols_whitelist = null;
        }
        if (protocols_whitelist) {
            that._debug('Deprecated API: Use "protocols_whitelist" option ' +
                        'instead of supplying protocol list as a second ' +
                        'parameter to SockJS constructor.');
        }
    }
    that._protocols = [];
    that.protocol = null;
    that.readyState = SockJS.CONNECTING;
    that._ir = createInfoReceiver(that._base_url);
    that._ir.onfinish = function(info, rtt) {
        that._ir = null;
        if (info) {
            if (that._options.info) {
                // Override if user supplies the option
                info = utils.objectExtend(info, that._options.info);
            }
            if (that._options.rtt) {
                rtt = that._options.rtt;
            }
            that._applyInfo(info, rtt, protocols_whitelist);
            that._didClose();
        } else {
            that._didClose(1002, 'Can\'t connect to server', true);
        }
    };
}

// Inheritance
SockJS.prototype = new REventTarget();

SockJS.version = '1.0.0-alpha1';

SockJS.prototype.CONNECTING = SockJS.CONNECTING = 0;
SockJS.prototype.OPEN = SockJS.OPEN = 1;
SockJS.prototype.CLOSING = SockJS.CLOSING = 2;
SockJS.prototype.CLOSED = SockJS.CLOSED = 3;

SockJS.prototype._debug = function() {
    if (this._options.debug)
        utils.log.apply(utils, arguments);
};

SockJS.prototype._dispatchOpen = function() {
    var that = this;
    if (that.readyState === SockJS.CONNECTING) {
        if (that._transport_tref) {
            clearTimeout(that._transport_tref);
            that._transport_tref = null;
        }
        that.readyState = SockJS.OPEN;
        that.dispatchEvent(new SimpleEvent("open"));
    } else {
        // The server might have been restarted, and lost track of our
        // connection.
        that._didClose(1006, "Server lost session");
    }
};

SockJS.prototype._dispatchMessage = function(data) {
    var that = this;
    if (that.readyState !== SockJS.OPEN)
            return;
    that.dispatchEvent(new SimpleEvent("message", {data: data}));
};

SockJS.prototype._dispatchHeartbeat = function(data) {
    var that = this;
    if (that.readyState !== SockJS.OPEN)
        return;
    that.dispatchEvent(new SimpleEvent('heartbeat', {}));
};

SockJS.prototype._didClose = function(code, reason, force) {
    var that = this;
    if (that.readyState !== SockJS.CONNECTING &&
        that.readyState !== SockJS.OPEN &&
        that.readyState !== SockJS.CLOSING)
            throw new Error('INVALID_STATE_ERR');
    if (that._ir) {
        that._ir.nuke();
        that._ir = null;
    }

    if (that._transport) {
        that._transport.doCleanup();
        that._transport = null;
    }

    var close_event = new SimpleEvent("close", {
        code: code,
        reason: reason,
        wasClean: utils.userSetCode(code)});

    if (!utils.userSetCode(code) &&
        that.readyState === SockJS.CONNECTING && !force) {
        if (that._try_next_protocol(close_event)) {
            return;
        }
        close_event = new SimpleEvent("close", {code: 2000,
                                                reason: "All transports failed",
                                                wasClean: false,
                                                last_event: close_event});
    }
    that.readyState = SockJS.CLOSED;

    utils.delay(function() {
                   that.dispatchEvent(close_event);
                });
};

SockJS.prototype._didMessage = function(data) {
    var that = this;
    var type = data.slice(0, 1);
    var payload;
    switch(type) {
    case 'o':
        that._dispatchOpen();
        break;
    case 'a':
        payload = JSON3.parse(data.slice(1) || '[]');
        for(var i=0; i < payload.length; i++){
            that._dispatchMessage(payload[i]);
        }
        break;
    case 'm':
        payload = JSON3.parse(data.slice(1) || 'null');
        that._dispatchMessage(payload);
        break;
    case 'c':
        payload = JSON3.parse(data.slice(1) || '[]');
        that._didClose(payload[0], payload[1]);
        break;
    case 'h':
        that._dispatchHeartbeat();
        break;
    }
};

SockJS.prototype._try_next_protocol = function(close_event) {
    var that = this;
    if (that.protocol) {
        that._debug('Closed transport:', that.protocol, ''+close_event);
        that.protocol = null;
    }
    if (that._transport_tref) {
        clearTimeout(that._transport_tref);
        that._transport_tref = null;
    }

    function timeoutFunction() {
        if (that.readyState === SockJS.CONNECTING) {
            // I can't understand how it is possible to run
            // this timer, when the state is CLOSED, but
            // apparently in IE everythin is possible.
            that._didClose(2007, "Transport timed out");
        }
    }

    function tryNextProtocol() {
        that._try_next_protocol();
    }

    while(1) {
        var protocol = that.protocol = that._protocols.shift();
        if (!protocol) {
            return false;
        }
        // Some protocols require access to `body`, what if were in
        // the `head`?
        if (SockJS[protocol] &&
            SockJS[protocol].need_body === true &&
            (!document.body ||
             (typeof document.readyState !== 'undefined'
              && document.readyState !== 'complete'))) {
            that._protocols.unshift(protocol);
            that.protocol = 'waiting-for-load';
            utils.attachEvent('load', tryNextProtocol);
            return true;
        }

        if (!SockJS[protocol] ||
              !SockJS[protocol].enabled(that._options)) {
            that._debug('Skipping transport:', protocol);
        } else {
            var roundTrips = SockJS[protocol].roundTrips || 1;
            var to = ((that._options.rto || 0) * roundTrips) || 5000;
            that._transport_tref = utils.delay(to, timeoutFunction);

            var connid = utils.random_string(8);
            var trans_url = that._base_url + '/' + that._server + '/' + connid;
            that._debug('Opening transport:', protocol, ' url:'+trans_url,
                        ' RTO:'+that._options.rto);
            that._transport = new SockJS[protocol](that, trans_url,
                                                   that._base_url);
            return true;
        }
    }
};

SockJS.prototype.close = function(code, reason) {
    var that = this;
    if (code && !utils.userSetCode(code))
        throw new Error("INVALID_ACCESS_ERR");
    if(that.readyState !== SockJS.CONNECTING &&
       that.readyState !== SockJS.OPEN) {
        return false;
    }
    that.readyState = SockJS.CLOSING;
    that._didClose(code || 1000, reason || "Normal closure");
    return true;
};

SockJS.prototype.send = function(data) {
    var that = this;
    if (that.readyState === SockJS.CONNECTING)
        throw new Error('INVALID_STATE_ERR');
    if (that.readyState === SockJS.OPEN) {
        that._transport.doSend(utils.quote('' + data));
    }
    return true;
};

SockJS.prototype._applyInfo = function(info, rtt, protocols_whitelist) {
    var that = this;
    that._options.info = info;
    that._options.rtt = rtt;
    that._options.rto = utils.countRTO(rtt);
    that._options.info.null_origin = !document.domain;
    // Servers can override base_url, eg to provide a randomized domain name and
    // avoid browser per-domain connection limits.
    if (info.base_url)
      that._base_url = utils.amendUrl(info.base_url);
    var probed = utils.probeProtocols();
    that._protocols = utils.detectProtocols(probed, protocols_whitelist, info);
};

utils.parent_origin = undefined;

SockJS.bootstrap_iframe = function() {
    var facade;
    utils.curr_window_id = document.location.hash.slice(1);
    var onMessage = function(e) {
        if(e.source !== parent) return;
        if(typeof utils.parent_origin === 'undefined')
            utils.parent_origin = e.origin;
        if (e.origin !== utils.parent_origin) return;

        var window_id = e.data.slice(0, 8);
        var type = e.data.slice(8, 9);
        var data = e.data.slice(9);
        if (window_id !== utils.curr_window_id) return;
        switch(type) {
        case 's':
            var p = JSON3.parse(data);
            var version = p[0];
            var protocol = p[1];
            var trans_url = p[2];
            var base_url = p[3];
            // change this to semver logic
            if (version !== SockJS.version) {
                utils.log("Incompatibile SockJS! Main site uses:" +
                          " \"" + version + "\", the iframe:" +
                          " \"" + SockJS.version + "\".");
            }
            if (!utils.flatUrl(trans_url) || !utils.flatUrl(base_url)) {
                utils.log("Only basic urls are supported in SockJS");
                return;
            }

            if (!utils.isSameOriginUrl(trans_url) ||
                !utils.isSameOriginUrl(base_url)) {
                utils.log("Can't connect to different domain from within an " +
                          "iframe. (" + JSON3.stringify([window.location.href, trans_url, base_url]) +
                          ")");
                return;
            }
            facade = new FacadeJS();
            facade._transport = new FacadeJS[protocol](facade, trans_url, base_url);
            break;
        case 'm':
            facade._doSend(data);
            break;
        case 'c':
            if (facade)
                facade._doCleanup();
            facade = null;
            break;
        }
    };

    utils.attachMessage(onMessage);

    // Start
    utils.postMessage('s');
};

SockJS.websocket = require('./trans-websocket');
SockJS['iframe-eventsource'] = require('./trans-iframe-eventsource');
SockJS['iframe-htmlfile'] = require('./trans-iframe-htmlfile');
SockJS['iframe-xhr-polling'] = require('./trans-iframe-xhr-polling');
SockJS['jsonp-polling'] = require('./trans-jsonp-polling');
SockJS['xdr-polling'] = require('./trans-xdr-polling');
SockJS['xdr-streaming'] = require('./trans-xdr-streaming');
SockJS['xhr-polling'] = require('./trans-xhr-polling');
SockJS['xhr-streaming'] = require('./trans-xhr-streaming');

module.exports = SockJS;

FacadeJS['w-iframe-info-receiver'] = require('./info-receiver-iframe');
FacadeJS['w-iframe-eventsource'] = require('./trans-eventsource');
FacadeJS['w-iframe-htmlfile'] = require('./trans-htmlfile');
FacadeJS['w-iframe-xhr-polling'] = require('./xhr-polling-iframe');

// TODO get rid of both of these!!!!
SockJS.getUtils = function () { return utils; };

// This is seriously wack.
if ('_sockjs_onload' in window) setTimeout(window._sockjs_onload, 1);

function createInfoReceiver(base_url) {
    if (utils.isSameOriginUrl(base_url)) {
        // If, for some reason, we have SockJS locally - there's no
        // need to start up the complex machinery. Just use ajax.
        return new InfoReceiver(base_url, XHRCorsObject);
    }
    switch (utils.isXHRCorsCapable()) {
    case 1:
        // XHRLocalObject -> no_credentials=true
        return new InfoReceiver(base_url, XHRLocalObject);
    case 2:
        // IE 8/9 if the request target uses the same scheme
        if (utils.isSameOriginScheme(base_url)) {
            return new InfoReceiver(base_url, XDRObject);
        }
        break;
    case 3:
        // Opera
        return new InfoReceiverIframe(base_url);
    }

    // IE 7, and IE 8/9 if requesting across schemes (e.g. http -> https)
    return new InfoReceiverFake();
}
<commit_msg>fix casing of simpleevent<commit_after>'use strict';
/*
 * ***** BEGIN LICENSE BLOCK *****
 * Copyright (c) 2011-2012 VMware, Inc.
 *
 * For the license see COPYING.
 * ***** END LICENSE BLOCK *****
 */

var utils = require('./utils');
var REventTarget = require('./reventtarget');
var SimpleEvent = require('./simpleevent');
var InfoReceiver = require('./info-receiver');
var InfoReceiverIframe = require('./info-receiver-iframe');
var InfoReceiverFake = require('./info-receiver-fake');
var FacadeJS = require('./facade');
var JSON3 = require('json3');
var XHRLocalObject = require('./xhr-local');
var XHRCorsObject = require('./xhr-cors');
var XDRObject = require('./xdr');

function SockJS(url, dep_protocols_whitelist, options) {
    if (!(this instanceof SockJS)) {
        // makes `new` optional
        return new SockJS(url, dep_protocols_whitelist, options);
    }

    var that = this, protocols_whitelist;
    that._options = {devel: false, debug: false, protocols_whitelist: [],
                     info: undefined, rtt: undefined};
    if (options) {
        utils.objectExtend(that._options, options);
    }
    that._base_url = utils.amendUrl(url);
    that._server = that._options.server || utils.random_number_string(1000);
    if (that._options.protocols_whitelist &&
        that._options.protocols_whitelist.length) {
        protocols_whitelist = that._options.protocols_whitelist;
    } else {
        // Deprecated API
        if (typeof dep_protocols_whitelist === 'string' &&
            dep_protocols_whitelist.length > 0) {
            protocols_whitelist = [dep_protocols_whitelist];
        } else if (utils.isArray(dep_protocols_whitelist)) {
            protocols_whitelist = dep_protocols_whitelist;
        } else {
            protocols_whitelist = null;
        }
        if (protocols_whitelist) {
            that._debug('Deprecated API: Use "protocols_whitelist" option ' +
                        'instead of supplying protocol list as a second ' +
                        'parameter to SockJS constructor.');
        }
    }
    that._protocols = [];
    that.protocol = null;
    that.readyState = SockJS.CONNECTING;
    that._ir = createInfoReceiver(that._base_url);
    that._ir.onfinish = function(info, rtt) {
        that._ir = null;
        if (info) {
            if (that._options.info) {
                // Override if user supplies the option
                info = utils.objectExtend(info, that._options.info);
            }
            if (that._options.rtt) {
                rtt = that._options.rtt;
            }
            that._applyInfo(info, rtt, protocols_whitelist);
            that._didClose();
        } else {
            that._didClose(1002, 'Can\'t connect to server', true);
        }
    };
}

// Inheritance
SockJS.prototype = new REventTarget();

SockJS.version = '1.0.0-alpha1';

SockJS.prototype.CONNECTING = SockJS.CONNECTING = 0;
SockJS.prototype.OPEN = SockJS.OPEN = 1;
SockJS.prototype.CLOSING = SockJS.CLOSING = 2;
SockJS.prototype.CLOSED = SockJS.CLOSED = 3;

SockJS.prototype._debug = function() {
    if (this._options.debug)
        utils.log.apply(utils, arguments);
};

SockJS.prototype._dispatchOpen = function() {
    var that = this;
    if (that.readyState === SockJS.CONNECTING) {
        if (that._transport_tref) {
            clearTimeout(that._transport_tref);
            that._transport_tref = null;
        }
        that.readyState = SockJS.OPEN;
        that.dispatchEvent(new SimpleEvent("open"));
    } else {
        // The server might have been restarted, and lost track of our
        // connection.
        that._didClose(1006, "Server lost session");
    }
};

SockJS.prototype._dispatchMessage = function(data) {
    var that = this;
    if (that.readyState !== SockJS.OPEN)
            return;
    that.dispatchEvent(new SimpleEvent("message", {data: data}));
};

SockJS.prototype._dispatchHeartbeat = function(data) {
    var that = this;
    if (that.readyState !== SockJS.OPEN)
        return;
    that.dispatchEvent(new SimpleEvent('heartbeat', {}));
};

SockJS.prototype._didClose = function(code, reason, force) {
    var that = this;
    if (that.readyState !== SockJS.CONNECTING &&
        that.readyState !== SockJS.OPEN &&
        that.readyState !== SockJS.CLOSING)
            throw new Error('INVALID_STATE_ERR');
    if (that._ir) {
        that._ir.nuke();
        that._ir = null;
    }

    if (that._transport) {
        that._transport.doCleanup();
        that._transport = null;
    }

    var close_event = new SimpleEvent("close", {
        code: code,
        reason: reason,
        wasClean: utils.userSetCode(code)});

    if (!utils.userSetCode(code) &&
        that.readyState === SockJS.CONNECTING && !force) {
        if (that._try_next_protocol(close_event)) {
            return;
        }
        close_event = new SimpleEvent("close", {code: 2000,
                                                reason: "All transports failed",
                                                wasClean: false,
                                                last_event: close_event});
    }
    that.readyState = SockJS.CLOSED;

    utils.delay(function() {
                   that.dispatchEvent(close_event);
                });
};

SockJS.prototype._didMessage = function(data) {
    var that = this;
    var type = data.slice(0, 1);
    var payload;
    switch(type) {
    case 'o':
        that._dispatchOpen();
        break;
    case 'a':
        payload = JSON3.parse(data.slice(1) || '[]');
        for(var i=0; i < payload.length; i++){
            that._dispatchMessage(payload[i]);
        }
        break;
    case 'm':
        payload = JSON3.parse(data.slice(1) || 'null');
        that._dispatchMessage(payload);
        break;
    case 'c':
        payload = JSON3.parse(data.slice(1) || '[]');
        that._didClose(payload[0], payload[1]);
        break;
    case 'h':
        that._dispatchHeartbeat();
        break;
    }
};

SockJS.prototype._try_next_protocol = function(close_event) {
    var that = this;
    if (that.protocol) {
        that._debug('Closed transport:', that.protocol, ''+close_event);
        that.protocol = null;
    }
    if (that._transport_tref) {
        clearTimeout(that._transport_tref);
        that._transport_tref = null;
    }

    function timeoutFunction() {
        if (that.readyState === SockJS.CONNECTING) {
            // I can't understand how it is possible to run
            // this timer, when the state is CLOSED, but
            // apparently in IE everythin is possible.
            that._didClose(2007, "Transport timed out");
        }
    }

    function tryNextProtocol() {
        that._try_next_protocol();
    }

    while(1) {
        var protocol = that.protocol = that._protocols.shift();
        if (!protocol) {
            return false;
        }
        // Some protocols require access to `body`, what if were in
        // the `head`?
        if (SockJS[protocol] &&
            SockJS[protocol].need_body === true &&
            (!document.body ||
             (typeof document.readyState !== 'undefined'
              && document.readyState !== 'complete'))) {
            that._protocols.unshift(protocol);
            that.protocol = 'waiting-for-load';
            utils.attachEvent('load', tryNextProtocol);
            return true;
        }

        if (!SockJS[protocol] ||
              !SockJS[protocol].enabled(that._options)) {
            that._debug('Skipping transport:', protocol);
        } else {
            var roundTrips = SockJS[protocol].roundTrips || 1;
            var to = ((that._options.rto || 0) * roundTrips) || 5000;
            that._transport_tref = utils.delay(to, timeoutFunction);

            var connid = utils.random_string(8);
            var trans_url = that._base_url + '/' + that._server + '/' + connid;
            that._debug('Opening transport:', protocol, ' url:'+trans_url,
                        ' RTO:'+that._options.rto);
            that._transport = new SockJS[protocol](that, trans_url,
                                                   that._base_url);
            return true;
        }
    }
};

SockJS.prototype.close = function(code, reason) {
    var that = this;
    if (code && !utils.userSetCode(code))
        throw new Error("INVALID_ACCESS_ERR");
    if(that.readyState !== SockJS.CONNECTING &&
       that.readyState !== SockJS.OPEN) {
        return false;
    }
    that.readyState = SockJS.CLOSING;
    that._didClose(code || 1000, reason || "Normal closure");
    return true;
};

SockJS.prototype.send = function(data) {
    var that = this;
    if (that.readyState === SockJS.CONNECTING)
        throw new Error('INVALID_STATE_ERR');
    if (that.readyState === SockJS.OPEN) {
        that._transport.doSend(utils.quote('' + data));
    }
    return true;
};

SockJS.prototype._applyInfo = function(info, rtt, protocols_whitelist) {
    var that = this;
    that._options.info = info;
    that._options.rtt = rtt;
    that._options.rto = utils.countRTO(rtt);
    that._options.info.null_origin = !document.domain;
    // Servers can override base_url, eg to provide a randomized domain name and
    // avoid browser per-domain connection limits.
    if (info.base_url)
      that._base_url = utils.amendUrl(info.base_url);
    var probed = utils.probeProtocols();
    that._protocols = utils.detectProtocols(probed, protocols_whitelist, info);
};

utils.parent_origin = undefined;

SockJS.bootstrap_iframe = function() {
    var facade;
    utils.curr_window_id = document.location.hash.slice(1);
    var onMessage = function(e) {
        if(e.source !== parent) return;
        if(typeof utils.parent_origin === 'undefined')
            utils.parent_origin = e.origin;
        if (e.origin !== utils.parent_origin) return;

        var window_id = e.data.slice(0, 8);
        var type = e.data.slice(8, 9);
        var data = e.data.slice(9);
        if (window_id !== utils.curr_window_id) return;
        switch(type) {
        case 's':
            var p = JSON3.parse(data);
            var version = p[0];
            var protocol = p[1];
            var trans_url = p[2];
            var base_url = p[3];
            // change this to semver logic
            if (version !== SockJS.version) {
                utils.log("Incompatibile SockJS! Main site uses:" +
                          " \"" + version + "\", the iframe:" +
                          " \"" + SockJS.version + "\".");
            }
            if (!utils.flatUrl(trans_url) || !utils.flatUrl(base_url)) {
                utils.log("Only basic urls are supported in SockJS");
                return;
            }

            if (!utils.isSameOriginUrl(trans_url) ||
                !utils.isSameOriginUrl(base_url)) {
                utils.log("Can't connect to different domain from within an " +
                          "iframe. (" + JSON3.stringify([window.location.href, trans_url, base_url]) +
                          ")");
                return;
            }
            facade = new FacadeJS();
            facade._transport = new FacadeJS[protocol](facade, trans_url, base_url);
            break;
        case 'm':
            facade._doSend(data);
            break;
        case 'c':
            if (facade)
                facade._doCleanup();
            facade = null;
            break;
        }
    };

    utils.attachMessage(onMessage);

    // Start
    utils.postMessage('s');
};

SockJS.websocket = require('./trans-websocket');
SockJS['iframe-eventsource'] = require('./trans-iframe-eventsource');
SockJS['iframe-htmlfile'] = require('./trans-iframe-htmlfile');
SockJS['iframe-xhr-polling'] = require('./trans-iframe-xhr-polling');
SockJS['jsonp-polling'] = require('./trans-jsonp-polling');
SockJS['xdr-polling'] = require('./trans-xdr-polling');
SockJS['xdr-streaming'] = require('./trans-xdr-streaming');
SockJS['xhr-polling'] = require('./trans-xhr-polling');
SockJS['xhr-streaming'] = require('./trans-xhr-streaming');

module.exports = SockJS;

FacadeJS['w-iframe-info-receiver'] = require('./info-receiver-iframe');
FacadeJS['w-iframe-eventsource'] = require('./trans-eventsource');
FacadeJS['w-iframe-htmlfile'] = require('./trans-htmlfile');
FacadeJS['w-iframe-xhr-polling'] = require('./xhr-polling-iframe');

// TODO get rid of both of these!!!!
SockJS.getUtils = function () { return utils; };

// This is seriously wack.
if ('_sockjs_onload' in window) setTimeout(window._sockjs_onload, 1);

function createInfoReceiver(base_url) {
    if (utils.isSameOriginUrl(base_url)) {
        // If, for some reason, we have SockJS locally - there's no
        // need to start up the complex machinery. Just use ajax.
        return new InfoReceiver(base_url, XHRCorsObject);
    }
    switch (utils.isXHRCorsCapable()) {
    case 1:
        // XHRLocalObject -> no_credentials=true
        return new InfoReceiver(base_url, XHRLocalObject);
    case 2:
        // IE 8/9 if the request target uses the same scheme
        if (utils.isSameOriginScheme(base_url)) {
            return new InfoReceiver(base_url, XDRObject);
        }
        break;
    case 3:
        // Opera
        return new InfoReceiverIframe(base_url);
    }

    // IE 7, and IE 8/9 if requesting across schemes (e.g. http -> https)
    return new InfoReceiverFake();
}
<|endoftext|>


<commit_before>(function (flow, $, d3) {

    var color = d3.scale.category20();

    $('.legend li').each(function() {
        var type = $(this).data('type');

        this.style.backgroundColor = color(type);
    });

    d3.json(flow.config.url.graph, function(error, graphs) {

        if (error) throw "Error rendering graph: " + error;

        createGraphs(graphs);

        if (typeof flow.component.search !== 'undefined') {
            flow.component.search.init(graphs);
        }
    });

    function createGraphs(graphs) {
        for (id in graphs) {
            if (graphs.hasOwnProperty(id)) {
                var graph = graphs[id];
                createGraph(id, graph);
            }
        }
    }

    function createGraph(id, graph) {
        var container = createGraphContainer(id);

        var links = container.selectAll(".link").data(graph.links);
        var nodes = container.selectAll(".node").data(graph.nodes);

        createForceLayout(graph, nodes, links);
    }

    function createGraphContainer(id) {
        var container = d3.select("body")
            .append("div")
            .attr("id",  "#graph-" + id)
            .attr("class", "graph-container well")
            .append("svg")
            .attr("viewBox", "0 0 " + flow.config.canvas.width + " " + flow.config.canvas.height )
            .attr("preserveAspectRatio", "xMidYMid meet");

        // arrow
        container.append("svg:defs").selectAll("marker")
            .data(["end"])
            .enter().append("marker")
            .attr("id", String)
            .attr("viewBox", "0 -5 12 12")
            .attr("refX", 25)
            .attr("refY", -1.5)
            .attr("markerWidth", 7)
            .attr("markerHeight", 7)
            .attr("orient", "auto")
            .append("path")
            .attr("d", "M0,-5L10,0L0,5")
            .style("stroke", "#4679BD")
            .style("opacity", "0.6");

        return container;
    }

    function createForceLayout(graph, nodes, links) {
        var force = d3.layout.force()
            .charge(flow.config.force.charge)
            .linkDistance(flow.config.force.linkDistance)
            .size([flow.config.canvas.width, flow.config.canvas.height]);

        force
            .nodes(graph.nodes)
            .links(graph.links)
            .start();

        links.enter().append("line")
            .attr("class", "link")
            .attr("marker-end", "url(#end)");

        nodes.enter().append("circle")
            .attr("class", "node")
            .attr("id", function (d) { return d.id; })
            .attr("r", 8)
            .style("fill", function (d) { return color(d.type); })
            .call(force.drag);

        nodes.enter().append("text")
            .attr("dx", 10)
            .attr("dy", "0.35em")
            .attr("class", "label")
            .attr("data-for-node", function (d) { return d.id; })
            .text(function(d) { return d.id });

        var circles = d3.selectAll("circle");
        var texts = d3.selectAll("text");

        force.on("tick", function() {
            links
                .attr("x1", function(d) { return d.source.x; })
                .attr("y1", function(d) { return d.source.y; })
                .attr("x2", function(d) { return d.target.x; })
                .attr("y2", function(d) { return d.target.y; });

            circles
                .attr("cx", function (d) { return d.x; })
                .attr("cy", function (d) { return d.y; });

            texts
                .attr("x", function (d) { return d.x; })
                .attr("y", function (d) { return d.y; });
        });
    }

    function temporaryFadeAllExcept(nodeId) {
        var nodes = d3.selectAll(".node:not(#" + nodeId + ")");
        var labels = d3.selectAll(".label:not([data-for-node='" + nodeId + "'])");
        var links = d3.selectAll(".link");

        nodes.style("opacity", "0");
        labels.style("opacity", "0");
        links.style("opacity", "0");

        d3.selectAll(".node, .link, .label")
            .transition()
            .duration(2000)
            .style("opacity", 1);
    }

    flow.component.graph = {
        temporaryFadeAllExcept: temporaryFadeAllExcept
    };

}(flow, jQuery, d3));<commit_msg>Reduce sentences<commit_after>(function (flow, $, d3) {

    var color = d3.scale.category20();

    $('.legend li').each(function() {
        var type = $(this).data('type');

        this.style.backgroundColor = color(type);
    });

    d3.json(flow.config.url.graph, function(error, graphs) {

        if (error) throw "Error rendering graph: " + error;

        createGraphs(graphs);

        if (typeof flow.component.search !== 'undefined') {
            flow.component.search.init(graphs);
        }
    });

    function createGraphs(graphs) {
        for (id in graphs) {
            if (graphs.hasOwnProperty(id)) {
                var graph = graphs[id];
                createGraph(id, graph);
            }
        }
    }

    function createGraph(id, graph) {
        var container = createGraphContainer(id);

        var links = container.selectAll(".link").data(graph.links);
        var nodes = container.selectAll(".node").data(graph.nodes);

        createForceLayout(graph, nodes, links);
    }

    function createGraphContainer(id) {
        var container = d3.select("body")
            .append("div")
            .attr("id",  "#graph-" + id)
            .attr("class", "graph-container well")
            .append("svg")
            .attr("viewBox", "0 0 " + flow.config.canvas.width + " " + flow.config.canvas.height )
            .attr("preserveAspectRatio", "xMidYMid meet");

        // arrow
        container.append("svg:defs").selectAll("marker")
            .data(["end"])
            .enter().append("marker")
            .attr("id", String)
            .attr("viewBox", "0 -5 12 12")
            .attr("refX", 25)
            .attr("refY", -1.5)
            .attr("markerWidth", 7)
            .attr("markerHeight", 7)
            .attr("orient", "auto")
            .append("path")
            .attr("d", "M0,-5L10,0L0,5")
            .style("stroke", "#4679BD")
            .style("opacity", "0.6");

        return container;
    }

    function createForceLayout(graph, nodes, links) {
        var force = d3.layout.force()
            .charge(flow.config.force.charge)
            .linkDistance(flow.config.force.linkDistance)
            .size([flow.config.canvas.width, flow.config.canvas.height])
            .nodes(graph.nodes)
            .links(graph.links)
            .start();

        links.enter().append("line")
            .attr("class", "link")
            .attr("marker-end", "url(#end)");

        var circles = nodes.enter().append("circle")
            .attr("class", "node")
            .attr("id", function (d) { return d.id; })
            .attr("r", 8)
            .style("fill", function (d) { return color(d.type); })

        circles.call(force.drag);

        var texts = nodes.enter().append("text")
            .attr("dx", 10)
            .attr("dy", "0.35em")
            .attr("class", "label")
            .attr("data-for-node", function (d) { return d.id; })
            .text(function(d) { return d.id });

        force.on("tick", function() {
            links
                .attr("x1", function(d) { return d.source.x; })
                .attr("y1", function(d) { return d.source.y; })
                .attr("x2", function(d) { return d.target.x; })
                .attr("y2", function(d) { return d.target.y; });

            circles
                .attr("cx", function (d) { return d.x; })
                .attr("cy", function (d) { return d.y; });

            texts
                .attr("x", function (d) { return d.x; })
                .attr("y", function (d) { return d.y; });
        });
    }

    function temporaryFadeAllExcept(nodeId) {
        var nodes = d3.selectAll(".node:not(#" + nodeId + ")");
        var labels = d3.selectAll(".label:not([data-for-node='" + nodeId + "'])");
        var links = d3.selectAll(".link");

        nodes.style("opacity", "0");
        labels.style("opacity", "0");
        links.style("opacity", "0");

        d3.selectAll(".node, .link, .label")
            .transition()
            .duration(2000)
            .style("opacity", 1);
    }

    flow.component.graph = {
        temporaryFadeAllExcept: temporaryFadeAllExcept
    };

}(flow, jQuery, d3));<|endoftext|>


<commit_before>/*
 * Copyright (c) 2010, Duponchel David
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the GraouPack nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL DUPONCHEL DAVID BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

$.namespace("izpack.zip.ZipBuilder");

/**
 * Allow the creation of a zip containing the specified files.
 * A way to use it :
 * window.open("data:application/zip;base64," + zipBuilder.createZIP())
 * This solution has known issues :
 * - It more-or-less works on firefox, unknown on other browsers (IE < 8 doesn't support the data: uri scheme,
 *   IE 8 supports it only for images).
 * - on firefox (last : 3.6), the browser asks to download <random name>.zip.part.
 *
 * @see https://bugzilla.mozilla.org/show_bug.cgi?id=367231
 * @see https://bugzilla.mozilla.org/show_bug.cgi?id=532230
 *
 * An other way to do that is to use flash (yerk)
 * @see http://www.downloadify.info/
 */
izpack.zip.ZipBuilder = function (files) {

	this.files = files;
	/* = [
		{
			name : "readme.txt",
			content : "this is a readme"
		},
		{
			name : "logo.png",
			content : ""
		}
	];
	*/
};

izpack.zip.ZipBuilder.prototype = {
	msdosTime : function (now) {
		var DOSTime, DOSDate;
		// http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html
		// http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html
		// http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html

		DOSTime = now.getHours();
		DOSTime = DOSTime << 6;
		DOSTime = DOSTime | now.getMinutes();
		DOSTime = DOSTime << 5;
		DOSTime = DOSTime | now.getSeconds() / 2;

		DOSDate = now.getFullYear() - 1980;
		DOSDate = DOSDate << 4;
		DOSDate = DOSDate | (now.getMonth() + 1);
		DOSDate = DOSDate << 5;
		DOSDate = DOSDate | now.getDate();

		return 	String.fromCharCode(DOSTime & 0xFF, (DOSTime & 0xFF00) >> 8, DOSDate & 0xFF, (DOSDate & 0xFF00) >> 8);
	},

	intToBytes : function (integer, bytesNb) {
		var mask = 0xFF;
		var offset = 0;
		var res = [];
		for (var i = 0; i < bytesNb; i++) {
			res.push((integer & mask) >> offset);
			mask = mask << 8;
			offset += 8;
		}
		return  String.fromCharCode.apply(String, res);
	},

	/*
	 * local file header signature     4 bytes  (0x04034b50)
	 * version needed to extract       2 bytes
	 * general purpose bit flag        2 bytes
	 * compression method              2 bytes
	 * last mod file time              2 bytes
	 * last mod file date              2 bytes
	 * crc-32                          4 bytes
	 * compressed size                 4 bytes
	 * uncompressed size               4 bytes
	 * file name length                2 bytes
	 * extra field length              2 bytes
	 * file name (variable size)
	 * extra field (variable size)
	 */
	getLocalFileHeader : function (file) {
		var now = new Date();
		var zero = String.fromCharCode(0x0);
		return String.fromCharCode(0x50, 0x4b, 0x03, 0x04) + // magic number, 4 bytes. Here : a zip file :)
			String.fromCharCode(0x0a, 0x0) + // version needed to extract, 2 bytes. Here "Default value" (zip 1.0)
			zero + zero + // general purpose bit flag, 2 bytes. Here : nothing special
			zero + zero + // compression method, 2 bytes. Here : STORE
			this.msdosTime(now) + // last mod file time/date, 2+2 bytes
			this.intToBytes($.crc32(file.content), 4) + // crc-32, 4 bytes
			this.intToBytes(file.content.length, 4) + // compressed-size, 4 bytes (no compression, same as uncompressed)
			this.intToBytes(file.content.length, 4) + // uncompressed-size, 4 bytes
			this.intToBytes(file.name.length, 2) + // file name length, 2 bytes
			zero + zero + // extra field length, 2 bytes
			file.name + // file name, variable size
			""; // extra field, variable size
	},

	/*
	 * central file header signature   4 bytes  (0x02014b50)
	 * version made by                 2 bytes
	 * version needed to extract       2 bytes
	 * general purpose bit flag        2 bytes
	 * compression method              2 bytes
	 * last mod file time              2 bytes
	 * last mod file date              2 bytes
	 * crc-32                          4 bytes
	 * compressed size                 4 bytes
	 * uncompressed size               4 bytes
	 * file name length                2 bytes
	 * extra field length              2 bytes
	 * file comment length             2 bytes
	 * disk number start               2 bytes
	 * internal file attributes        2 bytes
	 * external file attributes        4 bytes
	 * relative offset of local header 4 bytes
	 * file name (variable size)
	 * extra field (variable size)
	 * file comment (variable size)
	 */
	getCentralDirectoryFileHeader : function (file, offsetFromStart) {
		var now = new Date();
		var zero = String.fromCharCode(0x0);
		return String.fromCharCode(0x50, 0x4b, 0x01, 0x02) + // central file header signature, 4bytes
			String.fromCharCode(0x1E, 0x3) + // version made by, 2 bytes. Here : UNIX, zip version 1.0 or above.
			String.fromCharCode(0x0a, 0x0) + // version needed to extract, 2 bytes. Here "Default value" (zip 1.0)
			zero + zero + // general purpose bit flag, 2 bytes. Here : nothing special
			zero + zero + // compression method, 2 bytes. Here : STORE
			this.msdosTime(now) + // last mod file time/date, 2+2 bytes
			this.intToBytes($.crc32(file.content), 4) + // crc-32, 4 bytes
			this.intToBytes(file.content.length, 4) + // compressed-size, 4 bytes (no compression, same as uncompressed)
			this.intToBytes(file.content.length, 4) + // uncompressed-size, 4 bytes
			this.intToBytes(file.name.length, 2) + // file name length, 2 bytes
			zero + zero + // extra field length, 2 bytes
			zero + zero + // file comment length, 2 bytes
			zero + zero + // disk number start, 2 bytes
			zero + zero + // internal file attributes, 2 bytes
			zero + zero + zero + zero + // external file attributes, 4 bytes
			this.intToBytes(offsetFromStart, 4) + // relative offset of the local header, 4 bytes
			file.name + // file name, variable size
			"" + // extra field, variable size
			""; // file comment, variable size
	},

	/*
	 * end of central dir signature    4 bytes  (0x06054b50)
	 * number of this disk             2 bytes
	 * number of the disk with the
	 * start of the central directory  2 bytes
	 * total number of entries in the
	 * central directory on this disk  2 bytes
	 * total number of entries in
	 * the central directory           2 bytes
	 * size of the central directory   4 bytes
	 * offset of start of central
	 * directory with respect to
	 * the starting disk number        4 bytes
	 * .ZIP file comment length        2 bytes
	 * .ZIP file comment       (variable size)
	 */
	getEndOfCentralDirectory : function (files, centralDirectoryStart, centralDirectoryEnd) {
		var zipComment = "Created by GraouPack";
		return String.fromCharCode(0x50, 0x4b, 0x05, 0x06) + // end of central dir signature, 4 bytes
			this.intToBytes(0, 2) + // number of this disk, 2 bytes
			this.intToBytes(0, 2) + // number of the disk with the start of the central directory, 2 bytes
			this.intToBytes(files.length, 2) + // total number of entries in the central directory on this disk, 2 bytes
			this.intToBytes(files.length, 2) + // total number of entries in the central directory, 2 bytes
			this.intToBytes(centralDirectoryEnd - centralDirectoryStart, 4) + // size of the central directory, 4 bytes
			this.intToBytes(centralDirectoryStart, 4) + // offset of start of central directory with respect to the starting disk number, 4 bytes
			this.intToBytes(zipComment.length, 2) + // zip file comment length, 2 bytes
			zipComment; // zip file comment, variable size
	},

	createZIP : function () {
		var i, file;
		var zip = ""; // yes, a bunch of bits in a string. It works and the base64 function needs a string...
		var centralDirectoryStart = 0;
		var centralDirectoryEnd = 0;
		for (i = 0; i < this.files.length; i++) {
			// write the header + content
			file = this.files[i];
			var header = this.getLocalFileHeader(file);
			zip += header;
			zip += file.content;
			file.sizeLocalFile = header.length + file.content.length;
			centralDirectoryStart += file.sizeLocalFile;
		}
		var currentOffsetFromStart = 0;
		centralDirectoryEnd = centralDirectoryStart;
		for (i = 0; i < this.files.length; i++) {
			// write the header for central directory
			file = this.files[i];
			var directoryHeader = this.getCentralDirectoryFileHeader(file, currentOffsetFromStart);
			zip += directoryHeader;
			centralDirectoryEnd += directoryHeader.length;
			currentOffsetFromStart += file.sizeLocalFile;
		}
		// end of central directory record
		zip += this.getEndOfCentralDirectory(files, centralDirectoryStart, centralDirectoryEnd);
		return $.base64.encode(zip);
	}
};
<commit_msg>now handle folders, and declare an unknown os version (unzip will now apply default settings)<commit_after>/*
 * Copyright (c) 2010, Duponchel David
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the GraouPack nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL DUPONCHEL DAVID BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

$.namespace("izpack.zip.ZipBuilder");

/**
 * Allow the creation of a zip containing the specified files.
 * @param {Array} files The files to put in the zip
 * @param {String} rootFolder The root folder, which will contains all files.
 *
 * each file have a name and a content. Example :
 * files = [
 * 	{ name : "readme.txt", content : "this is a readme" },
 * 	{ name : "img/logo.png", content : "" }
 * ];
 *
 * A way to use it :
 * window.open("data:application/zip;base64," + zipBuilder.createZIP())
 * This solution has known issues :
 * - It more-or-less works on firefox, unknown on other browsers (IE < 8 doesn't support the data: uri scheme,
 *   IE 8 supports it only for images).
 * - on firefox (last : 3.6), the browser asks to download <random name>.zip.part.
 *
 * @see https://bugzilla.mozilla.org/show_bug.cgi?id=367231
 * @see https://bugzilla.mozilla.org/show_bug.cgi?id=532230
 *
 * An other way to do that is to use flash (yerk)
 * @see http://www.downloadify.info/
 */
izpack.zip.ZipBuilder = function (files, rootFolder) {

	for (var i = 0; i < files.length; i++) {
		var file = files[i];
		file.name = rootFolder + "/" + file.name;
	}
	this.files = this.getFilesAndFolders(files);

	this.rootFolder = rootFolder;

	this.createdSubFolders = [];
};

izpack.zip.ZipBuilder.prototype = {
	msdosTime : function (now) {
		var DOSTime, DOSDate;
		// http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html
		// http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html
		// http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html

		DOSTime = now.getHours();
		DOSTime = DOSTime << 6;
		DOSTime = DOSTime | now.getMinutes();
		DOSTime = DOSTime << 5;
		DOSTime = DOSTime | now.getSeconds() / 2;

		DOSDate = now.getFullYear() - 1980;
		DOSDate = DOSDate << 4;
		DOSDate = DOSDate | (now.getMonth() + 1);
		DOSDate = DOSDate << 5;
		DOSDate = DOSDate | now.getDate();

		return 	String.fromCharCode(DOSTime & 0xFF, (DOSTime & 0xFF00) >> 8, DOSDate & 0xFF, (DOSDate & 0xFF00) >> 8);
	},

	getFilesAndFolders : function (files) {
		var filesAndFolders	= [];
		var createdFolders 	= [];
		var foldersRegex 	= /[^\/]+\//g;
		for (var i = 0; i < files.length; i++) {
			var file = files[i];
			var subFolders = file.name.match(foldersRegex);
			if (subFolders) {
				// create folders, if not already done
				var path = "";
				for (var folderIndex = 0; folderIndex < subFolders.length; folderIndex++) {
					path += subFolders[folderIndex];
					if ($.inArray(path, createdFolders) === -1) { // doesn't exist
						filesAndFolders.push({
							name : path,
							content : ""
						});
						createdFolders.push(path);
					}
				}
			}
			filesAndFolders.push(file);
		}
		return filesAndFolders;
	},

	intToBytes : function (integer, bytesNb) {
		var mask = 0xFF;
		var offset = 0;
		var res = [];
		for (var i = 0; i < bytesNb; i++) {
			res.push((integer & mask) >> offset);
			mask = mask << 8;
			offset += 8;
		}
		return  String.fromCharCode.apply(String, res);
	},

	/*
	 * local file header signature     4 bytes  (0x04034b50)
	 * version needed to extract       2 bytes
	 * general purpose bit flag        2 bytes
	 * compression method              2 bytes
	 * last mod file time              2 bytes
	 * last mod file date              2 bytes
	 * crc-32                          4 bytes
	 * compressed size                 4 bytes
	 * uncompressed size               4 bytes
	 * file name length                2 bytes
	 * extra field length              2 bytes
	 * file name (variable size)
	 * extra field (variable size)
	 */
	getLocalFileHeader : function (file) {
		var now = new Date();
		var zero = String.fromCharCode(0x0);
		return String.fromCharCode(0x50, 0x4b, 0x03, 0x04) + // magic number, 4 bytes. Here : a zip file :)
			String.fromCharCode(0x0a, 0x0) + // version needed to extract, 2 bytes. Here "Default value" (zip 1.0)
			zero + zero + // general purpose bit flag, 2 bytes. Here : nothing special
			zero + zero + // compression method, 2 bytes. Here : STORE
			this.msdosTime(now) + // last mod file time/date, 2+2 bytes
			this.intToBytes($.crc32(file.content), 4) + // crc-32, 4 bytes
			this.intToBytes(file.content.length, 4) + // compressed-size, 4 bytes (no compression, same as uncompressed)
			this.intToBytes(file.content.length, 4) + // uncompressed-size, 4 bytes
			this.intToBytes(file.name.length, 2) + // file name length, 2 bytes
			zero + zero + // extra field length, 2 bytes
			file.name + // file name, variable size
			""; // extra field, variable size
	},

	/*
	 * central file header signature   4 bytes  (0x02014b50)
	 * version made by                 2 bytes
	 * version needed to extract       2 bytes
	 * general purpose bit flag        2 bytes
	 * compression method              2 bytes
	 * last mod file time              2 bytes
	 * last mod file date              2 bytes
	 * crc-32                          4 bytes
	 * compressed size                 4 bytes
	 * uncompressed size               4 bytes
	 * file name length                2 bytes
	 * extra field length              2 bytes
	 * file comment length             2 bytes
	 * disk number start               2 bytes
	 * internal file attributes        2 bytes
	 * external file attributes        4 bytes
	 * relative offset of local header 4 bytes
	 * file name (variable size)
	 * extra field (variable size)
	 * file comment (variable size)
	 */
	getCentralDirectoryFileHeader : function (file, offsetFromStart) {
		var now = new Date();
		var zero = String.fromCharCode(0x0);
		return String.fromCharCode(0x50, 0x4b, 0x01, 0x02) + // central file header signature, 4bytes
			String.fromCharCode(0x14, 0xFF) + // version made by, 2 bytes. 'Javascript VM' doesn't exist, so 0xFF, zip version 2.0 or above.
			String.fromCharCode(0x0a, 0x0) + // version needed to extract, 2 bytes. Here "Default value" (zip 1.0)
			zero + zero + // general purpose bit flag, 2 bytes. Here : nothing special
			zero + zero + // compression method, 2 bytes. Here : STORE
			this.msdosTime(now) + // last mod file time/date, 2+2 bytes
			this.intToBytes($.crc32(file.content), 4) + // crc-32, 4 bytes
			this.intToBytes(file.content.length, 4) + // compressed-size, 4 bytes (no compression, same as uncompressed)
			this.intToBytes(file.content.length, 4) + // uncompressed-size, 4 bytes
			this.intToBytes(file.name.length, 2) + // file name length, 2 bytes
			zero + zero + // extra field length, 2 bytes
			zero + zero + // file comment length, 2 bytes
			zero + zero + // disk number start, 2 bytes
			zero + zero + // internal file attributes, 2 bytes
			zero + zero + zero + zero + // external file attributes, 4 bytes
			this.intToBytes(offsetFromStart, 4) + // relative offset of the local header, 4 bytes
			file.name + // file name, variable size
			"" + // extra field, variable size
			""; // file comment, variable size
	},

	/*
	 * end of central dir signature    4 bytes  (0x06054b50)
	 * number of this disk             2 bytes
	 * number of the disk with the
	 * start of the central directory  2 bytes
	 * total number of entries in the
	 * central directory on this disk  2 bytes
	 * total number of entries in
	 * the central directory           2 bytes
	 * size of the central directory   4 bytes
	 * offset of start of central
	 * directory with respect to
	 * the starting disk number        4 bytes
	 * .ZIP file comment length        2 bytes
	 * .ZIP file comment       (variable size)
	 */
	getEndOfCentralDirectory : function (files, centralDirectoryStart, centralDirectoryEnd) {
		var zipComment = "Created by GraouPack";
		return String.fromCharCode(0x50, 0x4b, 0x05, 0x06) + // end of central dir signature, 4 bytes
			this.intToBytes(0, 2) + // number of this disk, 2 bytes
			this.intToBytes(0, 2) + // number of the disk with the start of the central directory, 2 bytes
			this.intToBytes(files.length, 2) + // total number of entries in the central directory on this disk, 2 bytes
			this.intToBytes(files.length, 2) + // total number of entries in the central directory, 2 bytes
			this.intToBytes(centralDirectoryEnd - centralDirectoryStart, 4) + // size of the central directory, 4 bytes
			this.intToBytes(centralDirectoryStart, 4) + // offset of start of central directory with respect to the starting disk number, 4 bytes
			this.intToBytes(zipComment.length, 2) + // zip file comment length, 2 bytes
			zipComment; // zip file comment, variable size
	},

	createZIP : function () {
		var i, file;
		var zip = ""; // yes, a bunch of bits in a string. It works and the base64 function needs a string...

		var centralDirectoryStart = 0;
		var centralDirectoryEnd = 0;
		for (i = 0; i < this.files.length; i++) {
			// write the header + content
			file = this.files[i];
			var header = this.getLocalFileHeader(file);
			zip += header;
			zip += file.content;
			file.sizeLocalFile = header.length + file.content.length;
			centralDirectoryStart += file.sizeLocalFile;
		}
		var currentOffsetFromStart = 0;
		centralDirectoryEnd = centralDirectoryStart;
		for (i = 0; i < this.files.length; i++) {
			// write the header for central directory
			file = this.files[i];
			var directoryHeader = this.getCentralDirectoryFileHeader(file, currentOffsetFromStart);
			zip += directoryHeader;
			centralDirectoryEnd += directoryHeader.length;
			currentOffsetFromStart += file.sizeLocalFile;
		}
		// end of central directory record
		zip += this.getEndOfCentralDirectory(this.files, centralDirectoryStart, centralDirectoryEnd);
		return $.base64.encode(zip);
	}
};
<|endoftext|>


<commit_before>/**
 * source.js
 * Andrea Tino - 2015
 */

/**
 * Extracts parts from the source code basing on line number and column number.
 * This module implements interface [SourceBrowser].
 * _src: [string] - Source code to provide
 */
module.exports = function(_src) {
  var astUtils = require('./JSParser/mozillaAstUtils.js');

  var validateSrc = function(src) {
    if (!src || src.lenght <= 0) {
      throw 'Error: src cannot be null, undefined or an empty string!';
    }
    return src;
  };

  // Converts to array for each
  var processSrc = function(src) {
    return src.replace(/\n\r/g, '\n').split('\n');
  };

  var src = processSrc(validateSrc(_src)); // [string*] Array of lines
  var locationUtils = astUtils();

  // Private functions
  var extract = function(str, s, e) {
    return str.substring(s, e);
  };

  return {
    /**
     * Extracts source code at provided line number and col number.
     * loc: [ASTNodeLocation]
     * return: [string]
     */
    at: function(loc) {
      if (!locationUtils.isValidLocation(loc)) {
        throw 'Error: ' + JSON.stringify(loc) + ' is not a valid location!';
      }

      var lines = [];
      for (var r = loc.rowStart; r <= loc.rowEnd; r++) {
        lines.push(src[r]);
      }

      if (lines.length === 1) {
        return extract(lines[0], loc.colStart, loc.colEnd);
      }

      // Spanning more lines
      lines[0] = extract(lines[0], loc.colStart, lines[0].length - 1);
      lines[lines.length - 1] = extract(lines[lines.length - 1], 0, loc.colEnd);

      var singleLine = '';
      for (var l in lines) {
        //singleLine += lines[l] + (l === lines.length - 1 ? '' : '\n');
        singleLine += lines[l];
      }
      return singleLine;
    },

    /**
     * Gets a line.
     * l: Line number.
     */
    line: function(l) {
      if (!l || typeof l !== 'number') {
        throw 'Error: Line must be a number!';
      }
      return src[l];
    }
  };
};
<commit_msg>Adjusted newline token handling<commit_after>/**
 * source.js
 * Andrea Tino - 2015
 */

/**
 * Extracts parts from the source code basing on line number and column number.
 * This module implements interface [SourceBrowser].
 * _src: [string] - Source code to provide
 */
module.exports = function(_src) {
  var astUtils = require('./JSParser/mozillaAstUtils.js');

  /**
   * This constant is extremely important because of the source handling process.
   * The source might span more lines. In order to identify lines, we need to do this:
   * 1. Split by this character.
   * 2. Work on the array of lines.
   * 3. When returning an excerpt, we combine lines with this character.
   */
  var NEWLINE_TOKEN = '\\n';

  var validateSrc = function(src) {
    if (!src || src.lenght <= 0) {
      throw 'Error: src cannot be null, undefined or an empty string!';
    }
    return src;
  };

  // Converts to array for each
  var processSrc = function(src) {
    // In different platforms we can have the following options for newline characters:
    // 1. \n\r
    // 2. \n
    // We replace all of them with the last, so we are sure that we locate all lines.
    return src.replace(/\n\r/g, NEWLINE_TOKEN).split(NEWLINE_TOKEN);
  };

  var src = processSrc(validateSrc(_src)); // [string*] Array of lines
  var locationUtils = astUtils();

  // Private functions
  var extract = function(str, s, e) {
    return str.substring(s, e);
  };

  return {
    /**
     * Extracts source code at provided line number and col number.
     * loc: [ASTNodeLocation]
     * return: [string]
     */
    at: function(loc) {
      if (!locationUtils.isValidLocation(loc)) {
        throw 'Error: ' + JSON.stringify(loc) + ' is not a valid location!';
      }

      var lines = [];
      for (var r = loc.rowStart; r <= loc.rowEnd; r++) {
        lines.push(src[r]);
      }

      if (lines.length === 1) {
        return extract(lines[0], loc.colStart, loc.colEnd);
      }

      // Spanning more lines
      lines[0] = extract(lines[0], loc.colStart, lines[0].length - 1);
      lines[lines.length - 1] = extract(lines[lines.length - 1], 0, loc.colEnd);

      var singleLine = '';
      for (var l in lines) {
        singleLine += lines[l] + (l === lines.length - 1 ? '' : NEWLINE_TOKEN);
        singleLine += lines[l];
      }
      return singleLine;
    },

    /**
     * Gets a line.
     * l: Line number.
     */
    line: function(l) {
      if (!l || typeof l !== 'number') {
        throw 'Error: Line must be a number!';
      }
      return src[l];
    }
  };
};
<|endoftext|>


<commit_before>import app from '../app';
import { getOpenModals } from '../views/modals/BaseModal';
import Listing from '../models/listing/Listing';
import About from '../views/modals/about/About';
import EditListing from '../views/modals/editListing/EditListing';
import DebugLog from '../views/modals/DebugLog';
import ModeratorDetails from '../views/modals/moderatorDetails';
import Wallet from '../views/modals/wallet/Wallet';
import Settings from '../views/modals/Settings/Settings';

let aboutModal;
let settingsModal;
let debugLogModal;
let moderatorDetailsModal;
let _wallet;

export function launchEditListingModal(modalOptions = {}) {
  const model = modalOptions.model;
  const openModals = getOpenModals();

  if (!(model instanceof Listing)) {
    throw new Error('In the modalOptions, please provide an instance of ' +
      'a Listing model.');
  }

  if (model.isNew()) {
    const createModal = openModals
      .find(modal => modal instanceof EditListing && modal.model.isNew());
    if (createModal) {
      createModal.bringToTop();
      return createModal;
    }
  }

  const editListingModal = new EditListing(modalOptions);
  // use a timeout to prevent the editModal from being undefined when the view listing
  // function is set due to the override of the open method
  setTimeout(() => {
    editListingModal.render().open();
  });

  return editListingModal;
}

export function launchAboutModal(modalOptions = {}) {
  if (aboutModal) {
    aboutModal.bringToTop();
    if (modalOptions.initialTab) aboutModal.selectTab(modalOptions.initialTab);
  } else {
    aboutModal = new About({
      removeOnClose: true,
      ...modalOptions,
    })
      .render()
      .open();

    aboutModal.on('modal-will-remove', () => (aboutModal = null));
  }

  return aboutModal;
}

export function launchSettingsModal(modalOptions = {}) {
  if (settingsModal) {
    settingsModal.bringToTop();
  } else {
    settingsModal = new Settings({
      removeOnClose: true,
      ...modalOptions,
    })
      .render()
      .open();

    settingsModal.on('modal-will-remove', () => (settingsModal = null));
  }

  return settingsModal;
}

export function launchDebugLogModal(modalOptions = {}) {
  if (debugLogModal) debugLogModal.remove();

  debugLogModal = new DebugLog(modalOptions)
    .render()
    .open();

  return debugLogModal;
}

export function launchModeratorDetailsModal(modalOptions = {}) {
  if (moderatorDetailsModal) moderatorDetailsModal.remove();

  moderatorDetailsModal = new ModeratorDetails(modalOptions)
      .render()
      .open();

  return moderatorDetailsModal;
}

export function launchWallet(modalOptions = {}) {
  if (_wallet) {
    _wallet.open();
  } else {
    _wallet = new Wallet({
      removeOnRoute: false,
      ...modalOptions,
    })
      .render()
      .open();

    app.router.on('will-route', () => _wallet.close());
  }

  return _wallet;
}

export function getWallet() {
  return _wallet;
}
<commit_msg>adjust spacing<commit_after>import app from '../app';
import { getOpenModals } from '../views/modals/BaseModal';
import Listing from '../models/listing/Listing';
import About from '../views/modals/about/About';
import EditListing from '../views/modals/editListing/EditListing';
import DebugLog from '../views/modals/DebugLog';
import ModeratorDetails from '../views/modals/moderatorDetails';
import Wallet from '../views/modals/wallet/Wallet';
import Settings from '../views/modals/Settings/Settings';

let aboutModal;
let settingsModal;
let debugLogModal;
let moderatorDetailsModal;
let _wallet;

export function launchEditListingModal(modalOptions = {}) {
  const model = modalOptions.model;
  const openModals = getOpenModals();

  if (!(model instanceof Listing)) {
    throw new Error('In the modalOptions, please provide an instance of ' +
      'a Listing model.');
  }

  if (model.isNew()) {
    const createModal = openModals
      .find(modal => modal instanceof EditListing && modal.model.isNew());
    if (createModal) {
      createModal.bringToTop();
      return createModal;
    }
  }

  const editListingModal = new EditListing(modalOptions);
  // use a timeout to prevent the editModal from being undefined when the view listing
  // function is set due to the override of the open method
  setTimeout(() => {
    editListingModal.render()
      .open();
  });

  return editListingModal;
}

export function launchAboutModal(modalOptions = {}) {
  if (aboutModal) {
    aboutModal.bringToTop();
    if (modalOptions.initialTab) aboutModal.selectTab(modalOptions.initialTab);
  } else {
    aboutModal = new About({
      removeOnClose: true,
      ...modalOptions,
    })
      .render()
      .open();

    aboutModal.on('modal-will-remove', () => (aboutModal = null));
  }

  return aboutModal;
}

export function launchSettingsModal(modalOptions = {}) {
  if (settingsModal) {
    settingsModal.bringToTop();
  } else {
    settingsModal = new Settings({
      removeOnClose: true,
      ...modalOptions,
    })
      .render()
      .open();

    settingsModal.on('modal-will-remove', () => (settingsModal = null));
  }

  return settingsModal;
}

export function launchDebugLogModal(modalOptions = {}) {
  if (debugLogModal) debugLogModal.remove();

  debugLogModal = new DebugLog(modalOptions)
    .render()
    .open();

  return debugLogModal;
}

export function launchModeratorDetailsModal(modalOptions = {}) {
  if (moderatorDetailsModal) moderatorDetailsModal.remove();

  moderatorDetailsModal = new ModeratorDetails(modalOptions)
      .render()
      .open();

  return moderatorDetailsModal;
}

export function launchWallet(modalOptions = {}) {
  if (_wallet) {
    _wallet.open();
  } else {
    _wallet = new Wallet({
      removeOnRoute: false,
      ...modalOptions,
    })
      .render()
      .open();

    app.router.on('will-route', () => _wallet.close());
  }

  return _wallet;
}

export function getWallet() {
  return _wallet;
}
<|endoftext|>


<commit_before>
var path = require('path');
var fs = require('fs');
var readFileSync = fs.readFileSync;

var consoleModulePath = require.resolve('ti-console/src/ti-console');

var processModulePath = require.resolve('./process');

var globalModulePath = require.resolve('./global');

function fromPath(modulepath, extra) {
  return function () {
    return 'require(' + JSON.stringify(modulepath) + ')' + (extra ? '.' + extra : '');
  };
}

module.exports = {

  console: fromPath(consoleModulePath),

  process: fromPath(processModulePath),

  global: fromPath(globalModulePath),

  Buffer: fromPath('buffer', 'Buffer'),

  __filename: function (row, basedir) {
    var file = '/' + path.relative(basedir, row.id);
    return JSON.stringify(file);
  },

  __dirname: function (row, basedir) {
    var dir = path.dirname('/' + path.relative(basedir, row.id));
    return JSON.stringify(dir);
  }

};
<commit_msg>Actual transforms for globals<commit_after>
var path = require('path');
var fs = require('fs');
var readFileSync = fs.readFileSync;

var consoleModulePath = require.resolve('ti-console/src/ti-console');

var processModulePath = require.resolve('./process');

var globalModulePath = require.resolve('./global');

function fromPath(modulepath, extra) {
  return function () {
    return 'require(' + JSON.stringify(modulepath) + ')' + (extra ? '.' + extra : '');
  };
}

module.exports = {

  console: fromPath(consoleModulePath),

  process: fromPath(processModulePath),

  global: fromPath(globalModulePath),

  Buffer: fromPath('buffer', 'Buffer'),

  __filename: function (filepath, basedir) {
    var file = '/' + path.relative(basedir, filepath);
    return JSON.stringify(file);
  },

  __dirname: function (filepath, basedir) {
    var dir = path.dirname('/' + path.relative(basedir, filepath));
    return JSON.stringify(dir);
  }

};
<|endoftext|>


<commit_before>/**
 * Created by synder on 16/5/31.
 */

exports.date = function (date, dateJoin) {

    if(date.constructor !== Date){
        if(typeof date == 'string'){
            date = Date.parse(date);
        }
    }

    if(!date){
        return '';
    }

    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    var day = date.getDate();

    month = month < 10 ? '0' + month : month;
    day = day < 10 ? '0' + day : day;

    if (!dateJoin) {
        return year + '年' + month + '月' + day + '日';
    } else {
        return year + dateJoin + month + dateJoin + day;
    }
};

exports.time = function (date, timeJoin) {
    if(date.constructor !== Date){
        if(typeof date == 'string'){
            date = Date.parse(date);
        }
    }

    if(!date){
        return '';
    }

    var hour = date.getHours();
    var minute = date.getMinutes();
    var second = date.getSeconds() + 1;

    hour = hour < 10 ? '0' + hour : hour;
    minute = minute < 10 ? '0' + minute : minute;
    second = second < 10 ? '0' + second : second;

    if (!timeJoin) {
        return hour + '时' + minute + '分' + second + '秒';
    } else {
        return hour + timeJoin + minute + timeJoin + second;
    }
};

exports.dateTime = function (date, dateJoin, timeJoin) {
    if(date.constructor !== Date){
        if(typeof date == 'string'){
            date = Date.parse(date);
        }
    }

    if(!date){
        return '';
    }

    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    var day = date.getDate();
    var hour = date.getHours();
    var minute = date.getMinutes();
    var second = date.getSeconds() + 1;

    month = month < 10 ? '0' + month : month;
    day = day < 10 ? '0' + day : day;
    hour = hour < 10 ? '0' + hour : hour;
    minute = minute < 10 ? '0' + minute : minute;
    second = second < 10 ? '0' + second : second;

    var dateTemp = '';
    if (!dateJoin) {
        dateTemp = year + '年' + month + '月' + day + '日';
    } else {
        dateTemp = year + dateJoin + month + dateJoin + day;
    }

    var timeTemp = '';
    if (!timeJoin) {
        timeTemp = hour + '时' + minute + '分' + second + '秒';
    } else {
        timeTemp = hour + timeJoin + minute + timeJoin + second;
    }

    return dateTemp + ' ' + timeTemp;
};

exports.format = function format(fmt) {
    var argIndex = 1,
        args = [].slice.call(arguments),
        i = 0,
        n = fmt.length,
        result = '',
        c,
        escaped = false,
        arg,
        tmp,
        leadingZero = false,
        precision,
        nextArg = function() { return args[argIndex++]; },
        slurpNumber = function() {
            var digits = '';
            var temp = fmt.charCodeAt(i);
            while ( temp > 47 && temp < 58) {
                digits += fmt[i++];
                c = fmt[i];
            }
            return digits.length > 0 ? parseInt(digits) : null;
        };

    for (; i < n; ++i) {
        c = fmt[i];
        if (escaped) {
            escaped = false;
            if (c == '.') {
                leadingZero = false;
                c = fmt[++i];
            }
            else if (c == '0' && fmt[i + 1] == '.') {
                leadingZero = true;
                i += 2;
                c = fmt[i];
            }
            else {
                leadingZero = true;
            }
            precision = slurpNumber();
            switch (c) {
                case 'b': // number in binary
                    result += parseInt(nextArg(), 10).toString(2);
                    break;
                case 'c': // character
                    arg = nextArg();
                    if (typeof arg === 'string' || arg instanceof String)
                        result += arg;
                    else
                        result += String.fromCharCode(parseInt(arg, 10));
                    break;
                case 'd': // number in decimal
                    result += parseInt(nextArg(), 10);
                    break;
                case 'f': // floating point number
                    tmp = String(parseFloat(nextArg()).toFixed(precision || 6));
                    result += leadingZero ? tmp : tmp.replace(/^0/, '');
                    break;
                case 'j': // JSON
                    result += JSON.stringify(nextArg());
                    break;
                case 'o': // number in octal
                    result += '0' + parseInt(nextArg(), 10).toString(8);
                    break;
                case 's': // string
                    result += nextArg();
                    break;
                case 'x': // lowercase hexadecimal
                    result += '0x' + parseInt(nextArg(), 10).toString(16);
                    break;
                case 'X': // uppercase hexadecimal
                    result += '0x' + parseInt(nextArg(), 10).toString(16).toUpperCase();
                    break;
                default:
                    result += c;
                    break;
            }
        } else if (c === '%') {
            escaped = true;
        } else {
            result += c;
        }
    }
    return result;
};

exports.pad = function pad(str, length, padStr, direction) {
    str = (str == null) ? '' : str + '';

    length = ~~length;

    var padLen = 0;

    if (!padStr){
        padStr = ' ';
    } else if (padStr.length > 1){
        padStr = padStr.charAt(0);
    }

    var strRepeat = function (str, times) {
        if (times < 1) return '';
        var result = '';
        while (times > 0) {
            if (times & 1) {
                result += str;
            }
            times >>= 1;
            str += str;
        }
        return result;
    };

    switch (direction) {
        case 'right':
            padLen = length - str.length;
            return str + strRepeat(padStr, padLen);
        case 'both':
            padLen = length - str.length;
            return strRepeat(padStr, Math.ceil(padLen / 2)) + str + strRepeat(padStr, Math.floor(padLen / 2));
        default:
            padLen = length - str.length;
            return strRepeat(padStr, padLen) + str;
    }
};

exports.unit = function (str, unit, defaults) {
    if(!str){
        return defaults ? defaults : '';
    }else{
        return str + '' + unit;
    }
};

exports.mask = function (str, mask, start, len) {

    if(!str){
        return '';
    }else{
        str = str + '';
    }

    if(!mask){
        return '';
    }else{
        mask = mask + '';
    }

    var res = '';
    var end = 0;

    if(start < 0){
        end = start + str.length;
        start = end < len ? 0 : end - len;
    }else{
        start = start - 1;
        end = start + len - 1;
    }

    for(var i = 0; i < str.length; i++){
        if(i < start || i > end){
            res += str[i];
        }else{
            res += mask;
        }
    }

    return res;
};

exports.join = function () {
    if (arguments.length === 0) {
        return '';
    }

    if (arguments.length === 1) {
        return (arguments[0] == null) ? '' : arguments[0] + '';
    }

    var joiner = arguments[arguments.length - 1];

    var temp = [];

    for (var i = 0, len = arguments.length - 1; i < len; i++) {

        arguments[i] = (arguments[i] == null) ? '' : arguments[i] + '';

        if(!arguments[i]){
            continue;
        }

        temp.push(arguments[i]);
    }

    return temp.join(joiner);
};

exports.trim = function (str) {
    str = (str == null) ? '' : str + '';
    return str.trim();
};

exports.quote = function (str, quoteChar) {
    quoteChar = quoteChar || '"';
    return [quoteChar, str, quoteChar].join('');
};

exports.clean = function (str) {
    str = (str == null) ? '' : str + '';
    return str.trim().replace(/\s\s+/g, ' ');
};

exports.lines = function (str) {
    str = (str == null) ? '' : str + '';

    if (!str) {
        return [];
    }

    return str.split(/\r\n?/);
};

exports.splicing = function (str, ext) {
    str = (str == null) ? '' : str + '';

    if(!str){
        return '';
    }

    return str + ext;
};

exports.signed = function (number) {
    number = parseFloat(number);

    if(number > 0){
        return '+' + number;
    }else if(number < 0){
        return '-' + number;
    }else{
        return number + '';
    }
};

exports.stringify = function (content) {
    if(content == null){
        return '';
    }

    if(content.constructor === Date){
        return content + '';
    }

    if(content.constructor === RegExp){
        return content + '';
    }

    if(Array.isArray(content)){
        return '[' + content.join(',') + ']';
    }

    if(typeof content === 'object'){
        return JSON.stringify(content);
    }

    return content + '';
};

exports.truncate = function (str, length, ellipsis) {
    str = (str == null) ? '' : str + '';
    ellipsis = (ellipsis == null) ? '' : ellipsis + '';

    var res = str.slice(0, length - ellipsis.length);
    if (ellipsis) {
        res += ellipsis;
    }
    return res;
};

exports.capitalize = function (str, lowercaseRest) {
    str = (str == null) ? '' : str + '';
    var remainingChars = !lowercaseRest ? str.slice(1) : str.slice(1).toLowerCase();
    return str.charAt(0).toUpperCase() + remainingChars;
};

exports.upperCase = function (str) {
    str = (str == null) ? '' : str + '';
    return str.toUpperCase();
};

exports.lowerCase = function (str) {
    str = (str == null) ? '' : str + '';
    return str.toLowerCase();
};

exports.currency = function (money, unit, n) {
    n = n || 2;
    unit = unit || '';
    money = parseFloat(money) || 0;
    money = money.toFixed(n);
    money = money + '';

    var temp = money.split('.');
    var decimal = temp.length > 1 ? temp[1] : '';
    var integer = temp[0];
    var result = '';

    while (integer.length > 3) {
        result = ',' + integer.slice(-3) + result;
        integer = integer.slice(0, integer.length - 3);
    }
    if (integer) {
        result = integer + result;
    }

    if (decimal) {
        result = result + '.' + decimal;
    }

    return unit + result;
};

exports.chineseCurrency = function (money) {

    var number = String(money);

    number = number.split('.')[0];

    const NUM = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "扒", "玖", "拾"],
        BASE_UNIT = ["", "拾", "佰", "仟"],
        ADVANCE_UNIT = ["", "萬", "亿", "兆"];

    var last = number.length % 4;

    var temp = [];

    for(var i = 0; i < number.length; i++){

        var index = 0;

        if(last > 0){
            index = Math.floor((i + (4 - last)) / 4);
        }else{
            index = Math.floor(i / 4);
        }

        if(!temp[index]){
            temp[index] = [];
        }

        if(index == 0){
            if(temp[index].length == 0){
                if(number[i] != '0'){
                    temp[index].push(NUM[number[i]]);
                }
            }else{
                temp[index].push(NUM[number[i]]);
            }
        }else{
            temp[index].push(NUM[number[i]]);
        }

    }

    var result = '';

    while (temp[0].length == 0){
        temp = temp.slice(1);
    }

    for(var j = 0; j < temp.length; j++){
        for(var k = 0, len = temp[j].length; k < len; k++){
            temp[j][k] = temp[j][k] == NUM[0] ? temp[j][k] : temp[j][k] + BASE_UNIT[len - k - 1];
            if(k == 3 && temp[j][k] == NUM[0]){
                temp[j][k] = '';
            }
        }

        result += temp[j].join('') + ADVANCE_UNIT[temp.length - j - 1];
    }

    result = result.replace(/零{3}萬/g, '');
    result = result.replace(/零{3}亿/g, '');
    result = result.replace(/零{3}兆/g, '');
    result = result.replace(/零{1,2}萬/g, '萬');
    result = result.replace(/零{1,2}亿/g, '亿');
    result = result.replace(/零{1,2}兆/g, '兆');
    result = result.replace(/零+/g, '零');
    result = result.replace(/零$/g, '');

    return result;
};

exports.thousands = function (money, n) {

    money = parseFloat(money) || 0;

    if(n){
        money = money.toFixed(n);
    }

    money = money + '';

    var temp = money.split('.');
    var decimal = temp.length > 1 ? temp[1] : '';
    var integer = temp[0];
    var result = '';

    while (integer.length > 3) {
        result = ',' + integer.slice(-3) + result;
        integer = integer.slice(0, integer.length - 3);
    }
    if (integer) {
        result = integer + result;
    }

    if (decimal) {
        result = result + '.' + decimal;
    }

    return result;
};

exports.bankCard = function (card) {

    card = card + '';

    var result = '';

    while (card.length > 4) {
        result = result + card.slice(0, 4) + ' ';
        card = card.substr(4);
    }

    if (card) {
        result += card;
    }

    return result;
};

exports.percentage = function (number, n) {

    if (typeof number !== 'number') {
        number = parseFloat(number) || 0;
    }

    number = number * 100;

    if (n) {
        number = number.toFixed(n);
    }

    return number + '%';
};

exports.number = function (number, fraction) {

    if(fraction == null){
        return number;
    }

    fraction = parseInt(fraction) || 0;

    if (typeof number !== 'number') {
        number = parseFloat(number) || 0;
    }

    return number.toFixed(fraction);
};
<commit_msg>add auto gen doc<commit_after>/**
 * Created by synder on 16/5/31.
 */

exports.date = function (date, dateJoin) {

    if(date.constructor !== Date){
        if(typeof date == 'string'){
            date = Date.parse(date);
        }
    }

    if(!date){
        return '';
    }

    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    var day = date.getDate();

    month = month < 10 ? '0' + month : month;
    day = day < 10 ? '0' + day : day;

    if (!dateJoin) {
        return year + '年' + month + '月' + day + '日';
    } else {
        return year + dateJoin + month + dateJoin + day;
    }
};

exports.time = function (date, timeJoin) {
    if(date.constructor !== Date){
        if(typeof date == 'string'){
            date = Date.parse(date);
        }
    }

    if(!date){
        return '';
    }

    var hour = date.getHours();
    var minute = date.getMinutes();
    var second = date.getSeconds() + 1;

    hour = hour < 10 ? '0' + hour : hour;
    minute = minute < 10 ? '0' + minute : minute;
    second = second < 10 ? '0' + second : second;

    if (!timeJoin) {
        return hour + '时' + minute + '分' + second + '秒';
    } else {
        return hour + timeJoin + minute + timeJoin + second;
    }
};

exports.dateTime = function (date, dateJoin, timeJoin) {
    if(date.constructor !== Date){
        if(typeof date == 'string'){
            date = Date.parse(date);
        }
    }

    if(!date){
        return '';
    }

    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    var day = date.getDate();
    var hour = date.getHours();
    var minute = date.getMinutes();
    var second = date.getSeconds() + 1;

    month = month < 10 ? '0' + month : month;
    day = day < 10 ? '0' + day : day;
    hour = hour < 10 ? '0' + hour : hour;
    minute = minute < 10 ? '0' + minute : minute;
    second = second < 10 ? '0' + second : second;

    var dateTemp = '';
    if (!dateJoin) {
        dateTemp = year + '年' + month + '月' + day + '日';
    } else {
        dateTemp = year + dateJoin + month + dateJoin + day;
    }

    var timeTemp = '';
    if (!timeJoin) {
        timeTemp = hour + '时' + minute + '分' + second + '秒';
    } else {
        timeTemp = hour + timeJoin + minute + timeJoin + second;
    }

    return dateTemp + ' ' + timeTemp;
};

exports.format = function format(fmt) {
    var argIndex = 1,
        args = [].slice.call(arguments),
        i = 0,
        n = fmt.length,
        result = '',
        c,
        escaped = false,
        arg,
        tmp,
        leadingZero = false,
        precision,
        nextArg = function() { return args[argIndex++]; },
        slurpNumber = function() {
            var digits = '';
            var temp = fmt.charCodeAt(i);
            while ( temp > 47 && temp < 58) {
                digits += fmt[i++];
                c = fmt[i];
            }
            return digits.length > 0 ? parseInt(digits) : null;
        };

    for (; i < n; ++i) {
        c = fmt[i];
        if (escaped) {
            escaped = false;
            if (c == '.') {
                leadingZero = false;
                c = fmt[++i];
            }
            else if (c == '0' && fmt[i + 1] == '.') {
                leadingZero = true;
                i += 2;
                c = fmt[i];
            }
            else {
                leadingZero = true;
            }
            precision = slurpNumber();
            switch (c) {
                case 'b': // number in binary
                    result += parseInt(nextArg(), 10).toString(2);
                    break;
                case 'c': // character
                    arg = nextArg();
                    if (typeof arg === 'string' || arg instanceof String)
                        result += arg;
                    else
                        result += String.fromCharCode(parseInt(arg, 10));
                    break;
                case 'd': // number in decimal
                    result += parseInt(nextArg(), 10);
                    break;
                case 'f': // floating point number
                    tmp = String(parseFloat(nextArg()).toFixed(precision || 6));
                    result += leadingZero ? tmp : tmp.replace(/^0/, '');
                    break;
                case 'j': // JSON
                    result += JSON.stringify(nextArg());
                    break;
                case 'o': // number in octal
                    result += '0' + parseInt(nextArg(), 10).toString(8);
                    break;
                case 's': // string
                    result += nextArg();
                    break;
                case 'x': // lowercase hexadecimal
                    result += '0x' + parseInt(nextArg(), 10).toString(16);
                    break;
                case 'X': // uppercase hexadecimal
                    result += '0x' + parseInt(nextArg(), 10).toString(16).toUpperCase();
                    break;
                default:
                    result += c;
                    break;
            }
        } else if (c === '%') {
            escaped = true;
        } else {
            result += c;
        }
    }
    return result;
};

exports.pad = function pad(str, length, padStr, direction) {
    str = (str == null) ? '' : str + '';

    length = ~~length;

    var padLen = 0;

    if (!padStr){
        padStr = ' ';
    } else if (padStr.length > 1){
        padStr = padStr.charAt(0);
    }

    var strRepeat = function (str, times) {
        if (times < 1) return '';
        var result = '';
        while (times > 0) {
            if (times & 1) {
                result += str;
            }
            times >>= 1;
            str += str;
        }
        return result;
    };

    switch (direction) {
        case 'right':
            padLen = length - str.length;
            return str + strRepeat(padStr, padLen);
        case 'both':
            padLen = length - str.length;
            return strRepeat(padStr, Math.ceil(padLen / 2)) + str + strRepeat(padStr, Math.floor(padLen / 2));
        default:
            padLen = length - str.length;
            return strRepeat(padStr, padLen) + str;
    }
};

exports.unit = function (str, unit, defaults) {
    if(!str){
        return defaults ? defaults : '';
    }else{
        return str + '' + unit;
    }
};

exports.mask = function (str, mask, start, len) {

    if(!str){
        return '';
    }else{
        str = str + '';
    }

    if(!mask){
        return '';
    }else{
        mask = mask + '';
    }

    var res = '';
    var end = 0;

    if(start < 0){
        end = start + str.length;
        start = end < len ? 0 : end - len;
    }else{
        start = start - 1;
        end = start + len - 1;
    }

    for(var i = 0; i < str.length; i++){
        if(i < start || i > end){
            res += str[i];
        }else{
            res += mask;
        }
    }

    return res;
};

exports.join = function () {
    if (arguments.length === 0) {
        return '';
    }

    if (arguments.length === 1) {
        return (arguments[0] == null) ? '' : arguments[0] + '';
    }

    var joiner = arguments[arguments.length - 1];

    var temp = [];

    for (var i = 0, len = arguments.length - 1; i < len; i++) {

        arguments[i] = (arguments[i] == null) ? '' : arguments[i] + '';

        if(!arguments[i]){
            continue;
        }

        temp.push(arguments[i]);
    }

    return temp.join(joiner);
};

exports.trim = function (str) {
    str = (str == null) ? '' : str + '';
    return str.trim();
};

exports.quote = function (str, quoteChar) {
    quoteChar = quoteChar || '"';
    return [quoteChar, str, quoteChar].join('');
};

exports.clean = function (str) {
    str = (str == null) ? '' : str + '';
    return str.trim().replace(/\s\s+/g, ' ');
};

exports.lines = function (str) {
    str = (str == null) ? '' : str + '';

    if (!str) {
        return [];
    }

    return str.split(/\r\n?/);
};

exports.splicing = function (str, ext) {
    str = (str == null) ? '' : str + '';

    if(!str){
        return '';
    }

    return str + ext;
};

exports.signed = function (number) {
    number = parseFloat(number);

    if(number > 0){
        return '+' + number;
    }else if(number < 0){
        return '-' + number;
    }else{
        return number + '';
    }
};

exports.stringify = function (content) {
    if(content == null){
        return '';
    }

    if(content.constructor === Date){
        return content + '';
    }

    if(content.constructor === RegExp){
        return content + '';
    }

    if(Array.isArray(content)){
        return '[' + content.join(',') + ']';
    }

    if(typeof content === 'object'){
        return JSON.stringify(content, null, 2);
    }

    return content + '';
};

exports.truncate = function (str, length, ellipsis) {
    str = (str == null) ? '' : str + '';
    ellipsis = (ellipsis == null) ? '' : ellipsis + '';

    var res = str.slice(0, length - ellipsis.length);
    if (ellipsis) {
        res += ellipsis;
    }
    return res;
};

exports.capitalize = function (str, lowercaseRest) {
    str = (str == null) ? '' : str + '';
    var remainingChars = !lowercaseRest ? str.slice(1) : str.slice(1).toLowerCase();
    return str.charAt(0).toUpperCase() + remainingChars;
};

exports.upperCase = function (str) {
    str = (str == null) ? '' : str + '';
    return str.toUpperCase();
};

exports.lowerCase = function (str) {
    str = (str == null) ? '' : str + '';
    return str.toLowerCase();
};

exports.currency = function (money, unit, n) {
    n = n || 2;
    unit = unit || '';
    money = parseFloat(money) || 0;
    money = money.toFixed(n);
    money = money + '';

    var temp = money.split('.');
    var decimal = temp.length > 1 ? temp[1] : '';
    var integer = temp[0];
    var result = '';

    while (integer.length > 3) {
        result = ',' + integer.slice(-3) + result;
        integer = integer.slice(0, integer.length - 3);
    }
    if (integer) {
        result = integer + result;
    }

    if (decimal) {
        result = result + '.' + decimal;
    }

    return unit + result;
};

exports.chineseCurrency = function (money) {

    var number = String(money);

    number = number.split('.')[0];

    const NUM = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "扒", "玖", "拾"],
        BASE_UNIT = ["", "拾", "佰", "仟"],
        ADVANCE_UNIT = ["", "萬", "亿", "兆"];

    var last = number.length % 4;

    var temp = [];

    for(var i = 0; i < number.length; i++){

        var index = 0;

        if(last > 0){
            index = Math.floor((i + (4 - last)) / 4);
        }else{
            index = Math.floor(i / 4);
        }

        if(!temp[index]){
            temp[index] = [];
        }

        if(index == 0){
            if(temp[index].length == 0){
                if(number[i] != '0'){
                    temp[index].push(NUM[number[i]]);
                }
            }else{
                temp[index].push(NUM[number[i]]);
            }
        }else{
            temp[index].push(NUM[number[i]]);
        }

    }

    var result = '';

    while (temp[0].length == 0){
        temp = temp.slice(1);
    }

    for(var j = 0; j < temp.length; j++){
        for(var k = 0, len = temp[j].length; k < len; k++){
            temp[j][k] = temp[j][k] == NUM[0] ? temp[j][k] : temp[j][k] + BASE_UNIT[len - k - 1];
            if(k == 3 && temp[j][k] == NUM[0]){
                temp[j][k] = '';
            }
        }

        result += temp[j].join('') + ADVANCE_UNIT[temp.length - j - 1];
    }

    result = result.replace(/零{3}萬/g, '');
    result = result.replace(/零{3}亿/g, '');
    result = result.replace(/零{3}兆/g, '');
    result = result.replace(/零{1,2}萬/g, '萬');
    result = result.replace(/零{1,2}亿/g, '亿');
    result = result.replace(/零{1,2}兆/g, '兆');
    result = result.replace(/零+/g, '零');
    result = result.replace(/零$/g, '');

    return result;
};

exports.thousands = function (money, n) {

    money = parseFloat(money) || 0;

    if(n){
        money = money.toFixed(n);
    }

    money = money + '';

    var temp = money.split('.');
    var decimal = temp.length > 1 ? temp[1] : '';
    var integer = temp[0];
    var result = '';

    while (integer.length > 3) {
        result = ',' + integer.slice(-3) + result;
        integer = integer.slice(0, integer.length - 3);
    }
    if (integer) {
        result = integer + result;
    }

    if (decimal) {
        result = result + '.' + decimal;
    }

    return result;
};

exports.bankCard = function (card) {

    card = card + '';

    var result = '';

    while (card.length > 4) {
        result = result + card.slice(0, 4) + ' ';
        card = card.substr(4);
    }

    if (card) {
        result += card;
    }

    return result;
};

exports.percentage = function (number, n) {

    if (typeof number !== 'number') {
        number = parseFloat(number) || 0;
    }

    number = number * 100;

    if (n) {
        number = number.toFixed(n);
    }

    return number + '%';
};

exports.number = function (number, fraction) {

    if(fraction == null){
        return number;
    }

    fraction = parseInt(fraction) || 0;

    if (typeof number !== 'number') {
        number = parseFloat(number) || 0;
    }

    return number.toFixed(fraction);
};
<|endoftext|>