Skip to content

Instantly share code, notes, and snippets.

@shakdwipeea
Created July 10, 2014 12:46
Show Gist options
  • Save shakdwipeea/eef427f5dbaf6a10f9af to your computer and use it in GitHub Desktop.
Save shakdwipeea/eef427f5dbaf6a10f9af to your computer and use it in GitHub Desktop.
The server for akant
This gist exceeds the recommended number of files (~10). To access all files, please clone this gist.
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# =========================
# Operating System Files
# =========================
# OSX
# =========================
.DS_Store
.AppleDouble
.LSOverride
# Icon must ends with two \r.
Icon
# Thumbnails
._*
# Files that might appear on external disk
.Spotlight-V100
.Trashes
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Akant_Back node_modules" level="project" />
<orderEntry type="library" name="Node.js v0.10.29 Core Modules" level="application" />
</component>
</module>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<file url="file://$PROJECT_DIR$" libraries="{Akant_Back node_modules}" />
<file url="PROJECT" libraries="{Node.js v0.10.29 Core Modules}" />
</component>
</project>
<component name="libraryTable">
<library name="Akant_Back node_modules" type="javaScript">
<properties>
<option name="frameworkName" value="node_modules" />
<sourceFilesUrls>
<item url="file://$PROJECT_DIR$/node_modules" />
</sourceFilesUrls>
</properties>
<CLASSES>
<root url="file://$PROJECT_DIR$/node_modules" />
</CLASSES>
<SOURCES />
</library>
</component>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JsBowerSettings">
<exe-path />
<config-path />
</component>
<component name="ProjectRootManager" version="2" />
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/Akant_Back.iml" filepath="$PROJECT_DIR$/.idea/Akant_Back.iml" />
</modules>
</component>
</project>
<component name="DependencyValidationManager">
<state>
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</state>
</component>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
benchmark/
test/
tool/
.travis.yml

Changes

This file is a manually maintained list of changes for each release. Feel free to add your changes here when sending pull requests. Also send corrections if you spot any mistakes.

v2.3.2 (2014-05-29)

  • Fix pool leaking connections after conn.changeUser #833

v2.3.1 (2014-05-26)

  • Add database errors to error constants
  • Add global errors to error constants
  • Throw when calling conn.release multiple times #824 #827
  • Update known error codes

v2.3.0 (2014-05-16)

  • Accept MySQL charset (like UTF8 or UTF8MB4) in charset option #808
  • Accept pool options in connection string to mysql.createPool #811
  • Clone connection config for new pool connections
  • Default connectTimeout to 2 minutes
  • Reject unauthorized SSL connections (use ssl.rejectUnauthorized to override) #816
  • Return last error when PoolCluster exhausts connection retries #818
  • Remove connection from pool after conn.changeUser is released #806
  • Throw on unknown SSL profile name #817
  • User newer TLS functions when available #809

v2.2.0 (2014-04-27)

  • Use indexOf instead of for loops removing conn from pool #611
  • Make callback to pool.query optional like conn.query #585
  • Prevent enqueuing sequences after fatal error #400
  • Fix geometry parser for empty fields #742
  • Accept lower-case charset option
  • Throw on unknown charset option #789
  • Update known charsets
  • Remove console.warn from PoolCluster #744
  • Fix pool.end to handle queued connections #797
  • Fix pool.releaseConnection to keep connection queue flowing #797
  • Fix SSL handshake error to be catchable #800
  • Add connection.threadId to get MySQL connection ID #602
  • Ensure pool.getConnection retrieves good connections #434 #557 #778
  • Fix pool cluster wildcard matching #627
  • Pass query values through to SqlString.format #590

v2.1.1 (2014-03-13)

  • fix authentication w/password failure for node.js 0.10.5 #746 #752
  • fix authentication w/password TypeError exception for node.js 0.10.0-0.10.4 #747
  • fix specifying values in conn.query({...}).on(...) pattern #755
  • fix long stack trace to include the pool.query(...) call #715

v2.1.0 (2014-02-20)

  • crypto.createHash fix for node.js < 11 #735
  • Add connectTimeout option to specify a timeout for establishing a connection #726
  • SSL support #481

v2.0.1

  • internal parser speed improvement #702
  • domains support
  • 'trace' connection option to control if long stack traces are generated #713 #710 #439

v2.0.0 (2014-01-09)

  • stream improvements:
    • node 0.8 support #692
    • Emit 'close' events from query streams #688
  • encoding fix in streaming LOAD DATA LOCAL INFILE #670
  • Doc improvements

v2.0.0-rc2 (2013-12-07)

  • Streaming LOAD DATA LOCAL INFILE #668
  • Doc improvements

v2.0.0-rc1 (2013-11-30)

  • Transaction support
  • Expose SqlString.format as mysql.format()
  • Many bug fixes
  • Better support for dates in local time zone
  • Doc improvements

v2.0.0-alpha9 (2013-08-27)

  • Add query to pool to execute queries directly using the pool
  • Pool option to set queue limit
  • Pool sends 'connection' event when it opens a new connection
  • Added stringifyObjects option to treat input as strings rather than objects (#501)
  • Support for poolClusters
  • Datetime improvements
  • Bug fixes

v2.0.0-alpha8 (2013-04-30)

  • Switch to old mode for Streams 2 (Node.js v 0.10.x)
  • Add stream method to Query Wraps events from the query object into a node v0.10.x Readable stream
  • DECIMAL should also be treated as big number
  • Removed slow unnecessary stack access
  • Added charsets
  • Added bigNumberStrings option for forcing BIGINT columns as strings
  • Changes date parsing to return String if not a valid JS Date
  • Adds support for ?? escape sequence to escape identifiers
  • Changes Auth.token() to force password to be in binary, not utf8 (#378)
  • Restrict debugging by packet types
  • Add 'multipleStatements' option tracking to ConnectionConfig. Fixes GH-408
  • Changes Pool to handle 'error' events and dispose connection
  • Allows db.query({ sql: "..." }, [ val1, ... ], cb); (#390)
  • Improved documentation
  • Bug fixes

v2.0.0-alpha7 (2013-02-03)

  • Add connection pooling (#351)

v2.0.0-alpha6 (2013-01-31)

  • Add supportBigNumbers option (#381, #382)
  • Accept prebuilt Query object in connection.query
  • Bug fixes

v2.0.0-alpha5 (2012-12-03)

  • Add mysql.escapeId to escape identifiers (closes #342)
  • Allow custom escaping mode (config.queryFormat)
  • Convert DATE columns to configured timezone instead of UTC (#332)
  • Convert LONGLONG and NEWDECIMAL to numbers (#333)
  • Fix Connection.escape() (fixes #330)
  • Changed Readme ambiguity about custom type cast fallback
  • Change typeCast to receive Connection instead of Connection.config.timezone
  • Fix drain event having useless err parameter
  • Add Connection.statistics() back from v0.9
  • Add Connection.ping() back from v0.9

v2.0.0-alpha4 (2012-10-03)

  • Fix some OOB errors on resume()
  • Fix quick pause() / resume() usage
  • Properly parse host denied / similar errors
  • Add Connection.ChangeUser functionality
  • Make sure changeUser errors are fatal
  • Enable formatting nested arrays for bulk inserts
  • Add Connection.escape functionality
  • Renamed 'close' to 'end' event
  • Return parsed object instead of Buffer for GEOMETRY types
  • Allow nestTables inline (using a string instead of a boolean)
  • Check for ZEROFILL_FLAG and format number accordingly
  • Add timezone support (default: local)
  • Add custom typeCast functionality
  • Export mysql column types
  • Add connection flags functionality (#237)
  • Exports drain event when queue finishes processing (#272, #271, #306)

v2.0.0-alpha3 (2012-06-12)

  • Implement support for LOAD DATA LOCAL INFILE queries (#182).
  • Support OLD_PASSWORD() accounts like 0.9.x did. You should still upgrade any user accounts in your your MySQL user table that has short (16 byte) Password values. Connecting to those accounts is not secure. (#204)
  • Ignore function values when escaping objects, allows to use RowDataPacket objects as query arguments. (Alex Gorbatchev, #213)
  • Handle initial error packets from server such as ER_HOST_NOT_PRIVILEGED.
  • Treat utf8\_bin as a String, not Buffer. (#214)
  • Handle empty strings in first row column value. (#222)
  • Honor Connection#nestTables setting for queries. (#221)
  • Remove CLIENT_INTERACTIVE flag from config. Improves #225.
  • Improve docs for connections settings.
  • Implement url string support for Connection configs.

v2.0.0-alpha2 (2012-05-31)

  • Specify escaping before for NaN / Infinity (they are as unquoted constants).
  • Support for unix domain socket connections (use: {socketPath: '...'}).
  • Fix type casting for NULL values for Date/Number fields
  • Add fields argument to query() as well as 'fields' event. This is similar to what was available in 0.9.x.
  • Support connecting to the sphinx searchd daemon as well as MariaDB (#199).
  • Implement long stack trace support, will be removed / disabled if the node core ever supports it natively.
  • Implement nestTables option for queries, allows fetching JOIN result sets with overlapping column names.
  • Fix ? placeholder mechanism for values containing '?' characters (#205).
  • Detect when connect() is called more than once on a connection and provide the user with a good error message for it (#204).
  • Switch to UTF8_GENERAL_CI (previously UTF8_UNICODE_CI) as the default charset for all connections to avoid strange MySQL performance issues (#200), and also make the charset user configurable.
  • Fix BLOB type casting for TINY_BLOB, MEDIUM_BLOB and LONG_BLOB.
  • Add support for sending and receiving large (> 16 MB) packets.

v2.0.0-alpha (2012-05-15)

This release is a rewrite. You should carefully test your application after upgrading to avoid problems. This release features many improvements, most importantly:

  • ~5x faster than v0.9.x for parsing query results
  • Support for pause() / resume() (for streaming rows)
  • Support for multiple statement queries
  • Support for stored procedures
  • Support for transactions
  • Support for binary columns (as blobs)
  • Consistent & well documented error handling
  • A new Connection class that has well defined semantics (unlike the old Client class).
  • Convenient escaping of objects / arrays that allows for simpler query construction
  • A significantly simpler code base
  • Many bug fixes & other small improvements (Closed 62 out of 66 GitHub issues)

Below are a few notes on the upgrade process itself:

The first thing you will run into is that the old Client class is gone and has been replaced with a less ambitious Connection class. So instead of mysql.createClient(), you now have to:

var mysql      = require('mysql');
var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'me',
  password : 'secret',
});

connection.query('SELECT 1', function(err, rows) {
  if (err) throw err;

  console.log('Query result: ', rows);
});

connection.end();

The new Connection class does not try to handle re-connects, please study the Server disconnects section in the new Readme.

Other than that, the interface has stayed very similar. Here are a few things to check out so:

  • BIGINT's are now cast into strings
  • Binary data is now cast to buffers
  • The 'row' event on the Query object is now called 'result' and will also be emitted for queries that produce an OK/Error response.
  • Error handling is consistently defined now, check the Readme
  • Escaping has become more powerful which may break your code if you are currently using objects to fill query placeholders.
  • Connections can now be established explicitly again, so you may wish to do so if you want to handle connection errors specifically.

That should be most of it, if you run into anything else, please send a patch or open an issue to improve this document.

v0.9.6 (2012-03-12)

  • Escape array values so they produce sql arrays (Roger Castells, Colin Smith)
  • docs: mention mysql transaction stop gap solution (Blake Miner)
  • docs: Mention affectedRows in FAQ (Michael Baldwin)

v0.9.5 (2011-11-26)

  • Fix #142 Driver stalls upon reconnect attempt that's immediately closed
  • Add travis build
  • Switch to urun as a test runner
  • Switch to utest for unit tests
  • Remove fast-or-slow dependency for tests
  • Split integration tests into individual files again

v0.9.4 (2011-08-31)

  • Expose package.json as mysql.PACKAGE (#104)

v0.9.3 (2011-08-22)

  • Set default client.user to root
  • Fix #91: Client#format should not mutate params array
  • Fix #94: TypeError in client.js
  • Parse decimals as string (vadimg)

v0.9.2 (2011-08-07)

  • The underlaying socket connection is now managed implicitly rather than explicitly.
  • Check the [upgrading guide][] for a full list of changes.

v0.9.1 (2011-02-20)

  • Fix issue #49 / client.escape() throwing exceptions on objects. (Nick Payne)
  • Drop < v0.4.x compatibility. From now on you need node v0.4.x to use this module.

Older releases

These releases were done before maintaining this file:

{
"Amazon RDS": {
"ca": "-----BEGIN CERTIFICATE-----\nMIIDQzCCAqygAwIBAgIJAOd1tlfiGoEoMA0GCSqGSIb3DQEBBQUAMHUxCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdTZWF0dGxlMRMw\nEQYDVQQKEwpBbWF6b24uY29tMQwwCgYDVQQLEwNSRFMxHDAaBgNVBAMTE2F3cy5h\nbWF6b24uY29tL3Jkcy8wHhcNMTAwNDA1MjI0NDMxWhcNMTUwNDA0MjI0NDMxWjB1\nMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHU2Vh\ndHRsZTETMBEGA1UEChMKQW1hem9uLmNvbTEMMAoGA1UECxMDUkRTMRwwGgYDVQQD\nExNhd3MuYW1hem9uLmNvbS9yZHMvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\ngQDKhXGU7tizxUR5WaFoMTFcxNxa05PEjZaIOEN5ctkWrqYSRov0/nOMoZjqk8bC\nmed9vPFoQGD0OTakPs0jVe3wwmR735hyVwmKIPPsGlaBYj1O6llIpZeQVyupNx56\nUzqtiLaDzh1KcmfqP3qP2dInzBfJQKjiRudo1FWnpPt33QIDAQABo4HaMIHXMB0G\nA1UdDgQWBBT/H3x+cqSkR/ePSIinPtc4yWKe3DCBpwYDVR0jBIGfMIGcgBT/H3x+\ncqSkR/ePSIinPtc4yWKe3KF5pHcwdTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh\nc2hpbmd0b24xEDAOBgNVBAcTB1NlYXR0bGUxEzARBgNVBAoTCkFtYXpvbi5jb20x\nDDAKBgNVBAsTA1JEUzEcMBoGA1UEAxMTYXdzLmFtYXpvbi5jb20vcmRzL4IJAOd1\ntlfiGoEoMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAvguZy/BDT66x\nGfgnJlyQwnFSeVLQm9u/FIvz4huGjbq9dqnD6h/Gm56QPFdyMEyDiZWaqY6V08lY\nLTBNb4kcIc9/6pc0/ojKciP5QJRm6OiZ4vgG05nF4fYjhU7WClUx7cxq1fKjNc2J\nUCmmYqgiVkAGWRETVo+byOSDZ4swb10=\n-----END CERTIFICATE-----\n"
}
}
var Connection = require('./lib/Connection');
var ConnectionConfig = require('./lib/ConnectionConfig');
var Types = require('./lib/protocol/constants/types');
var SqlString = require('./lib/protocol/SqlString');
var Pool = require('./lib/Pool');
var PoolConfig = require('./lib/PoolConfig');
var PoolCluster = require('./lib/PoolCluster');
exports.createConnection = function(config) {
return new Connection({config: new ConnectionConfig(config)});
};
exports.createPool = function(config) {
return new Pool({config: new PoolConfig(config)});
};
exports.createPoolCluster = function(config) {
return new PoolCluster(config);
};
exports.createQuery = Connection.createQuery;
exports.Types = Types;
exports.escape = SqlString.escape;
exports.escapeId = SqlString.escapeId;
exports.format = SqlString.format;
var Crypto = require('crypto');
var Net = require('net');
var tls = require('tls');
var ConnectionConfig = require('./ConnectionConfig');
var Protocol = require('./protocol/Protocol');
var SqlString = require('./protocol/SqlString');
var Query = require('./protocol/sequences/Query');
var EventEmitter = require('events').EventEmitter;
var Util = require('util');
module.exports = Connection;
Util.inherits(Connection, EventEmitter);
function Connection(options) {
EventEmitter.call(this);
this.config = options.config;
this._socket = options.socket;
this._protocol = new Protocol({config: this.config, connection: this});
this._connectCalled = false;
this.state = "disconnected";
this.threadId = null;
}
function bindToCurrentDomain(cb) {
var domain = process.domain;
if (!domain || !cb)
return cb;
else
return domain.bind(cb);
}
Connection.createQuery = function(sql, values, cb) {
if (sql instanceof Query) {
return sql;
}
var options = {};
if (typeof sql === 'object') {
// query(options, cb)
options = sql;
if (typeof values === 'function') {
cb = values;
} else if (typeof values !== 'undefined') {
options.values = values;
}
} else if (typeof values === 'function') {
// query(sql, cb)
cb = values;
options.sql = sql;
options.values = undefined;
} else {
// query(sql, values, cb)
options.sql = sql;
options.values = values;
}
return new Query(options, bindToCurrentDomain(cb));
};
Connection.prototype.connect = function(cb) {
if (!this._connectCalled) {
this._connectCalled = true;
// Connect either via a UNIX domain socket or a TCP socket.
this._socket = (this.config.socketPath)
? Net.createConnection(this.config.socketPath)
: Net.createConnection(this.config);
var connection = this;
this._protocol.on('data', function(data) {
connection._socket.write(data);
});
this._socket.on('data', function(data) {
connection._protocol.write(data);
});
this._protocol.on('end', function() {
connection._socket.end()
});
this._socket.on('end', function(err) {
connection._protocol.end();
});
this._socket.on('error', this._handleNetworkError.bind(this));
this._socket.on('connect', this._handleProtocolConnect.bind(this));
this._protocol.on('handshake', this._handleProtocolHandshake.bind(this));
this._protocol.on('unhandledError', this._handleProtocolError.bind(this));
this._protocol.on('drain', this._handleProtocolDrain.bind(this));
this._protocol.on('end', this._handleProtocolEnd.bind(this));
if (this.config.connectTimeout) {
var handleConnectTimeout = this._handleConnectTimeout.bind(this);
this._socket.setTimeout(this.config.connectTimeout, handleConnectTimeout);
this._socket.once('connect', function() {
this.setTimeout(0, handleConnectTimeout);
});
}
}
this._protocol.handshake(cb);
};
Connection.prototype.changeUser = function(options, cb){
cb = cb || function() {};
this._implyConnect();
if (typeof options === 'function') {
cb = options;
options = {};
}
var charsetNumber = (options.charset)
? ConnectionConfig.getCharsetNumber(options.charset)
: this.config.charsetNumber;
return this._protocol.changeUser({
user : options.user || this.config.user,
password : options.password || this.config.password,
database : options.database || this.config.database,
charsetNumber : charsetNumber,
currentConfig : this.config
}, bindToCurrentDomain(cb));
};
Connection.prototype.beginTransaction = function(cb) {
this._implyConnect();
var query = Connection.createQuery('START TRANSACTION', cb);
query._connection = this;
return this._protocol._enqueue(query);
};
Connection.prototype.commit = function(cb) {
this._implyConnect();
var query = Connection.createQuery('COMMIT', cb);
query._connection = this;
return this._protocol._enqueue(query);
};
Connection.prototype.rollback = function(cb) {
this._implyConnect();
var query = Connection.createQuery('ROLLBACK', cb);
query._connection = this;
return this._protocol._enqueue(query);
};
Connection.prototype.query = function(sql, values, cb) {
this._implyConnect();
var query = Connection.createQuery(sql, values, cb);
query._connection = this;
if (!(typeof sql == 'object' && 'typeCast' in sql)) {
query.typeCast = this.config.typeCast;
}
query.sql = this.format(query.sql, query.values);
return this._protocol._enqueue(query);
};
Connection.prototype.ping = function(cb) {
this._implyConnect();
this._protocol.ping(bindToCurrentDomain(cb));
};
Connection.prototype.statistics = function(cb) {
this._implyConnect();
this._protocol.stats(bindToCurrentDomain(cb));
};
Connection.prototype.end = function(cb) {
this._implyConnect();
this._protocol.quit(bindToCurrentDomain(cb));
};
Connection.prototype.destroy = function() {
this.state = "disconnected";
this._implyConnect();
this._socket.destroy();
this._protocol.destroy();
};
Connection.prototype.pause = function() {
this._socket.pause();
this._protocol.pause();
};
Connection.prototype.resume = function() {
this._socket.resume();
this._protocol.resume();
};
Connection.prototype.escape = function(value) {
return SqlString.escape(value, false, this.config.timezone);
};
Connection.prototype.format = function(sql, values) {
if (typeof this.config.queryFormat == "function") {
return this.config.queryFormat.call(this, sql, values, this.config.timezone);
}
return SqlString.format(sql, values, this.config.stringifyObjects, this.config.timezone);
};
if (tls.TLSSocket) {
// 0.11+ environment
Connection.prototype._startTLS = function _startTLS(onSecure) {
var secureContext = tls.createSecureContext({
key : this.config.ssl.key,
cert : this.config.ssl.cert,
passphrase : this.config.ssl.passphrase,
ca : this.config.ssl.ca
});
// "unpipe"
this._socket.removeAllListeners('data');
this._protocol.removeAllListeners('data');
// socket <-> encrypted
var rejectUnauthorized = this.config.ssl.rejectUnauthorized;
var secureSocket = new tls.TLSSocket(this._socket, {
rejectUnauthorized : rejectUnauthorized,
requestCert : true,
secureContext : secureContext,
isServer : false
});
// cleartext <-> protocol
secureSocket.pipe(this._protocol);
this._protocol.on('data', function(data) {
secureSocket.write(data);
});
secureSocket.on('secure', function() {
onSecure(rejectUnauthorized ? this.ssl.verifyError() : null);
});
// start TLS communications
secureSocket._start();
};
} else {
// pre-0.11 environment
Connection.prototype._startTLS = function _startTLS(onSecure) {
// before TLS:
// _socket <-> _protocol
// after:
// _socket <-> securePair.encrypted <-> securePair.cleartext <-> _protocol
var credentials = Crypto.createCredentials({
key : this.config.ssl.key,
cert : this.config.ssl.cert,
passphrase : this.config.ssl.passphrase,
ca : this.config.ssl.ca
});
var rejectUnauthorized = this.config.ssl.rejectUnauthorized;
var securePair = tls.createSecurePair(credentials, false, true, rejectUnauthorized);
// "unpipe"
this._socket.removeAllListeners('data');
this._protocol.removeAllListeners('data');
// socket <-> encrypted
securePair.encrypted.pipe(this._socket);
this._socket.on('data', function(data) {
securePair.encrypted.write(data);
});
// cleartext <-> protocol
securePair.cleartext.pipe(this._protocol);
this._protocol.on('data', function(data) {
securePair.cleartext.write(data);
});
securePair.on('secure', function() {
onSecure(rejectUnauthorized ? this.ssl.verifyError() : null);
});
};
}
Connection.prototype._handleConnectTimeout = function() {
if (this._socket) {
this._socket.setTimeout(0);
this._socket.destroy();
}
var err = new Error('connect ETIMEDOUT');
err.errorno = 'ETIMEDOUT';
err.code = 'ETIMEDOUT';
err.syscall = 'connect';
this._handleNetworkError(err);
};
Connection.prototype._handleNetworkError = function(err) {
this._protocol.handleNetworkError(err);
};
Connection.prototype._handleProtocolError = function(err) {
this.state = "protocol_error";
this.emit('error', err);
};
Connection.prototype._handleProtocolDrain = function() {
this.emit('drain');
};
Connection.prototype._handleProtocolConnect = function() {
this.state = "connected";
};
Connection.prototype._handleProtocolHandshake = function _handleProtocolHandshake(packet) {
this.state = "authenticated";
this.threadId = packet.threadId;
};
Connection.prototype._handleProtocolEnd = function(err) {
this.state = "disconnected";
this.emit('end', err);
};
Connection.prototype._implyConnect = function() {
if (!this._connectCalled) {
this.connect();
}
};
var urlParse = require('url').parse;
var ClientConstants = require('./protocol/constants/client');
var Charsets = require('./protocol/constants/charsets');
var SSLProfiles = null;
module.exports = ConnectionConfig;
function ConnectionConfig(options) {
if (typeof options === 'string') {
options = ConnectionConfig.parseUrl(options);
}
this.host = options.host || 'localhost';
this.port = options.port || 3306;
this.localAddress = options.localAddress;
this.socketPath = options.socketPath;
this.user = options.user || undefined;
this.password = options.password || undefined;
this.database = options.database;
this.connectTimeout = (options.connectTimeout === undefined)
? (2 * 60 * 1000)
: options.connectTimeout;
this.insecureAuth = options.insecureAuth || false;
this.supportBigNumbers = options.supportBigNumbers || false;
this.bigNumberStrings = options.bigNumberStrings || false;
this.dateStrings = options.dateStrings || false;
this.debug = options.debug;
this.trace = options.trace !== false;
this.stringifyObjects = options.stringifyObjects || false;
this.timezone = options.timezone || 'local';
this.flags = options.flags || '';
this.queryFormat = options.queryFormat;
this.pool = options.pool || undefined;
this.ssl = (typeof options.ssl === 'string')
? ConnectionConfig.getSSLProfile(options.ssl)
: (options.ssl || false);
this.multipleStatements = options.multipleStatements || false;
this.typeCast = (options.typeCast === undefined)
? true
: options.typeCast;
if (this.timezone[0] == " ") {
// "+" is a url encoded char for space so it
// gets translated to space when giving a
// connection string..
this.timezone = "+" + this.timezone.substr(1);
}
if (this.ssl) {
// Default rejectUnauthorized to true
this.ssl.rejectUnauthorized = this.ssl.rejectUnauthorized !== false;
}
this.maxPacketSize = 0;
this.charsetNumber = (options.charset)
? ConnectionConfig.getCharsetNumber(options.charset)
: options.charsetNumber||Charsets.UTF8_GENERAL_CI;
this.clientFlags = ConnectionConfig.mergeFlags(ConnectionConfig.getDefaultFlags(options),
options.flags || '');
}
ConnectionConfig.mergeFlags = function(default_flags, user_flags) {
var flags = 0x0, i;
user_flags = (user_flags || '').toUpperCase().split(/\s*,+\s*/);
// add default flags unless "blacklisted"
for (i in default_flags) {
if (user_flags.indexOf("-" + default_flags[i]) >= 0) continue;
flags |= ClientConstants["CLIENT_" + default_flags[i]] || 0x0;
}
// add user flags unless already already added
for (i in user_flags) {
if (user_flags[i][0] == "-") continue;
if (default_flags.indexOf(user_flags[i]) >= 0) continue;
flags |= ClientConstants["CLIENT_" + user_flags[i]] || 0x0;
}
return flags;
};
ConnectionConfig.getDefaultFlags = function(options) {
var defaultFlags = [ "LONG_PASSWORD", "FOUND_ROWS", "LONG_FLAG",
"CONNECT_WITH_DB", "ODBC", "LOCAL_FILES",
"IGNORE_SPACE", "PROTOCOL_41", "IGNORE_SIGPIPE",
"TRANSACTIONS", "RESERVED", "SECURE_CONNECTION",
"MULTI_RESULTS" ];
if (options && options.multipleStatements) {
defaultFlags.push("MULTI_STATEMENTS");
}
return defaultFlags;
};
ConnectionConfig.getCharsetNumber = function getCharsetNumber(charset) {
var num = Charsets[charset.toUpperCase()];
if (num === undefined) {
throw new TypeError('Unknown charset \'' + charset + '\'');
}
return num;
};
ConnectionConfig.getSSLProfile = function getSSLProfile(name) {
if (!SSLProfiles) {
SSLProfiles = require('./../fixtures/ssl-profiles.json');
}
var ssl = SSLProfiles[name];
if (ssl === undefined) {
throw new TypeError('Unknown SSL profile \'' + name + '\'');
}
return ssl;
};
ConnectionConfig.parseUrl = function(url) {
url = urlParse(url, true);
var options = {
host : url.hostname,
port : url.port,
database : url.pathname.substr(1),
};
if (url.auth) {
var auth = url.auth.split(':');
options.user = auth[0];
options.password = auth[1];
}
if (url.query) {
for (var key in url.query) {
var value = url.query[key];
try {
// Try to parse this as a JSON expression first
options[key] = JSON.parse(value);
} catch (err) {
// Otherwise assume it is a plain string
options[key] = value;
}
}
}
return options;
};
var mysql = require('../');
var Connection = require('./Connection');
var EventEmitter = require('events').EventEmitter;
var Util = require('util');
var PoolConnection = require('./PoolConnection');
module.exports = Pool;
Util.inherits(Pool, EventEmitter);
function Pool(options) {
EventEmitter.call(this);
this.config = options.config;
this.config.connectionConfig.pool = this;
this._allConnections = [];
this._freeConnections = [];
this._connectionQueue = [];
this._closed = false;
}
Pool.prototype.getConnection = function (cb) {
if (this._closed) {
return process.nextTick(function(){
return cb(new Error('Pool is closed.'));
});
}
var connection;
if (this._freeConnections.length > 0) {
connection = this._freeConnections.shift();
return this.acquireConnection(connection, cb);
}
if (this.config.connectionLimit === 0 || this._allConnections.length < this.config.connectionLimit) {
connection = new PoolConnection(this, { config: this.config.newConnectionConfig() });
this._allConnections.push(connection);
return connection.connect(function(err) {
if (this._closed) {
return cb(new Error('Pool is closed.'));
}
if (err) {
return cb(err);
}
this.emit('connection', connection);
return cb(null, connection);
}.bind(this));
}
if (!this.config.waitForConnections) {
return process.nextTick(function(){
return cb(new Error('No connections available.'));
});
}
if (this.config.queueLimit && this._connectionQueue.length >= this.config.queueLimit) {
return cb(new Error('Queue limit reached.'));
}
if (cb && process.domain)
cb = process.domain.bind(cb);
this._connectionQueue.push(cb);
};
Pool.prototype.acquireConnection = function acquireConnection(connection, cb) {
if (connection._pool !== this) {
throw new Error('Connection acquired from wrong pool.');
}
var pool = this;
connection._pool = null;
connection.ping(function(err){
if (!err) {
connection._pool = pool;
cb(null, connection);
return;
}
connection.destroy();
pool._connectionQueue.unshift(cb);
pool._removeConnection(connection);
});
};
Pool.prototype.releaseConnection = function releaseConnection(connection) {
var cb;
if (connection._pool) {
if (connection._pool !== this) {
throw new Error('Connection released to wrong pool');
}
if (connection._purge) {
// purge connection from pool
this._purgeConnection(connection);
return;
} else if (this._freeConnections.indexOf(connection) !== -1) {
// connection already in free connection pool
// this won't catch all double-release cases
throw new Error('Connection already released');
} else {
// add connection to end of free queue
this._freeConnections.push(connection);
}
}
while (this._closed && this._connectionQueue.length) {
// empty the connection queue
cb = this._connectionQueue.shift();
process.nextTick(cb.bind(null, new Error('Pool is closed.')));
}
if (this._connectionQueue.length) {
cb = this._connectionQueue.shift();
this.getConnection(cb);
}
};
Pool.prototype.end = function (cb) {
this._closed = true;
if (typeof cb != "function") {
cb = function (err) {
if (err) throw err;
};
}
var calledBack = false;
var closedConnections = 0;
var connection;
var endCB = function(err) {
if (calledBack) {
return;
}
if (err || ++closedConnections >= this._allConnections.length) {
calledBack = true;
return cb(err);
}
}.bind(this);
if (this._allConnections.length === 0) {
return process.nextTick(endCB);
}
while (this._allConnections.length) {
connection = this._allConnections[0];
connection._pool = null;
connection._realEnd(endCB);
this._removeConnection(connection);
}
};
Pool.prototype.query = function (sql, values, cb) {
if (typeof values === 'function') {
cb = values;
values = null;
}
if (!cb) {
// Ignore results and errors if no cb supplied; matches connection.query
cb = function () {};
}
var connection;
var query = Connection.createQuery(sql, values, function (err, rows, fields) {
connection.release();
cb.apply(this, arguments);
});
if (this.config.connectionConfig.trace) {
// Long stack trace support
query._callSite = new Error;
}
this.getConnection(function (err, conn) {
if (err) return cb(err);
connection = conn;
conn.query(query);
});
};
Pool.prototype._purgeConnection = function _purgeConnection(connection) {
var pool = this;
connection._realEnd(function(err) {
if (err) {
connection.destroy();
}
pool._removeConnection(connection);
});
};
Pool.prototype._removeConnection = function(connection) {
var index;
connection._pool = null;
if ((index = this._allConnections.indexOf(connection)) !== -1) {
// Remove connection from all connections
this._allConnections.splice(index, 1);
}
if ((index = this._freeConnections.indexOf(connection)) !== -1) {
// Remove connection from free connections
this._freeConnections.splice(index, 1);
}
this.releaseConnection(connection);
};
Pool.prototype.escape = function(value) {
return mysql.escape(value, this.config.connectionConfig.stringifyObjects, this.config.connectionConfig.timezone);
};
var Pool = require('./Pool');
var PoolConfig = require('./PoolConfig');
var Util = require('util');
var EventEmitter = require('events').EventEmitter;
module.exports = PoolCluster;
/**
* PoolCluster
*/
function PoolCluster(config) {
EventEmitter.call(this);
config = config || {};
this._canRetry = typeof config.canRetry === 'undefined' ? true : config.canRetry;
this._removeNodeErrorCount = config.removeNodeErrorCount || 5;
this._defaultSelector = config.defaultSelector || 'RR';
this._closed = false;
this._lastId = 0;
this._nodes = {};
this._serviceableNodeIds = [];
this._namespaces = {};
this._findCaches = {};
}
Util.inherits(PoolCluster, EventEmitter);
PoolCluster.prototype.of = function(pattern, selector) {
pattern = pattern || '*';
selector = selector || this._defaultSelector;
selector = selector.toUpperCase();
if (typeof Selector[selector] === 'undefined') {
selector = this._defaultSelector;
}
var key = pattern + selector;
if (typeof this._namespaces[key] === 'undefined') {
this._namespaces[key] = new PoolNamespace(this, pattern, selector);
}
return this._namespaces[key];
};
PoolCluster.prototype.add = function(id, config) {
if (typeof id === 'object') {
config = id;
id = 'CLUSTER::' + (++this._lastId);
}
if (typeof this._nodes[id] === 'undefined') {
this._nodes[id] = {
id: id,
errorCount: 0,
pool: new Pool({config: new PoolConfig(config)})
};
this._serviceableNodeIds.push(id);
this._clearFindCaches();
}
};
PoolCluster.prototype.getConnection = function(pattern, selector, cb) {
var namespace;
if (typeof pattern === 'function') {
cb = pattern;
namespace = this.of();
} else {
if (typeof selector === 'function') {
cb = selector;
selector = this._defaultSelector;
}
namespace = this.of(pattern, selector);
}
namespace.getConnection(cb);
};
PoolCluster.prototype.end = function() {
if (this._closed) {
return;
}
this._closed = true;
for (var id in this._nodes) {
this._nodes[id].pool.end();
}
};
PoolCluster.prototype._findNodeIds = function(pattern) {
if (typeof this._findCaches[pattern] !== 'undefined') {
return this._findCaches[pattern];
}
var foundNodeIds;
if (pattern === '*') { // all
foundNodeIds = this._serviceableNodeIds;
} else if (this._serviceableNodeIds.indexOf(pattern) != -1) { // one
foundNodeIds = [pattern];
} else if (pattern[pattern.length - 1] === '*') {
// wild matching
var keyword = pattern.substring(pattern.length - 1, 0);
foundNodeIds = this._serviceableNodeIds.filter(function (id) {
return id.indexOf(keyword) === 0;
});
} else {
foundNodeIds = [];
}
this._findCaches[pattern] = foundNodeIds;
return foundNodeIds;
};
PoolCluster.prototype._getNode = function(id) {
return this._nodes[id] || null;
};
PoolCluster.prototype._increaseErrorCount = function(node) {
if (++node.errorCount >= this._removeNodeErrorCount) {
var index = this._serviceableNodeIds.indexOf(node.id);
if (index !== -1) {
this._serviceableNodeIds.splice(index, 1);
delete this._nodes[node.id];
this._clearFindCaches();
node.pool.end();
this.emit('remove', node.id);
}
}
};
PoolCluster.prototype._decreaseErrorCount = function(node) {
if (node.errorCount > 0) {
--node.errorCount;
}
};
PoolCluster.prototype._getConnection = function(node, cb) {
var self = this;
node.pool.getConnection(function (err, connection) {
if (err) {
self._increaseErrorCount(node);
cb(err);
return;
} else {
self._decreaseErrorCount(node);
}
connection._clusterId = node.id;
cb(null, connection);
});
};
PoolCluster.prototype._clearFindCaches = function() {
this._findCaches = {};
};
/**
* PoolNamespace
*/
function PoolNamespace(cluster, pattern, selector) {
this._cluster = cluster;
this._pattern = pattern;
this._selector = new Selector[selector]();
}
PoolNamespace.prototype.getConnection = function(cb) {
var clusterNode = this._getClusterNode();
var cluster = this._cluster;
var namespace = this;
if (clusterNode === null) {
return cb(new Error('Pool does not exist.'));
}
cluster._getConnection(clusterNode, function(err, connection) {
var retry = err && cluster._canRetry
&& cluster._findNodeIds(namespace._pattern).length !== 0;
if (retry) {
return namespace.getConnection(cb);
}
if (err) {
return cb(err);
}
cb(null, connection);
});
};
PoolNamespace.prototype._getClusterNode = function _getClusterNode() {
var foundNodeIds = this._cluster._findNodeIds(this._pattern);
var nodeId;
switch (foundNodeIds.length) {
case 0:
nodeId = null;
break;
case 1:
nodeId = foundNodeIds[0];
break;
default:
nodeId = this._selector(foundNodeIds);
break;
}
return nodeId !== null
? this._cluster._getNode(nodeId)
: null;
};
/**
* Selector
*/
var Selector = {};
Selector.RR = function () {
var index = 0;
return function(clusterIds) {
if (index >= clusterIds.length) {
index = 0;
}
var clusterId = clusterIds[index++];
return clusterId;
};
};
Selector.RANDOM = function () {
return function(clusterIds) {
return clusterIds[Math.floor(Math.random() * clusterIds.length)];
};
};
Selector.ORDER = function () {
return function(clusterIds) {
return clusterIds[0];
};
};
var ConnectionConfig = require('./ConnectionConfig');
module.exports = PoolConfig;
function PoolConfig(options) {
if (typeof options === 'string') {
options = ConnectionConfig.parseUrl(options);
}
this.connectionConfig = new ConnectionConfig(options);
this.waitForConnections = (options.waitForConnections === undefined)
? true
: Boolean(options.waitForConnections);
this.connectionLimit = (options.connectionLimit === undefined)
? 10
: Number(options.connectionLimit);
this.queueLimit = (options.queueLimit === undefined)
? 0
: Number(options.queueLimit);
}
PoolConfig.prototype.newConnectionConfig = function newConnectionConfig() {
var connectionConfig = new ConnectionConfig(this.connectionConfig);
connectionConfig.clientFlags = this.connectionConfig.clientFlags;
connectionConfig.maxPacketSize = this.connectionConfig.maxPacketSize;
return connectionConfig;
};
var inherits = require('util').inherits;
var Connection = require('./Connection')
var __changeUser = Connection.prototype.changeUser;
module.exports = PoolConnection;
inherits(PoolConnection, Connection);
function PoolConnection(pool, options) {
Connection.call(this, options);
this._pool = pool;
this._purge = false
// When a fatal error occurs the connection's protocol ends, which will cause
// the connection to end as well, thus we only need to watch for the end event
// and we will be notified of disconnects.
this.on('end', this._removeFromPool);
this.on('error', this._removeFromPool);
}
PoolConnection.prototype.changeUser = function changeUser(options, callback) {
this._purge = true;
return __changeUser.apply(this, arguments);
};
PoolConnection.prototype.release = function release() {
var pool = this._pool;
if (!pool || pool._closed) {
return;
}
return pool.releaseConnection(this);
};
// TODO: Remove this when we are removing PoolConnection#end
PoolConnection.prototype._realEnd = Connection.prototype.end;
PoolConnection.prototype.end = function () {
console.warn( 'Calling conn.end() to release a pooled connection is '
+ 'deprecated. In next version calling conn.end() will be '
+ 'restored to default conn.end() behavior. Use '
+ 'conn.release() instead.'
);
this.release();
};
PoolConnection.prototype.destroy = function () {
this._removeFromPool(this);
return Connection.prototype.destroy.apply(this, arguments);
};
PoolConnection.prototype._removeFromPool = function(connection) {
if (!this._pool || this._pool._closed) {
return;
}
var pool = this._pool;
this._pool = null;
pool._removeConnection(this);
};
var Buffer = require('buffer').Buffer;
var Crypto = require('crypto');
var Auth = exports;
function sha1(msg) {
var hash = Crypto.createHash('sha1');
hash.update(msg, 'binary');
return hash.digest('binary');
}
Auth.sha1 = sha1;
function xor(a, b) {
a = new Buffer(a, 'binary');
b = new Buffer(b, 'binary');
var result = new Buffer(a.length);
for (var i = 0; i < a.length; i++) {
result[i] = (a[i] ^ b[i]);
}
return result;
};
Auth.xor = xor;
Auth.token = function(password, scramble) {
if (!password) {
return new Buffer(0);
}
// password must be in binary format, not utf8
var stage1 = sha1((new Buffer(password, "utf8")).toString("binary"));
var stage2 = sha1(stage1);
var stage3 = sha1(scramble.toString('binary') + stage2);
return xor(stage3, stage1);
};
// This is a port of sql/password.c:hash_password which needs to be used for
// pre-4.1 passwords.
Auth.hashPassword = function(password) {
var nr = [0x5030, 0x5735],
add = 7,
nr2 = [0x1234, 0x5671],
result = new Buffer(8);
if (typeof password == 'string'){
password = new Buffer(password);
}
for (var i = 0; i < password.length; i++) {
var c = password[i];
if (c == 32 || c == 9) {
// skip space in password
continue;
}
// nr^= (((nr & 63)+add)*c)+ (nr << 8);
// nr = xor(nr, add(mul(add(and(nr, 63), add), c), shl(nr, 8)))
nr = this.xor32(nr, this.add32(this.mul32(this.add32(this.and32(nr, [0,63]), [0,add]), [0,c]), this.shl32(nr, 8)));
// nr2+=(nr2 << 8) ^ nr;
// nr2 = add(nr2, xor(shl(nr2, 8), nr))
nr2 = this.add32(nr2, this.xor32(this.shl32(nr2, 8), nr));
// add+=tmp;
add += c;
}
this.int31Write(result, nr, 0);
this.int31Write(result, nr2, 4);
return result;
};
Auth.randomInit = function(seed1, seed2) {
return {
max_value: 0x3FFFFFFF,
max_value_dbl: 0x3FFFFFFF,
seed1: seed1 % 0x3FFFFFFF,
seed2: seed2 % 0x3FFFFFFF
};
};
Auth.myRnd = function(r){
r.seed1 = (r.seed1 * 3 + r.seed2) % r.max_value;
r.seed2 = (r.seed1 + r.seed2 + 33) % r.max_value;
return r.seed1 / r.max_value_dbl;
};
Auth.scramble323 = function(message, password) {
var to = new Buffer(8),
hashPass = this.hashPassword(password),
hashMessage = this.hashPassword(message.slice(0, 8)),
seed1 = this.int32Read(hashPass, 0) ^ this.int32Read(hashMessage, 0),
seed2 = this.int32Read(hashPass, 4) ^ this.int32Read(hashMessage, 4),
r = this.randomInit(seed1, seed2);
for (var i = 0; i < 8; i++){
to[i] = Math.floor(this.myRnd(r) * 31) + 64;
}
var extra = (Math.floor(this.myRnd(r) * 31));
for (var i = 0; i < 8; i++){
to[i] ^= extra;
}
return to;
};
Auth.fmt32 = function(x){
var a = x[0].toString(16),
b = x[1].toString(16);
if (a.length == 1) a = '000'+a;
if (a.length == 2) a = '00'+a;
if (a.length == 3) a = '0'+a;
if (b.length == 1) b = '000'+b;
if (b.length == 2) b = '00'+b;
if (b.length == 3) b = '0'+b;
return '' + a + '/' + b;
};
Auth.xor32 = function(a,b){
return [a[0] ^ b[0], a[1] ^ b[1]];
};
Auth.add32 = function(a,b){
var w1 = a[1] + b[1],
w2 = a[0] + b[0] + ((w1 & 0xFFFF0000) >> 16);
return [w2 & 0xFFFF, w1 & 0xFFFF];
};
Auth.mul32 = function(a,b){
// based on this example of multiplying 32b ints using 16b
// http://www.dsprelated.com/showmessage/89790/1.php
var w1 = a[1] * b[1],
w2 = (((a[1] * b[1]) >> 16) & 0xFFFF) + ((a[0] * b[1]) & 0xFFFF) + (a[1] * b[0] & 0xFFFF);
return [w2 & 0xFFFF, w1 & 0xFFFF];
};
Auth.and32 = function(a,b){
return [a[0] & b[0], a[1] & b[1]];
};
Auth.shl32 = function(a,b){
// assume b is 16 or less
var w1 = a[1] << b,
w2 = (a[0] << b) | ((w1 & 0xFFFF0000) >> 16);
return [w2 & 0xFFFF, w1 & 0xFFFF];
};
Auth.int31Write = function(buffer, number, offset) {
buffer[offset] = (number[0] >> 8) & 0x7F;
buffer[offset + 1] = (number[0]) & 0xFF;
buffer[offset + 2] = (number[1] >> 8) & 0xFF;
buffer[offset + 3] = (number[1]) & 0xFF;
};
Auth.int32Read = function(buffer, offset){
return (buffer[offset] << 24)
+ (buffer[offset+1] << 16)
+ (buffer[offset+2] << 8)
+ (buffer[offset+3]);
};
exports.BIG5_CHINESE_CI = 1;
exports.LATIN2_CZECH_CS = 2;
exports.DEC8_SWEDISH_CI = 3;
exports.CP850_GENERAL_CI = 4;
exports.LATIN1_GERMAN1_CI = 5;
exports.HP8_ENGLISH_CI = 6;
exports.KOI8R_GENERAL_CI = 7;
exports.LATIN1_SWEDISH_CI = 8;
exports.LATIN2_GENERAL_CI = 9;
exports.SWE7_SWEDISH_CI = 10;
exports.ASCII_GENERAL_CI = 11;
exports.UJIS_JAPANESE_CI = 12;
exports.SJIS_JAPANESE_CI = 13;
exports.CP1251_BULGARIAN_CI = 14;
exports.LATIN1_DANISH_CI = 15;
exports.HEBREW_GENERAL_CI = 16;
exports.TIS620_THAI_CI = 18;
exports.EUCKR_KOREAN_CI = 19;
exports.LATIN7_ESTONIAN_CS = 20;
exports.LATIN2_HUNGARIAN_CI = 21;
exports.KOI8U_GENERAL_CI = 22;
exports.CP1251_UKRAINIAN_CI = 23;
exports.GB2312_CHINESE_CI = 24;
exports.GREEK_GENERAL_CI = 25;
exports.CP1250_GENERAL_CI = 26;
exports.LATIN2_CROATIAN_CI = 27;
exports.GBK_CHINESE_CI = 28;
exports.CP1257_LITHUANIAN_CI = 29;
exports.LATIN5_TURKISH_CI = 30;
exports.LATIN1_GERMAN2_CI = 31;
exports.ARMSCII8_GENERAL_CI = 32;
exports.UTF8_GENERAL_CI = 33;
exports.CP1250_CZECH_CS = 34;
exports.UCS2_GENERAL_CI = 35;
exports.CP866_GENERAL_CI = 36;
exports.KEYBCS2_GENERAL_CI = 37;
exports.MACCE_GENERAL_CI = 38;
exports.MACROMAN_GENERAL_CI = 39;
exports.CP852_GENERAL_CI = 40;
exports.LATIN7_GENERAL_CI = 41;
exports.LATIN7_GENERAL_CS = 42;
exports.MACCE_BIN = 43;
exports.CP1250_CROATIAN_CI = 44;
exports.UTF8MB4_GENERAL_CI = 45;
exports.UTF8MB4_BIN = 46;
exports.LATIN1_BIN = 47;
exports.LATIN1_GENERAL_CI = 48;
exports.LATIN1_GENERAL_CS = 49;
exports.CP1251_BIN = 50;
exports.CP1251_GENERAL_CI = 51;
exports.CP1251_GENERAL_CS = 52;
exports.MACROMAN_BIN = 53;
exports.UTF16_GENERAL_CI = 54;
exports.UTF16_BIN = 55;
exports.UTF16LE_GENERAL_CI = 56;
exports.CP1256_GENERAL_CI = 57;
exports.CP1257_BIN = 58;
exports.CP1257_GENERAL_CI = 59;
exports.UTF32_GENERAL_CI = 60;
exports.UTF32_BIN = 61;
exports.UTF16LE_BIN = 62;
exports.BINARY = 63;
exports.ARMSCII8_BIN = 64;
exports.ASCII_BIN = 65;
exports.CP1250_BIN = 66;
exports.CP1256_BIN = 67;
exports.CP866_BIN = 68;
exports.DEC8_BIN = 69;
exports.GREEK_BIN = 70;
exports.HEBREW_BIN = 71;
exports.HP8_BIN = 72;
exports.KEYBCS2_BIN = 73;
exports.KOI8R_BIN = 74;
exports.KOI8U_BIN = 75;
exports.LATIN2_BIN = 77;
exports.LATIN5_BIN = 78;
exports.LATIN7_BIN = 79;
exports.CP850_BIN = 80;
exports.CP852_BIN = 81;
exports.SWE7_BIN = 82;
exports.UTF8_BIN = 83;
exports.BIG5_BIN = 84;
exports.EUCKR_BIN = 85;
exports.GB2312_BIN = 86;
exports.GBK_BIN = 87;
exports.SJIS_BIN = 88;
exports.TIS620_BIN = 89;
exports.UCS2_BIN = 90;
exports.UJIS_BIN = 91;
exports.GEOSTD8_GENERAL_CI = 92;
exports.GEOSTD8_BIN = 93;
exports.LATIN1_SPANISH_CI = 94;
exports.CP932_JAPANESE_CI = 95;
exports.CP932_BIN = 96;
exports.EUCJPMS_JAPANESE_CI = 97;
exports.EUCJPMS_BIN = 98;
exports.CP1250_POLISH_CI = 99;
exports.UTF16_UNICODE_CI = 101;
exports.UTF16_ICELANDIC_CI = 102;
exports.UTF16_LATVIAN_CI = 103;
exports.UTF16_ROMANIAN_CI = 104;
exports.UTF16_SLOVENIAN_CI = 105;
exports.UTF16_POLISH_CI = 106;
exports.UTF16_ESTONIAN_CI = 107;
exports.UTF16_SPANISH_CI = 108;
exports.UTF16_SWEDISH_CI = 109;
exports.UTF16_TURKISH_CI = 110;
exports.UTF16_CZECH_CI = 111;
exports.UTF16_DANISH_CI = 112;
exports.UTF16_LITHUANIAN_CI = 113;
exports.UTF16_SLOVAK_CI = 114;
exports.UTF16_SPANISH2_CI = 115;
exports.UTF16_ROMAN_CI = 116;
exports.UTF16_PERSIAN_CI = 117;
exports.UTF16_ESPERANTO_CI = 118;
exports.UTF16_HUNGARIAN_CI = 119;
exports.UTF16_SINHALA_CI = 120;
exports.UTF16_GERMAN2_CI = 121;
exports.UTF16_CROATIAN_MYSQL561_CI = 122;
exports.UTF16_UNICODE_520_CI = 123;
exports.UTF16_VIETNAMESE_CI = 124;
exports.UCS2_UNICODE_CI = 128;
exports.UCS2_ICELANDIC_CI = 129;
exports.UCS2_LATVIAN_CI = 130;
exports.UCS2_ROMANIAN_CI = 131;
exports.UCS2_SLOVENIAN_CI = 132;
exports.UCS2_POLISH_CI = 133;
exports.UCS2_ESTONIAN_CI = 134;
exports.UCS2_SPANISH_CI = 135;
exports.UCS2_SWEDISH_CI = 136;
exports.UCS2_TURKISH_CI = 137;
exports.UCS2_CZECH_CI = 138;
exports.UCS2_DANISH_CI = 139;
exports.UCS2_LITHUANIAN_CI = 140;
exports.UCS2_SLOVAK_CI = 141;
exports.UCS2_SPANISH2_CI = 142;
exports.UCS2_ROMAN_CI = 143;
exports.UCS2_PERSIAN_CI = 144;
exports.UCS2_ESPERANTO_CI = 145;
exports.UCS2_HUNGARIAN_CI = 146;
exports.UCS2_SINHALA_CI = 147;
exports.UCS2_GERMAN2_CI = 148;
exports.UCS2_CROATIAN_MYSQL561_CI = 149;
exports.UCS2_UNICODE_520_CI = 150;
exports.UCS2_VIETNAMESE_CI = 151;
exports.UCS2_GENERAL_MYSQL500_CI = 159;
exports.UTF32_UNICODE_CI = 160;
exports.UTF32_ICELANDIC_CI = 161;
exports.UTF32_LATVIAN_CI = 162;
exports.UTF32_ROMANIAN_CI = 163;
exports.UTF32_SLOVENIAN_CI = 164;
exports.UTF32_POLISH_CI = 165;
exports.UTF32_ESTONIAN_CI = 166;
exports.UTF32_SPANISH_CI = 167;
exports.UTF32_SWEDISH_CI = 168;
exports.UTF32_TURKISH_CI = 169;
exports.UTF32_CZECH_CI = 170;
exports.UTF32_DANISH_CI = 171;
exports.UTF32_LITHUANIAN_CI = 172;
exports.UTF32_SLOVAK_CI = 173;
exports.UTF32_SPANISH2_CI = 174;
exports.UTF32_ROMAN_CI = 175;
exports.UTF32_PERSIAN_CI = 176;
exports.UTF32_ESPERANTO_CI = 177;
exports.UTF32_HUNGARIAN_CI = 178;
exports.UTF32_SINHALA_CI = 179;
exports.UTF32_GERMAN2_CI = 180;
exports.UTF32_CROATIAN_MYSQL561_CI = 181;
exports.UTF32_UNICODE_520_CI = 182;
exports.UTF32_VIETNAMESE_CI = 183;
exports.UTF8_UNICODE_CI = 192;
exports.UTF8_ICELANDIC_CI = 193;
exports.UTF8_LATVIAN_CI = 194;
exports.UTF8_ROMANIAN_CI = 195;
exports.UTF8_SLOVENIAN_CI = 196;
exports.UTF8_POLISH_CI = 197;
exports.UTF8_ESTONIAN_CI = 198;
exports.UTF8_SPANISH_CI = 199;
exports.UTF8_SWEDISH_CI = 200;
exports.UTF8_TURKISH_CI = 201;
exports.UTF8_CZECH_CI = 202;
exports.UTF8_DANISH_CI = 203;
exports.UTF8_LITHUANIAN_CI = 204;
exports.UTF8_SLOVAK_CI = 205;
exports.UTF8_SPANISH2_CI = 206;
exports.UTF8_ROMAN_CI = 207;
exports.UTF8_PERSIAN_CI = 208;
exports.UTF8_ESPERANTO_CI = 209;
exports.UTF8_HUNGARIAN_CI = 210;
exports.UTF8_SINHALA_CI = 211;
exports.UTF8_GERMAN2_CI = 212;
exports.UTF8_CROATIAN_MYSQL561_CI = 213;
exports.UTF8_UNICODE_520_CI = 214;
exports.UTF8_VIETNAMESE_CI = 215;
exports.UTF8_GENERAL_MYSQL500_CI = 223;
exports.UTF8MB4_UNICODE_CI = 224;
exports.UTF8MB4_ICELANDIC_CI = 225;
exports.UTF8MB4_LATVIAN_CI = 226;
exports.UTF8MB4_ROMANIAN_CI = 227;
exports.UTF8MB4_SLOVENIAN_CI = 228;
exports.UTF8MB4_POLISH_CI = 229;
exports.UTF8MB4_ESTONIAN_CI = 230;
exports.UTF8MB4_SPANISH_CI = 231;
exports.UTF8MB4_SWEDISH_CI = 232;
exports.UTF8MB4_TURKISH_CI = 233;
exports.UTF8MB4_CZECH_CI = 234;
exports.UTF8MB4_DANISH_CI = 235;
exports.UTF8MB4_LITHUANIAN_CI = 236;
exports.UTF8MB4_SLOVAK_CI = 237;
exports.UTF8MB4_SPANISH2_CI = 238;
exports.UTF8MB4_ROMAN_CI = 239;
exports.UTF8MB4_PERSIAN_CI = 240;
exports.UTF8MB4_ESPERANTO_CI = 241;
exports.UTF8MB4_HUNGARIAN_CI = 242;
exports.UTF8MB4_SINHALA_CI = 243;
exports.UTF8MB4_GERMAN2_CI = 244;
exports.UTF8MB4_CROATIAN_MYSQL561_CI = 245;
exports.UTF8MB4_UNICODE_520_CI = 246;
exports.UTF8MB4_VIETNAMESE_CI = 247;
exports.UTF8_GENERAL50_CI = 253;
// short aliases
exports.ARMSCII8 = exports.ARMSCII8_GENERAL_CI;
exports.ASCII = exports.ASCII_GENERAL_CI;
exports.BIG5 = exports.BIG5_CHINESE_CI;
exports.BINARY = exports.BINARY;
exports.CP1250 = exports.CP1250_GENERAL_CI;
exports.CP1251 = exports.CP1251_GENERAL_CI;
exports.CP1256 = exports.CP1256_GENERAL_CI;
exports.CP1257 = exports.CP1257_GENERAL_CI;
exports.CP866 = exports.CP866_GENERAL_CI;
exports.CP850 = exports.CP850_GENERAL_CI;
exports.CP852 = exports.CP852_GENERAL_CI;
exports.CP932 = exports.CP932_JAPANESE_CI;
exports.DEC8 = exports.DEC8_SWEDISH_CI;
exports.EUCJPMS = exports.EUCJPMS_JAPANESE_CI;
exports.EUCKR = exports.EUCKR_KOREAN_CI;
exports.GB2312 = exports.GB2312_CHINESE_CI;
exports.GBK = exports.GBK_CHINESE_CI;
exports.GEOSTD8 = exports.GEOSTD8_GENERAL_CI;
exports.GREEK = exports.GREEK_GENERAL_CI;
exports.HEBREW = exports.HEBREW_GENERAL_CI;
exports.HP8 = exports.HP8_ENGLISH_CI;
exports.KEYBCS2 = exports.KEYBCS2_GENERAL_CI;
exports.KOI8R = exports.KOI8R_GENERAL_CI;
exports.KOI8U = exports.KOI8U_GENERAL_CI;
exports.LATIN1 = exports.LATIN1_SWEDISH_CI;
exports.LATIN2 = exports.LATIN2_GENERAL_CI;
exports.LATIN5 = exports.LATIN5_TURKISH_CI;
exports.LATIN7 = exports.LATIN7_GENERAL_CI;
exports.MACCE = exports.MACCE_GENERAL_CI;
exports.MACROMAN = exports.MACROMAN_GENERAL_CI;
exports.SJIS = exports.SJIS_JAPANESE_CI;
exports.SWE7 = exports.SWE7_SWEDISH_CI;
exports.TIS620 = exports.TIS620_THAI_CI;
exports.UCS2 = exports.UCS2_GENERAL_CI;
exports.UJIS = exports.UJIS_JAPANESE_CI;
exports.UTF16 = exports.UTF16_GENERAL_CI;
exports.UTF16LE = exports.UTF16LE_GENERAL_CI;
exports.UTF8 = exports.UTF8_GENERAL_CI;
exports.UTF8MB4 = exports.UTF8MB4_GENERAL_CI;
exports.UTF32 = exports.UTF32_GENERAL_CI;
// Manually extracted from mysql-5.5.23/include/mysql_com.h
exports.CLIENT_LONG_PASSWORD = 1; /* new more secure passwords */
exports.CLIENT_FOUND_ROWS = 2; /* Found instead of affected rows */
exports.CLIENT_LONG_FLAG = 4; /* Get all column flags */
exports.CLIENT_CONNECT_WITH_DB = 8; /* One can specify db on connect */
exports.CLIENT_NO_SCHEMA = 16; /* Don't allow database.table.column */
exports.CLIENT_COMPRESS = 32; /* Can use compression protocol */
exports.CLIENT_ODBC = 64; /* Odbc client */
exports.CLIENT_LOCAL_FILES = 128; /* Can use LOAD DATA LOCAL */
exports.CLIENT_IGNORE_SPACE = 256; /* Ignore spaces before '(' */
exports.CLIENT_PROTOCOL_41 = 512; /* New 4.1 protocol */
exports.CLIENT_INTERACTIVE = 1024; /* This is an interactive client */
exports.CLIENT_SSL = 2048; /* Switch to SSL after handshake */
exports.CLIENT_IGNORE_SIGPIPE = 4096; /* IGNORE sigpipes */
exports.CLIENT_TRANSACTIONS = 8192; /* Client knows about transactions */
exports.CLIENT_RESERVED = 16384; /* Old flag for 4.1 protocol */
exports.CLIENT_SECURE_CONNECTION = 32768; /* New 4.1 authentication */
exports.CLIENT_MULTI_STATEMENTS = 65536; /* Enable/disable multi-stmt support */
exports.CLIENT_MULTI_RESULTS = 131072; /* Enable/disable multi-results */
exports.CLIENT_PS_MULTI_RESULTS = 262144; /* Multi-results in PS-protocol */
exports.CLIENT_PLUGIN_AUTH = 524288; /* Client supports plugin authentication */
exports.CLIENT_SSL_VERIFY_SERVER_CERT = 1073741824;
exports.CLIENT_REMEMBER_OPTIONS = 2147483648;
/**
* MySQL error constants
*
* !! Generated by generate-error-constants.js, do not modify by hand !!
*/
exports.EE_CANTCREATEFILE = 1;
exports.EE_READ = 2;
exports.EE_WRITE = 3;
exports.EE_BADCLOSE = 4;
exports.EE_OUTOFMEMORY = 5;
exports.EE_DELETE = 6;
exports.EE_LINK = 7;
exports.EE_EOFERR = 9;
exports.EE_CANTLOCK = 10;
exports.EE_CANTUNLOCK = 11;
exports.EE_DIR = 12;
exports.EE_STAT = 13;
exports.EE_CANT_CHSIZE = 14;
exports.EE_CANT_OPEN_STREAM = 15;
exports.EE_GETWD = 16;
exports.EE_SETWD = 17;
exports.EE_LINK_WARNING = 18;
exports.EE_OPEN_WARNING = 19;
exports.EE_DISK_FULL = 20;
exports.EE_CANT_MKDIR = 21;
exports.EE_UNKNOWN_CHARSET = 22;
exports.EE_OUT_OF_FILERESOURCES = 23;
exports.EE_CANT_READLINK = 24;
exports.EE_CANT_SYMLINK = 25;
exports.EE_REALPATH = 26;
exports.EE_SYNC = 27;
exports.EE_UNKNOWN_COLLATION = 28;
exports.EE_FILENOTFOUND = 29;
exports.EE_FILE_NOT_CLOSED = 30;
exports.EE_CHANGE_OWNERSHIP = 31;
exports.EE_CHANGE_PERMISSIONS = 32;
exports.EE_CANT_SEEK = 33;
exports.HA_ERR_KEY_NOT_FOUND = 120;
exports.HA_ERR_FOUND_DUPP_KEY = 121;
exports.HA_ERR_INTERNAL_ERROR = 122;
exports.HA_ERR_RECORD_CHANGED = 123;
exports.HA_ERR_WRONG_INDEX = 124;
exports.HA_ERR_CRASHED = 126;
exports.HA_ERR_WRONG_IN_RECORD = 127;
exports.HA_ERR_OUT_OF_MEM = 128;
exports.HA_ERR_NOT_A_TABLE = 130;
exports.HA_ERR_WRONG_COMMAND = 131;
exports.HA_ERR_OLD_FILE = 132;
exports.HA_ERR_NO_ACTIVE_RECORD = 133;
exports.HA_ERR_RECORD_DELETED = 134;
exports.HA_ERR_RECORD_FILE_FULL = 135;
exports.HA_ERR_INDEX_FILE_FULL = 136;
exports.HA_ERR_END_OF_FILE = 137;
exports.HA_ERR_UNSUPPORTED = 138;
exports.HA_ERR_TO_BIG_ROW = 139;
exports.HA_WRONG_CREATE_OPTION = 140;
exports.HA_ERR_FOUND_DUPP_UNIQUE = 141;
exports.HA_ERR_UNKNOWN_CHARSET = 142;
exports.HA_ERR_WRONG_MRG_TABLE_DEF = 143;
exports.HA_ERR_CRASHED_ON_REPAIR = 144;
exports.HA_ERR_CRASHED_ON_USAGE = 145;
exports.HA_ERR_LOCK_WAIT_TIMEOUT = 146;
exports.HA_ERR_LOCK_TABLE_FULL = 147;
exports.HA_ERR_READ_ONLY_TRANSACTION = 148;
exports.HA_ERR_LOCK_DEADLOCK = 149;
exports.HA_ERR_CANNOT_ADD_FOREIGN = 150;
exports.HA_ERR_NO_REFERENCED_ROW = 151;
exports.HA_ERR_ROW_IS_REFERENCED = 152;
exports.HA_ERR_NO_SAVEPOINT = 153;
exports.HA_ERR_NON_UNIQUE_BLOCK_SIZE = 154;
exports.HA_ERR_NO_SUCH_TABLE = 155;
exports.HA_ERR_TABLE_EXIST = 156;
exports.HA_ERR_NO_CONNECTION = 157;
exports.HA_ERR_NULL_IN_SPATIAL = 158;
exports.HA_ERR_TABLE_DEF_CHANGED = 159;
exports.HA_ERR_NO_PARTITION_FOUND = 160;
exports.HA_ERR_RBR_LOGGING_FAILED = 161;
exports.HA_ERR_DROP_INDEX_FK = 162;
exports.HA_ERR_FOREIGN_DUPLICATE_KEY = 163;
exports.HA_ERR_TABLE_NEEDS_UPGRADE = 164;
exports.HA_ERR_TABLE_READONLY = 165;
exports.HA_ERR_AUTOINC_READ_FAILED = 166;
exports.HA_ERR_AUTOINC_ERANGE = 167;
exports.HA_ERR_GENERIC = 168;
exports.HA_ERR_RECORD_IS_THE_SAME = 169;
exports.HA_ERR_LOGGING_IMPOSSIBLE = 170;
exports.HA_ERR_CORRUPT_EVENT = 171;
exports.HA_ERR_NEW_FILE = 172;
exports.HA_ERR_ROWS_EVENT_APPLY = 173;
exports.HA_ERR_INITIALIZATION = 174;
exports.HA_ERR_FILE_TOO_SHORT = 175;
exports.HA_ERR_WRONG_CRC = 176;
exports.HA_ERR_TOO_MANY_CONCURRENT_TRXS = 177;
exports.HA_ERR_NOT_IN_LOCK_PARTITIONS = 178;
exports.HA_ERR_INDEX_COL_TOO_LONG = 179;
exports.HA_ERR_INDEX_CORRUPT = 180;
exports.HA_ERR_UNDO_REC_TOO_BIG = 181;
exports.HA_FTS_INVALID_DOCID = 182;
exports.HA_ERR_TABLE_IN_FK_CHECK = 183;
exports.HA_ERR_TABLESPACE_EXISTS = 184;
exports.HA_ERR_TOO_MANY_FIELDS = 185;
exports.HA_ERR_ROW_IN_WRONG_PARTITION = 186;
exports.HA_ERR_INNODB_READ_ONLY = 187;
exports.HA_ERR_FTS_EXCEED_RESULT_CACHE_LIMIT = 188;
exports.HA_ERR_TEMP_FILE_WRITE_FAILURE = 189;
exports.HA_ERR_INNODB_FORCED_RECOVERY = 190;
exports.HA_ERR_FTS_TOO_MANY_WORDS_IN_PHRASE = 191;
exports.ER_HASHCHK = 1000;
exports.ER_NISAMCHK = 1001;
exports.ER_NO = 1002;
exports.ER_YES = 1003;
exports.ER_CANT_CREATE_FILE = 1004;
exports.ER_CANT_CREATE_TABLE = 1005;
exports.ER_CANT_CREATE_DB = 1006;
exports.ER_DB_CREATE_EXISTS = 1007;
exports.ER_DB_DROP_EXISTS = 1008;
exports.ER_DB_DROP_DELETE = 1009;
exports.ER_DB_DROP_RMDIR = 1010;
exports.ER_CANT_DELETE_FILE = 1011;
exports.ER_CANT_FIND_SYSTEM_REC = 1012;
exports.ER_CANT_GET_STAT = 1013;
exports.ER_CANT_GET_WD = 1014;
exports.ER_CANT_LOCK = 1015;
exports.ER_CANT_OPEN_FILE = 1016;
exports.ER_FILE_NOT_FOUND = 1017;
exports.ER_CANT_READ_DIR = 1018;
exports.ER_CANT_SET_WD = 1019;
exports.ER_CHECKREAD = 1020;
exports.ER_DISK_FULL = 1021;
exports.ER_DUP_KEY = 1022;
exports.ER_ERROR_ON_CLOSE = 1023;
exports.ER_ERROR_ON_READ = 1024;
exports.ER_ERROR_ON_RENAME = 1025;
exports.ER_ERROR_ON_WRITE = 1026;
exports.ER_FILE_USED = 1027;
exports.ER_FILSORT_ABORT = 1028;
exports.ER_FORM_NOT_FOUND = 1029;
exports.ER_GET_ERRNO = 1030;
exports.ER_ILLEGAL_HA = 1031;
exports.ER_KEY_NOT_FOUND = 1032;
exports.ER_NOT_FORM_FILE = 1033;
exports.ER_NOT_KEYFILE = 1034;
exports.ER_OLD_KEYFILE = 1035;
exports.ER_OPEN_AS_READONLY = 1036;
exports.ER_OUTOFMEMORY = 1037;
exports.ER_OUT_OF_SORTMEMORY = 1038;
exports.ER_UNEXPECTED_EOF = 1039;
exports.ER_CON_COUNT_ERROR = 1040;
exports.ER_OUT_OF_RESOURCES = 1041;
exports.ER_BAD_HOST_ERROR = 1042;
exports.ER_HANDSHAKE_ERROR = 1043;
exports.ER_DBACCESS_DENIED_ERROR = 1044;
exports.ER_ACCESS_DENIED_ERROR = 1045;
exports.ER_NO_DB_ERROR = 1046;
exports.ER_UNKNOWN_COM_ERROR = 1047;
exports.ER_BAD_NULL_ERROR = 1048;
exports.ER_BAD_DB_ERROR = 1049;
exports.ER_TABLE_EXISTS_ERROR = 1050;
exports.ER_BAD_TABLE_ERROR = 1051;
exports.ER_NON_UNIQ_ERROR = 1052;
exports.ER_SERVER_SHUTDOWN = 1053;
exports.ER_BAD_FIELD_ERROR = 1054;
exports.ER_WRONG_FIELD_WITH_GROUP = 1055;
exports.ER_WRONG_GROUP_FIELD = 1056;
exports.ER_WRONG_SUM_SELECT = 1057;
exports.ER_WRONG_VALUE_COUNT = 1058;
exports.ER_TOO_LONG_IDENT = 1059;
exports.ER_DUP_FIELDNAME = 1060;
exports.ER_DUP_KEYNAME = 1061;
exports.ER_DUP_ENTRY = 1062;
exports.ER_WRONG_FIELD_SPEC = 1063;
exports.ER_PARSE_ERROR = 1064;
exports.ER_EMPTY_QUERY = 1065;
exports.ER_NONUNIQ_TABLE = 1066;
exports.ER_INVALID_DEFAULT = 1067;
exports.ER_MULTIPLE_PRI_KEY = 1068;
exports.ER_TOO_MANY_KEYS = 1069;
exports.ER_TOO_MANY_KEY_PARTS = 1070;
exports.ER_TOO_LONG_KEY = 1071;
exports.ER_KEY_COLUMN_DOES_NOT_EXITS = 1072;
exports.ER_BLOB_USED_AS_KEY = 1073;
exports.ER_TOO_BIG_FIELDLENGTH = 1074;
exports.ER_WRONG_AUTO_KEY = 1075;
exports.ER_READY = 1076;
exports.ER_NORMAL_SHUTDOWN = 1077;
exports.ER_GOT_SIGNAL = 1078;
exports.ER_SHUTDOWN_COMPLETE = 1079;
exports.ER_FORCING_CLOSE = 1080;
exports.ER_IPSOCK_ERROR = 1081;
exports.ER_NO_SUCH_INDEX = 1082;
exports.ER_WRONG_FIELD_TERMINATORS = 1083;
exports.ER_BLOBS_AND_NO_TERMINATED = 1084;
exports.ER_TEXTFILE_NOT_READABLE = 1085;
exports.ER_FILE_EXISTS_ERROR = 1086;
exports.ER_LOAD_INFO = 1087;
exports.ER_ALTER_INFO = 1088;
exports.ER_WRONG_SUB_KEY = 1089;
exports.ER_CANT_REMOVE_ALL_FIELDS = 1090;
exports.ER_CANT_DROP_FIELD_OR_KEY = 1091;
exports.ER_INSERT_INFO = 1092;
exports.ER_UPDATE_TABLE_USED = 1093;
exports.ER_NO_SUCH_THREAD = 1094;
exports.ER_KILL_DENIED_ERROR = 1095;
exports.ER_NO_TABLES_USED = 1096;
exports.ER_TOO_BIG_SET = 1097;
exports.ER_NO_UNIQUE_LOGFILE = 1098;
exports.ER_TABLE_NOT_LOCKED_FOR_WRITE = 1099;
exports.ER_TABLE_NOT_LOCKED = 1100;
exports.ER_BLOB_CANT_HAVE_DEFAULT = 1101;
exports.ER_WRONG_DB_NAME = 1102;
exports.ER_WRONG_TABLE_NAME = 1103;
exports.ER_TOO_BIG_SELECT = 1104;
exports.ER_UNKNOWN_ERROR = 1105;
exports.ER_UNKNOWN_PROCEDURE = 1106;
exports.ER_WRONG_PARAMCOUNT_TO_PROCEDURE = 1107;
exports.ER_WRONG_PARAMETERS_TO_PROCEDURE = 1108;
exports.ER_UNKNOWN_TABLE = 1109;
exports.ER_FIELD_SPECIFIED_TWICE = 1110;
exports.ER_INVALID_GROUP_FUNC_USE = 1111;
exports.ER_UNSUPPORTED_EXTENSION = 1112;
exports.ER_TABLE_MUST_HAVE_COLUMNS = 1113;
exports.ER_RECORD_FILE_FULL = 1114;
exports.ER_UNKNOWN_CHARACTER_SET = 1115;
exports.ER_TOO_MANY_TABLES = 1116;
exports.ER_TOO_MANY_FIELDS = 1117;
exports.ER_TOO_BIG_ROWSIZE = 1118;
exports.ER_STACK_OVERRUN = 1119;
exports.ER_WRONG_OUTER_JOIN = 1120;
exports.ER_NULL_COLUMN_IN_INDEX = 1121;
exports.ER_CANT_FIND_UDF = 1122;
exports.ER_CANT_INITIALIZE_UDF = 1123;
exports.ER_UDF_NO_PATHS = 1124;
exports.ER_UDF_EXISTS = 1125;
exports.ER_CANT_OPEN_LIBRARY = 1126;
exports.ER_CANT_FIND_DL_ENTRY = 1127;
exports.ER_FUNCTION_NOT_DEFINED = 1128;
exports.ER_HOST_IS_BLOCKED = 1129;
exports.ER_HOST_NOT_PRIVILEGED = 1130;
exports.ER_PASSWORD_ANONYMOUS_USER = 1131;
exports.ER_PASSWORD_NOT_ALLOWED = 1132;
exports.ER_PASSWORD_NO_MATCH = 1133;
exports.ER_UPDATE_INFO = 1134;
exports.ER_CANT_CREATE_THREAD = 1135;
exports.ER_WRONG_VALUE_COUNT_ON_ROW = 1136;
exports.ER_CANT_REOPEN_TABLE = 1137;
exports.ER_INVALID_USE_OF_NULL = 1138;
exports.ER_REGEXP_ERROR = 1139;
exports.ER_MIX_OF_GROUP_FUNC_AND_FIELDS = 1140;
exports.ER_NONEXISTING_GRANT = 1141;
exports.ER_TABLEACCESS_DENIED_ERROR = 1142;
exports.ER_COLUMNACCESS_DENIED_ERROR = 1143;
exports.ER_ILLEGAL_GRANT_FOR_TABLE = 1144;
exports.ER_GRANT_WRONG_HOST_OR_USER = 1145;
exports.ER_NO_SUCH_TABLE = 1146;
exports.ER_NONEXISTING_TABLE_GRANT = 1147;
exports.ER_NOT_ALLOWED_COMMAND = 1148;
exports.ER_SYNTAX_ERROR = 1149;
exports.ER_DELAYED_CANT_CHANGE_LOCK = 1150;
exports.ER_TOO_MANY_DELAYED_THREADS = 1151;
exports.ER_ABORTING_CONNECTION = 1152;
exports.ER_NET_PACKET_TOO_LARGE = 1153;
exports.ER_NET_READ_ERROR_FROM_PIPE = 1154;
exports.ER_NET_FCNTL_ERROR = 1155;
exports.ER_NET_PACKETS_OUT_OF_ORDER = 1156;
exports.ER_NET_UNCOMPRESS_ERROR = 1157;
exports.ER_NET_READ_ERROR = 1158;
exports.ER_NET_READ_INTERRUPTED = 1159;
exports.ER_NET_ERROR_ON_WRITE = 1160;
exports.ER_NET_WRITE_INTERRUPTED = 1161;
exports.ER_TOO_LONG_STRING = 1162;
exports.ER_TABLE_CANT_HANDLE_BLOB = 1163;
exports.ER_TABLE_CANT_HANDLE_AUTO_INCREMENT = 1164;
exports.ER_DELAYED_INSERT_TABLE_LOCKED = 1165;
exports.ER_WRONG_COLUMN_NAME = 1166;
exports.ER_WRONG_KEY_COLUMN = 1167;
exports.ER_WRONG_MRG_TABLE = 1168;
exports.ER_DUP_UNIQUE = 1169;
exports.ER_BLOB_KEY_WITHOUT_LENGTH = 1170;
exports.ER_PRIMARY_CANT_HAVE_NULL = 1171;
exports.ER_TOO_MANY_ROWS = 1172;
exports.ER_REQUIRES_PRIMARY_KEY = 1173;
exports.ER_NO_RAID_COMPILED = 1174;
exports.ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE = 1175;
exports.ER_KEY_DOES_NOT_EXITS = 1176;
exports.ER_CHECK_NO_SUCH_TABLE = 1177;
exports.ER_CHECK_NOT_IMPLEMENTED = 1178;
exports.ER_CANT_DO_THIS_DURING_AN_TRANSACTION = 1179;
exports.ER_ERROR_DURING_COMMIT = 1180;
exports.ER_ERROR_DURING_ROLLBACK = 1181;
exports.ER_ERROR_DURING_FLUSH_LOGS = 1182;
exports.ER_ERROR_DURING_CHECKPOINT = 1183;
exports.ER_NEW_ABORTING_CONNECTION = 1184;
exports.ER_DUMP_NOT_IMPLEMENTED = 1185;
exports.ER_FLUSH_MASTER_BINLOG_CLOSED = 1186;
exports.ER_INDEX_REBUILD = 1187;
exports.ER_MASTER = 1188;
exports.ER_MASTER_NET_READ = 1189;
exports.ER_MASTER_NET_WRITE = 1190;
exports.ER_FT_MATCHING_KEY_NOT_FOUND = 1191;
exports.ER_LOCK_OR_ACTIVE_TRANSACTION = 1192;
exports.ER_UNKNOWN_SYSTEM_VARIABLE = 1193;
exports.ER_CRASHED_ON_USAGE = 1194;
exports.ER_CRASHED_ON_REPAIR = 1195;
exports.ER_WARNING_NOT_COMPLETE_ROLLBACK = 1196;
exports.ER_TRANS_CACHE_FULL = 1197;
exports.ER_SLAVE_MUST_STOP = 1198;
exports.ER_SLAVE_NOT_RUNNING = 1199;
exports.ER_BAD_SLAVE = 1200;
exports.ER_MASTER_INFO = 1201;
exports.ER_SLAVE_THREAD = 1202;
exports.ER_TOO_MANY_USER_CONNECTIONS = 1203;
exports.ER_SET_CONSTANTS_ONLY = 1204;
exports.ER_LOCK_WAIT_TIMEOUT = 1205;
exports.ER_LOCK_TABLE_FULL = 1206;
exports.ER_READ_ONLY_TRANSACTION = 1207;
exports.ER_DROP_DB_WITH_READ_LOCK = 1208;
exports.ER_CREATE_DB_WITH_READ_LOCK = 1209;
exports.ER_WRONG_ARGUMENTS = 1210;
exports.ER_NO_PERMISSION_TO_CREATE_USER = 1211;
exports.ER_UNION_TABLES_IN_DIFFERENT_DIR = 1212;
exports.ER_LOCK_DEADLOCK = 1213;
exports.ER_TABLE_CANT_HANDLE_FT = 1214;
exports.ER_CANNOT_ADD_FOREIGN = 1215;
exports.ER_NO_REFERENCED_ROW = 1216;
exports.ER_ROW_IS_REFERENCED = 1217;
exports.ER_CONNECT_TO_MASTER = 1218;
exports.ER_QUERY_ON_MASTER = 1219;
exports.ER_ERROR_WHEN_EXECUTING_COMMAND = 1220;
exports.ER_WRONG_USAGE = 1221;
exports.ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT = 1222;
exports.ER_CANT_UPDATE_WITH_READLOCK = 1223;
exports.ER_MIXING_NOT_ALLOWED = 1224;
exports.ER_DUP_ARGUMENT = 1225;
exports.ER_USER_LIMIT_REACHED = 1226;
exports.ER_SPECIFIC_ACCESS_DENIED_ERROR = 1227;
exports.ER_LOCAL_VARIABLE = 1228;
exports.ER_GLOBAL_VARIABLE = 1229;
exports.ER_NO_DEFAULT = 1230;
exports.ER_WRONG_VALUE_FOR_VAR = 1231;
exports.ER_WRONG_TYPE_FOR_VAR = 1232;
exports.ER_VAR_CANT_BE_READ = 1233;
exports.ER_CANT_USE_OPTION_HERE = 1234;
exports.ER_NOT_SUPPORTED_YET = 1235;
exports.ER_MASTER_FATAL_ERROR_READING_BINLOG = 1236;
exports.ER_SLAVE_IGNORED_TABLE = 1237;
exports.ER_INCORRECT_GLOBAL_LOCAL_VAR = 1238;
exports.ER_WRONG_FK_DEF = 1239;
exports.ER_KEY_REF_DO_NOT_MATCH_TABLE_REF = 1240;
exports.ER_OPERAND_COLUMNS = 1241;
exports.ER_SUBQUERY_NO_ = 1242;
exports.ER_UNKNOWN_STMT_HANDLER = 1243;
exports.ER_CORRUPT_HELP_DB = 1244;
exports.ER_CYCLIC_REFERENCE = 1245;
exports.ER_AUTO_CONVERT = 1246;
exports.ER_ILLEGAL_REFERENCE = 1247;
exports.ER_DERIVED_MUST_HAVE_ALIAS = 1248;
exports.ER_SELECT_REDUCED = 1249;
exports.ER_TABLENAME_NOT_ALLOWED_HERE = 1250;
exports.ER_NOT_SUPPORTED_AUTH_MODE = 1251;
exports.ER_SPATIAL_CANT_HAVE_NULL = 1252;
exports.ER_COLLATION_CHARSET_MISMATCH = 1253;
exports.ER_SLAVE_WAS_RUNNING = 1254;
exports.ER_SLAVE_WAS_NOT_RUNNING = 1255;
exports.ER_TOO_BIG_FOR_UNCOMPRESS = 1256;
exports.ER_ZLIB_Z_MEM_ERROR = 1257;
exports.ER_ZLIB_Z_BUF_ERROR = 1258;
exports.ER_ZLIB_Z_DATA_ERROR = 1259;
exports.ER_CUT_VALUE_GROUP_CONCAT = 1260;
exports.ER_WARN_TOO_FEW_RECORDS = 1261;
exports.ER_WARN_TOO_MANY_RECORDS = 1262;
exports.ER_WARN_NULL_TO_NOTNULL = 1263;
exports.ER_WARN_DATA_OUT_OF_RANGE = 1264;
exports.WARN_DATA_TRUNCATED = 1265;
exports.ER_WARN_USING_OTHER_HANDLER = 1266;
exports.ER_CANT_AGGREGATE_ = 1267;
exports.ER_DROP_USER = 1268;
exports.ER_REVOKE_GRANTS = 1269;
exports.ER_CANT_AGGREGATE_ = 1270;
exports.ER_CANT_AGGREGATE_NCOLLATIONS = 1271;
exports.ER_VARIABLE_IS_NOT_STRUCT = 1272;
exports.ER_UNKNOWN_COLLATION = 1273;
exports.ER_SLAVE_IGNORED_SSL_PARAMS = 1274;
exports.ER_SERVER_IS_IN_SECURE_AUTH_MODE = 1275;
exports.ER_WARN_FIELD_RESOLVED = 1276;
exports.ER_BAD_SLAVE_UNTIL_COND = 1277;
exports.ER_MISSING_SKIP_SLAVE = 1278;
exports.ER_UNTIL_COND_IGNORED = 1279;
exports.ER_WRONG_NAME_FOR_INDEX = 1280;
exports.ER_WRONG_NAME_FOR_CATALOG = 1281;
exports.ER_WARN_QC_RESIZE = 1282;
exports.ER_BAD_FT_COLUMN = 1283;
exports.ER_UNKNOWN_KEY_CACHE = 1284;
exports.ER_WARN_HOSTNAME_WONT_WORK = 1285;
exports.ER_UNKNOWN_STORAGE_ENGINE = 1286;
exports.ER_WARN_DEPRECATED_SYNTAX = 1287;
exports.ER_NON_UPDATABLE_TABLE = 1288;
exports.ER_FEATURE_DISABLED = 1289;
exports.ER_OPTION_PREVENTS_STATEMENT = 1290;
exports.ER_DUPLICATED_VALUE_IN_TYPE = 1291;
exports.ER_TRUNCATED_WRONG_VALUE = 1292;
exports.ER_TOO_MUCH_AUTO_TIMESTAMP_COLS = 1293;
exports.ER_INVALID_ON_UPDATE = 1294;
exports.ER_UNSUPPORTED_PS = 1295;
exports.ER_GET_ERRMSG = 1296;
exports.ER_GET_TEMPORARY_ERRMSG = 1297;
exports.ER_UNKNOWN_TIME_ZONE = 1298;
exports.ER_WARN_INVALID_TIMESTAMP = 1299;
exports.ER_INVALID_CHARACTER_STRING = 1300;
exports.ER_WARN_ALLOWED_PACKET_OVERFLOWED = 1301;
exports.ER_CONFLICTING_DECLARATIONS = 1302;
exports.ER_SP_NO_RECURSIVE_CREATE = 1303;
exports.ER_SP_ALREADY_EXISTS = 1304;
exports.ER_SP_DOES_NOT_EXIST = 1305;
exports.ER_SP_DROP_FAILED = 1306;
exports.ER_SP_STORE_FAILED = 1307;
exports.ER_SP_LILABEL_MISMATCH = 1308;
exports.ER_SP_LABEL_REDEFINE = 1309;
exports.ER_SP_LABEL_MISMATCH = 1310;
exports.ER_SP_UNINIT_VAR = 1311;
exports.ER_SP_BADSELECT = 1312;
exports.ER_SP_BADRETURN = 1313;
exports.ER_SP_BADSTATEMENT = 1314;
exports.ER_UPDATE_LOG_DEPRECATED_IGNORED = 1315;
exports.ER_UPDATE_LOG_DEPRECATED_TRANSLATED = 1316;
exports.ER_QUERY_INTERRUPTED = 1317;
exports.ER_SP_WRONG_NO_OF_ARGS = 1318;
exports.ER_SP_COND_MISMATCH = 1319;
exports.ER_SP_NORETURN = 1320;
exports.ER_SP_NORETURNEND = 1321;
exports.ER_SP_BAD_CURSOR_QUERY = 1322;
exports.ER_SP_BAD_CURSOR_SELECT = 1323;
exports.ER_SP_CURSOR_MISMATCH = 1324;
exports.ER_SP_CURSOR_ALREADY_OPEN = 1325;
exports.ER_SP_CURSOR_NOT_OPEN = 1326;
exports.ER_SP_UNDECLARED_VAR = 1327;
exports.ER_SP_WRONG_NO_OF_FETCH_ARGS = 1328;
exports.ER_SP_FETCH_NO_DATA = 1329;
exports.ER_SP_DUP_PARAM = 1330;
exports.ER_SP_DUP_VAR = 1331;
exports.ER_SP_DUP_COND = 1332;
exports.ER_SP_DUP_CURS = 1333;
exports.ER_SP_CANT_ALTER = 1334;
exports.ER_SP_SUBSELECT_NYI = 1335;
exports.ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG = 1336;
exports.ER_SP_VARCOND_AFTER_CURSHNDLR = 1337;
exports.ER_SP_CURSOR_AFTER_HANDLER = 1338;
exports.ER_SP_CASE_NOT_FOUND = 1339;
exports.ER_FPARSER_TOO_BIG_FILE = 1340;
exports.ER_FPARSER_BAD_HEADER = 1341;
exports.ER_FPARSER_EOF_IN_COMMENT = 1342;
exports.ER_FPARSER_ERROR_IN_PARAMETER = 1343;
exports.ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER = 1344;
exports.ER_VIEW_NO_EXPLAIN = 1345;
exports.ER_FRM_UNKNOWN_TYPE = 1346;
exports.ER_WRONG_OBJECT = 1347;
exports.ER_NONUPDATEABLE_COLUMN = 1348;
exports.ER_VIEW_SELECT_DERIVED = 1349;
exports.ER_VIEW_SELECT_CLAUSE = 1350;
exports.ER_VIEW_SELECT_VARIABLE = 1351;
exports.ER_VIEW_SELECT_TMPTABLE = 1352;
exports.ER_VIEW_WRONG_LIST = 1353;
exports.ER_WARN_VIEW_MERGE = 1354;
exports.ER_WARN_VIEW_WITHOUT_KEY = 1355;
exports.ER_VIEW_INVALID = 1356;
exports.ER_SP_NO_DROP_SP = 1357;
exports.ER_SP_GOTO_IN_HNDLR = 1358;
exports.ER_TRG_ALREADY_EXISTS = 1359;
exports.ER_TRG_DOES_NOT_EXIST = 1360;
exports.ER_TRG_ON_VIEW_OR_TEMP_TABLE = 1361;
exports.ER_TRG_CANT_CHANGE_ROW = 1362;
exports.ER_TRG_NO_SUCH_ROW_IN_TRG = 1363;
exports.ER_NO_DEFAULT_FOR_FIELD = 1364;
exports.ER_DIVISION_BY_ZERO = 1365;
exports.ER_TRUNCATED_WRONG_VALUE_FOR_FIELD = 1366;
exports.ER_ILLEGAL_VALUE_FOR_TYPE = 1367;
exports.ER_VIEW_NONUPD_CHECK = 1368;
exports.ER_VIEW_CHECK_FAILED = 1369;
exports.ER_PROCACCESS_DENIED_ERROR = 1370;
exports.ER_RELAY_LOG_FAIL = 1371;
exports.ER_PASSWD_LENGTH = 1372;
exports.ER_UNKNOWN_TARGET_BINLOG = 1373;
exports.ER_IO_ERR_LOG_INDEX_READ = 1374;
exports.ER_BINLOG_PURGE_PROHIBITED = 1375;
exports.ER_FSEEK_FAIL = 1376;
exports.ER_BINLOG_PURGE_FATAL_ERR = 1377;
exports.ER_LOG_IN_USE = 1378;
exports.ER_LOG_PURGE_UNKNOWN_ERR = 1379;
exports.ER_RELAY_LOG_INIT = 1380;
exports.ER_NO_BINARY_LOGGING = 1381;
exports.ER_RESERVED_SYNTAX = 1382;
exports.ER_WSAS_FAILED = 1383;
exports.ER_DIFF_GROUPS_PROC = 1384;
exports.ER_NO_GROUP_FOR_PROC = 1385;
exports.ER_ORDER_WITH_PROC = 1386;
exports.ER_LOGGING_PROHIBIT_CHANGING_OF = 1387;
exports.ER_NO_FILE_MAPPING = 1388;
exports.ER_WRONG_MAGIC = 1389;
exports.ER_PS_MANY_PARAM = 1390;
exports.ER_KEY_PART_ = 1391;
exports.ER_VIEW_CHECKSUM = 1392;
exports.ER_VIEW_MULTIUPDATE = 1393;
exports.ER_VIEW_NO_INSERT_FIELD_LIST = 1394;
exports.ER_VIEW_DELETE_MERGE_VIEW = 1395;
exports.ER_CANNOT_USER = 1396;
exports.ER_XAER_NOTA = 1397;
exports.ER_XAER_INVAL = 1398;
exports.ER_XAER_RMFAIL = 1399;
exports.ER_XAER_OUTSIDE = 1400;
exports.ER_XAER_RMERR = 1401;
exports.ER_XA_RBROLLBACK = 1402;
exports.ER_NONEXISTING_PROC_GRANT = 1403;
exports.ER_PROC_AUTO_GRANT_FAIL = 1404;
exports.ER_PROC_AUTO_REVOKE_FAIL = 1405;
exports.ER_DATA_TOO_LONG = 1406;
exports.ER_SP_BAD_SQLSTATE = 1407;
exports.ER_STARTUP = 1408;
exports.ER_LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR = 1409;
exports.ER_CANT_CREATE_USER_WITH_GRANT = 1410;
exports.ER_WRONG_VALUE_FOR_TYPE = 1411;
exports.ER_TABLE_DEF_CHANGED = 1412;
exports.ER_SP_DUP_HANDLER = 1413;
exports.ER_SP_NOT_VAR_ARG = 1414;
exports.ER_SP_NO_RETSET = 1415;
exports.ER_CANT_CREATE_GEOMETRY_OBJECT = 1416;
exports.ER_FAILED_ROUTINE_BREAK_BINLOG = 1417;
exports.ER_BINLOG_UNSAFE_ROUTINE = 1418;
exports.ER_BINLOG_CREATE_ROUTINE_NEED_SUPER = 1419;
exports.ER_EXEC_STMT_WITH_OPEN_CURSOR = 1420;
exports.ER_STMT_HAS_NO_OPEN_CURSOR = 1421;
exports.ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG = 1422;
exports.ER_NO_DEFAULT_FOR_VIEW_FIELD = 1423;
exports.ER_SP_NO_RECURSION = 1424;
exports.ER_TOO_BIG_SCALE = 1425;
exports.ER_TOO_BIG_PRECISION = 1426;
exports.ER_M_BIGGER_THAN_D = 1427;
exports.ER_WRONG_LOCK_OF_SYSTEM_TABLE = 1428;
exports.ER_CONNECT_TO_FOREIGN_DATA_SOURCE = 1429;
exports.ER_QUERY_ON_FOREIGN_DATA_SOURCE = 1430;
exports.ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST = 1431;
exports.ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE = 1432;
exports.ER_FOREIGN_DATA_STRING_INVALID = 1433;
exports.ER_CANT_CREATE_FEDERATED_TABLE = 1434;
exports.ER_TRG_IN_WRONG_SCHEMA = 1435;
exports.ER_STACK_OVERRUN_NEED_MORE = 1436;
exports.ER_TOO_LONG_BODY = 1437;
exports.ER_WARN_CANT_DROP_DEFAULT_KEYCACHE = 1438;
exports.ER_TOO_BIG_DISPLAYWIDTH = 1439;
exports.ER_XAER_DUPID = 1440;
exports.ER_DATETIME_FUNCTION_OVERFLOW = 1441;
exports.ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG = 1442;
exports.ER_VIEW_PREVENT_UPDATE = 1443;
exports.ER_PS_NO_RECURSION = 1444;
exports.ER_SP_CANT_SET_AUTOCOMMIT = 1445;
exports.ER_MALFORMED_DEFINER = 1446;
exports.ER_VIEW_FRM_NO_USER = 1447;
exports.ER_VIEW_OTHER_USER = 1448;
exports.ER_NO_SUCH_USER = 1449;
exports.ER_FORBID_SCHEMA_CHANGE = 1450;
exports.ER_ROW_IS_REFERENCED_ = 1451;
exports.ER_NO_REFERENCED_ROW_ = 1452;
exports.ER_SP_BAD_VAR_SHADOW = 1453;
exports.ER_TRG_NO_DEFINER = 1454;
exports.ER_OLD_FILE_FORMAT = 1455;
exports.ER_SP_RECURSION_LIMIT = 1456;
exports.ER_SP_PROC_TABLE_CORRUPT = 1457;
exports.ER_SP_WRONG_NAME = 1458;
exports.ER_TABLE_NEEDS_UPGRADE = 1459;
exports.ER_SP_NO_AGGREGATE = 1460;
exports.ER_MAX_PREPARED_STMT_COUNT_REACHED = 1461;
exports.ER_VIEW_RECURSIVE = 1462;
exports.ER_NON_GROUPING_FIELD_USED = 1463;
exports.ER_TABLE_CANT_HANDLE_SPKEYS = 1464;
exports.ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA = 1465;
exports.ER_REMOVED_SPACES = 1466;
exports.ER_AUTOINC_READ_FAILED = 1467;
exports.ER_USERNAME = 1468;
exports.ER_HOSTNAME = 1469;
exports.ER_WRONG_STRING_LENGTH = 1470;
exports.ER_NON_INSERTABLE_TABLE = 1471;
exports.ER_ADMIN_WRONG_MRG_TABLE = 1472;
exports.ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT = 1473;
exports.ER_NAME_BECOMES_EMPTY = 1474;
exports.ER_AMBIGUOUS_FIELD_TERM = 1475;
exports.ER_FOREIGN_SERVER_EXISTS = 1476;
exports.ER_FOREIGN_SERVER_DOESNT_EXIST = 1477;
exports.ER_ILLEGAL_HA_CREATE_OPTION = 1478;
exports.ER_PARTITION_REQUIRES_VALUES_ERROR = 1479;
exports.ER_PARTITION_WRONG_VALUES_ERROR = 1480;
exports.ER_PARTITION_MAXVALUE_ERROR = 1481;
exports.ER_PARTITION_SUBPARTITION_ERROR = 1482;
exports.ER_PARTITION_SUBPART_MIX_ERROR = 1483;
exports.ER_PARTITION_WRONG_NO_PART_ERROR = 1484;
exports.ER_PARTITION_WRONG_NO_SUBPART_ERROR = 1485;
exports.ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR = 1486;
exports.ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR = 1487;
exports.ER_FIELD_NOT_FOUND_PART_ERROR = 1488;
exports.ER_LIST_OF_FIELDS_ONLY_IN_HASH_ERROR = 1489;
exports.ER_INCONSISTENT_PARTITION_INFO_ERROR = 1490;
exports.ER_PARTITION_FUNC_NOT_ALLOWED_ERROR = 1491;
exports.ER_PARTITIONS_MUST_BE_DEFINED_ERROR = 1492;
exports.ER_RANGE_NOT_INCREASING_ERROR = 1493;
exports.ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR = 1494;
exports.ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR = 1495;
exports.ER_PARTITION_ENTRY_ERROR = 1496;
exports.ER_MIX_HANDLER_ERROR = 1497;
exports.ER_PARTITION_NOT_DEFINED_ERROR = 1498;
exports.ER_TOO_MANY_PARTITIONS_ERROR = 1499;
exports.ER_SUBPARTITION_ERROR = 1500;
exports.ER_CANT_CREATE_HANDLER_FILE = 1501;
exports.ER_BLOB_FIELD_IN_PART_FUNC_ERROR = 1502;
exports.ER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF = 1503;
exports.ER_NO_PARTS_ERROR = 1504;
exports.ER_PARTITION_MGMT_ON_NONPARTITIONED = 1505;
exports.ER_FOREIGN_KEY_ON_PARTITIONED = 1506;
exports.ER_DROP_PARTITION_NON_EXISTENT = 1507;
exports.ER_DROP_LAST_PARTITION = 1508;
exports.ER_COALESCE_ONLY_ON_HASH_PARTITION = 1509;
exports.ER_REORG_HASH_ONLY_ON_SAME_NO = 1510;
exports.ER_REORG_NO_PARAM_ERROR = 1511;
exports.ER_ONLY_ON_RANGE_LIST_PARTITION = 1512;
exports.ER_ADD_PARTITION_SUBPART_ERROR = 1513;
exports.ER_ADD_PARTITION_NO_NEW_PARTITION = 1514;
exports.ER_COALESCE_PARTITION_NO_PARTITION = 1515;
exports.ER_REORG_PARTITION_NOT_EXIST = 1516;
exports.ER_SAME_NAME_PARTITION = 1517;
exports.ER_NO_BINLOG_ERROR = 1518;
exports.ER_CONSECUTIVE_REORG_PARTITIONS = 1519;
exports.ER_REORG_OUTSIDE_RANGE = 1520;
exports.ER_PARTITION_FUNCTION_FAILURE = 1521;
exports.ER_PART_STATE_ERROR = 1522;
exports.ER_LIMITED_PART_RANGE = 1523;
exports.ER_PLUGIN_IS_NOT_LOADED = 1524;
exports.ER_WRONG_VALUE = 1525;
exports.ER_NO_PARTITION_FOR_GIVEN_VALUE = 1526;
exports.ER_FILEGROUP_OPTION_ONLY_ONCE = 1527;
exports.ER_CREATE_FILEGROUP_FAILED = 1528;
exports.ER_DROP_FILEGROUP_FAILED = 1529;
exports.ER_TABLESPACE_AUTO_EXTEND_ERROR = 1530;
exports.ER_WRONG_SIZE_NUMBER = 1531;
exports.ER_SIZE_OVERFLOW_ERROR = 1532;
exports.ER_ALTER_FILEGROUP_FAILED = 1533;
exports.ER_BINLOG_ROW_LOGGING_FAILED = 1534;
exports.ER_BINLOG_ROW_WRONG_TABLE_DEF = 1535;
exports.ER_BINLOG_ROW_RBR_TO_SBR = 1536;
exports.ER_EVENT_ALREADY_EXISTS = 1537;
exports.ER_EVENT_STORE_FAILED = 1538;
exports.ER_EVENT_DOES_NOT_EXIST = 1539;
exports.ER_EVENT_CANT_ALTER = 1540;
exports.ER_EVENT_DROP_FAILED = 1541;
exports.ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG = 1542;
exports.ER_EVENT_ENDS_BEFORE_STARTS = 1543;
exports.ER_EVENT_EXEC_TIME_IN_THE_PAST = 1544;
exports.ER_EVENT_OPEN_TABLE_FAILED = 1545;
exports.ER_EVENT_NEITHER_M_EXPR_NOR_M_AT = 1546;
exports.ER_COL_COUNT_DOESNT_MATCH_CORRUPTED = 1547;
exports.ER_CANNOT_LOAD_FROM_TABLE = 1548;
exports.ER_EVENT_CANNOT_DELETE = 1549;
exports.ER_EVENT_COMPILE_ERROR = 1550;
exports.ER_EVENT_SAME_NAME = 1551;
exports.ER_EVENT_DATA_TOO_LONG = 1552;
exports.ER_DROP_INDEX_FK = 1553;
exports.ER_WARN_DEPRECATED_SYNTAX_WITH_VER = 1554;
exports.ER_CANT_WRITE_LOCK_LOG_TABLE = 1555;
exports.ER_CANT_LOCK_LOG_TABLE = 1556;
exports.ER_FOREIGN_DUPLICATE_KEY = 1557;
exports.ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE = 1558;
exports.ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR = 1559;
exports.ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT = 1560;
exports.ER_NDB_CANT_SWITCH_BINLOG_FORMAT = 1561;
exports.ER_PARTITION_NO_TEMPORARY = 1562;
exports.ER_PARTITION_CONST_DOMAIN_ERROR = 1563;
exports.ER_PARTITION_FUNCTION_IS_NOT_ALLOWED = 1564;
exports.ER_DDL_LOG_ERROR = 1565;
exports.ER_NULL_IN_VALUES_LESS_THAN = 1566;
exports.ER_WRONG_PARTITION_NAME = 1567;
exports.ER_CANT_CHANGE_TX_CHARACTERISTICS = 1568;
exports.ER_DUP_ENTRY_AUTOINCREMENT_CASE = 1569;
exports.ER_EVENT_MODIFY_QUEUE_ERROR = 1570;
exports.ER_EVENT_SET_VAR_ERROR = 1571;
exports.ER_PARTITION_MERGE_ERROR = 1572;
exports.ER_CANT_ACTIVATE_LOG = 1573;
exports.ER_RBR_NOT_AVAILABLE = 1574;
exports.ER_BASE = 1575;
exports.ER_EVENT_RECURSION_FORBIDDEN = 1576;
exports.ER_EVENTS_DB_ERROR = 1577;
exports.ER_ONLY_INTEGERS_ALLOWED = 1578;
exports.ER_UNSUPORTED_LOG_ENGINE = 1579;
exports.ER_BAD_LOG_STATEMENT = 1580;
exports.ER_CANT_RENAME_LOG_TABLE = 1581;
exports.ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT = 1582;
exports.ER_WRONG_PARAMETERS_TO_NATIVE_FCT = 1583;
exports.ER_WRONG_PARAMETERS_TO_STORED_FCT = 1584;
exports.ER_NATIVE_FCT_NAME_COLLISION = 1585;
exports.ER_DUP_ENTRY_WITH_KEY_NAME = 1586;
exports.ER_BINLOG_PURGE_EMFILE = 1587;
exports.ER_EVENT_CANNOT_CREATE_IN_THE_PAST = 1588;
exports.ER_EVENT_CANNOT_ALTER_IN_THE_PAST = 1589;
exports.ER_SLAVE_INCIDENT = 1590;
exports.ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT = 1591;
exports.ER_BINLOG_UNSAFE_STATEMENT = 1592;
exports.ER_SLAVE_FATAL_ERROR = 1593;
exports.ER_SLAVE_RELAY_LOG_READ_FAILURE = 1594;
exports.ER_SLAVE_RELAY_LOG_WRITE_FAILURE = 1595;
exports.ER_SLAVE_CREATE_EVENT_FAILURE = 1596;
exports.ER_SLAVE_MASTER_COM_FAILURE = 1597;
exports.ER_BINLOG_LOGGING_IMPOSSIBLE = 1598;
exports.ER_VIEW_NO_CREATION_CTX = 1599;
exports.ER_VIEW_INVALID_CREATION_CTX = 1600;
exports.ER_SR_INVALID_CREATION_CTX = 1601;
exports.ER_TRG_CORRUPTED_FILE = 1602;
exports.ER_TRG_NO_CREATION_CTX = 1603;
exports.ER_TRG_INVALID_CREATION_CTX = 1604;
exports.ER_EVENT_INVALID_CREATION_CTX = 1605;
exports.ER_TRG_CANT_OPEN_TABLE = 1606;
exports.ER_CANT_CREATE_SROUTINE = 1607;
exports.ER_NEVER_USED = 1608;
exports.ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT = 1609;
exports.ER_SLAVE_CORRUPT_EVENT = 1610;
exports.ER_LOAD_DATA_INVALID_COLUMN = 1611;
exports.ER_LOG_PURGE_NO_FILE = 1612;
exports.ER_XA_RBTIMEOUT = 1613;
exports.ER_XA_RBDEADLOCK = 1614;
exports.ER_NEED_REPREPARE = 1615;
exports.ER_DELAYED_NOT_SUPPORTED = 1616;
exports.WARN_NO_MASTER_INFO = 1617;
exports.WARN_OPTION_IGNORED = 1618;
exports.WARN_PLUGIN_DELETE_BUILTIN = 1619;
exports.WARN_PLUGIN_BUSY = 1620;
exports.ER_VARIABLE_IS_READONLY = 1621;
exports.ER_WARN_ENGINE_TRANSACTION_ROLLBACK = 1622;
exports.ER_SLAVE_HEARTBEAT_FAILURE = 1623;
exports.ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE = 1624;
exports.ER_NDB_REPLICATION_SCHEMA_ERROR = 1625;
exports.ER_CONFLICT_FN_PARSE_ERROR = 1626;
exports.ER_EXCEPTIONS_WRITE_ERROR = 1627;
exports.ER_TOO_LONG_TABLE_COMMENT = 1628;
exports.ER_TOO_LONG_FIELD_COMMENT = 1629;
exports.ER_FUNC_INEXISTENT_NAME_COLLISION = 1630;
exports.ER_DATABASE_NAME = 1631;
exports.ER_TABLE_NAME = 1632;
exports.ER_PARTITION_NAME = 1633;
exports.ER_SUBPARTITION_NAME = 1634;
exports.ER_TEMPORARY_NAME = 1635;
exports.ER_RENAMED_NAME = 1636;
exports.ER_TOO_MANY_CONCURRENT_TRXS = 1637;
exports.WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED = 1638;
exports.ER_DEBUG_SYNC_TIMEOUT = 1639;
exports.ER_DEBUG_SYNC_HIT_LIMIT = 1640;
exports.ER_DUP_SIGNAL_SET = 1641;
exports.ER_SIGNAL_WARN = 1642;
exports.ER_SIGNAL_NOT_FOUND = 1643;
exports.ER_SIGNAL_EXCEPTION = 1644;
exports.ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER = 1645;
exports.ER_SIGNAL_BAD_CONDITION_TYPE = 1646;
exports.WARN_COND_ITEM_TRUNCATED = 1647;
exports.ER_COND_ITEM_TOO_LONG = 1648;
exports.ER_UNKNOWN_LOCALE = 1649;
exports.ER_SLAVE_IGNORE_SERVER_IDS = 1650;
exports.ER_QUERY_CACHE_DISABLED = 1651;
exports.ER_SAME_NAME_PARTITION_FIELD = 1652;
exports.ER_PARTITION_COLUMN_LIST_ERROR = 1653;
exports.ER_WRONG_TYPE_COLUMN_VALUE_ERROR = 1654;
exports.ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR = 1655;
exports.ER_MAXVALUE_IN_VALUES_IN = 1656;
exports.ER_TOO_MANY_VALUES_ERROR = 1657;
exports.ER_ROW_SINGLE_PARTITION_FIELD_ERROR = 1658;
exports.ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD = 1659;
exports.ER_PARTITION_FIELDS_TOO_LONG = 1660;
exports.ER_BINLOG_ROW_ENGINE_AND_STMT_ENGINE = 1661;
exports.ER_BINLOG_ROW_MODE_AND_STMT_ENGINE = 1662;
exports.ER_BINLOG_UNSAFE_AND_STMT_ENGINE = 1663;
exports.ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE = 1664;
exports.ER_BINLOG_STMT_MODE_AND_ROW_ENGINE = 1665;
exports.ER_BINLOG_ROW_INJECTION_AND_STMT_MODE = 1666;
exports.ER_BINLOG_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE = 1667;
exports.ER_BINLOG_UNSAFE_LIMIT = 1668;
exports.ER_BINLOG_UNSAFE_INSERT_DELAYED = 1669;
exports.ER_BINLOG_UNSAFE_SYSTEM_TABLE = 1670;
exports.ER_BINLOG_UNSAFE_AUTOINC_COLUMNS = 1671;
exports.ER_BINLOG_UNSAFE_UDF = 1672;
exports.ER_BINLOG_UNSAFE_SYSTEM_VARIABLE = 1673;
exports.ER_BINLOG_UNSAFE_SYSTEM_FUNCTION = 1674;
exports.ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS = 1675;
exports.ER_MESSAGE_AND_STATEMENT = 1676;
exports.ER_SLAVE_CONVERSION_FAILED = 1677;
exports.ER_SLAVE_CANT_CREATE_CONVERSION = 1678;
exports.ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT = 1679;
exports.ER_PATH_LENGTH = 1680;
exports.ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT = 1681;
exports.ER_WRONG_NATIVE_TABLE_STRUCTURE = 1682;
exports.ER_WRONG_PERFSCHEMA_USAGE = 1683;
exports.ER_WARN_I_S_SKIPPED_TABLE = 1684;
exports.ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT = 1685;
exports.ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT = 1686;
exports.ER_SPATIAL_MUST_HAVE_GEOM_COL = 1687;
exports.ER_TOO_LONG_INDEX_COMMENT = 1688;
exports.ER_LOCK_ABORTED = 1689;
exports.ER_DATA_OUT_OF_RANGE = 1690;
exports.ER_WRONG_SPVAR_TYPE_IN_LIMIT = 1691;
exports.ER_BINLOG_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE = 1692;
exports.ER_BINLOG_UNSAFE_MIXED_STATEMENT = 1693;
exports.ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SQL_LOG_BIN = 1694;
exports.ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN = 1695;
exports.ER_FAILED_READ_FROM_PAR_FILE = 1696;
exports.ER_VALUES_IS_NOT_INT_TYPE_ERROR = 1697;
exports.ER_ACCESS_DENIED_NO_PASSWORD_ERROR = 1698;
exports.ER_SET_PASSWORD_AUTH_PLUGIN = 1699;
exports.ER_GRANT_PLUGIN_USER_EXISTS = 1700;
exports.ER_TRUNCATE_ILLEGAL_FK = 1701;
exports.ER_PLUGIN_IS_PERMANENT = 1702;
exports.ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN = 1703;
exports.ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX = 1704;
exports.ER_STMT_CACHE_FULL = 1705;
exports.ER_MULTI_UPDATE_KEY_CONFLICT = 1706;
exports.ER_TABLE_NEEDS_REBUILD = 1707;
exports.WARN_OPTION_BELOW_LIMIT = 1708;
exports.ER_INDEX_COLUMN_TOO_LONG = 1709;
exports.ER_ERROR_IN_TRIGGER_BODY = 1710;
exports.ER_ERROR_IN_UNKNOWN_TRIGGER_BODY = 1711;
exports.ER_INDEX_CORRUPT = 1712;
exports.ER_UNDO_RECORD_TOO_BIG = 1713;
exports.ER_BINLOG_UNSAFE_INSERT_IGNORE_SELECT = 1714;
exports.ER_BINLOG_UNSAFE_INSERT_SELECT_UPDATE = 1715;
exports.ER_BINLOG_UNSAFE_REPLACE_SELECT = 1716;
exports.ER_BINLOG_UNSAFE_CREATE_IGNORE_SELECT = 1717;
exports.ER_BINLOG_UNSAFE_CREATE_REPLACE_SELECT = 1718;
exports.ER_BINLOG_UNSAFE_UPDATE_IGNORE = 1719;
exports.ER_PLUGIN_NO_UNINSTALL = 1720;
exports.ER_PLUGIN_NO_INSTALL = 1721;
exports.ER_BINLOG_UNSAFE_WRITE_AUTOINC_SELECT = 1722;
exports.ER_BINLOG_UNSAFE_CREATE_SELECT_AUTOINC = 1723;
exports.ER_BINLOG_UNSAFE_INSERT_TWO_KEYS = 1724;
exports.ER_TABLE_IN_FK_CHECK = 1725;
exports.ER_UNSUPPORTED_ENGINE = 1726;
exports.ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST = 1727;
exports.ER_CANNOT_LOAD_FROM_TABLE_V = 1728;
exports.ER_MASTER_DELAY_VALUE_OUT_OF_RANGE = 1729;
exports.ER_ONLY_FD_AND_RBR_EVENTS_ALLOWED_IN_BINLOG_STATEMENT = 1730;
exports.ER_PARTITION_EXCHANGE_DIFFERENT_OPTION = 1731;
exports.ER_PARTITION_EXCHANGE_PART_TABLE = 1732;
exports.ER_PARTITION_EXCHANGE_TEMP_TABLE = 1733;
exports.ER_PARTITION_INSTEAD_OF_SUBPARTITION = 1734;
exports.ER_UNKNOWN_PARTITION = 1735;
exports.ER_TABLES_DIFFERENT_METADATA = 1736;
exports.ER_ROW_DOES_NOT_MATCH_PARTITION = 1737;
exports.ER_BINLOG_CACHE_SIZE_GREATER_THAN_MAX = 1738;
exports.ER_WARN_INDEX_NOT_APPLICABLE = 1739;
exports.ER_PARTITION_EXCHANGE_FOREIGN_KEY = 1740;
exports.ER_NO_SUCH_KEY_VALUE = 1741;
exports.ER_RPL_INFO_DATA_TOO_LONG = 1742;
exports.ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE = 1743;
exports.ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE = 1744;
exports.ER_BINLOG_STMT_CACHE_SIZE_GREATER_THAN_MAX = 1745;
exports.ER_CANT_UPDATE_TABLE_IN_CREATE_TABLE_SELECT = 1746;
exports.ER_PARTITION_CLAUSE_ON_NONPARTITIONED = 1747;
exports.ER_ROW_DOES_NOT_MATCH_GIVEN_PARTITION_SET = 1748;
exports.ER_NO_SUCH_PARTITION = 1749;
exports.ER_CHANGE_RPL_INFO_REPOSITORY_FAILURE = 1750;
exports.ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_CREATED_TEMP_TABLE = 1751;
exports.ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_DROPPED_TEMP_TABLE = 1752;
exports.ER_MTS_FEATURE_IS_NOT_SUPPORTED = 1753;
exports.ER_MTS_UPDATED_DBS_GREATER_MAX = 1754;
exports.ER_MTS_CANT_PARALLEL = 1755;
exports.ER_MTS_INCONSISTENT_DATA = 1756;
exports.ER_FULLTEXT_NOT_SUPPORTED_WITH_PARTITIONING = 1757;
exports.ER_DA_INVALID_CONDITION_NUMBER = 1758;
exports.ER_INSECURE_PLAIN_TEXT = 1759;
exports.ER_INSECURE_CHANGE_MASTER = 1760;
exports.ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO = 1761;
exports.ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO = 1762;
exports.ER_SQLTHREAD_WITH_SECURE_SLAVE = 1763;
exports.ER_TABLE_HAS_NO_FT = 1764;
exports.ER_VARIABLE_NOT_SETTABLE_IN_SF_OR_TRIGGER = 1765;
exports.ER_VARIABLE_NOT_SETTABLE_IN_TRANSACTION = 1766;
exports.ER_GTID_NEXT_IS_NOT_IN_GTID_NEXT_LIST = 1767;
exports.ER_CANT_CHANGE_GTID_NEXT_IN_TRANSACTION_WHEN_GTID_NEXT_LIST_IS_NULL = 1768;
exports.ER_SET_STATEMENT_CANNOT_INVOKE_FUNCTION = 1769;
exports.ER_GTID_NEXT_CANT_BE_AUTOMATIC_IF_GTID_NEXT_LIST_IS_NON_NULL = 1770;
exports.ER_SKIPPING_LOGGED_TRANSACTION = 1771;
exports.ER_MALFORMED_GTID_SET_SPECIFICATION = 1772;
exports.ER_MALFORMED_GTID_SET_ENCODING = 1773;
exports.ER_MALFORMED_GTID_SPECIFICATION = 1774;
exports.ER_GNO_EXHAUSTED = 1775;
exports.ER_BAD_SLAVE_AUTO_POSITION = 1776;
exports.ER_AUTO_POSITION_REQUIRES_GTID_MODE_ON = 1777;
exports.ER_CANT_DO_IMPLICIT_COMMIT_IN_TRX_WHEN_GTID_NEXT_IS_SET = 1778;
exports.ER_GTID_MODE_ = 1779;
exports.ER_GTID_MODE_REQUIRES_BINLOG = 1780;
exports.ER_CANT_SET_GTID_NEXT_TO_GTID_WHEN_GTID_MODE_IS_OFF = 1781;
exports.ER_CANT_SET_GTID_NEXT_TO_ANONYMOUS_WHEN_GTID_MODE_IS_ON = 1782;
exports.ER_CANT_SET_GTID_NEXT_LIST_TO_NON_NULL_WHEN_GTID_MODE_IS_OFF = 1783;
exports.ER_FOUND_GTID_EVENT_WHEN_GTID_MODE_IS_OFF = 1784;
exports.ER_GTID_UNSAFE_NON_TRANSACTIONAL_TABLE = 1785;
exports.ER_GTID_UNSAFE_CREATE_SELECT = 1786;
exports.ER_GTID_UNSAFE_CREATE_DROP_TEMPORARY_TABLE_IN_TRANSACTION = 1787;
exports.ER_GTID_MODE_CAN_ONLY_CHANGE_ONE_STEP_AT_A_TIME = 1788;
exports.ER_MASTER_HAS_PURGED_REQUIRED_GTIDS = 1789;
exports.ER_CANT_SET_GTID_NEXT_WHEN_OWNING_GTID = 1790;
exports.ER_UNKNOWN_EXPLAIN_FORMAT = 1791;
exports.ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION = 1792;
exports.ER_TOO_LONG_TABLE_PARTITION_COMMENT = 1793;
exports.ER_SLAVE_CONFIGURATION = 1794;
exports.ER_INNODB_FT_LIMIT = 1795;
exports.ER_INNODB_NO_FT_TEMP_TABLE = 1796;
exports.ER_INNODB_FT_WRONG_DOCID_COLUMN = 1797;
exports.ER_INNODB_FT_WRONG_DOCID_INDEX = 1798;
exports.ER_INNODB_ONLINE_LOG_TOO_BIG = 1799;
exports.ER_UNKNOWN_ALTER_ALGORITHM = 1800;
exports.ER_UNKNOWN_ALTER_LOCK = 1801;
exports.ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS = 1802;
exports.ER_MTS_RECOVERY_FAILURE = 1803;
exports.ER_MTS_RESET_WORKERS = 1804;
exports.ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V = 1805;
exports.ER_SLAVE_SILENT_RETRY_TRANSACTION = 1806;
exports.ER_DISCARD_FK_CHECKS_RUNNING = 1807;
exports.ER_TABLE_SCHEMA_MISMATCH = 1808;
exports.ER_TABLE_IN_SYSTEM_TABLESPACE = 1809;
exports.ER_IO_READ_ERROR = 1810;
exports.ER_IO_WRITE_ERROR = 1811;
exports.ER_TABLESPACE_MISSING = 1812;
exports.ER_TABLESPACE_EXISTS = 1813;
exports.ER_TABLESPACE_DISCARDED = 1814;
exports.ER_INTERNAL_ERROR = 1815;
exports.ER_INNODB_IMPORT_ERROR = 1816;
exports.ER_INNODB_INDEX_CORRUPT = 1817;
exports.ER_INVALID_YEAR_COLUMN_LENGTH = 1818;
exports.ER_NOT_VALID_PASSWORD = 1819;
exports.ER_MUST_CHANGE_PASSWORD = 1820;
exports.ER_FK_NO_INDEX_CHILD = 1821;
exports.ER_FK_NO_INDEX_PARENT = 1822;
exports.ER_FK_FAIL_ADD_SYSTEM = 1823;
exports.ER_FK_CANNOT_OPEN_PARENT = 1824;
exports.ER_FK_INCORRECT_OPTION = 1825;
exports.ER_FK_DUP_NAME = 1826;
exports.ER_PASSWORD_FORMAT = 1827;
exports.ER_FK_COLUMN_CANNOT_DROP = 1828;
exports.ER_FK_COLUMN_CANNOT_DROP_CHILD = 1829;
exports.ER_FK_COLUMN_NOT_NULL = 1830;
exports.ER_DUP_INDEX = 1831;
exports.ER_FK_COLUMN_CANNOT_CHANGE = 1832;
exports.ER_FK_COLUMN_CANNOT_CHANGE_CHILD = 1833;
exports.ER_FK_CANNOT_DELETE_PARENT = 1834;
exports.ER_MALFORMED_PACKET = 1835;
exports.ER_READ_ONLY_MODE = 1836;
exports.ER_GTID_NEXT_TYPE_UNDEFINED_GROUP = 1837;
exports.ER_VARIABLE_NOT_SETTABLE_IN_SP = 1838;
exports.ER_CANT_SET_GTID_PURGED_WHEN_GTID_MODE_IS_OFF = 1839;
exports.ER_CANT_SET_GTID_PURGED_WHEN_GTID_EXECUTED_IS_NOT_EMPTY = 1840;
exports.ER_CANT_SET_GTID_PURGED_WHEN_OWNED_GTIDS_IS_NOT_EMPTY = 1841;
exports.ER_GTID_PURGED_WAS_CHANGED = 1842;
exports.ER_GTID_EXECUTED_WAS_CHANGED = 1843;
exports.ER_BINLOG_STMT_MODE_AND_NO_REPL_TABLES = 1844;
exports.ER_ALTER_OPERATION_NOT_SUPPORTED = 1845;
exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON = 1846;
exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COPY = 1847;
exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_PARTITION = 1848;
exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_RENAME = 1849;
exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COLUMN_TYPE = 1850;
exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_CHECK = 1851;
exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_IGNORE = 1852;
exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOPK = 1853;
exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_AUTOINC = 1854;
exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_HIDDEN_FTS = 1855;
exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_CHANGE_FTS = 1856;
exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FTS = 1857;
exports.ER_SQL_SLAVE_SKIP_COUNTER_NOT_SETTABLE_IN_GTID_MODE = 1858;
exports.ER_DUP_UNKNOWN_IN_INDEX = 1859;
exports.ER_IDENT_CAUSES_TOO_LONG_PATH = 1860;
exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL = 1861;
exports.ER_MUST_CHANGE_PASSWORD_LOGIN = 1862;
exports.ER_ROW_IN_WRONG_PARTITION = 1863;
exports.ER_MTS_EVENT_BIGGER_PENDING_JOBS_SIZE_MAX = 1864;
exports.ER_INNODB_NO_FT_USES_PARSER = 1865;
exports.ER_BINLOG_LOGICAL_CORRUPTION = 1866;
exports.ER_WARN_PURGE_LOG_IN_USE = 1867;
exports.ER_WARN_PURGE_LOG_IS_ACTIVE = 1868;
exports.ER_AUTO_INCREMENT_CONFLICT = 1869;
exports.WARN_ON_BLOCKHOLE_IN_RBR = 1870;
exports.ER_SLAVE_MI_INIT_REPOSITORY = 1871;
exports.ER_SLAVE_RLI_INIT_REPOSITORY = 1872;
exports.ER_ACCESS_DENIED_CHANGE_USER_ERROR = 1873;
exports.ER_INNODB_READ_ONLY = 1874;
exports.ER_STOP_SLAVE_SQL_THREAD_TIMEOUT = 1875;
exports.ER_STOP_SLAVE_IO_THREAD_TIMEOUT = 1876;
exports.ER_TABLE_CORRUPT = 1877;
exports.ER_TEMP_FILE_WRITE_FAILURE = 1878;
exports.ER_INNODB_FT_AUX_NOT_HEX_ID = 1879;
exports.ER_OLD_TEMPORALS_UPGRADED = 1880;
exports.ER_INNODB_FORCED_RECOVERY = 1881;
exports.ER_AES_INVALID_IV = 1882;
// Lookup-by-number table
exports[1] = 'EE_CANTCREATEFILE';
exports[2] = 'EE_READ';
exports[3] = 'EE_WRITE';
exports[4] = 'EE_BADCLOSE';
exports[5] = 'EE_OUTOFMEMORY';
exports[6] = 'EE_DELETE';
exports[7] = 'EE_LINK';
exports[9] = 'EE_EOFERR';
exports[10] = 'EE_CANTLOCK';
exports[11] = 'EE_CANTUNLOCK';
exports[12] = 'EE_DIR';
exports[13] = 'EE_STAT';
exports[14] = 'EE_CANT_CHSIZE';
exports[15] = 'EE_CANT_OPEN_STREAM';
exports[16] = 'EE_GETWD';
exports[17] = 'EE_SETWD';
exports[18] = 'EE_LINK_WARNING';
exports[19] = 'EE_OPEN_WARNING';
exports[20] = 'EE_DISK_FULL';
exports[21] = 'EE_CANT_MKDIR';
exports[22] = 'EE_UNKNOWN_CHARSET';
exports[23] = 'EE_OUT_OF_FILERESOURCES';
exports[24] = 'EE_CANT_READLINK';
exports[25] = 'EE_CANT_SYMLINK';
exports[26] = 'EE_REALPATH';
exports[27] = 'EE_SYNC';
exports[28] = 'EE_UNKNOWN_COLLATION';
exports[29] = 'EE_FILENOTFOUND';
exports[30] = 'EE_FILE_NOT_CLOSED';
exports[31] = 'EE_CHANGE_OWNERSHIP';
exports[32] = 'EE_CHANGE_PERMISSIONS';
exports[33] = 'EE_CANT_SEEK';
exports[120] = 'HA_ERR_KEY_NOT_FOUND';
exports[121] = 'HA_ERR_FOUND_DUPP_KEY';
exports[122] = 'HA_ERR_INTERNAL_ERROR';
exports[123] = 'HA_ERR_RECORD_CHANGED';
exports[124] = 'HA_ERR_WRONG_INDEX';
exports[126] = 'HA_ERR_CRASHED';
exports[127] = 'HA_ERR_WRONG_IN_RECORD';
exports[128] = 'HA_ERR_OUT_OF_MEM';
exports[130] = 'HA_ERR_NOT_A_TABLE';
exports[131] = 'HA_ERR_WRONG_COMMAND';
exports[132] = 'HA_ERR_OLD_FILE';
exports[133] = 'HA_ERR_NO_ACTIVE_RECORD';
exports[134] = 'HA_ERR_RECORD_DELETED';
exports[135] = 'HA_ERR_RECORD_FILE_FULL';
exports[136] = 'HA_ERR_INDEX_FILE_FULL';
exports[137] = 'HA_ERR_END_OF_FILE';
exports[138] = 'HA_ERR_UNSUPPORTED';
exports[139] = 'HA_ERR_TO_BIG_ROW';
exports[140] = 'HA_WRONG_CREATE_OPTION';
exports[141] = 'HA_ERR_FOUND_DUPP_UNIQUE';
exports[142] = 'HA_ERR_UNKNOWN_CHARSET';
exports[143] = 'HA_ERR_WRONG_MRG_TABLE_DEF';
exports[144] = 'HA_ERR_CRASHED_ON_REPAIR';
exports[145] = 'HA_ERR_CRASHED_ON_USAGE';
exports[146] = 'HA_ERR_LOCK_WAIT_TIMEOUT';
exports[147] = 'HA_ERR_LOCK_TABLE_FULL';
exports[148] = 'HA_ERR_READ_ONLY_TRANSACTION';
exports[149] = 'HA_ERR_LOCK_DEADLOCK';
exports[150] = 'HA_ERR_CANNOT_ADD_FOREIGN';
exports[151] = 'HA_ERR_NO_REFERENCED_ROW';
exports[152] = 'HA_ERR_ROW_IS_REFERENCED';
exports[153] = 'HA_ERR_NO_SAVEPOINT';
exports[154] = 'HA_ERR_NON_UNIQUE_BLOCK_SIZE';
exports[155] = 'HA_ERR_NO_SUCH_TABLE';
exports[156] = 'HA_ERR_TABLE_EXIST';
exports[157] = 'HA_ERR_NO_CONNECTION';
exports[158] = 'HA_ERR_NULL_IN_SPATIAL';
exports[159] = 'HA_ERR_TABLE_DEF_CHANGED';
exports[160] = 'HA_ERR_NO_PARTITION_FOUND';
exports[161] = 'HA_ERR_RBR_LOGGING_FAILED';
exports[162] = 'HA_ERR_DROP_INDEX_FK';
exports[163] = 'HA_ERR_FOREIGN_DUPLICATE_KEY';
exports[164] = 'HA_ERR_TABLE_NEEDS_UPGRADE';
exports[165] = 'HA_ERR_TABLE_READONLY';
exports[166] = 'HA_ERR_AUTOINC_READ_FAILED';
exports[167] = 'HA_ERR_AUTOINC_ERANGE';
exports[168] = 'HA_ERR_GENERIC';
exports[169] = 'HA_ERR_RECORD_IS_THE_SAME';
exports[170] = 'HA_ERR_LOGGING_IMPOSSIBLE';
exports[171] = 'HA_ERR_CORRUPT_EVENT';
exports[172] = 'HA_ERR_NEW_FILE';
exports[173] = 'HA_ERR_ROWS_EVENT_APPLY';
exports[174] = 'HA_ERR_INITIALIZATION';
exports[175] = 'HA_ERR_FILE_TOO_SHORT';
exports[176] = 'HA_ERR_WRONG_CRC';
exports[177] = 'HA_ERR_TOO_MANY_CONCURRENT_TRXS';
exports[178] = 'HA_ERR_NOT_IN_LOCK_PARTITIONS';
exports[179] = 'HA_ERR_INDEX_COL_TOO_LONG';
exports[180] = 'HA_ERR_INDEX_CORRUPT';
exports[181] = 'HA_ERR_UNDO_REC_TOO_BIG';
exports[182] = 'HA_FTS_INVALID_DOCID';
exports[183] = 'HA_ERR_TABLE_IN_FK_CHECK';
exports[184] = 'HA_ERR_TABLESPACE_EXISTS';
exports[185] = 'HA_ERR_TOO_MANY_FIELDS';
exports[186] = 'HA_ERR_ROW_IN_WRONG_PARTITION';
exports[187] = 'HA_ERR_INNODB_READ_ONLY';
exports[188] = 'HA_ERR_FTS_EXCEED_RESULT_CACHE_LIMIT';
exports[189] = 'HA_ERR_TEMP_FILE_WRITE_FAILURE';
exports[190] = 'HA_ERR_INNODB_FORCED_RECOVERY';
exports[191] = 'HA_ERR_FTS_TOO_MANY_WORDS_IN_PHRASE';
exports[1000] = 'ER_HASHCHK';
exports[1001] = 'ER_NISAMCHK';
exports[1002] = 'ER_NO';
exports[1003] = 'ER_YES';
exports[1004] = 'ER_CANT_CREATE_FILE';
exports[1005] = 'ER_CANT_CREATE_TABLE';
exports[1006] = 'ER_CANT_CREATE_DB';
exports[1007] = 'ER_DB_CREATE_EXISTS';
exports[1008] = 'ER_DB_DROP_EXISTS';
exports[1009] = 'ER_DB_DROP_DELETE';
exports[1010] = 'ER_DB_DROP_RMDIR';
exports[1011] = 'ER_CANT_DELETE_FILE';
exports[1012] = 'ER_CANT_FIND_SYSTEM_REC';
exports[1013] = 'ER_CANT_GET_STAT';
exports[1014] = 'ER_CANT_GET_WD';
exports[1015] = 'ER_CANT_LOCK';
exports[1016] = 'ER_CANT_OPEN_FILE';
exports[1017] = 'ER_FILE_NOT_FOUND';
exports[1018] = 'ER_CANT_READ_DIR';
exports[1019] = 'ER_CANT_SET_WD';
exports[1020] = 'ER_CHECKREAD';
exports[1021] = 'ER_DISK_FULL';
exports[1022] = 'ER_DUP_KEY';
exports[1023] = 'ER_ERROR_ON_CLOSE';
exports[1024] = 'ER_ERROR_ON_READ';
exports[1025] = 'ER_ERROR_ON_RENAME';
exports[1026] = 'ER_ERROR_ON_WRITE';
exports[1027] = 'ER_FILE_USED';
exports[1028] = 'ER_FILSORT_ABORT';
exports[1029] = 'ER_FORM_NOT_FOUND';
exports[1030] = 'ER_GET_ERRNO';
exports[1031] = 'ER_ILLEGAL_HA';
exports[1032] = 'ER_KEY_NOT_FOUND';
exports[1033] = 'ER_NOT_FORM_FILE';
exports[1034] = 'ER_NOT_KEYFILE';
exports[1035] = 'ER_OLD_KEYFILE';
exports[1036] = 'ER_OPEN_AS_READONLY';
exports[1037] = 'ER_OUTOFMEMORY';
exports[1038] = 'ER_OUT_OF_SORTMEMORY';
exports[1039] = 'ER_UNEXPECTED_EOF';
exports[1040] = 'ER_CON_COUNT_ERROR';
exports[1041] = 'ER_OUT_OF_RESOURCES';
exports[1042] = 'ER_BAD_HOST_ERROR';
exports[1043] = 'ER_HANDSHAKE_ERROR';
exports[1044] = 'ER_DBACCESS_DENIED_ERROR';
exports[1045] = 'ER_ACCESS_DENIED_ERROR';
exports[1046] = 'ER_NO_DB_ERROR';
exports[1047] = 'ER_UNKNOWN_COM_ERROR';
exports[1048] = 'ER_BAD_NULL_ERROR';
exports[1049] = 'ER_BAD_DB_ERROR';
exports[1050] = 'ER_TABLE_EXISTS_ERROR';
exports[1051] = 'ER_BAD_TABLE_ERROR';
exports[1052] = 'ER_NON_UNIQ_ERROR';
exports[1053] = 'ER_SERVER_SHUTDOWN';
exports[1054] = 'ER_BAD_FIELD_ERROR';
exports[1055] = 'ER_WRONG_FIELD_WITH_GROUP';
exports[1056] = 'ER_WRONG_GROUP_FIELD';
exports[1057] = 'ER_WRONG_SUM_SELECT';
exports[1058] = 'ER_WRONG_VALUE_COUNT';
exports[1059] = 'ER_TOO_LONG_IDENT';
exports[1060] = 'ER_DUP_FIELDNAME';
exports[1061] = 'ER_DUP_KEYNAME';
exports[1062] = 'ER_DUP_ENTRY';
exports[1063] = 'ER_WRONG_FIELD_SPEC';
exports[1064] = 'ER_PARSE_ERROR';
exports[1065] = 'ER_EMPTY_QUERY';
exports[1066] = 'ER_NONUNIQ_TABLE';
exports[1067] = 'ER_INVALID_DEFAULT';
exports[1068] = 'ER_MULTIPLE_PRI_KEY';
exports[1069] = 'ER_TOO_MANY_KEYS';
exports[1070] = 'ER_TOO_MANY_KEY_PARTS';
exports[1071] = 'ER_TOO_LONG_KEY';
exports[1072] = 'ER_KEY_COLUMN_DOES_NOT_EXITS';
exports[1073] = 'ER_BLOB_USED_AS_KEY';
exports[1074] = 'ER_TOO_BIG_FIELDLENGTH';
exports[1075] = 'ER_WRONG_AUTO_KEY';
exports[1076] = 'ER_READY';
exports[1077] = 'ER_NORMAL_SHUTDOWN';
exports[1078] = 'ER_GOT_SIGNAL';
exports[1079] = 'ER_SHUTDOWN_COMPLETE';
exports[1080] = 'ER_FORCING_CLOSE';
exports[1081] = 'ER_IPSOCK_ERROR';
exports[1082] = 'ER_NO_SUCH_INDEX';
exports[1083] = 'ER_WRONG_FIELD_TERMINATORS';
exports[1084] = 'ER_BLOBS_AND_NO_TERMINATED';
exports[1085] = 'ER_TEXTFILE_NOT_READABLE';
exports[1086] = 'ER_FILE_EXISTS_ERROR';
exports[1087] = 'ER_LOAD_INFO';
exports[1088] = 'ER_ALTER_INFO';
exports[1089] = 'ER_WRONG_SUB_KEY';
exports[1090] = 'ER_CANT_REMOVE_ALL_FIELDS';
exports[1091] = 'ER_CANT_DROP_FIELD_OR_KEY';
exports[1092] = 'ER_INSERT_INFO';
exports[1093] = 'ER_UPDATE_TABLE_USED';
exports[1094] = 'ER_NO_SUCH_THREAD';
exports[1095] = 'ER_KILL_DENIED_ERROR';
exports[1096] = 'ER_NO_TABLES_USED';
exports[1097] = 'ER_TOO_BIG_SET';
exports[1098] = 'ER_NO_UNIQUE_LOGFILE';
exports[1099] = 'ER_TABLE_NOT_LOCKED_FOR_WRITE';
exports[1100] = 'ER_TABLE_NOT_LOCKED';
exports[1101] = 'ER_BLOB_CANT_HAVE_DEFAULT';
exports[1102] = 'ER_WRONG_DB_NAME';
exports[1103] = 'ER_WRONG_TABLE_NAME';
exports[1104] = 'ER_TOO_BIG_SELECT';
exports[1105] = 'ER_UNKNOWN_ERROR';
exports[1106] = 'ER_UNKNOWN_PROCEDURE';
exports[1107] = 'ER_WRONG_PARAMCOUNT_TO_PROCEDURE';
exports[1108] = 'ER_WRONG_PARAMETERS_TO_PROCEDURE';
exports[1109] = 'ER_UNKNOWN_TABLE';
exports[1110] = 'ER_FIELD_SPECIFIED_TWICE';
exports[1111] = 'ER_INVALID_GROUP_FUNC_USE';
exports[1112] = 'ER_UNSUPPORTED_EXTENSION';
exports[1113] = 'ER_TABLE_MUST_HAVE_COLUMNS';
exports[1114] = 'ER_RECORD_FILE_FULL';
exports[1115] = 'ER_UNKNOWN_CHARACTER_SET';
exports[1116] = 'ER_TOO_MANY_TABLES';
exports[1117] = 'ER_TOO_MANY_FIELDS';
exports[1118] = 'ER_TOO_BIG_ROWSIZE';
exports[1119] = 'ER_STACK_OVERRUN';
exports[1120] = 'ER_WRONG_OUTER_JOIN';
exports[1121] = 'ER_NULL_COLUMN_IN_INDEX';
exports[1122] = 'ER_CANT_FIND_UDF';
exports[1123] = 'ER_CANT_INITIALIZE_UDF';
exports[1124] = 'ER_UDF_NO_PATHS';
exports[1125] = 'ER_UDF_EXISTS';
exports[1126] = 'ER_CANT_OPEN_LIBRARY';
exports[1127] = 'ER_CANT_FIND_DL_ENTRY';
exports[1128] = 'ER_FUNCTION_NOT_DEFINED';
exports[1129] = 'ER_HOST_IS_BLOCKED';
exports[1130] = 'ER_HOST_NOT_PRIVILEGED';
exports[1131] = 'ER_PASSWORD_ANONYMOUS_USER';
exports[1132] = 'ER_PASSWORD_NOT_ALLOWED';
exports[1133] = 'ER_PASSWORD_NO_MATCH';
exports[1134] = 'ER_UPDATE_INFO';
exports[1135] = 'ER_CANT_CREATE_THREAD';
exports[1136] = 'ER_WRONG_VALUE_COUNT_ON_ROW';
exports[1137] = 'ER_CANT_REOPEN_TABLE';
exports[1138] = 'ER_INVALID_USE_OF_NULL';
exports[1139] = 'ER_REGEXP_ERROR';
exports[1140] = 'ER_MIX_OF_GROUP_FUNC_AND_FIELDS';
exports[1141] = 'ER_NONEXISTING_GRANT';
exports[1142] = 'ER_TABLEACCESS_DENIED_ERROR';
exports[1143] = 'ER_COLUMNACCESS_DENIED_ERROR';
exports[1144] = 'ER_ILLEGAL_GRANT_FOR_TABLE';
exports[1145] = 'ER_GRANT_WRONG_HOST_OR_USER';
exports[1146] = 'ER_NO_SUCH_TABLE';
exports[1147] = 'ER_NONEXISTING_TABLE_GRANT';
exports[1148] = 'ER_NOT_ALLOWED_COMMAND';
exports[1149] = 'ER_SYNTAX_ERROR';
exports[1150] = 'ER_DELAYED_CANT_CHANGE_LOCK';
exports[1151] = 'ER_TOO_MANY_DELAYED_THREADS';
exports[1152] = 'ER_ABORTING_CONNECTION';
exports[1153] = 'ER_NET_PACKET_TOO_LARGE';
exports[1154] = 'ER_NET_READ_ERROR_FROM_PIPE';
exports[1155] = 'ER_NET_FCNTL_ERROR';
exports[1156] = 'ER_NET_PACKETS_OUT_OF_ORDER';
exports[1157] = 'ER_NET_UNCOMPRESS_ERROR';
exports[1158] = 'ER_NET_READ_ERROR';
exports[1159] = 'ER_NET_READ_INTERRUPTED';
exports[1160] = 'ER_NET_ERROR_ON_WRITE';
exports[1161] = 'ER_NET_WRITE_INTERRUPTED';
exports[1162] = 'ER_TOO_LONG_STRING';
exports[1163] = 'ER_TABLE_CANT_HANDLE_BLOB';
exports[1164] = 'ER_TABLE_CANT_HANDLE_AUTO_INCREMENT';
exports[1165] = 'ER_DELAYED_INSERT_TABLE_LOCKED';
exports[1166] = 'ER_WRONG_COLUMN_NAME';
exports[1167] = 'ER_WRONG_KEY_COLUMN';
exports[1168] = 'ER_WRONG_MRG_TABLE';
exports[1169] = 'ER_DUP_UNIQUE';
exports[1170] = 'ER_BLOB_KEY_WITHOUT_LENGTH';
exports[1171] = 'ER_PRIMARY_CANT_HAVE_NULL';
exports[1172] = 'ER_TOO_MANY_ROWS';
exports[1173] = 'ER_REQUIRES_PRIMARY_KEY';
exports[1174] = 'ER_NO_RAID_COMPILED';
exports[1175] = 'ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE';
exports[1176] = 'ER_KEY_DOES_NOT_EXITS';
exports[1177] = 'ER_CHECK_NO_SUCH_TABLE';
exports[1178] = 'ER_CHECK_NOT_IMPLEMENTED';
exports[1179] = 'ER_CANT_DO_THIS_DURING_AN_TRANSACTION';
exports[1180] = 'ER_ERROR_DURING_COMMIT';
exports[1181] = 'ER_ERROR_DURING_ROLLBACK';
exports[1182] = 'ER_ERROR_DURING_FLUSH_LOGS';
exports[1183] = 'ER_ERROR_DURING_CHECKPOINT';
exports[1184] = 'ER_NEW_ABORTING_CONNECTION';
exports[1185] = 'ER_DUMP_NOT_IMPLEMENTED';
exports[1186] = 'ER_FLUSH_MASTER_BINLOG_CLOSED';
exports[1187] = 'ER_INDEX_REBUILD';
exports[1188] = 'ER_MASTER';
exports[1189] = 'ER_MASTER_NET_READ';
exports[1190] = 'ER_MASTER_NET_WRITE';
exports[1191] = 'ER_FT_MATCHING_KEY_NOT_FOUND';
exports[1192] = 'ER_LOCK_OR_ACTIVE_TRANSACTION';
exports[1193] = 'ER_UNKNOWN_SYSTEM_VARIABLE';
exports[1194] = 'ER_CRASHED_ON_USAGE';
exports[1195] = 'ER_CRASHED_ON_REPAIR';
exports[1196] = 'ER_WARNING_NOT_COMPLETE_ROLLBACK';
exports[1197] = 'ER_TRANS_CACHE_FULL';
exports[1198] = 'ER_SLAVE_MUST_STOP';
exports[1199] = 'ER_SLAVE_NOT_RUNNING';
exports[1200] = 'ER_BAD_SLAVE';
exports[1201] = 'ER_MASTER_INFO';
exports[1202] = 'ER_SLAVE_THREAD';
exports[1203] = 'ER_TOO_MANY_USER_CONNECTIONS';
exports[1204] = 'ER_SET_CONSTANTS_ONLY';
exports[1205] = 'ER_LOCK_WAIT_TIMEOUT';
exports[1206] = 'ER_LOCK_TABLE_FULL';
exports[1207] = 'ER_READ_ONLY_TRANSACTION';
exports[1208] = 'ER_DROP_DB_WITH_READ_LOCK';
exports[1209] = 'ER_CREATE_DB_WITH_READ_LOCK';
exports[1210] = 'ER_WRONG_ARGUMENTS';
exports[1211] = 'ER_NO_PERMISSION_TO_CREATE_USER';
exports[1212] = 'ER_UNION_TABLES_IN_DIFFERENT_DIR';
exports[1213] = 'ER_LOCK_DEADLOCK';
exports[1214] = 'ER_TABLE_CANT_HANDLE_FT';
exports[1215] = 'ER_CANNOT_ADD_FOREIGN';
exports[1216] = 'ER_NO_REFERENCED_ROW';
exports[1217] = 'ER_ROW_IS_REFERENCED';
exports[1218] = 'ER_CONNECT_TO_MASTER';
exports[1219] = 'ER_QUERY_ON_MASTER';
exports[1220] = 'ER_ERROR_WHEN_EXECUTING_COMMAND';
exports[1221] = 'ER_WRONG_USAGE';
exports[1222] = 'ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT';
exports[1223] = 'ER_CANT_UPDATE_WITH_READLOCK';
exports[1224] = 'ER_MIXING_NOT_ALLOWED';
exports[1225] = 'ER_DUP_ARGUMENT';
exports[1226] = 'ER_USER_LIMIT_REACHED';
exports[1227] = 'ER_SPECIFIC_ACCESS_DENIED_ERROR';
exports[1228] = 'ER_LOCAL_VARIABLE';
exports[1229] = 'ER_GLOBAL_VARIABLE';
exports[1230] = 'ER_NO_DEFAULT';
exports[1231] = 'ER_WRONG_VALUE_FOR_VAR';
exports[1232] = 'ER_WRONG_TYPE_FOR_VAR';
exports[1233] = 'ER_VAR_CANT_BE_READ';
exports[1234] = 'ER_CANT_USE_OPTION_HERE';
exports[1235] = 'ER_NOT_SUPPORTED_YET';
exports[1236] = 'ER_MASTER_FATAL_ERROR_READING_BINLOG';
exports[1237] = 'ER_SLAVE_IGNORED_TABLE';
exports[1238] = 'ER_INCORRECT_GLOBAL_LOCAL_VAR';
exports[1239] = 'ER_WRONG_FK_DEF';
exports[1240] = 'ER_KEY_REF_DO_NOT_MATCH_TABLE_REF';
exports[1241] = 'ER_OPERAND_COLUMNS';
exports[1242] = 'ER_SUBQUERY_NO_';
exports[1243] = 'ER_UNKNOWN_STMT_HANDLER';
exports[1244] = 'ER_CORRUPT_HELP_DB';
exports[1245] = 'ER_CYCLIC_REFERENCE';
exports[1246] = 'ER_AUTO_CONVERT';
exports[1247] = 'ER_ILLEGAL_REFERENCE';
exports[1248] = 'ER_DERIVED_MUST_HAVE_ALIAS';
exports[1249] = 'ER_SELECT_REDUCED';
exports[1250] = 'ER_TABLENAME_NOT_ALLOWED_HERE';
exports[1251] = 'ER_NOT_SUPPORTED_AUTH_MODE';
exports[1252] = 'ER_SPATIAL_CANT_HAVE_NULL';
exports[1253] = 'ER_COLLATION_CHARSET_MISMATCH';
exports[1254] = 'ER_SLAVE_WAS_RUNNING';
exports[1255] = 'ER_SLAVE_WAS_NOT_RUNNING';
exports[1256] = 'ER_TOO_BIG_FOR_UNCOMPRESS';
exports[1257] = 'ER_ZLIB_Z_MEM_ERROR';
exports[1258] = 'ER_ZLIB_Z_BUF_ERROR';
exports[1259] = 'ER_ZLIB_Z_DATA_ERROR';
exports[1260] = 'ER_CUT_VALUE_GROUP_CONCAT';
exports[1261] = 'ER_WARN_TOO_FEW_RECORDS';
exports[1262] = 'ER_WARN_TOO_MANY_RECORDS';
exports[1263] = 'ER_WARN_NULL_TO_NOTNULL';
exports[1264] = 'ER_WARN_DATA_OUT_OF_RANGE';
exports[1265] = 'WARN_DATA_TRUNCATED';
exports[1266] = 'ER_WARN_USING_OTHER_HANDLER';
exports[1267] = 'ER_CANT_AGGREGATE_';
exports[1268] = 'ER_DROP_USER';
exports[1269] = 'ER_REVOKE_GRANTS';
exports[1270] = 'ER_CANT_AGGREGATE_';
exports[1271] = 'ER_CANT_AGGREGATE_NCOLLATIONS';
exports[1272] = 'ER_VARIABLE_IS_NOT_STRUCT';
exports[1273] = 'ER_UNKNOWN_COLLATION';
exports[1274] = 'ER_SLAVE_IGNORED_SSL_PARAMS';
exports[1275] = 'ER_SERVER_IS_IN_SECURE_AUTH_MODE';
exports[1276] = 'ER_WARN_FIELD_RESOLVED';
exports[1277] = 'ER_BAD_SLAVE_UNTIL_COND';
exports[1278] = 'ER_MISSING_SKIP_SLAVE';
exports[1279] = 'ER_UNTIL_COND_IGNORED';
exports[1280] = 'ER_WRONG_NAME_FOR_INDEX';
exports[1281] = 'ER_WRONG_NAME_FOR_CATALOG';
exports[1282] = 'ER_WARN_QC_RESIZE';
exports[1283] = 'ER_BAD_FT_COLUMN';
exports[1284] = 'ER_UNKNOWN_KEY_CACHE';
exports[1285] = 'ER_WARN_HOSTNAME_WONT_WORK';
exports[1286] = 'ER_UNKNOWN_STORAGE_ENGINE';
exports[1287] = 'ER_WARN_DEPRECATED_SYNTAX';
exports[1288] = 'ER_NON_UPDATABLE_TABLE';
exports[1289] = 'ER_FEATURE_DISABLED';
exports[1290] = 'ER_OPTION_PREVENTS_STATEMENT';
exports[1291] = 'ER_DUPLICATED_VALUE_IN_TYPE';
exports[1292] = 'ER_TRUNCATED_WRONG_VALUE';
exports[1293] = 'ER_TOO_MUCH_AUTO_TIMESTAMP_COLS';
exports[1294] = 'ER_INVALID_ON_UPDATE';
exports[1295] = 'ER_UNSUPPORTED_PS';
exports[1296] = 'ER_GET_ERRMSG';
exports[1297] = 'ER_GET_TEMPORARY_ERRMSG';
exports[1298] = 'ER_UNKNOWN_TIME_ZONE';
exports[1299] = 'ER_WARN_INVALID_TIMESTAMP';
exports[1300] = 'ER_INVALID_CHARACTER_STRING';
exports[1301] = 'ER_WARN_ALLOWED_PACKET_OVERFLOWED';
exports[1302] = 'ER_CONFLICTING_DECLARATIONS';
exports[1303] = 'ER_SP_NO_RECURSIVE_CREATE';
exports[1304] = 'ER_SP_ALREADY_EXISTS';
exports[1305] = 'ER_SP_DOES_NOT_EXIST';
exports[1306] = 'ER_SP_DROP_FAILED';
exports[1307] = 'ER_SP_STORE_FAILED';
exports[1308] = 'ER_SP_LILABEL_MISMATCH';
exports[1309] = 'ER_SP_LABEL_REDEFINE';
exports[1310] = 'ER_SP_LABEL_MISMATCH';
exports[1311] = 'ER_SP_UNINIT_VAR';
exports[1312] = 'ER_SP_BADSELECT';
exports[1313] = 'ER_SP_BADRETURN';
exports[1314] = 'ER_SP_BADSTATEMENT';
exports[1315] = 'ER_UPDATE_LOG_DEPRECATED_IGNORED';
exports[1316] = 'ER_UPDATE_LOG_DEPRECATED_TRANSLATED';
exports[1317] = 'ER_QUERY_INTERRUPTED';
exports[1318] = 'ER_SP_WRONG_NO_OF_ARGS';
exports[1319] = 'ER_SP_COND_MISMATCH';
exports[1320] = 'ER_SP_NORETURN';
exports[1321] = 'ER_SP_NORETURNEND';
exports[1322] = 'ER_SP_BAD_CURSOR_QUERY';
exports[1323] = 'ER_SP_BAD_CURSOR_SELECT';
exports[1324] = 'ER_SP_CURSOR_MISMATCH';
exports[1325] = 'ER_SP_CURSOR_ALREADY_OPEN';
exports[1326] = 'ER_SP_CURSOR_NOT_OPEN';
exports[1327] = 'ER_SP_UNDECLARED_VAR';
exports[1328] = 'ER_SP_WRONG_NO_OF_FETCH_ARGS';
exports[1329] = 'ER_SP_FETCH_NO_DATA';
exports[1330] = 'ER_SP_DUP_PARAM';
exports[1331] = 'ER_SP_DUP_VAR';
exports[1332] = 'ER_SP_DUP_COND';
exports[1333] = 'ER_SP_DUP_CURS';
exports[1334] = 'ER_SP_CANT_ALTER';
exports[1335] = 'ER_SP_SUBSELECT_NYI';
exports[1336] = 'ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG';
exports[1337] = 'ER_SP_VARCOND_AFTER_CURSHNDLR';
exports[1338] = 'ER_SP_CURSOR_AFTER_HANDLER';
exports[1339] = 'ER_SP_CASE_NOT_FOUND';
exports[1340] = 'ER_FPARSER_TOO_BIG_FILE';
exports[1341] = 'ER_FPARSER_BAD_HEADER';
exports[1342] = 'ER_FPARSER_EOF_IN_COMMENT';
exports[1343] = 'ER_FPARSER_ERROR_IN_PARAMETER';
exports[1344] = 'ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER';
exports[1345] = 'ER_VIEW_NO_EXPLAIN';
exports[1346] = 'ER_FRM_UNKNOWN_TYPE';
exports[1347] = 'ER_WRONG_OBJECT';
exports[1348] = 'ER_NONUPDATEABLE_COLUMN';
exports[1349] = 'ER_VIEW_SELECT_DERIVED';
exports[1350] = 'ER_VIEW_SELECT_CLAUSE';
exports[1351] = 'ER_VIEW_SELECT_VARIABLE';
exports[1352] = 'ER_VIEW_SELECT_TMPTABLE';
exports[1353] = 'ER_VIEW_WRONG_LIST';
exports[1354] = 'ER_WARN_VIEW_MERGE';
exports[1355] = 'ER_WARN_VIEW_WITHOUT_KEY';
exports[1356] = 'ER_VIEW_INVALID';
exports[1357] = 'ER_SP_NO_DROP_SP';
exports[1358] = 'ER_SP_GOTO_IN_HNDLR';
exports[1359] = 'ER_TRG_ALREADY_EXISTS';
exports[1360] = 'ER_TRG_DOES_NOT_EXIST';
exports[1361] = 'ER_TRG_ON_VIEW_OR_TEMP_TABLE';
exports[1362] = 'ER_TRG_CANT_CHANGE_ROW';
exports[1363] = 'ER_TRG_NO_SUCH_ROW_IN_TRG';
exports[1364] = 'ER_NO_DEFAULT_FOR_FIELD';
exports[1365] = 'ER_DIVISION_BY_ZERO';
exports[1366] = 'ER_TRUNCATED_WRONG_VALUE_FOR_FIELD';
exports[1367] = 'ER_ILLEGAL_VALUE_FOR_TYPE';
exports[1368] = 'ER_VIEW_NONUPD_CHECK';
exports[1369] = 'ER_VIEW_CHECK_FAILED';
exports[1370] = 'ER_PROCACCESS_DENIED_ERROR';
exports[1371] = 'ER_RELAY_LOG_FAIL';
exports[1372] = 'ER_PASSWD_LENGTH';
exports[1373] = 'ER_UNKNOWN_TARGET_BINLOG';
exports[1374] = 'ER_IO_ERR_LOG_INDEX_READ';
exports[1375] = 'ER_BINLOG_PURGE_PROHIBITED';
exports[1376] = 'ER_FSEEK_FAIL';
exports[1377] = 'ER_BINLOG_PURGE_FATAL_ERR';
exports[1378] = 'ER_LOG_IN_USE';
exports[1379] = 'ER_LOG_PURGE_UNKNOWN_ERR';
exports[1380] = 'ER_RELAY_LOG_INIT';
exports[1381] = 'ER_NO_BINARY_LOGGING';
exports[1382] = 'ER_RESERVED_SYNTAX';
exports[1383] = 'ER_WSAS_FAILED';
exports[1384] = 'ER_DIFF_GROUPS_PROC';
exports[1385] = 'ER_NO_GROUP_FOR_PROC';
exports[1386] = 'ER_ORDER_WITH_PROC';
exports[1387] = 'ER_LOGGING_PROHIBIT_CHANGING_OF';
exports[1388] = 'ER_NO_FILE_MAPPING';
exports[1389] = 'ER_WRONG_MAGIC';
exports[1390] = 'ER_PS_MANY_PARAM';
exports[1391] = 'ER_KEY_PART_';
exports[1392] = 'ER_VIEW_CHECKSUM';
exports[1393] = 'ER_VIEW_MULTIUPDATE';
exports[1394] = 'ER_VIEW_NO_INSERT_FIELD_LIST';
exports[1395] = 'ER_VIEW_DELETE_MERGE_VIEW';
exports[1396] = 'ER_CANNOT_USER';
exports[1397] = 'ER_XAER_NOTA';
exports[1398] = 'ER_XAER_INVAL';
exports[1399] = 'ER_XAER_RMFAIL';
exports[1400] = 'ER_XAER_OUTSIDE';
exports[1401] = 'ER_XAER_RMERR';
exports[1402] = 'ER_XA_RBROLLBACK';
exports[1403] = 'ER_NONEXISTING_PROC_GRANT';
exports[1404] = 'ER_PROC_AUTO_GRANT_FAIL';
exports[1405] = 'ER_PROC_AUTO_REVOKE_FAIL';
exports[1406] = 'ER_DATA_TOO_LONG';
exports[1407] = 'ER_SP_BAD_SQLSTATE';
exports[1408] = 'ER_STARTUP';
exports[1409] = 'ER_LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR';
exports[1410] = 'ER_CANT_CREATE_USER_WITH_GRANT';
exports[1411] = 'ER_WRONG_VALUE_FOR_TYPE';
exports[1412] = 'ER_TABLE_DEF_CHANGED';
exports[1413] = 'ER_SP_DUP_HANDLER';
exports[1414] = 'ER_SP_NOT_VAR_ARG';
exports[1415] = 'ER_SP_NO_RETSET';
exports[1416] = 'ER_CANT_CREATE_GEOMETRY_OBJECT';
exports[1417] = 'ER_FAILED_ROUTINE_BREAK_BINLOG';
exports[1418] = 'ER_BINLOG_UNSAFE_ROUTINE';
exports[1419] = 'ER_BINLOG_CREATE_ROUTINE_NEED_SUPER';
exports[1420] = 'ER_EXEC_STMT_WITH_OPEN_CURSOR';
exports[1421] = 'ER_STMT_HAS_NO_OPEN_CURSOR';
exports[1422] = 'ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG';
exports[1423] = 'ER_NO_DEFAULT_FOR_VIEW_FIELD';
exports[1424] = 'ER_SP_NO_RECURSION';
exports[1425] = 'ER_TOO_BIG_SCALE';
exports[1426] = 'ER_TOO_BIG_PRECISION';
exports[1427] = 'ER_M_BIGGER_THAN_D';
exports[1428] = 'ER_WRONG_LOCK_OF_SYSTEM_TABLE';
exports[1429] = 'ER_CONNECT_TO_FOREIGN_DATA_SOURCE';
exports[1430] = 'ER_QUERY_ON_FOREIGN_DATA_SOURCE';
exports[1431] = 'ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST';
exports[1432] = 'ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE';
exports[1433] = 'ER_FOREIGN_DATA_STRING_INVALID';
exports[1434] = 'ER_CANT_CREATE_FEDERATED_TABLE';
exports[1435] = 'ER_TRG_IN_WRONG_SCHEMA';
exports[1436] = 'ER_STACK_OVERRUN_NEED_MORE';
exports[1437] = 'ER_TOO_LONG_BODY';
exports[1438] = 'ER_WARN_CANT_DROP_DEFAULT_KEYCACHE';
exports[1439] = 'ER_TOO_BIG_DISPLAYWIDTH';
exports[1440] = 'ER_XAER_DUPID';
exports[1441] = 'ER_DATETIME_FUNCTION_OVERFLOW';
exports[1442] = 'ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG';
exports[1443] = 'ER_VIEW_PREVENT_UPDATE';
exports[1444] = 'ER_PS_NO_RECURSION';
exports[1445] = 'ER_SP_CANT_SET_AUTOCOMMIT';
exports[1446] = 'ER_MALFORMED_DEFINER';
exports[1447] = 'ER_VIEW_FRM_NO_USER';
exports[1448] = 'ER_VIEW_OTHER_USER';
exports[1449] = 'ER_NO_SUCH_USER';
exports[1450] = 'ER_FORBID_SCHEMA_CHANGE';
exports[1451] = 'ER_ROW_IS_REFERENCED_';
exports[1452] = 'ER_NO_REFERENCED_ROW_';
exports[1453] = 'ER_SP_BAD_VAR_SHADOW';
exports[1454] = 'ER_TRG_NO_DEFINER';
exports[1455] = 'ER_OLD_FILE_FORMAT';
exports[1456] = 'ER_SP_RECURSION_LIMIT';
exports[1457] = 'ER_SP_PROC_TABLE_CORRUPT';
exports[1458] = 'ER_SP_WRONG_NAME';
exports[1459] = 'ER_TABLE_NEEDS_UPGRADE';
exports[1460] = 'ER_SP_NO_AGGREGATE';
exports[1461] = 'ER_MAX_PREPARED_STMT_COUNT_REACHED';
exports[1462] = 'ER_VIEW_RECURSIVE';
exports[1463] = 'ER_NON_GROUPING_FIELD_USED';
exports[1464] = 'ER_TABLE_CANT_HANDLE_SPKEYS';
exports[1465] = 'ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA';
exports[1466] = 'ER_REMOVED_SPACES';
exports[1467] = 'ER_AUTOINC_READ_FAILED';
exports[1468] = 'ER_USERNAME';
exports[1469] = 'ER_HOSTNAME';
exports[1470] = 'ER_WRONG_STRING_LENGTH';
exports[1471] = 'ER_NON_INSERTABLE_TABLE';
exports[1472] = 'ER_ADMIN_WRONG_MRG_TABLE';
exports[1473] = 'ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT';
exports[1474] = 'ER_NAME_BECOMES_EMPTY';
exports[1475] = 'ER_AMBIGUOUS_FIELD_TERM';
exports[1476] = 'ER_FOREIGN_SERVER_EXISTS';
exports[1477] = 'ER_FOREIGN_SERVER_DOESNT_EXIST';
exports[1478] = 'ER_ILLEGAL_HA_CREATE_OPTION';
exports[1479] = 'ER_PARTITION_REQUIRES_VALUES_ERROR';
exports[1480] = 'ER_PARTITION_WRONG_VALUES_ERROR';
exports[1481] = 'ER_PARTITION_MAXVALUE_ERROR';
exports[1482] = 'ER_PARTITION_SUBPARTITION_ERROR';
exports[1483] = 'ER_PARTITION_SUBPART_MIX_ERROR';
exports[1484] = 'ER_PARTITION_WRONG_NO_PART_ERROR';
exports[1485] = 'ER_PARTITION_WRONG_NO_SUBPART_ERROR';
exports[1486] = 'ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR';
exports[1487] = 'ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR';
exports[1488] = 'ER_FIELD_NOT_FOUND_PART_ERROR';
exports[1489] = 'ER_LIST_OF_FIELDS_ONLY_IN_HASH_ERROR';
exports[1490] = 'ER_INCONSISTENT_PARTITION_INFO_ERROR';
exports[1491] = 'ER_PARTITION_FUNC_NOT_ALLOWED_ERROR';
exports[1492] = 'ER_PARTITIONS_MUST_BE_DEFINED_ERROR';
exports[1493] = 'ER_RANGE_NOT_INCREASING_ERROR';
exports[1494] = 'ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR';
exports[1495] = 'ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR';
exports[1496] = 'ER_PARTITION_ENTRY_ERROR';
exports[1497] = 'ER_MIX_HANDLER_ERROR';
exports[1498] = 'ER_PARTITION_NOT_DEFINED_ERROR';
exports[1499] = 'ER_TOO_MANY_PARTITIONS_ERROR';
exports[1500] = 'ER_SUBPARTITION_ERROR';
exports[1501] = 'ER_CANT_CREATE_HANDLER_FILE';
exports[1502] = 'ER_BLOB_FIELD_IN_PART_FUNC_ERROR';
exports[1503] = 'ER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF';
exports[1504] = 'ER_NO_PARTS_ERROR';
exports[1505] = 'ER_PARTITION_MGMT_ON_NONPARTITIONED';
exports[1506] = 'ER_FOREIGN_KEY_ON_PARTITIONED';
exports[1507] = 'ER_DROP_PARTITION_NON_EXISTENT';
exports[1508] = 'ER_DROP_LAST_PARTITION';
exports[1509] = 'ER_COALESCE_ONLY_ON_HASH_PARTITION';
exports[1510] = 'ER_REORG_HASH_ONLY_ON_SAME_NO';
exports[1511] = 'ER_REORG_NO_PARAM_ERROR';
exports[1512] = 'ER_ONLY_ON_RANGE_LIST_PARTITION';
exports[1513] = 'ER_ADD_PARTITION_SUBPART_ERROR';
exports[1514] = 'ER_ADD_PARTITION_NO_NEW_PARTITION';
exports[1515] = 'ER_COALESCE_PARTITION_NO_PARTITION';
exports[1516] = 'ER_REORG_PARTITION_NOT_EXIST';
exports[1517] = 'ER_SAME_NAME_PARTITION';
exports[1518] = 'ER_NO_BINLOG_ERROR';
exports[1519] = 'ER_CONSECUTIVE_REORG_PARTITIONS';
exports[1520] = 'ER_REORG_OUTSIDE_RANGE';
exports[1521] = 'ER_PARTITION_FUNCTION_FAILURE';
exports[1522] = 'ER_PART_STATE_ERROR';
exports[1523] = 'ER_LIMITED_PART_RANGE';
exports[1524] = 'ER_PLUGIN_IS_NOT_LOADED';
exports[1525] = 'ER_WRONG_VALUE';
exports[1526] = 'ER_NO_PARTITION_FOR_GIVEN_VALUE';
exports[1527] = 'ER_FILEGROUP_OPTION_ONLY_ONCE';
exports[1528] = 'ER_CREATE_FILEGROUP_FAILED';
exports[1529] = 'ER_DROP_FILEGROUP_FAILED';
exports[1530] = 'ER_TABLESPACE_AUTO_EXTEND_ERROR';
exports[1531] = 'ER_WRONG_SIZE_NUMBER';
exports[1532] = 'ER_SIZE_OVERFLOW_ERROR';
exports[1533] = 'ER_ALTER_FILEGROUP_FAILED';
exports[1534] = 'ER_BINLOG_ROW_LOGGING_FAILED';
exports[1535] = 'ER_BINLOG_ROW_WRONG_TABLE_DEF';
exports[1536] = 'ER_BINLOG_ROW_RBR_TO_SBR';
exports[1537] = 'ER_EVENT_ALREADY_EXISTS';
exports[1538] = 'ER_EVENT_STORE_FAILED';
exports[1539] = 'ER_EVENT_DOES_NOT_EXIST';
exports[1540] = 'ER_EVENT_CANT_ALTER';
exports[1541] = 'ER_EVENT_DROP_FAILED';
exports[1542] = 'ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG';
exports[1543] = 'ER_EVENT_ENDS_BEFORE_STARTS';
exports[1544] = 'ER_EVENT_EXEC_TIME_IN_THE_PAST';
exports[1545] = 'ER_EVENT_OPEN_TABLE_FAILED';
exports[1546] = 'ER_EVENT_NEITHER_M_EXPR_NOR_M_AT';
exports[1547] = 'ER_COL_COUNT_DOESNT_MATCH_CORRUPTED';
exports[1548] = 'ER_CANNOT_LOAD_FROM_TABLE';
exports[1549] = 'ER_EVENT_CANNOT_DELETE';
exports[1550] = 'ER_EVENT_COMPILE_ERROR';
exports[1551] = 'ER_EVENT_SAME_NAME';
exports[1552] = 'ER_EVENT_DATA_TOO_LONG';
exports[1553] = 'ER_DROP_INDEX_FK';
exports[1554] = 'ER_WARN_DEPRECATED_SYNTAX_WITH_VER';
exports[1555] = 'ER_CANT_WRITE_LOCK_LOG_TABLE';
exports[1556] = 'ER_CANT_LOCK_LOG_TABLE';
exports[1557] = 'ER_FOREIGN_DUPLICATE_KEY';
exports[1558] = 'ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE';
exports[1559] = 'ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR';
exports[1560] = 'ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT';
exports[1561] = 'ER_NDB_CANT_SWITCH_BINLOG_FORMAT';
exports[1562] = 'ER_PARTITION_NO_TEMPORARY';
exports[1563] = 'ER_PARTITION_CONST_DOMAIN_ERROR';
exports[1564] = 'ER_PARTITION_FUNCTION_IS_NOT_ALLOWED';
exports[1565] = 'ER_DDL_LOG_ERROR';
exports[1566] = 'ER_NULL_IN_VALUES_LESS_THAN';
exports[1567] = 'ER_WRONG_PARTITION_NAME';
exports[1568] = 'ER_CANT_CHANGE_TX_CHARACTERISTICS';
exports[1569] = 'ER_DUP_ENTRY_AUTOINCREMENT_CASE';
exports[1570] = 'ER_EVENT_MODIFY_QUEUE_ERROR';
exports[1571] = 'ER_EVENT_SET_VAR_ERROR';
exports[1572] = 'ER_PARTITION_MERGE_ERROR';
exports[1573] = 'ER_CANT_ACTIVATE_LOG';
exports[1574] = 'ER_RBR_NOT_AVAILABLE';
exports[1575] = 'ER_BASE';
exports[1576] = 'ER_EVENT_RECURSION_FORBIDDEN';
exports[1577] = 'ER_EVENTS_DB_ERROR';
exports[1578] = 'ER_ONLY_INTEGERS_ALLOWED';
exports[1579] = 'ER_UNSUPORTED_LOG_ENGINE';
exports[1580] = 'ER_BAD_LOG_STATEMENT';
exports[1581] = 'ER_CANT_RENAME_LOG_TABLE';
exports[1582] = 'ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT';
exports[1583] = 'ER_WRONG_PARAMETERS_TO_NATIVE_FCT';
exports[1584] = 'ER_WRONG_PARAMETERS_TO_STORED_FCT';
exports[1585] = 'ER_NATIVE_FCT_NAME_COLLISION';
exports[1586] = 'ER_DUP_ENTRY_WITH_KEY_NAME';
exports[1587] = 'ER_BINLOG_PURGE_EMFILE';
exports[1588] = 'ER_EVENT_CANNOT_CREATE_IN_THE_PAST';
exports[1589] = 'ER_EVENT_CANNOT_ALTER_IN_THE_PAST';
exports[1590] = 'ER_SLAVE_INCIDENT';
exports[1591] = 'ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT';
exports[1592] = 'ER_BINLOG_UNSAFE_STATEMENT';
exports[1593] = 'ER_SLAVE_FATAL_ERROR';
exports[1594] = 'ER_SLAVE_RELAY_LOG_READ_FAILURE';
exports[1595] = 'ER_SLAVE_RELAY_LOG_WRITE_FAILURE';
exports[1596] = 'ER_SLAVE_CREATE_EVENT_FAILURE';
exports[1597] = 'ER_SLAVE_MASTER_COM_FAILURE';
exports[1598] = 'ER_BINLOG_LOGGING_IMPOSSIBLE';
exports[1599] = 'ER_VIEW_NO_CREATION_CTX';
exports[1600] = 'ER_VIEW_INVALID_CREATION_CTX';
exports[1601] = 'ER_SR_INVALID_CREATION_CTX';
exports[1602] = 'ER_TRG_CORRUPTED_FILE';
exports[1603] = 'ER_TRG_NO_CREATION_CTX';
exports[1604] = 'ER_TRG_INVALID_CREATION_CTX';
exports[1605] = 'ER_EVENT_INVALID_CREATION_CTX';
exports[1606] = 'ER_TRG_CANT_OPEN_TABLE';
exports[1607] = 'ER_CANT_CREATE_SROUTINE';
exports[1608] = 'ER_NEVER_USED';
exports[1609] = 'ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT';
exports[1610] = 'ER_SLAVE_CORRUPT_EVENT';
exports[1611] = 'ER_LOAD_DATA_INVALID_COLUMN';
exports[1612] = 'ER_LOG_PURGE_NO_FILE';
exports[1613] = 'ER_XA_RBTIMEOUT';
exports[1614] = 'ER_XA_RBDEADLOCK';
exports[1615] = 'ER_NEED_REPREPARE';
exports[1616] = 'ER_DELAYED_NOT_SUPPORTED';
exports[1617] = 'WARN_NO_MASTER_INFO';
exports[1618] = 'WARN_OPTION_IGNORED';
exports[1619] = 'WARN_PLUGIN_DELETE_BUILTIN';
exports[1620] = 'WARN_PLUGIN_BUSY';
exports[1621] = 'ER_VARIABLE_IS_READONLY';
exports[1622] = 'ER_WARN_ENGINE_TRANSACTION_ROLLBACK';
exports[1623] = 'ER_SLAVE_HEARTBEAT_FAILURE';
exports[1624] = 'ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE';
exports[1625] = 'ER_NDB_REPLICATION_SCHEMA_ERROR';
exports[1626] = 'ER_CONFLICT_FN_PARSE_ERROR';
exports[1627] = 'ER_EXCEPTIONS_WRITE_ERROR';
exports[1628] = 'ER_TOO_LONG_TABLE_COMMENT';
exports[1629] = 'ER_TOO_LONG_FIELD_COMMENT';
exports[1630] = 'ER_FUNC_INEXISTENT_NAME_COLLISION';
exports[1631] = 'ER_DATABASE_NAME';
exports[1632] = 'ER_TABLE_NAME';
exports[1633] = 'ER_PARTITION_NAME';
exports[1634] = 'ER_SUBPARTITION_NAME';
exports[1635] = 'ER_TEMPORARY_NAME';
exports[1636] = 'ER_RENAMED_NAME';
exports[1637] = 'ER_TOO_MANY_CONCURRENT_TRXS';
exports[1638] = 'WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED';
exports[1639] = 'ER_DEBUG_SYNC_TIMEOUT';
exports[1640] = 'ER_DEBUG_SYNC_HIT_LIMIT';
exports[1641] = 'ER_DUP_SIGNAL_SET';
exports[1642] = 'ER_SIGNAL_WARN';
exports[1643] = 'ER_SIGNAL_NOT_FOUND';
exports[1644] = 'ER_SIGNAL_EXCEPTION';
exports[1645] = 'ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER';
exports[1646] = 'ER_SIGNAL_BAD_CONDITION_TYPE';
exports[1647] = 'WARN_COND_ITEM_TRUNCATED';
exports[1648] = 'ER_COND_ITEM_TOO_LONG';
exports[1649] = 'ER_UNKNOWN_LOCALE';
exports[1650] = 'ER_SLAVE_IGNORE_SERVER_IDS';
exports[1651] = 'ER_QUERY_CACHE_DISABLED';
exports[1652] = 'ER_SAME_NAME_PARTITION_FIELD';
exports[1653] = 'ER_PARTITION_COLUMN_LIST_ERROR';
exports[1654] = 'ER_WRONG_TYPE_COLUMN_VALUE_ERROR';
exports[1655] = 'ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR';
exports[1656] = 'ER_MAXVALUE_IN_VALUES_IN';
exports[1657] = 'ER_TOO_MANY_VALUES_ERROR';
exports[1658] = 'ER_ROW_SINGLE_PARTITION_FIELD_ERROR';
exports[1659] = 'ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD';
exports[1660] = 'ER_PARTITION_FIELDS_TOO_LONG';
exports[1661] = 'ER_BINLOG_ROW_ENGINE_AND_STMT_ENGINE';
exports[1662] = 'ER_BINLOG_ROW_MODE_AND_STMT_ENGINE';
exports[1663] = 'ER_BINLOG_UNSAFE_AND_STMT_ENGINE';
exports[1664] = 'ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE';
exports[1665] = 'ER_BINLOG_STMT_MODE_AND_ROW_ENGINE';
exports[1666] = 'ER_BINLOG_ROW_INJECTION_AND_STMT_MODE';
exports[1667] = 'ER_BINLOG_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE';
exports[1668] = 'ER_BINLOG_UNSAFE_LIMIT';
exports[1669] = 'ER_BINLOG_UNSAFE_INSERT_DELAYED';
exports[1670] = 'ER_BINLOG_UNSAFE_SYSTEM_TABLE';
exports[1671] = 'ER_BINLOG_UNSAFE_AUTOINC_COLUMNS';
exports[1672] = 'ER_BINLOG_UNSAFE_UDF';
exports[1673] = 'ER_BINLOG_UNSAFE_SYSTEM_VARIABLE';
exports[1674] = 'ER_BINLOG_UNSAFE_SYSTEM_FUNCTION';
exports[1675] = 'ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS';
exports[1676] = 'ER_MESSAGE_AND_STATEMENT';
exports[1677] = 'ER_SLAVE_CONVERSION_FAILED';
exports[1678] = 'ER_SLAVE_CANT_CREATE_CONVERSION';
exports[1679] = 'ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT';
exports[1680] = 'ER_PATH_LENGTH';
exports[1681] = 'ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT';
exports[1682] = 'ER_WRONG_NATIVE_TABLE_STRUCTURE';
exports[1683] = 'ER_WRONG_PERFSCHEMA_USAGE';
exports[1684] = 'ER_WARN_I_S_SKIPPED_TABLE';
exports[1685] = 'ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT';
exports[1686] = 'ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT';
exports[1687] = 'ER_SPATIAL_MUST_HAVE_GEOM_COL';
exports[1688] = 'ER_TOO_LONG_INDEX_COMMENT';
exports[1689] = 'ER_LOCK_ABORTED';
exports[1690] = 'ER_DATA_OUT_OF_RANGE';
exports[1691] = 'ER_WRONG_SPVAR_TYPE_IN_LIMIT';
exports[1692] = 'ER_BINLOG_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE';
exports[1693] = 'ER_BINLOG_UNSAFE_MIXED_STATEMENT';
exports[1694] = 'ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SQL_LOG_BIN';
exports[1695] = 'ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN';
exports[1696] = 'ER_FAILED_READ_FROM_PAR_FILE';
exports[1697] = 'ER_VALUES_IS_NOT_INT_TYPE_ERROR';
exports[1698] = 'ER_ACCESS_DENIED_NO_PASSWORD_ERROR';
exports[1699] = 'ER_SET_PASSWORD_AUTH_PLUGIN';
exports[1700] = 'ER_GRANT_PLUGIN_USER_EXISTS';
exports[1701] = 'ER_TRUNCATE_ILLEGAL_FK';
exports[1702] = 'ER_PLUGIN_IS_PERMANENT';
exports[1703] = 'ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN';
exports[1704] = 'ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX';
exports[1705] = 'ER_STMT_CACHE_FULL';
exports[1706] = 'ER_MULTI_UPDATE_KEY_CONFLICT';
exports[1707] = 'ER_TABLE_NEEDS_REBUILD';
exports[1708] = 'WARN_OPTION_BELOW_LIMIT';
exports[1709] = 'ER_INDEX_COLUMN_TOO_LONG';
exports[1710] = 'ER_ERROR_IN_TRIGGER_BODY';
exports[1711] = 'ER_ERROR_IN_UNKNOWN_TRIGGER_BODY';
exports[1712] = 'ER_INDEX_CORRUPT';
exports[1713] = 'ER_UNDO_RECORD_TOO_BIG';
exports[1714] = 'ER_BINLOG_UNSAFE_INSERT_IGNORE_SELECT';
exports[1715] = 'ER_BINLOG_UNSAFE_INSERT_SELECT_UPDATE';
exports[1716] = 'ER_BINLOG_UNSAFE_REPLACE_SELECT';
exports[1717] = 'ER_BINLOG_UNSAFE_CREATE_IGNORE_SELECT';
exports[1718] = 'ER_BINLOG_UNSAFE_CREATE_REPLACE_SELECT';
exports[1719] = 'ER_BINLOG_UNSAFE_UPDATE_IGNORE';
exports[1720] = 'ER_PLUGIN_NO_UNINSTALL';
exports[1721] = 'ER_PLUGIN_NO_INSTALL';
exports[1722] = 'ER_BINLOG_UNSAFE_WRITE_AUTOINC_SELECT';
exports[1723] = 'ER_BINLOG_UNSAFE_CREATE_SELECT_AUTOINC';
exports[1724] = 'ER_BINLOG_UNSAFE_INSERT_TWO_KEYS';
exports[1725] = 'ER_TABLE_IN_FK_CHECK';
exports[1726] = 'ER_UNSUPPORTED_ENGINE';
exports[1727] = 'ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST';
exports[1728] = 'ER_CANNOT_LOAD_FROM_TABLE_V';
exports[1729] = 'ER_MASTER_DELAY_VALUE_OUT_OF_RANGE';
exports[1730] = 'ER_ONLY_FD_AND_RBR_EVENTS_ALLOWED_IN_BINLOG_STATEMENT';
exports[1731] = 'ER_PARTITION_EXCHANGE_DIFFERENT_OPTION';
exports[1732] = 'ER_PARTITION_EXCHANGE_PART_TABLE';
exports[1733] = 'ER_PARTITION_EXCHANGE_TEMP_TABLE';
exports[1734] = 'ER_PARTITION_INSTEAD_OF_SUBPARTITION';
exports[1735] = 'ER_UNKNOWN_PARTITION';
exports[1736] = 'ER_TABLES_DIFFERENT_METADATA';
exports[1737] = 'ER_ROW_DOES_NOT_MATCH_PARTITION';
exports[1738] = 'ER_BINLOG_CACHE_SIZE_GREATER_THAN_MAX';
exports[1739] = 'ER_WARN_INDEX_NOT_APPLICABLE';
exports[1740] = 'ER_PARTITION_EXCHANGE_FOREIGN_KEY';
exports[1741] = 'ER_NO_SUCH_KEY_VALUE';
exports[1742] = 'ER_RPL_INFO_DATA_TOO_LONG';
exports[1743] = 'ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE';
exports[1744] = 'ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE';
exports[1745] = 'ER_BINLOG_STMT_CACHE_SIZE_GREATER_THAN_MAX';
exports[1746] = 'ER_CANT_UPDATE_TABLE_IN_CREATE_TABLE_SELECT';
exports[1747] = 'ER_PARTITION_CLAUSE_ON_NONPARTITIONED';
exports[1748] = 'ER_ROW_DOES_NOT_MATCH_GIVEN_PARTITION_SET';
exports[1749] = 'ER_NO_SUCH_PARTITION';
exports[1750] = 'ER_CHANGE_RPL_INFO_REPOSITORY_FAILURE';
exports[1751] = 'ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_CREATED_TEMP_TABLE';
exports[1752] = 'ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_DROPPED_TEMP_TABLE';
exports[1753] = 'ER_MTS_FEATURE_IS_NOT_SUPPORTED';
exports[1754] = 'ER_MTS_UPDATED_DBS_GREATER_MAX';
exports[1755] = 'ER_MTS_CANT_PARALLEL';
exports[1756] = 'ER_MTS_INCONSISTENT_DATA';
exports[1757] = 'ER_FULLTEXT_NOT_SUPPORTED_WITH_PARTITIONING';
exports[1758] = 'ER_DA_INVALID_CONDITION_NUMBER';
exports[1759] = 'ER_INSECURE_PLAIN_TEXT';
exports[1760] = 'ER_INSECURE_CHANGE_MASTER';
exports[1761] = 'ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO';
exports[1762] = 'ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO';
exports[1763] = 'ER_SQLTHREAD_WITH_SECURE_SLAVE';
exports[1764] = 'ER_TABLE_HAS_NO_FT';
exports[1765] = 'ER_VARIABLE_NOT_SETTABLE_IN_SF_OR_TRIGGER';
exports[1766] = 'ER_VARIABLE_NOT_SETTABLE_IN_TRANSACTION';
exports[1767] = 'ER_GTID_NEXT_IS_NOT_IN_GTID_NEXT_LIST';
exports[1768] = 'ER_CANT_CHANGE_GTID_NEXT_IN_TRANSACTION_WHEN_GTID_NEXT_LIST_IS_NULL';
exports[1769] = 'ER_SET_STATEMENT_CANNOT_INVOKE_FUNCTION';
exports[1770] = 'ER_GTID_NEXT_CANT_BE_AUTOMATIC_IF_GTID_NEXT_LIST_IS_NON_NULL';
exports[1771] = 'ER_SKIPPING_LOGGED_TRANSACTION';
exports[1772] = 'ER_MALFORMED_GTID_SET_SPECIFICATION';
exports[1773] = 'ER_MALFORMED_GTID_SET_ENCODING';
exports[1774] = 'ER_MALFORMED_GTID_SPECIFICATION';
exports[1775] = 'ER_GNO_EXHAUSTED';
exports[1776] = 'ER_BAD_SLAVE_AUTO_POSITION';
exports[1777] = 'ER_AUTO_POSITION_REQUIRES_GTID_MODE_ON';
exports[1778] = 'ER_CANT_DO_IMPLICIT_COMMIT_IN_TRX_WHEN_GTID_NEXT_IS_SET';
exports[1779] = 'ER_GTID_MODE_';
exports[1780] = 'ER_GTID_MODE_REQUIRES_BINLOG';
exports[1781] = 'ER_CANT_SET_GTID_NEXT_TO_GTID_WHEN_GTID_MODE_IS_OFF';
exports[1782] = 'ER_CANT_SET_GTID_NEXT_TO_ANONYMOUS_WHEN_GTID_MODE_IS_ON';
exports[1783] = 'ER_CANT_SET_GTID_NEXT_LIST_TO_NON_NULL_WHEN_GTID_MODE_IS_OFF';
exports[1784] = 'ER_FOUND_GTID_EVENT_WHEN_GTID_MODE_IS_OFF';
exports[1785] = 'ER_GTID_UNSAFE_NON_TRANSACTIONAL_TABLE';
exports[1786] = 'ER_GTID_UNSAFE_CREATE_SELECT';
exports[1787] = 'ER_GTID_UNSAFE_CREATE_DROP_TEMPORARY_TABLE_IN_TRANSACTION';
exports[1788] = 'ER_GTID_MODE_CAN_ONLY_CHANGE_ONE_STEP_AT_A_TIME';
exports[1789] = 'ER_MASTER_HAS_PURGED_REQUIRED_GTIDS';
exports[1790] = 'ER_CANT_SET_GTID_NEXT_WHEN_OWNING_GTID';
exports[1791] = 'ER_UNKNOWN_EXPLAIN_FORMAT';
exports[1792] = 'ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION';
exports[1793] = 'ER_TOO_LONG_TABLE_PARTITION_COMMENT';
exports[1794] = 'ER_SLAVE_CONFIGURATION';
exports[1795] = 'ER_INNODB_FT_LIMIT';
exports[1796] = 'ER_INNODB_NO_FT_TEMP_TABLE';
exports[1797] = 'ER_INNODB_FT_WRONG_DOCID_COLUMN';
exports[1798] = 'ER_INNODB_FT_WRONG_DOCID_INDEX';
exports[1799] = 'ER_INNODB_ONLINE_LOG_TOO_BIG';
exports[1800] = 'ER_UNKNOWN_ALTER_ALGORITHM';
exports[1801] = 'ER_UNKNOWN_ALTER_LOCK';
exports[1802] = 'ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS';
exports[1803] = 'ER_MTS_RECOVERY_FAILURE';
exports[1804] = 'ER_MTS_RESET_WORKERS';
exports[1805] = 'ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V';
exports[1806] = 'ER_SLAVE_SILENT_RETRY_TRANSACTION';
exports[1807] = 'ER_DISCARD_FK_CHECKS_RUNNING';
exports[1808] = 'ER_TABLE_SCHEMA_MISMATCH';
exports[1809] = 'ER_TABLE_IN_SYSTEM_TABLESPACE';
exports[1810] = 'ER_IO_READ_ERROR';
exports[1811] = 'ER_IO_WRITE_ERROR';
exports[1812] = 'ER_TABLESPACE_MISSING';
exports[1813] = 'ER_TABLESPACE_EXISTS';
exports[1814] = 'ER_TABLESPACE_DISCARDED';
exports[1815] = 'ER_INTERNAL_ERROR';
exports[1816] = 'ER_INNODB_IMPORT_ERROR';
exports[1817] = 'ER_INNODB_INDEX_CORRUPT';
exports[1818] = 'ER_INVALID_YEAR_COLUMN_LENGTH';
exports[1819] = 'ER_NOT_VALID_PASSWORD';
exports[1820] = 'ER_MUST_CHANGE_PASSWORD';
exports[1821] = 'ER_FK_NO_INDEX_CHILD';
exports[1822] = 'ER_FK_NO_INDEX_PARENT';
exports[1823] = 'ER_FK_FAIL_ADD_SYSTEM';
exports[1824] = 'ER_FK_CANNOT_OPEN_PARENT';
exports[1825] = 'ER_FK_INCORRECT_OPTION';
exports[1826] = 'ER_FK_DUP_NAME';
exports[1827] = 'ER_PASSWORD_FORMAT';
exports[1828] = 'ER_FK_COLUMN_CANNOT_DROP';
exports[1829] = 'ER_FK_COLUMN_CANNOT_DROP_CHILD';
exports[1830] = 'ER_FK_COLUMN_NOT_NULL';
exports[1831] = 'ER_DUP_INDEX';
exports[1832] = 'ER_FK_COLUMN_CANNOT_CHANGE';
exports[1833] = 'ER_FK_COLUMN_CANNOT_CHANGE_CHILD';
exports[1834] = 'ER_FK_CANNOT_DELETE_PARENT';
exports[1835] = 'ER_MALFORMED_PACKET';
exports[1836] = 'ER_READ_ONLY_MODE';
exports[1837] = 'ER_GTID_NEXT_TYPE_UNDEFINED_GROUP';
exports[1838] = 'ER_VARIABLE_NOT_SETTABLE_IN_SP';
exports[1839] = 'ER_CANT_SET_GTID_PURGED_WHEN_GTID_MODE_IS_OFF';
exports[1840] = 'ER_CANT_SET_GTID_PURGED_WHEN_GTID_EXECUTED_IS_NOT_EMPTY';
exports[1841] = 'ER_CANT_SET_GTID_PURGED_WHEN_OWNED_GTIDS_IS_NOT_EMPTY';
exports[1842] = 'ER_GTID_PURGED_WAS_CHANGED';
exports[1843] = 'ER_GTID_EXECUTED_WAS_CHANGED';
exports[1844] = 'ER_BINLOG_STMT_MODE_AND_NO_REPL_TABLES';
exports[1845] = 'ER_ALTER_OPERATION_NOT_SUPPORTED';
exports[1846] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON';
exports[1847] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COPY';
exports[1848] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_PARTITION';
exports[1849] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_RENAME';
exports[1850] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COLUMN_TYPE';
exports[1851] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_CHECK';
exports[1852] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_IGNORE';
exports[1853] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOPK';
exports[1854] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_AUTOINC';
exports[1855] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_HIDDEN_FTS';
exports[1856] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_CHANGE_FTS';
exports[1857] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FTS';
exports[1858] = 'ER_SQL_SLAVE_SKIP_COUNTER_NOT_SETTABLE_IN_GTID_MODE';
exports[1859] = 'ER_DUP_UNKNOWN_IN_INDEX';
exports[1860] = 'ER_IDENT_CAUSES_TOO_LONG_PATH';
exports[1861] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL';
exports[1862] = 'ER_MUST_CHANGE_PASSWORD_LOGIN';
exports[1863] = 'ER_ROW_IN_WRONG_PARTITION';
exports[1864] = 'ER_MTS_EVENT_BIGGER_PENDING_JOBS_SIZE_MAX';
exports[1865] = 'ER_INNODB_NO_FT_USES_PARSER';
exports[1866] = 'ER_BINLOG_LOGICAL_CORRUPTION';
exports[1867] = 'ER_WARN_PURGE_LOG_IN_USE';
exports[1868] = 'ER_WARN_PURGE_LOG_IS_ACTIVE';
exports[1869] = 'ER_AUTO_INCREMENT_CONFLICT';
exports[1870] = 'WARN_ON_BLOCKHOLE_IN_RBR';
exports[1871] = 'ER_SLAVE_MI_INIT_REPOSITORY';
exports[1872] = 'ER_SLAVE_RLI_INIT_REPOSITORY';
exports[1873] = 'ER_ACCESS_DENIED_CHANGE_USER_ERROR';
exports[1874] = 'ER_INNODB_READ_ONLY';
exports[1875] = 'ER_STOP_SLAVE_SQL_THREAD_TIMEOUT';
exports[1876] = 'ER_STOP_SLAVE_IO_THREAD_TIMEOUT';
exports[1877] = 'ER_TABLE_CORRUPT';
exports[1878] = 'ER_TEMP_FILE_WRITE_FAILURE';
exports[1879] = 'ER_INNODB_FT_AUX_NOT_HEX_ID';
exports[1880] = 'ER_OLD_TEMPORALS_UPGRADED';
exports[1881] = 'ER_INNODB_FORCED_RECOVERY';
exports[1882] = 'ER_AES_INVALID_IV';
// Manually extracted from mysql-5.5.23/include/mysql_com.h
exports.NOT_NULL_FLAG = 1; /* Field can't be NULL */
exports.PRI_KEY_FLAG = 2; /* Field is part of a primary key */
exports.UNIQUE_KEY_FLAG = 4; /* Field is part of a unique key */
exports.MULTIPLE_KEY_FLAG = 8; /* Field is part of a key */
exports.BLOB_FLAG = 16; /* Field is a blob */
exports.UNSIGNED_FLAG = 32; /* Field is unsigned */
exports.ZEROFILL_FLAG = 64; /* Field is zerofill */
exports.BINARY_FLAG = 128; /* Field is binary */
/* The following are only sent to new clients */
exports.ENUM_FLAG = 256; /* field is an enum */
exports.AUTO_INCREMENT_FLAG = 512; /* field is a autoincrement field */
exports.TIMESTAMP_FLAG = 1024; /* Field is a timestamp */
exports.SET_FLAG = 2048; /* field is a set */
exports.NO_DEFAULT_VALUE_FLAG = 4096; /* Field doesn't have default value */
exports.ON_UPDATE_NOW_FLAG = 8192; /* Field is set to NOW on UPDATE */
exports.NUM_FLAG = 32768; /* Field is num (for clients) */
// Manually extracted from mysql-5.5.23/include/mysql_com.h
/**
Is raised when a multi-statement transaction
has been started, either explicitly, by means
of BEGIN or COMMIT AND CHAIN, or
implicitly, by the first transactional
statement, when autocommit=off.
*/
exports.SERVER_STATUS_IN_TRANS = 1;
exports.SERVER_STATUS_AUTOCOMMIT = 2; /* Server in auto_commit mode */
exports.SERVER_MORE_RESULTS_EXISTS = 8; /* Multi query - next query exists */
exports.SERVER_QUERY_NO_GOOD_INDEX_USED = 16;
exports.SERVER_QUERY_NO_INDEX_USED = 32;
/**
The server was able to fulfill the clients request and opened a
read-only non-scrollable cursor for a query. This flag comes
in reply to COM_STMT_EXECUTE and COM_STMT_FETCH commands.
*/
exports.SERVER_STATUS_CURSOR_EXISTS = 64;
/**
This flag is sent when a read-only cursor is exhausted, in reply to
COM_STMT_FETCH command.
*/
exports.SERVER_STATUS_LAST_ROW_SENT = 128;
exports.SERVER_STATUS_DB_DROPPED = 256; /* A database was dropped */
exports.SERVER_STATUS_NO_BACKSLASH_ESCAPES = 512;
/**
Sent to the client if after a prepared statement reprepare
we discovered that the new statement returns a different
number of result set columns.
*/
exports.SERVER_STATUS_METADATA_CHANGED = 1024;
exports.SERVER_QUERY_WAS_SLOW = 2048;
/**
To mark ResultSet containing output parameter values.
*/
exports.SERVER_PS_OUT_PARAMS = 4096;
// Manually extracted from mysql-5.5.23/include/mysql_com.h
// some more info here: http://dev.mysql.com/doc/refman/5.5/en/c-api-prepared-statement-type-codes.html
exports.DECIMAL = 0x00; // aka DECIMAL (http://dev.mysql.com/doc/refman/5.0/en/precision-math-decimal-changes.html)
exports.TINY = 0x01; // aka TINYINT, 1 byte
exports.SHORT = 0x02; // aka SMALLINT, 2 bytes
exports.LONG = 0x03; // aka INT, 4 bytes
exports.FLOAT = 0x04; // aka FLOAT, 4-8 bytes
exports.DOUBLE = 0x05; // aka DOUBLE, 8 bytes
exports.NULL = 0x06; // NULL (used for prepared statements, I think)
exports.TIMESTAMP = 0x07; // aka TIMESTAMP
exports.LONGLONG = 0x08; // aka BIGINT, 8 bytes
exports.INT24 = 0x09; // aka MEDIUMINT, 3 bytes
exports.DATE = 0x0a; // aka DATE
exports.TIME = 0x0b; // aka TIME
exports.DATETIME = 0x0c; // aka DATETIME
exports.YEAR = 0x0d; // aka YEAR, 1 byte (don't ask)
exports.NEWDATE = 0x0e; // aka ?
exports.VARCHAR = 0x0f; // aka VARCHAR (?)
exports.BIT = 0x10; // aka BIT, 1-8 byte
exports.NEWDECIMAL = 0xf6; // aka DECIMAL
exports.ENUM = 0xf7; // aka ENUM
exports.SET = 0xf8; // aka SET
exports.TINY_BLOB = 0xf9; // aka TINYBLOB, TINYTEXT
exports.MEDIUM_BLOB = 0xfa; // aka MEDIUMBLOB, MEDIUMTEXT
exports.LONG_BLOB = 0xfb; // aka LONGBLOG, LONGTEXT
exports.BLOB = 0xfc; // aka BLOB, TEXT
exports.VAR_STRING = 0xfd; // aka VARCHAR, VARBINARY
exports.STRING = 0xfe; // aka CHAR, BINARY
exports.GEOMETRY = 0xff; // aka GEOMETRY
module.exports = PacketHeader;
function PacketHeader(length, number) {
this.length = length;
this.number = number;
}
module.exports = ClientAuthenticationPacket;
function ClientAuthenticationPacket(options) {
options = options || {};
this.clientFlags = options.clientFlags;
this.maxPacketSize = options.maxPacketSize;
this.charsetNumber = options.charsetNumber;
this.filler = undefined;
this.user = options.user;
this.scrambleBuff = options.scrambleBuff;
this.database = options.database;
this.protocol41 = options.protocol41;
}
ClientAuthenticationPacket.prototype.parse = function(parser) {
if (this.protocol41) {
this.clientFlags = parser.parseUnsignedNumber(4);
this.maxPacketSize = parser.parseUnsignedNumber(4);
this.charsetNumber = parser.parseUnsignedNumber(1);
this.filler = parser.parseFiller(23);
this.user = parser.parseNullTerminatedString();
this.scrambleBuff = parser.parseLengthCodedBuffer();
this.database = parser.parseNullTerminatedString();
} else {
this.clientFlags = parser.parseUnsignedNumber(2);
this.maxPacketSize = parser.parseUnsignedNumber(3);
this.user = parser.parseNullTerminatedString();
this.scrambleBuff = parser.parseBuffer(8);
this.database = parser.parseLengthCodedBuffer();
}
};
ClientAuthenticationPacket.prototype.write = function(writer) {
if (this.protocol41) {
writer.writeUnsignedNumber(4, this.clientFlags);
writer.writeUnsignedNumber(4, this.maxPacketSize);
writer.writeUnsignedNumber(1, this.charsetNumber);
writer.writeFiller(23);
writer.writeNullTerminatedString(this.user);
writer.writeLengthCodedBuffer(this.scrambleBuff);
writer.writeNullTerminatedString(this.database);
} else {
writer.writeUnsignedNumber(2, this.clientFlags);
writer.writeUnsignedNumber(3, this.maxPacketSize);
writer.writeNullTerminatedString(this.user);
writer.writeBuffer(this.scrambleBuff);
if (this.database && this.database.length) {
writer.writeFiller(1);
writer.writeBuffer(new Buffer(this.database));
}
}
};
module.exports = ComChangeUserPacket;
function ComChangeUserPacket(options) {
options = options || {};
this.command = 0x11;
this.user = options.user;
this.scrambleBuff = options.scrambleBuff;
this.database = options.database;
this.charsetNumber = options.charsetNumber;
}
ComChangeUserPacket.prototype.parse = function(parser) {
this.command = parser.parseUnsignedNumber(1);
this.user = parser.parseNullTerminatedString();
this.scrambleBuff = parser.parseLengthCodedBuffer();
this.database = parser.parseNullTerminatedString();
this.charsetNumber = parser.parseUnsignedNumber(1);
};
ComChangeUserPacket.prototype.write = function(writer) {
writer.writeUnsignedNumber(1, this.command);
writer.writeNullTerminatedString(this.user);
writer.writeLengthCodedBuffer(this.scrambleBuff);
writer.writeNullTerminatedString(this.database);
writer.writeUnsignedNumber(2, this.charsetNumber);
};
module.exports = ComPingPacket;
function ComPingPacket(sql) {
this.command = 0x0e;
}
ComPingPacket.prototype.write = function(writer) {
writer.writeUnsignedNumber(1, this.command);
};
ComPingPacket.prototype.parse = function(parser) {
this.command = parser.parseUnsignedNumber(1);
};
module.exports = ComQueryPacket;
function ComQueryPacket(sql) {
this.command = 0x03;
this.sql = sql;
}
ComQueryPacket.prototype.write = function(writer) {
writer.writeUnsignedNumber(1, this.command);
writer.writeString(this.sql);
};
ComQueryPacket.prototype.parse = function(parser) {
this.command = parser.parseUnsignedNumber(1);
this.sql = parser.parsePacketTerminatedString();
};
module.exports = ComQuitPacket;
function ComQuitPacket(sql) {
this.command = 0x01;
}
ComQuitPacket.prototype.parse = function parse(parser) {
this.command = parser.parseUnsignedNumber(1);
};
ComQuitPacket.prototype.write = function write(writer) {
writer.writeUnsignedNumber(1, this.command);
};
module.exports = ComStatisticsPacket;
function ComStatisticsPacket(sql) {
this.command = 0x09;
}
ComStatisticsPacket.prototype.write = function(writer) {
writer.writeUnsignedNumber(1, this.command);
};
ComStatisticsPacket.prototype.parse = function(parser) {
this.command = parser.parseUnsignedNumber(1);
};
module.exports = EmptyPacket;
function EmptyPacket() {
}
EmptyPacket.prototype.write = function(writer) {
};
module.exports = EofPacket;
function EofPacket(options) {
options = options || {};
this.fieldCount = undefined;
this.warningCount = options.warningCount;
this.serverStatus = options.serverStatus;
this.protocol41 = options.protocol41;
}
EofPacket.prototype.parse = function(parser) {
this.fieldCount = parser.parseUnsignedNumber(1);
if (this.protocol41) {
this.warningCount = parser.parseUnsignedNumber(2);
this.serverStatus = parser.parseUnsignedNumber(2);
}
};
EofPacket.prototype.write = function(writer) {
writer.writeUnsignedNumber(1, 0xfe);
if (this.protocol41) {
writer.writeUnsignedNumber(2, this.warningCount);
writer.writeUnsignedNumber(2, this.serverStatus);
}
};
module.exports = ErrorPacket;
function ErrorPacket(options) {
options = options || {};
this.fieldCount = options.fieldCount;
this.errno = options.errno;
this.sqlStateMarker = options.sqlStateMarker;
this.sqlState = options.sqlState;
this.message = options.message;
}
ErrorPacket.prototype.parse = function(parser) {
this.fieldCount = parser.parseUnsignedNumber(1);
this.errno = parser.parseUnsignedNumber(2);
// sqlStateMarker ('#' = 0x23) indicates error packet format
if (parser.peak() === 0x23) {
this.sqlStateMarker = parser.parseString(1);
this.sqlState = parser.parseString(5);
}
this.message = parser.parsePacketTerminatedString();
};
ErrorPacket.prototype.write = function(writer) {
writer.writeUnsignedNumber(1, 0xff);
writer.writeUnsignedNumber(2, this.errno);
if (this.sqlStateMarker) {
writer.writeString(this.sqlStateMarker);
writer.writeString(this.sqlState);
}
writer.writeString(this.message);
};
var Types = require('../constants/types');
module.exports = Field;
function Field(options) {
options = options || {};
this.parser = options.parser;
this.packet = options.packet;
this.db = options.packet.db;
this.table = options.packet.table;
this.name = options.packet.name;
this.type = typeToString(options.packet.type);
this.length = options.packet.length;
}
Field.prototype.string = function () {
return this.parser.parseLengthCodedString();
};
Field.prototype.buffer = function () {
return this.parser.parseLengthCodedBuffer();
};
Field.prototype.geometry = function () {
return this.parser.parseGeometryValue();
};
function typeToString(t) {
for (var k in Types) {
if (Types[k] == t) return k;
}
}
module.exports = FieldPacket;
function FieldPacket(options) {
options = options || {};
this.catalog = options.catalog;
this.db = options.db;
this.table = options.table;
this.orgTable = options.orgTable;
this.name = options.name;
this.orgName = options.orgName;
this.filler1 = undefined;
this.charsetNr = options.charsetNr;
this.length = options.length;
this.type = options.type;
this.flags = options.flags;
this.decimals = options.decimals;
this.filler2 = undefined;
this.default = options.default;
this.zeroFill = options.zeroFill;
this.protocol41 = options.protocol41
}
FieldPacket.prototype.parse = function(parser) {
if (this.protocol41) {
this.catalog = parser.parseLengthCodedString();
this.db = parser.parseLengthCodedString();
this.table = parser.parseLengthCodedString();
this.orgTable = parser.parseLengthCodedString();
this.name = parser.parseLengthCodedString();
this.orgName = parser.parseLengthCodedString();
this.filler1 = parser.parseFiller(1);
this.charsetNr = parser.parseUnsignedNumber(2);
this.length = parser.parseUnsignedNumber(4);
this.type = parser.parseUnsignedNumber(1);
this.flags = parser.parseUnsignedNumber(2);
this.decimals = parser.parseUnsignedNumber(1);
this.filler2 = parser.parseFiller(2);
// parsed flags
this.zeroFill = (this.flags & 0x0040 ? true : false);
if (parser.reachedPacketEnd()) {
return;
}
this.default = parser.parseLengthCodedNumber();
} else {
this.table = parser.parseLengthCodedString();
this.name = parser.parseLengthCodedString();
this.length = parser.parseUnsignedNumber(parser.parseUnsignedNumber(1));
this.type = parser.parseUnsignedNumber(parser.parseUnsignedNumber(1));
}
};
FieldPacket.prototype.write = function(writer) {
if (this.protocol41) {
writer.writeLengthCodedString(this.catalog);
writer.writeLengthCodedString(this.db);
writer.writeLengthCodedString(this.table);
writer.writeLengthCodedString(this.orgTable);
writer.writeLengthCodedString(this.name);
writer.writeLengthCodedString(this.orgName);
writer.writeFiller(1);
writer.writeUnsignedNumber(2, this.charsetNr || 0);
writer.writeUnsignedNumber(4, this.length || 0);
writer.writeUnsignedNumber(1, this.type || 0);
writer.writeUnsignedNumber(2, this.flags || 0);
writer.writeUnsignedNumber(1, this.decimals || 0);
writer.writeFiller(2);
if (this.default !== undefined) {
writer.writeLengthCodedString(this.default);
}
} else {
writer.writeLengthCodedString(this.table);
writer.writeLengthCodedString(this.name);
writer.writeUnsignedNumber(1, 0x01);
writer.writeUnsignedNumber(1, this.length);
writer.writeUnsignedNumber(1, 0x01);
writer.writeUnsignedNumber(1, this.type);
}
};
var Client = require('../constants/client');
module.exports = HandshakeInitializationPacket;
function HandshakeInitializationPacket(options) {
options = options || {};
this.protocolVersion = options.protocolVersion;
this.serverVersion = options.serverVersion;
this.threadId = options.threadId;
this.scrambleBuff1 = options.scrambleBuff1;
this.filler1 = options.filler1;
this.serverCapabilities1 = options.serverCapabilities1;
this.serverLanguage = options.serverLanguage;
this.serverStatus = options.serverStatus;
this.serverCapabilities2 = options.serverCapabilities2;
this.scrambleLength = options.scrambleLength;
this.filler2 = options.filler2;
this.scrambleBuff2 = options.scrambleBuff2;
this.filler3 = options.filler3;
this.pluginData = options.pluginData;
this.protocol41 = options.protocol41;
if (this.protocol41) {
// force set the bit in serverCapabilities1
this.serverCapabilities1 |= Client.CLIENT_PROTOCOL_41;
}
}
HandshakeInitializationPacket.prototype.parse = function(parser) {
this.protocolVersion = parser.parseUnsignedNumber(1);
this.serverVersion = parser.parseNullTerminatedString();
this.threadId = parser.parseUnsignedNumber(4);
this.scrambleBuff1 = parser.parseBuffer(8);
this.filler1 = parser.parseFiller(1);
this.serverCapabilities1 = parser.parseUnsignedNumber(2);
this.serverLanguage = parser.parseUnsignedNumber(1);
this.serverStatus = parser.parseUnsignedNumber(2);
this.protocol41 = (this.serverCapabilities1 & (1 << 9)) > 0;
if (this.protocol41) {
this.serverCapabilities2 = parser.parseUnsignedNumber(2);
this.scrambleLength = parser.parseUnsignedNumber(1);
this.filler2 = parser.parseFiller(10);
// scrambleBuff2 should be 0x00 terminated, but sphinx does not do this
// so we assume scrambleBuff2 to be 12 byte and treat the next byte as a
// filler byte.
this.scrambleBuff2 = parser.parseBuffer(12);
this.filler3 = parser.parseFiller(1);
} else {
this.filler2 = parser.parseFiller(13);
}
if (parser.reachedPacketEnd()) {
return;
}
// According to the docs this should be 0x00 terminated, but MariaDB does
// not do this, so we assume this string to be packet terminated.
this.pluginData = parser.parsePacketTerminatedString();
// However, if there is a trailing '\0', strip it
var lastChar = this.pluginData.length - 1;
if (this.pluginData[lastChar] === '\0') {
this.pluginData = this.pluginData.substr(0, lastChar);
}
};
HandshakeInitializationPacket.prototype.write = function(writer) {
writer.writeUnsignedNumber(1, this.protocolVersion);
writer.writeNullTerminatedString(this.serverVersion);
writer.writeUnsignedNumber(4, this.threadId);
writer.writeBuffer(this.scrambleBuff1);
writer.writeFiller(1);
writer.writeUnsignedNumber(2, this.serverCapabilities1);
writer.writeUnsignedNumber(1, this.serverLanguage);
writer.writeUnsignedNumber(2, this.serverStatus);
if (this.protocol41) {
writer.writeUnsignedNumber(2, this.serverCapabilities2);
writer.writeUnsignedNumber(1, this.scrambleLength);
writer.writeFiller(10);
}
writer.writeNullTerminatedBuffer(this.scrambleBuff2);
if (this.pluginData !== undefined) {
writer.writeNullTerminatedString(this.pluginData);
}
};
HandshakeInitializationPacket.prototype.scrambleBuff = function() {
var buffer = new Buffer(this.scrambleBuff1.length +
(typeof this.scrambleBuff2 != "undefined" ? this.scrambleBuff2.length : 0));
this.scrambleBuff1.copy(buffer);
if (typeof this.scrambleBuff2 != "undefined") {
this.scrambleBuff2.copy(buffer, this.scrambleBuff1.length);
}
return buffer;
};
var Elements = module.exports = require('require-all')({
dirname : __dirname,
filter : /([A-Z].+)\.js$/,
});
module.exports = LocalDataFilePacket;
/**
* @param {Buffer} data
*/
function LocalDataFilePacket(data) {
this.data = data;
}
LocalDataFilePacket.prototype.write = function(writer) {
writer.writeBuffer(this.data);
};
module.exports = OkPacket;
function OkPacket(options) {
options = options || {};
this.fieldCount = undefined;
this.affectedRows = undefined;
this.insertId = undefined;
this.serverStatus = undefined;
this.warningCount = undefined;
this.message = undefined;
this.protocol41 = options.protocol41;
}
OkPacket.prototype.parse = function(parser) {
this.fieldCount = parser.parseUnsignedNumber(1);
this.affectedRows = parser.parseLengthCodedNumber();
this.insertId = parser.parseLengthCodedNumber();
if (this.protocol41) {
this.serverStatus = parser.parseUnsignedNumber(2);
this.warningCount = parser.parseUnsignedNumber(2);
}
this.message = parser.parsePacketTerminatedString();
this.changedRows = 0;
var m = this.message.match(/\schanged:\s*(\d+)/i);
if (m !== null) {
this.changedRows = parseInt(m[1], 10);
}
};
OkPacket.prototype.write = function(writer) {
writer.writeUnsignedNumber(1, 0x00);
writer.writeLengthCodedNumber(this.affectedRows || 0);
writer.writeLengthCodedNumber(this.insertId || 0);
if (this.protocol41) {
writer.writeUnsignedNumber(2, this.serverStatus || 0);
writer.writeUnsignedNumber(2, this.warningCount || 0);
}
writer.writeString(this.message);
};
module.exports = OldPasswordPacket;
function OldPasswordPacket(options) {
options = options || {};
this.scrambleBuff = options.scrambleBuff;
}
OldPasswordPacket.prototype.parse = function(parser) {
this.scrambleBuff = parser.parseNullTerminatedBuffer();
};
OldPasswordPacket.prototype.write = function(writer) {
writer.writeBuffer(this.scrambleBuff);
writer.writeFiller(1);
};
module.exports = ResultSetHeaderPacket;
function ResultSetHeaderPacket(options) {
options = options || {};
this.fieldCount = options.fieldCount;
this.extra = options.extra;
}
ResultSetHeaderPacket.prototype.parse = function(parser) {
this.fieldCount = parser.parseLengthCodedNumber();
if (parser.reachedPacketEnd()) return;
this.extra = (this.fieldCount === null)
? parser.parsePacketTerminatedString()
: parser.parseLengthCodedNumber();
};
ResultSetHeaderPacket.prototype.write = function(writer) {
writer.writeLengthCodedNumber(this.fieldCount);
if (this.extra !== undefined) {
writer.writeLengthCodedNumber(this.extra);
}
};
var Types = require('../constants/types');
var Charsets = require('../constants/charsets');
var Field = require('./Field');
var IEEE_754_BINARY_64_PRECISION = Math.pow(2, 53);
module.exports = RowDataPacket;
function RowDataPacket() {
}
RowDataPacket.prototype.parse = function(parser, fieldPackets, typeCast, nestTables, connection) {
var self = this;
var next = function () {
return self._typeCast(fieldPacket, parser, connection.config.timezone, connection.config.supportBigNumbers, connection.config.bigNumberStrings, connection.config.dateStrings);
};
for (var i = 0; i < fieldPackets.length; i++) {
var fieldPacket = fieldPackets[i];
var value;
if (typeof typeCast == "function") {
value = typeCast.apply(connection, [ new Field({ packet: fieldPacket, parser: parser }), next ]);
} else {
value = (typeCast)
? this._typeCast(fieldPacket, parser, connection.config.timezone, connection.config.supportBigNumbers, connection.config.bigNumberStrings, connection.config.dateStrings)
: ( (fieldPacket.charsetNr === Charsets.BINARY)
? parser.parseLengthCodedBuffer()
: parser.parseLengthCodedString() );
}
if (typeof nestTables == "string" && nestTables.length) {
this[fieldPacket.table + nestTables + fieldPacket.name] = value;
} else if (nestTables) {
this[fieldPacket.table] = this[fieldPacket.table] || {};
this[fieldPacket.table][fieldPacket.name] = value;
} else {
this[fieldPacket.name] = value;
}
}
};
RowDataPacket.prototype._typeCast = function(field, parser, timeZone, supportBigNumbers, bigNumberStrings, dateStrings) {
var numberString;
switch (field.type) {
case Types.TIMESTAMP:
case Types.DATE:
case Types.DATETIME:
case Types.NEWDATE:
var dateString = parser.parseLengthCodedString();
if (dateStrings) {
return dateString;
}
var dt;
if (dateString === null) {
return null;
}
var originalString = dateString;
if (field.type === Types.DATE) {
dateString += ' 00:00:00';
}
if (timeZone !== 'local') {
dateString += ' ' + timeZone;
}
dt = new Date(dateString);
if (isNaN(dt.getTime())) {
return originalString;
}
return dt;
case Types.TINY:
case Types.SHORT:
case Types.LONG:
case Types.INT24:
case Types.YEAR:
case Types.FLOAT:
case Types.DOUBLE:
numberString = parser.parseLengthCodedString();
return (numberString === null || (field.zeroFill && numberString[0] == "0"))
? numberString : Number(numberString);
case Types.NEWDECIMAL:
case Types.LONGLONG:
numberString = parser.parseLengthCodedString();
return (numberString === null || (field.zeroFill && numberString[0] == "0"))
? numberString
: ((supportBigNumbers && (bigNumberStrings || (Number(numberString) > IEEE_754_BINARY_64_PRECISION)))
? numberString
: Number(numberString));
case Types.BIT:
return parser.parseLengthCodedBuffer();
case Types.STRING:
case Types.VAR_STRING:
case Types.TINY_BLOB:
case Types.MEDIUM_BLOB:
case Types.LONG_BLOB:
case Types.BLOB:
return (field.charsetNr === Charsets.BINARY)
? parser.parseLengthCodedBuffer()
: parser.parseLengthCodedString();
case Types.GEOMETRY:
return parser.parseGeometryValue();
default:
return parser.parseLengthCodedString();
}
};
// http://dev.mysql.com/doc/internals/en/ssl.html
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::SSLRequest
var ClientConstants = require('../constants/client');
module.exports = SSLRequestPacket;
function SSLRequestPacket(options) {
options = options || {};
this.clientFlags = options.clientFlags | ClientConstants.CLIENT_SSL;
this.maxPacketSize = options.maxPacketSize;
this.charsetNumber = options.charsetNumber;
}
SSLRequestPacket.prototype.parse = function(parser) {
// TODO: check SSLRequest packet v41 vs pre v41
this.clientFlags = parser.parseUnsignedNumber(4);
this.maxPacketSize = parser.parseUnsignedNumber(4);
this.charsetNumber = parser.parseUnsignedNumber(1);
};
SSLRequestPacket.prototype.write = function(writer) {
writer.writeUnsignedNumber(4, this.clientFlags);
writer.writeUnsignedNumber(4, this.maxPacketSize);
writer.writeUnsignedNumber(1, this.charsetNumber);
writer.writeFiller(23);
};
module.exports = StatisticsPacket;
function StatisticsPacket() {
this.message = undefined;
}
StatisticsPacket.prototype.parse = function(parser) {
this.message = parser.parsePacketTerminatedString();
var items = this.message.split(/\s\s/);
for (var i = 0; i < items.length; i++) {
var m = items[i].match(/^(.+)\:\s+(.+)$/);
if (m !== null) {
this[m[1].toLowerCase().replace(/\s/g, '_')] = Number(m[2]);
}
}
};
StatisticsPacket.prototype.write = function(writer) {
writer.writeString(this.message);
};
module.exports = UseOldPasswordPacket;
function UseOldPasswordPacket(options) {
options = options || {};
this.firstByte = options.firstByte || 0xfe;
}
UseOldPasswordPacket.prototype.parse = function(parser) {
this.firstByte = parser.parseUnsignedNumber(1);
};
UseOldPasswordPacket.prototype.write = function(writer) {
writer.writeUnsignedNumber(1, this.firstByte);
};
var BIT_16 = Math.pow(2, 16);
var BIT_24 = Math.pow(2, 24);
// The maximum precision JS Numbers can hold precisely
// Don't panic: Good enough to represent byte values up to 8192 TB
var IEEE_754_BINARY_64_PRECISION = Math.pow(2, 53);
var MAX_PACKET_LENGTH = Math.pow(2, 24) - 1;
module.exports = PacketWriter;
function PacketWriter() {
this._buffer = new Buffer(0);
this._offset = 0;
}
PacketWriter.prototype.toBuffer = function(parser) {
var packets = Math.floor(this._buffer.length / MAX_PACKET_LENGTH) + 1;
var buffer = this._buffer;
this._buffer = new Buffer(this._buffer.length + packets * 4);
for (var packet = 0; packet < packets; packet++) {
this._offset = packet * (MAX_PACKET_LENGTH + 4);
var isLast = (packet + 1 === packets);
var packetLength = (isLast)
? buffer.length % MAX_PACKET_LENGTH
: MAX_PACKET_LENGTH;
var packetNumber = parser.incrementPacketNumber();
this.writeUnsignedNumber(3, packetLength);
this.writeUnsignedNumber(1, packetNumber);
var start = packet * MAX_PACKET_LENGTH;
var end = start + packetLength;
this.writeBuffer(buffer.slice(start, end));
}
return this._buffer;
};
PacketWriter.prototype.writeUnsignedNumber = function(bytes, value) {
this._allocate(bytes);
for (var i = 0; i < bytes; i++) {
this._buffer[this._offset++] = (value >> (i * 8)) & 0xff;
}
};
PacketWriter.prototype.writeFiller = function(bytes) {
this._allocate(bytes);
for (var i = 0; i < bytes; i++) {
this._buffer[this._offset++] = 0x00;
}
};
PacketWriter.prototype.writeNullTerminatedString = function(value, encoding) {
// Typecast undefined into '' and numbers into strings
value = value || '';
value = value + '';
var bytes = Buffer.byteLength(value, encoding || 'utf-8') + 1;
this._allocate(bytes);
this._buffer.write(value, this._offset, encoding);
this._buffer[this._offset + bytes - 1] = 0x00;
this._offset += bytes;
};
PacketWriter.prototype.writeString = function(value) {
// Typecast undefined into '' and numbers into strings
value = value || '';
value = value + '';
var bytes = Buffer.byteLength(value, 'utf-8');
this._allocate(bytes);
this._buffer.write(value, this._offset, 'utf-8');
this._offset += bytes;
};
PacketWriter.prototype.writeBuffer = function(value) {
var bytes = value.length;
this._allocate(bytes);
value.copy(this._buffer, this._offset);
this._offset += bytes;
};
PacketWriter.prototype.writeLengthCodedNumber = function(value) {
if (value === null) {
this._allocate(1);
this._buffer[this._offset++] = 251;
return;
}
if (value <= 250) {
this._allocate(1);
this._buffer[this._offset++] = value;
return;
}
if (value > IEEE_754_BINARY_64_PRECISION) {
throw new Error(
'writeLengthCodedNumber: JS precision range exceeded, your ' +
'number is > 53 bit: "' + value + '"'
);
}
if (value <= BIT_16) {
this._allocate(3)
this._buffer[this._offset++] = 252;
} else if (value <= BIT_24) {
this._allocate(4)
this._buffer[this._offset++] = 253;
} else {
this._allocate(9);
this._buffer[this._offset++] = 254;
}
// 16 Bit
this._buffer[this._offset++] = value & 0xff;
this._buffer[this._offset++] = (value >> 8) & 0xff;
if (value <= BIT_16) return;
// 24 Bit
this._buffer[this._offset++] = (value >> 16) & 0xff;
if (value <= BIT_24) return;
this._buffer[this._offset++] = (value >> 24) & 0xff;
// Hack: Get the most significant 32 bit (JS bitwise operators are 32 bit)
value = value.toString(2);
value = value.substr(0, value.length - 32);
value = parseInt(value, 2);
this._buffer[this._offset++] = value & 0xff;
this._buffer[this._offset++] = (value >> 8) & 0xff;
this._buffer[this._offset++] = (value >> 16) & 0xff;
// Set last byte to 0, as we can only support 53 bits in JS (see above)
this._buffer[this._offset++] = 0;
};
PacketWriter.prototype.writeLengthCodedBuffer = function(value) {
var bytes = value.length;
this.writeLengthCodedNumber(bytes);
this.writeBuffer(value);
};
PacketWriter.prototype.writeNullTerminatedBuffer = function(value) {
this.writeBuffer(value);
this.writeFiller(1); // 0x00 terminator
};
PacketWriter.prototype.writeLengthCodedString = function(value) {
if (value === null) {
this.writeLengthCodedNumber(null);
return;
}
value = (value === undefined)
? ''
: String(value);
var bytes = Buffer.byteLength(value, 'utf-8');
this.writeLengthCodedNumber(bytes);
if (!bytes) {
return;
}
this._allocate(bytes);
this._buffer.write(value, this._offset, 'utf-8');
this._offset += bytes;
};
PacketWriter.prototype._allocate = function(bytes) {
if (!this._buffer) {
this._buffer = new Buffer(bytes);
return;
}
var bytesRemaining = this._buffer.length - this._offset;
if (bytesRemaining >= bytes) {
return;
}
var oldBuffer = this._buffer;
this._buffer = new Buffer(oldBuffer.length + bytes);
oldBuffer.copy(this._buffer);
};
var MAX_PACKET_LENGTH = Math.pow(2, 24) - 1;
var MUL_32BIT = Math.pow(2, 32);
var PacketHeader = require('./PacketHeader');
var BigNumber = require('bignumber.js');
module.exports = Parser;
function Parser(options) {
options = options || {};
this._supportBigNumbers = options.config && options.config.supportBigNumbers;
this._buffer = new Buffer(0);
this._longPacketBuffers = [];
this._offset = 0;
this._packetEnd = null;
this._packetHeader = null;
this._onPacket = options.onPacket || function() {};
this._nextPacketNumber = 0;
this._encoding = 'utf-8';
this._paused = false;
}
Parser.prototype.write = function(buffer) {
this.append(buffer);
while (true) {
if (this._paused) {
return;
}
if (!this._packetHeader) {
if (this._bytesRemaining() < 4) {
break;
}
this._packetHeader = new PacketHeader(
this.parseUnsignedNumber(3),
this.parseUnsignedNumber(1)
);
this._trackAndVerifyPacketNumber(this._packetHeader.number);
}
if (this._bytesRemaining() < this._packetHeader.length) {
break;
}
this._packetEnd = this._offset + this._packetHeader.length;
if (this._packetHeader.length === MAX_PACKET_LENGTH) {
this._longPacketBuffers.push(this._buffer.slice(this._offset, this._packetEnd));
this._advanceToNextPacket();
continue;
}
this._combineLongPacketBuffers();
// Try...finally to ensure exception safety. Unfortunately this is costing
// us up to ~10% performance in some benchmarks.
var hadException = true;
try {
this._onPacket(this._packetHeader);
hadException = false;
} finally {
this._advanceToNextPacket();
// If we had an exception, the parser while loop will be broken out
// of after the finally block. So we need to make sure to re-enter it
// to continue parsing any bytes that may already have been received.
if (hadException) {
process.nextTick(this.write.bind(this));
}
}
}
};
Parser.prototype.append = function(newBuffer) {
// If resume() is called, we don't pass a buffer to write()
if (!newBuffer) {
return;
}
var oldBuffer = this._buffer;
var bytesRemaining = this._bytesRemaining();
var newLength = bytesRemaining + newBuffer.length;
var combinedBuffer = (this._offset > newLength)
? oldBuffer.slice(0, newLength)
: new Buffer(newLength);
oldBuffer.copy(combinedBuffer, 0, this._offset);
newBuffer.copy(combinedBuffer, bytesRemaining);
this._buffer = combinedBuffer;
this._offset = 0;
};
Parser.prototype.pause = function() {
this._paused = true;
};
Parser.prototype.resume = function() {
this._paused = false;
// nextTick() to avoid entering write() multiple times within the same stack
// which would cause problems as write manipulates the state of the object.
process.nextTick(this.write.bind(this));
};
Parser.prototype.peak = function() {
return this._buffer[this._offset];
};
Parser.prototype.parseUnsignedNumber = function(bytes) {
if (bytes === 1) {
return this._buffer[this._offset++];
}
var buffer = this._buffer;
var offset = this._offset + bytes - 1;
var value = 0;
if (bytes > 4) {
throw new Error('parseUnsignedNumber: Supports only up to 4 bytes');
}
while (offset >= this._offset) {
value = ((value << 8) | buffer[offset]) >>> 0;
offset--;
}
this._offset += bytes;
return value;
};
Parser.prototype.parseLengthCodedString = function() {
var length = this.parseLengthCodedNumber();
if (length === null) {
return null;
}
return this.parseString(length);
};
Parser.prototype.parseLengthCodedBuffer = function() {
var length = this.parseLengthCodedNumber();
if (length === null) {
return null;
}
return this.parseBuffer(length);
};
Parser.prototype.parseLengthCodedNumber = function() {
var bits = this._buffer[this._offset++];
if (bits <= 250) {
return bits;
}
switch (bits) {
case 251:
return null;
case 252:
return this.parseUnsignedNumber(2);
case 253:
return this.parseUnsignedNumber(3);
case 254:
break;
default:
throw new Error('parseLengthCodedNumber: Unexpected first byte: 0x' + bits.toString(16));
}
var low = this.parseUnsignedNumber(4);
var high = this.parseUnsignedNumber(4);
var value;
if (high >>> 21) {
value = (new BigNumber(low)).plus((new BigNumber(MUL_32BIT)).times(high)).toString();
if (this._supportBigNumbers) {
return value;
}
throw new Error(
'parseLengthCodedNumber: JS precision range exceeded, ' +
'number is >= 53 bit: "' + value + '"'
);
}
value = low + (MUL_32BIT * high);
return value;
};
Parser.prototype.parseFiller = function(length) {
return this.parseBuffer(length);
};
Parser.prototype.parseNullTerminatedBuffer = function() {
var end = this._nullByteOffset();
var value = this._buffer.slice(this._offset, end);
this._offset = end + 1;
return value;
};
Parser.prototype.parseNullTerminatedString = function() {
var end = this._nullByteOffset();
var value = this._buffer.toString(this._encoding, this._offset, end);
this._offset = end + 1;
return value;
};
Parser.prototype._nullByteOffset = function() {
var offset = this._offset;
while (this._buffer[offset] !== 0x00) {
offset++;
if (offset >= this._buffer.length) {
throw new Error('Offset of null terminated string not found.');
}
}
return offset;
};
Parser.prototype.parsePacketTerminatedString = function() {
var length = this._packetEnd - this._offset;
return this.parseString(length);
};
Parser.prototype.parseBuffer = function(length) {
var response = new Buffer(length);
this._buffer.copy(response, 0, this._offset, this._offset + length);
this._offset += length;
return response;
};
Parser.prototype.parseString = function(length) {
var offset = this._offset;
var end = offset + length;
var value = this._buffer.toString(this._encoding, offset, end);
this._offset = end;
return value;
};
Parser.prototype.parseGeometryValue = function() {
var buffer = this.parseLengthCodedBuffer();
var offset = 4;
if (buffer === null || !buffer.length) {
return null;
}
function parseGeometry() {
var result = null;
var byteOrder = buffer.readUInt8(offset); offset += 1;
var wkbType = byteOrder? buffer.readUInt32LE(offset) : buffer.readUInt32BE(offset); offset += 4;
switch(wkbType) {
case 1: // WKBPoint
var x = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8;
var y = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8;
result = {x: x, y: y};
break;
case 2: // WKBLineString
var numPoints = byteOrder? buffer.readUInt32LE(offset) : buffer.readUInt32BE(offset); offset += 4;
result = [];
for(var i=numPoints;i>0;i--) {
var x = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8;
var y = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8;
result.push({x: x, y: y});
}
break;
case 3: // WKBPolygon
var numRings = byteOrder? buffer.readUInt32LE(offset) : buffer.readUInt32BE(offset); offset += 4;
result = [];
for(var i=numRings;i>0;i--) {
var numPoints = byteOrder? buffer.readUInt32LE(offset) : buffer.readUInt32BE(offset); offset += 4;
var line = [];
for(var j=numPoints;j>0;j--) {
var x = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8;
var y = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8;
line.push({x: x, y: y});
}
result.push(line);
}
break;
case 4: // WKBMultiPoint
case 5: // WKBMultiLineString
case 6: // WKBMultiPolygon
case 7: // WKBGeometryCollection
var num = byteOrder? buffer.readUInt32LE(offset) : buffer.readUInt32BE(offset); offset += 4;
var result = [];
for(var i=num;i>0;i--) {
result.push(parseGeometry());
}
break;
}
return result;
}
return parseGeometry();
};
Parser.prototype.reachedPacketEnd = function() {
return this._offset === this._packetEnd;
};
Parser.prototype._bytesRemaining = function() {
return this._buffer.length - this._offset;
};
Parser.prototype._trackAndVerifyPacketNumber = function(number) {
if (number !== this._nextPacketNumber) {
var err = new Error(
'Packets out of order. Got: ' + number + ' ' +
'Expected: ' + this._nextPacketNumber
);
err.code = 'PROTOCOL_PACKETS_OUT_OF_ORDER';
throw err;
}
this.incrementPacketNumber();
};
Parser.prototype.incrementPacketNumber = function() {
var currentPacketNumber = this._nextPacketNumber;
this._nextPacketNumber = (this._nextPacketNumber + 1) % 256;
return currentPacketNumber;
};
Parser.prototype.resetPacketNumber = function() {
this._nextPacketNumber = 0;
};
Parser.prototype.packetLength = function() {
return this._longPacketBuffers.reduce(function(length, buffer) {
return length + buffer.length;
}, this._packetHeader.length);
};
Parser.prototype._combineLongPacketBuffers = function() {
if (!this._longPacketBuffers.length) {
return;
}
var trailingPacketBytes = this._buffer.length - this._packetEnd;
var length = this._longPacketBuffers.reduce(function(length, buffer) {
return length + buffer.length;
}, this._bytesRemaining());
var combinedBuffer = new Buffer(length);
var offset = this._longPacketBuffers.reduce(function(offset, buffer) {
buffer.copy(combinedBuffer, offset);
return offset + buffer.length;
}, 0);
this._buffer.copy(combinedBuffer, offset, this._offset);
this._buffer = combinedBuffer;
this._longPacketBuffers = [];
this._offset = 0;
this._packetEnd = this._buffer.length - trailingPacketBytes;
};
Parser.prototype._advanceToNextPacket = function() {
this._offset = this._packetEnd;
this._packetHeader = null;
this._packetEnd = null;
};
var Parser = require('./Parser');
var Sequences = require('./sequences');
var Packets = require('./packets');
var Stream = require('stream').Stream;
var Util = require('util');
var PacketWriter = require('./PacketWriter');
module.exports = Protocol;
Util.inherits(Protocol, Stream);
function Protocol(options) {
Stream.call(this);
options = options || {};
this.readable = true;
this.writable = true;
this._config = options.config || {};
this._connection = options.connection;
this._callback = null;
this._fatalError = null;
this._quitSequence = null;
this._handshakeSequence = null;
this._handshaked = false;
this._ended = false;
this._destroyed = false;
this._queue = [];
this._handshakeInitializationPacket = null;
this._parser = new Parser({
onPacket : this._parsePacket.bind(this),
config : this._config
});
}
Protocol.prototype.write = function(buffer) {
this._parser.write(buffer);
return true;
};
Protocol.prototype.handshake = function(cb) {
return this._handshakeSequence = this._enqueue(new Sequences.Handshake(this._config, cb));
};
Protocol.prototype.query = function(options, cb) {
return this._enqueue(new Sequences.Query(options, cb));
};
Protocol.prototype.changeUser = function(options, cb) {
return this._enqueue(new Sequences.ChangeUser(options, cb));
};
Protocol.prototype.ping = function(cb) {
return this._enqueue(new Sequences.Ping(cb));
};
Protocol.prototype.stats = function(cb) {
return this._enqueue(new Sequences.Statistics(cb));
};
Protocol.prototype.quit = function(cb) {
return this._quitSequence = this._enqueue(new Sequences.Quit(cb));
};
Protocol.prototype.end = function() {
if(this._ended) {
return;
}
this._ended = true;
var expected = (this._quitSequence && this._queue[0] === this._quitSequence);
if (expected) {
this._quitSequence.end();
this.emit('end');
return;
}
var err = new Error('Connection lost: The server closed the connection.');
err.fatal = true;
err.code = 'PROTOCOL_CONNECTION_LOST';
this._delegateError(err);
};
Protocol.prototype.pause = function() {
this._parser.pause();
// Since there is a file stream in query, we must transmit pause/resume event to current sequence.
var seq = this._queue[0];
if (seq && seq.emit) {
seq.emit('pause');
}
};
Protocol.prototype.resume = function() {
this._parser.resume();
// Since there is a file stream in query, we must transmit pause/resume event to current sequence.
var seq = this._queue[0];
if (seq && seq.emit) {
seq.emit('resume');
}
};
Protocol.prototype._enqueue = function(sequence) {
if (!this._validateEnqueue(sequence)) {
return sequence;
}
if (this._config.trace) {
// Long stack trace support
sequence._callSite = sequence._callSite || new Error;
}
this._queue.push(sequence);
var self = this;
sequence
.on('error', function(err) {
self._delegateError(err, sequence);
})
.on('packet', function(packet) {
self._emitPacket(packet);
})
.on('end', function() {
self._dequeue();
})
.on('start-tls', function() {
self._connection._startTLS(function(err) {
if (err) {
// SSL negotiation error are fatal
err.code = 'HANDSHAKE_SSL_ERROR';
err.fatal = true;
sequence.end(err);
return
}
sequence._tlsUpgradeCompleteHandler();
})
});
if (this._queue.length === 1) {
this._parser.resetPacketNumber();
this._startSequence(sequence);
}
return sequence;
};
Protocol.prototype._validateEnqueue = function(sequence) {
var err;
var prefix = 'Cannot enqueue ' + sequence.constructor.name;
var prefixBefore = prefix + ' before ';
var prefixAfter = prefix + ' after ';
if (this._fatalError) {
err = new Error(prefixAfter + 'fatal error.');
err.code = 'PROTOCOL_ENQUEUE_AFTER_FATAL_ERROR';
} else if (this._quitSequence) {
err = new Error(prefixAfter + 'invoking quit.');
err.code = 'PROTOCOL_ENQUEUE_AFTER_QUIT';
} else if (this._destroyed) {
err = new Error(prefixAfter + 'being destroyed.');
err.code = 'PROTOCOL_ENQUEUE_AFTER_DESTROY';
} else if (this._handshakeSequence && sequence.constructor === Sequences.Handshake) {
err = new Error(prefixAfter + 'already enqueuing a Handshake.');
err.code = 'PROTOCOL_ENQUEUE_HANDSHAKE_TWICE';
} else if (!this._handshakeSequence && sequence.constructor === Sequences.ChangeUser) {
err = new Error(prefixBefore + 'a Handshake.');
err.code = 'PROTOCOL_ENQUEUE_BEFORE_HANDSHAKE';
} else {
return true;
}
var self = this;
err.fatal = false;
sequence
.on('error', function(err) {
self._delegateError(err, sequence);
})
.end(err);
return false;
};
Protocol.prototype._parsePacket = function() {
var sequence = this._queue[0];
var Packet = this._determinePacket(sequence);
var packet = new Packet({
protocol41: this._config.protocol41
});
// Special case: Faster dispatch, and parsing done inside sequence
if (Packet === Packets.RowDataPacket) {
sequence.RowDataPacket(packet, this._parser, this._connection);
if (this._config.debug) {
this._debugPacket(true, packet);
}
return;
}
packet.parse(this._parser);
if (this._config.debug) {
this._debugPacket(true, packet);
}
if (Packet === Packets.HandshakeInitializationPacket) {
this._handshakeInitializationPacket = packet;
}
sequence[Packet.name](packet);
};
Protocol.prototype._emitPacket = function(packet) {
var packetWriter = new PacketWriter();
packet.write(packetWriter);
this.emit('data', packetWriter.toBuffer(this._parser));
if (this._config.debug) {
this._debugPacket(false, packet);
}
};
Protocol.prototype._determinePacket = function(sequence) {
var firstByte = this._parser.peak();
if (sequence.determinePacket) {
var Packet = sequence.determinePacket(firstByte, this._parser);
if (Packet) {
return Packet;
}
}
switch (firstByte) {
case 0x00:
if (!this._handshaked) {
this._handshaked = true;
this.emit('handshake', this._handshakeInitializationPacket);
}
return Packets.OkPacket;
case 0xfe: return Packets.EofPacket;
case 0xff: return Packets.ErrorPacket;
}
throw new Error('Could not determine packet, firstByte = ' + firstByte);
};
Protocol.prototype._dequeue = function() {
// No point in advancing the queue, we are dead
if (this._fatalError) {
return;
}
this._queue.shift();
var sequence = this._queue[0];
if (!sequence) {
this.emit('drain');
return;
}
this._parser.resetPacketNumber();
this._startSequence(sequence);
};
Protocol.prototype._startSequence = function(sequence) {
if (sequence.constructor === Sequences.ChangeUser) {
sequence.start(this._handshakeInitializationPacket);
} else {
sequence.start();
}
};
Protocol.prototype.handleNetworkError = function(err) {
err.fatal = true;
var sequence = this._queue[0];
if (sequence) {
sequence.end(err);
} else {
this._delegateError(err);
}
};
Protocol.prototype._delegateError = function(err, sequence) {
// Stop delegating errors after the first fatal error
if (this._fatalError) {
return;
}
if (err.fatal) {
this._fatalError = err;
}
if (this._shouldErrorBubbleUp(err, sequence)) {
// Can't use regular 'error' event here as that always destroys the pipe
// between socket and protocol which is not what we want (unless the
// exception was fatal).
this.emit('unhandledError', err);
} else if (err.fatal) {
this._queue.forEach(function(sequence) {
sequence.end(err);
});
}
// Make sure the stream we are piping to is getting closed
if (err.fatal) {
this.emit('end', err);
}
};
Protocol.prototype._shouldErrorBubbleUp = function(err, sequence) {
if (sequence) {
if (sequence.hasErrorHandler()) {
return false;
} else if (!err.fatal) {
return true;
}
}
return (err.fatal && !this._hasPendingErrorHandlers());
};
Protocol.prototype._hasPendingErrorHandlers = function() {
return this._queue.some(function(sequence) {
return sequence.hasErrorHandler();
});
};
Protocol.prototype.destroy = function() {
this._destroyed = true;
this._parser.pause();
if (this._connection.state !== "disconnected") {
if(!this._ended) {
this.end();
}
}
};
Protocol.prototype._debugPacket = function(incoming, packet) {
var headline = (incoming)
? '<-- '
: '--> ';
headline = headline + packet.constructor.name;
// check for debug packet restriction
if (Array.isArray(this._config.debug) && this._config.debug.indexOf(packet.constructor.name) === -1) {
return;
}
console.log(headline);
console.log(packet);
console.log('');
};
module.exports = ResultSet;
function ResultSet(resultSetHeaderPacket) {
this.resultSetHeaderPacket = resultSetHeaderPacket;
this.fieldPackets = [];
this.eofPackets = [];
this.rows = [];
}
var Sequence = require('./Sequence');
var Util = require('util');
var Packets = require('../packets');
var Auth = require('../Auth');
module.exports = ChangeUser;
Util.inherits(ChangeUser, Sequence);
function ChangeUser(options, callback) {
Sequence.call(this, callback);
this._user = options.user;
this._password = options.password;
this._database = options.database;
this._charsetNumber = options.charsetNumber;
this._currentConfig = options.currentConfig;
}
ChangeUser.prototype.start = function(handshakeInitializationPacket) {
var scrambleBuff = handshakeInitializationPacket.scrambleBuff();
scrambleBuff = Auth.token(this._password, scrambleBuff);
var packet = new Packets.ComChangeUserPacket({
user : this._user,
scrambleBuff : scrambleBuff,
database : this._database,
charsetNumber : this._charsetNumber,
});
this._currentConfig.user = this._user;
this._currentConfig.password = this._password;
this._currentConfig.database = this._database;
this._currentConfig.charsetNumber = this._charsetNumber;
this.emit('packet', packet);
};
ChangeUser.prototype['ErrorPacket'] = function(packet) {
var err = this._packetToError(packet);
err.fatal = true;
this.end(err);
};
var Sequence = require('./Sequence');
var Util = require('util');
var Packets = require('../packets');
var Auth = require('../Auth');
var ClientConstants = require('../constants/client');
module.exports = Handshake;
Util.inherits(Handshake, Sequence);
function Handshake(config, callback) {
Sequence.call(this, callback);
this._config = config;
this._handshakeInitializationPacket = null;
}
Handshake.prototype.determinePacket = function(firstByte) {
if (firstByte === 0xff) {
return Packets.ErrorPacket;
}
if (!this._handshakeInitializationPacket) {
return Packets.HandshakeInitializationPacket;
}
if (firstByte === 0xfe) {
return Packets.UseOldPasswordPacket;
}
};
Handshake.prototype['HandshakeInitializationPacket'] = function(packet) {
this._handshakeInitializationPacket = packet;
this._config.protocol41 = packet.protocol41;
var serverSSLSupport = packet.serverCapabilities1 & ClientConstants.CLIENT_SSL;
if (this._config.ssl) {
if (!serverSSLSupport) {
var err = new Error('Server does not support secure connnection');
err.code = 'HANDSHAKE_NO_SSL_SUPPORT';
err.fatal = true;
this.end(err);
return;
}
this._config.clientFlags |= ClientConstants.CLIENT_SSL;
this.emit('packet', new Packets.SSLRequestPacket({
clientFlags : this._config.clientFlags,
maxPacketSize : this._config.maxPacketSize,
charsetNumber : this._config.charsetNumber
}));
this.emit('start-tls');
} else {
this._sendCredentials();
}
};
Handshake.prototype._tlsUpgradeCompleteHandler = function() {
this._sendCredentials();
};
Handshake.prototype._sendCredentials = function(serverHello) {
var packet = this._handshakeInitializationPacket;
this.emit('packet', new Packets.ClientAuthenticationPacket({
clientFlags : this._config.clientFlags,
maxPacketSize : this._config.maxPacketSize,
charsetNumber : this._config.charsetNumber,
user : this._config.user,
scrambleBuff : (packet.protocol41)
? Auth.token(this._config.password, packet.scrambleBuff())
: Auth.scramble323(packet.scrambleBuff(), this._config.password),
database : this._config.database,
protocol41 : packet.protocol41
}));
};
Handshake.prototype['UseOldPasswordPacket'] = function(packet) {
if (!this._config.insecureAuth) {
var err = new Error(
'MySQL server is requesting the old and insecure pre-4.1 auth mechanism.' +
'Upgrade the user password or use the {insecureAuth: true} option.'
);
err.code = 'HANDSHAKE_INSECURE_AUTH';
err.fatal = true;
this.end(err);
return;
}
this.emit('packet', new Packets.OldPasswordPacket({
scrambleBuff : Auth.scramble323(this._handshakeInitializationPacket.scrambleBuff(), this._config.password),
}));
};
Handshake.prototype['ErrorPacket'] = function(packet) {
var err = this._packetToError(packet, true);
err.fatal = true;
this.end(err);
};
var Elements = module.exports = require('require-all')({
dirname : __dirname,
filter : /([A-Z].+)\.js$/,
});
var Sequence = require('./Sequence');
var Util = require('util');
var Packets = require('../packets');
module.exports = Ping;
Util.inherits(Ping, Sequence);
function Ping(callback) {
Sequence.call(this, callback);
}
Ping.prototype.start = function() {
this.emit('packet', new Packets.ComPingPacket);
};
var Sequence = require('./Sequence');
var Util = require('util');
var Packets = require('../packets');
var ResultSet = require('../ResultSet');
var ServerStatus = require('../constants/server_status');
var fs = require('fs');
var Readable = require('readable-stream');
module.exports = Query;
Util.inherits(Query, Sequence);
function Query(options, callback) {
Sequence.call(this, callback);
this.sql = options.sql;
this.values = options.values;
this.typeCast = (options.typeCast === undefined)
? true
: options.typeCast;
this.nestTables = options.nestTables || false;
this._resultSet = null;
this._results = [];
this._fields = [];
this._index = 0;
this._loadError = null;
}
Query.prototype.start = function() {
this.emit('packet', new Packets.ComQueryPacket(this.sql));
};
Query.prototype.determinePacket = function(firstByte, parser) {
if (firstByte === 0) {
// If we have a resultSet and got one eofPacket
if (this._resultSet && this._resultSet.eofPackets.length === 1) {
// Then this is a RowDataPacket with an empty string in the first column.
// See: https://github.com/felixge/node-mysql/issues/222
} else if (this._resultSet && this._resultSet.resultSetHeaderPacket
&& this._resultSet.resultSetHeaderPacket.fieldCount !== null) {
return Packets.FieldPacket;
} else {
return;
}
}
if (firstByte === 255) {
return;
}
// EofPacket's are 5 bytes in mysql >= 4.1
// This is the only / best way to differentiate their firstByte from a 9
// byte length coded binary.
if (firstByte === 0xfe && parser.packetLength() < 9) {
return Packets.EofPacket;
}
if (!this._resultSet) {
return Packets.ResultSetHeaderPacket;
}
return (this._resultSet.eofPackets.length === 0)
? Packets.FieldPacket
: Packets.RowDataPacket;
};
Query.prototype['OkPacket'] = function(packet) {
// try...finally for exception safety
try {
if (!this._callback) {
this.emit('result', packet, this._index);
} else {
this._results.push(packet);
this._fields.push(undefined);
}
} finally {
this._index++;
this._handleFinalResultPacket(packet);
}
};
Query.prototype['ErrorPacket'] = function(packet) {
var err = this._packetToError(packet);
var results = (this._results.length > 0)
? this._results
: undefined;
var fields = (this._fields.length > 0)
? this._fields
: undefined;
err.index = this._index;
this.end(err, results, fields);
};
Query.prototype['ResultSetHeaderPacket'] = function(packet) {
this._resultSet = new ResultSet(packet);
// used by LOAD DATA LOCAL INFILE queries
if (packet.fieldCount === null) {
this._sendLocalDataFile(packet.extra);
}
};
Query.prototype['FieldPacket'] = function(packet) {
this._resultSet.fieldPackets.push(packet);
};
Query.prototype['EofPacket'] = function(packet) {
this._resultSet.eofPackets.push(packet);
if (this._resultSet.eofPackets.length === 1 && !this._callback) {
this.emit('fields', this._resultSet.fieldPackets, this._index);
}
if (this._resultSet.eofPackets.length !== 2) {
return;
}
if (this._callback) {
this._results.push(this._resultSet.rows);
this._fields.push(this._resultSet.fieldPackets);
}
this._index++;
this._resultSet = null;
this._handleFinalResultPacket(packet);
};
Query.prototype._handleFinalResultPacket = function(packet) {
if (packet.serverStatus & ServerStatus.SERVER_MORE_RESULTS_EXISTS) {
return;
}
var results = (this._results.length > 1)
? this._results
: this._results[0];
var fields = (this._fields.length > 1)
? this._fields
: this._fields[0];
this.end(this._loadError, results, fields);
};
Query.prototype['RowDataPacket'] = function(packet, parser, connection) {
packet.parse(parser, this._resultSet.fieldPackets, this.typeCast, this.nestTables, connection);
if (this._callback) {
this._resultSet.rows.push(packet);
} else {
this.emit('result', packet, this._index);
}
};
Query.prototype._sendLocalDataFile = function(path) {
var self = this;
var localStream = fs.createReadStream(path, {
'flag': 'r',
'encoding': null,
'autoClose': true
});
this.on('pause', function () {
localStream.pause();
});
this.on('resume', function () {
localStream.resume();
});
localStream.on('data', function (data) {
self.emit('packet', new Packets.LocalDataFilePacket(data));
});
localStream.on('error', function (err) {
self._loadError = err;
localStream.emit('end');
});
localStream.on('end', function () {
self.emit('packet', new Packets.EmptyPacket());
});
};
Query.prototype.stream = function(options) {
var self = this,
stream;
options = options || {};
options.objectMode = true;
stream = new Readable(options);
stream._read = function() {
self._connection && self._connection.resume();
};
this.on('result',function(row,i) {
if (!stream.push(row)) self._connection.pause();
stream.emit('result',row,i); // replicate old emitter
});
this.on('error',function(err) {
stream.emit('error',err); // Pass on any errors
});
this.on('end', function() {
stream.emit('close'); // notify readers that query has completed
stream.push(null); // pushing null, indicating EOF
});
this.on('fields',function(fields,i) {
stream.emit('fields',fields,i); // replicate old emitter
});
return stream;
};
var Sequence = require('./Sequence');
var Util = require('util');
var Packets = require('../packets');
module.exports = Quit;
Util.inherits(Quit, Sequence);
function Quit(callback) {
Sequence.call(this, callback);
}
Quit.prototype.start = function() {
this.emit('packet', new Packets.ComQuitPacket);
};
var Util = require('util');
var EventEmitter = require('events').EventEmitter;
var Packets = require('../packets');
var ErrorConstants = require('../constants/errors');
module.exports = Sequence;
Util.inherits(Sequence, EventEmitter);
function Sequence(callback) {
EventEmitter.call(this);
this._callback = callback;
this._callSite = null;
this._ended = false;
}
Sequence.determinePacket = function(byte) {
switch (byte) {
case 0x00: return Packets.OkPacket;
case 0xfe: return Packets.EofPacket;
case 0xff: return Packets.ErrorPacket;
}
};
Sequence.prototype.hasErrorHandler = function() {
return this._callback || this.listeners('error').length > 1;
};
Sequence.prototype._packetToError = function(packet) {
var code = ErrorConstants[packet.errno] || 'UNKNOWN_CODE_PLEASE_REPORT';
var err = new Error(code + ': ' + packet.message);
err.code = code;
err.errno = packet.errno;
err.sqlState = packet.sqlState;
return err;
};
Sequence.prototype._addLongStackTrace = function(err) {
if (!this._callSite) {
return;
}
var delimiter = '\n --------------------\n' ;
if (err.stack.indexOf(delimiter) > -1) {
return;
}
err.stack += delimiter + this._callSite.stack.replace(/.+\n/, '');
};
Sequence.prototype.end = function(err) {
if (this._ended) {
return;
}
this._ended = true;
if (err) {
this._addLongStackTrace(err);
}
// Without this we are leaking memory. This problem was introduced in
// 8189925374e7ce3819bbe88b64c7b15abac96b16. I suspect that the error object
// causes a cyclic reference that the GC does not detect properly, but I was
// unable to produce a standalone version of this leak. This would be a great
// challenge for somebody interested in difficult problems : )!
this._callSite = null;
// try...finally for exception safety
try {
if (err) {
this.emit('error', err);
}
} finally {
try {
if (this._callback) {
this._callback.apply(this, arguments);
}
} finally {
this.emit('end');
}
}
};
Sequence.prototype['OkPacket'] = function(packet) {
this.end(null, packet);
};
Sequence.prototype['ErrorPacket'] = function(packet) {
this.end(this._packetToError(packet));
};
// Implemented by child classes
Sequence.prototype.start = function() {};
var Sequence = require('./Sequence');
var Util = require('util');
var Packets = require('../packets');
module.exports = Statistics;
Util.inherits(Statistics, Sequence);
function Statistics(callback) {
Sequence.call(this, callback);
}
Statistics.prototype.start = function() {
this.emit('packet', new Packets.ComStatisticsPacket);
};
Statistics.prototype['StatisticsPacket'] = function (packet) {
this.end(null, packet);
};
Statistics.prototype.determinePacket = function(firstByte, parser) {
if (firstByte === 0x55) {
return Packets.StatisticsPacket;
}
};
var SqlString = exports;
SqlString.escapeId = function (val, forbidQualified) {
if (Array.isArray(val)) {
return val.map(function(v) {
return SqlString.escapeId(v, forbidQualified);
}).join(', ');
}
if (forbidQualified) {
return '`' + val.replace(/`/g, '``') + '`';
}
return '`' + val.replace(/`/g, '``').replace(/\./g, '`.`') + '`';
};
SqlString.escape = function(val, stringifyObjects, timeZone) {
if (val === undefined || val === null) {
return 'NULL';
}
switch (typeof val) {
case 'boolean': return (val) ? 'true' : 'false';
case 'number': return val+'';
}
if (val instanceof Date) {
val = SqlString.dateToString(val, timeZone || 'local');
}
if (Buffer.isBuffer(val)) {
return SqlString.bufferToString(val);
}
if (Array.isArray(val)) {
return SqlString.arrayToList(val, timeZone);
}
if (typeof val === 'object') {
if (stringifyObjects) {
val = val.toString();
} else {
return SqlString.objectToValues(val, timeZone);
}
}
val = val.replace(/[\0\n\r\b\t\\\'\"\x1a]/g, function(s) {
switch(s) {
case "\0": return "\\0";
case "\n": return "\\n";
case "\r": return "\\r";
case "\b": return "\\b";
case "\t": return "\\t";
case "\x1a": return "\\Z";
default: return "\\"+s;
}
});
return "'"+val+"'";
};
SqlString.arrayToList = function(array, timeZone) {
return array.map(function(v) {
if (Array.isArray(v)) return '(' + SqlString.arrayToList(v, timeZone) + ')';
return SqlString.escape(v, true, timeZone);
}).join(', ');
};
SqlString.format = function(sql, values, stringifyObjects, timeZone) {
values = values == null ? [] : [].concat(values);
return sql.replace(/\?\??/g, function(match) {
if (!values.length) {
return match;
}
if (match == "??") {
return SqlString.escapeId(values.shift());
}
return SqlString.escape(values.shift(), stringifyObjects, timeZone);
});
};
SqlString.dateToString = function(date, timeZone) {
var dt = new Date(date);
if (timeZone != 'local') {
var tz = convertTimezone(timeZone);
dt.setTime(dt.getTime() + (dt.getTimezoneOffset() * 60000));
if (tz !== false) {
dt.setTime(dt.getTime() + (tz * 60000));
}
}
var year = dt.getFullYear();
var month = zeroPad(dt.getMonth() + 1, 2);
var day = zeroPad(dt.getDate(), 2);
var hour = zeroPad(dt.getHours(), 2);
var minute = zeroPad(dt.getMinutes(), 2);
var second = zeroPad(dt.getSeconds(), 2);
var millisecond = zeroPad(dt.getMilliseconds(), 3);
return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second + '.' + millisecond;
};
SqlString.bufferToString = function(buffer) {
var hex = '';
try {
hex = buffer.toString('hex');
} catch (err) {
// node v0.4.x does not support hex / throws unknown encoding error
for (var i = 0; i < buffer.length; i++) {
var byte = buffer[i];
hex += zeroPad(byte.toString(16));
}
}
return "X'" + hex+ "'";
};
SqlString.objectToValues = function(object, timeZone) {
var values = [];
for (var key in object) {
var value = object[key];
if(typeof value === 'function') {
continue;
}
values.push(this.escapeId(key) + ' = ' + SqlString.escape(value, true, timeZone));
}
return values.join(', ');
};
function zeroPad(number, length) {
number = number.toString();
while (number.length < length) {
number = '0' + number;
}
return number;
}
function convertTimezone(tz) {
if (tz == "Z") return 0;
var m = tz.match(/([\+\-\s])(\d\d):?(\d\d)?/);
if (m) {
return (m[1] == '-' ? -1 : 1) * (parseInt(m[2], 10) + ((m[3] ? parseInt(m[3], 10) : 0) / 60)) * 60;
}
return false;
}
Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
language: node_js
node_js:
- "0.11"
- "0.10"
- "0.8"
- "0.6"
/*! bignumber.js v1.4.0 https://github.com/MikeMcl/bignumber.js/LICENCE */
;(function ( global ) {
'use strict';
/*
bignumber.js v1.4.0
A JavaScript library for arbitrary-precision arithmetic.
https://github.com/MikeMcl/bignumber.js
Copyright (c) 2012 Michael Mclaughlin <M8ch88l@gmail.com>
MIT Expat Licence
*/
/*********************************** DEFAULTS ************************************/
/*
* The default values below must be integers within the stated ranges (inclusive).
* Most of these values can be changed during run-time using BigNumber.config().
*/
/*
* The limit on the value of DECIMAL_PLACES, TO_EXP_NEG, TO_EXP_POS, MIN_EXP,
* MAX_EXP, and the argument to toFixed, toPrecision and toExponential, beyond
* which an exception is thrown (if ERRORS is true).
*/
var MAX = 1E9, // 0 to 1e+9
// Limit of magnitude of exponent argument to toPower.
MAX_POWER = 1E6, // 1 to 1e+6
// The maximum number of decimal places for operations involving division.
DECIMAL_PLACES = 20, // 0 to MAX
/*
* The rounding mode used when rounding to the above decimal places, and when
* using toFixed, toPrecision and toExponential, and round (default value).
* UP 0 Away from zero.
* DOWN 1 Towards zero.
* CEIL 2 Towards +Infinity.
* FLOOR 3 Towards -Infinity.
* HALF_UP 4 Towards nearest neighbour. If equidistant, up.
* HALF_DOWN 5 Towards nearest neighbour. If equidistant, down.
* HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour.
* HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity.
* HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity.
*/
ROUNDING_MODE = 4, // 0 to 8
// EXPONENTIAL_AT : [TO_EXP_NEG , TO_EXP_POS]
// The exponent value at and beneath which toString returns exponential notation.
// Number type: -7
TO_EXP_NEG = -7, // 0 to -MAX
// The exponent value at and above which toString returns exponential notation.
// Number type: 21
TO_EXP_POS = 21, // 0 to MAX
// RANGE : [MIN_EXP, MAX_EXP]
// The minimum exponent value, beneath which underflow to zero occurs.
// Number type: -324 (5e-324)
MIN_EXP = -MAX, // -1 to -MAX
// The maximum exponent value, above which overflow to Infinity occurs.
// Number type: 308 (1.7976931348623157e+308)
MAX_EXP = MAX, // 1 to MAX
// Whether BigNumber Errors are ever thrown.
// CHANGE parseInt to parseFloat if changing ERRORS to false.
ERRORS = true, // true or false
parse = parseInt, // parseInt or parseFloat
/***********************************************************************************/
P = BigNumber.prototype,
DIGITS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_',
outOfRange,
id = 0,
isValid = /^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,
trim = String.prototype.trim || function () {return this.replace(/^\s+|\s+$/g, '')},
ONE = BigNumber(1);
// CONSTRUCTOR
/*
* The exported function.
* Create and return a new instance of a BigNumber object.
*
* n {number|string|BigNumber} A numeric value.
* [b] {number} The base of n. Integer, 2 to 64 inclusive.
*/
function BigNumber( n, b ) {
var e, i, isNum, digits, valid, orig,
x = this;
// Enable constructor usage without new.
if ( !(x instanceof BigNumber) ) {
return new BigNumber( n, b )
}
// Duplicate.
if ( n instanceof BigNumber ) {
id = 0;
// e is undefined.
if ( b !== e ) {
n += ''
} else {
x['s'] = n['s'];
x['e'] = n['e'];
x['c'] = ( n = n['c'] ) ? n.slice() : n;
return;
}
}
// If number, check if minus zero.
if ( typeof n != 'string' ) {
n = ( isNum = typeof n == 'number' ||
Object.prototype.toString.call(n) == '[object Number]' ) &&
n === 0 && 1 / n < 0 ? '-0' : n + '';
}
orig = n;
if ( b === e && isValid.test(n) ) {
// Determine sign.
x['s'] = n.charAt(0) == '-' ? ( n = n.slice(1), -1 ) : 1;
// Either n is not a valid BigNumber or a base has been specified.
} else {
// Enable exponential notation to be used with base 10 argument.
// Ensure return value is rounded to DECIMAL_PLACES as with other bases.
if ( b == 10 ) {
return setMode( n, DECIMAL_PLACES, ROUNDING_MODE );
}
n = trim.call(n).replace( /^\+(?!-)/, '' );
x['s'] = n.charAt(0) == '-' ? ( n = n.replace( /^-(?!-)/, '' ), -1 ) : 1;
if ( b != null ) {
if ( ( b == (b | 0) || !ERRORS ) &&
!( outOfRange = !( b >= 2 && b < 65 ) ) ) {
digits = '[' + DIGITS.slice( 0, b = b | 0 ) + ']+';
// Before non-decimal number validity test and base conversion
// remove the `.` from e.g. '1.', and replace e.g. '.1' with '0.1'.
n = n.replace( /\.$/, '' ).replace( /^\./, '0.' );
// Any number in exponential form will fail due to the e+/-.
if ( valid = new RegExp(
'^' + digits + '(?:\\.' + digits + ')?$', b < 37 ? 'i' : '' ).test(n) ) {
if ( isNum ) {
if ( n.replace( /^0\.0*|\./, '' ).length > 15 ) {
// 'new BigNumber() number type has more than 15 significant digits: {n}'
ifExceptionsThrow( orig, 0 );
}
// Prevent later check for length on converted number.
isNum = !isNum;
}
n = convert( n, 10, b, x['s'] );
} else if ( n != 'Infinity' && n != 'NaN' ) {
// 'new BigNumber() not a base {b} number: {n}'
ifExceptionsThrow( orig, 1, b );
n = 'NaN';
}
} else {
// 'new BigNumber() base not an integer: {b}'
// 'new BigNumber() base out of range: {b}'
ifExceptionsThrow( b, 2 );
// Ignore base.
valid = isValid.test(n);
}
} else {
valid = isValid.test(n);
}
if ( !valid ) {
// Infinity/NaN
x['c'] = x['e'] = null;
// NaN
if ( n != 'Infinity' ) {
// No exception on NaN.
if ( n != 'NaN' ) {
// 'new BigNumber() not a number: {n}'
ifExceptionsThrow( orig, 3 );
}
x['s'] = null;
}
id = 0;
return;
}
}
// Decimal point?
if ( ( e = n.indexOf('.') ) > -1 ) {
n = n.replace( '.', '' );
}
// Exponential form?
if ( ( i = n.search( /e/i ) ) > 0 ) {
// Determine exponent.
if ( e < 0 ) {
e = i;
}
e += +n.slice( i + 1 );
n = n.substring( 0, i );
} else if ( e < 0 ) {
// Integer.
e = n.length;
}
// Determine leading zeros.
for ( i = 0; n.charAt(i) == '0'; i++ ) {
}
b = n.length;
// Disallow numbers with over 15 significant digits if number type.
if ( isNum && b > 15 && n.slice(i).length > 15 ) {
// 'new BigNumber() number type has more than 15 significant digits: {n}'
ifExceptionsThrow( orig, 0 );
}
id = 0;
// Overflow?
if ( ( e -= i + 1 ) > MAX_EXP ) {
// Infinity.
x['c'] = x['e'] = null;
// Zero or underflow?
} else if ( i == b || e < MIN_EXP ) {
// Zero.
x['c'] = [ x['e'] = 0 ];
} else {
// Determine trailing zeros.
for ( ; n.charAt(--b) == '0'; ) {
}
x['e'] = e;
x['c'] = [];
// Convert string to array of digits (without leading and trailing zeros).
for ( e = 0; i <= b; x['c'][e++] = +n.charAt(i++) ) {
}
}
}
// CONSTRUCTOR PROPERTIES/METHODS
BigNumber['ROUND_UP'] = 0;
BigNumber['ROUND_DOWN'] = 1;
BigNumber['ROUND_CEIL'] = 2;
BigNumber['ROUND_FLOOR'] = 3;
BigNumber['ROUND_HALF_UP'] = 4;
BigNumber['ROUND_HALF_DOWN'] = 5;
BigNumber['ROUND_HALF_EVEN'] = 6;
BigNumber['ROUND_HALF_CEIL'] = 7;
BigNumber['ROUND_HALF_FLOOR'] = 8;
/*
* Configure infrequently-changing library-wide settings.
*
* Accept an object or an argument list, with one or many of the following
* properties or parameters respectively:
* [ DECIMAL_PLACES [, ROUNDING_MODE [, EXPONENTIAL_AT [, RANGE [, ERRORS ]]]]]
*
* E.g.
* BigNumber.config(20, 4) is equivalent to
* BigNumber.config({ DECIMAL_PLACES : 20, ROUNDING_MODE : 4 })
* Ignore properties/parameters set to null or undefined.
*
* Return an object with the properties current values.
*/
BigNumber['config'] = function () {
var v, p,
i = 0,
r = {},
a = arguments,
o = a[0],
c = 'config',
inRange = function ( n, lo, hi ) {
return !( ( outOfRange = n < lo || n > hi ) ||
parse(n) != n && n !== 0 );
},
has = o && typeof o == 'object'
? function () {if ( o.hasOwnProperty(p) ) return ( v = o[p] ) != null}
: function () {if ( a.length > i ) return ( v = a[i++] ) != null};
// [DECIMAL_PLACES] {number} Integer, 0 to MAX inclusive.
if ( has( p = 'DECIMAL_PLACES' ) ) {
if ( inRange( v, 0, MAX ) ) {
DECIMAL_PLACES = v | 0;
} else {
// 'config() DECIMAL_PLACES not an integer: {v}'
// 'config() DECIMAL_PLACES out of range: {v}'
ifExceptionsThrow( v, p, c );
}
}
r[p] = DECIMAL_PLACES;
// [ROUNDING_MODE] {number} Integer, 0 to 8 inclusive.
if ( has( p = 'ROUNDING_MODE' ) ) {
if ( inRange( v, 0, 8 ) ) {
ROUNDING_MODE = v | 0;
} else {
// 'config() ROUNDING_MODE not an integer: {v}'
// 'config() ROUNDING_MODE out of range: {v}'
ifExceptionsThrow( v, p, c );
}
}
r[p] = ROUNDING_MODE;
/*
* [EXPONENTIAL_AT] {number|number[]} Integer, -MAX to MAX inclusive or
* [ integer -MAX to 0 inclusive, 0 to MAX inclusive ].
*/
if ( has( p = 'EXPONENTIAL_AT' ) ) {
if ( inRange( v, -MAX, MAX ) ) {
TO_EXP_NEG = -( TO_EXP_POS = ~~( v < 0 ? -v : +v ) );
} else if ( !outOfRange && v && inRange( v[0], -MAX, 0 ) &&
inRange( v[1], 0, MAX ) ) {
TO_EXP_NEG = ~~v[0];
TO_EXP_POS = ~~v[1];
} else {
// 'config() EXPONENTIAL_AT not an integer or not [integer, integer]: {v}'
// 'config() EXPONENTIAL_AT out of range or not [negative, positive: {v}'
ifExceptionsThrow( v, p, c, 1 );
}
}
r[p] = [ TO_EXP_NEG, TO_EXP_POS ];
/*
* [RANGE][ {number|number[]} Non-zero integer, -MAX to MAX inclusive or
* [ integer -MAX to -1 inclusive, integer 1 to MAX inclusive ].
*/
if ( has( p = 'RANGE' ) ) {
if ( inRange( v, -MAX, MAX ) && ~~v ) {
MIN_EXP = -( MAX_EXP = ~~( v < 0 ? -v : +v ) );
} else if ( !outOfRange && v && inRange( v[0], -MAX, -1 ) &&
inRange( v[1], 1, MAX ) ) {
MIN_EXP = ~~v[0], MAX_EXP = ~~v[1];
} else {
// 'config() RANGE not a non-zero integer or not [integer, integer]: {v}'
// 'config() RANGE out of range or not [negative, positive: {v}'
ifExceptionsThrow( v, p, c, 1, 1 );
}
}
r[p] = [ MIN_EXP, MAX_EXP ];
// [ERRORS] {boolean|number} true, false, 1 or 0.
if ( has( p = 'ERRORS' ) ) {
if ( v === !!v || v === 1 || v === 0 ) {
parse = ( outOfRange = id = 0, ERRORS = !!v )
? parseInt
: parseFloat;
} else {
// 'config() ERRORS not a boolean or binary digit: {v}'
ifExceptionsThrow( v, p, c, 0, 0, 1 );
}
}
r[p] = ERRORS;
return r;
};
// PRIVATE FUNCTIONS
// Assemble error messages. Throw BigNumber Errors.
function ifExceptionsThrow( arg, i, j, isArray, isRange, isErrors) {
if ( ERRORS ) {
var error,
method = ['new BigNumber', 'cmp', 'div', 'eq', 'gt', 'gte', 'lt',
'lte', 'minus', 'mod', 'plus', 'times', 'toFr'
][ id ? id < 0 ? -id : id : 1 / id < 0 ? 1 : 0 ] + '()',
message = outOfRange ? ' out of range' : ' not a' +
( isRange ? ' non-zero' : 'n' ) + ' integer';
message = ( [
method + ' number type has more than 15 significant digits',
method + ' not a base ' + j + ' number',
method + ' base' + message,
method + ' not a number' ][i] ||
j + '() ' + i + ( isErrors
? ' not a boolean or binary digit'
: message + ( isArray
? ' or not [' + ( outOfRange
? ' negative, positive'
: ' integer, integer' ) + ' ]'
: '' ) ) ) + ': ' + arg;
outOfRange = id = 0;
error = new Error(message);
error['name'] = 'BigNumber Error';
throw error;
}
}
/*
* Convert a numeric string of baseIn to a numeric string of baseOut.
*/
function convert( nStr, baseOut, baseIn, sign ) {
var e, dvs, dvd, nArr, fracArr, fracBN;
// Convert string of base bIn to an array of numbers of baseOut.
// Eg. strToArr('255', 10) where baseOut is 16, returns [15, 15].
// Eg. strToArr('ff', 16) where baseOut is 10, returns [2, 5, 5].
function strToArr( str, bIn ) {
var j,
i = 0,
strL = str.length,
arrL,
arr = [0];
for ( bIn = bIn || baseIn; i < strL; i++ ) {
for ( arrL = arr.length, j = 0; j < arrL; arr[j] *= bIn, j++ ) {
}
for ( arr[0] += DIGITS.indexOf( str.charAt(i) ), j = 0;
j < arr.length;
j++ ) {
if ( arr[j] > baseOut - 1 ) {
if ( arr[j + 1] == null ) {
arr[j + 1] = 0;
}
arr[j + 1] += arr[j] / baseOut ^ 0;
arr[j] %= baseOut;
}
}
}
return arr.reverse();
}
// Convert array to string.
// E.g. arrToStr( [9, 10, 11] ) becomes '9ab' (in bases above 11).
function arrToStr( arr ) {
var i = 0,
arrL = arr.length,
str = '';
for ( ; i < arrL; str += DIGITS.charAt( arr[i++] ) ) {
}
return str;
}
if ( baseIn < 37 ) {
nStr = nStr.toLowerCase();
}
/*
* If non-integer convert integer part and fraction part separately.
* Convert the fraction part as if it is an integer than use division to
* reduce it down again to a value less than one.
*/
if ( ( e = nStr.indexOf( '.' ) ) > -1 ) {
/*
* Calculate the power to which to raise the base to get the number
* to divide the fraction part by after it has been converted as an
* integer to the required base.
*/
e = nStr.length - e - 1;
// Use toFixed to avoid possible exponential notation.
dvs = strToArr( new BigNumber(baseIn)['pow'](e)['toF'](), 10 );
nArr = nStr.split('.');
// Convert the base of the fraction part (as integer).
dvd = strToArr( nArr[1] );
// Convert the base of the integer part.
nArr = strToArr( nArr[0] );
// Result will be a BigNumber with a value less than 1.
fracBN = divide( dvd, dvs, dvd.length - dvs.length, sign, baseOut,
// Is least significant digit of integer part an odd number?
nArr[nArr.length - 1] & 1 );
fracArr = fracBN['c'];
// e can be <= 0 ( if e == 0, fracArr is [0] or [1] ).
if ( e = fracBN['e'] ) {
// Append zeros according to the exponent of the result.
for ( ; ++e; fracArr.unshift(0) ) {
}
// Append the fraction part to the converted integer part.
nStr = arrToStr(nArr) + '.' + arrToStr(fracArr);
// fracArr is [1].
// Fraction digits rounded up, so increment last digit of integer part.
} else if ( fracArr[0] ) {
if ( nArr[ e = nArr.length - 1 ] < baseOut - 1 ) {
++nArr[e];
nStr = arrToStr(nArr);
} else {
nStr = new BigNumber( arrToStr(nArr),
baseOut )['plus'](ONE)['toS'](baseOut);
}
// fracArr is [0]. No fraction digits.
} else {
nStr = arrToStr(nArr);
}
} else {
// Simple integer. Convert base.
nStr = arrToStr( strToArr(nStr) );
}
return nStr;
}
// Perform division in the specified base. Called by div and convert.
function divide( dvd, dvs, exp, s, base, isOdd ) {
var dvsL, dvsT, next, cmp, remI,
dvsZ = dvs.slice(),
dvdI = dvsL = dvs.length,
dvdL = dvd.length,
rem = dvd.slice( 0, dvsL ),
remL = rem.length,
quo = new BigNumber(ONE),
qc = quo['c'] = [],
qi = 0,
dig = DECIMAL_PLACES + ( quo['e'] = exp ) + 1;
quo['s'] = s;
s = dig < 0 ? 0 : dig;
// Add zeros to make remainder as long as divisor.
for ( ; remL++ < dvsL; rem.push(0) ) {
}
// Create version of divisor with leading zero.
dvsZ.unshift(0);
do {
// 'next' is how many times the divisor goes into the current remainder.
for ( next = 0; next < base; next++ ) {
// Compare divisor and remainder.
if ( dvsL != ( remL = rem.length ) ) {
cmp = dvsL > remL ? 1 : -1;
} else {
for ( remI = -1, cmp = 0; ++remI < dvsL; ) {
if ( dvs[remI] != rem[remI] ) {
cmp = dvs[remI] > rem[remI] ? 1 : -1;
break;
}
}
}
// Subtract divisor from remainder (if divisor < remainder).
if ( cmp < 0 ) {
// Remainder cannot be more than one digit longer than divisor.
// Equalise lengths using divisor with extra leading zero?
for ( dvsT = remL == dvsL ? dvs : dvsZ; remL; ) {
if ( rem[--remL] < dvsT[remL] ) {
for ( remI = remL;
remI && !rem[--remI];
rem[remI] = base - 1 ) {
}
--rem[remI];
rem[remL] += base;
}
rem[remL] -= dvsT[remL];
}
for ( ; !rem[0]; rem.shift() ) {
}
} else {
break;
}
}
// Add the 'next' digit to the result array.
qc[qi++] = cmp ? next : ++next;
// Update the remainder.
rem[0] && cmp
? ( rem[remL] = dvd[dvdI] || 0 )
: ( rem = [ dvd[dvdI] ] );
} while ( ( dvdI++ < dvdL || rem[0] != null ) && s-- );
// Leading zero? Do not remove if result is simply zero (qi == 1).
if ( !qc[0] && qi != 1 ) {
// There can't be more than one zero.
--quo['e'];
qc.shift();
}
// Round?
if ( qi > dig ) {
rnd( quo, DECIMAL_PLACES, base, isOdd, rem[0] != null );
}
// Overflow?
if ( quo['e'] > MAX_EXP ) {
// Infinity.
quo['c'] = quo['e'] = null;
// Underflow?
} else if ( quo['e'] < MIN_EXP ) {
// Zero.
quo['c'] = [quo['e'] = 0];
}
return quo;
}
/*
* Return a string representing the value of BigNumber n in normal or
* exponential notation rounded to the specified decimal places or
* significant digits.
* Called by toString, toExponential (exp 1), toFixed, and toPrecision (exp 2).
* d is the index (with the value in normal notation) of the digit that may be
* rounded up.
*/
function format( n, d, exp ) {
// Initially, i is the number of decimal places required.
var i = d - (n = new BigNumber(n))['e'],
c = n['c'];
// +-Infinity or NaN?
if ( !c ) {
return n['toS']();
}
// Round?
if ( c.length > ++d ) {
rnd( n, i, 10 );
}
// Recalculate d if toFixed as n['e'] may have changed if value rounded up.
i = c[0] == 0 ? i + 1 : exp ? d : n['e'] + i + 1;
// Append zeros?
for ( ; c.length < i; c.push(0) ) {
}
i = n['e'];
/*
* toPrecision returns exponential notation if the number of significant
* digits specified is less than the number of digits necessary to
* represent the integer part of the value in normal notation.
*/
return exp == 1 || exp == 2 && ( --d < i || i <= TO_EXP_NEG )
// Exponential notation.
? ( n['s'] < 0 && c[0] ? '-' : '' ) + ( c.length > 1
? ( c.splice( 1, 0, '.' ), c.join('') )
: c[0] ) + ( i < 0 ? 'e' : 'e+' ) + i
// Normal notation.
: n['toS']();
}
// Round if necessary.
// Called by divide, format, setMode and sqrt.
function rnd( x, dp, base, isOdd, r ) {
var xc = x['c'],
isNeg = x['s'] < 0,
half = base / 2,
i = x['e'] + dp + 1,
// 'next' is the digit after the digit that may be rounded up.
next = xc[i],
/*
* 'more' is whether there are digits after 'next'.
* E.g.
* 0.005 (e = -3) to be rounded to 0 decimal places (dp = 0) gives i = -2
* The 'next' digit is zero, and there ARE 'more' digits after it.
* 0.5 (e = -1) dp = 0 gives i = 0
* The 'next' digit is 5 and there are no 'more' digits after it.
*/
more = r || i < 0 || xc[i + 1] != null;
r = ROUNDING_MODE < 4
? ( next != null || more ) &&
( ROUNDING_MODE == 0 ||
ROUNDING_MODE == 2 && !isNeg ||
ROUNDING_MODE == 3 && isNeg )
: next > half || next == half &&
( ROUNDING_MODE == 4 || more ||
/*
* isOdd is used in base conversion and refers to the least significant
* digit of the integer part of the value to be converted. The fraction
* part is rounded by this method separately from the integer part.
*/
ROUNDING_MODE == 6 && ( xc[i - 1] & 1 || !dp && isOdd ) ||
ROUNDING_MODE == 7 && !isNeg ||
ROUNDING_MODE == 8 && isNeg );
if ( i < 1 || !xc[0] ) {
xc.length = 0;
xc.push(0);
if ( r ) {
// 1, 0.1, 0.01, 0.001, 0.0001 etc.
xc[0] = 1;
x['e'] = -dp;
} else {
// Zero.
x['e'] = 0;
}
return x;
}
// Remove any digits after the required decimal places.
xc.length = i--;
// Round up?
if ( r ) {
// Rounding up may mean the previous digit has to be rounded up and so on.
for ( --base; ++xc[i] > base; ) {
xc[i] = 0;
if ( !i-- ) {
++x['e'];
xc.unshift(1);
}
}
}
// Remove trailing zeros.
for ( i = xc.length; !xc[--i]; xc.pop() ) {
}
return x;
}
// Round after setting the appropriate rounding mode.
// Handles ceil, floor and round.
function setMode( x, dp, rm ) {
var r = ROUNDING_MODE;
ROUNDING_MODE = rm;
x = new BigNumber(x);
x['c'] && rnd( x, dp, 10 );
ROUNDING_MODE = r;
return x;
}
// PROTOTYPE/INSTANCE METHODS
/*
* Return a new BigNumber whose value is the absolute value of this BigNumber.
*/
P['abs'] = P['absoluteValue'] = function () {
var x = new BigNumber(this);
if ( x['s'] < 0 ) {
x['s'] = 1;
}
return x;
};
/*
* Return a new BigNumber whose value is the value of this BigNumber
* rounded to a whole number in the direction of Infinity.
*/
P['ceil'] = function () {
return setMode( this, 0, 2 );
};
/*
* Return
* 1 if the value of this BigNumber is greater than the value of BigNumber(y, b),
* -1 if the value of this BigNumber is less than the value of BigNumber(y, b),
* 0 if they have the same value,
* or null if the value of either is NaN.
*/
P['comparedTo'] = P['cmp'] = function ( y, b ) {
var a,
x = this,
xc = x['c'],
yc = ( id = -id, y = new BigNumber( y, b ) )['c'],
i = x['s'],
j = y['s'],
k = x['e'],
l = y['e'];
// Either NaN?
if ( !i || !j ) {
return null;
}
a = xc && !xc[0], b = yc && !yc[0];
// Either zero?
if ( a || b ) {
return a ? b ? 0 : -j : i;
}
// Signs differ?
if ( i != j ) {
return i;
}
// Either Infinity?
if ( a = i < 0, b = k == l, !xc || !yc ) {
return b ? 0 : !xc ^ a ? 1 : -1;
}
// Compare exponents.
if ( !b ) {
return k > l ^ a ? 1 : -1;
}
// Compare digit by digit.
for ( i = -1,
j = ( k = xc.length ) < ( l = yc.length ) ? k : l;
++i < j; ) {
if ( xc[i] != yc[i] ) {
return xc[i] > yc[i] ^ a ? 1 : -1;
}
}
// Compare lengths.
return k == l ? 0 : k > l ^ a ? 1 : -1;
};
/*
* n / 0 = I
* n / N = N
* n / I = 0
* 0 / n = 0
* 0 / 0 = N
* 0 / N = N
* 0 / I = 0
* N / n = N
* N / 0 = N
* N / N = N
* N / I = N
* I / n = I
* I / 0 = I
* I / N = N
* I / I = N
*
* Return a new BigNumber whose value is the value of this BigNumber
* divided by the value of BigNumber(y, b), rounded according to
* DECIMAL_PLACES and ROUNDING_MODE.
*/
P['dividedBy'] = P['div'] = function ( y, b ) {
var xc = this['c'],
xe = this['e'],
xs = this['s'],
yc = ( id = 2, y = new BigNumber( y, b ) )['c'],
ye = y['e'],
ys = y['s'],
s = xs == ys ? 1 : -1;
// Either NaN/Infinity/0?
return !xe && ( !xc || !xc[0] ) || !ye && ( !yc || !yc[0] )
// Either NaN?
? new BigNumber( !xs || !ys ||
// Both 0 or both Infinity?
( xc ? yc && xc[0] == yc[0] : !yc )
// Return NaN.
? NaN
// x is 0 or y is Infinity?
: xc && xc[0] == 0 || !yc
// Return +-0.
? s * 0
// y is 0. Return +-Infinity.
: s / 0 )
: divide( xc, yc, xe - ye, s, 10 );
};
/*
* Return true if the value of this BigNumber is equal to the value of
* BigNumber(n, b), otherwise returns false.
*/
P['equals'] = P['eq'] = function ( n, b ) {
id = 3;
return this['cmp']( n, b ) === 0;
};
/*
* Return a new BigNumber whose value is the value of this BigNumber
* rounded to a whole number in the direction of -Infinity.
*/
P['floor'] = function () {
return setMode( this, 0, 3 );
};
/*
* Return true if the value of this BigNumber is greater than the value of
* BigNumber(n, b), otherwise returns false.
*/
P['greaterThan'] = P['gt'] = function ( n, b ) {
id = 4;
return this['cmp']( n, b ) > 0;
};
/*
* Return true if the value of this BigNumber is greater than or equal to
* the value of BigNumber(n, b), otherwise returns false.
*/
P['greaterThanOrEqualTo'] = P['gte'] = function ( n, b ) {
id = 5;
return ( b = this['cmp']( n, b ) ) == 1 || b === 0;
};
/*
* Return true if the value of this BigNumber is a finite number, otherwise
* returns false.
*/
P['isFinite'] = P['isF'] = function () {
return !!this['c'];
};
/*
* Return true if the value of this BigNumber is NaN, otherwise returns
* false.
*/
P['isNaN'] = function () {
return !this['s'];
};
/*
* Return true if the value of this BigNumber is negative, otherwise
* returns false.
*/
P['isNegative'] = P['isNeg'] = function () {
return this['s'] < 0;
};
/*
* Return true if the value of this BigNumber is 0 or -0, otherwise returns
* false.
*/
P['isZero'] = P['isZ'] = function () {
return !!this['c'] && this['c'][0] == 0;
};
/*
* Return true if the value of this BigNumber is less than the value of
* BigNumber(n, b), otherwise returns false.
*/
P['lessThan'] = P['lt'] = function ( n, b ) {
id = 6;
return this['cmp']( n, b ) < 0;
};
/*
* Return true if the value of this BigNumber is less than or equal to the
* value of BigNumber(n, b), otherwise returns false.
*/
P['lessThanOrEqualTo'] = P['lte'] = function ( n, b ) {
id = 7;
return ( b = this['cmp']( n, b ) ) == -1 || b === 0;
};
/*
* n - 0 = n
* n - N = N
* n - I = -I
* 0 - n = -n
* 0 - 0 = 0
* 0 - N = N
* 0 - I = -I
* N - n = N
* N - 0 = N
* N - N = N
* N - I = N
* I - n = I
* I - 0 = I
* I - N = N
* I - I = N
*
* Return a new BigNumber whose value is the value of this BigNumber minus
* the value of BigNumber(y, b).
*/
P['minus'] = function ( y, b ) {
var d, i, j, xLTy,
x = this,
a = x['s'];
b = ( id = 8, y = new BigNumber( y, b ) )['s'];
// Either NaN?
if ( !a || !b ) {
return new BigNumber(NaN);
}
// Signs differ?
if ( a != b ) {
return y['s'] = -b, x['plus'](y);
}
var xc = x['c'],
xe = x['e'],
yc = y['c'],
ye = y['e'];
if ( !xe || !ye ) {
// Either Infinity?
if ( !xc || !yc ) {
return xc ? ( y['s'] = -b, y ) : new BigNumber( yc ? x : NaN );
}
// Either zero?
if ( !xc[0] || !yc[0] ) {
// y is non-zero?
return yc[0]
? ( y['s'] = -b, y )
// x is non-zero?
: new BigNumber( xc[0]
? x
// Both are zero.
// IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity
: ROUNDING_MODE == 3 ? -0 : 0 );
}
}
// Determine which is the bigger number.
// Prepend zeros to equalise exponents.
if ( xc = xc.slice(), a = xe - ye ) {
d = ( xLTy = a < 0 ) ? ( a = -a, xc ) : ( ye = xe, yc );
for ( d.reverse(), b = a; b--; d.push(0) ) {
}
d.reverse();
} else {
// Exponents equal. Check digit by digit.
j = ( ( xLTy = xc.length < yc.length ) ? xc : yc ).length;
for ( a = b = 0; b < j; b++ ) {
if ( xc[b] != yc[b] ) {
xLTy = xc[b] < yc[b];
break;
}
}
}
// x < y? Point xc to the array of the bigger number.
if ( xLTy ) {
d = xc, xc = yc, yc = d;
y['s'] = -y['s'];
}
/*
* Append zeros to xc if shorter. No need to add zeros to yc if shorter
* as subtraction only needs to start at yc.length.
*/
if ( ( b = -( ( j = xc.length ) - yc.length ) ) > 0 ) {
for ( ; b--; xc[j++] = 0 ) {
}
}
// Subtract yc from xc.
for ( b = yc.length; b > a; ){
if ( xc[--b] < yc[b] ) {
for ( i = b; i && !xc[--i]; xc[i] = 9 ) {
}
--xc[i];
xc[b] += 10;
}
xc[b] -= yc[b];
}
// Remove trailing zeros.
for ( ; xc[--j] == 0; xc.pop() ) {
}
// Remove leading zeros and adjust exponent accordingly.
for ( ; xc[0] == 0; xc.shift(), --ye ) {
}
/*
* No need to check for Infinity as +x - +y != Infinity && -x - -y != Infinity
* when neither x or y are Infinity.
*/
// Underflow?
if ( ye < MIN_EXP || !xc[0] ) {
/*
* Following IEEE 754 (2008) 6.3,
* n - n = +0 but n - n = -0 when rounding towards -Infinity.
*/
if ( !xc[0] ) {
y['s'] = ROUNDING_MODE == 3 ? -1 : 1;
}
// Result is zero.
xc = [ye = 0];
}
return y['c'] = xc, y['e'] = ye, y;
};
/*
* n % 0 = N
* n % N = N
* 0 % n = 0
* -0 % n = -0
* 0 % 0 = N
* 0 % N = N
* N % n = N
* N % 0 = N
* N % N = N
*
* Return a new BigNumber whose value is the value of this BigNumber modulo
* the value of BigNumber(y, b).
*/
P['modulo'] = P['mod'] = function ( y, b ) {
var x = this,
xc = x['c'],
yc = ( id = 9, y = new BigNumber( y, b ) )['c'],
i = x['s'],
j = y['s'];
// Is x or y NaN, or y zero?
b = !i || !j || yc && !yc[0];
if ( b || xc && !xc[0] ) {
return new BigNumber( b ? NaN : x );
}
x['s'] = y['s'] = 1;
b = y['cmp'](x) == 1;
x['s'] = i, y['s'] = j;
return b
? new BigNumber(x)
: ( i = DECIMAL_PLACES, j = ROUNDING_MODE,
DECIMAL_PLACES = 0, ROUNDING_MODE = 1,
x = x['div'](y),
DECIMAL_PLACES = i, ROUNDING_MODE = j,
this['minus']( x['times'](y) ) );
};
/*
* Return a new BigNumber whose value is the value of this BigNumber
* negated, i.e. multiplied by -1.
*/
P['negated'] = P['neg'] = function () {
var x = new BigNumber(this);
return x['s'] = -x['s'] || null, x;
};
/*
* n + 0 = n
* n + N = N
* n + I = I
* 0 + n = n
* 0 + 0 = 0
* 0 + N = N
* 0 + I = I
* N + n = N
* N + 0 = N
* N + N = N
* N + I = N
* I + n = I
* I + 0 = I
* I + N = N
* I + I = I
*
* Return a new BigNumber whose value is the value of this BigNumber plus
* the value of BigNumber(y, b).
*/
P['plus'] = function ( y, b ) {
var d,
x = this,
a = x['s'];
b = ( id = 10, y = new BigNumber( y, b ) )['s'];
// Either NaN?
if ( !a || !b ) {
return new BigNumber(NaN);
}
// Signs differ?
if ( a != b ) {
return y['s'] = -b, x['minus'](y);
}
var xe = x['e'],
xc = x['c'],
ye = y['e'],
yc = y['c'];
if ( !xe || !ye ) {
// Either Infinity?
if ( !xc || !yc ) {
// Return +-Infinity.
return new BigNumber( a / 0 );
}
// Either zero?
if ( !xc[0] || !yc[0] ) {
// y is non-zero?
return yc[0]
? y
// x is non-zero?
: new BigNumber( xc[0]
? x
// Both are zero. Return zero.
: a * 0 );
}
}
// Prepend zeros to equalise exponents.
// Note: Faster to use reverse then do unshifts.
if ( xc = xc.slice(), a = xe - ye ) {
d = a > 0 ? ( ye = xe, yc ) : ( a = -a, xc );
for ( d.reverse(); a--; d.push(0) ) {
}
d.reverse();
}
// Point xc to the longer array.
if ( xc.length - yc.length < 0 ) {
d = yc, yc = xc, xc = d;
}
/*
* Only start adding at yc.length - 1 as the
* further digits of xc can be left as they are.
*/
for ( a = yc.length, b = 0; a;
b = ( xc[--a] = xc[a] + yc[a] + b ) / 10 ^ 0, xc[a] %= 10 ) {
}
// No need to check for zero, as +x + +y != 0 && -x + -y != 0
if ( b ) {
xc.unshift(b);
// Overflow? (MAX_EXP + 1 possible)
if ( ++ye > MAX_EXP ) {
// Infinity.
xc = ye = null;
}
}
// Remove trailing zeros.
for ( a = xc.length; xc[--a] == 0; xc.pop() ) {
}
return y['c'] = xc, y['e'] = ye, y;
};
/*
* Return a BigNumber whose value is the value of this BigNumber raised to
* the power e. If e is negative round according to DECIMAL_PLACES and
* ROUNDING_MODE.
*
* e {number} Integer, -MAX_POWER to MAX_POWER inclusive.
*/
P['toPower'] = P['pow'] = function ( e ) {
// e to integer, avoiding NaN or Infinity becoming 0.
var i = e * 0 == 0 ? e | 0 : e,
x = new BigNumber(this),
y = new BigNumber(ONE);
// Use Math.pow?
// Pass +-Infinity for out of range exponents.
if ( ( ( ( outOfRange = e < -MAX_POWER || e > MAX_POWER ) &&
(i = e * 1 / 0) ) ||
/*
* Any exponent that fails the parse becomes NaN.
*
* Include 'e !== 0' because on Opera -0 == parseFloat(-0) is false,
* despite -0 === parseFloat(-0) && -0 == parseFloat('-0') is true.
*/
parse(e) != e && e !== 0 && !(i = NaN) ) &&
// 'pow() exponent not an integer: {e}'
// 'pow() exponent out of range: {e}'
!ifExceptionsThrow( e, 'exponent', 'pow' ) ||
// Pass zero to Math.pow, as any value to the power zero is 1.
!i ) {
// i is +-Infinity, NaN or 0.
return new BigNumber( Math.pow( x['toS'](), i ) );
}
for ( i = i < 0 ? -i : i; ; ) {
if ( i & 1 ) {
y = y['times'](x);
}
i >>= 1;
if ( !i ) {
break;
}
x = x['times'](x);
}
return e < 0 ? ONE['div'](y) : y;
};
/*
* Return a new BigNumber whose value is the value of this BigNumber
* rounded to a maximum of dp decimal places using rounding mode rm, or to
* 0 and ROUNDING_MODE respectively if omitted.
*
* [dp] {number} Integer, 0 to MAX inclusive.
* [rm] {number} Integer, 0 to 8 inclusive.
*/
P['round'] = function ( dp, rm ) {
dp = dp == null || ( ( ( outOfRange = dp < 0 || dp > MAX ) ||
parse(dp) != dp ) &&
// 'round() decimal places out of range: {dp}'
// 'round() decimal places not an integer: {dp}'
!ifExceptionsThrow( dp, 'decimal places', 'round' ) )
? 0
: dp | 0;
rm = rm == null || ( ( ( outOfRange = rm < 0 || rm > 8 ) ||
// Include '&& rm !== 0' because with Opera -0 == parseFloat(-0) is false.
parse(rm) != rm && rm !== 0 ) &&
// 'round() mode not an integer: {rm}'
// 'round() mode out of range: {rm}'
!ifExceptionsThrow( rm, 'mode', 'round' ) )
? ROUNDING_MODE
: rm | 0;
return setMode( this, dp, rm );
};
/*
* sqrt(-n) = N
* sqrt( N) = N
* sqrt(-I) = N
* sqrt( I) = I
* sqrt( 0) = 0
* sqrt(-0) = -0
*
* Return a new BigNumber whose value is the square root of the value of
* this BigNumber, rounded according to DECIMAL_PLACES and ROUNDING_MODE.
*/
P['squareRoot'] = P['sqrt'] = function () {
var n, r, re, t,
x = this,
c = x['c'],
s = x['s'],
e = x['e'],
dp = DECIMAL_PLACES,
rm = ROUNDING_MODE,
half = new BigNumber('0.5');
// Negative/NaN/Infinity/zero?
if ( s !== 1 || !c || !c[0] ) {
return new BigNumber( !s || s < 0 && ( !c || c[0] )
? NaN
: c ? x : 1 / 0 );
}
// Initial estimate.
s = Math.sqrt( x['toS']() );
ROUNDING_MODE = 1;
/*
Math.sqrt underflow/overflow?
Pass x to Math.sqrt as integer, then adjust the exponent of the result.
*/
if ( s == 0 || s == 1 / 0 ) {
n = c.join('');
if ( !( n.length + e & 1 ) ) {
n += '0';
}
r = new BigNumber( Math.sqrt(n) + '' );
// r may still not be finite.
if ( !r['c'] ) {
r['c'] = [1];
}
r['e'] = ( ( ( e + 1 ) / 2 ) | 0 ) - ( e < 0 || e & 1 );
} else {
r = new BigNumber( n = s.toString() );
}
re = r['e'];
s = re + ( DECIMAL_PLACES += 4 );
if ( s < 3 ) {
s = 0;
}
e = s;
// Newton-Raphson iteration.
for ( ; ; ) {
t = r;
r = half['times']( t['plus']( x['div'](t) ) );
if ( t['c'].slice( 0, s ).join('') === r['c'].slice( 0, s ).join('') ) {
c = r['c'];
/*
The exponent of r may here be one less than the final result
exponent (re), e.g 0.0009999 (e-4) --> 0.001 (e-3), so adjust
s so the rounding digits are indexed correctly.
*/
s = s - ( n && r['e'] < re );
/*
The 4th rounding digit may be in error by -1 so if the 4 rounding
digits are 9999 or 4999 (i.e. approaching a rounding boundary)
continue the iteration.
*/
if ( c[s] == 9 && c[s - 1] == 9 && c[s - 2] == 9 &&
( c[s - 3] == 9 || n && c[s - 3] == 4 ) ) {
/*
If 9999 on first run through, check to see if rounding up
gives the exact result as the nines may infinitely repeat.
*/
if ( n && c[s - 3] == 9 ) {
t = r['round']( dp, 0 );
if ( t['times'](t)['eq'](x) ) {
ROUNDING_MODE = rm;
DECIMAL_PLACES = dp;
return t;
}
}
DECIMAL_PLACES += 4;
s += 4;
n = '';
} else {
/*
If the rounding digits are null, 0000 or 5000, check for an
exact result. If not, then there are further digits so
increment the 1st rounding digit to ensure correct rounding.
*/
if ( !c[e] && !c[e - 1] && !c[e - 2] &&
( !c[e - 3] || c[e - 3] == 5 ) ) {
// Truncate to the first rounding digit.
if ( c.length > e - 2 ) {
c.length = e - 2;
}
if ( !r['times'](r)['eq'](x) ) {
while ( c.length < e - 3 ) {
c.push(0);
}
c[e - 3]++;
}
}
ROUNDING_MODE = rm;
rnd( r, DECIMAL_PLACES = dp, 10 );
return r;
}
}
}
};
/*
* n * 0 = 0
* n * N = N
* n * I = I
* 0 * n = 0
* 0 * 0 = 0
* 0 * N = N
* 0 * I = N
* N * n = N
* N * 0 = N
* N * N = N
* N * I = N
* I * n = I
* I * 0 = N
* I * N = N
* I * I = I
*
* Return a new BigNumber whose value is the value of this BigNumber times
* the value of BigNumber(y, b).
*/
P['times'] = function ( y, b ) {
var c,
x = this,
xc = x['c'],
yc = ( id = 11, y = new BigNumber( y, b ) )['c'],
i = x['e'],
j = y['e'],
a = x['s'];
y['s'] = a == ( b = y['s'] ) ? 1 : -1;
// Either NaN/Infinity/0?
if ( !i && ( !xc || !xc[0] ) || !j && ( !yc || !yc[0] ) ) {
// Either NaN?
return new BigNumber( !a || !b ||
// x is 0 and y is Infinity or y is 0 and x is Infinity?
xc && !xc[0] && !yc || yc && !yc[0] && !xc
// Return NaN.
? NaN
// Either Infinity?
: !xc || !yc
// Return +-Infinity.
? y['s'] / 0
// x or y is 0. Return +-0.
: y['s'] * 0 );
}
y['e'] = i + j;
if ( ( a = xc.length ) < ( b = yc.length ) ) {
c = xc, xc = yc, yc = c, j = a, a = b, b = j;
}
for ( j = a + b, c = []; j--; c.push(0) ) {
}
// Multiply!
for ( i = b - 1; i > -1; i-- ) {
for ( b = 0, j = a + i;
j > i;
b = c[j] + yc[i] * xc[j - i - 1] + b,
c[j--] = b % 10 | 0,
b = b / 10 | 0 ) {
}
if ( b ) {
c[j] = ( c[j] + b ) % 10;
}
}
b && ++y['e'];
// Remove any leading zero.
!c[0] && c.shift();
// Remove trailing zeros.
for ( j = c.length; !c[--j]; c.pop() ) {
}
// No zero check needed as only x * 0 == 0 etc.
// Overflow?
y['c'] = y['e'] > MAX_EXP
// Infinity.
? ( y['e'] = null )
// Underflow?
: y['e'] < MIN_EXP
// Zero.
? [ y['e'] = 0 ]
// Neither.
: c;
return y;
};
/*
* Return a string representing the value of this BigNumber in exponential
* notation to dp fixed decimal places and rounded using ROUNDING_MODE if
* necessary.
*
* [dp] {number} Integer, 0 to MAX inclusive.
*/
P['toExponential'] = P['toE'] = function ( dp ) {
return format( this,
( dp == null || ( ( outOfRange = dp < 0 || dp > MAX ) ||
/*
* Include '&& dp !== 0' because with Opera -0 == parseFloat(-0) is
* false, despite -0 == parseFloat('-0') && 0 == -0 being true.
*/
parse(dp) != dp && dp !== 0 ) &&
// 'toE() decimal places not an integer: {dp}'
// 'toE() decimal places out of range: {dp}'
!ifExceptionsThrow( dp, 'decimal places', 'toE' ) ) && this['c']
? this['c'].length - 1
: dp | 0, 1 );
};
/*
* Return a string representing the value of this BigNumber in normal
* notation to dp fixed decimal places and rounded using ROUNDING_MODE if
* necessary.
*
* Note: as with JavaScript's number type, (-0).toFixed(0) is '0',
* but e.g. (-0.00001).toFixed(0) is '-0'.
*
* [dp] {number} Integer, 0 to MAX inclusive.
*/
P['toFixed'] = P['toF'] = function ( dp ) {
var n, str, d,
x = this;
if ( !( dp == null || ( ( outOfRange = dp < 0 || dp > MAX ) ||
parse(dp) != dp && dp !== 0 ) &&
// 'toF() decimal places not an integer: {dp}'
// 'toF() decimal places out of range: {dp}'
!ifExceptionsThrow( dp, 'decimal places', 'toF' ) ) ) {
d = x['e'] + ( dp | 0 );
}
n = TO_EXP_NEG, dp = TO_EXP_POS;
TO_EXP_NEG = -( TO_EXP_POS = 1 / 0 );
// Note: str is initially undefined.
if ( d == str ) {
str = x['toS']();
} else {
str = format( x, d );
// (-0).toFixed() is '0', but (-0.1).toFixed() is '-0'.
// (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'.
if ( x['s'] < 0 && x['c'] ) {
// As e.g. -0 toFixed(3), will wrongly be returned as -0.000 from toString.
if ( !x['c'][0] ) {
str = str.replace(/^-/, '');
// As e.g. -0.5 if rounded to -0 will cause toString to omit the minus sign.
} else if ( str.indexOf('-') < 0 ) {
str = '-' + str;
}
}
}
TO_EXP_NEG = n, TO_EXP_POS = dp;
return str;
};
/*
* Return a string array representing the value of this BigNumber as a
* simple fraction with an integer numerator and an integer denominator.
* The denominator will be a positive non-zero value less than or equal to
* the specified maximum denominator. If a maximum denominator is not
* specified, the denominator will be the lowest value necessary to
* represent the number exactly.
*
* [maxD] {number|string|BigNumber} Integer >= 1 and < Infinity.
*/
P['toFraction'] = P['toFr'] = function ( maxD ) {
var q, frac, n0, d0, d2, n, e,
n1 = d0 = new BigNumber(ONE),
d1 = n0 = new BigNumber('0'),
x = this,
xc = x['c'],
exp = MAX_EXP,
dp = DECIMAL_PLACES,
rm = ROUNDING_MODE,
d = new BigNumber(ONE);
// NaN, Infinity.
if ( !xc ) {
return x['toS']();
}
e = d['e'] = xc.length - x['e'] - 1;
// If max denominator is undefined or null...
if ( maxD == null ||
// or NaN...
( !( id = 12, n = new BigNumber(maxD) )['s'] ||
// or less than 1, or Infinity...
( outOfRange = n['cmp'](n1) < 0 || !n['c'] ) ||
// or not an integer...
( ERRORS && n['e'] < n['c'].length - 1 ) ) &&
// 'toFr() max denominator not an integer: {maxD}'
// 'toFr() max denominator out of range: {maxD}'
!ifExceptionsThrow( maxD, 'max denominator', 'toFr' ) ||
// or greater than the maxD needed to specify the value exactly...
( maxD = n )['cmp'](d) > 0 ) {
// d is e.g. 10, 100, 1000, 10000... , n1 is 1.
maxD = e > 0 ? d : n1;
}
MAX_EXP = 1 / 0;
n = new BigNumber( xc.join('') );
for ( DECIMAL_PLACES = 0, ROUNDING_MODE = 1; ; ) {
q = n['div'](d);
d2 = d0['plus']( q['times'](d1) );
if ( d2['cmp'](maxD) == 1 ) {
break;
}
d0 = d1, d1 = d2;
n1 = n0['plus']( q['times']( d2 = n1 ) );
n0 = d2;
d = n['minus']( q['times']( d2 = d ) );
n = d2;
}
d2 = maxD['minus'](d0)['div'](d1);
n0 = n0['plus']( d2['times'](n1) );
d0 = d0['plus']( d2['times'](d1) );
n0['s'] = n1['s'] = x['s'];
DECIMAL_PLACES = e * 2;
ROUNDING_MODE = rm;
// Determine which fraction is closer to x, n0 / d0 or n1 / d1?
frac = n1['div'](d1)['minus'](x)['abs']()['cmp'](
n0['div'](d0)['minus'](x)['abs']() ) < 1
? [ n1['toS'](), d1['toS']() ]
: [ n0['toS'](), d0['toS']() ];
return MAX_EXP = exp, DECIMAL_PLACES = dp, frac;
};
/*
* Return a string representing the value of this BigNumber to sd significant
* digits and rounded using ROUNDING_MODE if necessary.
* If sd is less than the number of digits necessary to represent the integer
* part of the value in normal notation, then use exponential notation.
*
* sd {number} Integer, 1 to MAX inclusive.
*/
P['toPrecision'] = P['toP'] = function ( sd ) {
/*
* ERRORS true: Throw if sd not undefined, null or an integer in range.
* ERRORS false: Ignore sd if not a number or not in range.
* Truncate non-integers.
*/
return sd == null || ( ( ( outOfRange = sd < 1 || sd > MAX ) ||
parse(sd) != sd ) &&
// 'toP() precision not an integer: {sd}'
// 'toP() precision out of range: {sd}'
!ifExceptionsThrow( sd, 'precision', 'toP' ) )
? this['toS']()
: format( this, --sd | 0, 2 );
};
/*
* Return a string representing the value of this BigNumber in base b, or
* base 10 if b is omitted. If a base is specified, including base 10,
* round according to DECIMAL_PLACES and ROUNDING_MODE.
* If a base is not specified, and this BigNumber has a positive exponent
* that is equal to or greater than TO_EXP_POS, or a negative exponent equal
* to or less than TO_EXP_NEG, return exponential notation.
*
* [b] {number} Integer, 2 to 64 inclusive.
*/
P['toString'] = P['toS'] = function ( b ) {
var u, str, strL,
x = this,
xe = x['e'];
// Infinity or NaN?
if ( xe === null ) {
str = x['s'] ? 'Infinity' : 'NaN';
// Exponential format?
} else if ( b === u && ( xe <= TO_EXP_NEG || xe >= TO_EXP_POS ) ) {
return format( x, x['c'].length - 1, 1 );
} else {
str = x['c'].join('');
// Negative exponent?
if ( xe < 0 ) {
// Prepend zeros.
for ( ; ++xe; str = '0' + str ) {
}
str = '0.' + str;
// Positive exponent?
} else if ( strL = str.length, xe > 0 ) {
if ( ++xe > strL ) {
// Append zeros.
for ( xe -= strL; xe-- ; str += '0' ) {
}
} else if ( xe < strL ) {
str = str.slice( 0, xe ) + '.' + str.slice(xe);
}
// Exponent zero.
} else {
if ( u = str.charAt(0), strL > 1 ) {
str = u + '.' + str.slice(1);
// Avoid '-0'
} else if ( u == '0' ) {
return u;
}
}
if ( b != null ) {
if ( !( outOfRange = !( b >= 2 && b < 65 ) ) &&
( b == (b | 0) || !ERRORS ) ) {
str = convert( str, b | 0, 10, x['s'] );
// Avoid '-0'
if ( str == '0' ) {
return str;
}
} else {
// 'toS() base not an integer: {b}'
// 'toS() base out of range: {b}'
ifExceptionsThrow( b, 'base', 'toS' );
}
}
}
return x['s'] < 0 ? '-' + str : str;
};
/*
* Return the value of this BigNumber converted to a number primitive.
*
*/
P['toNumber'] = P['toN'] = function () {
var x = this;
// Ensure zero has correct sign.
return +x || ( x['s'] ? 0 * x['s'] : NaN );
};
/*
* Return as toString, but do not accept a base argument.
*/
P['valueOf'] = function () {
return this['toS']();
};
// Add aliases for BigDecimal methods.
//P['add'] = P['plus'];
//P['subtract'] = P['minus'];
//P['multiply'] = P['times'];
//P['divide'] = P['div'];
//P['remainder'] = P['mod'];
//P['compareTo'] = P['cmp'];
//P['negate'] = P['neg'];
// EXPORT
// Node and other CommonJS-like environments that support module.exports.
if ( typeof module !== 'undefined' && module.exports ) {
module.exports = BigNumber;
//AMD.
} else if ( typeof define == 'function' && define.amd ) {
define( function () {
return BigNumber;
});
//Browser.
} else {
global['BigNumber'] = BigNumber;
}
})( this );
/*! bignumber.js v1.4.0 https://github.com/MikeMcl/bignumber.js/LICENCE */
(function(n){"use strict";function t(n,i){var c,l,a,b,w,p,s=this;if(!(s instanceof t))return new t(n,i);if(n instanceof t)if(u=0,i!==c)n+="";else{s.s=n.s;s.e=n.e;s.c=(n=n.c)?n.slice():n;return}if(typeof n!="string"&&(n=(a=typeof n=="number"||Object.prototype.toString.call(n)=="[object Number]")&&n===0&&1/n<0?"-0":n+""),p=n,i===c&&g.test(n))s.s=n.charAt(0)=="-"?(n=n.slice(1),-1):1;else{if(i==10)return k(n,e,r);if(n=rt.call(n).replace(/^\+(?!-)/,""),s.s=n.charAt(0)=="-"?(n=n.replace(/^-(?!-)/,""),-1):1,i!=null?i!=(i|0)&&y||(o=!(i>=2&&i<65))?(f(i,2),w=g.test(n)):(b="["+d.slice(0,i=i|0)+"]+",n=n.replace(/\.$/,"").replace(/^\./,"0."),(w=new RegExp("^"+b+"(?:\\."+b+")?$",i<37?"i":"").test(n))?(a&&(n.replace(/^0\.0*|\./,"").length>15&&f(p,0),a=!a),n=tt(n,10,i,s.s)):n!="Infinity"&&n!="NaN"&&(f(p,1,i),n="NaN")):w=g.test(n),!w){s.c=s.e=null;n!="Infinity"&&(n!="NaN"&&f(p,3),s.s=null);u=0;return}}for((c=n.indexOf("."))>-1&&(n=n.replace(".","")),(l=n.search(/e/i))>0?(c<0&&(c=l),c+=+n.slice(l+1),n=n.substring(0,l)):c<0&&(c=n.length),l=0;n.charAt(l)=="0";l++);if(i=n.length,a&&i>15&&n.slice(l).length>15&&f(p,0),u=0,(c-=l+1)>h)s.c=s.e=null;else if(l==i||c<v)s.c=[s.e=0];else{for(;n.charAt(--i)=="0";);for(s.e=c,s.c=[],c=0;l<=i;s.c[c++]=+n.charAt(l++));}}function f(n,t,i,r,f,e){if(y){var c,s=["new BigNumber","cmp","div","eq","gt","gte","lt","lte","minus","mod","plus","times","toFr"][u?u<0?-u:u:1/u<0?1:0]+"()",h=o?" out of range":" not a"+(f?" non-zero":"n")+" integer";h=([s+" number type has more than 15 significant digits",s+" not a base "+i+" number",s+" base"+h,s+" not a number"][t]||i+"() "+t+(e?" not a boolean or binary digit":h+(r?" or not ["+(o?" negative, positive":" integer, integer")+" ]":"")))+": "+n;o=u=0;c=new Error(h);c.name="BigNumber Error";throw c;}}function tt(n,i,r,u){function h(n,t){var u,e=0,s=n.length,o,f=[0];for(t=t||r;e<s;e++){for(o=f.length,u=0;u<o;f[u]*=t,u++);for(f[0]+=d.indexOf(n.charAt(e)),u=0;u<f.length;u++)f[u]>i-1&&(f[u+1]==null&&(f[u+1]=0),f[u+1]+=f[u]/i^0,f[u]%=i)}return f.reverse()}function o(n){for(var t=0,r=n.length,i="";t<r;i+=d.charAt(n[t++]));return i}var e,c,l,f,s,a;if(r<37&&(n=n.toLowerCase()),(e=n.indexOf("."))>-1)if(e=n.length-e-1,c=h(new t(r).pow(e).toF(),10),f=n.split("."),l=h(f[1]),f=h(f[0]),a=it(l,c,l.length-c.length,u,i,f[f.length-1]&1),s=a.c,e=a.e){for(;++e;s.unshift(0));n=o(f)+"."+o(s)}else s[0]?f[e=f.length-1]<i-1?(++f[e],n=o(f)):n=new t(o(f),i).plus(p).toS(i):n=o(f);else n=o(h(n));return n}function it(n,i,r,u,f,o){var y,d,k,w,a,rt=i.slice(),g=y=i.length,ut=n.length,s=n.slice(0,y),c=s.length,l=new t(p),nt=l.c=[],tt=0,it=e+(l.e=r)+1;for(l.s=u,u=it<0?0:it;c++<y;s.push(0));rt.unshift(0);do{for(k=0;k<f;k++){if(y!=(c=s.length))w=y>c?1:-1;else for(a=-1,w=0;++a<y;)if(i[a]!=s[a]){w=i[a]>s[a]?1:-1;break}if(w<0){for(d=c==y?i:rt;c;){if(s[--c]<d[c]){for(a=c;a&&!s[--a];s[a]=f-1);--s[a];s[c]+=f}s[c]-=d[c]}for(;!s[0];s.shift());}else break}nt[tt++]=w?k:++k;s[0]&&w?s[c]=n[g]||0:s=[n[g]]}while((g++<ut||s[0]!=null)&&u--);return nt[0]||tt==1||(--l.e,nt.shift()),tt>it&&b(l,e,f,o,s[0]!=null),l.e>h?l.c=l.e=null:l.e<v&&(l.c=[l.e=0]),l}function w(n,i,r){var u=i-(n=new t(n)).e,f=n.c;if(!f)return n.toS();for(f.length>++i&&b(n,u,10),u=f[0]==0?u+1:r?i:n.e+u+1;f.length<u;f.push(0));return u=n.e,r==1||r==2&&(--i<u||u<=c)?(n.s<0&&f[0]?"-":"")+(f.length>1?(f.splice(1,0,"."),f.join("")):f[0])+(u<0?"e":"e+")+u:n.toS()}function b(n,t,i,u,f){var e=n.c,s=n.s<0,c=i/2,o=n.e+t+1,h=e[o],l=f||o<0||e[o+1]!=null;if(f=r<4?(h!=null||l)&&(r==0||r==2&&!s||r==3&&s):h>c||h==c&&(r==4||l||r==6&&(e[o-1]&1||!t&&u)||r==7&&!s||r==8&&s),o<1||!e[0])return e.length=0,e.push(0),f?(e[0]=1,n.e=-t):n.e=0,n;if(e.length=o--,f)for(--i;++e[o]>i;)e[o]=0,o--||(++n.e,e.unshift(1));for(o=e.length;!e[--o];e.pop());return n}function k(n,i,u){var f=r;return r=u,n=new t(n),n.c&&b(n,i,10),r=f,n}var s=1e9,nt=1e6,e=20,r=4,c=-7,a=21,v=-s,h=s,y=!0,l=parseInt,i=t.prototype,d="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_",o,u=0,g=/^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,rt=String.prototype.trim||function(){return this.replace(/^\s+|\s+$/g,"")},p=t(1);t.ROUND_UP=0;t.ROUND_DOWN=1;t.ROUND_CEIL=2;t.ROUND_FLOOR=3;t.ROUND_HALF_UP=4;t.ROUND_HALF_DOWN=5;t.ROUND_HALF_EVEN=6;t.ROUND_HALF_CEIL=7;t.ROUND_HALF_FLOOR=8;t.config=function(){var n,t,g=0,p={},d=arguments,k=d[0],w="config",i=function(n,t,i){return!((o=n<t||n>i)||l(n)!=n&&n!==0)},b=k&&typeof k=="object"?function(){if(k.hasOwnProperty(t))return(n=k[t])!=null}:function(){if(d.length>g)return(n=d[g++])!=null};return b(t="DECIMAL_PLACES")&&(i(n,0,s)?e=n|0:f(n,t,w)),p[t]=e,b(t="ROUNDING_MODE")&&(i(n,0,8)?r=n|0:f(n,t,w)),p[t]=r,b(t="EXPONENTIAL_AT")&&(i(n,-s,s)?c=-(a=~~(n<0?-n:+n)):!o&&n&&i(n[0],-s,0)&&i(n[1],0,s)?(c=~~n[0],a=~~n[1]):f(n,t,w,1)),p[t]=[c,a],b(t="RANGE")&&(i(n,-s,s)&&~~n?v=-(h=~~(n<0?-n:+n)):!o&&n&&i(n[0],-s,-1)&&i(n[1],1,s)?(v=~~n[0],h=~~n[1]):f(n,t,w,1,1)),p[t]=[v,h],b(t="ERRORS")&&(n===!!n||n===1||n===0?l=(o=u=0,y=!!n)?parseInt:parseFloat:f(n,t,w,0,0,1)),p[t]=y,p};i.abs=i.absoluteValue=function(){var n=new t(this);return n.s<0&&(n.s=1),n};i.ceil=function(){return k(this,0,2)};i.comparedTo=i.cmp=function(n,i){var f,l=this,e=l.c,o=(u=-u,n=new t(n,i)).c,r=l.s,c=n.s,s=l.e,h=n.e;if(!r||!c)return null;if(f=e&&!e[0],i=o&&!o[0],f||i)return f?i?0:-c:r;if(r!=c)return r;if(f=r<0,i=s==h,!e||!o)return i?0:!e^f?1:-1;if(!i)return s>h^f?1:-1;for(r=-1,c=(s=e.length)<(h=o.length)?s:h;++r<c;)if(e[r]!=o[r])return e[r]>o[r]^f?1:-1;return s==h?0:s>h^f?1:-1};i.dividedBy=i.div=function(n,i){var r=this.c,o=this.e,s=this.s,f=(u=2,n=new t(n,i)).c,h=n.e,c=n.s,e=s==c?1:-1;return!o&&(!r||!r[0])||!h&&(!f||!f[0])?new t(!s||!c||(r?f&&r[0]==f[0]:!f)?NaN:r&&r[0]==0||!f?e*0:e/0):it(r,f,o-h,e,10)};i.equals=i.eq=function(n,t){return u=3,this.cmp(n,t)===0};i.floor=function(){return k(this,0,3)};i.greaterThan=i.gt=function(n,t){return u=4,this.cmp(n,t)>0};i.greaterThanOrEqualTo=i.gte=function(n,t){return u=5,(t=this.cmp(n,t))==1||t===0};i.isFinite=i.isF=function(){return!!this.c};i.isNaN=function(){return!this.s};i.isNegative=i.isNeg=function(){return this.s<0};i.isZero=i.isZ=function(){return!!this.c&&this.c[0]==0};i.lessThan=i.lt=function(n,t){return u=6,this.cmp(n,t)<0};i.lessThanOrEqualTo=i.lte=function(n,t){return u=7,(t=this.cmp(n,t))==-1||t===0};i.minus=function(n,i){var h,l,a,y,c=this,o=c.s;if(i=(u=8,n=new t(n,i)).s,!o||!i)return new t(NaN);if(o!=i)return n.s=-i,c.plus(n);var f=c.c,p=c.e,e=n.c,s=n.e;if(!p||!s){if(!f||!e)return f?(n.s=-i,n):new t(e?c:NaN);if(!f[0]||!e[0])return e[0]?(n.s=-i,n):new t(f[0]?c:r==3?-0:0)}if(f=f.slice(),o=p-s){for(h=(y=o<0)?(o=-o,f):(s=p,e),h.reverse(),i=o;i--;h.push(0));h.reverse()}else for(a=((y=f.length<e.length)?f:e).length,o=i=0;i<a;i++)if(f[i]!=e[i]){y=f[i]<e[i];break}if(y&&(h=f,f=e,e=h,n.s=-n.s),(i=-((a=f.length)-e.length))>0)for(;i--;f[a++]=0);for(i=e.length;i>o;){if(f[--i]<e[i]){for(l=i;l&&!f[--l];f[l]=9);--f[l];f[i]+=10}f[i]-=e[i]}for(;f[--a]==0;f.pop());for(;f[0]==0;f.shift(),--s);return(s<v||!f[0])&&(f[0]||(n.s=r==3?-1:1),f=[s=0]),n.c=f,n.e=s,n};i.modulo=i.mod=function(n,i){var f=this,h=f.c,c=(u=9,n=new t(n,i)).c,o=f.s,s=n.s;return(i=!o||!s||c&&!c[0],i||h&&!h[0])?new t(i?NaN:f):(f.s=n.s=1,i=n.cmp(f)==1,f.s=o,n.s=s,i?new t(f):(o=e,s=r,e=0,r=1,f=f.div(n),e=o,r=s,this.minus(f.times(n))))};i.negated=i.neg=function(){var n=new t(this);return n.s=-n.s||null,n};i.plus=function(n,i){var o,c=this,f=c.s;if(i=(u=10,n=new t(n,i)).s,!f||!i)return new t(NaN);if(f!=i)return n.s=-i,c.minus(n);var l=c.e,r=c.c,s=n.e,e=n.c;if(!l||!s){if(!r||!e)return new t(f/0);if(!r[0]||!e[0])return e[0]?n:new t(r[0]?c:f*0)}if(r=r.slice(),f=l-s){for(o=f>0?(s=l,e):(f=-f,r),o.reverse();f--;o.push(0));o.reverse()}for(r.length-e.length<0&&(o=e,e=r,r=o),f=e.length,i=0;f;i=(r[--f]=r[f]+e[f]+i)/10^0,r[f]%=10);for(i&&(r.unshift(i),++s>h&&(r=s=null)),f=r.length;r[--f]==0;r.pop());return n.c=r,n.e=s,n};i.toPower=i.pow=function(n){var i=n*0==0?n|0:n,r=new t(this),u=new t(p);if(((o=n<-nt||n>nt)&&(i=n/0)||l(n)!=n&&n!==0&&!(i=NaN))&&!f(n,"exponent","pow")||!i)return new t(Math.pow(r.toS(),i));for(i=i<0?-i:i;;){if(i&1&&(u=u.times(r)),i>>=1,!i)break;r=r.times(r)}return n<0?p.div(u):u};i.round=function(n,t){return n=n==null||((o=n<0||n>s)||l(n)!=n)&&!f(n,"decimal places","round")?0:n|0,t=t==null||((o=t<0||t>8)||l(t)!=t&&t!==0)&&!f(t,"mode","round")?r:t|0,k(this,n,t)};i.squareRoot=i.sqrt=function(){var o,u,c,s,h=this,n=h.c,i=h.s,f=h.e,l=e,a=r,v=new t("0.5");if(i!==1||!n||!n[0])return new t(!i||i<0&&(!n||n[0])?NaN:n?h:1/0);for(i=Math.sqrt(h.toS()),r=1,i==0||i==1/0?(o=n.join(""),o.length+f&1||(o+="0"),u=new t(Math.sqrt(o)+""),u.c||(u.c=[1]),u.e=((f+1)/2|0)-(f<0||f&1)):u=new t(o=i.toString()),c=u.e,i=c+(e+=4),i<3&&(i=0),f=i;;)if(s=u,u=v.times(s.plus(h.div(s))),s.c.slice(0,i).join("")===u.c.slice(0,i).join(""))if(n=u.c,i=i-(o&&u.e<c),n[i]==9&&n[i-1]==9&&n[i-2]==9&&(n[i-3]==9||o&&n[i-3]==4)){if(o&&n[i-3]==9&&(s=u.round(l,0),s.times(s).eq(h)))return r=a,e=l,s;e+=4;i+=4;o=""}else{if(!n[f]&&!n[f-1]&&!n[f-2]&&(!n[f-3]||n[f-3]==5)&&(n.length>f-2&&(n.length=f-2),!u.times(u).eq(h))){while(n.length<f-3)n.push(0);n[f-3]++}return r=a,b(u,e=l,10),u}};i.times=function(n,i){var f,l=this,e=l.c,o=(u=11,n=new t(n,i)).c,s=l.e,r=n.e,c=l.s;if(n.s=c==(i=n.s)?1:-1,!s&&(!e||!e[0])||!r&&(!o||!o[0]))return new t(!c||!i||e&&!e[0]&&!o||o&&!o[0]&&!e?NaN:!e||!o?n.s/0:n.s*0);for(n.e=s+r,(c=e.length)<(i=o.length)&&(f=e,e=o,o=f,r=c,c=i,i=r),r=c+i,f=[];r--;f.push(0));for(s=i-1;s>-1;s--){for(i=0,r=c+s;r>s;i=f[r]+o[s]*e[r-s-1]+i,f[r--]=i%10|0,i=i/10|0);i&&(f[r]=(f[r]+i)%10)}for(i&&++n.e,f[0]||f.shift(),r=f.length;!f[--r];f.pop());return n.c=n.e>h?n.e=null:n.e<v?[n.e=0]:f,n};i.toExponential=i.toE=function(n){return w(this,(n==null||((o=n<0||n>s)||l(n)!=n&&n!==0)&&!f(n,"decimal places","toE"))&&this.c?this.c.length-1:n|0,1)};i.toFixed=i.toF=function(n){var u,t,r,i=this;return n==null||((o=n<0||n>s)||l(n)!=n&&n!==0)&&!f(n,"decimal places","toF")||(r=i.e+(n|0)),u=c,n=a,c=-(a=1/0),r==t?t=i.toS():(t=w(i,r),i.s<0&&i.c&&(i.c[0]?t.indexOf("-")<0&&(t="-"+t):t=t.replace(/^-/,""))),c=u,a=n,t};i.toFraction=i.toFr=function(n){var k,nt,c,l,i,s,d,a=l=new t(p),v=c=new t("0"),w=this,g=w.c,tt=h,it=e,rt=r,b=new t(p);if(!g)return w.toS();for(d=b.e=g.length-w.e-1,(n==null||(!(u=12,s=new t(n)).s||(o=s.cmp(a)<0||!s.c)||y&&s.e<s.c.length-1)&&!f(n,"max denominator","toFr")||(n=s).cmp(b)>0)&&(n=d>0?b:a),h=1/0,s=new t(g.join("")),e=0,r=1;;){if(k=s.div(b),i=l.plus(k.times(v)),i.cmp(n)==1)break;l=v;v=i;a=c.plus(k.times(i=a));c=i;b=s.minus(k.times(i=b));s=i}return i=n.minus(l).div(v),c=c.plus(i.times(a)),l=l.plus(i.times(v)),c.s=a.s=w.s,e=d*2,r=rt,nt=a.div(v).minus(w).abs().cmp(c.div(l).minus(w).abs())<1?[a.toS(),v.toS()]:[c.toS(),l.toS()],h=tt,e=it,nt};i.toPrecision=i.toP=function(n){return n==null||((o=n<1||n>s)||l(n)!=n)&&!f(n,"precision","toP")?this.toS():w(this,--n|0,2)};i.toString=i.toS=function(n){var u,t,e,r=this,i=r.e;if(i===null)t=r.s?"Infinity":"NaN";else{if(n===u&&(i<=c||i>=a))return w(r,r.c.length-1,1);if(t=r.c.join(""),i<0){for(;++i;t="0"+t);t="0."+t}else if(e=t.length,i>0)if(++i>e)for(i-=e;i--;t+="0");else i<e&&(t=t.slice(0,i)+"."+t.slice(i));else if(u=t.charAt(0),e>1)t=u+"."+t.slice(1);else if(u=="0")return u;if(n!=null)if((o=!(n>=2&&n<65))||n!=(n|0)&&y)f(n,"base","toS");else if(t=tt(t,n|0,10,r.s),t=="0")return t}return r.s<0?"-"+t:t};i.toNumber=i.toN=function(){var n=this;return+n||(n.s?0*n.s:NaN)};i.valueOf=function(){return this.toS()};typeof module!="undefined"&&module.exports?module.exports=t:typeof define=="function"&&define.amd?define(function(){return t}):n.BigNumber=t})(this)
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="Author" content="M Mclaughlin">
<title>bignumber.js API</title>
<style>
html{font-family:sans-serif;font-size:100%}
body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;
line-height:1.65em;background:#fefff5;color:#000;min-height:100%;margin:0}
.nav{background:#fff;position:fixed;top:0;bottom:0;left:0;width:180px;
overflow-y:auto;padding:15px 0 30px 20px}
div.container{width:600px;margin:50px 0 50px 240px}
p{margin:0 0 1em;width:600px}
pre,ul{margin:1em 0}
h1,h2,h3,h4,h5{margin:0;padding:1.5em 0 0}
h1,h2{padding:.75em 0}
h1{font-size:2.5em;color:#fa6900}
h2{font-size:2.25em;color:#fa6900}
h3{font-size:1.75em;color:#69d2e7}
h4{font-size:1.75em;color:#fa6900;padding-bottom:.75em}
h5{font-size:1.2em;padding-bottom:.3em}
h6{font-size:1.1em;margin:0;padding:0.5em 0}
dd dt{font-size:1.2em}
dt{padding-top:.5em}
dd{padding-top:.35em}
b{font-weight:700}
a,a:visited{color:#444;text-decoration:none}
a:active,a:hover{outline:0;color:#000}
.nav a:hover{text-decoration:underline}
.nav a,.nav b,.nav a:visited{display:block;color:#fa6900;font-weight:700;
margin-top:15px}
.nav b{color:#69d2e7;margin-top:20px;cursor:default;width:auto}
ul{list-style-type:none;padding:0 0 0 20px}
.nav ul{line-height:14px;padding-left:0;margin:5px 0 0}
.nav ul a,.nav ul a:visited{display:inline;color:#000;font-family:Verdana,
Geneva,sans-serif;font-size:11px;font-weight:400;margin:0}
.inset,ul.inset{margin-left:20px}
code.inset{font-size:.9em}
.nav li{cursor:pointer;width:auto;margin:0 0 3px}
span.alias{font-style:italic;margin-left:20px}
table{border-collapse:collapse;border-spacing:0;border:2px solid #a7dbd8;
margin:1.75em 0;padding:0}
td,th{text-align:left;margin:0;padding:2px 5px;border:1px dotted #a7dbd8}
th{border-top:2px solid #a7dbd8;border-bottom:2px solid #a7dbd8;color:#f38630}
pre{background:#fff;white-space:pre-wrap;word-wrap:break-word;
border-left:5px solid #a7dbd8;padding:1px 0 1px 15px;margin:1.2em 0}
code,pre{font-family:Monaco,Consolas,"Lucida Console",monospace;
font-weight:400}
.end{margin-bottom:25px}
.nav-title{color:#fa6900}
.centre{text-align:center}
.error-table{font-size:13px;width:100%}
</style>
</head>
<body>
<div class="nav">
<a class='nav-title' href="#">bignumber.js</a>
<b> CONSTRUCTOR </b>
<ul>
<li><a href="#bignumber">BigNumber</a></li>
</ul>
<a href="#methods">Methods</a>
<ul>
<li><a href="#config">config</a></li>
<li>
<ul class="inset">
<li><a href="#decimal-places">DECIMAL_PLACES</a></li>
<li><a href="#rounding-mode" >ROUNDING_MODE</a></li>
<li><a href="#exponential-at">EXPONENTIAL_AT</a></li>
<li><a href="#range" >RANGE</a></li>
<li><a href="#errors" >ERRORS</a></li>
</ul>
</li>
</ul>
<a href="#constructor-properties">Properties</a>
<ul>
<li><a href="#round-up" >ROUND_UP</a></li>
<li><a href="#round-down" >ROUND_DOWN</a></li>
<li><a href="#round-ceil" >ROUND_CEIL</a></li>
<li><a href="#round-floor" >ROUND_FLOOR</a></li>
<li><a href="#round-half-up" >ROUND_HALF_UP</a></li>
<li><a href="#round-half-down" >ROUND_HALF_DOWN</a></li>
<li><a href="#round-half-even" >ROUND_HALF_EVEN</a></li>
<li><a href="#round-half-ceil" >ROUND_HALF_CEIL</a></li>
<li><a href="#round-half-floor">ROUND_HALF_FLOOR</a></li>
</ul>
<b> INSTANCE </b>
<a href="#prototype-methods">Methods</a>
<ul>
<li><a href="#abs" >absoluteValue</a></li>
<li><a href="#ceil" >ceil</a></li>
<li><a href="#floor" >floor</a></li>
<li><a href="#neg" >negated</a></li>
<li><a href="#sqrt" >squareRoot</a></li>
<li><a href="#isF" >isFinite</a></li>
<li><a href="#isNaN" >isNaN</a></li>
<li><a href="#isNeg" >isNegative</a></li>
<li><a href="#isZ" >isZero</a></li>
<li><a href="#cmp" >comparedTo</a></li>
<li><a href="#div" >dividedBy</a></li>
<li><a href="#minus" >minus</a></li>
<li><a href="#mod" >modulo</a></li>
<li><a href="#plus" >plus</a></li>
<li><a href="#times" >times</a></li>
<li><a href="#pow" >toPower</a></li>
<li><a href="#eq" >equals</a></li>
<li><a href="#gt" >greaterThan</a></li>
<li><a href="#gte" >greaterThanOrEqualTo</a></li>
<li><a href="#lt" >lessThan</a></li>
<li><a href="#lte" >lessThanOrEqualTo</a></li>
<li><a href="#toE" >toExponential</a></li>
<li><a href="#toF" >toFixed</a></li>
<li><a href="#toN" >toNumber</a></li>
<li><a href="#toP" >toPrecision</a></li>
<li><a href="#toS" >toString</a></li>
<li><a href="#valueOf">valueOf</a></li>
<li><a href="#toFr" >toFraction</a></li>
<li><a href="#round" >round</a></li>
</ul>
<a href="#instance-properties">Properties</a>
<ul>
<li><a href="#coefficient">c : coefficient</a></li>
<li><a href="#exponent" >e : exponent</a></li>
<li><a href="#sign" >s : sign</a></li>
</ul>
<a href="#zero-nan-infinity">Zero, NaN &amp; Infinity</a>
<a href="#Errors">Errors</a>
<a class='end' href="#faq">FAQ</a>
</div>
<div class="container">
<h1>bignumber.js</h1>
<p>A JavaScript library for arbitrary-precision arithmetic.</p>
<p>
<a href="https://github.com/MikeMcl/bignumber.js">Hosted on GitHub</a>.
</p>
<h2>API</h2>
<p>
In all examples below, <code>var</code> and semicolons are not shown, and
if a commented-out value is in quotes it means <code>toString</code> has
been called on the preceding expression.
</p>
<h3>CONSTRUCTOR</h3>
<h5 id="bignumber">
BigNumber<code class='inset'>BigNumber(value [, base]) &rArr;
<i>BigNumber</i>
</code>
</h5>
<dl>
<dt><code>value</code></dt>
<dd>
<i>number|string|BigNumber</i> : See <a href='#range'>RANGE</a> for
range.
</dd>
<dd>
A numeric value.
</dd>
<dd>
Legitimate values include <code>&plusmn;0</code>,
<code>&plusmn;Infinity</code> and <code>NaN</code>.
</dd>
<dd>
Values of type <em>number</em> with more than 15 significant digits are
considered invalid as calling <code>toString</code> or
<code>valueOf</code> on such numbers may not result in the intended
value.
</dd>
<dd>
There is no limit to the number of digits of a value of type
<em>string</em> (other than that of JavaScript's maximum array size).
</dd>
<dd>
Decimal string values may be in exponential, as well as normal
(non-exponential) notation. Non-decimal values must be in normal
notation.
</dd>
<dd>
String values in hexadecimal literal form, e.g. <code>'0xff'</code>, are
invalid, and string values in octal literal form will be interpreted as
decimals, e.g. <code>'011'</code> is interpreted as 11, not 9.
</dd>
<dd>Values in any base may have fraction digits.</dd>
<dd>
For bases from 10 to 36, lower and/or upper case letters can be used to
represent values from 10 to 35. For bases above 36, <code>a-z</code>
represents values from 10 to 35, <code>A-Z</code> from 36 to 61, and
<code>$</code> and <code>_</code> represent 62 and 63 respectively <i>
(this can be changed by ediiting the DIGITS variable near the top of the
source file).</i>
</dd>
</dl>
<dl>
<dt><code>base</code></dt>
<dd>
<i>number</i> : integer, <code>2</code> to <code>64</code> inclusive
</dd>
<dd>The base of <code>value</code>.</dd>
<dd>If <code>base</code> is omitted, or is <code>null</code> or undefined,
base 10 is assumed.</dd>
</dl>
<p>Returns a new instance of a BigNumber object.</p>
<p>
If a base is specified, the value is rounded according to
the current <a href='#decimal-places'><code>DECIMAL_PLACES</code></a> and
<a href='#rounding-mode'><code>ROUNDING_MODE</code></a> settings.
Usefully, this means the decimal places of a decimal value
passed to the constructor can be limited by explicitly specifying base 10.
</p>
<p>
See <a href='#Errors'>Errors</a> for the treatment of an invalid
<code>value</code> or <code>base</code>.
</p>
<pre>
x = new BigNumber(9) // '9'
y = new BigNumber(x) // '9'
BigNumber(435.345) // 'new' is optional
new BigNumber('5032485723458348569331745.33434346346912144534543')
new BigNumber('4.321e+4') // '43210'
new BigNumber('-735.0918e-430') // '-7.350918e-428'
new BigNumber(Infinity) // 'Infinity'
new BigNumber(NaN) // 'NaN'
new BigNumber('.5') // '0.5'
new BigNumber('+2') // '2'
new BigNumber(-10110100.1, 2) // '-180.5'
new BigNumber('123412421.234324', 5) // '607236.557696'
new BigNumber('ff.8', 16) // '255.5'
new BigNumber(9, 2)
// Throws 'not a base 2 number' if ERRORS is true, otherwise 'NaN'
new BigNumber(96517860459076817.4395)
// Throws 'number type has more than 15 significant digits'
// if ERRORS is true, otherwise '96517860459076820'
new BigNumber('blurgh')
// Throws 'not a number' if ERRORS is true, otherwise 'NaN'
BigNumber.config({DECIMAL_PLACES : 5})
new BigNumber(1.23456789) // '1.23456789'
new BigNumber(1.23456789, 10) // '1.23457'</pre>
<h4 id="methods">Methods</h4>
<p>
The <code>BigNumber</code> constructor has one added method,
<code>config</code>, which configures the library-wide settings for
arithmetic, formatting and errors.
</p>
<h5 id="config">
config<code class='inset'>config([settings]) &rArr; <i>object</i></code>
</h5>
<i>
Note: the settings can also be supplied as an argument list,
see below.
</i>
<dl>
<dt><code>settings</code></dt>
<dd><i>object</i></dd>
<dd>
An object that contains some or all of the following properties:
<dl>
<dt id="decimal-places"><code><b>DECIMAL_PLACES</b></code></dt>
<dd>
<i>number</i> : integer, <code>0</code> to <code>1e+9</code>
inclusive<br />
Default value: <code>20</code>
</dd>
<dd>
The <u>maximum</u> number of decimal places of the results of
division, square root and base conversion operations, and power
operations with negative exponents.<br />
I.e. aside from the base conversion which may be involved with any
method that accepts a base argument, the value is only relevant to
the <code>dividedBy</code>, <code>squareRoot</code> and
<code>toPower</code> methods.
</dd>
<dd>
<pre>BigNumber.config({ DECIMAL_PLACES : 5 })
BigNumber.config(5) // equivalent</pre>
</dd>
<dt id="rounding-mode"><code><b>ROUNDING_MODE</b></code></dt>
<dd>
<i>number</i> : integer, <code>0</code> to <code>8</code>
inclusive<br />
Default value: <code>4</code>
<a href="#h-up">(<code>ROUND_HALF_UP</code>)</a>
</dd>
<dd>
The rounding mode used in the above operations and by
<a href='#round'><code>round</code></a>,
<a href='#toE'><code>toExponential</code></a>,
<a href='#toF'><code>toFixed</code></a> and
<a href='#toP'><code>toPrecision</code></a>.
</dd>
<dd>
The modes are available as enumerated properties of the BigNumber
constructor.
</dd>
<dd>
<pre>BigNumber.config({ ROUNDING_MODE : 0 })
BigNumber.config(null, BigNumber.ROUND_UP) // equivalent</pre>
</dd>
<dt id="exponential-at"><code><b>EXPONENTIAL_AT</b></code></dt>
<dd>
<i>number</i> : integer, magnitude <code>0</code> to
<code>1e+9</code> inclusive, or<br />
<i>number</i>[] : [ integer -1e+9 to 0 inclusive, integer 0 to 1e+9
inclusive ]<br />
Default value: <code>[-7, 20]</code>
</dd>
<dd>
The exponent value(s) at which <code>toString</code> returns
exponential notation.
</dd>
<dd>
If a single number is assigned, the value is the exponent magnitude.
<br />
If an array of two numbers is assigned then the first number is the
negative exponent value at and beneath which exponential notation is
used, and the second number is the positive exponent value at and
above which the same.
</dd>
<dd>
For example, to emulate JavaScript numbers in terms of the exponent
values at which they begin to use exponential notation, use
<code>[-7, 20]</code>.
</dd>
<dd>
<pre>BigNumber.config({ EXPONENTIAL_AT : 2 })
new BigNumber(12.3) // '12.3' e is only 1
new BigNumber(123) // '1.23e+2'
new BigNumber(0.123) // '0.123' e is only -1
new BigNumber(0.0123) // '1.23e-2'
BigNumber.config({ EXPONENTIAL_AT : [-7, 20] })
new BigNumber(123456789) // '123456789' e is only 8
new BigNumber(0.000000123) // '1.23e-7'
// Almost never return exponential notation:
BigNumber.config({ EXPONENTIAL_AT : 1e+9 })
// Always return exponential notation:
BigNumber.config({ EXPONENTIAL_AT : 0 })</pre>
</dd>
<dd>
Regardless of the value of <code>EXPONENTIAL_AT</code>, the
<code>toFixed</code> method will always return a value in
normal notation and the <code>toExponential</code> method will
always return a value in exponential form.
</dd>
<dd>
Calling <code>toString</code> with a base argument, e.g.
<code>toString(10)</code>, will also always return normal notation.
</dd>
<dt id="range"><code><b>RANGE</b></code></dt>
<dd>
<i>number</i> : integer, magnitude <code>1</code> to
<code>1e+9</code> inclusive, or<br />
<i>number</i>[] : [ integer -1e+9 to -1 inclusive, integer 1 to 1e+9
inclusive ]<br />
Default value: <code>[-1e+9, 1e+9]</code>
</dd>
<dd>
The exponent value(s) beyond which overflow to Infinity and
underflow to zero occurs.
</dd>
<dd>
If a single number is assigned, it is the maximum exponent
magnitude: values wth a positive exponent of greater magnitude
become Infinity and those with a negative exponent of
greater magnitude become zero.
<dd>
If an array of two numbers is assigned then the first number is the
negative exponent limit and the second number is the positive
exponent limit.
</dd>
<dd>
For example, to emulate JavaScript numbers in terms of the exponent
values at which they become zero and Infinity, use
<code>[-324, 308]</code>.
</dd>
<dd>
<pre>BigNumber.config({ RANGE : 500 })
BigNumber.config().RANGE // [ -500, 500 ]
new BigNumber('9.999e499') // '9.999e+499'
new BigNumber('1e500') // 'Infinity'
new BigNumber('1e-499') // '1e-499'
new BigNumber('1e-500') // '0'
BigNumber.config({ RANGE : [-3, 4] })
new BigNumber(99999) // '99999' e is only 4
new BigNumber(100000) // 'Infinity' e is 5
new BigNumber(0.001) // '0.01' e is only -3
new BigNumber(0.0001) // '0' e is -4</pre>
</dd>
<dd>
The largest possible magnitude of a finite BigNumber is<br />
9.999...e+1000000000<br />
The smallest possible magnitude of a non-zero BigNumber is<br />
1e-1000000000
</dd>
<dt id="errors"><code><b>ERRORS</b></code></dt>
<dd>
<i>boolean/number</i> : <code>true, false, 1 or 0</code><br />
Default value: <code>true</code>
</dd>
<dd>
The value that determines whether BigNumber Errors are thrown.<br />
If <code>ERRORS</code> is false, this library will not throw errors.
</dd>
<dd>
See <a href='#Errors'>Errors</a>.
</dd>
<dd>
<pre>BigNumber.config({ ERRORS : false })</pre>
</dd>
</dl>
</dd>
</dl>
<p>
<br />Returns an object with the above properties and their current
values.
</p>
<p>
If the value to be assigned to any of the above properties is
<code>null</code> or undefined it is ignored. See
<a href='#Errors'>Errors</a> for the treatment of invalid values.
</p>
<pre>
BigNumber.config({
DECIMAL_PLACES : 40,
ROUNDING_MODE : BigNumber.ROUND_HALF_CEIL,
EXPONENTIAL_AT : [-10, 20],
RANGE : [-500, 500],
ERRORS : true
});
// Alternatively but equivalently:
BigNumber.config( 40, 7, [-10, 20], 500, 1 )
obj = BigNumber.config();
obj.ERRORS // true
obj.RANGE // [-500, 500]</pre>
<h4 id="constructor-properties">Properties</h4>
<p>
The library's enumerated rounding modes are stored as properties of the
constructor.<br />
They are not referenced internally by the library itself.
</p>
<p>
Rounding modes 0 to 6 (inclusive) are the same as those of Java's
BigDecimal class.
</p>
<table>
<tr>
<th>Property</th>
<th>Value</th>
<th>Description</th>
</tr>
<tr>
<td id="round-up"><b>ROUND_UP</b></td>
<td class='centre'>0</td>
<td>Rounds away from zero</td>
</tr>
<tr>
<td id="round-down"><b>ROUND_DOWN</b></td>
<td class='centre'>1</td>
<td>Rounds towards zero</td>
</tr>
<tr>
<td id="round-ceil"><b>ROUND_CEIL</b></td>
<td class='centre'>2</td>
<td>Rounds towards Infinity</td>
</tr>
<tr>
<td id="round-floor"><b>ROUND_FLOOR</b></td>
<td class='centre'>3</td>
<td>Rounds towards -Infinity</td>
</tr>
<tr>
<td id="round-half-up"><b>ROUND_HALF_UP</b></td>
<td class='centre'>4</td>
<td>
Rounds towards nearest neighbour.<br />
If equidistant, rounds away from zero
</td>
</tr>
<tr>
<td id="round-half-down"><b>ROUND_HALF_DOWN</b></td>
<td class='centre'>5</td>
<td>
Rounds towards nearest neighbour.<br />
If equidistant, rounds towards zero
</td>
</tr>
<tr>
<td id="round-half-even"><b>ROUND_HALF_EVEN</b></td>
<td class='centre'>6</td>
<td>
Rounds towards nearest neighbour.<br />
If equidistant, rounds towards even neighbour
</td>
</tr>
<tr>
<td id="round-half-ceil"><b>ROUND_HALF_CEIL</b></td>
<td class='centre'>7</td>
<td>
Rounds towards nearest neighbour.<br />
If equidistant, rounds towards Infinity
</td>
</tr>
<tr>
<td id="round-half-floor"><b>ROUND_HALF_FLOOR</b></td>
<td class='centre'>8</td>
<td>
Rounds towards nearest neighbour.<br />
If equidistant, rounds towards -Infinity
</td>
</tr>
</table>
<pre>
BigNumber.config({ ROUNDING_MODE : BigNumber.ROUND_CEIL })
BigNumber.config({ ROUNDING_MODE : 2 }) // equivalent</pre>
<h3>INSTANCE</h3>
<h4 id="prototype-methods">Methods</h4>
<p>
The methods inherited by a BigNumber instance from its constructor's
prototype object.
</p>
<p>
A BigNumber is immutable in the sense that it is not changed by its
methods.
</p>
<p>
The treatment of &plusmn;<code>0</code>, &plusmn;<code>Infinity</code> and
<code>NaN</code> is consistent with how JavaScript treats these values.
</p>
<p>
Method names over 5 letters in length have a shorter alias (except
<code>valueOf</code>).<br />
Internally, the library always uses the shorter method names.
</p>
<h5 id="abs">
absoluteValue<code class='inset'>.abs() &rArr; <i>BigNumber</i></code>
</h5>
<p>
Returns a BigNumber whose value is the absolute value, i.e. the magnitude,
of this BigNumber.
</p>
<pre>
x = new BigNumber(-0.8)
y = x.absoluteValue() // '0.8'
z = y.abs() // '0.8'</pre>
<h5 id="ceil">
ceil<code class='inset'>.ceil() &rArr; <i>BigNumber</i></code>
</h5>
<p>
Returns a BigNumber whose value is the value of this BigNumber rounded to
a whole number in the direction of Infinity.
</p>
<pre>
x = new BigNumber(1.3)
x.ceil() // '2'
y = new BigNumber(-1.8)
y.ceil() // '-1'</pre>
<h5 id="floor">
floor<code class='inset'>.floor() &rArr;
<i>BigNumber</i></code>
</h5>
<p>
Returns a BigNumber whose value is the value of this BigNumber rounded to
a whole number in the direction of -Infinity.
</p>
<pre>
x = new BigNumber(1.8)
x.floor() // '1'
y = new BigNumber(-1.3)
y.floor() // '-2'</pre>
<h5 id="neg">
negated<code class='inset'>.neg() &rArr; <i>BigNumber</i></code>
</h5>
<p>
Returns a BigNumber whose value is the value of this BigNumber negated,
i.e. multiplied by -1.
</p>
<pre>
x = new BigNumber(1.8)
x.negated() // '-1.8'
y = new BigNumber(-1.3)
y.neg() // '1.3'</pre>
<h5 id="sqrt">
squareRoot<code class='inset'>.sqrt() &rArr; <i>BigNumber</i></code>
</h5>
<p>
Returns a BigNumber whose value is the square root of this BigNumber,
correctly rounded according to the current
<a href='#decimal-places'><code>DECIMAL_PLACES</code></a> and
<a href='#rounding-mode'><code>ROUNDING_MODE</code></a> settings.
</p>
<pre>
x = new BigNumber(16)
x.squareRoot() // '4'
y = new BigNumber(3)
y.sqrt() // '1.73205080756887729353'</pre>
<h5 id="isF">
isFinite<code class='inset'>.isF() &rArr; <i>boolean</i></code>
</h5>
<p>
Returns <code>true</code> if the value of this BigNumber is a finite
number, otherwise returns <code>false</code>.<br />
The only possible non-finite values of a BigNumber are NaN, Infinity and
-Infinity.
</p>
<pre>
x = new BigNumber(1)
x.isFinite() // true
y = new BigNumber(Infinity)
y.isF() // false</pre>
<p>
Note: The native method <code>isFinite()</code> can be used if
<code>n &lt;= Number.MAX_VALUE</code>.
</p>
<h5 id="isNaN">
isNaN<code class='inset'>.isNaN() &rArr; <i>boolean</i></code>
</h5>
<p>
Returns <code>true</code> if the value of this BigNumber is NaN, otherwise
returns <code>false</code>.<br />
</p>
<pre>
x = new BigNumber(NaN)
x.isNaN() // true
y = new BigNumber('Infinity')
y.isNaN() // false</pre>
<p>
Note: The native method <code>isNaN()</code> can also be used.
</p>
<h5 id="isNeg">
isNegative<code class='inset'>.isNeg() &rArr; <i>boolean</i></code>
</h5>
<p>
Returns <code>true</code> if the value of this BigNumber is negative,
otherwise returns <code>false</code>.<br />
</p>
<pre>
x = new BigNumber(-0)
x.isNegative() // true
y = new BigNumber(2)
y.isNeg // false</pre>
<p>
Note: <code>n &lt; 0</code> can be used if
<code>n &lt;= -Number.MIN_VALUE</code>.
</p>
<h5 id="isZ">
isZero<code class='inset'>.isZ() &rArr; <i>boolean</i></code>
</h5>
<p>
Returns <code>true</code> if the value of this BigNumber is zero or minus
zero, otherwise returns <code>false</code>.<br />
</p>
<pre>
x = new BigNumber(-0)
x.isZero() && x.isNeg() // true
y = new BigNumber(Infinity)
y.isZ() // false</pre>
<p>
Note: <code>n == 0</code> can be used if
<code>n &gt;= Number.MIN_VALUE</code>.
</p>
<h5 id="cmp">
comparedTo<code class='inset'>.cmp(n [, base]) &rArr; <i>number</i></code>
</h5>
<p>
<code>n</code> : <i>number|string|BigNumber</i><br />
<code>base</code> : <i>number</i><br />
<i>
See <a href="#bignumber">constructor</a> for further parameter details.
</i>
</p>
<table>
<tr>
<th>Returns</th>
<th colspan=2>&nbsp;</th>
</tr>
<tr>
<td class='centre'>1</td>
<td>
If the value of this BigNumber is greater than the value of <code>n</code>
</td>
</tr>
<tr>
<td class='centre'>-1</td>
<td>
If the value of this BigNumber is less than the value of <code>n</code>
</td>
</tr>
<tr>
<td class='centre'>0</td>
<td>If this BigNumber and <code>n</code> have the same value</td>
</tr>
<tr>
<td class='centre'>null</td>
<td>
if the value of either this BigNumber or <code>n</code> is
<code>NaN</code>
</td>
</tr>
</table>
<pre>
x = new BigNumber(Infinity)
y = new BigNumber(5)
x.comparedTo(y) // 1
x.comparedTo(x.minus(1)) // 0
y.cmp(NaN) // null
y.cmp('110', 2) // -1</pre>
<h5 id="div">
dividedBy<code class='inset'>.div(n [, base]) &rArr;
<i>BigNumber</i></code>
</h5>
<p>
<code>n</code> : <i>number|string|BigNumber</i><br />
<code>base</code> : <i>number</i><br />
<i>See <a href="#bignumber">constructor</a> for further parameter details.
</i>
</p>
<p>
Returns a BigNumber whose value is the value of this BigNumber divided by
<code>n</code>, rounded according to the current
<a href='#decimal-places'><code>DECIMAL_PLACES</code></a> and
<a href='#rounding-mode'><code>ROUNDING_MODE</code></a> settings.
</p>
<pre>
x = new BigNumber(355)
y = new BigNumber(113)
x.dividedBy(y) // '3.14159292035398230088'
x.div(5) // '71'
x.div(47, 16) // '5'</pre>
<h5 id="minus">
minus<code class='inset'>.minus(n [, base]) &rArr; <i>BigNumber</i></code>
</h5>
<p>
<code>n</code> : <i>number|string|BigNumber</i><br />
<code>base</code> : <i>number</i><br />
<i>See <a href="#bignumber">constructor</a> for further parameter details.
</i>
</p>
<p>
Returns a BigNumber whose value is the value of this BigNumber minus
<code>n</code>.
</p>
<pre>
0.3 - 0.1 // 0.19999999999999998
x = new BigNumber(0.3)
x.minus(0.1) // '0.2'
x.minus(0.6, 20) // '0'</pre>
<h5 id="mod">
modulo<code class='inset'>.mod(n [, base]) &rArr; <i>BigNumber</i></code>
</h5>
<p>
<code>n</code> : <i>number|string|BigNumber</i><br />
<code>base</code> : <i>number</i><br />
<i>See <a href="#bignumber">constructor</a> for further parameter details.
</i>
</p>
<p>
Returns a BigNumber whose value is the value of this BigNumber modulo
<code>n</code>, i.e. the integer remainder of dividing this BigNumber by
<code>n</code>.
</p>
<p>
The result will have the same sign as this BigNumber, and it will match
that of JavaScript's % operator (within the limits of its precision) and
BigDecimal's remainder method.
</p>
<pre>
1 % 0.9 // 0.09999999999999998
x = new BigNumber(1)
x.modulo(0.9) // '0.1'
y = new BigNumber(33)
y.mod('a', 33) // '3'</pre>
<h5 id="plus">
plus<code class='inset'>.plus(n [, base]) &rArr; <i>BigNumber</i></code>
</h5>
<p>
<code>n</code> : <i>number|string|BigNumber</i><br />
<code>base</code> : <i>number</i><br />
<i>See <a href="#bignumber">constructor</a> for further parameter details.
</i>
</p>
<p>
Returns a BigNumber whose value is the value of this BigNumber plus
<code>n</code>.
</p>
<pre>
0.1 + 0.2 // 0.30000000000000004
x = new BigNumber(0.1)
y = x.plus(0.2) // '0.3'
BigNumber(0.7).plus(x).plus(y) // '1'
x.plus('0.1', 8) // '0.225'</pre>
<h5 id="times">
times<code class='inset'>.times(n [, base]) &rArr; <i>BigNumber</i></code>
</h5>
<p>
<code>n</code> : <i>number|string|BigNumber</i><br />
<code>base</code> : <i>number</i><br />
<i>See <a href="#bignumber">constructor</a> for further parameter details.
</i>
</p>
<p>
Returns a BigNumber whose value is the value of this BigNumber times
<code>n</code>.
</p>
<pre>
0.6 * 3 // 1.7999999999999998
x = new BigNumber(0.6)
y = x.times(3) // '1.8'
BigNumber('7e+500').times(y) // '1.26e+501'
x.times('-a', 16) // '-6'</pre>
<h5 id="pow">
toPower<code class='inset'>.pow(exp) &rArr; <i>BigNumber</i></code>
</h5>
<p>
<code>exp</code> : <i>number</i> : integer, -1e+6 to 1e+6 inclusive
</p>
<p>
Returns a BigNumber whose value is the value of this BigNumber raised to
the power <code>exp</code>.
</p>
<p>
If <code>exp</code> is negative the result is rounded according to the
current <a href='#decimal-places'><code>DECIMAL_PLACES</code></a> and
<a href='#rounding-mode'><code>ROUNDING_MODE</code></a> settings.
</p>
<p>
If <code>exp</code> is not an integer or is out of range:
</p>
<p class='inset'>
If <code>ERRORS</code> is <code>true</code> a BigNumber
Error is thrown,<br />
else if <code>exp</code> is greater than 1e+6, it is interpreted as
<code>Infinity</code>;<br />
else if <code>exp</code> is less than -1e+6, it is interpreted as
<code>-Infinity</code>;<br />
else if <code>exp</code> is otherwise a number, it is truncated to an
integer;<br />
else it is interpreted as <code>NaN</code>.
</p>
<p>
Note: High value exponents may cause this method to be slow to return.
</p>
<pre>
Math.pow(0.7, 2) // 0.48999999999999994
x = new BigNumber(0.7)
x.toPower(2) // '0.49'
BigNumber(3).pow(-2) // '0.11111111111111111111'
new BigNumber(123.456).toPower(1000).toString().length // 5099
new BigNumber(2).pow(1e+6) // Time taken (Node.js): 9 minutes 34 secs.</pre>
<h5 id="eq">
equals<code class='inset'>.eq(n [, base]) &rArr; <i>boolean</i></code>
</h5>
<p>
<code>n</code> : <i>number|string|BigNumber</i><br />
<code>base</code> : <i>number</i><br />
<i>See <a href="#bignumber">constructor</a> for further parameter details.
</i>
</p>
<p>
Returns <code>true</code> if the value of this BigNumber equals the value
of <code>n</code>, otherwise returns <code>false</code>.<br />
As with JavaScript, NaN does not equal NaN.
<br />Note : This method uses the <code>comparedTo</code> method
internally.
</p>
<pre>
0 === 1e-324 // true
x = new BigNumber(0)
x.equals('1e-324') // false
BigNumber(-0).eq(x) // true ( -0 === 0 )
BigNumber(255).eq('ff', 16) // true
y = new BigNumber(NaN)
y.equals(NaN) // false</pre>
<h5 id="gt">
greaterThan<code class='inset'>.gt(n [, base]) &rArr;
<i>boolean</i></code>
</h5>
<p>
<code>n</code> : <i>number|string|BigNumber</i><br />
<code>base</code> : <i>number</i><br />
<i>See <a href="#bignumber">constructor</a> for further parameter details.
</i>
</p>
<p>
Returns <code>true</code> if the value of this BigNumber is greater than
the value of <code>n</code>, otherwise returns <code>false</code>.<br />
Note : This method uses the <code>comparedTo</code> method internally.
</p>
<pre>
0.1 &gt; (0.3 - 0.2) // true
x = new BigNumber(0.1)
x.greaterThan(BigNumber(0.3).minus(0.2)) // false
BigNumber(0).gt(x) // false
BigNumber(11, 3).gt(11.1, 2) // true</pre>
<h5 id="gte">
greaterThanOrEqualTo<code class='inset'>.gte(n [, base]) &rArr;
<i>boolean</i></code>
</h5>
<p>
<code>n</code> : <i>number|string|BigNumber</i><br />
<code>base</code> : <i>number</i><br />
<i>See <a href="#bignumber">constructor</a> for further parameter details.
</i>
</p>
<p>
Returns <code>true</code> if the value of this BigNumber is greater than
or equal to the value of <code>n</code>, otherwise returns
<code>false</code>.<br />
Note : This method uses the <code>comparedTo</code> method internally.
</p>
<pre>
(0.3 - 0.2) &gt;= 0.1 // false
x = new BigNumber(0.3).minus(0.2)
x.greaterThanOrEqualTo(0.1) // true
BigNumber(1).gte(x) // true
BigNumber(10, 18).gte('i', 36) // true</pre>
<h5 id="lt">
lessThan<code class='inset'>.lt(n [, base]) &rArr; <i>boolean</i></code>
</h5>
<p>
<code>n</code> : <i>number|string|BigNumber</i><br />
<code>base</code> : <i>number</i><br />
<i>See <a href="#bignumber">constructor</a> for further parameter details.
</i>
</p>
<p>
Returns <code>true</code> if the value of this BigNumber is less than the
value of <code>n</code>, otherwise returns <code>false</code>.<br />
Note : This method uses the <code>comparedTo</code> method internally.
</p>
<pre>
(0.3 - 0.2) &lt; 0.1 // true
x = new BigNumber(0.3).minus(0.2)
x.lessThan(0.1) // false
BigNumber(0).lt(x) // true
BigNumber(11.1, 2).lt(11, 3) // true</pre>
<h5 id="lte">
lessThanOrEqualTo<code class='inset'>.lte(n [, base]) &rArr;
<i>boolean</i></code>
</h5>
<p>
<code>n</code> : <i>number|string|BigNumber</i><br />
<code>base</code> : <i>number</i><br />
<i>See <a href="#bignumber">constructor</a> for further parameter details.
</i>
</p>
<p>
Returns <code>true</code> if the value of this BigNumber is less than or
equal to the value of <code>n</code>, otherwise returns
<code>false</code>.<br />
Note : This method uses the <code>comparedTo</code> method internally.
</p>
<pre>
0.1 &lt;= (0.3 - 0.2) // false
x = new BigNumber(0.1)
x.lessThanOrEqualTo(BigNumber(0.3).minus(0.2)) // true
BigNumber(-1).lte(x) // true
BigNumber(10, 18).lte('i', 36) // true</pre>
<h5 id="toE">
toExponential<code class='inset'>.toE([decimal_places]) &rArr;
<i>string</i></code>
</h5>
<p>
<code>decimal_places</code> : <i>number</i> : integer, 0 to 1e+9 inclusive
</p>
<p>
Returns a string representing the value of this BigNumber in exponential
notation to the specified decimal places, i.e with one digit before the
decimal point and <code>decimal_places</code> digits after it. If rounding
is necessary, the current
<a href='#rounding-mode'><code>ROUNDING_MODE</code></a> is used.
</p>
<p>
If the value of this BigNumber in exponential notation has fewer fraction
digits then is specified by <code>decimal_places</code>, the return value
will be appended with zeros accordingly.
</p>
<p>
If <code>decimal_places</code> is omitted, or is <code>null</code> or
undefined, the number of digits after the decimal point defaults to the
minimum number of digits necessary to represent the value exactly.
</p>
<p>
See <a href='#Errors'>Errors</a> for the treatment of other
non-integer or out of range <code>decimal_places</code> values.
</p>
<pre>
x = 45.6
y = new BigNumber(x)
x.toExponential() // '4.56e+1'
y.toExponential() // '4.56e+1'
x.toExponential(0) // '5e+1'
y.toE(0) // '5e+1'
x.toExponential(1) // '4.6e+1'
y.toE(1) // '4.6e+1'
x.toExponential(3) // '4.560e+1'
y.toE(3) // '4.560e+1'</pre>
<h5 id="toF">
toFixed<code class='inset'>.toF([decimal_places]) &rArr;
<i>string</i></code>
</h5>
<p>
<code>decimal_places</code> : <i>number</i> : integer, 0 to 1e+9 inclusive
</p>
<p>
Returns a string representing the value of this BigNumber in normal
notation to the specified fixed number of decimal places, i.e. with
<code>decimal_places</code> digits after the decimal point. If rounding is
necessary, the current
<a href='#rounding-mode'><code>ROUNDING_MODE</code></a> setting is used.
</p>
<p>
If the value of this BigNumber in normal notation has fewer fraction
digits then is specified by <code>decimal_places</code>, the return value
will be appended with zeros accordingly.
</p>
<p>
Unlike <code>Number.prototype.toFixed</code>, which returns
exponential notation if a number is greater or equal to 10<sup>21</sup>,
this method will always return normal notation.
</p>
<p>
If <code>decimal_places</code> is omitted, or is <code>null</code> or
undefined, then the return value is the same as <code>n.toString()</code>.
This is also unlike <code>Number.prototype.toFixed</code>, which returns
the value to zero decimal places.
</p>
<p>
See <a href='#Errors'>Errors</a> for the treatment of other
non-integer or out of range <code>decimal_places</code> values.
</p>
<pre>
x = 45.6
y = new BigNumber(x)
x.toFixed() // '46'
y.toFixed() // '45.6'
y.toF(0) // '46'
x.toFixed(3) // '45.600'
y.toF(3) // '45.600'</pre>
<h5 id="toN">toNumber<code class='inset'>.toN() &rArr; <i>number</i></code></h5>
<p>Returns the value of this BigNumber as a number primitive.</p>
<p>
Type coercion with, for example, JavaScript's unary plus operator can alternatively be used,
but then a BigNumber with the value minus zero will convert to positive zero.
</p>
<pre>
x = new BigNumber(456.789)
x.toNumber() // 456.789
+x // 456.789
y = new BigNumber('45987349857634085409857349856430985')
y.toNumber() // 4.598734985763409e+34
z = new BigNumber(-0)
1 / +z // Infinity
1 / z.toNumber() // -Infinity</pre>
<h5 id="toP">
toPrecision<code class='inset'>.toP([significant_figures]) &rArr;
<i>string</i></code>
</h5>
<p>
<code>significant_figures</code> : <i>number</i> : integer, 1 to 1e+9
inclusive
</p>
<p>
Returns a string representing the value of this BigNumber to the
specified number of significant digits. If rounding is necessary, the
current <a href='#rounding-mode'><code>ROUNDING_MODE</code></a> setting is
used.
</p>
<p>
If <code>significant_figures</code> is less than the number of digits
necessary to represent the integer part of the value in normal notation,
then exponential notation is used.
</p>
<p>
If <code>significant_figures</code> is omitted, or is <code>null</code> or
undefined, then the return value is the same as <code>n.toString()</code>.
</p>
<p>
See <a href='#Errors'>Errors</a> for the treatment of other
non-integer or out of range <code>significant_figures</code> values.
</p>
<pre>
x = 45.6
y = new BigNumber(x)
x.toPrecision() // '45.6'
y.toPrecision() // '45.6'
x.toPrecision(1) // '5e+1'
y.toP(1) // '5e+1'
x.toPrecision(5) // '45.600'
y.toP(5) // '45.600'</pre>
<h5 id="toS">
toString<code class='inset'>.toS([base]) &rArr; <i>string</i></code>
</h5>
<p>
<code>base</code> : <i>number</i> : integer, 2 to 64 inclusive
</p>
<p>
Returns a string representing the value of this BigNumber in the specified
base, or base 10 if <code>base</code> is omitted. For bases above 10,
values from 10 to 35 are represented by <code>a-z</code> (as with
<code>Number.toString</code>), 36 to 61 by <code>A-Z</code>, and 62 and 63
by <code>$</code> and <code>_</code> respectively.
</p>
<p>
If a base is specified the value is rounded according to the current
<a href='#decimal-places'><code>DECIMAL_PLACES</code></a>
and <a href='#rounding-mode'><code>ROUNDING_MODE</code></a> settings.
</p>
<p>
If a base is not specified, and this BigNumber has a positive
exponent that is equal to or greater than the positive component of the
current <a href="#exponential-at"><code>EXPONENTIAL_AT</code></a> setting,
or a negative exponent equal to or less than the negative component of the
setting, then exponential notation is returned.
</p>
<p>
If <code>base</code> is <code>null</code> or undefined it is ignored.
<br />
See <a href='#Errors'>Errors</a> for the treatment of other non-integer or
out of range <code>base</code> values.
</p>
<pre>
x = new BigNumber(750000)
x.toString() // '750000'
BigNumber.config({ EXPONENTIAL_AT : 5 })
x.toString() // '7.5e+5'
y = new BigNumber(362.875)
y.toString(2) // '101101010.111'
y.toString(9) // '442.77777777777777777778'
y.toString(32) // 'ba.s'
BigNumber.config({ DECIMAL_PLACES : 4 });
z = new BigNumber('1.23456789')
z.toString() // '1.23456789'
z.toString(10) // '1.2346'</pre>
<h5 id="valueOf">
valueOf<code class='inset'>.valueOf() &rArr; <i>string</i></code>
</h5>
<p>
As <code>toString</code>, but does not accept a base argument.
</p>
<pre>
x = new BigNumber('1.777e+457')
x.valueOf() // '1.777e+457'</pre>
<h5 id="toFr">
toFraction<code class='inset'>.toFr([max_denominator]) &rArr;
<i>[string, string]</i></code>
</h5>
<p>
<code>max_denominator</code> : <i>number|string|BigNumber</i> :
integer &gt;= 1 and &lt; Infinity
</p>
<p>
Returns a string array representing the value of this BigNumber as a
simple fraction with an integer numerator and an integer denominator. The
denominator will be a positive non-zero value less than or equal to
<code>max_denominator</code>.
</p>
<p>
If a maximum denominator is not specified, or is <code>null</code> or
undefined, the denominator will be the lowest value necessary to represent
the number exactly.
</p>
<p>
See <a href='#Errors'>Errors</a> for the treatment of other non-integer or
out of range <code>max_denominator</code> values.
</p>
<pre>
x = new BigNumber(1.75)
x.toFraction() // '7, 4'
pi = new BigNumber('3.14159265358')
pi.toFr() // '157079632679,50000000000'
pi.toFr(100000) // '312689, 99532'
pi.toFr(10000) // '355, 113'
pi.toFr(100) // '311, 99'
pi.toFr(10) // '22, 7'
pi.toFr(1) // '3, 1'</pre>
<h5 id="round">
round<code class='inset'>.round([decimal_places [, rounding_mode]])
&rArr; <i>BigNumber</i></code>
</h5>
<p>
<code>decimal_places</code> : <i>number</i> : integer, 0 to 1e+9 inclusive
<br />
<code>rounding_mode</code> : <i>number</i> : integer, 0 to 8 inclusive
</p>
<p>
Returns a BigNumber whose value is the value of this BigNumber rounded by
the specified <code>rounding_mode</code> to a maximum of
<code>decimal_places</code> digits after the decimal point.
</p>
<p>
if <code>decimal_places</code> is omitted, or is <code>null</code> or
undefined, the return value is <code>n</code> rounded to a whole number.
</p>
<p>
if <code>rounding_mode</code> is omitted, or is <code>null</code> or
undefined, the current
<a href='#rounding-mode'><code>ROUNDING_MODE</code></a> setting is used.
</p>
<p>
See <a href='#Errors'>Errors</a> for the treatment of other
non-integer or out of range <code>decimal_places</code> or
<code>rounding_mode</code> values.
</p>
<pre>
x = 1234.56
Math.round(x) // 1235
y = new BigNumber(x)
y.round() // '1235'
y.round(1) // '1234.6'
y.round(2) // '1234.56'
y.round(10) // '1234.56'
y.round(0, 1) // '1234'
y.round(0, 6) // '1235'
y.round(1, 1) // '1234.5'
y.round(1, BigNumber.ROUND_HALF_EVEN) // '1234.6'
y // '1234.56'</pre>
<h4 id="instance-properties">Properties</h4>
<p>
A BigNumber is an object with three properties:
</p>
<table>
<tr>
<th>Property</th>
<th>Description</th>
<th>Type</th>
<th>Value</th>
</tr>
<tr>
<td class='centre' id='coefficient'><b>c</b></td>
<td>coefficient<sup>*</sup></td>
<td><i>number</i><code>[]</code></td>
<td> Array of single digits</td>
</tr>
<tr>
<td class='centre' id='exponent'><b>e</b></td>
<td>exponent</td>
<td><i>number</i></td>
<td>Integer, -1e+9 to 1e+9 inclusive</td>
</tr>
<tr>
<td class='centre' id='sign'><b>s</b></td>
<td>sign</td>
<td><i>number</i></td>
<td>-1 or 1</td>
</tr>
</table>
<p><sup>*</sup>significand</p>
<p>
The value of any of the three properties may also be <code>null</code>.
</p>
<p>
The value of a BigNumber is stored in a normalised decimal floating point
format which corresponds to the value's <code>toExponential</code> form,
with the decimal point to be positioned after the most significant
(left-most) digit of the coefficient.
</p>
<p>
Note that, as with JavaScript numbers, the original exponent and
fractional trailing zeros are not preserved.
</p>
<pre>x = new BigNumber(0.123) // '0.123'
x.toExponential() // '1.23e-1'
x.c // '1,2,3'
x.e // -1
x.s // 1
y = new Number(-123.4567000e+2) // '-12345.67'
y.toExponential() // '-1.234567e+4'
z = new BigNumber('-123.4567000e+2') // '-12345.67'
z.toExponential() // '-1.234567e+4'
z.c // '1,2,3,4,5,6,7'
z.e // 4
z.s // -1</pre>
<p>
A BigNumber is mutable in the sense that the value of its properties can
be changed.<br />
For example, to rapidly shift a value by a power of 10:
</p>
<pre>
x = new BigNumber('1234.000') // '1234'
x.toExponential() // '1.234e+3'
x.c // '1,2,3,4'
x.e // 3
x.e = -5
x // '0.00001234'</pre>
<p>
If changing the coefficient array directly, which is not recommended, be
careful to avoid leading or trailing zeros (unless zero itself is being
represented).
</p>
<h4 id="zero-nan-infinity">Zero, NaN and Infinity</h4>
<p>
The table below shows how &plusmn;0, NaN and &plusmn;Infinity are stored.
</p>
<table>
<tr>
<th> </th>
<th class='centre'>c</th>
<th class='centre'>e</th>
<th class='centre'>s</th>
</tr>
<tr>
<td>&plusmn;0</td>
<td><code>[0]</code></td>
<td><code>0</code></td>
<td><code>&plusmn;1</code></td>
</tr>
<tr>
<td>NaN</td>
<td><code>null</code></td>
<td><code>null</code></td>
<td><code>null</code></td>
</tr>
<tr>
<td>&plusmn;Infinity</td>
<td><code>null</code></td>
<td><code>null</code></td>
<td><code>&plusmn;1</code></td>
</tr>
</table>
<pre>
x = new Number(-0) // 0
1 / x == -Infinity // true
y = new BigNumber(-0) // '0'
y.c // '0' ( [0].toString() )
y.e // 0
y.s // -1</pre>
<h4 id='Errors'>Errors</h4>
<p>
The errors that are thrown are generic <code>Error</code> objects with
<code>name</code> <i>BigNumber Error</i>. The table below shows the errors
that may be thrown if <code>ERRORS</code> is <code>true</code>, and the
action taken if <code>ERRORS</code> is <code>false</code>.
</p>
<table class='error-table'>
<tr>
<th>Method(s)</th>
<th>ERRORS : true<br />Throw BigNumber Error</th>
<th>ERRORS : false<br />Action on invalid argument</th>
</tr>
<tr>
<td rowspan=5><code>
BigNumber<br />
comparedTo<br />
dividedBy<br />
equals<br />
greaterThan<br />
greaterThanOrEqualTo<br />
lessThan<br />
lessThanOrEqualTo<br />
minus<br />
mod<br />
plus<br />
times</code></td>
<td>number type has more than<br />15 significant digits</td>
<td>Accept.</td>
</tr>
<tr>
<td>not a base... number</td>
<td>Substitute <code>NaN</code>.</td>
</tr>
<tr>
<td>base not an integer</td>
<td>Truncate to integer.<br />Ignore if not a number.</td>
</tr>
<tr>
<td>base out of range</td>
<td>Ignore.</td>
</tr>
<tr>
<td>not a number<sup>*</sup></td>
<td>Substitute <code>NaN</code>.</td>
</tr>
<tr>
<td rowspan=9><code>config</code></td>
<td><code>DECIMAL_PLACES</code> not an integer</td>
<td>Truncate to integer.<br />Ignore if not a number.</td>
</tr>
<tr>
<td><code>DECIMAL_PLACES</code> out of range</td>
<td>Ignore.</td>
</tr>
<tr>
<td><code>ROUNDING_MODE</code> not an integer</td>
<td>Truncate to integer.<br />Ignore if not a number.</td>
</tr>
<tr>
<td><code>ROUNDING_MODE</code> out of range</td>
<td>Ignore.</td>
</tr>
<tr>
<td>
<code>EXPONENTIAL_AT</code> not an integer<br />
or not [integer, integer]
</td>
<td>Truncate to integer(s).<br />Ignore if not number(s).</td>
</tr>
<tr>
<td>
<code>EXPONENTIAL_AT</code> out of range<br />
or not [negative, positive]
</td>
<td>Ignore.</td>
</tr>
<tr>
<td>
<code>RANGE</code> not a non-zero integer<br />
or not [integer, integer]
</td>
<td> Truncate to integer(s).<br />Ignore if zero or not number(s).</td>
</tr>
<tr>
<td>
<code>RANGE</code> out of range<br />
or not [negative, positive]
</td>
<td>Ignore.</td>
</tr>
<tr>
<td>
<code>ERRORS</code> not a boolean<br />
or binary digit
</td>
<td>Ignore.</td>
</tr>
<tr>
<td rowspan=2><code>toPower</code></td>
<td>exponent not an integer</td>
<td>Truncate to integer.<br />Substitute <code>NaN</code> if not a number.</td>
</tr>
<tr>
<td>exponent out of range</td>
<td>Substitute <code>&plusmn;Infinity</code>.
</td>
</tr>
<tr>
<td rowspan=4><code>round</code></td>
<td>decimal places not an integer</td>
<td>Truncate to integer.<br />Ignore if not a number.</td>
</tr>
<tr>
<td>decimal places out of range</td>
<td>Ignore.</td>
</tr>
<tr>
<td>mode not an integer</td>
<td>Truncate to integer.<br />Ignore if not a number.</td>
</tr>
<tr>
<td>mode out of range</td>
<td>Ignore.</td>
</tr>
<tr>
<td rowspan=2><code>toExponential</code></td>
<td>decimal places not an integer</td>
<td>Truncate to integer.<br />Ignore if not a number.</td>
</tr>
<tr>
<td>decimal places out of range</td>
<td>Ignore.</td>
</tr>
<tr>
<td rowspan=2><code>toFixed</code></td>
<td>decimal places not an integer</td>
<td>Truncate to integer.<br />Ignore if not a number.</td>
</tr>
<tr>
<td>decimal places out of range</td>
<td>Ignore.</td>
</tr>
<tr>
<td rowspan=2><code>toFraction</code></td>
<td>max denominator not an integer</td>
<td>Truncate to integer.<br />Ignore if not a number.</td>
</tr>
<tr>
<td>max denominator out of range</td>
<td>Ignore.</td>
</tr>
<tr>
<td rowspan=2><code>toPrecision</code></td>
<td>precision not an integer</td>
<td>Truncate to integer.<br />Ignore if not a number.</td>
</tr>
<tr>
<td>precision out of range</td>
<td>Ignore.</td>
</tr>
<tr>
<td rowspan=2><code>toString</code></td>
<td>base not an integer</td>
<td>Truncate to integer.<br />Ignore if not a number.</td>
</tr>
<tr>
<td>base out of range</td>
<td>Ignore.</td>
</tr>
</table>
<p>
<sup>*</sup>No error is thrown if the value is <code>NaN</code> or 'NaN'
</p>
<p>
The message of a <i>BigNumber Error</i> will also contain the name of the
method from which the error originated.
</p>
<p>
To determine if an exception is a <i>BigNumber Error</i>:
</p>
<pre>
try {
// ...
} catch (e) {
if ( e instanceof Error && e.name == 'BigNumber Error' ) {
// ...
}
}</pre>
<h4 id='faq'>FAQ</h4>
<h6>Why are trailing fractional zeros removed from BigNumbers?</h6>
<p>
Many arbitrary-precision libraries retain trailing fractional zeros as
they can indicate the precision of a value. This can be useful but the
results of arithmetic operations can be misleading.
</p>
<pre>
x = new BigDecimal("1.0")
y = new BigDecimal("1.1000")
z = x.add(y) // 2.1000
x = new BigDecimal("1.20")
y = new BigDecimal("3.45000")
z = x.multiply(y) // 4.1400000</pre>
<p>
To specify the precision of a value is to specify that the value lies
within a certain range.
</p>
<p>
In the first example, <code>x</code> has a value of 1.0. The trailing zero
shows the precision of the value, implying that it is in the range 0.95 to
1.05. Similarly, the precision indicated by the trailing zeros of
<code>y</code> indicates that the value is in the range 1.09995 to
1.10005. If we add the two lowest values in the ranges we get 0.95 +
1.09995 = 2.04995 and if we add the two highest values we get 1.05 +
1.10005 = 2.15005, so the range of the result of the addition implied by
the precision of its operands is 2.04995 to 2.15005. The result given by
BigDecimal of 2.1000 however, indicates that the value is in the range
2.09995 to 2.10005 and therefore the precision implied by its trailing
zeros is misleading.
</p>
<p>
In the second example, the true range is 4.122744 to 4.157256 yet the
BigDecimal answer of 4.1400000 indicates a range of 4.13999995 to
4.14000005. Again, the precision implied by the trailing zeros is
misleading.
</p>
<p>
This library, like binary floating point and most calculators, does not
retain trailing fractional zeros. Instead, the <code>toExponential</code>,
<code>toFixed</code> and <code>toPrecision</code> methods enable trailing
zeros to be added if and when required.
</p>
<br />
</div>
</body>
</html>
The MIT Expat Licence.
Copyright (c) 2012 Michael Mclaughlin
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
{
"name": "bignumber.js",
"description": "A library for arbitrary-precision decimal and non-decimal arithmetic",
"version": "1.4.0",
"keywords": [
"arbitrary",
"precision",
"arithmetic",
"big",
"number",
"decimal",
"float",
"biginteger",
"bigdecimal",
"bignumber",
"bigint",
"bignum"
],
"repository": {
"type": "git",
"url": "https://github.com/MikeMcl/bignumber.js.git"
},
"main": "bignumber",
"author": {
"name": "Michael Mclaughlin",
"email": "M8ch88l@gmail.com"
},
"engines": {
"node": "*"
},
"license": "MIT",
"scripts": {
"test": "node ./test/every-test.js",
"build": "uglifyjs bignumber.js -c -m -o bignumber.min.js --preamble '/* bignumber.js v1.4.0 https://github.com/MikeMcl/bignumber.js/LICENCE */'"
},
"readme": "[![Build Status](https://travis-ci.org/MikeMcl/bignumber.js.png)](https://travis-ci.org/MikeMcl/bignumber.js)\r\n\r\n# bignumber.js #\r\n\r\nA JavaScript library for arbitrary-precision decimal and non-decimal arithmetic. \r\n \r\n## Features\r\n\r\n - Faster, smaller, and perhaps easier to use than JavaScript versions of Java's BigDecimal\r\n - 5 KB minified and gzipped\r\n - Simple API but full-featured\r\n - Works with numbers with or without fraction digits in bases from 2 to 64 inclusive\r\n - Replicates the `toExponential`, `toFixed`, `toPrecision` and `toString` methods of JavaScript's Number type\r\n - Includes a `toFraction` and a correctly-rounded `squareRoot` method\r\n - Stores values in an accessible decimal floating point format\r\n - No dependencies\r\n - Comprehensive [documentation](http://mikemcl.github.io/bignumber.js/) and test set \r\n\r\nIf an even smaller and simpler library is required see [big.js](https://github.com/MikeMcl/big.js/). \r\nIt's half the size but only works with decimal numbers and only has half the methods. \r\nIt also does not allow `NaN` or `Infinity`, or have the configuration options of this library. \r\nSee also [decimal.js](https://github.com/MikeMcl/decimal.js/).\r\n\r\n## Load\r\n\r\nThe library is the single JavaScript file *bignumber.js* (or minified, *bignumber.min.js*). \r\n\r\nIt can be loaded via a script tag in an HTML document for the browser\r\n\r\n <script src='./relative/path/to/bignumber.js'></script>\r\n \r\nor as a CommonJS, [Node.js](http://nodejs.org) or AMD module using `require`. \r\n\r\nFor Node, put the *bignumber.js* file into the same directory as the file that is requiring it and use\r\n\r\n var BigNumber = require('./bignumber'); \r\n\r\nor put it in a *node_modules* directory within the directory and use `require('bignumber')`. \r\n\r\nThe library is also available from the [npm](https://npmjs.org/) registry, so\r\n\r\n $ npm install bignumber.js\r\n\r\nwill install this directory in a *node_modules* directory within the current directory. \r\n \r\nTo load with AMD loader libraries such as [requireJS](http://requirejs.org/):\r\n\r\n require(['path/to/bignumber'], function(BigNumber) { \r\n // Use BigNumber here in local scope. No global BigNumber. \r\n });\r\n\r\n## Use\r\n\r\n*In all examples below, `var`, semicolons and `toString` calls are not shown. \r\nIf a commented-out value is in quotes it means `toString` has been called on the preceding expression.*\r\n\r\nThe library exports a single function: BigNumber, the constructor of BigNumber instances. \r\nIt accepts a value of type Number *(up to 15 significant digits only)*, String or BigNumber Object, \r\n\r\n x = new BigNumber(123.4567)\r\n y = BigNumber('123456.7e-3') // 'new' is optional\r\n z = new BigNumber(x)\r\n x.equals(y) && y.equals(z) && x.equals(z) // true\r\n\r\nand a base from 2 to 64 inclusive can be specified.\r\n\r\n x = new BigNumber(1011, 2) // \"11\" \r\n y = new BigNumber('zz.9', 36) // \"1295.25\"\r\n z = x.plus(y) // \"1306.25\"\r\n\r\nA BigNumber is immutable in the sense that it is not changed by its methods. \r\n\r\n 0.3 - 0.1 // 0.19999999999999998 \r\n x = new BigNumber(0.3) \r\n x.minus(0.1) // \"0.2\"\r\n x // \"0.3\"\r\n\r\nThe methods that return a BigNumber can be chained.\r\n\r\n x.dividedBy(y).plus(z).times(9).floor()\r\n x.times('1.23456780123456789e+9').plus(9876.5432321).dividedBy('4444562598.111772').ceil()\r\n\r\nMethod names over 5 letters in length have a shorter alias.\r\n\r\n x.squareRoot().dividedBy(y).toPower(3).equals(x.sqrt().div(y).pow(3)) // true\r\n x.cmp(y.mod(z).neg()) == 1 && x.comparedTo(y.modulo(z).negated()) == 1 // true\r\n\r\nLike JavaScript's Number type, there are `toExponential`, `toFixed` and `toPrecision` methods\r\n\r\n x = new BigNumber(255.5) \r\n x.toExponential(5) // \"2.55500e+2\"\r\n x.toFixed(5) // \"255.50000\"\r\n x.toPrecision(5) // \"255.50\"\r\n x.toNumber() // 255.5\r\n\r\n and a base can be specified for `toString`.\r\n\r\n x.toString(16) // \"ff.8\"\r\n\r\nThe maximum number of decimal places of, and the rounding mode applied to, the results of operations involving division (i.e. division, square root, base conversion, and negative power operations) is set by a configuration object passed to the `config` method of the `BigNumber` constructor. \r\nThe other arithmetic operations always give the exact result.\r\n\r\n BigNumber.config({ DECIMAL_PLACES: 10, ROUNDING_MODE: 4 })\r\n // Alternatively, BigNumber.config( 10, 4 );\r\n\r\n x = new BigNumber(2);\r\n y = new BigNumber(3); \r\n z = x.div(y) // \"0.6666666667\"\r\n z.sqrt() // \"0.8164965809\"\r\n z.pow(-3) // \"3.3749999995\"\r\n z.toString(2) // \"0.1010101011\"\r\n z.times(z) // \"0.44444444448888888889\"\r\n z.times(z).round(10) // \"0.4444444445\"\r\n\r\nThere is a `toFraction` method with an optional *maximum denominator* argument\r\n\r\n y = new BigNumber(355)\r\n pi = y.dividedBy(113) // \"3.1415929204\"\r\n pi.toFraction() // [ \"7853982301\", \"2500000000\" ]\r\n pi.toFraction(1000) // [ \"355\", \"113\" ]\r\n\r\nand `isNaN` and `isFinite` methods, as `NaN` and `Infinity` are valid `BigNumber` values.\r\n\r\n x = new BigNumber(NaN) // \"NaN\"\r\n y = new BigNumber(Infinity) // \"Infinity\"\r\n x.isNaN() && !y.isNaN() && !x.isFinite() && !y.isFinite() // true\r\n\r\nThe value of a BigNumber is stored in a decimal floating point format in terms of a coefficient, exponent and sign.\r\n\r\n x = new BigNumber(-123.456); \r\n x.c // \"1,2,3,4,5,6\" coefficient (i.e. significand)\r\n x.e // 2 exponent \r\n x.s // -1 sign\r\n\r\nFor futher information see the [API](http://mikemcl.github.io/bignumber.js/) reference from the *doc* folder.\r\n\r\n## Test\r\n\r\nThe *test* directory contains the test scripts for each method. \r\n\r\nThe tests can be run with Node or a browser. \r\n\r\nFor a quick test of all the methods, from a command-line shell at the *test/* directory\r\n\r\n $ node quick-test\r\n\r\nTo test a single method in more depth, e.g.\r\n\r\n $ node toFraction\r\n\r\nTo test all the methods in more depth\r\n\r\n $ node every-test\r\n\r\nFor the browser, see *quick-test.html*, *single-test.html* and *every-test.html* in the *test/browser* directory. \r\n \r\n*bignumber-vs-number.html* enables some of the methods of bignumber.js to be compared with those of JavaScript's Number type. \r\n\r\n## Performance\r\n\r\nThe *perf* directory contains two applications and a *lib* directory containing the BigDecimal libraries used by both. \r\n \r\n*bignumber-vs-bigdecimal.html* tests the performance of bignumber.js against the JavaScript translations of two versions of BigDecimal, its use should be more or less self-explanatory.\r\n(The GWT version doesn't work in IE 6.) \r\n\r\n* GWT: java.math.BigDecimal \r\n<https://github.com/iriscouch/bigdecimal.js>\r\n* ICU4J: com.ibm.icu.math.BigDecimal \r\n<https://github.com/dtrebbien/BigDecimal.js> \r\n\r\nThe BigDecimal in Node's npm registry is the GWT version. Despite its seeming popularity I have found it to have some serious bugs, see the Node script *perf/lib/bigdecimal_GWT/bugs.js* for examples of flaws in its *remainder*, *divide* and *compareTo* methods. \r\n\r\n*bigtime.js* is a Node command-line application which tests the performance of bignumber.js against the GWT version of BigDecimal from the npm registry. \r\n\r\nFor example, to compare the time taken by the bignumber.js `plus` method and the BigDecimal `add` method: \r\n \r\n $ node bigtime plus 10000 40 \r\n \r\nThis will time 10000 calls to each, using operands of up to 40 random digits and will check that the results match. \r\n \r\nFor help:\r\n\r\n $ node bigtime -h\r\n\r\nSee the README in the directory for more information.\r\n\r\n## Build\r\n\r\nI.e. minify.\r\n\r\nFor Node, if uglify-js is installed globally ( `npm install uglify-js -g` ) then \r\n\r\n npm run build\r\n\r\nwill create *bignumber.min.js*. \r\n\r\n## Feedback\r\n\r\nOpen an issue, or email \r\n\r\nMichael \r\n<a href=\"mailto:M8ch88l@gmail.com\">M8ch88l@gmail.com</a>\r\n\r\nBitcoin donation to: \r\n**1CauoGYrEoJFhcyxGVaiLTE6f3WCaSUjnm** \r\nThank you\r\n\r\n## Licence\r\n\r\nMIT.\r\n\r\nSee LICENCE.\r\n\r\n## Change Log\r\n\r\n####1.4.0\r\n* 08/05/2014 Added `toNumber`.\r\n\r\n####1.3.0\r\n* 08/11/2013 Ensure correct rounding of `sqrt` in all, rather than almost all, cases.\r\n* Maximum radix to 64.\r\n\r\n####1.2.1\r\n* 17/10/2013 Sign of zero when x < 0 and x + (-x) = 0.\r\n\r\n####1.2.0\r\n* 19/9/2013 Throw Error objects for stack.\r\n\r\n####1.1.1\r\n* 22/8/2013 Show original value in constructor error message.\r\n\r\n####1.1.0\r\n* 1/8/2013 Allow numbers with trailing radix point. \r\n\r\n####1.0.1\r\n* Bugfix: error messages with incorrect method name \r\n\r\n####1.0.0\r\n* 8/11/2012 Initial release \r\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/MikeMcl/bignumber.js/issues"
},
"homepage": "https://github.com/MikeMcl/bignumber.js",
"_id": "bignumber.js@1.4.0",
"_shasum": "28a11ade4b26fa07896426a5e52513049f51ad72",
"_from": "bignumber.js@1.4.0",
"_resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-1.4.0.tgz"
}

Build Status

bignumber.js

A JavaScript library for arbitrary-precision decimal and non-decimal arithmetic.

Features

  • Faster, smaller, and perhaps easier to use than JavaScript versions of Java's BigDecimal
  • 5 KB minified and gzipped
  • Simple API but full-featured
  • Works with numbers with or without fraction digits in bases from 2 to 64 inclusive
  • Replicates the toExponential, toFixed, toPrecision and toString methods of JavaScript's Number type
  • Includes a toFraction and a correctly-rounded squareRoot method
  • Stores values in an accessible decimal floating point format
  • No dependencies
  • Comprehensive documentation and test set

If an even smaller and simpler library is required see big.js.
It's half the size but only works with decimal numbers and only has half the methods.
It also does not allow NaN or Infinity, or have the configuration options of this library.
See also decimal.js.

Load

The library is the single JavaScript file bignumber.js (or minified, bignumber.min.js).

It can be loaded via a script tag in an HTML document for the browser

<script src='./relative/path/to/bignumber.js'></script>

or as a CommonJS, Node.js or AMD module using require.

For Node, put the bignumber.js file into the same directory as the file that is requiring it and use

var BigNumber = require('./bignumber'); 

or put it in a node_modules directory within the directory and use require('bignumber').

The library is also available from the npm registry, so

$ npm install bignumber.js

will install this directory in a node_modules directory within the current directory.

To load with AMD loader libraries such as requireJS:

require(['path/to/bignumber'], function(BigNumber) {  
    // Use BigNumber here in local scope. No global BigNumber. 
});

Use

In all examples below, var, semicolons and toString calls are not shown.
If a commented-out value is in quotes it means toString has been called on the preceding expression.

The library exports a single function: BigNumber, the constructor of BigNumber instances.
It accepts a value of type Number (up to 15 significant digits only), String or BigNumber Object,

x = new BigNumber(123.4567)
y = BigNumber('123456.7e-3')                     // 'new' is optional
z = new BigNumber(x)
x.equals(y) && y.equals(z) && x.equals(z)        // true

and a base from 2 to 64 inclusive can be specified.

x = new BigNumber(1011, 2)           // "11" 
y = new BigNumber('zz.9', 36)        // "1295.25"
z = x.plus(y)                        // "1306.25"

A BigNumber is immutable in the sense that it is not changed by its methods.

0.3 - 0.1                     // 0.19999999999999998  
x = new BigNumber(0.3)            
x.minus(0.1)                  // "0.2"
x                             // "0.3"

The methods that return a BigNumber can be chained.

x.dividedBy(y).plus(z).times(9).floor()
x.times('1.23456780123456789e+9').plus(9876.5432321).dividedBy('4444562598.111772').ceil()

Method names over 5 letters in length have a shorter alias.

x.squareRoot().dividedBy(y).toPower(3).equals(x.sqrt().div(y).pow(3))         // true
x.cmp(y.mod(z).neg()) == 1 && x.comparedTo(y.modulo(z).negated()) == 1        // true

Like JavaScript's Number type, there are toExponential, toFixed and toPrecision methods

x = new BigNumber(255.5)        
x.toExponential(5)              // "2.55500e+2"
x.toFixed(5)                    // "255.50000"
x.toPrecision(5)                // "255.50"
x.toNumber()                    // 255.5

and a base can be specified for toString.

x.toString(16)        // "ff.8"

The maximum number of decimal places of, and the rounding mode applied to, the results of operations involving division (i.e. division, square root, base conversion, and negative power operations) is set by a configuration object passed to the config method of the BigNumber constructor.
The other arithmetic operations always give the exact result.

BigNumber.config({ DECIMAL_PLACES: 10, ROUNDING_MODE: 4 })
// Alternatively, BigNumber.config( 10, 4 );

x = new BigNumber(2);
y = new BigNumber(3);        
z = x.div(y)                 // "0.6666666667"
z.sqrt()                     // "0.8164965809"
z.pow(-3)                    // "3.3749999995"
z.toString(2)                // "0.1010101011"
z.times(z)                   // "0.44444444448888888889"
z.times(z).round(10)         // "0.4444444445"

There is a toFraction method with an optional maximum denominator argument

y = new BigNumber(355)
pi = y.dividedBy(113)        // "3.1415929204"
pi.toFraction()              // [ "7853982301", "2500000000" ]
pi.toFraction(1000)          // [ "355", "113" ]

and isNaN and isFinite methods, as NaN and Infinity are valid BigNumber values.

x = new BigNumber(NaN)                                           // "NaN"
y = new BigNumber(Infinity)                                      // "Infinity"
x.isNaN() && !y.isNaN() && !x.isFinite() && !y.isFinite()        // true

The value of a BigNumber is stored in a decimal floating point format in terms of a coefficient, exponent and sign.

x = new BigNumber(-123.456); 
x.c                                 // "1,2,3,4,5,6"    coefficient (i.e. significand)
x.e                                 // 2                exponent 
x.s                                 // -1               sign

For futher information see the API reference from the doc folder.

Test

The test directory contains the test scripts for each method.

The tests can be run with Node or a browser.

For a quick test of all the methods, from a command-line shell at the test/ directory

$ node quick-test

To test a single method in more depth, e.g.

$ node toFraction

To test all the methods in more depth

$ node every-test

For the browser, see quick-test.html, single-test.html and every-test.html in the test/browser directory.

bignumber-vs-number.html enables some of the methods of bignumber.js to be compared with those of JavaScript's Number type.

Performance

The perf directory contains two applications and a lib directory containing the BigDecimal libraries used by both.

bignumber-vs-bigdecimal.html tests the performance of bignumber.js against the JavaScript translations of two versions of BigDecimal, its use should be more or less self-explanatory. (The GWT version doesn't work in IE 6.)

The BigDecimal in Node's npm registry is the GWT version. Despite its seeming popularity I have found it to have some serious bugs, see the Node script perf/lib/bigdecimal_GWT/bugs.js for examples of flaws in its remainder, divide and compareTo methods.

bigtime.js is a Node command-line application which tests the performance of bignumber.js against the GWT version of BigDecimal from the npm registry.

For example, to compare the time taken by the bignumber.js plus method and the BigDecimal add method:

$ node bigtime plus 10000 40      

This will time 10000 calls to each, using operands of up to 40 random digits and will check that the results match.

For help:

$ node bigtime -h

See the README in the directory for more information.

Build

I.e. minify.

For Node, if uglify-js is installed globally ( npm install uglify-js -g ) then

npm run build

will create bignumber.min.js.

Feedback

Open an issue, or email

Michael
M8ch88l@gmail.com

Bitcoin donation to:
1CauoGYrEoJFhcyxGVaiLTE6f3WCaSUjnm
Thank you

Licence

MIT.

See LICENCE.

Change Log

####1.4.0

  • 08/05/2014 Added toNumber.

####1.3.0

  • 08/11/2013 Ensure correct rounding of sqrt in all, rather than almost all, cases.
  • Maximum radix to 64.

####1.2.1

  • 17/10/2013 Sign of zero when x < 0 and x + (-x) = 0.

####1.2.0

  • 19/9/2013 Throw Error objects for stack.

####1.1.1

  • 22/8/2013 Show original value in constructor error message.

####1.1.0

  • 1/8/2013 Allow numbers with trailing radix point.

####1.0.1

  • Bugfix: error messages with incorrect method name

####1.0.0

  • 8/11/2012 Initial release
module.exports = require("./lib/_stream_duplex.js")
diff --git a/lib/_stream_duplex.js b/lib/_stream_duplex.js
index c5a741c..a2e0d8e 100644
--- a/lib/_stream_duplex.js
+++ b/lib/_stream_duplex.js
@@ -26,8 +26,8 @@
module.exports = Duplex;
var util = require('util');
-var Readable = require('_stream_readable');
-var Writable = require('_stream_writable');
+var Readable = require('./_stream_readable');
+var Writable = require('./_stream_writable');
util.inherits(Duplex, Readable);
diff --git a/lib/_stream_passthrough.js b/lib/_stream_passthrough.js
index a5e9864..330c247 100644
--- a/lib/_stream_passthrough.js
+++ b/lib/_stream_passthrough.js
@@ -25,7 +25,7 @@
module.exports = PassThrough;
-var Transform = require('_stream_transform');
+var Transform = require('./_stream_transform');
var util = require('util');
util.inherits(PassThrough, Transform);
diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js
index 0c3fe3e..90a8298 100644
--- a/lib/_stream_readable.js
+++ b/lib/_stream_readable.js
@@ -23,10 +23,34 @@ module.exports = Readable;
Readable.ReadableState = ReadableState;
var EE = require('events').EventEmitter;
+if (!EE.listenerCount) EE.listenerCount = function(emitter, type) {
+ return emitter.listeners(type).length;
+};
+
+if (!global.setImmediate) global.setImmediate = function setImmediate(fn) {
+ return setTimeout(fn, 0);
+};
+if (!global.clearImmediate) global.clearImmediate = function clearImmediate(i) {
+ return clearTimeout(i);
+};
+
var Stream = require('stream');
var util = require('util');
+if (!util.isUndefined) {
+ var utilIs = require('core-util-is');
+ for (var f in utilIs) {
+ util[f] = utilIs[f];
+ }
+}
var StringDecoder;
-var debug = util.debuglog('stream');
+var debug;
+if (util.debuglog)
+ debug = util.debuglog('stream');
+else try {
+ debug = require('debuglog')('stream');
+} catch (er) {
+ debug = function() {};
+}
util.inherits(Readable, Stream);
@@ -380,7 +404,7 @@ function chunkInvalid(state, chunk) {
function onEofChunk(stream, state) {
- if (state.decoder && !state.ended) {
+ if (state.decoder && !state.ended && state.decoder.end) {
var chunk = state.decoder.end();
if (chunk && chunk.length) {
state.buffer.push(chunk);
diff --git a/lib/_stream_transform.js b/lib/_stream_transform.js
index b1f9fcc..b0caf57 100644
--- a/lib/_stream_transform.js
+++ b/lib/_stream_transform.js
@@ -64,8 +64,14 @@
module.exports = Transform;
-var Duplex = require('_stream_duplex');
+var Duplex = require('./_stream_duplex');
var util = require('util');
+if (!util.isUndefined) {
+ var utilIs = require('core-util-is');
+ for (var f in utilIs) {
+ util[f] = utilIs[f];
+ }
+}
util.inherits(Transform, Duplex);
diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js
index ba2e920..f49288b 100644
--- a/lib/_stream_writable.js
+++ b/lib/_stream_writable.js
@@ -27,6 +27,12 @@ module.exports = Writable;
Writable.WritableState = WritableState;
var util = require('util');
+if (!util.isUndefined) {
+ var utilIs = require('core-util-is');
+ for (var f in utilIs) {
+ util[f] = utilIs[f];
+ }
+}
var Stream = require('stream');
util.inherits(Writable, Stream);
@@ -119,7 +125,7 @@ function WritableState(options, stream) {
function Writable(options) {
// Writable ctor is applied to Duplexes, though they're not
// instanceof Writable, they're instanceof Readable.
- if (!(this instanceof Writable) && !(this instanceof Stream.Duplex))
+ if (!(this instanceof Writable) && !(this instanceof require('./_stream_duplex')))
return new Writable(options);
this._writableState = new WritableState(options, this);
diff --git a/test/simple/test-stream-big-push.js b/test/simple/test-stream-big-push.js
index e3787e4..8cd2127 100644
--- a/test/simple/test-stream-big-push.js
+++ b/test/simple/test-stream-big-push.js
@@ -21,7 +21,7 @@
var common = require('../common');
var assert = require('assert');
-var stream = require('stream');
+var stream = require('../../');
var str = 'asdfasdfasdfasdfasdf';
var r = new stream.Readable({
diff --git a/test/simple/test-stream-end-paused.js b/test/simple/test-stream-end-paused.js
index bb73777..d40efc7 100644
--- a/test/simple/test-stream-end-paused.js
+++ b/test/simple/test-stream-end-paused.js
@@ -25,7 +25,7 @@ var gotEnd = false;
// Make sure we don't miss the end event for paused 0-length streams
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
var stream = new Readable();
var calledRead = false;
stream._read = function() {
diff --git a/test/simple/test-stream-pipe-after-end.js b/test/simple/test-stream-pipe-after-end.js
index b46ee90..0be8366 100644
--- a/test/simple/test-stream-pipe-after-end.js
+++ b/test/simple/test-stream-pipe-after-end.js
@@ -22,8 +22,8 @@
var common = require('../common');
var assert = require('assert');
-var Readable = require('_stream_readable');
-var Writable = require('_stream_writable');
+var Readable = require('../../lib/_stream_readable');
+var Writable = require('../../lib/_stream_writable');
var util = require('util');
util.inherits(TestReadable, Readable);
diff --git a/test/simple/test-stream-pipe-cleanup.js b/test/simple/test-stream-pipe-cleanup.js
deleted file mode 100644
index f689358..0000000
--- a/test/simple/test-stream-pipe-cleanup.js
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// This test asserts that Stream.prototype.pipe does not leave listeners
-// hanging on the source or dest.
-
-var common = require('../common');
-var stream = require('stream');
-var assert = require('assert');
-var util = require('util');
-
-function Writable() {
- this.writable = true;
- this.endCalls = 0;
- stream.Stream.call(this);
-}
-util.inherits(Writable, stream.Stream);
-Writable.prototype.end = function() {
- this.endCalls++;
-};
-
-Writable.prototype.destroy = function() {
- this.endCalls++;
-};
-
-function Readable() {
- this.readable = true;
- stream.Stream.call(this);
-}
-util.inherits(Readable, stream.Stream);
-
-function Duplex() {
- this.readable = true;
- Writable.call(this);
-}
-util.inherits(Duplex, Writable);
-
-var i = 0;
-var limit = 100;
-
-var w = new Writable();
-
-var r;
-
-for (i = 0; i < limit; i++) {
- r = new Readable();
- r.pipe(w);
- r.emit('end');
-}
-assert.equal(0, r.listeners('end').length);
-assert.equal(limit, w.endCalls);
-
-w.endCalls = 0;
-
-for (i = 0; i < limit; i++) {
- r = new Readable();
- r.pipe(w);
- r.emit('close');
-}
-assert.equal(0, r.listeners('close').length);
-assert.equal(limit, w.endCalls);
-
-w.endCalls = 0;
-
-r = new Readable();
-
-for (i = 0; i < limit; i++) {
- w = new Writable();
- r.pipe(w);
- w.emit('close');
-}
-assert.equal(0, w.listeners('close').length);
-
-r = new Readable();
-w = new Writable();
-var d = new Duplex();
-r.pipe(d); // pipeline A
-d.pipe(w); // pipeline B
-assert.equal(r.listeners('end').length, 2); // A.onend, A.cleanup
-assert.equal(r.listeners('close').length, 2); // A.onclose, A.cleanup
-assert.equal(d.listeners('end').length, 2); // B.onend, B.cleanup
-assert.equal(d.listeners('close').length, 3); // A.cleanup, B.onclose, B.cleanup
-assert.equal(w.listeners('end').length, 0);
-assert.equal(w.listeners('close').length, 1); // B.cleanup
-
-r.emit('end');
-assert.equal(d.endCalls, 1);
-assert.equal(w.endCalls, 0);
-assert.equal(r.listeners('end').length, 0);
-assert.equal(r.listeners('close').length, 0);
-assert.equal(d.listeners('end').length, 2); // B.onend, B.cleanup
-assert.equal(d.listeners('close').length, 2); // B.onclose, B.cleanup
-assert.equal(w.listeners('end').length, 0);
-assert.equal(w.listeners('close').length, 1); // B.cleanup
-
-d.emit('end');
-assert.equal(d.endCalls, 1);
-assert.equal(w.endCalls, 1);
-assert.equal(r.listeners('end').length, 0);
-assert.equal(r.listeners('close').length, 0);
-assert.equal(d.listeners('end').length, 0);
-assert.equal(d.listeners('close').length, 0);
-assert.equal(w.listeners('end').length, 0);
-assert.equal(w.listeners('close').length, 0);
diff --git a/test/simple/test-stream-pipe-error-handling.js b/test/simple/test-stream-pipe-error-handling.js
index c5d724b..c7d6b7d 100644
--- a/test/simple/test-stream-pipe-error-handling.js
+++ b/test/simple/test-stream-pipe-error-handling.js
@@ -21,7 +21,7 @@
var common = require('../common');
var assert = require('assert');
-var Stream = require('stream').Stream;
+var Stream = require('../../').Stream;
(function testErrorListenerCatches() {
var source = new Stream();
diff --git a/test/simple/test-stream-pipe-event.js b/test/simple/test-stream-pipe-event.js
index cb9d5fe..56f8d61 100644
--- a/test/simple/test-stream-pipe-event.js
+++ b/test/simple/test-stream-pipe-event.js
@@ -20,7 +20,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common');
-var stream = require('stream');
+var stream = require('../../');
var assert = require('assert');
var util = require('util');
diff --git a/test/simple/test-stream-push-order.js b/test/simple/test-stream-push-order.js
index f2e6ec2..a5c9bf9 100644
--- a/test/simple/test-stream-push-order.js
+++ b/test/simple/test-stream-push-order.js
@@ -20,7 +20,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common.js');
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
var assert = require('assert');
var s = new Readable({
diff --git a/test/simple/test-stream-push-strings.js b/test/simple/test-stream-push-strings.js
index 06f43dc..1701a9a 100644
--- a/test/simple/test-stream-push-strings.js
+++ b/test/simple/test-stream-push-strings.js
@@ -22,7 +22,7 @@
var common = require('../common');
var assert = require('assert');
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
var util = require('util');
util.inherits(MyStream, Readable);
diff --git a/test/simple/test-stream-readable-event.js b/test/simple/test-stream-readable-event.js
index ba6a577..a8e6f7b 100644
--- a/test/simple/test-stream-readable-event.js
+++ b/test/simple/test-stream-readable-event.js
@@ -22,7 +22,7 @@
var common = require('../common');
var assert = require('assert');
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
(function first() {
// First test, not reading when the readable is added.
diff --git a/test/simple/test-stream-readable-flow-recursion.js b/test/simple/test-stream-readable-flow-recursion.js
index 2891ad6..11689ba 100644
--- a/test/simple/test-stream-readable-flow-recursion.js
+++ b/test/simple/test-stream-readable-flow-recursion.js
@@ -27,7 +27,7 @@ var assert = require('assert');
// more data continuously, but without triggering a nextTick
// warning or RangeError.
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
// throw an error if we trigger a nextTick warning.
process.throwDeprecation = true;
diff --git a/test/simple/test-stream-unshift-empty-chunk.js b/test/simple/test-stream-unshift-empty-chunk.js
index 0c96476..7827538 100644
--- a/test/simple/test-stream-unshift-empty-chunk.js
+++ b/test/simple/test-stream-unshift-empty-chunk.js
@@ -24,7 +24,7 @@ var assert = require('assert');
// This test verifies that stream.unshift(Buffer(0)) or
// stream.unshift('') does not set state.reading=false.
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
var r = new Readable();
var nChunks = 10;
diff --git a/test/simple/test-stream-unshift-read-race.js b/test/simple/test-stream-unshift-read-race.js
index 83fd9fa..17c18aa 100644
--- a/test/simple/test-stream-unshift-read-race.js
+++ b/test/simple/test-stream-unshift-read-race.js
@@ -29,7 +29,7 @@ var assert = require('assert');
// 3. push() after the EOF signaling null is an error.
// 4. _read() is not called after pushing the EOF null chunk.
-var stream = require('stream');
+var stream = require('../../');
var hwm = 10;
var r = stream.Readable({ highWaterMark: hwm });
var chunks = 10;
@@ -51,7 +51,14 @@ r._read = function(n) {
function push(fast) {
assert(!pushedNull, 'push() after null push');
- var c = pos >= data.length ? null : data.slice(pos, pos + n);
+ var c;
+ if (pos >= data.length)
+ c = null;
+ else {
+ if (n + pos > data.length)
+ n = data.length - pos;
+ c = data.slice(pos, pos + n);
+ }
pushedNull = c === null;
if (fast) {
pos += n;
diff --git a/test/simple/test-stream-writev.js b/test/simple/test-stream-writev.js
index 5b49e6e..b5321f3 100644
--- a/test/simple/test-stream-writev.js
+++ b/test/simple/test-stream-writev.js
@@ -22,7 +22,7 @@
var common = require('../common');
var assert = require('assert');
-var stream = require('stream');
+var stream = require('../../');
var queue = [];
for (var decode = 0; decode < 2; decode++) {
diff --git a/test/simple/test-stream2-basic.js b/test/simple/test-stream2-basic.js
index 3814bf0..248c1be 100644
--- a/test/simple/test-stream2-basic.js
+++ b/test/simple/test-stream2-basic.js
@@ -21,7 +21,7 @@
var common = require('../common.js');
-var R = require('_stream_readable');
+var R = require('../../lib/_stream_readable');
var assert = require('assert');
var util = require('util');
diff --git a/test/simple/test-stream2-compatibility.js b/test/simple/test-stream2-compatibility.js
index 6cdd4e9..f0fa84b 100644
--- a/test/simple/test-stream2-compatibility.js
+++ b/test/simple/test-stream2-compatibility.js
@@ -21,7 +21,7 @@
var common = require('../common.js');
-var R = require('_stream_readable');
+var R = require('../../lib/_stream_readable');
var assert = require('assert');
var util = require('util');
diff --git a/test/simple/test-stream2-finish-pipe.js b/test/simple/test-stream2-finish-pipe.js
index 39b274f..006a19b 100644
--- a/test/simple/test-stream2-finish-pipe.js
+++ b/test/simple/test-stream2-finish-pipe.js
@@ -20,7 +20,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common.js');
-var stream = require('stream');
+var stream = require('../../');
var Buffer = require('buffer').Buffer;
var r = new stream.Readable();
diff --git a/test/simple/test-stream2-fs.js b/test/simple/test-stream2-fs.js
deleted file mode 100644
index e162406..0000000
--- a/test/simple/test-stream2-fs.js
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-var common = require('../common.js');
-var R = require('_stream_readable');
-var assert = require('assert');
-
-var fs = require('fs');
-var FSReadable = fs.ReadStream;
-
-var path = require('path');
-var file = path.resolve(common.fixturesDir, 'x1024.txt');
-
-var size = fs.statSync(file).size;
-
-var expectLengths = [1024];
-
-var util = require('util');
-var Stream = require('stream');
-
-util.inherits(TestWriter, Stream);
-
-function TestWriter() {
- Stream.apply(this);
- this.buffer = [];
- this.length = 0;
-}
-
-TestWriter.prototype.write = function(c) {
- this.buffer.push(c.toString());
- this.length += c.length;
- return true;
-};
-
-TestWriter.prototype.end = function(c) {
- if (c) this.buffer.push(c.toString());
- this.emit('results', this.buffer);
-}
-
-var r = new FSReadable(file);
-var w = new TestWriter();
-
-w.on('results', function(res) {
- console.error(res, w.length);
- assert.equal(w.length, size);
- var l = 0;
- assert.deepEqual(res.map(function (c) {
- return c.length;
- }), expectLengths);
- console.log('ok');
-});
-
-r.pipe(w);
diff --git a/test/simple/test-stream2-httpclient-response-end.js b/test/simple/test-stream2-httpclient-response-end.js
deleted file mode 100644
index 15cffc2..0000000
--- a/test/simple/test-stream2-httpclient-response-end.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common.js');
-var assert = require('assert');
-var http = require('http');
-var msg = 'Hello';
-var readable_event = false;
-var end_event = false;
-var server = http.createServer(function(req, res) {
- res.writeHead(200, {'Content-Type': 'text/plain'});
- res.end(msg);
-}).listen(common.PORT, function() {
- http.get({port: common.PORT}, function(res) {
- var data = '';
- res.on('readable', function() {
- console.log('readable event');
- readable_event = true;
- data += res.read();
- });
- res.on('end', function() {
- console.log('end event');
- end_event = true;
- assert.strictEqual(msg, data);
- server.close();
- });
- });
-});
-
-process.on('exit', function() {
- assert(readable_event);
- assert(end_event);
-});
-
diff --git a/test/simple/test-stream2-large-read-stall.js b/test/simple/test-stream2-large-read-stall.js
index 2fbfbca..667985b 100644
--- a/test/simple/test-stream2-large-read-stall.js
+++ b/test/simple/test-stream2-large-read-stall.js
@@ -30,7 +30,7 @@ var PUSHSIZE = 20;
var PUSHCOUNT = 1000;
var HWM = 50;
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
var r = new Readable({
highWaterMark: HWM
});
@@ -39,23 +39,23 @@ var rs = r._readableState;
r._read = push;
r.on('readable', function() {
- console.error('>> readable');
+ //console.error('>> readable');
do {
- console.error(' > read(%d)', READSIZE);
+ //console.error(' > read(%d)', READSIZE);
var ret = r.read(READSIZE);
- console.error(' < %j (%d remain)', ret && ret.length, rs.length);
+ //console.error(' < %j (%d remain)', ret && ret.length, rs.length);
} while (ret && ret.length === READSIZE);
- console.error('<< after read()',
- ret && ret.length,
- rs.needReadable,
- rs.length);
+ //console.error('<< after read()',
+ // ret && ret.length,
+ // rs.needReadable,
+ // rs.length);
});
var endEmitted = false;
r.on('end', function() {
endEmitted = true;
- console.error('end');
+ //console.error('end');
});
var pushes = 0;
@@ -64,11 +64,11 @@ function push() {
return;
if (pushes++ === PUSHCOUNT) {
- console.error(' push(EOF)');
+ //console.error(' push(EOF)');
return r.push(null);
}
- console.error(' push #%d', pushes);
+ //console.error(' push #%d', pushes);
if (r.push(new Buffer(PUSHSIZE)))
setTimeout(push);
}
diff --git a/test/simple/test-stream2-objects.js b/test/simple/test-stream2-objects.js
index 3e6931d..ff47d89 100644
--- a/test/simple/test-stream2-objects.js
+++ b/test/simple/test-stream2-objects.js
@@ -21,8 +21,8 @@
var common = require('../common.js');
-var Readable = require('_stream_readable');
-var Writable = require('_stream_writable');
+var Readable = require('../../lib/_stream_readable');
+var Writable = require('../../lib/_stream_writable');
var assert = require('assert');
// tiny node-tap lookalike.
diff --git a/test/simple/test-stream2-pipe-error-handling.js b/test/simple/test-stream2-pipe-error-handling.js
index cf7531c..e3f3e4e 100644
--- a/test/simple/test-stream2-pipe-error-handling.js
+++ b/test/simple/test-stream2-pipe-error-handling.js
@@ -21,7 +21,7 @@
var common = require('../common');
var assert = require('assert');
-var stream = require('stream');
+var stream = require('../../');
(function testErrorListenerCatches() {
var count = 1000;
diff --git a/test/simple/test-stream2-pipe-error-once-listener.js b/test/simple/test-stream2-pipe-error-once-listener.js
index 5e8e3cb..53b2616 100755
--- a/test/simple/test-stream2-pipe-error-once-listener.js
+++ b/test/simple/test-stream2-pipe-error-once-listener.js
@@ -24,7 +24,7 @@ var common = require('../common.js');
var assert = require('assert');
var util = require('util');
-var stream = require('stream');
+var stream = require('../../');
var Read = function() {
diff --git a/test/simple/test-stream2-push.js b/test/simple/test-stream2-push.js
index b63edc3..eb2b0e9 100644
--- a/test/simple/test-stream2-push.js
+++ b/test/simple/test-stream2-push.js
@@ -20,7 +20,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common.js');
-var stream = require('stream');
+var stream = require('../../');
var Readable = stream.Readable;
var Writable = stream.Writable;
var assert = require('assert');
diff --git a/test/simple/test-stream2-read-sync-stack.js b/test/simple/test-stream2-read-sync-stack.js
index e8a7305..9740a47 100644
--- a/test/simple/test-stream2-read-sync-stack.js
+++ b/test/simple/test-stream2-read-sync-stack.js
@@ -21,7 +21,7 @@
var common = require('../common');
var assert = require('assert');
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
var r = new Readable();
var N = 256 * 1024;
diff --git a/test/simple/test-stream2-readable-empty-buffer-no-eof.js b/test/simple/test-stream2-readable-empty-buffer-no-eof.js
index cd30178..4b1659d 100644
--- a/test/simple/test-stream2-readable-empty-buffer-no-eof.js
+++ b/test/simple/test-stream2-readable-empty-buffer-no-eof.js
@@ -22,10 +22,9 @@
var common = require('../common');
var assert = require('assert');
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
test1();
-test2();
function test1() {
var r = new Readable();
@@ -88,31 +87,3 @@ function test1() {
console.log('ok');
});
}
-
-function test2() {
- var r = new Readable({ encoding: 'base64' });
- var reads = 5;
- r._read = function(n) {
- if (!reads--)
- return r.push(null); // EOF
- else
- return r.push(new Buffer('x'));
- };
-
- var results = [];
- function flow() {
- var chunk;
- while (null !== (chunk = r.read()))
- results.push(chunk + '');
- }
- r.on('readable', flow);
- r.on('end', function() {
- results.push('EOF');
- });
- flow();
-
- process.on('exit', function() {
- assert.deepEqual(results, [ 'eHh4', 'eHg=', 'EOF' ]);
- console.log('ok');
- });
-}
diff --git a/test/simple/test-stream2-readable-from-list.js b/test/simple/test-stream2-readable-from-list.js
index 7c96ffe..04a96f5 100644
--- a/test/simple/test-stream2-readable-from-list.js
+++ b/test/simple/test-stream2-readable-from-list.js
@@ -21,7 +21,7 @@
var assert = require('assert');
var common = require('../common.js');
-var fromList = require('_stream_readable')._fromList;
+var fromList = require('../../lib/_stream_readable')._fromList;
// tiny node-tap lookalike.
var tests = [];
diff --git a/test/simple/test-stream2-readable-legacy-drain.js b/test/simple/test-stream2-readable-legacy-drain.js
index 675da8e..51fd3d5 100644
--- a/test/simple/test-stream2-readable-legacy-drain.js
+++ b/test/simple/test-stream2-readable-legacy-drain.js
@@ -22,7 +22,7 @@
var common = require('../common');
var assert = require('assert');
-var Stream = require('stream');
+var Stream = require('../../');
var Readable = Stream.Readable;
var r = new Readable();
diff --git a/test/simple/test-stream2-readable-non-empty-end.js b/test/simple/test-stream2-readable-non-empty-end.js
index 7314ae7..c971898 100644
--- a/test/simple/test-stream2-readable-non-empty-end.js
+++ b/test/simple/test-stream2-readable-non-empty-end.js
@@ -21,7 +21,7 @@
var assert = require('assert');
var common = require('../common.js');
-var Readable = require('_stream_readable');
+var Readable = require('../../lib/_stream_readable');
var len = 0;
var chunks = new Array(10);
diff --git a/test/simple/test-stream2-readable-wrap-empty.js b/test/simple/test-stream2-readable-wrap-empty.js
index 2e5cf25..fd8a3dc 100644
--- a/test/simple/test-stream2-readable-wrap-empty.js
+++ b/test/simple/test-stream2-readable-wrap-empty.js
@@ -22,7 +22,7 @@
var common = require('../common');
var assert = require('assert');
-var Readable = require('_stream_readable');
+var Readable = require('../../lib/_stream_readable');
var EE = require('events').EventEmitter;
var oldStream = new EE();
diff --git a/test/simple/test-stream2-readable-wrap.js b/test/simple/test-stream2-readable-wrap.js
index 90eea01..6b177f7 100644
--- a/test/simple/test-stream2-readable-wrap.js
+++ b/test/simple/test-stream2-readable-wrap.js
@@ -22,8 +22,8 @@
var common = require('../common');
var assert = require('assert');
-var Readable = require('_stream_readable');
-var Writable = require('_stream_writable');
+var Readable = require('../../lib/_stream_readable');
+var Writable = require('../../lib/_stream_writable');
var EE = require('events').EventEmitter;
var testRuns = 0, completedRuns = 0;
diff --git a/test/simple/test-stream2-set-encoding.js b/test/simple/test-stream2-set-encoding.js
index 5d2c32a..685531b 100644
--- a/test/simple/test-stream2-set-encoding.js
+++ b/test/simple/test-stream2-set-encoding.js
@@ -22,7 +22,7 @@
var common = require('../common.js');
var assert = require('assert');
-var R = require('_stream_readable');
+var R = require('../../lib/_stream_readable');
var util = require('util');
// tiny node-tap lookalike.
diff --git a/test/simple/test-stream2-transform.js b/test/simple/test-stream2-transform.js
index 9c9ddd8..a0cacc6 100644
--- a/test/simple/test-stream2-transform.js
+++ b/test/simple/test-stream2-transform.js
@@ -21,8 +21,8 @@
var assert = require('assert');
var common = require('../common.js');
-var PassThrough = require('_stream_passthrough');
-var Transform = require('_stream_transform');
+var PassThrough = require('../../').PassThrough;
+var Transform = require('../../').Transform;
// tiny node-tap lookalike.
var tests = [];
diff --git a/test/simple/test-stream2-unpipe-drain.js b/test/simple/test-stream2-unpipe-drain.js
index d66dc3c..365b327 100644
--- a/test/simple/test-stream2-unpipe-drain.js
+++ b/test/simple/test-stream2-unpipe-drain.js
@@ -22,7 +22,7 @@
var common = require('../common.js');
var assert = require('assert');
-var stream = require('stream');
+var stream = require('../../');
var crypto = require('crypto');
var util = require('util');
diff --git a/test/simple/test-stream2-unpipe-leak.js b/test/simple/test-stream2-unpipe-leak.js
index 99f8746..17c92ae 100644
--- a/test/simple/test-stream2-unpipe-leak.js
+++ b/test/simple/test-stream2-unpipe-leak.js
@@ -22,7 +22,7 @@
var common = require('../common.js');
var assert = require('assert');
-var stream = require('stream');
+var stream = require('../../');
var chunk = new Buffer('hallo');
diff --git a/test/simple/test-stream2-writable.js b/test/simple/test-stream2-writable.js
index 704100c..209c3a6 100644
--- a/test/simple/test-stream2-writable.js
+++ b/test/simple/test-stream2-writable.js
@@ -20,8 +20,8 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common.js');
-var W = require('_stream_writable');
-var D = require('_stream_duplex');
+var W = require('../../').Writable;
+var D = require('../../').Duplex;
var assert = require('assert');
var util = require('util');
diff --git a/test/simple/test-stream3-pause-then-read.js b/test/simple/test-stream3-pause-then-read.js
index b91bde3..2f72c15 100644
--- a/test/simple/test-stream3-pause-then-read.js
+++ b/test/simple/test-stream3-pause-then-read.js
@@ -22,7 +22,7 @@
var common = require('../common');
var assert = require('assert');
-var stream = require('stream');
+var stream = require('../../');
var Readable = stream.Readable;
var Writable = stream.Writable;
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// a duplex stream is just a stream that is both readable and writable.
// Since JS doesn't have multiple prototypal inheritance, this class
// prototypally inherits from Readable, and then parasitically from
// Writable.
module.exports = Duplex;
/*<replacement>*/
var objectKeys = Object.keys || function (obj) {
var keys = [];
for (var key in obj) keys.push(key);
return keys;
}
/*</replacement>*/
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
var Readable = require('./_stream_readable');
var Writable = require('./_stream_writable');
util.inherits(Duplex, Readable);
forEach(objectKeys(Writable.prototype), function(method) {
if (!Duplex.prototype[method])
Duplex.prototype[method] = Writable.prototype[method];
});
function Duplex(options) {
if (!(this instanceof Duplex))
return new Duplex(options);
Readable.call(this, options);
Writable.call(this, options);
if (options && options.readable === false)
this.readable = false;
if (options && options.writable === false)
this.writable = false;
this.allowHalfOpen = true;
if (options && options.allowHalfOpen === false)
this.allowHalfOpen = false;
this.once('end', onend);
}
// the no-half-open enforcer
function onend() {
// if we allow half-open state, or if the writable side ended,
// then we're ok.
if (this.allowHalfOpen || this._writableState.ended)
return;
// no more data can be written.
// But allow more writes to happen in this tick.
process.nextTick(this.end.bind(this));
}
function forEach (xs, f) {
for (var i = 0, l = xs.length; i < l; i++) {
f(xs[i], i);
}
}
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// a passthrough stream.
// basically just the most minimal sort of Transform stream.
// Every written chunk gets output as-is.
module.exports = PassThrough;
var Transform = require('./_stream_transform');
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
util.inherits(PassThrough, Transform);
function PassThrough(options) {
if (!(this instanceof PassThrough))
return new PassThrough(options);
Transform.call(this, options);
}
PassThrough.prototype._transform = function(chunk, encoding, cb) {
cb(null, chunk);
};
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
module.exports = Readable;
/*<replacement>*/
var isArray = require('isarray');
/*</replacement>*/
/*<replacement>*/
var Buffer = require('buffer').Buffer;
/*</replacement>*/
Readable.ReadableState = ReadableState;
var EE = require('events').EventEmitter;
/*<replacement>*/
if (!EE.listenerCount) EE.listenerCount = function(emitter, type) {
return emitter.listeners(type).length;
};
/*</replacement>*/
var Stream = require('stream');
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
var StringDecoder;
/*<replacement>*/
var debug = require('util');
if (debug && debug.debuglog) {
debug = debug.debuglog('stream');
} else {
debug = function () {};
}
/*</replacement>*/
util.inherits(Readable, Stream);
function ReadableState(options, stream) {
options = options || {};
// the point at which it stops calling _read() to fill the buffer
// Note: 0 is a valid value, means "don't call _read preemptively ever"
var hwm = options.highWaterMark;
var defaultHwm = options.objectMode ? 16 : 16 * 1024;
this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;
// cast to ints.
this.highWaterMark = ~~this.highWaterMark;
this.buffer = [];
this.length = 0;
this.pipes = null;
this.pipesCount = 0;
this.flowing = null;
this.ended = false;
this.endEmitted = false;
this.reading = false;
// a flag to be able to tell if the onwrite cb is called immediately,
// or on a later tick. We set this to true at first, because any
// actions that shouldn't happen until "later" should generally also
// not happen before the first write call.
this.sync = true;
// whenever we return null, then we set a flag to say
// that we're awaiting a 'readable' event emission.
this.needReadable = false;
this.emittedReadable = false;
this.readableListening = false;
// object stream flag. Used to make read(n) ignore n and to
// make all the buffer merging and length checks go away
this.objectMode = !!options.objectMode;
// Crypto is kind of old and crusty. Historically, its default string
// encoding is 'binary' so we have to make this configurable.
// Everything else in the universe uses 'utf8', though.
this.defaultEncoding = options.defaultEncoding || 'utf8';
// when piping, we only care about 'readable' events that happen
// after read()ing all the bytes and not getting any pushback.
this.ranOut = false;
// the number of writers that are awaiting a drain event in .pipe()s
this.awaitDrain = 0;
// if true, a maybeReadMore has been scheduled
this.readingMore = false;
this.decoder = null;
this.encoding = null;
if (options.encoding) {
if (!StringDecoder)
StringDecoder = require('string_decoder/').StringDecoder;
this.decoder = new StringDecoder(options.encoding);
this.encoding = options.encoding;
}
}
function Readable(options) {
if (!(this instanceof Readable))
return new Readable(options);
this._readableState = new ReadableState(options, this);
// legacy
this.readable = true;
Stream.call(this);
}
// Manually shove something into the read() buffer.
// This returns true if the highWaterMark has not been hit yet,
// similar to how Writable.write() returns true if you should
// write() some more.
Readable.prototype.push = function(chunk, encoding) {
var state = this._readableState;
if (util.isString(chunk) && !state.objectMode) {
encoding = encoding || state.defaultEncoding;
if (encoding !== state.encoding) {
chunk = new Buffer(chunk, encoding);
encoding = '';
}
}
return readableAddChunk(this, state, chunk, encoding, false);
};
// Unshift should *always* be something directly out of read()
Readable.prototype.unshift = function(chunk) {
var state = this._readableState;
return readableAddChunk(this, state, chunk, '', true);
};
function readableAddChunk(stream, state, chunk, encoding, addToFront) {
var er = chunkInvalid(state, chunk);
if (er) {
stream.emit('error', er);
} else if (util.isNullOrUndefined(chunk)) {
state.reading = false;
if (!state.ended)
onEofChunk(stream, state);
} else if (state.objectMode || chunk && chunk.length > 0) {
if (state.ended && !addToFront) {
var e = new Error('stream.push() after EOF');
stream.emit('error', e);
} else if (state.endEmitted && addToFront) {
var e = new Error('stream.unshift() after end event');
stream.emit('error', e);
} else {
if (state.decoder && !addToFront && !encoding)
chunk = state.decoder.write(chunk);
if (!addToFront)
state.reading = false;
// if we want the data now, just emit it.
if (state.flowing && state.length === 0 && !state.sync) {
stream.emit('data', chunk);
stream.read(0);
} else {
// update the buffer info.
state.length += state.objectMode ? 1 : chunk.length;
if (addToFront)
state.buffer.unshift(chunk);
else
state.buffer.push(chunk);
if (state.needReadable)
emitReadable(stream);
}
maybeReadMore(stream, state);
}
} else if (!addToFront) {
state.reading = false;
}
return needMoreData(state);
}
// if it's past the high water mark, we can push in some more.
// Also, if we have no data yet, we can stand some
// more bytes. This is to work around cases where hwm=0,
// such as the repl. Also, if the push() triggered a
// readable event, and the user called read(largeNumber) such that
// needReadable was set, then we ought to push more, so that another
// 'readable' event will be triggered.
function needMoreData(state) {
return !state.ended &&
(state.needReadable ||
state.length < state.highWaterMark ||
state.length === 0);
}
// backwards compatibility.
Readable.prototype.setEncoding = function(enc) {
if (!StringDecoder)
StringDecoder = require('string_decoder/').StringDecoder;
this._readableState.decoder = new StringDecoder(enc);
this._readableState.encoding = enc;
return this;
};
// Don't raise the hwm > 128MB
var MAX_HWM = 0x800000;
function roundUpToNextPowerOf2(n) {
if (n >= MAX_HWM) {
n = MAX_HWM;
} else {
// Get the next highest power of 2
n--;
for (var p = 1; p < 32; p <<= 1) n |= n >> p;
n++;
}
return n;
}
function howMuchToRead(n, state) {
if (state.length === 0 && state.ended)
return 0;
if (state.objectMode)
return n === 0 ? 0 : 1;
if (isNaN(n) || util.isNull(n)) {
// only flow one buffer at a time
if (state.flowing && state.buffer.length)
return state.buffer[0].length;
else
return state.length;
}
if (n <= 0)
return 0;
// If we're asking for more than the target buffer level,
// then raise the water mark. Bump up to the next highest
// power of 2, to prevent increasing it excessively in tiny
// amounts.
if (n > state.highWaterMark)
state.highWaterMark = roundUpToNextPowerOf2(n);
// don't have that much. return null, unless we've ended.
if (n > state.length) {
if (!state.ended) {
state.needReadable = true;
return 0;
} else
return state.length;
}
return n;
}
// you can override either this method, or the async _read(n) below.
Readable.prototype.read = function(n) {
debug('read', n);
var state = this._readableState;
var nOrig = n;
if (!util.isNumber(n) || n > 0)
state.emittedReadable = false;
// if we're doing read(0) to trigger a readable event, but we
// already have a bunch of data in the buffer, then just trigger
// the 'readable' event and move on.
if (n === 0 &&
state.needReadable &&
(state.length >= state.highWaterMark || state.ended)) {
debug('read: emitReadable', state.length, state.ended);
if (state.length === 0 && state.ended)
endReadable(this);
else
emitReadable(this);
return null;
}
n = howMuchToRead(n, state);
// if we've ended, and we're now clear, then finish it up.
if (n === 0 && state.ended) {
if (state.length === 0)
endReadable(this);
return null;
}
// All the actual chunk generation logic needs to be
// *below* the call to _read. The reason is that in certain
// synthetic stream cases, such as passthrough streams, _read
// may be a completely synchronous operation which may change
// the state of the read buffer, providing enough data when
// before there was *not* enough.
//
// So, the steps are:
// 1. Figure out what the state of things will be after we do
// a read from the buffer.
//
// 2. If that resulting state will trigger a _read, then call _read.
// Note that this may be asynchronous, or synchronous. Yes, it is
// deeply ugly to write APIs this way, but that still doesn't mean
// that the Readable class should behave improperly, as streams are
// designed to be sync/async agnostic.
// Take note if the _read call is sync or async (ie, if the read call
// has returned yet), so that we know whether or not it's safe to emit
// 'readable' etc.
//
// 3. Actually pull the requested chunks out of the buffer and return.
// if we need a readable event, then we need to do some reading.
var doRead = state.needReadable;
debug('need readable', doRead);
// if we currently have less than the highWaterMark, then also read some
if (state.length === 0 || state.length - n < state.highWaterMark) {
doRead = true;
debug('length less than watermark', doRead);
}
// however, if we've ended, then there's no point, and if we're already
// reading, then it's unnecessary.
if (state.ended || state.reading) {
doRead = false;
debug('reading or ended', doRead);
}
if (doRead) {
debug('do read');
state.reading = true;
state.sync = true;
// if the length is currently zero, then we *need* a readable event.
if (state.length === 0)
state.needReadable = true;
// call internal read method
this._read(state.highWaterMark);
state.sync = false;
}
// If _read pushed data synchronously, then `reading` will be false,
// and we need to re-evaluate how much data we can return to the user.
if (doRead && !state.reading)
n = howMuchToRead(nOrig, state);
var ret;
if (n > 0)
ret = fromList(n, state);
else
ret = null;
if (util.isNull(ret)) {
state.needReadable = true;
n = 0;
}
state.length -= n;
// If we have nothing in the buffer, then we want to know
// as soon as we *do* get something into the buffer.
if (state.length === 0 && !state.ended)
state.needReadable = true;
// If we tried to read() past the EOF, then emit end on the next tick.
if (nOrig !== n && state.ended && state.length === 0)
endReadable(this);
if (!util.isNull(ret))
this.emit('data', ret);
return ret;
};
function chunkInvalid(state, chunk) {
var er = null;
if (!util.isBuffer(chunk) &&
!util.isString(chunk) &&
!util.isNullOrUndefined(chunk) &&
!state.objectMode) {
er = new TypeError('Invalid non-string/buffer chunk');
}
return er;
}
function onEofChunk(stream, state) {
if (state.decoder && !state.ended) {
var chunk = state.decoder.end();
if (chunk && chunk.length) {
state.buffer.push(chunk);
state.length += state.objectMode ? 1 : chunk.length;
}
}
state.ended = true;
// emit 'readable' now to make sure it gets picked up.
emitReadable(stream);
}
// Don't emit readable right away in sync mode, because this can trigger
// another read() call => stack overflow. This way, it might trigger
// a nextTick recursion warning, but that's not so bad.
function emitReadable(stream) {
var state = stream._readableState;
state.needReadable = false;
if (!state.emittedReadable) {
debug('emitReadable', state.flowing);
state.emittedReadable = true;
if (state.sync)
process.nextTick(function() {
emitReadable_(stream);
});
else
emitReadable_(stream);
}
}
function emitReadable_(stream) {
debug('emit readable');
stream.emit('readable');
flow(stream);
}
// at this point, the user has presumably seen the 'readable' event,
// and called read() to consume some data. that may have triggered
// in turn another _read(n) call, in which case reading = true if
// it's in progress.
// However, if we're not ended, or reading, and the length < hwm,
// then go ahead and try to read some more preemptively.
function maybeReadMore(stream, state) {
if (!state.readingMore) {
state.readingMore = true;
process.nextTick(function() {
maybeReadMore_(stream, state);
});
}
}
function maybeReadMore_(stream, state) {
var len = state.length;
while (!state.reading && !state.flowing && !state.ended &&
state.length < state.highWaterMark) {
debug('maybeReadMore read 0');
stream.read(0);
if (len === state.length)
// didn't get any data, stop spinning.
break;
else
len = state.length;
}
state.readingMore = false;
}
// abstract method. to be overridden in specific implementation classes.
// call cb(er, data) where data is <= n in length.
// for virtual (non-string, non-buffer) streams, "length" is somewhat
// arbitrary, and perhaps not very meaningful.
Readable.prototype._read = function(n) {
this.emit('error', new Error('not implemented'));
};
Readable.prototype.pipe = function(dest, pipeOpts) {
var src = this;
var state = this._readableState;
switch (state.pipesCount) {
case 0:
state.pipes = dest;
break;
case 1:
state.pipes = [state.pipes, dest];
break;
default:
state.pipes.push(dest);
break;
}
state.pipesCount += 1;
debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
var doEnd = (!pipeOpts || pipeOpts.end !== false) &&
dest !== process.stdout &&
dest !== process.stderr;
var endFn = doEnd ? onend : cleanup;
if (state.endEmitted)
process.nextTick(endFn);
else
src.once('end', endFn);
dest.on('unpipe', onunpipe);
function onunpipe(readable) {
debug('onunpipe');
if (readable === src) {
cleanup();
}
}
function onend() {
debug('onend');
dest.end();
}
// when the dest drains, it reduces the awaitDrain counter
// on the source. This would be more elegant with a .once()
// handler in flow(), but adding and removing repeatedly is
// too slow.
var ondrain = pipeOnDrain(src);
dest.on('drain', ondrain);
function cleanup() {
debug('cleanup');
// cleanup event handlers once the pipe is broken
dest.removeListener('close', onclose);
dest.removeListener('finish', onfinish);
dest.removeListener('drain', ondrain);
dest.removeListener('error', onerror);
dest.removeListener('unpipe', onunpipe);
src.removeListener('end', onend);
src.removeListener('end', cleanup);
src.removeListener('data', ondata);
// if the reader is waiting for a drain event from this
// specific writer, then it would cause it to never start
// flowing again.
// So, if this is awaiting a drain, then we just call it now.
// If we don't know, then assume that we are waiting for one.
if (state.awaitDrain &&
(!dest._writableState || dest._writableState.needDrain))
ondrain();
}
src.on('data', ondata);
function ondata(chunk) {
debug('ondata');
var ret = dest.write(chunk);
if (false === ret) {
debug('false write response, pause',
src._readableState.awaitDrain);
src._readableState.awaitDrain++;
src.pause();
}
}
// if the dest has an error, then stop piping into it.
// however, don't suppress the throwing behavior for this.
function onerror(er) {
debug('onerror', er);
unpipe();
dest.removeListener('error', onerror);
if (EE.listenerCount(dest, 'error') === 0)
dest.emit('error', er);
}
// This is a brutally ugly hack to make sure that our error handler
// is attached before any userland ones. NEVER DO THIS.
if (!dest._events || !dest._events.error)
dest.on('error', onerror);
else if (isArray(dest._events.error))
dest._events.error.unshift(onerror);
else
dest._events.error = [onerror, dest._events.error];
// Both close and finish should trigger unpipe, but only once.
function onclose() {
dest.removeListener('finish', onfinish);
unpipe();
}
dest.once('close', onclose);
function onfinish() {
debug('onfinish');
dest.removeListener('close', onclose);
unpipe();
}
dest.once('finish', onfinish);
function unpipe() {
debug('unpipe');
src.unpipe(dest);
}
// tell the dest that it's being piped to
dest.emit('pipe', src);
// start the flow if it hasn't been started already.
if (!state.flowing) {
debug('pipe resume');
src.resume();
}
return dest;
};
function pipeOnDrain(src) {
return function() {
var state = src._readableState;
debug('pipeOnDrain', state.awaitDrain);
if (state.awaitDrain)
state.awaitDrain--;
if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) {
state.flowing = true;
flow(src);
}
};
}
Readable.prototype.unpipe = function(dest) {
var state = this._readableState;
// if we're not piping anywhere, then do nothing.
if (state.pipesCount === 0)
return this;
// just one destination. most common case.
if (state.pipesCount === 1) {
// passed in one, but it's not the right one.
if (dest && dest !== state.pipes)
return this;
if (!dest)
dest = state.pipes;
// got a match.
state.pipes = null;
state.pipesCount = 0;
state.flowing = false;
if (dest)
dest.emit('unpipe', this);
return this;
}
// slow case. multiple pipe destinations.
if (!dest) {
// remove all.
var dests = state.pipes;
var len = state.pipesCount;
state.pipes = null;
state.pipesCount = 0;
state.flowing = false;
for (var i = 0; i < len; i++)
dests[i].emit('unpipe', this);
return this;
}
// try to find the right one.
var i = indexOf(state.pipes, dest);
if (i === -1)
return this;
state.pipes.splice(i, 1);
state.pipesCount -= 1;
if (state.pipesCount === 1)
state.pipes = state.pipes[0];
dest.emit('unpipe', this);
return this;
};
// set up data events if they are asked for
// Ensure readable listeners eventually get something
Readable.prototype.on = function(ev, fn) {
var res = Stream.prototype.on.call(this, ev, fn);
// If listening to data, and it has not explicitly been paused,
// then call resume to start the flow of data on the next tick.
if (ev === 'data' && false !== this._readableState.flowing) {
this.resume();
}
if (ev === 'readable' && this.readable) {
var state = this._readableState;
if (!state.readableListening) {
state.readableListening = true;
state.emittedReadable = false;
state.needReadable = true;
if (!state.reading) {
var self = this;
process.nextTick(function() {
debug('readable nexttick read 0');
self.read(0);
});
} else if (state.length) {
emitReadable(this, state);
}
}
}
return res;
};
Readable.prototype.addListener = Readable.prototype.on;
// pause() and resume() are remnants of the legacy readable stream API
// If the user uses them, then switch into old mode.
Readable.prototype.resume = function() {
var state = this._readableState;
if (!state.flowing) {
debug('resume');
state.flowing = true;
if (!state.reading) {
debug('resume read 0');
this.read(0);
}
resume(this, state);
}
return this;
};
function resume(stream, state) {
if (!state.resumeScheduled) {
state.resumeScheduled = true;
process.nextTick(function() {
resume_(stream, state);
});
}
}
function resume_(stream, state) {
state.resumeScheduled = false;
stream.emit('resume');
flow(stream);
if (state.flowing && !state.reading)
stream.read(0);
}
Readable.prototype.pause = function() {
debug('call pause flowing=%j', this._readableState.flowing);
if (false !== this._readableState.flowing) {
debug('pause');
this._readableState.flowing = false;
this.emit('pause');
}
return this;
};
function flow(stream) {
var state = stream._readableState;
debug('flow', state.flowing);
if (state.flowing) {
do {
var chunk = stream.read();
} while (null !== chunk && state.flowing);
}
}
// wrap an old-style stream as the async data source.
// This is *not* part of the readable stream interface.
// It is an ugly unfortunate mess of history.
Readable.prototype.wrap = function(stream) {
var state = this._readableState;
var paused = false;
var self = this;
stream.on('end', function() {
debug('wrapped end');
if (state.decoder && !state.ended) {
var chunk = state.decoder.end();
if (chunk && chunk.length)
self.push(chunk);
}
self.push(null);
});
stream.on('data', function(chunk) {
debug('wrapped data');
if (state.decoder)
chunk = state.decoder.write(chunk);
if (!chunk || !state.objectMode && !chunk.length)
return;
var ret = self.push(chunk);
if (!ret) {
paused = true;
stream.pause();
}
});
// proxy all the other methods.
// important when wrapping filters and duplexes.
for (var i in stream) {
if (util.isFunction(stream[i]) && util.isUndefined(this[i])) {
this[i] = function(method) { return function() {
return stream[method].apply(stream, arguments);
}}(i);
}
}
// proxy certain important events.
var events = ['error', 'close', 'destroy', 'pause', 'resume'];
forEach(events, function(ev) {
stream.on(ev, self.emit.bind(self, ev));
});
// when we try to consume some more bytes, simply unpause the
// underlying stream.
self._read = function(n) {
debug('wrapped _read', n);
if (paused) {
paused = false;
stream.resume();
}
};
return self;
};
// exposed for testing purposes only.
Readable._fromList = fromList;
// Pluck off n bytes from an array of buffers.
// Length is the combined lengths of all the buffers in the list.
function fromList(n, state) {
var list = state.buffer;
var length = state.length;
var stringMode = !!state.decoder;
var objectMode = !!state.objectMode;
var ret;
// nothing in the list, definitely empty.
if (list.length === 0)
return null;
if (length === 0)
ret = null;
else if (objectMode)
ret = list.shift();
else if (!n || n >= length) {
// read it all, truncate the array.
if (stringMode)
ret = list.join('');
else
ret = Buffer.concat(list, length);
list.length = 0;
} else {
// read just some of it.
if (n < list[0].length) {
// just take a part of the first list item.
// slice is the same for buffers and strings.
var buf = list[0];
ret = buf.slice(0, n);
list[0] = buf.slice(n);
} else if (n === list[0].length) {
// first list is a perfect match
ret = list.shift();
} else {
// complex case.
// we have enough to cover it, but it spans past the first buffer.
if (stringMode)
ret = '';
else
ret = new Buffer(n);
var c = 0;
for (var i = 0, l = list.length; i < l && c < n; i++) {
var buf = list[0];
var cpy = Math.min(n - c, buf.length);
if (stringMode)
ret += buf.slice(0, cpy);
else
buf.copy(ret, c, 0, cpy);
if (cpy < buf.length)
list[0] = buf.slice(cpy);
else
list.shift();
c += cpy;
}
}
}
return ret;
}
function endReadable(stream) {
var state = stream._readableState;
// If we get here before consuming all the bytes, then that is a
// bug in node. Should never happen.
if (state.length > 0)
throw new Error('endReadable called on non-empty stream');
if (!state.endEmitted) {
state.ended = true;
process.nextTick(function() {
// Check that we didn't get one last unshift.
if (!state.endEmitted && state.length === 0) {
state.endEmitted = true;
stream.readable = false;
stream.emit('end');
}
});
}
}
function forEach (xs, f) {
for (var i = 0, l = xs.length; i < l; i++) {
f(xs[i], i);
}
}
function indexOf (xs, x) {
for (var i = 0, l = xs.length; i < l; i++) {
if (xs[i] === x) return i;
}
return -1;
}
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// a transform stream is a readable/writable stream where you do
// something with the data. Sometimes it's called a "filter",
// but that's not a great name for it, since that implies a thing where
// some bits pass through, and others are simply ignored. (That would
// be a valid example of a transform, of course.)
//
// While the output is causally related to the input, it's not a
// necessarily symmetric or synchronous transformation. For example,
// a zlib stream might take multiple plain-text writes(), and then
// emit a single compressed chunk some time in the future.
//
// Here's how this works:
//
// The Transform stream has all the aspects of the readable and writable
// stream classes. When you write(chunk), that calls _write(chunk,cb)
// internally, and returns false if there's a lot of pending writes
// buffered up. When you call read(), that calls _read(n) until
// there's enough pending readable data buffered up.
//
// In a transform stream, the written data is placed in a buffer. When
// _read(n) is called, it transforms the queued up data, calling the
// buffered _write cb's as it consumes chunks. If consuming a single
// written chunk would result in multiple output chunks, then the first
// outputted bit calls the readcb, and subsequent chunks just go into
// the read buffer, and will cause it to emit 'readable' if necessary.
//
// This way, back-pressure is actually determined by the reading side,
// since _read has to be called to start processing a new chunk. However,
// a pathological inflate type of transform can cause excessive buffering
// here. For example, imagine a stream where every byte of input is
// interpreted as an integer from 0-255, and then results in that many
// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in
// 1kb of data being output. In this case, you could write a very small
// amount of input, and end up with a very large amount of output. In
// such a pathological inflating mechanism, there'd be no way to tell
// the system to stop doing the transform. A single 4MB write could
// cause the system to run out of memory.
//
// However, even in such a pathological case, only a single written chunk
// would be consumed, and then the rest would wait (un-transformed) until
// the results of the previous transformed chunk were consumed.
module.exports = Transform;
var Duplex = require('./_stream_duplex');
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
util.inherits(Transform, Duplex);
function TransformState(options, stream) {
this.afterTransform = function(er, data) {
return afterTransform(stream, er, data);
};
this.needTransform = false;
this.transforming = false;
this.writecb = null;
this.writechunk = null;
}
function afterTransform(stream, er, data) {
var ts = stream._transformState;
ts.transforming = false;
var cb = ts.writecb;
if (!cb)
return stream.emit('error', new Error('no writecb in Transform class'));
ts.writechunk = null;
ts.writecb = null;
if (!util.isNullOrUndefined(data))
stream.push(data);
if (cb)
cb(er);
var rs = stream._readableState;
rs.reading = false;
if (rs.needReadable || rs.length < rs.highWaterMark) {
stream._read(rs.highWaterMark);
}
}
function Transform(options) {
if (!(this instanceof Transform))
return new Transform(options);
Duplex.call(this, options);
this._transformState = new TransformState(options, this);
// when the writable side finishes, then flush out anything remaining.
var stream = this;
// start out asking for a readable event once data is transformed.
this._readableState.needReadable = true;
// we have implemented the _read method, and done the other things
// that Readable wants before the first _read call, so unset the
// sync guard flag.
this._readableState.sync = false;
this.once('prefinish', function() {
if (util.isFunction(this._flush))
this._flush(function(er) {
done(stream, er);
});
else
done(stream);
});
}
Transform.prototype.push = function(chunk, encoding) {
this._transformState.needTransform = false;
return Duplex.prototype.push.call(this, chunk, encoding);
};
// This is the part where you do stuff!
// override this function in implementation classes.
// 'chunk' is an input chunk.
//
// Call `push(newChunk)` to pass along transformed output
// to the readable side. You may call 'push' zero or more times.
//
// Call `cb(err)` when you are done with this chunk. If you pass
// an error, then that'll put the hurt on the whole operation. If you
// never call cb(), then you'll never get another chunk.
Transform.prototype._transform = function(chunk, encoding, cb) {
throw new Error('not implemented');
};
Transform.prototype._write = function(chunk, encoding, cb) {
var ts = this._transformState;
ts.writecb = cb;
ts.writechunk = chunk;
ts.writeencoding = encoding;
if (!ts.transforming) {
var rs = this._readableState;
if (ts.needTransform ||
rs.needReadable ||
rs.length < rs.highWaterMark)
this._read(rs.highWaterMark);
}
};
// Doesn't matter what the args are here.
// _transform does all the work.
// That we got here means that the readable side wants more data.
Transform.prototype._read = function(n) {
var ts = this._transformState;
if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) {
ts.transforming = true;
this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
} else {
// mark that we need a transform, so that any data that comes in
// will get processed, now that we've asked for it.
ts.needTransform = true;
}
};
function done(stream, er) {
if (er)
return stream.emit('error', er);
// if there's nothing in the write buffer, then that means
// that nothing more will ever be provided
var ws = stream._writableState;
var ts = stream._transformState;
if (ws.length)
throw new Error('calling transform done when ws.length != 0');
if (ts.transforming)
throw new Error('calling transform done when still transforming');
return stream.push(null);
}
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// A bit simpler than readable streams.
// Implement an async ._write(chunk, cb), and it'll handle all
// the drain event emission and buffering.
module.exports = Writable;
/*<replacement>*/
var Buffer = require('buffer').Buffer;
/*</replacement>*/
Writable.WritableState = WritableState;
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
var Stream = require('stream');
util.inherits(Writable, Stream);
function WriteReq(chunk, encoding, cb) {
this.chunk = chunk;
this.encoding = encoding;
this.callback = cb;
}
function WritableState(options, stream) {
options = options || {};
// the point at which write() starts returning false
// Note: 0 is a valid value, means that we always return false if
// the entire buffer is not flushed immediately on write()
var hwm = options.highWaterMark;
var defaultHwm = options.objectMode ? 16 : 16 * 1024;
this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;
// object stream flag to indicate whether or not this stream
// contains buffers or objects.
this.objectMode = !!options.objectMode;
// cast to ints.
this.highWaterMark = ~~this.highWaterMark;
this.needDrain = false;
// at the start of calling end()
this.ending = false;
// when end() has been called, and returned
this.ended = false;
// when 'finish' is emitted
this.finished = false;
// should we decode strings into buffers before passing to _write?
// this is here so that some node-core streams can optimize string
// handling at a lower level.
var noDecode = options.decodeStrings === false;
this.decodeStrings = !noDecode;
// Crypto is kind of old and crusty. Historically, its default string
// encoding is 'binary' so we have to make this configurable.
// Everything else in the universe uses 'utf8', though.
this.defaultEncoding = options.defaultEncoding || 'utf8';
// not an actual buffer we keep track of, but a measurement
// of how much we're waiting to get pushed to some underlying
// socket or file.
this.length = 0;
// a flag to see when we're in the middle of a write.
this.writing = false;
// when true all writes will be buffered until .uncork() call
this.corked = 0;
// a flag to be able to tell if the onwrite cb is called immediately,
// or on a later tick. We set this to true at first, because any
// actions that shouldn't happen until "later" should generally also
// not happen before the first write call.
this.sync = true;
// a flag to know if we're processing previously buffered items, which
// may call the _write() callback in the same tick, so that we don't
// end up in an overlapped onwrite situation.
this.bufferProcessing = false;
// the callback that's passed to _write(chunk,cb)
this.onwrite = function(er) {
onwrite(stream, er);
};
// the callback that the user supplies to write(chunk,encoding,cb)
this.writecb = null;
// the amount that is being written when _write is called.
this.writelen = 0;
this.buffer = [];
// number of pending user-supplied write callbacks
// this must be 0 before 'finish' can be emitted
this.pendingcb = 0;
// emit prefinish if the only thing we're waiting for is _write cbs
// This is relevant for synchronous Transform streams
this.prefinished = false;
// True if the error was already emitted and should not be thrown again
this.errorEmitted = false;
}
function Writable(options) {
var Duplex = require('./_stream_duplex');
// Writable ctor is applied to Duplexes, though they're not
// instanceof Writable, they're instanceof Readable.
if (!(this instanceof Writable) && !(this instanceof Duplex))
return new Writable(options);
this._writableState = new WritableState(options, this);
// legacy.
this.writable = true;
Stream.call(this);
}
// Otherwise people can pipe Writable streams, which is just wrong.
Writable.prototype.pipe = function() {
this.emit('error', new Error('Cannot pipe. Not readable.'));
};
function writeAfterEnd(stream, state, cb) {
var er = new Error('write after end');
// TODO: defer error events consistently everywhere, not just the cb
stream.emit('error', er);
process.nextTick(function() {
cb(er);
});
}
// If we get something that is not a buffer, string, null, or undefined,
// and we're not in objectMode, then that's an error.
// Otherwise stream chunks are all considered to be of length=1, and the
// watermarks determine how many objects to keep in the buffer, rather than
// how many bytes or characters.
function validChunk(stream, state, chunk, cb) {
var valid = true;
if (!util.isBuffer(chunk) &&
!util.isString(chunk) &&
!util.isNullOrUndefined(chunk) &&
!state.objectMode) {
var er = new TypeError('Invalid non-string/buffer chunk');
stream.emit('error', er);
process.nextTick(function() {
cb(er);
});
valid = false;
}
return valid;
}
Writable.prototype.write = function(chunk, encoding, cb) {
var state = this._writableState;
var ret = false;
if (util.isFunction(encoding)) {
cb = encoding;
encoding = null;
}
if (util.isBuffer(chunk))
encoding = 'buffer';
else if (!encoding)
encoding = state.defaultEncoding;
if (!util.isFunction(cb))
cb = function() {};
if (state.ended)
writeAfterEnd(this, state, cb);
else if (validChunk(this, state, chunk, cb)) {
state.pendingcb++;
ret = writeOrBuffer(this, state, chunk, encoding, cb);
}
return ret;
};
Writable.prototype.cork = function() {
var state = this._writableState;
state.corked++;
};
Writable.prototype.uncork = function() {
var state = this._writableState;
if (state.corked) {
state.corked--;
if (!state.writing &&
!state.corked &&
!state.finished &&
!state.bufferProcessing &&
state.buffer.length)
clearBuffer(this, state);
}
};
function decodeChunk(state, chunk, encoding) {
if (!state.objectMode &&
state.decodeStrings !== false &&
util.isString(chunk)) {
chunk = new Buffer(chunk, encoding);
}
return chunk;
}
// if we're already writing something, then just put this
// in the queue, and wait our turn. Otherwise, call _write
// If we return false, then we need a drain event, so set that flag.
function writeOrBuffer(stream, state, chunk, encoding, cb) {
chunk = decodeChunk(state, chunk, encoding);
if (util.isBuffer(chunk))
encoding = 'buffer';
var len = state.objectMode ? 1 : chunk.length;
state.length += len;
var ret = state.length < state.highWaterMark;
// we must ensure that previous needDrain will not be reset to false.
if (!ret)
state.needDrain = true;
if (state.writing || state.corked)
state.buffer.push(new WriteReq(chunk, encoding, cb));
else
doWrite(stream, state, false, len, chunk, encoding, cb);
return ret;
}
function doWrite(stream, state, writev, len, chunk, encoding, cb) {
state.writelen = len;
state.writecb = cb;
state.writing = true;
state.sync = true;
if (writev)
stream._writev(chunk, state.onwrite);
else
stream._write(chunk, encoding, state.onwrite);
state.sync = false;
}
function onwriteError(stream, state, sync, er, cb) {
if (sync)
process.nextTick(function() {
state.pendingcb--;
cb(er);
});
else {
state.pendingcb--;
cb(er);
}
stream._writableState.errorEmitted = true;
stream.emit('error', er);
}
function onwriteStateUpdate(state) {
state.writing = false;
state.writecb = null;
state.length -= state.writelen;
state.writelen = 0;
}
function onwrite(stream, er) {
var state = stream._writableState;
var sync = state.sync;
var cb = state.writecb;
onwriteStateUpdate(state);
if (er)
onwriteError(stream, state, sync, er, cb);
else {
// Check if we're actually ready to finish, but don't emit yet
var finished = needFinish(stream, state);
if (!finished &&
!state.corked &&
!state.bufferProcessing &&
state.buffer.length) {
clearBuffer(stream, state);
}
if (sync) {
process.nextTick(function() {
afterWrite(stream, state, finished, cb);
});
} else {
afterWrite(stream, state, finished, cb);
}
}
}
function afterWrite(stream, state, finished, cb) {
if (!finished)
onwriteDrain(stream, state);
state.pendingcb--;
cb();
finishMaybe(stream, state);
}
// Must force callback to be called on nextTick, so that we don't
// emit 'drain' before the write() consumer gets the 'false' return
// value, and has a chance to attach a 'drain' listener.
function onwriteDrain(stream, state) {
if (state.length === 0 && state.needDrain) {
state.needDrain = false;
stream.emit('drain');
}
}
// if there's something in the buffer waiting, then process it
function clearBuffer(stream, state) {
state.bufferProcessing = true;
if (stream._writev && state.buffer.length > 1) {
// Fast case, write everything using _writev()
var cbs = [];
for (var c = 0; c < state.buffer.length; c++)
cbs.push(state.buffer[c].callback);
// count the one we are adding, as well.
// TODO(isaacs) clean this up
state.pendingcb++;
doWrite(stream, state, true, state.length, state.buffer, '', function(err) {
for (var i = 0; i < cbs.length; i++) {
state.pendingcb--;
cbs[i](err);
}
});
// Clear buffer
state.buffer = [];
} else {
// Slow case, write chunks one-by-one
for (var c = 0; c < state.buffer.length; c++) {
var entry = state.buffer[c];
var chunk = entry.chunk;
var encoding = entry.encoding;
var cb = entry.callback;
var len = state.objectMode ? 1 : chunk.length;
doWrite(stream, state, false, len, chunk, encoding, cb);
// if we didn't call the onwrite immediately, then
// it means that we need to wait until it does.
// also, that means that the chunk and cb are currently
// being processed, so move the buffer counter past them.
if (state.writing) {
c++;
break;
}
}
if (c < state.buffer.length)
state.buffer = state.buffer.slice(c);
else
state.buffer.length = 0;
}
state.bufferProcessing = false;
}
Writable.prototype._write = function(chunk, encoding, cb) {
cb(new Error('not implemented'));
};
Writable.prototype._writev = null;
Writable.prototype.end = function(chunk, encoding, cb) {
var state = this._writableState;
if (util.isFunction(chunk)) {
cb = chunk;
chunk = null;
encoding = null;
} else if (util.isFunction(encoding)) {
cb = encoding;
encoding = null;
}
if (!util.isNullOrUndefined(chunk))
this.write(chunk, encoding);
// .end() fully uncorks
if (state.corked) {
state.corked = 1;
this.uncork();
}
// ignore unnecessary end() calls.
if (!state.ending && !state.finished)
endWritable(this, state, cb);
};
function needFinish(stream, state) {
return (state.ending &&
state.length === 0 &&
!state.finished &&
!state.writing);
}
function prefinish(stream, state) {
if (!state.prefinished) {
state.prefinished = true;
stream.emit('prefinish');
}
}
function finishMaybe(stream, state) {
var need = needFinish(stream, state);
if (need) {
if (state.pendingcb === 0) {
prefinish(stream, state);
state.finished = true;
stream.emit('finish');
} else
prefinish(stream, state);
}
return need;
}
function endWritable(stream, state, cb) {
state.ending = true;
finishMaybe(stream, state);
if (cb) {
if (state.finished)
process.nextTick(cb);
else
stream.once('finish', cb);
}
state.ended = true;
}
Copyright Joyent, Inc. and other Node contributors. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
diff --git a/lib/util.js b/lib/util.js
index a03e874..9074e8e 100644
--- a/lib/util.js
+++ b/lib/util.js
@@ -19,430 +19,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-var formatRegExp = /%[sdj%]/g;
-exports.format = function(f) {
- if (!isString(f)) {
- var objects = [];
- for (var i = 0; i < arguments.length; i++) {
- objects.push(inspect(arguments[i]));
- }
- return objects.join(' ');
- }
-
- var i = 1;
- var args = arguments;
- var len = args.length;
- var str = String(f).replace(formatRegExp, function(x) {
- if (x === '%%') return '%';
- if (i >= len) return x;
- switch (x) {
- case '%s': return String(args[i++]);
- case '%d': return Number(args[i++]);
- case '%j':
- try {
- return JSON.stringify(args[i++]);
- } catch (_) {
- return '[Circular]';
- }
- default:
- return x;
- }
- });
- for (var x = args[i]; i < len; x = args[++i]) {
- if (isNull(x) || !isObject(x)) {
- str += ' ' + x;
- } else {
- str += ' ' + inspect(x);
- }
- }
- return str;
-};
-
-
-// Mark that a method should not be used.
-// Returns a modified function which warns once by default.
-// If --no-deprecation is set, then it is a no-op.
-exports.deprecate = function(fn, msg) {
- // Allow for deprecating things in the process of starting up.
- if (isUndefined(global.process)) {
- return function() {
- return exports.deprecate(fn, msg).apply(this, arguments);
- };
- }
-
- if (process.noDeprecation === true) {
- return fn;
- }
-
- var warned = false;
- function deprecated() {
- if (!warned) {
- if (process.throwDeprecation) {
- throw new Error(msg);
- } else if (process.traceDeprecation) {
- console.trace(msg);
- } else {
- console.error(msg);
- }
- warned = true;
- }
- return fn.apply(this, arguments);
- }
-
- return deprecated;
-};
-
-
-var debugs = {};
-var debugEnviron;
-exports.debuglog = function(set) {
- if (isUndefined(debugEnviron))
- debugEnviron = process.env.NODE_DEBUG || '';
- set = set.toUpperCase();
- if (!debugs[set]) {
- if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
- var pid = process.pid;
- debugs[set] = function() {
- var msg = exports.format.apply(exports, arguments);
- console.error('%s %d: %s', set, pid, msg);
- };
- } else {
- debugs[set] = function() {};
- }
- }
- return debugs[set];
-};
-
-
-/**
- * Echos the value of a value. Trys to print the value out
- * in the best way possible given the different types.
- *
- * @param {Object} obj The object to print out.
- * @param {Object} opts Optional options object that alters the output.
- */
-/* legacy: obj, showHidden, depth, colors*/
-function inspect(obj, opts) {
- // default options
- var ctx = {
- seen: [],
- stylize: stylizeNoColor
- };
- // legacy...
- if (arguments.length >= 3) ctx.depth = arguments[2];
- if (arguments.length >= 4) ctx.colors = arguments[3];
- if (isBoolean(opts)) {
- // legacy...
- ctx.showHidden = opts;
- } else if (opts) {
- // got an "options" object
- exports._extend(ctx, opts);
- }
- // set default options
- if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
- if (isUndefined(ctx.depth)) ctx.depth = 2;
- if (isUndefined(ctx.colors)) ctx.colors = false;
- if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
- if (ctx.colors) ctx.stylize = stylizeWithColor;
- return formatValue(ctx, obj, ctx.depth);
-}
-exports.inspect = inspect;
-
-
-// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
-inspect.colors = {
- 'bold' : [1, 22],
- 'italic' : [3, 23],
- 'underline' : [4, 24],
- 'inverse' : [7, 27],
- 'white' : [37, 39],
- 'grey' : [90, 39],
- 'black' : [30, 39],
- 'blue' : [34, 39],
- 'cyan' : [36, 39],
- 'green' : [32, 39],
- 'magenta' : [35, 39],
- 'red' : [31, 39],
- 'yellow' : [33, 39]
-};
-
-// Don't use 'blue' not visible on cmd.exe
-inspect.styles = {
- 'special': 'cyan',
- 'number': 'yellow',
- 'boolean': 'yellow',
- 'undefined': 'grey',
- 'null': 'bold',
- 'string': 'green',
- 'date': 'magenta',
- // "name": intentionally not styling
- 'regexp': 'red'
-};
-
-
-function stylizeWithColor(str, styleType) {
- var style = inspect.styles[styleType];
-
- if (style) {
- return '\u001b[' + inspect.colors[style][0] + 'm' + str +
- '\u001b[' + inspect.colors[style][1] + 'm';
- } else {
- return str;
- }
-}
-
-
-function stylizeNoColor(str, styleType) {
- return str;
-}
-
-
-function arrayToHash(array) {
- var hash = {};
-
- array.forEach(function(val, idx) {
- hash[val] = true;
- });
-
- return hash;
-}
-
-
-function formatValue(ctx, value, recurseTimes) {
- // Provide a hook for user-specified inspect functions.
- // Check that value is an object with an inspect function on it
- if (ctx.customInspect &&
- value &&
- isFunction(value.inspect) &&
- // Filter out the util module, it's inspect function is special
- value.inspect !== exports.inspect &&
- // Also filter out any prototype objects using the circular check.
- !(value.constructor && value.constructor.prototype === value)) {
- var ret = value.inspect(recurseTimes, ctx);
- if (!isString(ret)) {
- ret = formatValue(ctx, ret, recurseTimes);
- }
- return ret;
- }
-
- // Primitive types cannot have properties
- var primitive = formatPrimitive(ctx, value);
- if (primitive) {
- return primitive;
- }
-
- // Look up the keys of the object.
- var keys = Object.keys(value);
- var visibleKeys = arrayToHash(keys);
-
- if (ctx.showHidden) {
- keys = Object.getOwnPropertyNames(value);
- }
-
- // Some type of object without properties can be shortcutted.
- if (keys.length === 0) {
- if (isFunction(value)) {
- var name = value.name ? ': ' + value.name : '';
- return ctx.stylize('[Function' + name + ']', 'special');
- }
- if (isRegExp(value)) {
- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
- }
- if (isDate(value)) {
- return ctx.stylize(Date.prototype.toString.call(value), 'date');
- }
- if (isError(value)) {
- return formatError(value);
- }
- }
-
- var base = '', array = false, braces = ['{', '}'];
-
- // Make Array say that they are Array
- if (isArray(value)) {
- array = true;
- braces = ['[', ']'];
- }
-
- // Make functions say that they are functions
- if (isFunction(value)) {
- var n = value.name ? ': ' + value.name : '';
- base = ' [Function' + n + ']';
- }
-
- // Make RegExps say that they are RegExps
- if (isRegExp(value)) {
- base = ' ' + RegExp.prototype.toString.call(value);
- }
-
- // Make dates with properties first say the date
- if (isDate(value)) {
- base = ' ' + Date.prototype.toUTCString.call(value);
- }
-
- // Make error with message first say the error
- if (isError(value)) {
- base = ' ' + formatError(value);
- }
-
- if (keys.length === 0 && (!array || value.length == 0)) {
- return braces[0] + base + braces[1];
- }
-
- if (recurseTimes < 0) {
- if (isRegExp(value)) {
- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
- } else {
- return ctx.stylize('[Object]', 'special');
- }
- }
-
- ctx.seen.push(value);
-
- var output;
- if (array) {
- output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
- } else {
- output = keys.map(function(key) {
- return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
- });
- }
-
- ctx.seen.pop();
-
- return reduceToSingleString(output, base, braces);
-}
-
-
-function formatPrimitive(ctx, value) {
- if (isUndefined(value))
- return ctx.stylize('undefined', 'undefined');
- if (isString(value)) {
- var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
- .replace(/'/g, "\\'")
- .replace(/\\"/g, '"') + '\'';
- return ctx.stylize(simple, 'string');
- }
- if (isNumber(value)) {
- // Format -0 as '-0'. Strict equality won't distinguish 0 from -0,
- // so instead we use the fact that 1 / -0 < 0 whereas 1 / 0 > 0 .
- if (value === 0 && 1 / value < 0)
- return ctx.stylize('-0', 'number');
- return ctx.stylize('' + value, 'number');
- }
- if (isBoolean(value))
- return ctx.stylize('' + value, 'boolean');
- // For some reason typeof null is "object", so special case here.
- if (isNull(value))
- return ctx.stylize('null', 'null');
-}
-
-
-function formatError(value) {
- return '[' + Error.prototype.toString.call(value) + ']';
-}
-
-
-function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
- var output = [];
- for (var i = 0, l = value.length; i < l; ++i) {
- if (hasOwnProperty(value, String(i))) {
- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
- String(i), true));
- } else {
- output.push('');
- }
- }
- keys.forEach(function(key) {
- if (!key.match(/^\d+$/)) {
- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
- key, true));
- }
- });
- return output;
-}
-
-
-function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
- var name, str, desc;
- desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
- if (desc.get) {
- if (desc.set) {
- str = ctx.stylize('[Getter/Setter]', 'special');
- } else {
- str = ctx.stylize('[Getter]', 'special');
- }
- } else {
- if (desc.set) {
- str = ctx.stylize('[Setter]', 'special');
- }
- }
- if (!hasOwnProperty(visibleKeys, key)) {
- name = '[' + key + ']';
- }
- if (!str) {
- if (ctx.seen.indexOf(desc.value) < 0) {
- if (isNull(recurseTimes)) {
- str = formatValue(ctx, desc.value, null);
- } else {
- str = formatValue(ctx, desc.value, recurseTimes - 1);
- }
- if (str.indexOf('\n') > -1) {
- if (array) {
- str = str.split('\n').map(function(line) {
- return ' ' + line;
- }).join('\n').substr(2);
- } else {
- str = '\n' + str.split('\n').map(function(line) {
- return ' ' + line;
- }).join('\n');
- }
- }
- } else {
- str = ctx.stylize('[Circular]', 'special');
- }
- }
- if (isUndefined(name)) {
- if (array && key.match(/^\d+$/)) {
- return str;
- }
- name = JSON.stringify('' + key);
- if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
- name = name.substr(1, name.length - 2);
- name = ctx.stylize(name, 'name');
- } else {
- name = name.replace(/'/g, "\\'")
- .replace(/\\"/g, '"')
- .replace(/(^"|"$)/g, "'");
- name = ctx.stylize(name, 'string');
- }
- }
-
- return name + ': ' + str;
-}
-
-
-function reduceToSingleString(output, base, braces) {
- var numLinesEst = 0;
- var length = output.reduce(function(prev, cur) {
- numLinesEst++;
- if (cur.indexOf('\n') >= 0) numLinesEst++;
- return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
- }, 0);
-
- if (length > 60) {
- return braces[0] +
- (base === '' ? '' : base + '\n ') +
- ' ' +
- output.join(',\n ') +
- ' ' +
- braces[1];
- }
-
- return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
-}
-
-
// NOTE: These type checking functions intentionally don't use `instanceof`
// because it is fragile and can be easily faked with `Object.create()`.
function isArray(ar) {
@@ -522,166 +98,10 @@ function isPrimitive(arg) {
exports.isPrimitive = isPrimitive;
function isBuffer(arg) {
- return arg instanceof Buffer;
+ return Buffer.isBuffer(arg);
}
exports.isBuffer = isBuffer;
function objectToString(o) {
return Object.prototype.toString.call(o);
-}
-
-
-function pad(n) {
- return n < 10 ? '0' + n.toString(10) : n.toString(10);
-}
-
-
-var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
- 'Oct', 'Nov', 'Dec'];
-
-// 26 Feb 16:19:34
-function timestamp() {
- var d = new Date();
- var time = [pad(d.getHours()),
- pad(d.getMinutes()),
- pad(d.getSeconds())].join(':');
- return [d.getDate(), months[d.getMonth()], time].join(' ');
-}
-
-
-// log is just a thin wrapper to console.log that prepends a timestamp
-exports.log = function() {
- console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
-};
-
-
-/**
- * Inherit the prototype methods from one constructor into another.
- *
- * The Function.prototype.inherits from lang.js rewritten as a standalone
- * function (not on Function.prototype). NOTE: If this file is to be loaded
- * during bootstrapping this function needs to be rewritten using some native
- * functions as prototype setup using normal JavaScript does not work as
- * expected during bootstrapping (see mirror.js in r114903).
- *
- * @param {function} ctor Constructor function which needs to inherit the
- * prototype.
- * @param {function} superCtor Constructor function to inherit prototype from.
- */
-exports.inherits = function(ctor, superCtor) {
- ctor.super_ = superCtor;
- ctor.prototype = Object.create(superCtor.prototype, {
- constructor: {
- value: ctor,
- enumerable: false,
- writable: true,
- configurable: true
- }
- });
-};
-
-exports._extend = function(origin, add) {
- // Don't do anything if add isn't an object
- if (!add || !isObject(add)) return origin;
-
- var keys = Object.keys(add);
- var i = keys.length;
- while (i--) {
- origin[keys[i]] = add[keys[i]];
- }
- return origin;
-};
-
-function hasOwnProperty(obj, prop) {
- return Object.prototype.hasOwnProperty.call(obj, prop);
-}
-
-
-// Deprecated old stuff.
-
-exports.p = exports.deprecate(function() {
- for (var i = 0, len = arguments.length; i < len; ++i) {
- console.error(exports.inspect(arguments[i]));
- }
-}, 'util.p: Use console.error() instead');
-
-
-exports.exec = exports.deprecate(function() {
- return require('child_process').exec.apply(this, arguments);
-}, 'util.exec is now called `child_process.exec`.');
-
-
-exports.print = exports.deprecate(function() {
- for (var i = 0, len = arguments.length; i < len; ++i) {
- process.stdout.write(String(arguments[i]));
- }
-}, 'util.print: Use console.log instead');
-
-
-exports.puts = exports.deprecate(function() {
- for (var i = 0, len = arguments.length; i < len; ++i) {
- process.stdout.write(arguments[i] + '\n');
- }
-}, 'util.puts: Use console.log instead');
-
-
-exports.debug = exports.deprecate(function(x) {
- process.stderr.write('DEBUG: ' + x + '\n');
-}, 'util.debug: Use console.error instead');
-
-
-exports.error = exports.deprecate(function(x) {
- for (var i = 0, len = arguments.length; i < len; ++i) {
- process.stderr.write(arguments[i] + '\n');
- }
-}, 'util.error: Use console.error instead');
-
-
-exports.pump = exports.deprecate(function(readStream, writeStream, callback) {
- var callbackCalled = false;
-
- function call(a, b, c) {
- if (callback && !callbackCalled) {
- callback(a, b, c);
- callbackCalled = true;
- }
- }
-
- readStream.addListener('data', function(chunk) {
- if (writeStream.write(chunk) === false) readStream.pause();
- });
-
- writeStream.addListener('drain', function() {
- readStream.resume();
- });
-
- readStream.addListener('end', function() {
- writeStream.end();
- });
-
- readStream.addListener('close', function() {
- call();
- });
-
- readStream.addListener('error', function(err) {
- writeStream.end();
- call(err);
- });
-
- writeStream.addListener('error', function(err) {
- readStream.destroy();
- call(err);
- });
-}, 'util.pump(): Use readableStream.pipe() instead');
-
-
-var uv;
-exports._errnoException = function(err, syscall) {
- if (isUndefined(uv)) uv = process.binding('uv');
- var errname = uv.errname(err);
- var e = new Error(syscall + ' ' + errname);
- e.code = errname;
- e.errno = errname;
- e.syscall = syscall;
- return e;
-};
+}
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// NOTE: These type checking functions intentionally don't use `instanceof`
// because it is fragile and can be easily faked with `Object.create()`.
function isArray(ar) {
return Array.isArray(ar);
}
exports.isArray = isArray;
function isBoolean(arg) {
return typeof arg === 'boolean';
}
exports.isBoolean = isBoolean;
function isNull(arg) {
return arg === null;
}
exports.isNull = isNull;
function isNullOrUndefined(arg) {
return arg == null;
}
exports.isNullOrUndefined = isNullOrUndefined;
function isNumber(arg) {
return typeof arg === 'number';
}
exports.isNumber = isNumber;
function isString(arg) {
return typeof arg === 'string';
}
exports.isString = isString;
function isSymbol(arg) {
return typeof arg === 'symbol';
}
exports.isSymbol = isSymbol;
function isUndefined(arg) {
return arg === void 0;
}
exports.isUndefined = isUndefined;
function isRegExp(re) {
return isObject(re) && objectToString(re) === '[object RegExp]';
}
exports.isRegExp = isRegExp;
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
exports.isObject = isObject;
function isDate(d) {
return isObject(d) && objectToString(d) === '[object Date]';
}
exports.isDate = isDate;
function isError(e) {
return isObject(e) &&
(objectToString(e) === '[object Error]' || e instanceof Error);
}
exports.isError = isError;
function isFunction(arg) {
return typeof arg === 'function';
}
exports.isFunction = isFunction;
function isPrimitive(arg) {
return arg === null ||
typeof arg === 'boolean' ||
typeof arg === 'number' ||
typeof arg === 'string' ||
typeof arg === 'symbol' || // ES6 symbol
typeof arg === 'undefined';
}
exports.isPrimitive = isPrimitive;
function isBuffer(arg) {
return Buffer.isBuffer(arg);
}
exports.isBuffer = isBuffer;
function objectToString(o) {
return Object.prototype.toString.call(o);
}
{
"name": "core-util-is",
"version": "1.0.1",
"description": "The `util.is*` functions introduced in Node v0.12.",
"main": "lib/util.js",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/core-util-is"
},
"keywords": [
"util",
"isBuffer",
"isArray",
"isNumber",
"isString",
"isRegExp",
"isThis",
"isThat",
"polyfill"
],
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me",
"url": "http://blog.izs.me/"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/isaacs/core-util-is/issues"
},
"readme": "# core-util-is\n\nThe `util.is*` functions introduced in Node v0.12.\n",
"readmeFilename": "README.md",
"homepage": "https://github.com/isaacs/core-util-is",
"_id": "core-util-is@1.0.1",
"_shasum": "6b07085aef9a3ccac6ee53bf9d3df0c1521a5538",
"_from": "core-util-is@~1.0.0",
"_resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz",
"scripts": {}
}
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// NOTE: These type checking functions intentionally don't use `instanceof`
// because it is fragile and can be easily faked with `Object.create()`.
function isArray(ar) {
return Array.isArray(ar);
}
exports.isArray = isArray;
function isBoolean(arg) {
return typeof arg === 'boolean';
}
exports.isBoolean = isBoolean;
function isNull(arg) {
return arg === null;
}
exports.isNull = isNull;
function isNullOrUndefined(arg) {
return arg == null;
}
exports.isNullOrUndefined = isNullOrUndefined;
function isNumber(arg) {
return typeof arg === 'number';
}
exports.isNumber = isNumber;
function isString(arg) {
return typeof arg === 'string';
}
exports.isString = isString;
function isSymbol(arg) {
return typeof arg === 'symbol';
}
exports.isSymbol = isSymbol;
function isUndefined(arg) {
return arg === void 0;
}
exports.isUndefined = isUndefined;
function isRegExp(re) {
return isObject(re) && objectToString(re) === '[object RegExp]';
}
exports.isRegExp = isRegExp;
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
exports.isObject = isObject;
function isDate(d) {
return isObject(d) && objectToString(d) === '[object Date]';
}
exports.isDate = isDate;
function isError(e) {
return isObject(e) && objectToString(e) === '[object Error]';
}
exports.isError = isError;
function isFunction(arg) {
return typeof arg === 'function';
}
exports.isFunction = isFunction;
function isPrimitive(arg) {
return arg === null ||
typeof arg === 'boolean' ||
typeof arg === 'number' ||
typeof arg === 'string' ||
typeof arg === 'symbol' || // ES6 symbol
typeof arg === 'undefined';
}
exports.isPrimitive = isPrimitive;
function isBuffer(arg) {
return arg instanceof Buffer;
}
exports.isBuffer = isBuffer;
function objectToString(o) {
return Object.prototype.toString.call(o);
}
if (typeof Object.create === 'function') {
// implementation from standard node.js 'util' module
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};
} else {
// old school shim for old browsers
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
var TempCtor = function () {}
TempCtor.prototype = superCtor.prototype
ctor.prototype = new TempCtor()
ctor.prototype.constructor = ctor
}
}
The ISC License
Copyright (c) Isaac Z. Schlueter
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
{
"name": "inherits",
"description": "Browser-friendly inheritance fully compatible with standard node.js inherits()",
"version": "2.0.1",
"keywords": [
"inheritance",
"class",
"klass",
"oop",
"object-oriented",
"inherits",
"browser",
"browserify"
],
"main": "./inherits.js",
"browser": "./inherits_browser.js",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/inherits"
},
"license": "ISC",
"scripts": {
"test": "node test"
},
"readme": "Browser-friendly inheritance fully compatible with standard node.js\n[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).\n\nThis package exports standard `inherits` from node.js `util` module in\nnode environment, but also provides alternative browser-friendly\nimplementation through [browser\nfield](https://gist.github.com/shtylman/4339901). Alternative\nimplementation is a literal copy of standard one located in standalone\nmodule to avoid requiring of `util`. It also has a shim for old\nbrowsers with no `Object.create` support.\n\nWhile keeping you sure you are using standard `inherits`\nimplementation in node.js environment, it allows bundlers such as\n[browserify](https://github.com/substack/node-browserify) to not\ninclude full `util` package to your client code if all you need is\njust `inherits` function. It worth, because browser shim for `util`\npackage is large and `inherits` is often the single function you need\nfrom it.\n\nIt's recommended to use this package instead of\n`require('util').inherits` for any code that has chances to be used\nnot only in node.js but in browser too.\n\n## usage\n\n```js\nvar inherits = require('inherits');\n// then use exactly as the standard one\n```\n\n## note on version ~1.0\n\nVersion ~1.0 had completely different motivation and is not compatible\nneither with 2.0 nor with standard node.js `inherits`.\n\nIf you are using version ~1.0 and planning to switch to ~2.0, be\ncareful:\n\n* new version uses `super_` instead of `super` for referencing\n superclass\n* new version overwrites current prototype while old one preserves any\n existing fields on it\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/isaacs/inherits/issues"
},
"homepage": "https://github.com/isaacs/inherits",
"_id": "inherits@2.0.1",
"_shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1",
"_from": "inherits@~2.0.1",
"_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
}

Browser-friendly inheritance fully compatible with standard node.js inherits.

This package exports standard inherits from node.js util module in node environment, but also provides alternative browser-friendly implementation through browser field. Alternative implementation is a literal copy of standard one located in standalone module to avoid requiring of util. It also has a shim for old browsers with no Object.create support.

While keeping you sure you are using standard inherits implementation in node.js environment, it allows bundlers such as browserify to not include full util package to your client code if all you need is just inherits function. It worth, because browser shim for util package is large and inherits is often the single function you need from it.

It's recommended to use this package instead of require('util').inherits for any code that has chances to be used not only in node.js but in browser too.

usage

var inherits = require('inherits');
// then use exactly as the standard one

note on version ~1.0

Version ~1.0 had completely different motivation and is not compatible neither with 2.0 nor with standard node.js inherits.

If you are using version ~1.0 and planning to switch to ~2.0, be careful:

  • new version uses super_ instead of super for referencing superclass
  • new version overwrites current prototype while old one preserves any existing fields on it
var inherits = require('./inherits.js')
var assert = require('assert')
function test(c) {
assert(c.constructor === Child)
assert(c.constructor.super_ === Parent)
assert(Object.getPrototypeOf(c) === Child.prototype)
assert(Object.getPrototypeOf(Object.getPrototypeOf(c)) === Parent.prototype)
assert(c instanceof Child)
assert(c instanceof Parent)
}
function Child() {
Parent.call(this)
test(this)
}
function Parent() {}
inherits(Child, Parent)
var c = new Child
test(c)
console.log('ok')
/**
* Require the given path.
*
* @param {String} path
* @return {Object} exports
* @api public
*/
function require(path, parent, orig) {
var resolved = require.resolve(path);
// lookup failed
if (null == resolved) {
orig = orig || path;
parent = parent || 'root';
var err = new Error('Failed to require "' + orig + '" from "' + parent + '"');
err.path = orig;
err.parent = parent;
err.require = true;
throw err;
}
var module = require.modules[resolved];
// perform real require()
// by invoking the module's
// registered function
if (!module.exports) {
module.exports = {};
module.client = module.component = true;
module.call(this, module.exports, require.relative(resolved), module);
}
return module.exports;
}
/**
* Registered modules.
*/
require.modules = {};
/**
* Registered aliases.
*/
require.aliases = {};
/**
* Resolve `path`.
*
* Lookup:
*
* - PATH/index.js
* - PATH.js
* - PATH
*
* @param {String} path
* @return {String} path or null
* @api private
*/
require.resolve = function(path) {
if (path.charAt(0) === '/') path = path.slice(1);
var index = path + '/index.js';
var paths = [
path,
path + '.js',
path + '.json',
path + '/index.js',
path + '/index.json'
];
for (var i = 0; i < paths.length; i++) {
var path = paths[i];
if (require.modules.hasOwnProperty(path)) return path;
}
if (require.aliases.hasOwnProperty(index)) {
return require.aliases[index];
}
};
/**
* Normalize `path` relative to the current path.
*
* @param {String} curr
* @param {String} path
* @return {String}
* @api private
*/
require.normalize = function(curr, path) {
var segs = [];
if ('.' != path.charAt(0)) return path;
curr = curr.split('/');
path = path.split('/');
for (var i = 0; i < path.length; ++i) {
if ('..' == path[i]) {
curr.pop();
} else if ('.' != path[i] && '' != path[i]) {
segs.push(path[i]);
}
}
return curr.concat(segs).join('/');
};
/**
* Register module at `path` with callback `definition`.
*
* @param {String} path
* @param {Function} definition
* @api private
*/
require.register = function(path, definition) {
require.modules[path] = definition;
};
/**
* Alias a module definition.
*
* @param {String} from
* @param {String} to
* @api private
*/
require.alias = function(from, to) {
if (!require.modules.hasOwnProperty(from)) {
throw new Error('Failed to alias "' + from + '", it does not exist');
}
require.aliases[to] = from;
};
/**
* Return a require function relative to the `parent` path.
*
* @param {String} parent
* @return {Function}
* @api private
*/
require.relative = function(parent) {
var p = require.normalize(parent, '..');
/**
* lastIndexOf helper.
*/
function lastIndexOf(arr, obj) {
var i = arr.length;
while (i--) {
if (arr[i] === obj) return i;
}
return -1;
}
/**
* The relative require() itself.
*/
function localRequire(path) {
var resolved = localRequire.resolve(path);
return require(resolved, parent, path);
}
/**
* Resolve relative to the parent.
*/
localRequire.resolve = function(path) {
var c = path.charAt(0);
if ('/' == c) return path.slice(1);
if ('.' == c) return require.normalize(p, path);
// resolve deps by returning
// the dep in the nearest "deps"
// directory
var segs = parent.split('/');
var i = lastIndexOf(segs, 'deps') + 1;
if (!i) i = 0;
path = segs.slice(0, i + 1).join('/') + '/deps/' + path;
return path;
};
/**
* Check if module is defined at `path`.
*/
localRequire.exists = function(path) {
return require.modules.hasOwnProperty(localRequire.resolve(path));
};
return localRequire;
};
require.register("isarray/index.js", function(exports, require, module){
module.exports = Array.isArray || function (arr) {
return Object.prototype.toString.call(arr) == '[object Array]';
};
});
require.alias("isarray/index.js", "isarray/index.js");
{
"name" : "isarray",
"description" : "Array#isArray for older browsers",
"version" : "0.0.1",
"repository" : "juliangruber/isarray",
"homepage": "https://github.com/juliangruber/isarray",
"main" : "index.js",
"scripts" : [
"index.js"
],
"dependencies" : {},
"keywords": ["browser","isarray","array"],
"author": {
"name": "Julian Gruber",
"email": "mail@juliangruber.com",
"url": "http://juliangruber.com"
},
"license": "MIT"
}
module.exports = Array.isArray || function (arr) {
return Object.prototype.toString.call(arr) == '[object Array]';
};
{
"name": "isarray",
"description": "Array#isArray for older browsers",
"version": "0.0.1",
"repository": {
"type": "git",
"url": "git://github.com/juliangruber/isarray.git"
},
"homepage": "https://github.com/juliangruber/isarray",
"main": "index.js",
"scripts": {
"test": "tap test/*.js"
},
"dependencies": {},
"devDependencies": {
"tap": "*"
},
"keywords": [
"browser",
"isarray",
"array"
],
"author": {
"name": "Julian Gruber",
"email": "mail@juliangruber.com",
"url": "http://juliangruber.com"
},
"license": "MIT",
"readme": "\n# isarray\n\n`Array#isArray` for older browsers.\n\n## Usage\n\n```js\nvar isArray = require('isarray');\n\nconsole.log(isArray([])); // => true\nconsole.log(isArray({})); // => false\n```\n\n## Installation\n\nWith [npm](http://npmjs.org) do\n\n```bash\n$ npm install isarray\n```\n\nThen bundle for the browser with\n[browserify](https://github.com/substack/browserify).\n\nWith [component](http://component.io) do\n\n```bash\n$ component install juliangruber/isarray\n```\n\n## License\n\n(MIT)\n\nCopyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/juliangruber/isarray/issues"
},
"_id": "isarray@0.0.1",
"_shasum": "8a18acfca9a8f4177e09abfc6038939b05d1eedf",
"_from": "isarray@0.0.1",
"_resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
}

isarray

Array#isArray for older browsers.

Usage

var isArray = require('isarray');

console.log(isArray([])); // => true
console.log(isArray({})); // => false

Installation

With npm do

$ npm install isarray

Then bundle for the browser with browserify.

With component do

$ component install juliangruber/isarray

License

(MIT)

Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var Buffer = require('buffer').Buffer;
var isBufferEncoding = Buffer.isEncoding
|| function(encoding) {
switch (encoding && encoding.toLowerCase()) {
case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;
default: return false;
}
}
function assertEncoding(encoding) {
if (encoding && !isBufferEncoding(encoding)) {
throw new Error('Unknown encoding: ' + encoding);
}
}
var StringDecoder = exports.StringDecoder = function(encoding) {
this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');
assertEncoding(encoding);
switch (this.encoding) {
case 'utf8':
// CESU-8 represents each of Surrogate Pair by 3-bytes
this.surrogateSize = 3;
break;
case 'ucs2':
case 'utf16le':
// UTF-16 represents each of Surrogate Pair by 2-bytes
this.surrogateSize = 2;
this.detectIncompleteChar = utf16DetectIncompleteChar;
break;
case 'base64':
// Base-64 stores 3 bytes in 4 chars, and pads the remainder.
this.surrogateSize = 3;
this.detectIncompleteChar = base64DetectIncompleteChar;
break;
default:
this.write = passThroughWrite;
return;
}
this.charBuffer = new Buffer(6);
this.charReceived = 0;
this.charLength = 0;
};
StringDecoder.prototype.write = function(buffer) {
var charStr = '';
var offset = 0;
// if our last write ended with an incomplete multibyte character
while (this.charLength) {
// determine how many remaining bytes this buffer has to offer for this char
var i = (buffer.length >= this.charLength - this.charReceived) ?
this.charLength - this.charReceived :
buffer.length;
// add the new bytes to the char buffer
buffer.copy(this.charBuffer, this.charReceived, offset, i);
this.charReceived += (i - offset);
offset = i;
if (this.charReceived < this.charLength) {
// still not enough chars in this buffer? wait for more ...
return '';
}
// get the character that was split
charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);
// lead surrogate (D800-DBFF) is also the incomplete character
var charCode = charStr.charCodeAt(charStr.length - 1);
if (charCode >= 0xD800 && charCode <= 0xDBFF) {
this.charLength += this.surrogateSize;
charStr = '';
continue;
}
this.charReceived = this.charLength = 0;
// if there are no more bytes in this buffer, just emit our char
if (i == buffer.length) return charStr;
// otherwise cut off the characters end from the beginning of this buffer
buffer = buffer.slice(i, buffer.length);
break;
}
var lenIncomplete = this.detectIncompleteChar(buffer);
var end = buffer.length;
if (this.charLength) {
// buffer the incomplete character bytes we got
buffer.copy(this.charBuffer, 0, buffer.length - lenIncomplete, end);
this.charReceived = lenIncomplete;
end -= lenIncomplete;
}
charStr += buffer.toString(this.encoding, 0, end);
var end = charStr.length - 1;
var charCode = charStr.charCodeAt(end);
// lead surrogate (D800-DBFF) is also the incomplete character
if (charCode >= 0xD800 && charCode <= 0xDBFF) {
var size = this.surrogateSize;
this.charLength += size;
this.charReceived += size;
this.charBuffer.copy(this.charBuffer, size, 0, size);
this.charBuffer.write(charStr.charAt(charStr.length - 1), this.encoding);
return charStr.substring(0, end);
}
// or just emit the charStr
return charStr;
};
StringDecoder.prototype.detectIncompleteChar = function(buffer) {
// determine how many bytes we have to check at the end of this buffer
var i = (buffer.length >= 3) ? 3 : buffer.length;
// Figure out if one of the last i bytes of our buffer announces an
// incomplete char.
for (; i > 0; i--) {
var c = buffer[buffer.length - i];
// See http://en.wikipedia.org/wiki/UTF-8#Description
// 110XXXXX
if (i == 1 && c >> 5 == 0x06) {
this.charLength = 2;
break;
}
// 1110XXXX
if (i <= 2 && c >> 4 == 0x0E) {
this.charLength = 3;
break;
}
// 11110XXX
if (i <= 3 && c >> 3 == 0x1E) {
this.charLength = 4;
break;
}
}
return i;
};
StringDecoder.prototype.end = function(buffer) {
var res = '';
if (buffer && buffer.length)
res = this.write(buffer);
if (this.charReceived) {
var cr = this.charReceived;
var buf = this.charBuffer;
var enc = this.encoding;
res += buf.slice(0, cr).toString(enc);
}
return res;
};
function passThroughWrite(buffer) {
return buffer.toString(this.encoding);
}
function utf16DetectIncompleteChar(buffer) {
var incomplete = this.charReceived = buffer.length % 2;
this.charLength = incomplete ? 2 : 0;
return incomplete;
}
function base64DetectIncompleteChar(buffer) {
var incomplete = this.charReceived = buffer.length % 3;
this.charLength = incomplete ? 3 : 0;
return incomplete;
}
Copyright Joyent, Inc. and other Node contributors.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
{
"name": "string_decoder",
"version": "0.10.25-1",
"description": "The string_decoder module from Node core",
"main": "index.js",
"dependencies": {},
"devDependencies": {
"tap": "~0.4.8"
},
"scripts": {
"test": "tap test/simple/*.js"
},
"repository": {
"type": "git",
"url": "git://github.com/rvagg/string_decoder.git"
},
"homepage": "https://github.com/rvagg/string_decoder",
"keywords": [
"string",
"decoder",
"browser",
"browserify"
],
"license": "MIT",
"readme": "**string_decoder.js** (`require('string_decoder')`) from Node.js core\n\nCopyright Joyent, Inc. and other Node contributors. See LICENCE file for details.\n\nVersion numbers match the versions found in Node core, e.g. 0.10.24 matches Node 0.10.24, likewise 0.11.10 matches Node 0.11.10. **Prefer the stable version over the unstable.**\n\nThe *build/* directory contains a build script that will scrape the source from the [joyent/node](https://github.com/joyent/node) repo given a specific Node version.",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/rvagg/string_decoder/issues"
},
"_id": "string_decoder@0.10.25-1",
"_shasum": "f387babd95d23a2bb73b1fbf2cb3efab6f78baab",
"_from": "string_decoder@~0.10.x",
"_resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.25-1.tgz"
}

string_decoder.js (require('string_decoder')) from Node.js core

Copyright Joyent, Inc. and other Node contributors. See LICENCE file for details.

Version numbers match the versions found in Node core, e.g. 0.10.24 matches Node 0.10.24, likewise 0.11.10 matches Node 0.11.10. Prefer the stable version over the unstable.

The build/ directory contains a build script that will scrape the source from the joyent/node repo given a specific Node version.

{
"name": "readable-stream",
"version": "1.1.13-1",
"description": "Streams3, a user-land copy of the stream library from Node.js v0.11.x",
"main": "readable.js",
"dependencies": {
"core-util-is": "~1.0.0",
"isarray": "0.0.1",
"string_decoder": "~0.10.x",
"inherits": "~2.0.1"
},
"devDependencies": {
"tap": "~0.2.6"
},
"scripts": {
"test": "tap test/simple/*.js"
},
"repository": {
"type": "git",
"url": "git://github.com/isaacs/readable-stream"
},
"keywords": [
"readable",
"stream",
"pipe"
],
"browser": {
"util": false
},
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me",
"url": "http://blog.izs.me/"
},
"license": "MIT",
"readme": "# readable-stream\n\n***Node-core streams for userland***\n\n[![NPM](https://nodei.co/npm/readable-stream.png?downloads=true)](https://nodei.co/npm/readable-stream/)\n[![NPM](https://nodei.co/npm-dl/readable-stream.png)](https://nodei.co/npm/readable-stream/)\n\nThis package is a mirror of the Streams2 and Streams3 implementations in Node-core.\n\nIf you want to guarantee a stable streams base, regardless of what version of Node you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *\"stream\"* module in Node-core.\n\n**readable-stream** comes in two major versions, v1.0.x and v1.1.x. The former tracks the Streams2 implementation in Node 0.10, including bug-fixes and minor improvements as they are added. The latter tracks Streams3 as it develops in Node 0.11; we will likely see a v1.2.x branch for Node 0.12.\n\n**readable-stream** uses proper patch-level versioning so if you pin to `\"~1.0.0\"` you’ll get the latest Node 0.10 Streams2 implementation, including any fixes and minor non-breaking improvements. The patch-level versions of 1.0.x and 1.1.x should mirror the patch-level versions of Node-core releases. You should prefer the **1.0.x** releases for now and when you’re ready to start using Streams3, pin to `\"~1.1.0\"`\n\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/isaacs/readable-stream/issues"
},
"homepage": "https://github.com/isaacs/readable-stream",
"_id": "readable-stream@1.1.13-1",
"_shasum": "fc6f04f3366bf37bae21bec2e411c1b4d2cf1a46",
"_from": "readable-stream@~1.1.13",
"_resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13-1.tgz"
}
module.exports = require("./lib/_stream_passthrough.js")
exports = module.exports = require('./lib/_stream_readable.js');
exports.Stream = require('stream');
exports.Readable = exports;
exports.Writable = require('./lib/_stream_writable.js');
exports.Duplex = require('./lib/_stream_duplex.js');
exports.Transform = require('./lib/_stream_transform.js');
exports.PassThrough = require('./lib/_stream_passthrough.js');

readable-stream

Node-core streams for userland

NPM NPM

This package is a mirror of the Streams2 and Streams3 implementations in Node-core.

If you want to guarantee a stable streams base, regardless of what version of Node you, or the users of your libraries are using, use readable-stream only and avoid the "stream" module in Node-core.

readable-stream comes in two major versions, v1.0.x and v1.1.x. The former tracks the Streams2 implementation in Node 0.10, including bug-fixes and minor improvements as they are added. The latter tracks Streams3 as it develops in Node 0.11; we will likely see a v1.2.x branch for Node 0.12.

readable-stream uses proper patch-level versioning so if you pin to "~1.0.0" you’ll get the latest Node 0.10 Streams2 implementation, including any fixes and minor non-breaking improvements. The patch-level versions of 1.0.x and 1.1.x should mirror the patch-level versions of Node-core releases. You should prefer the 1.0.x releases for now and when you’re ready to start using Streams3, pin to "~1.1.0"

module.exports = require("./lib/_stream_transform.js")
module.exports = require("./lib/_stream_writable.js")
var fs = require('fs');
module.exports = function requireAll(options) {
if (typeof options === 'string') {
options = {
dirname: options,
filter: /(.+)\.js(on)?$/,
excludeDirs: /^\.(git|svn)$/
};
}
var files = fs.readdirSync(options.dirname);
var modules = {};
function excludeDirectory(dirname) {
return options.excludeDirs && dirname.match(options.excludeDirs);
}
files.forEach(function (file) {
var filepath = options.dirname + '/' + file;
if (fs.statSync(filepath).isDirectory()) {
if (excludeDirectory(file)) return;
modules[file] = requireAll({
dirname: filepath,
filter: options.filter,
excludeDirs: options.excludeDirs
});
} else {
var match = file.match(options.filter);
if (!match) return;
modules[match[1]] = require(filepath);
}
});
return modules;
};
Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
{
"author": {
"name": "Felix Geisendörfer",
"email": "felix@debuggable.com",
"url": "http://debuggable.com/"
},
"name": "require-all",
"description": "An easy way to require all files within a directory.",
"version": "0.0.8",
"scripts": {
"test": "node test/test.js"
},
"repository": {
"type": "git",
"url": "git://github.com/felixge/node-require-all.git"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/felixge/node-require-all/blob/master/License"
}
],
"main": "./index",
"engines": {
"node": "*"
},
"dependencies": {},
"devDependencies": {
"semver": "~2.1.0"
},
"optionalDependencies": {},
"readme": "# require-all\n\nAn easy way to require all files within a directory.\n\n## Usage\n\n```js\nvar controllers = require('require-all')({\n dirname : __dirname + '/controllers',\n filter : /(.+Controller)\\.js$/,\n excludeDirs : /^\\.(git|svn)$/\n});\n\n// controllers now is an object with references to all modules matching the filter\n// for example:\n// { HomeController: function HomeController() {...}, ...}\n```\n\n## Advanced usage\n\nIf your objective is to simply require all .js and .json files in a directory you can just pass a string to require-all:\n\n``` js\nvar libs = require('require-all')(__dirname + '/lib');\n```\n",
"readmeFilename": "Readme.md",
"bugs": {
"url": "https://github.com/felixge/node-require-all/issues"
},
"homepage": "https://github.com/felixge/node-require-all",
"_id": "require-all@0.0.8",
"_shasum": "a7d4307d90e422fcb9f04af018c149920074e4b3",
"_from": "require-all@0.0.8",
"_resolved": "https://registry.npmjs.org/require-all/-/require-all-0.0.8.tgz"
}

require-all

An easy way to require all files within a directory.

Usage

var controllers = require('require-all')({
  dirname     :  __dirname + '/controllers',
  filter      :  /(.+Controller)\.js$/,
  excludeDirs :  /^\.(git|svn)$/
});

// controllers now is an object with references to all modules matching the filter
// for example:
// { HomeController: function HomeController() {...}, ...}

Advanced usage

If your objective is to simply require all .js and .json files in a directory you can just pass a string to require-all:

var libs = require('require-all')(__dirname + '/lib');
exports.index = 1;
exports.show = 2;
exports.add = 3;
exports.edit = 4;
var assert = require('assert');
var semver = require('semver');
var requireAll = require('..');
var controllers = requireAll({
dirname: __dirname + '/controllers',
filter: /(.+Controller)\.js$/
});
assert.deepEqual(controllers, {
'main-Controller': {
index: 1,
show: 2,
add: 3,
edit: 4
},
'other-Controller': {
index: 1,
show: 'nothing'
}
});
//
// requiring json only became an option in 0.6+
//
if (semver.gt(process.version, 'v0.6.0')) {
var mydir = requireAll({
dirname: __dirname + '/mydir',
filter: /(.+)\.(js|json)$/
});
var mydir_contents = {
foo: 'bar',
hello: {
world: true,
universe: 42
},
sub: {
config: {
settingA: 'A',
settingB: 'B'
},
yes: true
}
};
assert.deepEqual(mydir, mydir_contents);
var defaults = requireAll(__dirname + '/mydir');
assert.deepEqual(defaults, mydir_contents);
}
var unfiltered = requireAll({
dirname: __dirname + '/filterdir',
filter: /(.+)\.js$/
});
assert(unfiltered['.svn']);
assert(unfiltered.root);
assert(unfiltered.sub);
var excludedSvn = requireAll({
dirname: __dirname + '/filterdir',
filter: /(.+)\.js$/,
excludeDirs: /^\.svn$/
});
assert.equal(excludedSvn['.svn'], undefined);
assert.ok(excludedSvn.root);
assert.ok(excludedSvn.sub);
var excludedSvnAndSub = requireAll({
dirname: __dirname + '/filterdir',
filter: /(.+)\.js$/,
excludeDirs: /^(\.svn|sub)$/
});
assert.equal(excludedSvnAndSub['.svn'], undefined);
assert.ok(excludedSvnAndSub.root);
assert.equal(excludedSvnAndSub.sub, undefined);
{
"name": "mysql",
"description": "A node.js driver for mysql. It is written in JavaScript, does not require compiling, and is 100% MIT licensed.",
"version": "2.3.2",
"license": "MIT",
"author": {
"name": "Felix Geisendörfer",
"email": "felix@debuggable.com",
"url": "http://debuggable.com/"
},
"contributors": [
{
"name": "Andrey Sidorov",
"email": "sidorares@yandex.ru"
},
{
"name": "Douglas Christopher Wilson",
"email": "doug@somethingdoug.com"
},
{
"name": "Diogo Resende",
"email": "dresende@thinkdigital.pt"
}
],
"homepage": "https://github.com/felixge/node-mysql",
"repository": {
"type": "git",
"url": "https://github.com/felixge/node-mysql"
},
"main": "./index",
"scripts": {
"test": "node test/run.js"
},
"dependencies": {
"bignumber.js": "1.4.0",
"readable-stream": "~1.1.13",
"require-all": "0.0.8"
},
"devDependencies": {
"underscore": "1.6.0",
"urun": "0.0.8",
"utest": "0.0.8"
},
"engines": {
"node": ">= 0.8"
},
"readme": "# mysql [![Build Status](https://travis-ci.org/felixge/node-mysql.svg?branch=master)](https://travis-ci.org/felixge/node-mysql) [![NPM version](https://badge.fury.io/js/mysql.svg)](http://badge.fury.io/js/mysql)\n\n## Install\n\n```sh\n$ npm install mysql\n```\n\nFor information about the previous 0.9.x releases, visit the [v0.9 branch][].\n\nSometimes I may also ask you to install the latest version from Github to check\nif a bugfix is working. In this case, please do:\n\n```sh\n$ npm install felixge/node-mysql\n```\n\n[v0.9 branch]: https://github.com/felixge/node-mysql/tree/v0.9\n\n## Introduction\n\nThis is a node.js driver for mysql. It is written in JavaScript, does not\nrequire compiling, and is 100% MIT licensed.\n\nHere is an example on how to use it:\n\n```js\nvar mysql = require('mysql');\nvar connection = mysql.createConnection({\n host : 'localhost',\n user : 'me',\n password : 'secret'\n});\n\nconnection.connect();\n\nconnection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {\n if (err) throw err;\n\n console.log('The solution is: ', rows[0].solution);\n});\n\nconnection.end();\n```\n\nFrom this example, you can learn the following:\n\n* Every method you invoke on a connection is queued and executed in sequence.\n* Closing the connection is done using `end()` which makes sure all remaining\n queries are executed before sending a quit packet to the mysql server.\n\n## Contributors\n\nThanks goes to the people who have contributed code to this module, see the\n[GitHub Contributors page][].\n\n[GitHub Contributors page]: https://github.com/felixge/node-mysql/graphs/contributors\n\nAdditionally I'd like to thank the following people:\n\n* [Andrey Hristov][] (Oracle) - for helping me with protocol questions.\n* [Ulf Wendel][] (Oracle) - for helping me with protocol questions.\n\n[Ulf Wendel]: http://blog.ulf-wendel.de/\n[Andrey Hristov]: http://andrey.hristov.com/\n\n## Sponsors\n\nThe following companies have supported this project financially, allowing me to\nspend more time on it (ordered by time of contribution):\n\n* [Transloadit](http://transloadit.com) (my startup, we do file uploading &\n video encoding as a service, check it out)\n* [Joyent](http://www.joyent.com/)\n* [pinkbike.com](http://pinkbike.com/)\n* [Holiday Extras](http://www.holidayextras.co.uk/) (they are [hiring](http://join.holidayextras.co.uk/vacancy/software-engineer/))\n* [Newscope](http://newscope.com/) (they are [hiring](http://www.newscope.com/stellenangebote))\n\nIf you are interested in sponsoring a day or more of my time, please\n[get in touch][].\n\n[get in touch]: http://felixge.de/#consulting\n\n## Community\n\nIf you'd like to discuss this module, or ask questions about it, please use one\nof the following:\n\n* **Mailing list**: https://groups.google.com/forum/#!forum/node-mysql\n* **IRC Channel**: #node.js (on freenode.net, I pay attention to any message\n including the term `mysql`)\n\n## Establishing connections\n\nThe recommended way to establish a connection is this:\n\n```js\nvar mysql = require('mysql');\nvar connection = mysql.createConnection({\n host : 'example.org',\n user : 'bob',\n password : 'secret'\n});\n\nconnection.connect(function(err) {\n if (err) {\n console.error('error connecting: ' + err.stack);\n return;\n }\n\n console.log('connected as id ' + connection.threadId);\n});\n```\n\nHowever, a connection can also be implicitly established by invoking a query:\n\n```js\nvar mysql = require('mysql');\nvar connection = mysql.createConnection(...);\n\nconnection.query('SELECT 1', function(err, rows) {\n // connected! (unless `err` is set)\n});\n```\n\nDepending on how you like to handle your errors, either method may be\nappropriate. Any type of connection error (handshake or network) is considered\na fatal error, see the [Error Handling](#error-handling) section for more\ninformation.\n\n## Connection options\n\nWhen establishing a connection, you can set the following options:\n\n* `host`: The hostname of the database you are connecting to. (Default:\n `localhost`)\n* `port`: The port number to connect to. (Default: `3306`)\n* `localAddress`: The source IP address to use for TCP connection. (Optional)\n* `socketPath`: The path to a unix domain socket to connect to. When used `host`\n and `port` are ignored.\n* `user`: The MySQL user to authenticate as.\n* `password`: The password of that MySQL user.\n* `database`: Name of the database to use for this connection (Optional).\n* `charset`: The charset for the connection. This is called \"collation\" in the SQL-level\n of MySQL (like `utf8_general_ci`). If a SQL-level charset is specified (like `utf8mb4`)\n then the default collation for that charset is used. (Default: `'UTF8_GENERAL_CI'`)\n* `timezone`: The timezone used to store local dates. (Default: `'local'`)\n* `connectTimeout`: The milliseconds before a timeout occurs during the initial connection\n to the MySQL server. (Default: 2 minutes)\n* `stringifyObjects`: Stringify objects instead of converting to values. See\nissue [#501](https://github.com/felixge/node-mysql/issues/501). (Default: `'false'`)\n* `insecureAuth`: Allow connecting to MySQL instances that ask for the old\n (insecure) authentication method. (Default: `false`)\n* `typeCast`: Determines if column values should be converted to native\n JavaScript types. (Default: `true`)\n* `queryFormat`: A custom query format function. See [Custom format](#custom-format).\n* `supportBigNumbers`: When dealing with big numbers (BIGINT and DECIMAL columns) in the database,\n you should enable this option (Default: `false`).\n* `bigNumberStrings`: Enabling both `supportBigNumbers` and `bigNumberStrings` forces big numbers\n (BIGINT and DECIMAL columns) to be always returned as JavaScript String objects (Default: `false`).\n Enabling `supportBigNumbers` but leaving `bigNumberStrings` disabled will return big numbers as String\n objects only when they cannot be accurately represented with [JavaScript Number objects] (http://ecma262-5.com/ELS5_HTML.htm#Section_8.5)\n (which happens when they exceed the [-2^53, +2^53] range), otherwise they will be returned as\n Number objects. This option is ignored if `supportBigNumbers` is disabled.\n* `dateStrings`: Force date types (TIMESTAMP, DATETIME, DATE) to be returned as strings rather then\n inflated into JavaScript Date objects. (Default: `false`)\n* `debug`: Prints protocol details to stdout. (Default: `false`)\n* `trace`: Generates stack traces on `Error` to include call site of library\n entrance (\"long stack traces\"). Slight performance penalty for most calls.\n (Default: `true`)\n* `multipleStatements`: Allow multiple mysql statements per query. Be careful\n with this, it exposes you to SQL injection attacks. (Default: `false`)\n* `flags`: List of connection flags to use other than the default ones. It is\n also possible to blacklist default ones. For more information, check [Connection Flags](#connection-flags).\n* `ssl`: object with ssl parameters or a string containing name of ssl profile. See [SSL options](#ssl-options).\n\n\nIn addition to passing these options as an object, you can also use a url\nstring. For example:\n\n```js\nvar connection = mysql.createConnection('mysql://user:pass@host/db?debug=true&charset=BIG5_CHINESE_CI&timezone=-0700');\n```\n\nNote: The query values are first attempted to be parsed as JSON, and if that\nfails assumed to be plaintext strings.\n\n### SSL options\n\nThe `ssl` option in the connection options takes a string or an object. When given a string,\nit uses one of the predefined SSL profiles included. The following profiles are included:\n\n* `\"Amazon RDS\"`: this profile is for connecting to an Amazon RDS server and contains the\r\n ca from https://rds.amazonaws.com/doc/rds-ssl-ca-cert.pem\r\n\r\nWhen connecting to other servers, you will need to provide an object of options, in the\nsame format as [crypto.createCredentials](http://nodejs.org/api/crypto.html#crypto_crypto_createcredentials_details).\nPlease note the arguments expect a string of the certificate, not a file name to the\ncertificate. Here is a simple example:\n\n```js\nvar connection = mysql.createConnection({\n host : 'localhost',\n ssl : {\n ca : fs.readFileSync(__dirname + '/mysql-ca.crt')\n }\n});\n```\n\nYou can also connect to a MySQL server without properly providing the appropriate\nCA to trust. _You should not do this_.\n\n```js\nvar connection = mysql.createConnection({\n host : 'localhost',\n ssl : {\n // DO NOT DO THIS\n // set up your ca correctly to trust the connection\n rejectUnauthorized: false\n }\n});\n```\n\n## Terminating connections\n\nThere are two ways to end a connection. Terminating a connection gracefully is\ndone by calling the `end()` method:\n\n```js\nconnection.end(function(err) {\n // The connection is terminated now\n});\n```\n\nThis will make sure all previously enqueued queries are still before sending a\n`COM_QUIT` packet to the MySQL server. If a fatal error occurs before the\n`COM_QUIT` packet can be sent, an `err` argument will be provided to the\ncallback, but the connection will be terminated regardless of that.\n\nAn alternative way to end the connection is to call the `destroy()` method.\nThis will cause an immediate termination of the underlying socket.\nAdditionally `destroy()` guarantees that no more events or callbacks will be\ntriggered for the connection.\n\n```js\nconnection.destroy();\n```\n\nUnlike `end()` the `destroy()` method does not take a callback argument.\n\n## Pooling connections\n\nUse pool directly.\n```js\nvar mysql = require('mysql');\nvar pool = mysql.createPool({\n connectionLimit : 10,\n host : 'example.org',\n user : 'bob',\n password : 'secret'\n});\n\npool.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {\n if (err) throw err;\n\n console.log('The solution is: ', rows[0].solution);\n});\n```\n\nConnections can be pooled to ease sharing a single connection, or managing\nmultiple connections.\n\n```js\nvar mysql = require('mysql');\nvar pool = mysql.createPool({\n host : 'example.org',\n user : 'bob',\n password : 'secret'\n});\n\npool.getConnection(function(err, connection) {\n // connected! (unless `err` is set)\n});\n```\n\nIf you need to set session variables on the connection before it gets used,\nyou can listen to the `connection` event.\n\n```js\npool.on('connection', function(connection) {\n connection.query('SET SESSION auto_increment_increment=1')\n});\n```\n\nWhen you are done with a connection, just call `connection.release()` and the\nconnection will return to the pool, ready to be used again by someone else.\n\n```js\nvar mysql = require('mysql');\nvar pool = mysql.createPool(...);\n\npool.getConnection(function(err, connection) {\n // Use the connection\n connection.query( 'SELECT something FROM sometable', function(err, rows) {\n // And done with the connection.\n connection.release();\n\n // Don't use the connection here, it has been returned to the pool.\n });\n});\n```\n\nIf you would like to close the connection and remove it from the pool, use\n`connection.destroy()` instead. The pool will create a new connection the next\ntime one is needed.\n\nConnections are lazily created by the pool. If you configure the pool to allow\nup to 100 connections, but only ever use 5 simultaneously, only 5 connections\nwill be made. Connections are also cycled round-robin style, with connections\nbeing taken from the top of the pool and returning to the bottom.\n\nWhen a previous connection is retrieved from the pool, a ping packet is sent\nto the server to check if the connection is still good.\n\n## Pool options\n\nPools accept all the same options as a connection. When creating a new\nconnection, the options are simply passed to the connection constructor. In\naddition to those options pools accept a few extras:\n\n* `waitForConnections`: Determines the pool's action when no connections are\n available and the limit has been reached. If `true`, the pool will queue the\n connection request and call it when one becomes available. If `false`, the\n pool will immediately call back with an error. (Default: `true`)\n* `connectionLimit`: The maximum number of connections to create at once.\n (Default: `10`)\n* `queueLimit`: The maximum number of connection requests the pool will queue\n before returning an error from `getConnection`. If set to `0`, there is no\n limit to the number of queued connection requests. (Default: `0`)\n\n## PoolCluster\n\nPoolCluster provides multiple hosts connection. (group & retry & selector)\n\n```js\n// create\nvar poolCluster = mysql.createPoolCluster();\n\npoolCluster.add(config); // anonymous group\npoolCluster.add('MASTER', masterConfig);\npoolCluster.add('SLAVE1', slave1Config);\npoolCluster.add('SLAVE2', slave2Config);\n\n// Target Group : ALL(anonymous, MASTER, SLAVE1-2), Selector : round-robin(default)\npoolCluster.getConnection(function (err, connection) {});\n\n// Target Group : MASTER, Selector : round-robin\npoolCluster.getConnection('MASTER', function (err, connection) {});\n\n// Target Group : SLAVE1-2, Selector : order\n// If can't connect to SLAVE1, return SLAVE2. (remove SLAVE1 in the cluster)\npoolCluster.on('remove', function (nodeId) {\n console.log('REMOVED NODE : ' + nodeId); // nodeId = SLAVE1 \n});\n\npoolCluster.getConnection('SLAVE*', 'ORDER', function (err, connection) {});\n\n// of namespace : of(pattern, selector)\npoolCluster.of('*').getConnection(function (err, connection) {});\n\nvar pool = poolCluster.of('SLAVE*', 'RANDOM');\npool.getConnection(function (err, connection) {});\npool.getConnection(function (err, connection) {});\n\n// destroy\npoolCluster.end();\n```\n\n## PoolCluster Option\n* `canRetry`: If `true`, `PoolCluster` will attempt to reconnect when connection fails. (Default: `true`)\n* `removeNodeErrorCount`: If connection fails, node's `errorCount` increases. \n When `errorCount` is greater than `removeNodeErrorCount`, remove a node in the `PoolCluster`. (Default: `5`)\n* `defaultSelector`: The default selector. (Default: `RR`)\n * `RR`: Select one alternately. (Round-Robin)\n * `RANDOM`: Select the node by random function.\n * `ORDER`: Select the first node available unconditionally.\n\n```js\nvar clusterConfig = {\n removeNodeErrorCount: 1, // Remove the node immediately when connection fails.\n defaultSelector: 'ORDER'\n};\n\nvar poolCluster = mysql.createPoolCluster(clusterConfig);\n```\n\n## Switching users / altering connection state\n\nMySQL offers a changeUser command that allows you to alter the current user and\nother aspects of the connection without shutting down the underlying socket:\n\n```js\nconnection.changeUser({user : 'john'}, function(err) {\n if (err) throw err;\n});\n```\n\nThe available options for this feature are:\n\n* `user`: The name of the new user (defaults to the previous one).\n* `password`: The password of the new user (defaults to the previous one).\n* `charset`: The new charset (defaults to the previous one).\n* `database`: The new database (defaults to the previous one).\n\nA sometimes useful side effect of this functionality is that this function also\nresets any connection state (variables, transactions, etc.).\n\nErrors encountered during this operation are treated as fatal connection errors\nby this module.\n\n## Server disconnects\n\nYou may lose the connection to a MySQL server due to network problems, the\nserver timing you out, the server being restarted, or crashing. All of these\nevents are considered fatal errors, and will have the `err.code =\n'PROTOCOL_CONNECTION_LOST'`. See the [Error Handling](#error-handling) section\nfor more information.\n\nRe-connecting a connection is done by establishing a new connection. Once\nterminated, an existing connection object cannot be re-connected by design.\n\nWith Pool, disconnected connections will be removed from the pool freeing up\nspace for a new connection to be created on the next getConnection call.\n\n## Escaping query values\n\nIn order to avoid SQL Injection attacks, you should always escape any user\nprovided data before using it inside a SQL query. You can do so using the\n`connection.escape()` or `pool.escape()` methods:\n\n```js\nvar userId = 'some user provided value';\nvar sql = 'SELECT * FROM users WHERE id = ' + connection.escape(userId);\nconnection.query(sql, function(err, results) {\n // ...\n});\n```\n\nAlternatively, you can use `?` characters as placeholders for values you would\nlike to have escaped like this:\n\n```js\nconnection.query('SELECT * FROM users WHERE id = ?', [userId], function(err, results) {\n // ...\n});\n```\n\nThis looks similar to prepared statements in MySQL, however it really just uses\nthe same `connection.escape()` method internally.\n\n**Caution** This also differs from prepared statements in that all `?` are\nreplaced, even those contained in comments and strings.\n\nDifferent value types are escaped differently, here is how:\n\n* Numbers are left untouched\n* Booleans are converted to `true` / `false` strings\n* Date objects are converted to `'YYYY-mm-dd HH:ii:ss'` strings\n* Buffers are converted to hex strings, e.g. `X'0fa5'`\n* Strings are safely escaped\n* Arrays are turned into list, e.g. `['a', 'b']` turns into `'a', 'b'`\n* Nested arrays are turned into grouped lists (for bulk inserts), e.g. `[['a',\n 'b'], ['c', 'd']]` turns into `('a', 'b'), ('c', 'd')`\n* Objects are turned into `key = 'val'` pairs. Nested objects are cast to\n strings.\n* `undefined` / `null` are converted to `NULL`\n* `NaN` / `Infinity` are left as-is. MySQL does not support these, and trying\n to insert them as values will trigger MySQL errors until they implement\n support.\n\nIf you paid attention, you may have noticed that this escaping allows you\nto do neat things like this:\n\n```js\nvar post = {id: 1, title: 'Hello MySQL'};\nvar query = connection.query('INSERT INTO posts SET ?', post, function(err, result) {\n // Neat!\n});\nconsole.log(query.sql); // INSERT INTO posts SET `id` = 1, `title` = 'Hello MySQL'\n\n```\n\nIf you feel the need to escape queries by yourself, you can also use the escaping\nfunction directly:\n\n```js\nvar query = \"SELECT * FROM posts WHERE title=\" + mysql.escape(\"Hello MySQL\");\n\nconsole.log(query); // SELECT * FROM posts WHERE title='Hello MySQL'\n```\n\n## Escaping query identifiers\n\nIf you can't trust an SQL identifier (database / table / column name) because it is\nprovided by a user, you should escape it with `mysql.escapeId(identifier)` like this:\n\n```js\nvar sorter = 'date';\nvar query = 'SELECT * FROM posts ORDER BY ' + mysql.escapeId(sorter);\n\nconsole.log(query); // SELECT * FROM posts ORDER BY `date`\n```\n\nIt also supports adding qualified identifiers. It will escape both parts.\n\n```js\nvar sorter = 'date';\nvar query = 'SELECT * FROM posts ORDER BY ' + mysql.escapeId('posts.' + sorter);\n\nconsole.log(query); // SELECT * FROM posts ORDER BY `posts`.`date`\n```\n\nAlternatively, you can use `??` characters as placeholders for identifiers you would\nlike to have escaped like this:\n\n```js\nvar userId = 1;\nvar columns = ['username', 'email'];\nvar query = connection.query('SELECT ?? FROM ?? WHERE id = ?', [columns, 'users', userId], function(err, results) {\n // ...\n});\n\nconsole.log(query.sql); // SELECT `username`, `email` FROM `users` WHERE id = 1\n```\n**Please note that this last character sequence is experimental and syntax might change**\n\nWhen you pass an Object to `.escape()` or `.query()`, `.escapeId()` is used to avoid SQL injection in object keys.\n\n### Preparing Queries\n\nYou can use mysql.format to prepare a query with multiple insertion points, utilizing the proper escaping for ids and values. A simple example of this follows:\n\n```js\nvar sql = \"SELECT * FROM ?? WHERE ?? = ?\";\nvar inserts = ['users', 'id', userId];\nsql = mysql.format(sql, inserts);\n```\n\nFollowing this you then have a valid, escaped query that you can then send to the database safely. This is useful if you are looking to prepare the query before actually sending it to the database. As mysql.format is exposed from SqlString.format you also have the option (but are not required) to pass in stringifyObject and timezone, allowing you provide a custom means of turning objects into strings, as well as a location-specific/timezone-aware Date.\n\n### Custom format\n\nIf you prefer to have another type of query escape format, there's a connection configuration option you can use to define a custom format function. You can access the connection object if you want to use the built-in `.escape()` or any other connection function.\n\nHere's an example of how to implement another format:\n\n```js\nconnection.config.queryFormat = function (query, values) {\n if (!values) return query;\n return query.replace(/\\:(\\w+)/g, function (txt, key) {\n if (values.hasOwnProperty(key)) {\n return this.escape(values[key]);\n }\n return txt;\n }.bind(this));\n};\n\nconnection.query(\"UPDATE posts SET title = :title\", { title: \"Hello MySQL\" });\n```\n\n## Getting the id of an inserted row\n\nIf you are inserting a row into a table with an auto increment primary key, you\ncan retrieve the insert id like this:\n\n```js\nconnection.query('INSERT INTO posts SET ?', {title: 'test'}, function(err, result) {\n if (err) throw err;\n\n console.log(result.insertId);\n});\n```\n\nWhen dealing with big numbers (above JavaScript Number precision limit), you should\nconsider enabling `supportBigNumbers` option to be able to read the insert id as a\nstring, otherwise it will throw.\n\nThis option is also required when fetching big numbers from the database, otherwise\nyou will get values rounded to hundreds or thousands due to the precision limit.\n\n## Getting the number of affected rows.\n\nYou can get the number of affected rows from an insert, update or delete statement.\n\n```js\nconnection.query('DELETE FROM posts WHERE title = \"wrong\"', function (err, result) {\n if (err) throw err;\n\n console.log('deleted ' + result.affectedRows + ' rows');\n})\n```\n\n## Getting the number of changed rows.\n\nYou can get the number of changed rows from an update statement.\n\n\"changedRows\" differs from \"affectedRows\" in that it does not count updated rows\nwhose values were not changed.\n\n```js\nconnection.query('UPDATE posts SET ...', function (err, response) {\n if (err) throw err;\n\n console.log('changed ' + result.changedRows + ' rows');\n})\n```\n\n## Getting the connection ID\n\nYou can get the MySQL connection ID (\"thread ID\") of a given connection using the `threadId`\nproperty.\n\n```js\nconnection.connect(function(err) {\n if (err) throw err;\n console.log('connected as id ' + connection.threadId);\n});\n```\n\n## Executing queries in parallel\n\nThe MySQL protocol is sequential, this means that you need multiple connections\nto execute queries in parallel. You can use a Pool to manage connections, one\nsimple approach is to create one connection per incoming http request.\n\n## Streaming query rows\n\nSometimes you may want to select large quantities of rows and process each of\nthem as they are received. This can be done like this:\n\n```js\nvar query = connection.query('SELECT * FROM posts');\nquery\n .on('error', function(err) {\n // Handle error, an 'end' event will be emitted after this as well\n })\n .on('fields', function(fields) {\n // the field packets for the rows to follow\n })\n .on('result', function(row) {\n // Pausing the connnection is useful if your processing involves I/O\n connection.pause();\n\n processRow(row, function() {\n connection.resume();\n });\n })\n .on('end', function() {\n // all rows have been received\n });\n```\n\nPlease note a few things about the example above:\n\n* Usually you will want to receive a certain amount of rows before starting to\n throttle the connection using `pause()`. This number will depend on the\n amount and size of your rows.\n* `pause()` / `resume()` operate on the underlying socket and parser. You are\n guaranteed that no more `'result'` events will fire after calling `pause()`.\n* You MUST NOT provide a callback to the `query()` method when streaming rows.\n* The `'result'` event will fire for both rows as well as OK packets\n confirming the success of a INSERT/UPDATE query.\n\nAdditionally you may be interested to know that it is currently not possible to\nstream individual row columns, they will always be buffered up entirely. If you\nhave a good use case for streaming large fields to and from MySQL, I'd love to\nget your thoughts and contributions on this.\n\n### Piping results with [Streams2](http://blog.nodejs.org/2012/12/20/streams2/)\n\nThe query object provides a convenience method `.stream([options])` that wraps\nquery events into a [Readable](http://nodejs.org/api/stream.html#stream_class_stream_readable)\nStreams2 object. This stream can easily be piped downstream and provides\nautomatic pause/resume, based on downstream congestion and the optional\n`highWaterMark`. The `objectMode` parameter of the stream is set to `true` by\ndefault.\n\nFor example, piping query results into another stream (with a max buffer of 5\nobjects) is simply:\n\n```js\nconnection.query('SELECT * FROM posts')\n .stream({highWaterMark: 5})\n .pipe(...);\n```\n\n## Multiple statement queries\n\nSupport for multiple statements is disabled for security reasons (it allows for\nSQL injection attacks if values are not properly escaped). To use this feature\nyou have to enable it for your connection:\n\n```js\nvar connection = mysql.createConnection({multipleStatements: true});\n```\n\nOnce enabled, you can execute multiple statement queries like any other query:\n\n```js\nconnection.query('SELECT 1; SELECT 2', function(err, results) {\n if (err) throw err;\n\n // `results` is an array with one element for every statement in the query:\n console.log(results[0]); // [{1: 1}]\n console.log(results[1]); // [{2: 2}]\n});\n```\n\nAdditionally you can also stream the results of multiple statement queries:\n\n```js\nvar query = connection.query('SELECT 1; SELECT 2');\n\nquery\n .on('fields', function(fields, index) {\n // the fields for the result rows that follow\n })\n .on('result', function(row, index) {\n // index refers to the statement this result belongs to (starts at 0)\n });\n```\n\nIf one of the statements in your query causes an error, the resulting Error\nobject contains a `err.index` property which tells you which statement caused\nit. MySQL will also stop executing any remaining statements when an error\noccurs.\n\nPlease note that the interface for streaming multiple statement queries is\nexperimental and I am looking forward to feedback on it.\n\n## Stored procedures\n\nYou can call stored procedures from your queries as with any other mysql driver.\nIf the stored procedure produces several result sets, they are exposed to you\nthe same way as the results for multiple statement queries.\n\n## Joins with overlapping column names\n\nWhen executing joins, you are likely to get result sets with overlapping column\nnames.\n\nBy default, node-mysql will overwrite colliding column names in the\norder the columns are received from MySQL, causing some of the received values\nto be unavailable.\n\nHowever, you can also specify that you want your columns to be nested below\nthe table name like this:\n\n```js\nvar options = {sql: '...', nestTables: true};\nconnection.query(options, function(err, results) {\n /* results will be an array like this now:\n [{\n table1: {\n fieldA: '...',\n fieldB: '...',\n },\n table2: {\n fieldA: '...',\n fieldB: '...',\n },\n }, ...]\n */\n});\n```\n\nOr use a string separator to have your results merged.\n\n```js\nvar options = {sql: '...', nestTables: '_'};\nconnection.query(options, function(err, results) {\n /* results will be an array like this now:\n [{\n table1_fieldA: '...',\n table1_fieldB: '...',\n table2_fieldA: '...',\n table2_fieldB: '...',\n }, ...]\n */\n});\n```\n\n## Transactions\n\nSimple transaction support is available at the connection level:\n\n```js\nconnection.beginTransaction(function(err) {\n if (err) { throw err; }\n connection.query('INSERT INTO posts SET title=?', title, function(err, result) {\n if (err) { \n connection.rollback(function() {\n throw err;\n });\n }\n\n\tvar log = 'Post ' + result.insertId + ' added';\n\n\tconnection.query('INSERT INTO log SET data=?', log, function(err, result) {\n\t if (err) { \n connection.rollback(function() {\n throw err;\n });\n } \n\t connection.commit(function(err) {\n\t if (err) { \n connection.rollback(function() {\n throw err;\n });\n }\n\t console.log('success!');\n\t });\n });\n });\n});\n```\nPlease note that beginTransaction(), commit() and rollback() are simply convenience\nfunctions that execute the START TRANSACTION, COMMIT, and ROLLBACK commands respectively.\nIt is important to understand that many commands in MySQL can cause an implicit commit,\nas described [in the MySQL documentation](http://dev.mysql.com/doc/refman/5.5/en/implicit-commit.html)\n\n## Error handling\n\nThis module comes with a consistent approach to error handling that you should\nreview carefully in order to write solid applications.\n\nAll errors created by this module are instances of the JavaScript [Error][]\nobject. Additionally they come with two properties:\n\n* `err.code`: Either a [MySQL server error][] (e.g.\n `'ER_ACCESS_DENIED_ERROR'`), a node.js error (e.g. `'ECONNREFUSED'`) or an\n internal error (e.g. `'PROTOCOL_CONNECTION_LOST'`).\n* `err.fatal`: Boolean, indicating if this error is terminal to the connection\n object.\n\n[Error]: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error\n[MySQL server error]: http://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html\n\nFatal errors are propagated to *all* pending callbacks. In the example below, a\nfatal error is triggered by trying to connect to an invalid port. Therefore the\nerror object is propagated to both pending callbacks:\n\n```js\nvar connection = require('mysql').createConnection({\n port: 84943, // WRONG PORT\n});\n\nconnection.connect(function(err) {\n console.log(err.code); // 'ECONNREFUSED'\n console.log(err.fatal); // true\n});\n\nconnection.query('SELECT 1', function(err) {\n console.log(err.code); // 'ECONNREFUSED'\n console.log(err.fatal); // true\n});\n```\n\nNormal errors however are only delegated to the callback they belong to. So in\nthe example below, only the first callback receives an error, the second query\nworks as expected:\n\n```js\nconnection.query('USE name_of_db_that_does_not_exist', function(err, rows) {\n console.log(err.code); // 'ER_BAD_DB_ERROR'\n});\n\nconnection.query('SELECT 1', function(err, rows) {\n console.log(err); // null\n console.log(rows.length); // 1\n});\n```\n\nLast but not least: If a fatal errors occurs and there are no pending\ncallbacks, or a normal error occurs which has no callback belonging to it, the\nerror is emitted as an `'error'` event on the connection object. This is\ndemonstrated in the example below:\n\n```js\nconnection.on('error', function(err) {\n console.log(err.code); // 'ER_BAD_DB_ERROR'\n});\n\nconnection.query('USE name_of_db_that_does_not_exist');\n```\n\nNote: `'error'` are special in node. If they occur without an attached\nlistener, a stack trace is printed and your process is killed.\n\n**tl;dr:** This module does not want you to deal with silent failures. You\nshould always provide callbacks to your method calls. If you want to ignore\nthis advice and suppress unhandled errors, you can do this:\n\n```js\n// I am Chuck Norris:\nconnection.on('error', function() {});\n```\n\n## Exception Safety\n\nThis module is exception safe. That means you can continue to use it, even if\none of your callback functions throws an error which you're catching using\n'uncaughtException' or a domain.\n\n## Type casting\n\nFor your convenience, this driver will cast mysql types into native JavaScript\ntypes by default. The following mappings exist:\n\n### Number\n\n* TINYINT\n* SMALLINT\n* INT\n* MEDIUMINT\n* YEAR\n* FLOAT\n* DOUBLE\n\n### Date\n\n* TIMESTAMP\n* DATE\n* DATETIME\n\n### Buffer\n\n* TINYBLOB\n* MEDIUMBLOB\n* LONGBLOB\n* BLOB\n* BINARY\n* VARBINARY\n* BIT (last byte will be filled with 0 bits as necessary)\n\n### String\n\n* CHAR\n* VARCHAR\n* TINYTEXT\n* MEDIUMTEXT\n* LONGTEXT\n* TEXT\n* ENUM\n* SET\n* DECIMAL (may exceed float precision)\n* BIGINT (may exceed float precision)\n* TIME (could be mapped to Date, but what date would be set?)\n* GEOMETRY (never used those, get in touch if you do)\n\nIt is not recommended (and may go away / change in the future) to disable type\ncasting, but you can currently do so on either the connection:\n\n```js\nvar connection = require('mysql').createConnection({typeCast: false});\n```\n\nOr on the query level:\n\n```js\nvar options = {sql: '...', typeCast: false};\nvar query = connection.query(options, function(err, results) {\n\n});\n```\n\nYou can also pass a function and handle type casting yourself. You're given some\ncolumn information like database, table and name and also type and length. If you\njust want to apply a custom type casting to a specific type you can do it and then\nfallback to the default. Here's an example of converting `TINYINT(1)` to boolean:\n\n```js\nconnection.query({\n sql: '...',\n typeCast: function (field, next) {\n if (field.type == 'TINY' && field.length == 1) {\n return (field.string() == '1'); // 1 = true, 0 = false\n }\n return next();\n }\n});\n```\n__WARNING: YOU MUST INVOKE the parser using one of these three field functions in your custom typeCast callback. They can only be called once.( see #539 for discussion)__\n\n```\nfield.string()\nfield.buffer()\nfield.geometry()\n```\nare aliases for\n```\nparser.parseLengthCodedString()\nparser.parseLengthCodedBuffer()\nparser.parseGeometryValue()\n```\n__You can find which field function you need to use by looking at: [RowDataPacket.prototype._typeCast](https://github.com/felixge/node-mysql/blob/master/lib/protocol/packets/RowDataPacket.js#L41)__\n\n\n## Connection Flags\n\nIf, for any reason, you would like to change the default connection flags, you\ncan use the connection option `flags`. Pass a string with a comma separated list\nof items to add to the default flags. If you don't want a default flag to be used\nprepend the flag with a minus sign. To add a flag that is not in the default list, don't prepend it with a plus sign, just write the flag name (case insensitive).\n\n**Please note that some available flags that are not default are still not supported\n(e.g.: SSL, Compression). Use at your own risk.**\n\n### Example\n\nThe next example blacklists FOUND_ROWS flag from default connection flags.\n\n```js\nvar connection = mysql.createConnection(\"mysql://localhost/test?flags=-FOUND_ROWS\");\n```\n\n### Default Flags\n\n- LONG_PASSWORD\n- FOUND_ROWS\n- LONG_FLAG\n- CONNECT_WITH_DB\n- ODBC\n- LOCAL_FILES\n- IGNORE_SPACE\n- PROTOCOL_41\n- IGNORE_SIGPIPE\n- TRANSACTIONS\n- RESERVED\n- SECURE_CONNECTION\n- MULTI_RESULTS\n- MULTI_STATEMENTS (used if `multipleStatements` option is activated)\n\n### Other Available Flags\n\n- NO_SCHEMA\n- COMPRESS\n- INTERACTIVE\n- SSL\n- PS_MULTI_RESULTS\n- PLUGIN_AUTH\n- SSL_VERIFY_SERVER_CERT\n- REMEMBER_OPTIONS\n\n## Debugging and reporting problems\n\nIf you are running into problems, one thing that may help is enabling the\n`debug` mode for the connection:\n\n```js\nvar connection = mysql.createConnection({debug: true});\n```\n\nThis will print all incoming and outgoing packets on stdout. You can also restrict debugging to\npacket types by passing an array of types to debug:\n\n```js\nvar connection = mysql.createConnection({debug: ['ComQueryPacket', 'RowDataPacket']});\n```\n\nto restrict debugging to the query and data packets.\n\nIf that does not help, feel free to open a GitHub issue. A good GitHub issue\nwill have:\n\n* The minimal amount of code required to reproduce the problem (if possible)\n* As much debugging output and information about your environment (mysql\n version, node version, os, etc.) as you can gather.\n\n## Running unit tests\n\nSet the environment variables `MYSQL_DATABASE`, `MYSQL_HOST`, `MYSQL_PORT`, `MYSQL_USER` and `MYSQL_PASSWORD`. Then run `npm test`.\n\nFor example, if you have an installation of mysql running on localhost:3306 and no password set for the `root` user, run:\n\n```\n mysql -u root -e \"CREATE DATABASE IF NOT EXISTS node_mysql_test\"\n MYSQL_HOST=localhost MYSQL_PORT=3306 MYSQL_DATABASE=node_mysql_test MYSQL_USER=root MYSQL_PASSWORD= npm test\n```\n\n## Todo\n\n* Prepared statements\n* setTimeout() for Query\n* Support for encodings other than UTF-8 / ASCII\n",
"readmeFilename": "Readme.md",
"bugs": {
"url": "https://github.com/felixge/node-mysql/issues"
},
"_id": "mysql@2.3.2",
"_shasum": "dbfabbc355d5690fd31c53a786c38acbbfda5046",
"_from": "mysql@",
"_resolved": "https://registry.npmjs.org/mysql/-/mysql-2.3.2.tgz"
}

mysql Build Status NPM version

Install

$ npm install mysql

For information about the previous 0.9.x releases, visit the v0.9 branch.

Sometimes I may also ask you to install the latest version from Github to check if a bugfix is working. In this case, please do:

$ npm install felixge/node-mysql

Introduction

This is a node.js driver for mysql. It is written in JavaScript, does not require compiling, and is 100% MIT licensed.

Here is an example on how to use it:

var mysql      = require('mysql');
var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'me',
  password : 'secret'
});

connection.connect();

connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
  if (err) throw err;

  console.log('The solution is: ', rows[0].solution);
});

connection.end();

From this example, you can learn the following:

  • Every method you invoke on a connection is queued and executed in sequence.
  • Closing the connection is done using end() which makes sure all remaining queries are executed before sending a quit packet to the mysql server.

Contributors

Thanks goes to the people who have contributed code to this module, see the GitHub Contributors page.

Additionally I'd like to thank the following people:

  • Andrey Hristov (Oracle) - for helping me with protocol questions.
  • Ulf Wendel (Oracle) - for helping me with protocol questions.

Sponsors

The following companies have supported this project financially, allowing me to spend more time on it (ordered by time of contribution):

If you are interested in sponsoring a day or more of my time, please get in touch.

Community

If you'd like to discuss this module, or ask questions about it, please use one of the following:

Establishing connections

The recommended way to establish a connection is this:

var mysql      = require('mysql');
var connection = mysql.createConnection({
  host     : 'example.org',
  user     : 'bob',
  password : 'secret'
});

connection.connect(function(err) {
  if (err) {
    console.error('error connecting: ' + err.stack);
    return;
  }

  console.log('connected as id ' + connection.threadId);
});

However, a connection can also be implicitly established by invoking a query:

var mysql      = require('mysql');
var connection = mysql.createConnection(...);

connection.query('SELECT 1', function(err, rows) {
  // connected! (unless `err` is set)
});

Depending on how you like to handle your errors, either method may be appropriate. Any type of connection error (handshake or network) is considered a fatal error, see the Error Handling section for more information.

Connection options

When establishing a connection, you can set the following options:

  • host: The hostname of the database you are connecting to. (Default: localhost)
  • port: The port number to connect to. (Default: 3306)
  • localAddress: The source IP address to use for TCP connection. (Optional)
  • socketPath: The path to a unix domain socket to connect to. When used host and port are ignored.
  • user: The MySQL user to authenticate as.
  • password: The password of that MySQL user.
  • database: Name of the database to use for this connection (Optional).
  • charset: The charset for the connection. This is called "collation" in the SQL-level of MySQL (like utf8_general_ci). If a SQL-level charset is specified (like utf8mb4) then the default collation for that charset is used. (Default: 'UTF8_GENERAL_CI')
  • timezone: The timezone used to store local dates. (Default: 'local')
  • connectTimeout: The milliseconds before a timeout occurs during the initial connection to the MySQL server. (Default: 2 minutes)
  • stringifyObjects: Stringify objects instead of converting to values. See issue #501. (Default: 'false')
  • insecureAuth: Allow connecting to MySQL instances that ask for the old (insecure) authentication method. (Default: false)
  • typeCast: Determines if column values should be converted to native JavaScript types. (Default: true)
  • queryFormat: A custom query format function. See Custom format.
  • supportBigNumbers: When dealing with big numbers (BIGINT and DECIMAL columns) in the database, you should enable this option (Default: false).
  • bigNumberStrings: Enabling both supportBigNumbers and bigNumberStrings forces big numbers (BIGINT and DECIMAL columns) to be always returned as JavaScript String objects (Default: false). Enabling supportBigNumbers but leaving bigNumberStrings disabled will return big numbers as String objects only when they cannot be accurately represented with [JavaScript Number objects] (http://ecma262-5.com/ELS5_HTML.htm#Section_8.5) (which happens when they exceed the [-2^53, +2^53] range), otherwise they will be returned as Number objects. This option is ignored if supportBigNumbers is disabled.
  • dateStrings: Force date types (TIMESTAMP, DATETIME, DATE) to be returned as strings rather then inflated into JavaScript Date objects. (Default: false)
  • debug: Prints protocol details to stdout. (Default: false)
  • trace: Generates stack traces on Error to include call site of library entrance ("long stack traces"). Slight performance penalty for most calls. (Default: true)
  • multipleStatements: Allow multiple mysql statements per query. Be careful with this, it exposes you to SQL injection attacks. (Default: false)
  • flags: List of connection flags to use other than the default ones. It is also possible to blacklist default ones. For more information, check Connection Flags.
  • ssl: object with ssl parameters or a string containing name of ssl profile. See SSL options.

In addition to passing these options as an object, you can also use a url string. For example:

var connection = mysql.createConnection('mysql://user:pass@host/db?debug=true&charset=BIG5_CHINESE_CI&timezone=-0700');

Note: The query values are first attempted to be parsed as JSON, and if that fails assumed to be plaintext strings.

SSL options

The ssl option in the connection options takes a string or an object. When given a string, it uses one of the predefined SSL profiles included. The following profiles are included:

When connecting to other servers, you will need to provide an object of options, in the same format as crypto.createCredentials. Please note the arguments expect a string of the certificate, not a file name to the certificate. Here is a simple example:

var connection = mysql.createConnection({
  host : 'localhost',
  ssl  : {
    ca : fs.readFileSync(__dirname + '/mysql-ca.crt')
  }
});

You can also connect to a MySQL server without properly providing the appropriate CA to trust. You should not do this.

var connection = mysql.createConnection({
  host : 'localhost',
  ssl  : {
    // DO NOT DO THIS
    // set up your ca correctly to trust the connection
    rejectUnauthorized: false
  }
});

Terminating connections

There are two ways to end a connection. Terminating a connection gracefully is done by calling the end() method:

connection.end(function(err) {
  // The connection is terminated now
});

This will make sure all previously enqueued queries are still before sending a COM_QUIT packet to the MySQL server. If a fatal error occurs before the COM_QUIT packet can be sent, an err argument will be provided to the callback, but the connection will be terminated regardless of that.

An alternative way to end the connection is to call the destroy() method. This will cause an immediate termination of the underlying socket. Additionally destroy() guarantees that no more events or callbacks will be triggered for the connection.

connection.destroy();

Unlike end() the destroy() method does not take a callback argument.

Pooling connections

Use pool directly.

var mysql = require('mysql');
var pool  = mysql.createPool({
  connectionLimit : 10,
  host            : 'example.org',
  user            : 'bob',
  password        : 'secret'
});

pool.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
  if (err) throw err;

  console.log('The solution is: ', rows[0].solution);
});

Connections can be pooled to ease sharing a single connection, or managing multiple connections.

var mysql = require('mysql');
var pool  = mysql.createPool({
  host     : 'example.org',
  user     : 'bob',
  password : 'secret'
});

pool.getConnection(function(err, connection) {
  // connected! (unless `err` is set)
});

If you need to set session variables on the connection before it gets used, you can listen to the connection event.

pool.on('connection', function(connection) {
  connection.query('SET SESSION auto_increment_increment=1')
});

When you are done with a connection, just call connection.release() and the connection will return to the pool, ready to be used again by someone else.

var mysql = require('mysql');
var pool  = mysql.createPool(...);

pool.getConnection(function(err, connection) {
  // Use the connection
  connection.query( 'SELECT something FROM sometable', function(err, rows) {
    // And done with the connection.
    connection.release();

    // Don't use the connection here, it has been returned to the pool.
  });
});

If you would like to close the connection and remove it from the pool, use connection.destroy() instead. The pool will create a new connection the next time one is needed.

Connections are lazily created by the pool. If you configure the pool to allow up to 100 connections, but only ever use 5 simultaneously, only 5 connections will be made. Connections are also cycled round-robin style, with connections being taken from the top of the pool and returning to the bottom.

When a previous connection is retrieved from the pool, a ping packet is sent to the server to check if the connection is still good.

Pool options

Pools accept all the same options as a connection. When creating a new connection, the options are simply passed to the connection constructor. In addition to those options pools accept a few extras:

  • waitForConnections: Determines the pool's action when no connections are available and the limit has been reached. If true, the pool will queue the connection request and call it when one becomes available. If false, the pool will immediately call back with an error. (Default: true)
  • connectionLimit: The maximum number of connections to create at once. (Default: 10)
  • queueLimit: The maximum number of connection requests the pool will queue before returning an error from getConnection. If set to 0, there is no limit to the number of queued connection requests. (Default: 0)

PoolCluster

PoolCluster provides multiple hosts connection. (group & retry & selector)

// create
var poolCluster = mysql.createPoolCluster();

poolCluster.add(config); // anonymous group
poolCluster.add('MASTER', masterConfig);
poolCluster.add('SLAVE1', slave1Config);
poolCluster.add('SLAVE2', slave2Config);

// Target Group : ALL(anonymous, MASTER, SLAVE1-2), Selector : round-robin(default)
poolCluster.getConnection(function (err, connection) {});

// Target Group : MASTER, Selector : round-robin
poolCluster.getConnection('MASTER', function (err, connection) {});

// Target Group : SLAVE1-2, Selector : order
// If can't connect to SLAVE1, return SLAVE2. (remove SLAVE1 in the cluster)
poolCluster.on('remove', function (nodeId) {
  console.log('REMOVED NODE : ' + nodeId); // nodeId = SLAVE1 
});

poolCluster.getConnection('SLAVE*', 'ORDER', function (err, connection) {});

// of namespace : of(pattern, selector)
poolCluster.of('*').getConnection(function (err, connection) {});

var pool = poolCluster.of('SLAVE*', 'RANDOM');
pool.getConnection(function (err, connection) {});
pool.getConnection(function (err, connection) {});

// destroy
poolCluster.end();

PoolCluster Option

  • canRetry: If true, PoolCluster will attempt to reconnect when connection fails. (Default: true)
  • removeNodeErrorCount: If connection fails, node's errorCount increases. When errorCount is greater than removeNodeErrorCount, remove a node in the PoolCluster. (Default: 5)
  • defaultSelector: The default selector. (Default: RR)
    • RR: Select one alternately. (Round-Robin)
    • RANDOM: Select the node by random function.
    • ORDER: Select the first node available unconditionally.
var clusterConfig = {
  removeNodeErrorCount: 1, // Remove the node immediately when connection fails.
  defaultSelector: 'ORDER'
};

var poolCluster = mysql.createPoolCluster(clusterConfig);

Switching users / altering connection state

MySQL offers a changeUser command that allows you to alter the current user and other aspects of the connection without shutting down the underlying socket:

connection.changeUser({user : 'john'}, function(err) {
  if (err) throw err;
});

The available options for this feature are:

  • user: The name of the new user (defaults to the previous one).
  • password: The password of the new user (defaults to the previous one).
  • charset: The new charset (defaults to the previous one).
  • database: The new database (defaults to the previous one).

A sometimes useful side effect of this functionality is that this function also resets any connection state (variables, transactions, etc.).

Errors encountered during this operation are treated as fatal connection errors by this module.

Server disconnects

You may lose the connection to a MySQL server due to network problems, the server timing you out, the server being restarted, or crashing. All of these events are considered fatal errors, and will have the err.code = 'PROTOCOL_CONNECTION_LOST'. See the Error Handling section for more information.

Re-connecting a connection is done by establishing a new connection. Once terminated, an existing connection object cannot be re-connected by design.

With Pool, disconnected connections will be removed from the pool freeing up space for a new connection to be created on the next getConnection call.

Escaping query values

In order to avoid SQL Injection attacks, you should always escape any user provided data before using it inside a SQL query. You can do so using the connection.escape() or pool.escape() methods:

var userId = 'some user provided value';
var sql    = 'SELECT * FROM users WHERE id = ' + connection.escape(userId);
connection.query(sql, function(err, results) {
  // ...
});

Alternatively, you can use ? characters as placeholders for values you would like to have escaped like this:

connection.query('SELECT * FROM users WHERE id = ?', [userId], function(err, results) {
  // ...
});

This looks similar to prepared statements in MySQL, however it really just uses the same connection.escape() method internally.

Caution This also differs from prepared statements in that all ? are replaced, even those contained in comments and strings.

Different value types are escaped differently, here is how:

  • Numbers are left untouched
  • Booleans are converted to true / false strings
  • Date objects are converted to 'YYYY-mm-dd HH:ii:ss' strings
  • Buffers are converted to hex strings, e.g. X'0fa5'
  • Strings are safely escaped
  • Arrays are turned into list, e.g. ['a', 'b'] turns into 'a', 'b'
  • Nested arrays are turned into grouped lists (for bulk inserts), e.g. [['a', 'b'], ['c', 'd']] turns into ('a', 'b'), ('c', 'd')
  • Objects are turned into key = 'val' pairs. Nested objects are cast to strings.
  • undefined / null are converted to NULL
  • NaN / Infinity are left as-is. MySQL does not support these, and trying to insert them as values will trigger MySQL errors until they implement support.

If you paid attention, you may have noticed that this escaping allows you to do neat things like this:

var post  = {id: 1, title: 'Hello MySQL'};
var query = connection.query('INSERT INTO posts SET ?', post, function(err, result) {
  // Neat!
});
console.log(query.sql); // INSERT INTO posts SET `id` = 1, `title` = 'Hello MySQL'

If you feel the need to escape queries by yourself, you can also use the escaping function directly:

var query = "SELECT * FROM posts WHERE title=" + mysql.escape("Hello MySQL");

console.log(query); // SELECT * FROM posts WHERE title='Hello MySQL'

Escaping query identifiers

If you can't trust an SQL identifier (database / table / column name) because it is provided by a user, you should escape it with mysql.escapeId(identifier) like this:

var sorter = 'date';
var query = 'SELECT * FROM posts ORDER BY ' + mysql.escapeId(sorter);

console.log(query); // SELECT * FROM posts ORDER BY `date`

It also supports adding qualified identifiers. It will escape both parts.

var sorter = 'date';
var query = 'SELECT * FROM posts ORDER BY ' + mysql.escapeId('posts.' + sorter);

console.log(query); // SELECT * FROM posts ORDER BY `posts`.`date`

Alternatively, you can use ?? characters as placeholders for identifiers you would like to have escaped like this:

var userId = 1;
var columns = ['username', 'email'];
var query = connection.query('SELECT ?? FROM ?? WHERE id = ?', [columns, 'users', userId], function(err, results) {
  // ...
});

console.log(query.sql); // SELECT `username`, `email` FROM `users` WHERE id = 1

Please note that this last character sequence is experimental and syntax might change

When you pass an Object to .escape() or .query(), .escapeId() is used to avoid SQL injection in object keys.

Preparing Queries

You can use mysql.format to prepare a query with multiple insertion points, utilizing the proper escaping for ids and values. A simple example of this follows:

var sql = "SELECT * FROM ?? WHERE ?? = ?";
var inserts = ['users', 'id', userId];
sql = mysql.format(sql, inserts);

Following this you then have a valid, escaped query that you can then send to the database safely. This is useful if you are looking to prepare the query before actually sending it to the database. As mysql.format is exposed from SqlString.format you also have the option (but are not required) to pass in stringifyObject and timezone, allowing you provide a custom means of turning objects into strings, as well as a location-specific/timezone-aware Date.

Custom format

If you prefer to have another type of query escape format, there's a connection configuration option you can use to define a custom format function. You can access the connection object if you want to use the built-in .escape() or any other connection function.

Here's an example of how to implement another format:

connection.config.queryFormat = function (query, values) {
  if (!values) return query;
  return query.replace(/\:(\w+)/g, function (txt, key) {
    if (values.hasOwnProperty(key)) {
      return this.escape(values[key]);
    }
    return txt;
  }.bind(this));
};

connection.query("UPDATE posts SET title = :title", { title: "Hello MySQL" });

Getting the id of an inserted row

If you are inserting a row into a table with an auto increment primary key, you can retrieve the insert id like this:

connection.query('INSERT INTO posts SET ?', {title: 'test'}, function(err, result) {
  if (err) throw err;

  console.log(result.insertId);
});

When dealing with big numbers (above JavaScript Number precision limit), you should consider enabling supportBigNumbers option to be able to read the insert id as a string, otherwise it will throw.

This option is also required when fetching big numbers from the database, otherwise you will get values rounded to hundreds or thousands due to the precision limit.

Getting the number of affected rows.

You can get the number of affected rows from an insert, update or delete statement.

connection.query('DELETE FROM posts WHERE title = "wrong"', function (err, result) {
  if (err) throw err;

  console.log('deleted ' + result.affectedRows + ' rows');
})

Getting the number of changed rows.

You can get the number of changed rows from an update statement.

"changedRows" differs from "affectedRows" in that it does not count updated rows whose values were not changed.

connection.query('UPDATE posts SET ...', function (err, response) {
  if (err) throw err;

  console.log('changed ' + result.changedRows + ' rows');
})

Getting the connection ID

You can get the MySQL connection ID ("thread ID") of a given connection using the threadId property.

connection.connect(function(err) {
  if (err) throw err;
  console.log('connected as id ' + connection.threadId);
});

Executing queries in parallel

The MySQL protocol is sequential, this means that you need multiple connections to execute queries in parallel. You can use a Pool to manage connections, one simple approach is to create one connection per incoming http request.

Streaming query rows

Sometimes you may want to select large quantities of rows and process each of them as they are received. This can be done like this:

var query = connection.query('SELECT * FROM posts');
query
  .on('error', function(err) {
    // Handle error, an 'end' event will be emitted after this as well
  })
  .on('fields', function(fields) {
    // the field packets for the rows to follow
  })
  .on('result', function(row) {
    // Pausing the connnection is useful if your processing involves I/O
    connection.pause();

    processRow(row, function() {
      connection.resume();
    });
  })
  .on('end', function() {
    // all rows have been received
  });

Please note a few things about the example above:

  • Usually you will want to receive a certain amount of rows before starting to throttle the connection using pause(). This number will depend on the amount and size of your rows.
  • pause() / resume() operate on the underlying socket and parser. You are guaranteed that no more 'result' events will fire after calling pause().
  • You MUST NOT provide a callback to the query() method when streaming rows.
  • The 'result' event will fire for both rows as well as OK packets confirming the success of a INSERT/UPDATE query.

Additionally you may be interested to know that it is currently not possible to stream individual row columns, they will always be buffered up entirely. If you have a good use case for streaming large fields to and from MySQL, I'd love to get your thoughts and contributions on this.

Piping results with Streams2

The query object provides a convenience method .stream([options]) that wraps query events into a Readable Streams2 object. This stream can easily be piped downstream and provides automatic pause/resume, based on downstream congestion and the optional highWaterMark. The objectMode parameter of the stream is set to true by default.

For example, piping query results into another stream (with a max buffer of 5 objects) is simply:

connection.query('SELECT * FROM posts')
  .stream({highWaterMark: 5})
  .pipe(...);

Multiple statement queries

Support for multiple statements is disabled for security reasons (it allows for SQL injection attacks if values are not properly escaped). To use this feature you have to enable it for your connection:

var connection = mysql.createConnection({multipleStatements: true});

Once enabled, you can execute multiple statement queries like any other query:

connection.query('SELECT 1; SELECT 2', function(err, results) {
  if (err) throw err;

  // `results` is an array with one element for every statement in the query:
  console.log(results[0]); // [{1: 1}]
  console.log(results[1]); // [{2: 2}]
});

Additionally you can also stream the results of multiple statement queries:

var query = connection.query('SELECT 1; SELECT 2');

query
  .on('fields', function(fields, index) {
    // the fields for the result rows that follow
  })
  .on('result', function(row, index) {
    // index refers to the statement this result belongs to (starts at 0)
  });

If one of the statements in your query causes an error, the resulting Error object contains a err.index property which tells you which statement caused it. MySQL will also stop executing any remaining statements when an error occurs.

Please note that the interface for streaming multiple statement queries is experimental and I am looking forward to feedback on it.

Stored procedures

You can call stored procedures from your queries as with any other mysql driver. If the stored procedure produces several result sets, they are exposed to you the same way as the results for multiple statement queries.

Joins with overlapping column names

When executing joins, you are likely to get result sets with overlapping column names.

By default, node-mysql will overwrite colliding column names in the order the columns are received from MySQL, causing some of the received values to be unavailable.

However, you can also specify that you want your columns to be nested below the table name like this:

var options = {sql: '...', nestTables: true};
connection.query(options, function(err, results) {
  /* results will be an array like this now:
  [{
    table1: {
      fieldA: '...',
      fieldB: '...',
    },
    table2: {
      fieldA: '...',
      fieldB: '...',
    },
  }, ...]
  */
});

Or use a string separator to have your results merged.

var options = {sql: '...', nestTables: '_'};
connection.query(options, function(err, results) {
  /* results will be an array like this now:
  [{
    table1_fieldA: '...',
    table1_fieldB: '...',
    table2_fieldA: '...',
    table2_fieldB: '...',
  }, ...]
  */
});

Transactions

Simple transaction support is available at the connection level:

connection.beginTransaction(function(err) {
  if (err) { throw err; }
  connection.query('INSERT INTO posts SET title=?', title, function(err, result) {
    if (err) { 
      connection.rollback(function() {
        throw err;
      });
    }

	var log = 'Post ' + result.insertId + ' added';

	connection.query('INSERT INTO log SET data=?', log, function(err, result) {
	  if (err) { 
        connection.rollback(function() {
          throw err;
        });
      }  
	  connection.commit(function(err) {
	    if (err) { 
          connection.rollback(function() {
            throw err;
          });
        }
	    console.log('success!');
	  });
    });
  });
});

Please note that beginTransaction(), commit() and rollback() are simply convenience functions that execute the START TRANSACTION, COMMIT, and ROLLBACK commands respectively. It is important to understand that many commands in MySQL can cause an implicit commit, as described in the MySQL documentation

Error handling

This module comes with a consistent approach to error handling that you should review carefully in order to write solid applications.

All errors created by this module are instances of the JavaScript Error object. Additionally they come with two properties:

  • err.code: Either a MySQL server error (e.g. 'ER_ACCESS_DENIED_ERROR'), a node.js error (e.g. 'ECONNREFUSED') or an internal error (e.g. 'PROTOCOL_CONNECTION_LOST').
  • err.fatal: Boolean, indicating if this error is terminal to the connection object.

Fatal errors are propagated to all pending callbacks. In the example below, a fatal error is triggered by trying to connect to an invalid port. Therefore the error object is propagated to both pending callbacks:

var connection = require('mysql').createConnection({
  port: 84943, // WRONG PORT
});

connection.connect(function(err) {
  console.log(err.code); // 'ECONNREFUSED'
  console.log(err.fatal); // true
});

connection.query('SELECT 1', function(err) {
  console.log(err.code); // 'ECONNREFUSED'
  console.log(err.fatal); // true
});

Normal errors however are only delegated to the callback they belong to. So in the example below, only the first callback receives an error, the second query works as expected:

connection.query('USE name_of_db_that_does_not_exist', function(err, rows) {
  console.log(err.code); // 'ER_BAD_DB_ERROR'
});

connection.query('SELECT 1', function(err, rows) {
  console.log(err); // null
  console.log(rows.length); // 1
});

Last but not least: If a fatal errors occurs and there are no pending callbacks, or a normal error occurs which has no callback belonging to it, the error is emitted as an 'error' event on the connection object. This is demonstrated in the example below:

connection.on('error', function(err) {
  console.log(err.code); // 'ER_BAD_DB_ERROR'
});

connection.query('USE name_of_db_that_does_not_exist');

Note: 'error' are special in node. If they occur without an attached listener, a stack trace is printed and your process is killed.

tl;dr: This module does not want you to deal with silent failures. You should always provide callbacks to your method calls. If you want to ignore this advice and suppress unhandled errors, you can do this:

// I am Chuck Norris:
connection.on('error', function() {});

Exception Safety

This module is exception safe. That means you can continue to use it, even if one of your callback functions throws an error which you're catching using 'uncaughtException' or a domain.

Type casting

For your convenience, this driver will cast mysql types into native JavaScript types by default. The following mappings exist:

Number

  • TINYINT
  • SMALLINT
  • INT
  • MEDIUMINT
  • YEAR
  • FLOAT
  • DOUBLE

Date

  • TIMESTAMP
  • DATE
  • DATETIME

Buffer

  • TINYBLOB
  • MEDIUMBLOB
  • LONGBLOB
  • BLOB
  • BINARY
  • VARBINARY
  • BIT (last byte will be filled with 0 bits as necessary)

String

  • CHAR
  • VARCHAR
  • TINYTEXT
  • MEDIUMTEXT
  • LONGTEXT
  • TEXT
  • ENUM
  • SET
  • DECIMAL (may exceed float precision)
  • BIGINT (may exceed float precision)
  • TIME (could be mapped to Date, but what date would be set?)
  • GEOMETRY (never used those, get in touch if you do)

It is not recommended (and may go away / change in the future) to disable type casting, but you can currently do so on either the connection:

var connection = require('mysql').createConnection({typeCast: false});

Or on the query level:

var options = {sql: '...', typeCast: false};
var query = connection.query(options, function(err, results) {

});

You can also pass a function and handle type casting yourself. You're given some column information like database, table and name and also type and length. If you just want to apply a custom type casting to a specific type you can do it and then fallback to the default. Here's an example of converting TINYINT(1) to boolean:

connection.query({
  sql: '...',
  typeCast: function (field, next) {
    if (field.type == 'TINY' && field.length == 1) {
      return (field.string() == '1'); // 1 = true, 0 = false
    }
    return next();
  }
});

WARNING: YOU MUST INVOKE the parser using one of these three field functions in your custom typeCast callback. They can only be called once.( see #539 for discussion)

field.string()
field.buffer()
field.geometry()

are aliases for

parser.parseLengthCodedString()
parser.parseLengthCodedBuffer()
parser.parseGeometryValue()

You can find which field function you need to use by looking at: RowDataPacket.prototype._typeCast

Connection Flags

If, for any reason, you would like to change the default connection flags, you can use the connection option flags. Pass a string with a comma separated list of items to add to the default flags. If you don't want a default flag to be used prepend the flag with a minus sign. To add a flag that is not in the default list, don't prepend it with a plus sign, just write the flag name (case insensitive).

Please note that some available flags that are not default are still not supported (e.g.: SSL, Compression). Use at your own risk.

Example

The next example blacklists FOUND_ROWS flag from default connection flags.

var connection = mysql.createConnection("mysql://localhost/test?flags=-FOUND_ROWS");

Default Flags

  • LONG_PASSWORD
  • FOUND_ROWS
  • LONG_FLAG
  • CONNECT_WITH_DB
  • ODBC
  • LOCAL_FILES
  • IGNORE_SPACE
  • PROTOCOL_41
  • IGNORE_SIGPIPE
  • TRANSACTIONS
  • RESERVED
  • SECURE_CONNECTION
  • MULTI_RESULTS
  • MULTI_STATEMENTS (used if multipleStatements option is activated)

Other Available Flags

  • NO_SCHEMA
  • COMPRESS
  • INTERACTIVE
  • SSL
  • PS_MULTI_RESULTS
  • PLUGIN_AUTH
  • SSL_VERIFY_SERVER_CERT
  • REMEMBER_OPTIONS

Debugging and reporting problems

If you are running into problems, one thing that may help is enabling the debug mode for the connection:

var connection = mysql.createConnection({debug: true});

This will print all incoming and outgoing packets on stdout. You can also restrict debugging to packet types by passing an array of types to debug:

var connection = mysql.createConnection({debug: ['ComQueryPacket', 'RowDataPacket']});

to restrict debugging to the query and data packets.

If that does not help, feel free to open a GitHub issue. A good GitHub issue will have:

  • The minimal amount of code required to reproduce the problem (if possible)
  • As much debugging output and information about your environment (mysql version, node version, os, etc.) as you can gather.

Running unit tests

Set the environment variables MYSQL_DATABASE, MYSQL_HOST, MYSQL_PORT, MYSQL_USER and MYSQL_PASSWORD. Then run npm test.

For example, if you have an installation of mysql running on localhost:3306 and no password set for the root user, run:

  mysql -u root -e "CREATE DATABASE IF NOT EXISTS node_mysql_test"
  MYSQL_HOST=localhost MYSQL_PORT=3306 MYSQL_DATABASE=node_mysql_test MYSQL_USER=root MYSQL_PASSWORD= npm test

Todo

  • Prepared statements
  • setTimeout() for Query
  • Support for encodings other than UTF-8 / ASCII
.travis.yml
CONTRIBUTING.md
assets
examples
test

Changelog

v0.7.0 2014-06-17

  • Bumped version to v0.7.0
  • Fix AWS-SES usage [5b6bc144]
  • Replace current SES with new SES using AWS-SDK (Elanorr) [c79d797a]
  • Updated README.md about Node Email Templates (niftylettuce) [e52bef81]

v0.6.5 2014-05-15

  • Bumped version to v0.6.5
  • Use tildes instead of carets for dependency listing [5296ce41]
  • Allow clients to set a custom identityString (venables) [5373287d]
  • bugfix (adding "-i" to sendmail command line for each new mail) by copying this.args (vrodic) [05a8a9a3]
  • update copyright (gdi2290) [3a6cba3a]

v0.6.4 2014-05-13

  • Bumped version to v0.6.4
  • added npmignore, bumped dependencies [21bddcd9]
  • Add AOL to well-known services (msouce) [da7dd3b7]

v0.6.3 2014-04-16

  • Bumped version to v0.6.3
  • Upgraded simplesmtp dependency [dd367f59]

v0.6.2 2014-04-09

  • Bumped version to v0.6.2
  • Added error option to Stub transport [c423acad]
  • Use SVG npm badge (t3chnoboy) [677117b7]
  • add SendCloud to well known services (haio) [43c358e0]
  • High-res build-passing and NPM module badges (sahat) [9fdc37cd]

v0.6.1 2014-01-26

  • Bumped version to v0.6.1
  • Do not throw on multiple errors from sendmail command [c6e2cd12]
  • Do not require callback for pickup, fixes #238 [93eb3214]
  • Added AWSSecurityToken information to README, fixes #235 [58e921d1]
  • Added Nodemailer logo [06b7d1a8]

v0.6.0 2013-12-30

  • Bumped version to v0.6.0
  • Allow defining custom transport methods [ec5b48ce]
  • Return messageId with responseObject for all built in transport methods [74445cec]
  • Bumped dependency versions for mailcomposer and readable-stream [9a034c34]
  • Changed pickup argument name to 'directory' [01c3ea53]
  • Added support for IIS pickup directory with PICKUP transport (philipproplesch) [36940b59..360a2878]
  • Applied common styles [9e93a409]
  • Updated readme [c78075e7]

v0.5.15 2013-12-13

  • bumped version to v0.5.15
  • Updated README, added global options info for setting uo transports [554bb0e5]
  • Resolve public hostname, if resolveHostname property for a transport object is set to true [9023a6e1..4c66b819]

v0.5.14 2013-12-05

  • bumped version to v0.5.14
  • Expose status for direct messages [f0312df6]
  • Allow to skip the X-Mailer header if xMailer value is set to 'false' [f2c20a68]

v0.5.13 2013-12-03

  • bumped version to v0.5.13
  • Use the name property from the transport object to use for the domain part of message-id values (1598eee9)

v0.5.12 2013-12-02

  • bumped version to v0.5.12
  • Expose transport method and transport module version if available [a495106e]
  • Added 'he' module instead of using custom html entity decoding [c197d102]
  • Added xMailer property for transport configuration object to override X-Mailer value [e8733a61]
  • Updated README, added description for 'mail' method [e1f5f3a6]

v0.5.11 2013-11-28

  • bumped version to v0.5.11
  • Updated mailcomposer version. Replaces ent with he [6a45b790e]

v0.5.10 2013-11-26

  • bumped version to v0.5.10
  • added shorthand function mail() for direct transport type [88129bd7]
  • minor tweaks and typo fixes [f797409e..ceac0ca4]

v0.5.9 2013-11-25

  • bumped version to v0.5.9
  • Update for 'direct' handling [77b84e2f]
  • do not require callback to be provided for 'direct' type [ec51c79f]

v0.5.8 2013-11-22

  • bumped version to v0.5.8
  • Added support for 'direct' transport [826f226d..0dbbcbbc]

v0.5.7 2013-11-18

  • bumped version to v0.5.7
  • Replace \r\n by \n in Sendmail transport (rolftimmermans) [fed2089e..616ec90c] A lot of sendmail implementations choke on \r\n newlines and require \n This commit addresses this by transforming all \r\n sequences passed to the sendmail command with \n

v0.5.6 2013-11-15

  • bumped version to v0.5.6
  • Upgraded mailcomposer dependency to 0.2.4 [e5ff9c40]
  • Removed noCR option [e810d1b8]
  • Update wellknown.js, added FastMail (k-j-kleist) [cf930f6d]

v0.5.5 2013-10-30

  • bumped version to v0.5.5
  • Updated mailcomposer dependnecy version to 0.2.3
  • Remove legacy code - node v0.4 is not supported anymore anyway
  • Use hostname (autodetected or from the options.name property) for Message-Id instead of "Nodemailer" (helps a bit when messages are identified as spam)
  • Added maxMessages info to README

v0.5.4 2013-10-29

  • bumped version to v0.5.4
  • added "use strict" statements
  • Added DSN info to README
  • add support for QQ enterprise email (coderhaoxin)
  • Add a Bitdeli Badge to README
  • DSN options Passthrought into simplesmtp. (irvinzz)

v0.5.3 2013-10-03

  • bumped version v0.5.3
  • Using a stub transport to prevent sendmail from being called during a test. (jsdevel)
  • closes #78: sendmail transport does not work correctly on Unix machines. (jsdevel)
  • Updated PaaS Support list to include Modulus. (fiveisprime)
  • Translate self closing break tags to newline (kosmasgiannis)
  • fix typos (aeosynth)

v0.5.2 2013-07-25

  • bumped version v0.5.2
  • Merge pull request #177 from MrSwitch/master Fixing Amazon SES, fatal error caused by bad connection
"use strict";
var createDirectmail = require("directmail");
// Expose to the world
module.exports = DirectTransport;
/**
* <p>Generates a Transport object for DirectMail</p>
*
* <p>Possible options can be the following:</p>
*
* <ul>
* <li><b>debug</b> - If true, logs output to console</li>
* </ul>
*
* @constructor
* @param {Object} options Options object for the DirectMail transport
*/
function DirectTransport(options){
this.directmail = createDirectmail(options);
}
// Setup version info for the transport
DirectTransport.prototype.version = createDirectmail.version;
/**
* <p>Compiles a mailcomposer message and forwards it to handler that sends it.</p>
*
* @param {Object} emailMessage MailComposer object
* @param {Function} callback Callback function to run when the sending is completed
*/
DirectTransport.prototype.sendMail = function(emailMessage, callback) {
this.generateMessage(emailMessage, (function(err, email){
if(err){
return typeof callback == "function" && callback(err);
}
this.handleMessage(emailMessage, email, callback);
}).bind(this));
};
/**
* <p>Compiles and sends the request to SMTP with e-mail data</p>
*
* @param {Object} emailMessage MailComposer object
* @param {String} email Compiled raw e-mail as a string
* @param {Function} callback Callback function to run once the message has been sent
*/
DirectTransport.prototype.handleMessage = function(emailMessage, email, callback) {
var statusHandler,
envelope = emailMessage.getEnvelope();
try{
statusHandler = this.directmail.send({
from: envelope.from,
recipients: envelope.to,
message: email
});
}catch(E){
if(typeof callback == "function"){
callback(E);
}
return;
}
if(typeof callback == "function"){
callback(null, {
message: "Message Queued",
messageId: emailMessage._messageId,
statusHandler: statusHandler
});
}
};
/**
* <p>Compiles the messagecomposer object to a string.</p>
*
* @param {Object} emailMessage MailComposer object
* @param {Function} callback Callback function to run once the message has been compiled
*/
DirectTransport.prototype.generateMessage = function(emailMessage, callback) {
var email = "";
emailMessage.on("data", function(chunk){
email += (chunk || "").toString("utf-8");
});
emailMessage.on("end", function(chunk){
email += (chunk || "").toString("utf-8");
callback(null, email);
});
emailMessage.streamMessage();
};
"use strict";
var fs = require("fs"),
path = require("path");
// Expose to the world
module.exports = PickupTransport;
/**
* <p>Generates a Transport object which stores mails in a pickup directory</p>
*
* <p>Possible options can be the following:</p>
*
* <ul>
* <li><b>directory</b> - The directory where applications save e-mail for later processing by the SMTP server.</li>
* </ul>
*
* @constructor
* @param {Object} [options] Pickup directory options
*/
function PickupTransport(options) {
if(typeof options == "string"){
options = {
directory: options
};
}
this.options = options || {};
// Check if target directory has been set.
if (typeof this.options.directory === "undefined") {
throw new Error('directory is not set.');
}
// Check if the target directory exists.
fs.exists(this.options.directory, function(exists) {
if (!exists) {
throw new Error('directory does not exists.');
}
});
}
/**
* <p>Generates a raw e-mail source and stores it in the pickup directory</p>
*
* @param {Object} emailMessage MailComposer object
* @param {Function} callback Callback function to run when the e-mail is composed
*/
PickupTransport.prototype.sendMail = function(emailMessage, callback) {
var directory = this.options.directory,
callbackSent = false,
target = path.join(
directory,
emailMessage._messageId + ".eml"),
targetStream = fs.createWriteStream(target);
callback = callback || function(){};
emailMessage.options.keepBcc = true;
emailMessage.on("error", function(err){
if(callbackSent){
return;
}
callbackSent = true;
callback(err);
});
targetStream.on("error", function(err){
if(callbackSent){
return;
}
callbackSent = true;
callback(err);
});
emailMessage.on("end", function(){
if(callbackSent){
return;
}
callbackSent = true;
callback(null, {
envelope: emailMessage.getEnvelope(),
messageId: emailMessage._messageId,
path: target
});
});
emailMessage.pipe(targetStream);
emailMessage.streamMessage();
};
"use strict";
var spawn = require("child_process").spawn;
var util = require("util");
var Transform = require("stream").Transform || require("readable-stream").Transform;
// Transforming stream that replaces SMTP-style \r\n line endings to
// Sendmail-style \n line endings.
function NewlineTransform(options){
Transform.call(this, options);
}
util.inherits(NewlineTransform, Transform);
NewlineTransform.prototype._transform = function(chunk, encoding, done){
this.push(chunk.toString().replace(/\r\n/g, "\n"));
done();
};
// Expose to the world
module.exports = SendmailTransport;
/**
* <p>Generates a Transport object for Sendmail</p>
*
* @constructor
* @param {String} [config] path to the sendmail command
*/
function SendmailTransport(config){
this.path = "sendmail";
this.args = false;
if(typeof config=="string"){
this.path = config;
}else if(typeof config=="object"){
if(config.path){
this.path = config.path;
}
if(Array.isArray(config.args)){
this.args = config.args;
}
}
}
/**
* <p>Spawns a sendmail command either using <code>sendmail -i -f from_addr to_addr[]</code>
* (by default) or <code>sendmail -i list_of_args[]</code> (if args property was given)
* and pipes message to sendmail stdin. Return callback checks if the sendmail process
* ended with 0 (no error) or not.</p>
*
* @param {Object} emailMessage MailComposer object
* @param {Function} callback Callback function to run when the sending is completed
*/
SendmailTransport.prototype.sendMail = function sendMail(emailMessage, callback){
var envelope = emailMessage.getEnvelope(),
args = this.args ? this.args.slice() : ["-f"].concat(envelope.from).concat(envelope.to),
sendmail,
cbCounter = 2,
didCb,
marker = "SendmailTransport.sendMail",
transform;
args.unshift("-i"); // force -i to keep single dots
try {
sendmail = spawn(this.path, args);
} catch (e){
e[marker] = "spawn exception";
sendmailResult(e);
}
if(sendmail){
sendmail.on("error", sendmailError);
sendmail.once("exit", sendmailExit);
sendmail.once("close", endEvent);
sendmail.stdin.on("error", sendmailStdinError);
transform = new NewlineTransform();
emailMessage.pipe(transform).pipe(sendmail.stdin);
emailMessage.streamMessage();
}
function sendmailError(e){
e[marker] = "sendmailError";
sendmailResult(e);
}
function sendmailStdinError(e){
e[marker] = "sendmailStdinError";
sendmailResult(e);
}
function sendmailExit(code){
if(!code){
endEvent();
}else{
sendmailResult(new Error("Sendmail exited with " + code));
}
}
function endEvent(){
if(!--cbCounter){
sendmailResult();
}
}
function sendmailResult(e){
if(didCb){
// ignore any additional responses
return;
}
didCb = true;
if(typeof callback === "function"){
if(e){
callback(e);
}else{
callback(null, {
messageId: emailMessage._messageId
});
}
}
}
};
"use strict";
/*
* This file is based on the original SES module for Nodemailer by dfellis
* https://github.com/andris9/Nodemailer/blob/11fb3ef560b87e1c25e8bc15c2179df5647ea6f5/lib/engines/SES.js
* and on the rewrite by andris9
* https://github.com/andris9/Nodemailer/blob/3ac11ae9a9faf95aabd9bffb37ca702fe33105e4/lib/engines/ses.js
*/
// NB! Amazon SES does not allow unicode filenames on attachments!
var AWS = require('aws-sdk');
// Expose to the world
module.exports = SESTransport;
/**
* <p>Generates a Transport object for Amazon SES with aws-sdk</p>
*
* <p>Possible options can be the following:</p>
*
* <ul>
* <li><b>accessKeyId</b> - AWS access key (optional)</li>
* <li><b>secretAccessKey</b> - AWS secret (optional)</li>
* <li><b>region</b> - optional region (defaults to <code>"us-east-1"</code>)
* </ul>
*
* @constructor
* @param {Object} optional config parameter for the AWS SES service
*/
function SESTransport(options) {
var pattern = /(.*)email(.*)\.(.*).amazonaws.com/i,
result = pattern.exec(options.ServiceUrl);
this.options = options || {};
this.options.accessKeyId = options.accessKeyId || options.AWSAccessKeyID;
this.options.secretAccessKey = options.secretAccessKey || options.AWSSecretKey;
this.options.sessionToken = options.sessionToken || options.AWSSecurityToken;
this.options.apiVersion = '2010-12-01';
this.options.region = options.region || (result && result[3]) || 'us-east-1';
this.ses = new AWS.SES(this.options);
}
/**
* <p>Compiles a mailcomposer message and forwards it to handler that sends it.</p>
*
* @param {Object} emailMessage MailComposer object
* @param {Function} callback Callback function to run when the sending is completed
*/
SESTransport.prototype.sendMail = function (emailMessage, callback) {
// SES strips this header line by itself
emailMessage.options.keepBcc = true;
this.generateMessage(emailMessage, (function (err, email) {
if (err) {
return typeof callback === "function" && callback(err);
}
this.handleMessage(email, callback);
}).bind(this));
};
/**
* <p>Compiles and sends the request to SES with e-mail data</p>
*
* @param {String} email Compiled raw e-mail as a string
* @param {Function} callback Callback function to run once the message has been sent
*/
SESTransport.prototype.handleMessage = function (email, callback) {
var params = {
RawMessage: { // required
Data: new Buffer(email, "utf-8") // required
}
};
this.ses.sendRawEmail(params, this.responseHandler.bind(this, callback));
};
/**
* <p>Handles the response for the HTTP request to SES</p>
*
* @param {Function} callback Callback function to run on end (binded)
* @param {Object} err Error object returned from the request
* @param {Object} data De-serialized data returned from the request
*/
SESTransport.prototype.responseHandler = function (callback, err, data) {
if (err) {
if (!(err instanceof Error)) {
err = new Error('Email failed: ' + err);
}
return typeof callback === "function" && callback(err, null);
}
return typeof callback === "function" && callback(null, {
messageId: data && data.MessageId && data.MessageId + "@email.amazonses.com"
});
};
/**
* <p>Compiles the messagecomposer object to a string.</p>
*
* <p>SES requires strings as parameter so the message needs to be fully composed as a string.</p>
*
* @param {Object} emailMessage MailComposer object
* @param {Function} callback Callback function to run once the message has been compiled
*/
SESTransport.prototype.generateMessage = function (emailMessage, callback) {
var email = "";
emailMessage.on("data", function (chunk) {
email += (chunk || "").toString("utf-8");
});
emailMessage.on("end", function (chunk) {
email += (chunk || "").toString("utf-8");
callback(null, email);
});
emailMessage.streamMessage();
};
"use strict";
var wellKnownHosts = require("../wellknown"),
simplesmtp = require("simplesmtp"),
wellKnownDomains = {};
// Expose to the world
module.exports = SMTPTransport;
// Convert Wellknown keys to lowercase
wellKnownHosts = Object.keys(wellKnownHosts).reduce(function(lowerCaseKeys, currentKey){
[].concat(wellKnownHosts[currentKey].domains || []).forEach(function(domain){
wellKnownDomains[domain] = currentKey.toLowerCase().trim();
});
lowerCaseKeys[currentKey.toLowerCase().trim()] = wellKnownHosts[currentKey];
return lowerCaseKeys;
},{});
/**
* <p>Generates a Transport object for SMTP</p>
*
* <p>NB! This is a pool of connections that try to keep themselves alive. The
* connection is not closed to the server once the message is delivered.</p>
*
* <p>Possible options can be the following:</p>
*
* <ul>
* <li><b>service</b> - a well known service identifier ("Gmail", "Hotmail"
* etc.) for auto-completing host, port and secure connection settings</li>
* <li><b>host</b> - hostname of the SMTP server</li>
* <li><b>port</b> - port of the SMTP server</li>
* <li><b>secureConnection</b> - use SSL</li>
* <li><b>name</b> - the name of the client server</li>
* <li><b>authMethod</b> -specified the authMethod, value can be ["plain", "login"], default is "plain"</li>
* <li><b>auth</b> - authentication object as <code>{user:"...", pass:"..."}</code>
* <li><b>ignoreTLS</b> - ignore server support for STARTTLS</li>
* <li><b>debug</b> - output client and server messages to console</li>
* <li><b>maxConnections</b> - how many connections to keep in the pool</li>
* <li><b>maxMessages</b> - limit the count of messages to send through a single connection</li>
* <li><b>greetingTimeout</b> - Time to wait in ms until greeting message is received from the server (defaults to 10000)</li>
* <li><b>socketTimeout</b> - Time of inactivity until the connection is closed (defaults to 1 hour)</li>
* </ul>
*
* @constructor
* @param {Object} [options] SMTP options
*/
function SMTPTransport(options){
this.options = options || {};
this.initOptions();
this.pool = simplesmtp.createClientPool(this.options.port,
this.options.host, this.options);
}
SMTPTransport.wellKnownHosts = wellKnownHosts;
// Setup version info for the transport
SMTPTransport.prototype.version = simplesmtp.version;
/**
* <p>Initializes the SMTP connection options. Needed mostly for legacy option
* values and also for filling in the well known hosts data if needed.</p>
*/
SMTPTransport.prototype.initOptions = function(){
var keys, key, i, len, service;
// provide support for legacy API
if(this.options.use_authentication === false){
this.options.auth = false;
}else if(this.options.user || this.options.pass || this.options.XOAuthToken){
if(!this.options.auth){
this.options.auth = {};
}
this.options.authMethod = this.options.authMethod || "PLAIN";
this.options.auth.user = this.options.auth.user || this.options.user;
this.options.auth.pass = this.options.auth.pass || this.options.pass;
this.options.auth.XOAuthToken = this.options.auth.XOAuthToken || this.options.XOAuthToken;
this.options.auth.XOAuth2 = this.options.auth.XOAuth2 || this.options.XOAuth2;
}
if(this.options.ssl){
this.options.secureConnection = true;
}
if(this.options.tls === false){
this.options.ignoreTLS = true;
}
// lets be modest just in case
this.options.maxConnections = this.options.maxConnections || 5;
// detect service from the e-mail address if host is not provided before falling to localhost
if(!this.options.host && !this.options.port && !this.options.service && this.options.auth && this.options.auth.user){
this.options.service = wellKnownDomains[(this.options.auth.user || "").toString().split("@").pop().toLowerCase().trim()] || false;
}
// use well known settings if service is defined
if((service = this.options.service) && (service = service.toString().toLowerCase().trim()) && wellKnownHosts[service]){
keys = Object.keys(wellKnownHosts[service]);
for(i=0, len=keys.length; i<len; i++){
key = keys[i];
this.options[key] = this.options[key] ||
wellKnownHosts[service][key];
}
}
};
/**
* <p>Forwards the mailcomposer message object to the simplesmpt client pool</p>
*
* @param {Object} emailMessage MailComposer object
* @param {Function} callback Callback function to run when the sending is completed
*/
SMTPTransport.prototype.sendMail = function(emailMessage, callback){
// force SMTP encoding
emailMessage.options.escapeSMTP = true;
if(this.options.requiresAuth &&
(!this.options.auth || !((this.options.auth.user && this.options.auth.pass) || this.options.auth.XOAuth2 || this.options.auth.XOAuthToken))){
return typeof callback == "function" &&
callback(new Error("Authentication required, invalid details provided"));
}
this.pool.sendMail(emailMessage, callback);
};
/**
* <p>Closes the client pool</p>
*
* @param {Function} callback Callback function to run once the pool is closed
*/
SMTPTransport.prototype.close = function(callback){
this.pool.close(callback);
};
"use strict";
// Expose to the world
module.exports = StubTransport;
/**
* <p>Generates a stub Transport object for testing purposes</p>
*
* @constructor
*/
function StubTransport(options){
this.options = options || {};
}
/**
* <p>Generates a raw e-mail source and returns it with callback</p>
*
* @param {Object} emailMessage MailComposer object
* @param {Function} callback Callback function to run when the e-mail is composed
*/
StubTransport.prototype.sendMail = function(emailMessage, callback) {
var output = "";
if(this.options.error){
return callback(new Error(this.options.error.message || this.options.error));
}
// sendmail strips this header line by itself
emailMessage.options.keepBcc = true;
emailMessage.on("data", function(data){
output += (data || "").toString("utf-8");
});
emailMessage.on("error", function(err){
callback(err);
});
emailMessage.on("end", function(){
callback(null, {message: output, envelope: emailMessage.getEnvelope(), messageId: emailMessage._messageId});
});
emailMessage.streamMessage();
};
"use strict";
var he = require("he");
// expose to the world
module.exports.stripHTML = stripHTML;
/**
* <p>Converts a HTML stringo into plaintext format that resembles Markdown</p>
*
* <p>Only good for simple and valid HTML, probably breaks on eveything else</p>
*
* <p>Placeholders:</p>
*
* <ul>
* <li>-\u0000\u0000- for newline</li>
* <li>-\u0001\u0001- for a space</li>
* <li>-\u0002\u0002- temporary newlines</li>
* </ul>
*
* @param {String} str HTML string to convert
* @return {String} Plaintext that resembles Markdown
*/
function stripHTML(str){
str = (str || "").toString("utf-8").trim();
// remove head
str = str.replace(/<head[\s\S]{1,}?\/head>/gi, '');
// replace newlines
str = str.replace(/\r?\n|\r/g,"-\u0002\u0002-");
// convert block element endings to linebreak markers
str = str.replace(/<(?:\/p|br\s*\/*|\/tr|\/table|\/div)>/g,"-\u0000\u0000--\u0000\u0000-");
// H1-H6, add underline or prepend with #
str = str.replace(/<[hH](\d)[^>]*>(.*?)<\/[hH]\d[^>]*>/g,function(match, level, content){
var line = "",
symbol, // line symbol char
len;
level = Number(level) || 0;
content = he.decode(content.replace(/<[^>]*>/g," ").
replace(/\s\s+/g," ")).
trim();
if(!content){
// the tag was empty or only included other tags (<img> and such), nothing to show
return "";
}
// select correct symbol for the line
switch(level){
case 1:
symbol = "=";
len = content.length;
break;
case 2:
symbol = "-";
len = content.length;
break;
default:
symbol = "#";
len = level;
}
line = new Array(len+1).join(symbol);
if(symbol == "#"){
// prepend the line:
// ### This is a H3
return line + " " + content + "\n\n";
}else{
// add underline:
// This is a H1
// ============
return content + "\n" + line + "\n\n";
}
});
// B
str = str.replace(/<(?:b|strong)(?: [^>])?>(.*?)<\/(?:b|strong)>/ig,function(match, content){
return "**" + content.trim() + "**";
});
// U
str = str.replace(/<u(?: [^>])?>(.*?)<\/u>/ig,function(match, content){
return "_" + content.trim() + "_";
});
// EM
str = str.replace(/<(?:i|em)(?: [^>])?>(.*?)<\/(?:i|em)>/ig,function(match, content){
return "*" + content.trim() + "*";
});
// CODE
str = str.replace(/<code(?: [^>])?>(.*?)<\/code>/ig,function(match, content){
return "`" + content.trim() + "`";
});
// A
str = str.replace(/<a ([^>]*)>(.*?)<\/a[^>]*>/ig,function(match, params, content){
var paramMatch = params.match(/href\s*=\s*['"]([^'"]+)['"]/),
url = paramMatch && paramMatch[1] || "#";
return "[" + content.trim() + "]" + "(" + url +")";
});
// UL, replace with newlines
str = str.replace(/(<\/(?:ul|ol)>)/gi,"$1-\u0000\u0000--\u0000\u0000-");
// LI, indent by 2 spaces + *
str = str.replace(/<li[^>]*>(.*?)<\/?(?:li|ol|ul)[^>]*>/ig,function(match, content){
content = content.replace(/<[^>]*>/g," ").
replace(/\s\s+/g," ").
trim();
if(!content){
// the tag was empty or only included other tags (<img> and such), nothing to show
return "";
}
// return with the space placeholders
return "-\u0001\u0001--\u0001\u0001-* " + content + "\n";
});
// PRE, indent by 4 spaces
str = str.replace(/<pre[^>]*>(.*?)<\/pre[^>]*>/ig,function(match, content){
if(!content){
return "";
}
// remove empty lines before and after
content = content.replace(/^((?:[ \t]*)\-\u0002\u0002\-)+|((?:\-\u0002\u0002\-[ \t]*))+$/g, "");
// replace tabs with 4 spaces
content = content.replace(/\t/g, " ");
// replace temp. linebreak placeholders with 4 space placehorlders
content = content.replace(/\-\u0002\u0002\-([ ]*)/g, function(match, spaces){
// keep spaces in the beginning of the lines
spaces = spaces.replace(/ /g, "-\u0001\u0001-");
return "\n-\u0001\u0001--\u0001\u0001--\u0001\u0001--\u0001\u0001-" + spaces;
});
content = content.replace(/</g,"&lt;").replace(/>/g,"&gt;");
// add prepending 4 spaces
return "\n-\u0001\u0001--\u0001\u0001--\u0001\u0001--\u0001\u0001-" + content.trim() + "\n\n";
});
// remove all remaining html tags
str = str.replace(/<[^>]*>/g," ");
// remove duplicate spaces
str = str.replace(/[ ][ ]+/g," ");
// remove temp. newlines
str = str.replace(/-\u0002\u0002-/g," ");
// restore newlines
str = str.replace(/-\u0000\u0000-/g,"\n");
// remove spaces before and after newlines
str = str.replace(/[ \t]*\n[ \t]*/g,"\n");
// remove more than 2 newlines in a row
str = str.replace(/\n\n+/g,"\n\n");
// restore hidden spaces
str = str.replace(/-\u0001\u0001-/g," ");
// decode HTML entities (&lt; and such)
str = he.decode(str);
return str.trim();
}
"use strict";
var transportHandler = require("./transport"),
Transport = transportHandler.Transport,
MailComposer = require("mailcomposer").MailComposer,
XOAuthGenerator = require("./xoauth").XOAuthGenerator,
helpers = require("./helpers"),
crypto = require("crypto"),
os = require("os"),
net = require("net"),
packageData = require("../package.json"),
publicAddress = require("public-address");
/*
* Version constants
*/
var X_MAILER_NAME = "Nodemailer",
X_MAILER_HOMEPAGE = packageData.homepage;
module.exports.X_MAILER_NAME = X_MAILER_NAME;
module.exports.X_MAILER_HOMEPAGE = X_MAILER_HOMEPAGE;
// Export createTransport method
module.exports.createTransport = function(type, options){
var transport = new Transport(type, options);
transport.sendMail = function(options, callback){
options = options || {};
options.transport = options.transport || transport;
sendMail(options, callback);
};
return transport;
};
//Export createXOAuthGenerator function
module.exports.createXOAuthGenerator = function(options){
return new XOAuthGenerator(options);
};
// exports mail generator
Object.defineProperty(module.exports, "mail", {
get: function(){
var transport = module.exports.createTransport("direct");
return function(mailData){
transport.sendMail(mailData);
};
}
});
// Export Transport constructor
module.exports.Transport = Transport;
// Export Nodemailer constructor
module.exports.Nodemailer = Nodemailer;
// Export sendMail function (and the alias send_mail for legacy)
module.exports.sendMail = module.exports.send_mail = sendMail;
function sendMail(options, callback){
var mailer = new Nodemailer(options);
mailer.validateSettings(function(err){
if(err){
// report validation error back to the client
return callback(err);
}else{
// try to send the e-mail message
mailer.sendMail(callback);
}
});
return mailer;
}
/**
* <p>Generates a Nodemailer object which is the main 'hub' for managing the
* send process</p>
*
* @constructor
* @param {Object} options Message options object, see README for the complete list of possible options
*/
function Nodemailer(options){
var mailcomposerOptions = {};
this.options = options || {};
this.transport = this.options.transport;
mailcomposerOptions.identityString = X_MAILER_NAME + " " + packageData.version;
if(this.options.identityString){
mailcomposerOptions.identityString = this.options.identityString;
}
if(this.options.encoding){
mailcomposerOptions.encoding = this.options.encoding;
}
if(this.options.charset){
mailcomposerOptions.charset = this.options.charset;
}
if(!!this.options.forceEmbeddedImages){
mailcomposerOptions.forceEmbeddedImages = true;
}
this.mailcomposer = new MailComposer(mailcomposerOptions);
if(!this.transport){
this.transport = this.getGlobalTransport();
}
}
/**
* <p>Generates an user agent string for Nodemailer with homepage, version etc.</p>
*
* @return {String} user agent string for X-Mailer value
*/
Nodemailer.prototype.generateUserAgentString = function(){
var details = [];
if(packageData.version){
details.push(packageData.version);
}
if(X_MAILER_HOMEPAGE){
details.push("+"+X_MAILER_HOMEPAGE);
}
if(this.transport){
details.push((this.transport.transportType || "").toLowerCase() +
(this.transport.version ? "/" + this.transport.version : ""));
}
return X_MAILER_NAME+ (details.length?" ("+details.join("; ")+")":"");
};
/**
* <p>Add support for legacy transport settings by checking for global
* variables SMTP, sendmail and SES</p>
*
* @return {Object} {@link Transport} object
*/
Nodemailer.prototype.getGlobalTransport = function(){
if(this.options.SMTP){
// cache the transport for SMTP as it is actually a connection pool
if(!this.options.SMTP._smtp_transport){
this.options.SMTP._smtp_transport = new Transport("SMTP", this.options.SMTP);
}
return this.options.SMTP._smtp_transport;
}else if(this.options.sendmail){
return new Transport("sendmail", this.options.sendmail);
}else if(this.options.SES){
return new Transport("SES", this.options.SES);
}else if(module.exports.SMTP){
// cache the transport for SMTP as it is actually a connection pool
if(!module.exports._smtp_transport){
module.exports._smtp_transport = new Transport("SMTP", module.exports.SMTP);
}
return module.exports._smtp_transport;
}else if(module.exports.sendmail){
return new Transport("sendmail", module.exports.sendmail);
}else if(module.exports.SES){
return new Transport("SES", module.exports.SES);
}
return false;
};
/**
* <p>Doesn't do much currently, if the future should link to transport
* validation methods. For example in case of SES should check that AWS
* keys are set up etc.</p>
*
* @param {Function} callback Callback function to run after validation
*/
Nodemailer.prototype.validateSettings = function(callback){
if(!this.transport || !this.transport.transport){
return callback(new Error("No transport method defined"));
}
// transport.options.resolveHostname is set to true, resolve pulbic
// hostname for the machine and use this when generating Message-ID values
// or when communicating with SMTP
if(this.transport.options && this.transport.options.resolveHostname && !this.transport.options.name){
return publicHostnameResolver.resolve((function(err, resolved){
this.transport.options.name = this.resolveHostname(
resolved ? resolved.hostname : this.options.name);
callback();
}).bind(this));
}
callback(null);
};
/**
* <p>Send the e-mail message by using data from the original options object
* and selected transport</p>
*
* @param {Function} callback Callback function to run when the e-mail has been sent (or it failed)
*/
Nodemailer.prototype.sendMail = function(callback){
// compose the e-mail
this.generateMailObject();
// send the message using preselected transport method
this.transport.sendMailWithTransport(this.mailcomposer, callback);
};
/**
* <p>Uses the data from the original options object to compose a mailcomposer
* e-mail message that can be later streamed to the selected transport</p>
*/
Nodemailer.prototype.generateMailObject = function(){
// set envelope data, subject etc.
this.setGeneralOptions();
// set module defined headers (date, message-id, etc.)
this.setModuleHeaders();
// set user defined headers (if any)
this.setUserHeaders();
// set alternatives (if any)
this.setAlternatives();
// set attachments (if any)
this.setAttachments();
// setup dsn
if(this.options.dsn){
this.mailcomposer.options.dsn = this.options.dsn;
}
};
/**
* <p>Uses the general options (message sender and receiver, subject body, etc.)
* to set mailcomposer properties. Includes support for legacy properties.</p>
*/
Nodemailer.prototype.setGeneralOptions = function(){
// generate plaintext if only HTML exists and generateTextFromHTML is true
if(!(this.options.text || this.options.body) && (this.options.html) &&
this.options.generateTextFromHTML){
this.options.text = helpers.stripHTML(this.options.html);
}
var acceptedFields = ["from", "sender", "to", "subject", "replyTo", "debug",
"reply_to", "cc", "bcc", "body", "text", "html",
"envelope", "inReplyTo", "references"],
mailOptions = {},
keys = Object.keys(this.options),
key;
for(var i=0, len=keys.length; i<len; i++){
key = keys[i];
if(acceptedFields.indexOf(key) >=0 && this.options[key]){
mailOptions[key] = this.options[key];
}
}
if(this.options.debug){
console.log(mailOptions);
}
this.mailcomposer.setMessageOption(mailOptions);
};
/**
* <p>If the 'headers' property was set on the options, add the values to the
* header of the e-mail message</p>
*/
Nodemailer.prototype.setUserHeaders = function(){
if(typeof this.options.headers != "object"){
return;
}
var keys = Object.keys(this.options.headers),
key;
for(var i=0, len=keys.length; i<len; i++){
key = keys[i];
if(this.options.headers[key]){
this.mailcomposer.addHeader(key, this.options.headers[key], true);
}
}
};
/**
* <p>Add some required headers to the message, such as Date: and Message-Id:</p>
*/
Nodemailer.prototype.setModuleHeaders = function(){
var messageId,
transportOptions = this.transport &&
this.transport.options &&
typeof this.transport.options == "object" &&
this.transport.options || {};
// Mailer name + version
// if xMailer is explicitly set to false, skip the X-Mailer header
if(transportOptions.xMailer !== false){
this.mailcomposer.addHeader("X-Mailer",
transportOptions.xMailer || this.generateUserAgentString());
}
// Date
if(this.options.date){
this.mailcomposer.addHeader("Date", this.options.date);
}else{
this.mailcomposer.addHeader("Date", new Date().toUTCString());
}
// Message ID
if(this.options.messageId){
messageId = this.options.messageId;
}else if(this.options.messageId !== false){
messageId = crypto.randomBytes(15).toString("hex") +"@"+ this.resolveHostname(this.options.name || transportOptions.name);
}
if(messageId){
this.mailcomposer.addHeader("Message-Id", "<"+messageId+">");
this.mailcomposer._messageId = messageId;
}
};
/**
* <p>If attachment array is set on the options object, add these alternatives
* to the mailcomposer object</p>
*/
Nodemailer.prototype.setAlternatives = function(){
var alternative;
if(!this.options.alternatives){
return;
}
// convert non array value to an array if needed
this.options.alternatives = [].concat(this.options.alternatives);
for(var i=0, len=this.options.alternatives.length; i<len; i++){
alternative = this.options.alternatives[i];
this.mailcomposer.addAlternative(alternative);
}
};
/**
* <p>If attachment array is set on the options object, add these attachments
* to the mailcomposer object</p>
*/
Nodemailer.prototype.setAttachments = function(){
var attachment;
if(!this.options.attachments){
return;
}
// convert non array value to an array if needed
this.options.attachments = [].concat(this.options.attachments);
for(var i=0, len=this.options.attachments.length; i<len; i++){
attachment = this.options.attachments[i];
attachment.userAgent = attachment.userAgent || this.generateUserAgentString();
this.mailcomposer.addAttachment(attachment);
}
};
/**
* Resolves hostname, prefers given argument. If resolved
* name is an IP address, "localhost" is used
*
* @param {String} [name] Preferred hostname
* @return {String} Resolved hostname
*/
Nodemailer.prototype.resolveHostname = function(name){
if(name === true){
name = false;
}
if(!name || net.isIP(name.replace(/[\[\]]/g, "").trim())){
name = (os.hostname && os.hostname()) || "";
}
if(!name || net.isIP(name.replace(/[\[\]]/g, "").trim())){
name = "localhost";
}
return name.toLowerCase();
};
/**
* Interface for resolving public hostname for the current machine
* Resolves the hostname only once and uses the cached value later on
*/
var publicHostnameResolver = {
_callbacks: [],
_resolving: false,
_resolved: false,
/**
* Resolve hostname for the current machine
*
* @param {Function} callback Function with an error object and resolved data as arguments
*/
resolve: function(callback){
if(this._resolved){
return callback(null, this._resolved);
}
this._callbacks.push(callback);
if(!this._resolving){
this._startResolving();
}
},
/**
* Initiate hostname resolving
*/
_startResolving: function(){
this._resolving = true;
publicAddress((function(err, data){
this._resolving = false;
// if the resolving failed, skip it
this._resolved = data || {};
// emit all queued callbacks
this._callbacks.forEach((function(callback){
callback(null, this._resolved);
}).bind(this));
}).bind(this));
}
};
"use strict";
var SendmailTransport = require("./engines/sendmail"),
SMTPTransport = require("./engines/smtp"),
SESTransport = require("./engines/ses"),
StubTransport = require("./engines/stub"),
DirectTransport = require("./engines/direct"),
PickupTransport = require("./engines/pickup");
// Expose to the world
module.exports.Transport = Transport;
/**
* Hash of available transports (uppercase) and their constructor methods
*/
Transport.transports = {
"SMTP": SMTPTransport,
"SES": SESTransport,
"SENDMAIL": SendmailTransport,
"STUB": StubTransport,
"DIRECT": DirectTransport,
"PICKUP": PickupTransport
};
/**
* <p>Generates a Transport object that can be used to deliver e-mail.</p>
*
* <p>All transport objects need to have <code>sendMail</code> property defined
* and if needed, also an <code>close</code> method</p>
*
* @constructor
* @param {String|Function} type The type of the transport, currently available: SMTP, SES and Sendmail
*/
function Transport(type, options){
var Constructor;
this.options = options || {};
if(typeof type == "function"){
this.transportType = (type.name || "CUSTOM").toString().toUpperCase().trim();
Constructor = type;
}else{
this.transportType = (type || "direct").toString().trim().toUpperCase();
this.dkimOptions = false;
if(!(this.transportType in Transport.transports) && this.transportType.toLowerCase() in SMTPTransport.wellKnownHosts){
this.options.service = this.transportType;
this.transportType = SMTPTransport.wellKnownHosts[this.transportType.toLowerCase()].transport;
}
Constructor = Transport.transports[this.transportType];
}
if(Constructor){
this.transport = new Constructor(this.options);
this.version = this.transport.version || false;
}else{
this.transport = false;
}
}
/**
* <p>Forwards the generated mailcomposer object to the selected transport
* object for message delivery</p>
*
* @param {Object} emailMessage MailComposer object
* @param {Function} callback Callback function to run when the sending is completed
*/
Transport.prototype.sendMailWithTransport = function(emailMessage, callback){
if(!this.transport){
return callback(new Error("Invalid transport method defined"));
}
if(this.dkimOptions){
emailMessage.useDKIM(this.dkimOptions);
}
this.transport.sendMail(emailMessage, callback);
};
/**
* <p>Sets up DKIM signing for this transport object</p>
*
* @param {Object} dkim DKIM options
*/
Transport.prototype.useDKIM = function(dkim){
this.dkimOptions = dkim;
};
/**
* <p>Closes the transport when needed, useful with SMTP (which uses connection
* pool) but not so much with SES or Sendmail</p>
*
* @param {Function} Callback function to run when the connection is closed
*/
Transport.prototype.close = function(callback){
if(!this.transport){
return callback(new Error("Invalid transport method defined"));
}
if(typeof this.transport.close == "function"){
this.transport.close(callback);
}else{
if(typeof callback == "function"){
callback(null);
}
}
};
"use strict";
/*
* This is a collection of well known SMTP service providers
*/
module.exports = {
"Gmail":{
transport: "SMTP",
host: "smtp.gmail.com",
secureConnection: true,
port: 465,
requiresAuth: true,
domains: ["gmail.com", "googlemail.com"]
},
"Yahoo":{
transport: "SMTP",
host: "smtp.mail.yahoo.com",
secureConnection: true,
port: 465,
requiresAuth: true,
domains: ["yahoo.com"]
},
"Hotmail":{
transport: "SMTP",
host: "smtp.live.com",
port: 587,
requiresAuth: true,
domains: ["hotmail.com", "outlook.com"],
tls: {ciphers:'SSLv3'}
},
"hot.ee":{
transport: "SMTP",
host: "mail.hot.ee",
requiresAuth: true,
domains: ["hot.ee"]
},
"mail.ee":{
transport: "SMTP",
host: "smtp.mail.ee",
requiresAuth: true,
domains: ["mail.ee"]
},
"SES":{
transport: "SMTP",
host: "email-smtp.us-east-1.amazonaws.com",
secureConnection: true,
port: 465,
requiresAuth: true
},
"Zoho":{
transport: "SMTP",
host: "smtp.zoho.com",
secureConnection: true,
port: 465,
requiresAuth: true,
authMethod: 'LOGIN'
},
"iCloud":{
transport: "SMTP",
host:"smtp.mail.me.com",
port: 587,
requiresAuth: true,
domains: ["me.com", "mac.com"]
},
"SendGrid":{
transport: "SMTP",
host: "smtp.sendgrid.net",
port: 587,
requiresAuth: true
},
"Mailgun":{
transport: "SMTP",
host: "smtp.mailgun.org",
port: 587,
requiresAuth: true,
tls: {ciphers:'SSLv3'}
},
"Postmark":{
transport: "SMTP",
host: "smtp.postmarkapp.com",
port: 25,
requiresAuth: true
},
"yandex":{
transport: "SMTP",
host: "smtp.yandex.ru",
port: 465,
secureConnection: true,
requiresAuth: true,
domains: ["yandex.ru"]
},
"Mail.Ru":{
transport: "SMTP",
host: "smtp.mail.ru",
port: 465,
secureConnection: true,
requiresAuth: true,
domains: ["mail.ru"]
},
"DynectEmail":{
transport: "SMTP",
host:"smtp.dynect.net",
port:25,
requiresAuth: true
},
"Mandrill":{
transport: "SMTP",
host: "smtp.mandrillapp.com",
port: 587,
requiresAuth: true
},
"Mailjet":{
transport: "SMTP",
host: "in.mailjet.com",
port: 587,
requiresAuth: true
},
"QQ":{
transport: "SMTP",
host: "smtp.qq.com",
secureConnection: true,
port: 465,
requiresAuth: true,
domains: ["qq.com"]
},
"QQex":{
transport: "SMTP",
host: "smtp.exmail.qq.com",
secureConnection: true,
port: 465,
requiresAuth: true,
domains: ["exmail.qq.com"]
},
"Godaddy": {
transport: "SMTP",
host: "smtpout.secureserver.net",
port: 25,
requiresAuth: true
},
"GodaddyEurope": {
transport: "SMTP",
host: "smtp.europe.secureserver.net",
port: 25,
requiresAuth: true
},
"GodaddyAsia": {
transport: "SMTP",
host: "smtp.asia.secureserver.net",
port: 25,
requiresAuth: true
},
// https://www.fastmail.fm/help/remote_email_access_server_names_and_ports.html
'FastMail': {
transport: 'SMTP',
host: 'mail.messagingengine.com',
secureConnection: true,
port: 465,
requiresAuth: true,
// and many more: https://www.fastmail.fm/help/signup_domains.html
domains: ['fastmail.fm']
},
"SendCloud": {
transport: "SMPT",
host: "smtpcloud.sohu.com",
port: 25,
requiresAuth: true
},
// http://help.aol.com/help/microsites/microsite.do?cmd=displayKC&externalId=73332
"AOL":{
transport: "SMTP",
host: "smtp.aol.com",
port: 587,
requiresAuth: true,
domains: ["aol.com"]
}
};
"use strict";
// this module is inspired by xoauth.py
// http://code.google.com/p/google-mail-xoauth-tools/
var crypto = require("crypto");
module.exports.XOAuthGenerator = XOAuthGenerator;
function XOAuthGenerator(options){
this.options = options || {};
}
XOAuthGenerator.prototype.generate = function(callback){
return generateXOAuthStr(this.options, callback);
};
function escapeAndJoin(arr){
return arr.map(encodeURIComponent).join("&");
}
function hmacSha1(str, key){
var hmac = crypto.createHmac("sha1", key);
hmac.update(str);
return hmac.digest("base64");
}
function initOAuthParams(options){
return {
oauth_consumer_key: options.consumerKey || "anonymous",
oauth_nonce: options.nonce || "" + Date.now() + Math.round(Math.random()*1000000),
oauth_signature_method: "HMAC-SHA1",
oauth_version: "1.0",
oauth_timestamp: options.timestamp || "" + Math.round(Date.now()/1000)
};
}
function generateOAuthBaseStr(method, requestUrl, params){
var reqArr = [method, requestUrl].concat(Object.keys(params).sort().map(function(key){
return key + "=" + encodeURIComponent(params[key]);
}).join("&"));
return escapeAndJoin(reqArr);
}
function generateXOAuthStr(options, callback){
options = options || {};
var params = initOAuthParams(options),
requestUrl = options.requestUrl || "https://mail.google.com/mail/b/" + (options.user || "") + "/smtp/",
baseStr, signatureKey, paramsStr, returnStr;
if(options.token){
params.oauth_token = options.token;
}
baseStr = generateOAuthBaseStr(options.method || "GET", requestUrl, params);
signatureKey = escapeAndJoin([options.consumerSecret || "anonymous", options.tokenSecret]);
params.oauth_signature = hmacSha1(baseStr, signatureKey);
paramsStr = Object.keys(params).sort().map(function(key){
return key+"=\""+encodeURIComponent(params[key])+"\"";
}).join(",");
returnStr = [options.method || "GET", requestUrl, paramsStr].join(" ");
if(typeof callback == "function"){
callback(null, new Buffer(returnStr, "utf-8").toString("base64"));
}else{
return new Buffer(returnStr, "utf-8").toString("base64");
}
}
Copyright (c) 2011-2014 Andris Reinman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
#!/bin/sh
basedir=`dirname "$0"`
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../he/bin/he" "$@"
ret=$?
else
node "$basedir/../he/bin/he" "$@"
ret=$?
fi
exit $ret
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\he\bin\he" %*
) ELSE (
node "%~dp0\..\he\bin\he" %*
)
{
"env": {
"browser": true,
"node": true
},
"globals": {
"Buffer": true,
"escape": true
},
"rules": {
"quotes": [2, "single"],
"strict": 0,
"curly": 0,
"no-underscore-dangle": 0,
"new-cap": 0,
"dot-notation": 0,
"no-use-before-define": 0,
"no-require-in-service": 2
}
}
configuration
node_modules
npm-debug.log
coverage.html
vendor
.yardoc
doc
test/browser/build
test/browser/sample/appinfo.js
dist/aws-sdk-all.js
{
"node": true,
"browser": true,
"bitwise": true,
"camelcase": true,
"curly": false,
"eqeqeq": false,
"forin": true,
"immed": true,
"indent": 2,
"latedef": true,
"newcap": true,
"noarg": true,
"noempty": true,
"nonew": true,
"plusplus": false,
"quotmark": "single",
"regexp": true,
"undef": true,
"unused": true,
"strict": false,
"trailing": true,
"maxparams": false,
"maxdepth": false,
"maxstatements": 40,
"maxcomplexity": 10,
"sub": true,
"indent": false
}
.yard*
.eslintrc
.travis.yml
apis/source
configuration
configuration.sample
dist
dist-tools
doc
doc-src
eslint-rules
Gemfile
Gemfile.lock
features
Rakefile
test
tasks
vendor
language: node_js
node_js:
- "0.10"
branches:
only:
- master
- normalized
before_script:
- "npm install git://github.com/aws/aws-sdk-js-apis#$TRAVIS_BRANCH"
script: "if [ $INTEGRATION ]; then cucumber.js -f pretty; else npm test; fi"
# env:
# global:
# - secure: "..."
# matrix:
# - UNIT=1
# - AWS_REGION=us-east-1 INTEGRATION=1
-m markdown
--markup-provider rdiscount
--exclude lib/aws.js
--no-api private
--api experimental
--no-highlight
--title "AWS SDK for JavaScript"
--template-path doc-src/templates
--plugin sitemap
-o doc/latest
-e doc-src/templates/api-versions/plugin.rb
--plugin js
--define-class-expr (AWS\.util\.)?inherit
--update-class-expr (AWS\.util\.)?update
--mixin-module-expr (AWS\.util\.)?mixin
lib/core.js
lib/**/*.js
-
README.md
UPGRADING.md
--plugin sitemap
-t flasky_sphinx_guide
-p doc-src/templates
--title "AWS SDK for JavaScript"
--no-highlight
-o doc/guide
--readme doc-src/guide/index.md
-
doc-src/guide/browser-intro.md
doc-src/guide/browser-configuring.md
doc-src/guide/browser-services.md
doc-src/guide/browser-making-requests.md
doc-src/guide/browser-examples.md
doc-src/guide/browser-building.md
doc-src/guide/browser-configuring-wif.md
doc-src/guide/node-intro.md
doc-src/guide/node-configuring.md
doc-src/guide/node-services.md
doc-src/guide/node-making-requests.md
doc-src/guide/node-examples.md
{
"name": "aws-sdk",
"ignore": [
"doc-src", "features", "lib", "scripts", "tasks", "test",
"Gemfile*", "configuration*", "Rakefile", "*.json", ".*"
],
"main": "dist/aws-sdk.js"
}
{
"accessKeyId": "YOUR_ACCESS_KEY_ID",
"secretAccessKey": "YOUR_SECRET_ACCESS_KEY",
"region": "us-west-1"
}
{
"env": {
"node": true
},
"rules": {
"quotes": [2, "single"],
"strict": 0,
"curly": 0
}
}
#!/usr/bin/env node
var fs = require('fs');
var path = require('path');
var CacheStrategy = require('./strategies/cache');
var DefaultStrategy = require('./strategies/default');
var defaultServices = 'cloudwatch,dynamodb,kinesis,s3,sqs,sns,sts';
var sanitizeRegex = /[^a-zA-Z0-9,-]/;
function Builder(options) {
this.setDefaultOptions(options);
this.serviceCode = [];
this.builtServices = {};
this.buildStrategy = this.options.cache ?
new CacheStrategy(this) : new DefaultStrategy(this);
}
Builder.prototype.setDefaultOptions = function(options) {
this.options = options || {};
this.options.libPath = this.options.libPath || this.getRootPath();
this.options.cacheRoot = this.options.cacheRoot ||
path.join(this.options.libPath, 'dist-tools', 'cache');
this.options.cache = this.options.cache || false;
this.options.writeCache = this.options.writeCache || false;
this.options.minify = this.options.minify || false;
this.options.minifyOptions = this.options.minifyOptions || {compress: false};
};
Builder.prototype.getRootPath = function() {
return path.join(__dirname, '..');
};
Builder.prototype.cachePath = function(path) {
var fullPath = this.options.cacheRoot;
if (path) {
fullPath += '/' + path + (this.options.minify ? '.min' : '') + '.js';
}
return fullPath;
};
Builder.prototype.cacheExists = function(path) {
return fs.existsSync(this.cachePath(path));
};
Builder.prototype.buildService = function(name, usingDefaultServices) {
var match = name.match(/^(.+?)(?:-(.+?))?$/);
var service = match[1], version = match[2] || 'latest';
var contents = [];
var lines, err;
if (!this.builtServices[service]) {
this.builtServices[service] = {};
lines = this.buildStrategy.getServiceHeader(service);
if (lines === null) {
if (!usingDefaultServices) {
err = new Error('Invalid module: ' + service);
err.name = 'InvalidModuleError';
throw err;
}
} else {
contents.push(lines);
}
}
if (!this.builtServices[service][version]) {
this.builtServices[service][version] = true;
lines = this.buildStrategy.getService(service, version);
if (lines === null) {
if (!usingDefaultServices) {
err = new Error('Invalid module: ' + service + '-' + version);
err.name = 'InvalidModuleError';
throw err;
}
} else {
contents.push(lines);
}
}
return contents.join('\n');
};
Builder.prototype.addServices = function(services) {
var usingDefaultServices = false;
if (!services) {
usingDefaultServices = true;
services = defaultServices;
}
if (services.match(sanitizeRegex)) {
throw new Error('Incorrectly formatted service names');
}
var invalidModules = [];
var stsIncluded = false;
services.split(',').sort().forEach(function(name) {
if (name.match(/^sts\b/) || name === 'all') stsIncluded = true;
try {
this.serviceCode.push(this.buildService(name, usingDefaultServices));
} catch (e) {
if (e.name === 'InvalidModuleError') invalidModules.push(name);
else throw e;
}
}.bind(this));
if (!stsIncluded) {
this.serviceCode.push(this.buildService('sts'));
}
if (invalidModules.length > 0) {
throw new Error('Missing modules: ' + invalidModules.join(', '));
}
return this;
};
Builder.prototype.build = function(callback) {
this.buildStrategy.getCore(function(err, core) {
callback(err, err ? null : (core + ';' + this.serviceCode.join('\n')));
}.bind(this));
};
// run if we called this tool directly
if (require.main === module) {
var options = {
minify: process.env.MINIFY ? true : false,
cache: process.env.CACHE ? true : false,
writeCache: process.env.WRITE_CACHE ? true : false,
cacheRoot: process.env.CACHE_ROOT,
libPath: process.env.LIB_PATH
};
var services = process.argv[2] || process.env.SERVICES;
new Builder(options).addServices(services).build(function (err, code) {
if (err) console.error(err.message);
else console.log(code);
});
}
module.exports = Builder;
var fs = require('fs');
function CacheStrategy(builder) {
this.builder = builder;
this.cacheRoot = this.builder.options.cacheRoot;
this.minify = this.builder.options.minify;
this.loadServices();
if (!this.builder.cacheExists()) {
fs.mkdirSync(this.builder.cachePath());
}
}
CacheStrategy.prototype.loadServices = function() {
this.services = {};
fs.readdirSync(this.cacheRoot).forEach(function(file) {
var match = file.match(/^([^_-]+)-(latest|\d+-\d+-\d+)\.(?:min\.)?js$/);
if (match) {
var service = match[1], version = match[2];
if (!this.services[service]) this.services[service] = {};
this.services[service][version] = service + '-' + version;
}
}.bind(this));
};
CacheStrategy.prototype.getServiceHeader = function(service) {
if (service === 'all') {
return Object.keys(this.services).map(function (name) {
return this.getServiceHeader(name);
}.bind(this)).join('\n');
}
if (this.services[service] && this.builder.cacheExists(service)) {
return this.read(service);
}
return null;
};
CacheStrategy.prototype.getService = function(service, version) {
if (service === 'all') {
return Object.keys(this.services).map(function (name) {
return this.getService(name);
}.bind(this)).join('\n');
}
var versions = this.services[service];
if (versions) {
var file = versions[version || 'latest'];
if (file && this.builder.cacheExists(file)) {
return this.read(file);
}
}
return null;
};
CacheStrategy.prototype.getCore = function(callback) {
if (this.builder.cacheExists('_core')) {
callback(null, this.read('_core'));
} else {
callback(new Error('Core not found.'));
}
};
CacheStrategy.prototype.read = function(path) {
return fs.readFileSync(this.builder.cachePath(path)).toString();
};
module.exports = CacheStrategy;
var fs = require('fs');
var util = require('util');
var path = require('path');
function DefaultStrategy(builder) {
this.builder = builder;
this.libPath = this.builder.options.libPath;
this.isCached = this.builder.options.writeCache;
this.isMinified = this.builder.options.minify;
this.minifyOptions = this.builder.options.minifyOptions || {};
this.minifyOptions.fromString = true;
this.AWS = require(this.libPath + '/lib/aws');
this.apis = require('aws-sdk-apis');
this.license = [
'// AWS SDK for JavaScript v' + this.AWS.VERSION,
'// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.',
'// License at https://sdk.amazonaws.com/js/BUNDLE_LICENSE.txt'
].join('\n') + '\n';
this.setServiceClasses();
if (this.isCached && !this.builder.cacheExists()) {
fs.mkdirSync(this.builder.cachePath());
}
}
DefaultStrategy.prototype.setServiceClasses = function() {
this.serviceClasses = {};
this.AWS.util.each.call(this, this.AWS, function(name, serviceClass) {
if (serviceClass.serviceIdentifier) {
this.serviceClasses[serviceClass.serviceIdentifier] = serviceClass;
}
});
};
DefaultStrategy.prototype.minify = function(code) {
var uglify = require('uglify-js');
var minified = uglify.minify(code, this.minifyOptions);
return minified.code;
};
DefaultStrategy.prototype.stripComments = function(code) {
var lines = code.split(/\r?\n/);
var multiLine = false;
lines = lines.map(function (line) {
var rLine = line;
if (line.match(/^\s*\/\//)) {
rLine = null;
} else if (line.match(/^\s*\/\*/)) {
multiLine = true;
rLine = null;
}
if (multiLine) {
var multiLineEnd = line.match(/\*\/(.*)/);
if (multiLineEnd) {
multiLine = false;
rLine = multiLineEnd[1];
} else {
rLine = null;
}
}
return rLine;
}).filter(function(l) { return l !== null; });
var newCode = lines.join('\n');
newCode = newCode.replace(/\/\*\*[\s\S]+?Copyright\s+.+?Amazon[\s\S]+?\*\//g, '');
return newCode;
};
DefaultStrategy.prototype.getServiceHeader = function(service) {
if (service === 'all') {
return Object.keys(this.serviceClasses).map(function(service) {
return this.getServiceHeader(service);
}.bind(this)).join('\n');
}
var file = util.format(
'AWS.%s = AWS.Service.defineService(\'%s\');\n',
this.apis.serviceName(service), service);
var svcPath = this.libPath + '/lib/services/' + service + '.js';
if (fs.existsSync(svcPath)) {
var lines = fs.readFileSync(svcPath).toString().split(/\r?\n/);
file += lines.map(function (line) {
line = line.replace(/^var\s*.*\s*=\s*require\s*\(.+\).*/, '');
line = line.replace(/^module.exports\s*=.*/, '');
return line;
}).join('\n');
}
if (this.isMinified) file = this.minify(file);
else file = this.stripComments(file);
if (this.isCached) {
fs.writeFileSync(this.builder.cachePath(service), file);
}
return file;
};
DefaultStrategy.prototype.getService = function(service, version) {
if (service === 'all') {
return Object.keys(this.serviceClasses).map(function(service) {
var out = this.serviceClasses[service].apiVersions.map(function(version) {
if (version.indexOf('*') >= 0) return null;
return this.getService(service, version);
}.bind(this)).filter(function(c) { return c !== null; }).join('\n');
if (this.isCached) {
// build 'latest', but don't add it to code (for caching)
this.getService(service, 'latest');
}
return out;
}.bind(this)).join('\n');
}
var svc, api;
if (!this.serviceClasses[service]) {
return null;
}
try {
var ClassName = this.serviceClasses[service];
svc = new ClassName({apiVersion: version});
api = this.apis.load(service, svc.api.apiVersion);
} catch (e) {
return null;
}
var line = util.format(
'AWS.Service.defineServiceApi(AWS.%s, "%s", %s);',
this.apis.serviceName(service), svc.api.apiVersion, JSON.stringify(api));
if (this.isCached) {
fs.writeFileSync(this.builder.cachePath(service + '-' + version), line);
}
return line;
};
DefaultStrategy.prototype.getCore = function(callback) {
var img = require('browserify/node_modules/insert-module-globals');
img.vars.process = function() { return '{browser:true}'; };
var browserify = require('browserify');
var opts = { basedir: this.libPath };
browserify(opts).add('./lib/browser').
ignore('domain').bundle(function (err, data) {
if (err) return callback(err);
var code = (data || '').toString();
if (this.isMinified) code = this.minify(code);
else code = this.stripComments(code);
code = this.license + code;
if (this.isCached) {
fs.writeFileSync(this.builder.cachePath('_core'), code);
}
callback(null, code);
}.bind(this));
};
module.exports = DefaultStrategy;
helpers = require('./helpers')
Builder = helpers.Builder
exec = require('child_process').exec
fs = require('fs')
expect = helpers.chai.expect
describe 'Builder', ->
describe 'addServices', ->
builder = null
code = null
beforeEach -> builder = new helpers.Builder
add = (services) ->
builder.addServices(services)
code = builder.serviceCode.join('\n')
assertServiceAdded = (klass, version) ->
version = version || new helpers.AWS[klass]().api.apiVersion;
expect(code).to.match(new RegExp('AWS\\.' + klass +
' = AWS\\.Service\\.defineService\\(\'' +
helpers.AWS[klass].serviceIdentifier + '\''))
expect(code).to.match(new RegExp(
'AWS\\.Service\\.defineServiceApi\\(AWS\\.' +
klass + ', "' + version + '",'))
assertBundleFailed = (services, errMsg) ->
expect(-> builder.addServices(services)).to.throw(errMsg)
it 'accepts comma delimited services by name', ->
add 's3,cloudwatch'
assertServiceAdded 'S3'
assertServiceAdded 'CloudWatch'
assertServiceAdded 'STS' # STS always added
it 'uses latest service version if version suffix is not supplied', ->
add 'rds'
assertServiceAdded 'RDS'
it 'accepts fully qualified service-version pair', ->
add 'rds-2013-09-09'
assertServiceAdded 'RDS', '2013-09-09'
it 'accepts "all" for all services', ->
add 'all'
Object.keys(builder.buildStrategy.serviceClasses).forEach (s) ->
name = builder.buildStrategy.apis.serviceName(s)
assertServiceAdded(name)
it 'throws an error if the service does not exist', ->
assertBundleFailed 'invalidmodule', 'Missing modules: invalidmodule'
it 'throws an error if the service version does not exist', ->
services = 's3-1999-01-01'
msg = 'Missing modules: s3-1999-01-01'
assertBundleFailed(services, msg)
it 'groups multiple errors into one error object', ->
services = 's3-1999-01-01,invalidmodule,dynamodb-01-01-01'
msg = 'Missing modules: dynamodb-01-01-01, invalidmodule, s3-1999-01-01'
assertBundleFailed(services, msg)
it 'throws an opaque error if special characters are found (/, ., *)', ->
msg = 'Incorrectly formatted service names'
assertBundleFailed('path/to/service', msg)
assertBundleFailed('to/../../../root', msg)
assertBundleFailed('*.js', msg)
assertBundleFailed('a.b', msg)
assertBundleFailed('a=b', msg)
assertBundleFailed('!d', msg)
assertBundleFailed('valid1,valid2,invalid.module', msg)
describe 'build', ->
bundleCache = {}
data = null
beforeEach -> data = ''
buildBundle = (services, opts, code, cb) ->
cacheKey = JSON.stringify(services: services, options: opts)
if bundleCache[cacheKey]
result = null
if code
result = helpers.evalCode(code, bundleCache[cacheKey])
return cb(null, result)
opts = opts || {}
new Builder(opts).addServices(services).build (err, d) ->
data = d
bundleCache[cacheKey] = data
result = null
if !err && code
result = helpers.evalCode(code, data)
cb(err, result)
it 'defaults to no minification', ->
buildBundle null, null, 'window.AWS', (err, AWS) ->
expect(data).to.match(/Copyright Amazon\.com/i)
it 'can be minified (slow)', ->
buildBundle null, minify: true, null, ->
expect(data).to.match(/Copyright Amazon\.com/i) # has license
expect(data).to.match(/function \w\(\w,\w,\w\)\{function \w\(\w,\w\)\{/)
it 'can build default services into bundle', ->
buildBundle null, null, 'window.AWS', (err, AWS) ->
expect(new AWS.S3().api.apiVersion).to.equal(new helpers.AWS.S3().api.apiVersion)
expect(new AWS.DynamoDB().api.apiVersion).to.equal(new helpers.AWS.DynamoDB().api.apiVersion)
expect(new AWS.STS().api.apiVersion).to.equal(new helpers.AWS.STS().api.apiVersion)
it 'can build all services into bundle', ->
buildBundle 'all', null, 'window.AWS', (err, AWS) ->
Object.keys(helpers.AWS).forEach (k) ->
if k.serviceIdentifier
expect(typeof AWS[k]).to.equal('object')
describe 'cached writer', ->
it 'writes core and services to disk', (done) ->
root = __dirname + '/tmpcache/'
builder = new Builder(writeCache: true, cacheRoot: root)
builder.addServices('s3').build ->
try
['s3.js', 's3-latest.js', '_core.js'].forEach (item) ->
expect(fs.existsSync(root + item)).to.equal(true, item + ' exists?')
finally
exec('rm -rf ' + root, done)
it 'writes minified core and services to disk', (done) ->
root = __dirname + '/tmpcache/'
builder = new Builder(writeCache: true, cacheRoot: root, minify: true)
builder.addServices('s3').build ->
try
['s3.min.js', 's3-latest.min.js', '_core.min.js'].forEach (item) ->
expect(fs.existsSync(root + item)).to.equal(true, item + ' exists?')
finally
exec('rm -rf ' + root, done)
describe 'cached loading', ->
root = __dirname + '/tmpcache/'
it 'sets up cache', (done) ->
builder = new Builder(writeCache: true, cacheRoot: root)
builder.addServices('s3').build(done)
it 'loads from cache', ->
builder = new Builder(cache: true, cacheRoot: root)
builder.addServices('all').build (err, code) ->
expect(code).to.contain('AWS.S3 = ')
it 'fails if cache item is missing', ->
builder = new Builder(cache: true, cacheRoot: root)
expect(-> builder.addServices('kinesis')).to.throw('Missing modules: kinesis')
it 'fails to load from core if core is missing', (done) ->
exec 'rm ' + root + '_core.js', ->
builder = new Builder(cache: true, cacheRoot: root)
builder.addServices('s3').build (err, data) ->
expect(err.message).to.equal('Core not found.')
expect(data).to.equal(null)
done()
it 'removes cache', (done) ->
exec('rm -rf ' + root, done)
describe 'as executable', ->
cwd = __dirname + '/../'
script = './browser-builder.js '
it 'uses first argument to get services list', (done) ->
exec script + 'iam-2010-05-08', cwd: cwd, maxBuffer: 999999999, (e, out) ->
expect(out).to.match(/Copyright Amazon\.com/i)
expect(out).to.contain('"2010-05-08"')
expect(out).not.to.contain('"2006-03-01"')
done()
it 'uses MINIFY environment variable to set minification mode', (done) ->
env = JSON.parse(JSON.stringify(process.env))
env.MINIFY = '1'
exec script, cwd: cwd, maxBuffer: 999999999, (e, out) ->
expect(out).to.match(/Copyright Amazon\.com/i)
expect(out).to.match(/function \w\(\w,\w,\w\)\{function \w\(\w,\w\)\{/)
expect(out).to.contain('"2006-03-01"')
done()
fs = require('fs')
evalCode = (code, preamble) ->
eval """
(function() {
var window = GLOBAL;
#{preamble};
return #{code};
})();
"""
module.exports =
AWS: require('../../lib/aws')
Builder: require('../browser-builder')
chai: require('chai')
evalCode: evalCode
The bundled package of the AWS SDK for JavaScript is available under the
Apache License, Version 2.0:
Copyright 2012-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"). You
may not use this file except in compliance with the License. A copy of
the License is located at
http://aws.amazon.com/apache2.0/
or in the "license" file accompanying this file. This file is
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.
This product bundles browserify, which is available under a
"3-clause BSD" license:
Copyright Joyent, Inc. and other Node contributors.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
This product bundles crypto-browserify, which is available under
the MIT license:
Copyright (c) 2013 Dominic Tarr
Permission is hereby granted, free of charge,
to any person obtaining a copy of this software and
associated documentation files (the "Software"), to
deal in the Software without restriction, including
without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom
the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
This product bundles MD5, SHA-1, and SHA-256 hashing algorithm components,
which are available under a BSD license:
Copyright (c) 1998 - 2009, Paul Johnston & Contributors
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 copyrightnotice,
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 author 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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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.
source 'https://rubygems.org'
gem 'rake'
group :documentation do
gem 'rdiscount'
gem 'nokogiri'
gem 'yard', '~> 0.0'
gem 'yard-sitemap', '~> 1.0'
gem 'yard-js', '~> 0.0'
gem 'parsejs', github: 'lsegal/parsejs'
end
group :release do
gem 'samus'
end
GIT
remote: git://github.com/lsegal/parsejs.git
revision: 7ba09b48fefc2db2970406938c34fb3d97ad4148
specs:
parsejs (0.0.1)
kpeg
yard
GEM
remote: https://rubygems.org/
specs:
kpeg (1.0.0)
mini_portile (0.5.2)
nokogiri (1.6.1)
mini_portile (~> 0.5.0)
rake (10.1.1)
rdiscount (2.1.7)
samus (1.2.3)
yard (0.8.7.3)
yard-js (0.1.1)
yard-sitemap (1.0.1)
PLATFORMS
ruby
DEPENDENCIES
nokogiri
parsejs!
rake
rdiscount
samus
yard (~> 0.0)
yard-js (~> 0.0)
yard-sitemap (~> 1.0)
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2012-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
AWS SDK for JavaScript
Copyright 2012-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
This product includes software developed at
Amazon Web Services, Inc. (http://aws.amazon.com/).
LOGLEVEL = ($DEBUG || ENV['DEBUG']) ? '' : '-s'
task :default => 'test:all'
# Vendor tasks
root = File.dirname(__FILE__)
Dir[File.join(root, 'vendor', '*', 'Rakefile')].each do |vendor_rakefile|
load vendor_rakefile
end
# Local tasks
Dir[File.join(root, 'tasks', '**', '*.rake')].each do |task_file|
load task_file
end

AWS SDK for JavaScript Version Build Status

The official AWS SDK for JavaScript, available for browsers and mobile devices, or Node.js backends

Release notes can be found at http://aws.amazon.com/releasenotes/SDK/JavaScript

If you are upgrading from 1.x to 2.0 of the SDK, please see the {file:UPGRADING.md} notes for information on how to migrate existing code to work with the new major version.

Installing

In the Browser

To use the SDK in the browser, simply add the following script tag to your HTML pages:

<script src="https://sdk.amazonaws.com/js/aws-sdk-2.0.0-rc.20.min.js"></script>

In Node.js

The preferred way to install the AWS SDK for Node.js is to use the npm package manager for Node.js. Simply type the following into a terminal window:

npm install aws-sdk

Usage and Getting Started

You can find a getting started guide at:

http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/

Supported Services

Note: Although all services are supported in the browser version of the SDK, not all of the services are available in the default hosted build (using the script tag provided above). A list of services in the hosted build are provided in the "Working With Services" section of the browser SDK guide, including instructions on how to build a custom version of the SDK with extra services.

The SDK currently supports the following services:

Service Name Class Name API Version
Amazon CloudFrontAWS.CloudFront2012-05-05
2013-11-11
Amazon CloudSearchAWS.CloudSearch2011-02-01
2013-01-01
Amazon CloudWatchAWS.CloudWatch2010-08-01
Amazon DynamoDBAWS.DynamoDB2011-12-05
2012-08-10
Amazon Elastic Compute CloudAWS.EC22014-05-01
Amazon Elastic MapReduceAWS.EMR2009-03-31
Amazon Elastic TranscoderAWS.ElasticTranscoder2012-09-25
Amazon ElastiCacheAWS.ElastiCache2014-03-24
Amazon GlacierAWS.Glacier2012-06-01
Amazon KinesisAWS.Kinesis2013-12-02
Amazon RedshiftAWS.Redshift2012-12-01
Amazon Relational Database ServiceAWS.RDS2013-01-10
2013-02-12
2013-09-09
Amazon Route 53AWS.Route532013-04-01
Amazon Simple Email ServiceAWS.SES2010-12-01
Amazon Simple Notification ServiceAWS.SNS2010-03-31
Amazon Simple Queue ServiceAWS.SQS2012-11-05
Amazon Simple Storage ServiceAWS.S32006-03-01
Amazon Simple Workflow ServiceAWS.SimpleWorkflow2012-01-25
Amazon SimpleDBAWS.SimpleDB2009-04-15
Auto ScalingAWS.AutoScaling2011-01-01
AWS CloudFormationAWS.CloudFormation2010-05-15
AWS CloudTrailAWS.CloudTrail2013-11-01
AWS Data PipelineAWS.DataPipeline2012-10-29
AWS Direct ConnectAWS.DirectConnect2012-10-25
AWS Elastic BeanstalkAWS.ElasticBeanstalk2010-12-01
AWS Identity and Access ManagementAWS.IAM2010-05-08
AWS Import/ExportAWS.ImportExport2010-06-01
AWS OpsWorksAWS.OpsWorks2013-02-18
AWS Security Token ServiceAWS.STS2011-06-15
AWS Storage GatewayAWS.StorageGateway2012-06-30
2013-06-30
AWS SupportAWS.Support2013-04-15
Elastic Load BalancingAWS.ELB2012-06-01

License

This SDK is distributed under the Apache License, Version 2.0, see LICENSE.txt and NOTICE.txt for more information.

@!title Upgrading Notes (1.x to 2.0)

Upgrading Notes (1.x to 2.0)

This document captures breaking changes from 1.x versions to the first stable 2.x (non-RC) release of the AWS SDK for JavaScript.

1. Automatic Conversion of Base64 and Timestamp Types on Input/Output

The SDK will now automatically encode and decode base64-encoded values, as well as timestamp values, on the user's behalf. This change affects any operation where Base64 or Timestamp values were sent by a request or returned in a response, i.e., AWS.DynamoDB and AWS.SQS, which allow for Base64 encoded values.

User code that previously did base64 conversion no longer requires this. Furthermore, values encoded as base64 are now returned as Buffer objects from server responses (and can also be passed as Buffer input). For example, the following 1.x SQS.sendMessage() parameters:

var params = {
  MessageBody: 'Some Message',
  MessageAttributes: {
    attrName: {
      DataType: 'Binary',
      BinaryValue: new Buffer('example text').toString('base64')
    }
  }
};

Can be rewritten as:

var params = {
  MessageBody: 'Some Message',
  MessageAttributes: {
    attrName: {
      DataType: 'Binary',
      BinaryValue: 'example text'
    }
  }
};

And the message will be read as:

sqs.receiveMessage(params, function(err, data) {
  // buf is <Buffer 65 78 61 6d 70 6c 65 20 74 65 78 74>
  var buf = data.Messages[0].MessageAttributes.attrName.BinaryValue;
  console.log(buf.toString()); // "example text"
});

2. Moved response.data.RequestId to response.requestId

The SDK now stores request IDs for all services in a consistent place on the response object, rather than inside the response.data property. This is to improve consistency across services that expose request IDs in different ways. Note that this is also a breaking change that renames the response.data.RequestId property to response.requestId (or this.requestId inside of a callback).

To migrate your code, change:

svc.operation(params, function (err, data) {
  console.log('Request ID:', data.RequestId);
});

To the following:

svc.operation(params, function () {
  console.log('Request ID:', this.requestId);
});

3. Exposed Wrapper Elements

If you use {AWS.ElastiCache}, {AWS.RDS}, or {AWS.Redshift}, you must now access the response through the top-level output property in the response for certain operations. This change corrects the SDK to behave according to documentation output, which was previously listing this wrapper element.

Example:

RDS.describeEngineDefaultParameters() used to return:

{ Parameters: [ ... ] }

This operation now returns:

{ EngineDefaults: { Parameters: [ ... ] } }

The full list of affected operations for each service are:

AWS.ElastiCache: authorizeCacheSecurityGroupIngress, createCacheCluster, createCacheParameterGroup, createCacheSecurityGroup, createCacheSubnetGroup, createReplicationGroup, deleteCacheCluster, deleteReplicationGroup, describeEngineDefaultParameters, modifyCacheCluster, modifyCacheSubnetGroup, modifyReplicationGroup, purchaseReservedCacheNodesOffering, rebootCacheCluster, revokeCacheSecurityGroupIngress

AWS.RDS: addSourceIdentifierToSubscription, authorizeDBSecurityGroupIngress, copyDBSnapshot, createDBInstance, createDBInstanceReadReplica, createDBParameterGroup, createDBSecurityGroup, createDBSnapshot, createDBSubnetGroup, createEventSubscription, createOptionGroup, deleteDBInstance, deleteDBSnapshot, deleteEventSubscription, describeEngineDefaultParameters, modifyDBInstance, modifyDBSubnetGroup, modifyEventSubscription, modifyOptionGroup, promoteReadReplica, purchaseReservedDBInstancesOffering, rebootDBInstance, removeSourceIdentifierFromSubscription, restoreDBInstanceFromDBSnapshot, restoreDBInstanceToPointInTime, revokeDBSecurityGroupIngress

AWS.Redshift: authorizeClusterSecurityGroupIngress, authorizeSnapshotAccess, copyClusterSnapshot, createCluster, createClusterParameterGroup, createClusterSecurityGroup, createClusterSnapshot, createClusterSubnetGroup, createEventSubscription, createHsmClientCertificate, createHsmConfiguration, deleteCluster, deleteClusterSnapshot, describeDefaultClusterParameters, disableSnapshotCopy, enableSnapshotCopy, modifyCluster, modifyClusterSubnetGroup, modifyEventSubscription, modifySnapshotCopyRetentionPeriod, purchaseReservedNodeOffering, rebootCluster, restoreFromClusterSnapshot, revokeClusterSecurityGroupIngress, revokeSnapshotAccess, rotateEncryptionKey

4. Dropped .Client Property

The .Client property has been removed from Service objects. If you are using the .Client property on a Service class, remove this property from your code.

Upgrading example:

The following 1.x code:

var sts = new AWS.STS.Client();

Should be changed to the following:

var sts = new AWS.STS();

Nodemailer

Nodemailer is an easy to use module to send e-mails with Node.JS (using SMTP or sendmail or Amazon SES) and is unicode friendly - You can use any characters you like ✔

Nodemailer is Windows friendly, you can install it with npm on Windows just like any other module, there are no compiled dependencies. Use it from Azure or from your Windows box hassle free.

Read about using Nodemailer from the Node Knockout blog

Build Status NPM version

Notes and information

Nodemailer supports

  • Unicode to use any characters
  • HTML content as well as plain text alternative
  • Attachments (including attachment streaming for sending larger files)
  • Embedded images in HTML
  • SSL/STARTTLS for secure e-mail delivery
  • Different transport methods - SMTP, sendmail, Amazon SES or directly to recipients MX server or even a custom method
  • SMTP Connection pool and connection reuse for rapid delivery
  • Preconfigured services for using SMTP with Gmail, Hotmail etc.
  • Use objects as header values for SendGrid SMTP API
  • XOAUTH2 authentication and token generation support - useful with Gmail
  • DKIM signing

Support Nodemailer development

Donate to author

If you want to support with Bitcoins, then my wallet address is 15Z8ADxhssKUiwP3jbbqJwA21744KMCfTM

Nodemailer PaaS support

Nodemailer has been tested successfully on the following PaaS platforms (using free/trial accounts):

Check out my other mail related modules

If you want to parse generated or received e-mail instead of sending it, check out MailParser.

If you only want to generate the raw e-mail stream, check out MailComposer.

If you only want to communicate with the SMTP (both as client and the server), check out simplesmtp.

Templates

To use Nodemailer with templates, please see documentation for these projects.

TL;DR Usage Example

This is a complete example to send an e-mail with plaintext and HTML body

var nodemailer = require("nodemailer");

// create reusable transport method (opens pool of SMTP connections)
var smtpTransport = nodemailer.createTransport("SMTP",{
    service: "Gmail",
    auth: {
        user: "gmail.user@gmail.com",
        pass: "userpass"
    }
});

// setup e-mail data with unicode symbols
var mailOptions = {
    from: "Fred Foo ✔ <foo@blurdybloop.com>", // sender address
    to: "bar@blurdybloop.com, baz@blurdybloop.com", // list of receivers
    subject: "Hello ✔", // Subject line
    text: "Hello world ✔", // plaintext body
    html: "<b>Hello world ✔</b>" // html body
}

// send mail with defined transport object
smtpTransport.sendMail(mailOptions, function(error, response){
    if(error){
        console.log(error);
    }else{
        console.log("Message sent: " + response.message);
    }

    // if you don't want to use this transport object anymore, uncomment following line
    //smtpTransport.close(); // shut down the connection pool, no more messages
});

Or if you want to go the really easy (but not the best) route, you can try to send e-mails directly to the recipients MX server without a relaying service:

var mail = require("nodemailer").mail;

mail({
    from: "Fred Foo ✔ <foo@blurdybloop.com>", // sender address
    to: "bar@blurdybloop.com, baz@blurdybloop.com", // list of receivers
    subject: "Hello ✔", // Subject line
    text: "Hello world ✔", // plaintext body
    html: "<b>Hello world ✔</b>" // html body
});

See also the examples folder for full featured examples

Installation

Install through NPM

npm install nodemailer

Usage

Include the module

var nodemailer = require("nodemailer");

An e-mail can be sent with sendMail(mailOptions[, callback]) command

transport.sendMail(mailOptions, callback);

Where

  • transport is a transport object created from the nodemailer.createTransport method
  • mailOptions defines the e-mail (set its subject, body text, receivers etc.), see E-mail Message Fields for details
  • callback is the callback function that will be run after the e-mail is sent or the sending failed (see Return callback for details)

Setting up a transport method

Before you can send any e-mails you need to set up a transport method. This can be done with nodemailer.createTransport(type, options) where type indicates the transport protocol and options defines how it is used.

var transport = nodemailer.createTransport("SMTP", {smtp_options});

The same transport object can and should be reused several times.

When the transport method is defined, it can be used to send e-mail with sendMail

var transport = nodemailer.createTransport("SMTP", {smtp_options});

transport.sendMail({
    from: "sender@tr.ee",
    to: "receiver@tr.ee"
    ...
});

Possible transport methods

type parameter can be one of the following:

  • SMTP for using SMTP
  • SES for using Amazon SES with AWS Identity and Access Management (IAM) roles
  • Sendmail for utilizing systems sendmail command
  • Pickup for storing the e-mail in a directory on your machine
  • Direct for sending e-mails directly to recipients MTA servers

If type is not set, "direct" will be used

If you want to use custom transport method, you need to provide the transport handler constructor as the type parameter. See Custom Transport Methods for details

Global transport options

In addition to any specific configuration for a selected transport type, a few global ones exist.

  • resolveHostname - if set to true, resolves the public hostname for the current machine (makes an external HTTP request to remoteAddress.net for resolving it). The value is used when generating Message-ID values (as the domain part) and when identifying itself to a SMTP server
  • xMailer - if the value is a string it replaces the default X-Mailer header value. If the value is false then X-Mailer is stripped from the header

Setting up SMTP

SMTP is different from the other transport mechanisms, as in its case a connection pool is created. All the connections try to stay alive as long as possible and are reusable to minimize the protocol overhead delay - for example setting up TLS for authenticating is relatively lengthy process (in CPU terms, not by human terms), you do not want to do it several times.

Possible SMTP options are the following:

  • service - an optional well known service identifier ("Gmail", "Hotmail" etc., see Well known Services for a list of supported services) to auto-configure host, port and secure connection settings
  • host - hostname of the SMTP server (defaults to "localhost", not needed with service)
  • port - port of the SMTP server (defaults to 25, not needed with service)
  • secureConnection - use SSL (default is false, not needed with service). If you're using port 587 then keep secureConnection false, since the connection is started in insecure plain text mode and only later upgraded with STARTTLS
  • name - the name of the client server (defaults to machine name)
  • auth - authentication object as {user:"...", pass:"..."} or {XOAuth2: {xoauth2_options}} or {XOAuthToken: "base64data"}
  • ignoreTLS - ignore server support for STARTTLS (defaults to false)
  • debug - output client and server messages to console
  • maxConnections - how many connections to keep in the pool (defaults to 5)
  • maxMessages - limit the count of messages to send through a single connection (no limit by default)
  • greetingTimeout (defaults to 10000) - Time to wait in ms until greeting message is received from the server
  • connectionTimeout (system default if not set) - Time to wait in ms until the socket is opened to the server
  • socketTimeout (defaults to 1 hour) - Time of inactivity until the connection is closed

Example:

var transport = nodemailer.createTransport("SMTP", {
    service: "Gmail",
    auth: {
        user: "gmail.user@gmail.com",
        pass: "userpass"
    }
});

or the same without service parameter

var transport = nodemailer.createTransport("SMTP", {
    host: "smtp.gmail.com", // hostname
    secureConnection: true, // use SSL
    port: 465, // port for secure SMTP
    auth: {
        user: "gmail.user@gmail.com",
        pass: "userpass"
    }
});

NB! if you want to close the pool (cancel all open connections) you can use transport.close()

var transport = nodemailer.createTransport("SMTP",{});
...
transport.close(); // close the pool

SMTP XOAUTH and token generation

XOAUTH2

nodemailer supports XOAUTH2 authentication protocol. To use this you need to obtain a Client ID and a Client Secret from Google API Console (Open "API Access" and create "Client ID for web applications") and then request a refresh token for an user. See Google OAuth 2.0 Offline Access for more information.

Once you have obtained the Client ID, Client Secret and a Refresh Token for an user, you can use these values to send mail on behalf of the user.

var transportOptions = {
    ...,
    auth: {
        XOAuth2: {
            user: "example.user@gmail.com",
            clientId: "8819981768.apps.googleusercontent.com",
            clientSecret: "{client_secret}",
            refreshToken: "1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI",
            accessToken: "vF9dft4qmTc2Nvb3RlckBhdHRhdmlzdGEuY29tCg==",
            timeout: 3600
        }
    }
}

accessToken and timeout values are both optional. If XOAUTH2 login fails a new access token is generated automatically and the login is retried.

XOAUTH

Older XOAUTH is also supported by nodemailer for SMTP. XOAUTH is based on OAuth protocol 1.0 and is considered deprecated.

To use this, include XOAuthToken option in auth instead of the regular user and pass.

var transportOptions = {
    ...,
    auth: {
        XOAuthToken: "R0VUIGh0dHBzOi8vbWFpbC5nb29...."
    }
}

nodemailer includes also built in XOAUTH token generator which can be used with nodemailer.createXOAuthGenerator(). The function is preconfigured for Gmail, so in this case only mandatory options are user, token and tokenSecret.

var XOAuthTokenGenerator = nodemailer.createXOAuthGenerator({
        user: "test.nodemailer@gmail.com",
        // requestUrl: "https://oauth.access.point",
        // consumerKey: "anonymous",
        // consumerSecret: "anonymous",
        token: "1/O_HgoO4h2uOUfpus0V--7mygICXrQQ0ZajB3ZH52KqM",
        tokenSecret: "_mUBkIwNPnfQBUIWrJrpXJ0c"
    });

One of user or requestUrl is mandatory. consumerKey and consumerSecret both default to "anonymous".

var transportOptions = {
    service: "Gmail",
    auth: {
        XOAuthToken: nodemailer.createXOAuthGenerator({
            user: "test.nodemailer@gmail.com",
            token: "1/O_HgoO4h2uOUfpus0V--7mygICXrQQ0ZajB3ZH52KqM",
            tokenSecret: "_mUBkIwNPnfQBUIWrJrpXJ0c"
        })
    }
}

Setting up SES

SES use the aws-sdk node module that wraps all the HTTP requests to SES servers. If running on an Amazon EC2 instance, it allows the use of IAM Roles instead of AWS credentials. If necessary, the AWS credentials can still be provided to the createTransport method or through environment variables ( AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY ).

The SES options were renamed in v0.7. The new names are compatible with the naming convention of the AWS SDK for javascript in nodeJS used in Nodemailer. Thus you can pass a configuration object compatible with the AWS SDK to the createTransport() function.

Possible SES options are the following:

  • accessKeyId - optional AWS access key.
  • secretAccessKey - optional AWS secret.
  • sessionToken - optional session token.
  • region - optional Specify the region to send the service request to. Default to us-east-1

Deprecated parameters. These are kept for backward compatibility reasons to support users of Nodemailer prior to v0.7. Any new development should use the new parameters above:

  • AWSAccessKeyID - optional AWS access key. The option accessKeyId should be used instead.
  • AWSSecretKey - optional AWS secret. The option secretAccessKey should be used instead.
  • ServiceUrl - optional API end point URL (defaults to "https://email.us-east-1.amazonaws.com"). The option region should be used instead.
  • AWSSecurityToken - optional security token. The option sessionToken should be used instead.

Example:

var transport = nodemailer.createTransport("SES", {
    AWSAccessKeyID: "AWSACCESSKEY",
    AWSSecretKey: "AWS/Secret/key"
});

As of v0.7, sendmail() return only messageId instead of message, response and messageID

Setting up Sendmail

Sendmail transport method streams the compiled message to the stdin of sendmail command.

Options object is optional, possible sendmail options are the following:

  • path - path to the sendmail command (defaults to "sendmail")
  • args - an array of extra command line options to pass to the sendmail command (ie. ["-f", "foo@blurdybloop.com"]).

Currently the command to be spawned is built up like this: the command is either using sendmail -i -f from_addr to_addr[] (by default) or sendmail -i list_of_args[] (if args property was given). -i is ensured to be present on either case.

In the default case (no args defined) From and To addresses are either taken from From,To, Cc and Bcc properties or from the envelope property if one is present.

Be wary when using the args property - no recipients are defined by default, you need to ensure these by yourself, for example by using the -t flag.

Example:

var transport = nodemailer.createTransport("sendmail");

or

var transport = nodemailer.createTransport("sendmail", {
    path: "/usr/local/bin/sendmail",
    args: ["-t", "-f", "foo@blurdybloop.com"]
});

Sendmail uses a Transform stream, which is available in NodeJS >= 0.10. For previous versions you can include readable-stream in your depencies, which provides a polyfill.

Setting up Pickup

When choosing Pickup all e-mails will be stored in a directory so that they can be picked up by your SMTP server.

Possible options are the following:

  • directory - The directory where applications save e-mail for later processing by the SMTP server (required)

Example:

var transport = nodemailer.createTransport("PICKUP", {
    directory: "C:\\inetpub\\mailroot\\Pickup"
});

or the shorthand version:

var transport = nodemailer.createTransport("PICKUP", "C:\\inetpub\\mailroot\\Pickup");

Setting up Direct transport

Direct transport is useful when you can not or want not to use a relaying service or the sendmail command.

To set it up, you do not need to provide anything, just run the following to create a transport object:

var transport = nodemailer.createTransport();

If you want to use debug logging, use the following form:

var transport = nodemailer.createTransport("direct", {debug: true});

There is also a shorthand method mail if you do not like to set up a transport object (see E-mail message fields for options for the mailOptions object).

var mail = require("nodemailer").mail;
mail(mailOptions);

Direct can be quite inefficient as it queues all e-mails to be sent into memory. Additionally, if a message is not yet sent and the process is closed, all data about queued messages are lost. Thus direct is only suitable for low throughput systems, like password remainders and such, where the message can be processed immediatelly.

Direct is able to handle sending errors, graylisting and such. If a message can not be sent, it is requeued and retried later.

To raise the odds of getting your emails into recipients inboxes, you should setup SPF records for your domain. Using DKIM wouldn't hurt either. Dynamic IP addresses are frequently treated as spam sources, so using static IPs is advised.

Setting up Stub transport

Stub transport is useful for testing, it compiles the message and returns it with the callback.

var transport = nodemailer.createTransport('stub', {error: false});

Set error to a string or an error object if you want the callback to always return an error for this transport. Otherwise the callback should always succeed.

var transport = nodemailer.createTransport("Stub"),
    mailOptions = {
        from: "sender@example.com",
        to: "receiver@example.com",
        text: "hello world!"
    };

transport.sendMail(mailOptions, function(error, response){
    console.log(response.message);
});

Or if you want to ensure the sending fails, use the error option.

var transport = nodemailer.createTransport("Stub", {error: "Sending failed"});

transport.sendMail({}, function(error, response){
    console.log(error.message); // Sending failed
});

Handling responses

Direct exposes an event emitter for receiving status updates. If the message includes several recipients, the message is not sent to everyone at once but is sharded in chunks based on the domain name of the addresses. For example if your message includes the following recipients: user1@example.com, user2@example.com and user3@blurdybloop.com, then 2 separate messages are sent out - one for user1@example.com and user2@example.com and one for user3@blurdybloop.com. This means that sending to different recipients may succeed or fail independently. All information about messages being delivered, failed or requeued is emitted by the status emitter statusHandler.

Direct exposes the following events:

  • 'sent' - message was sent successfully
  • 'failed' - message was failed permanently
  • 'requeue' - message failed but the error might not be permanent, so the message is requeued for later (once the message is retried an event is fired again).

All events get the same argument which is an object with the following properties:

  • domain - is the domain part of the e-mail addresses
  • response - is the last line form the SMTP transmission

Usage example

transport.sendMail(messageOptions, function(error, response){
    if(error){
        console.log(error);
        return;
    }

    // response.statusHandler only applies to 'direct' transport
    response.statusHandler.once("failed", function(data){
        console.log(
          "Permanently failed delivering message to %s with the following response: %s",
          data.domain, data.response);
    });

    response.statusHandler.once("requeue", function(data){
        console.log("Temporarily failed delivering message to %s", data.domain);
    });

    response.statusHandler.once("sent", function(data){
        console.log("Message was accepted by %s", data.domain);
    });
});

NB! If you want to provide instant feedback to the user, listen for the first 'sent', 'failed', or 'requeued' event only. The first event should arrive quickly but once the message gets requeued, the delay until the next event for this particular domain is fired is at least 15 minutes.

This example uses .once for listening to the events which is ok if you have just one recipient. For several recipients with different domains, the events get called several times and thus would need a more complex handling.

When would you use Direct transport?

  • When prototyping your application
  • If you do not have or do not want to use a relaying service account
  • When running under Windows as a Sendmail replacement (by default Sendmail is not available in Windows)

DKIM Signing

Nodemailer supports DKIM signing with very simple setup. Use this with caution though since the generated message needs to be buffered entirely before it can be signed. Not a big deal with small messages but might consume a lot of RAM when using larger attachments.

Set up the DKIM signing with useDKIM method for a transport object:

transport.useDKIM(dkimOptions)

Where dkimOptions includes necessary options for signing

  • domainName - the domainname that is being used for signing
  • keySelector - key selector. If you have set up a TXT record with DKIM public key at zzz._domainkey.blurdybloop.com then zzz is the selector
  • privateKey - DKIM private key that is used for signing as a string
  • headerFieldNames - optional colon separated list of header fields to sign, by default all fields suggested by RFC4871 #5.5 are used

All messages transmitted through this transport objects are from now on DKIM signed.

Currently if several header fields with the same name exists, only the last one (the one in the bottom) is signed.

Example:

var transport = nodemailer.createTransport("Sendmail");

transport.useDKIM({
    domainName: "kreata.ee",
    keySelector: "dkim",
    privateKey: fs.readFileSync("private_key.pem")
});

transport.sendMail(mailOptions);

See examples/example_dkim.js for a complete example.

Well known services for SMTP

If you want to use a well known service as the SMTP host, you do not need to enter the hostname or port number, just use the service parameter

Currently supported services are:

  • AOL
  • DynectEmail
  • Gmail
  • hot.ee
  • Hotmail
  • iCloud
  • mail.ee
  • Mail.Ru
  • Mailgun
  • Mailjet
  • Mandrill
  • Postmark
  • QQ
  • QQex (Tencent Business Email)
  • SendGrid
  • SendCloud
  • SES
  • Yahoo
  • yandex
  • Zoho

Predefined service data covers host, port and secure connection settings, any other parameters (ie. auth) need to be set separately. Service names are case insensitive, so using "gmail" instead of "Gmail" is totally fine.

Example:

var smtpTransport = nodemailer.createTransport("Gmail",{
    auth: {
        user: "gmail.user@gmail.com",
        pass: "userpass"
    }
});

or alternatively

var smtpTransport = nodemailer.createTransport("SMTP",{
    service: "Gmail", // sets automatically host, port and connection security settings
    auth: {
        user: "gmail.user@gmail.com",
        pass: "userpass"
    }
});

Actually, if you are authenticating with an e-mail address that has a domain name like @gmail.com or @yahoo.com etc., then you don't even need to provide the service name, it is detected automatically.

var smtpTransport = nodemailer.createTransport("SMTP",{
    auth: {
        user: "gmail.user@gmail.com", // service is detected from the username
        pass: "userpass"
    }
});

E-mail message fields

The following are the possible fields of an e-mail message:

  • from - The e-mail address of the sender. All e-mail addresses can be plain sender@server.com or formatted Sender Name <sender@server.com>
  • to - Comma separated list or an array of recipients e-mail addresses that will appear on the To: field
  • cc - Comma separated list or an array of recipients e-mail addresses that will appear on the Cc: field
  • bcc - Comma separated list or an array of recipients e-mail addresses that will appear on the Bcc: field
  • replyTo - An e-mail address that will appear on the Reply-To: field
  • inReplyTo - The message-id this message is replying
  • references - Message-id list
  • subject - The subject of the e-mail
  • text - The plaintext version of the message
  • html - The HTML version of the message
  • generateTextFromHTML - if set to true uses HTML to generate plain text body part from the HTML if the text is not defined
  • headers - An object of additional header fields {"X-Key-Name": "key value"} (NB! values are passed as is, you should do your own encoding to 7bit and folding if needed)
  • attachments - An array of attachment objects.
  • alternatives - An array of alternative text contents (in addition to text and html parts)
  • envelope - optional SMTP envelope, if auto generated envelope is not suitable
  • messageId - optional Message-Id value, random value will be generated if not set. Set to false to omit the Message-Id header
  • date - optional Date value, current UTC string will be used if not set
  • encoding - optional transfer encoding for the textual parts (defaults to "quoted-printable")
  • charset - optional output character set for the textual parts (defaults to "utf-8")
  • dsn - An object with methods success, failure and delay. If any of these are set to true, DSN will be used

All text fields (e-mail addresses, plaintext body, html body) use UTF-8 as the encoding. Attachments are streamed as binary.

Example:

var transport = nodemailer.createTransport("Sendmail");

var mailOptions = {
    from: "me@tr.ee",
    to: "me@tr.ee",
    subject: "Hello world!",
    text: "Plaintext body"
}

transport.sendMail(mailOptions);

SendGrid support

Nodemailer supports SendGrid SMTP API out of the box - you can use objects as header values and these are automatically JSONized (and mime encoded if needed).

var mailOptions = {
    ...,
    headers: {
        'X-SMTPAPI': {
            category : "newuser",
            sub:{
                "%name%": ["Žiguli Õllepruul"]
            }
        }
    },
    subject: "Hello, %name%"
}

This also applies to any other service that expects a JSON string as a header value for specified key.

Generate Text from HTML

If generateTextFromHTML option is set to true, then HTML contents of the mail is automatically converted to plaintext format when plaintext content is empty or missing.

For example

mailOptions = {
    ...,
    generateTextFromHTML: true,
    html: '<h1>Hello world</h1><p><b>How</b> are you?',
    // text: '' // no text part
}

is automatically converted in the backround by Nodemailer to:

mailOptions = {
    ...,
    // source html:
    html: '<h1>Hello world</h1><p><b>How</b> are you?',
    // automatically generated plaintext message:
    text: "Hello world\n"+
          "===========\n"+
          "\n"+
          "**How** are you?"
}

As you can see the output syntax for generateTextFromHTML looks similar to markdown, and that is exactly the case here - Nodemailer includes a simple HTML to markdown converter. But don't expect too much from it, it's not full featured or perfect, just some regexes here and there.

Attachment fields

Attachment object consists of the following properties:

  • fileName - filename to be reported as the name of the attached file, use of unicode is allowed (except when using Amazon SES which doesn't like it)
  • cid - optional content id for using inline images in HTML message source
  • contents - String or a Buffer contents for the attachment
  • filePath - path to a file or an URL if you want to stream the file instead of including it (better for larger attachments)
  • streamSource - Stream object for arbitrary binary streams if you want to stream the contents (needs to support pause/resume)
  • contentType - optional content type for the attachment, if not set will be derived from the fileName property
  • contentDisposition - optional content disposition type for the attachment, defaults to "attachment"

One of contents, filePath or streamSource must be specified, if none is present, the attachment will be discarded. Other fields are optional.

Attachments can be added as many as you want.

var mailOptions = {
    ...
    attachments: [
        {   // utf-8 string as an attachment
            fileName: "text1.txt",
            contents: "hello world!"
        },
        {   // binary buffer as an attachment
            fileName: "text2.txt",
            contents: new Buffer("hello world!","utf-8")
        },
        {   // file on disk as an attachment
            fileName: "text3.txt",
            filePath: "/path/to/file.txt" // stream this file
        },
        {   // fileName and content type is derived from filePath
            filePath: "/path/to/file.txt"
        },
        {   // stream as an attachment
            fileName: "text4.txt",
            streamSource: fs.createReadStream("file.txt")
        },
        {   // define custom content type for the attachment
            fileName: "text.bin",
            contents: "hello world!",
            contentType: "text/plain"
        },
        {   // use URL as an attachment
            fileName: "license.txt",
            filePath: "https://raw.github.com/andris9/Nodemailer/master/LICENSE"
        }
    ]
}

Alternative fields

In addition to text and HTML, any kind of data can be inserted as an alternative content of the main body - for example a word processing document with the same text as in the HTML field. It is the job of the e-mail client to select and show the best fitting alternative to the reader.

Attahcment object consists of the following properties:

  • contents - String or a Buffer contents for the attachment
  • contentType - optional content type for the attachment, if not set will be set to "application/octet-stream"
  • contentEncoding - optional value of how the data is encoded, defaults to "base64"

If contents is empty, the alternative will be discarded. Other fields are optional.

Usage example:

var mailOptions = {
    ...
    html: "<b>Hello world!</b>",
    alternatives: [
        {
            contentType: "text/x-web-markdown",
            contents: "**Hello world!**"
        }
    ]
}

If the receiving e-mail client can render messages in Markdown syntax as well, it could prefer to display this alternative as the main content of the message instead of the html part.

Alternatives can be added as many as you want.

Address Formatting

All the e-mail addresses can be plain e-mail address

foobar@blurdybloop.com

or with formatted name (includes unicode support)

"Ноде Майлер" <foobar@blurdybloop.com>

To, Cc and Bcc fields accept comma separated list of e-mails or an array of emails or an array of comma separated list of e-mails - use it as you like. Formatting can be mixed.

...,
to: 'foobar@blurdybloop.com, "Ноде Майлер" <bar@blurdybloop.com>, "Name, User" <baz@blurdybloop.com>',
cc: ['foobar@blurdybloop.com', '"Ноде Майлер" <bar@blurdybloop.com>, "Name, User" <baz@blurdybloop.com>']
...

You can even use unicode domain and user names, these are automatically converted to the supported form

"Unicode Domain" <info@müriaad-polüteism.info>

SMTP envelope

SMTP envelope is usually auto generated from from, to, cc and bcc fields but if for some reason you want to specify it yourself, you can do it with envelope property.

envelope is an object with the following params: from, to, cc and bcc just like with regular mail options. You can also use the regular address format, unicode domains etc.

mailOptions = {
    ...,
    from: "mailer@kreata.ee",
    to: "daemon@kreata.ee",
    envelope: {
        from: "Daemon <deamon@kreata.ee>",
        to: "mailer@kreata.ee, Mailer <mailer2@kreata.ee>"
    }
}

The envelope only applies when using SMTP or sendmail, setting envelope has no effect with SES.

Using Embedded Images

Attachments can be used as embedded images in the HTML body. To use this feature, you need to set additional property of the attachment - cid (unique identifier of the file) which is a reference to the attachment file. The same cid value must be used as the image URL in HTML (using cid: as the URL protocol, see example below).

NB! the cid value should be as unique as possible!

var mailOptions = {
    ...
    html: "Embedded image: <img src='cid:unique@kreata.ee' />",
    attachments: [{
        filename: "image.png",
        filePath: "/path/to/file",
        cid: "unique@kreata.ee" //same cid value as in the html img src
    }]
}

Automatic embedding images

If you want to convert images in the HTML to embedded images automatically, you can set mail option forceEmbeddedImages to true. In this case all images in the HTML that are either using an absolute URL (http://...) or absolute file path (/path/to/file) are replaced with embedded attachments.

For example when using this code

var mailOptions = {
    forceEmbeddedImages: true
    html: 'Embedded image: <img src="http://example.com/image.png">'
};

The image linked is fetched and added automatically as an attachment and the url in the HTML is replaced automatically with a proper cid: string.

Return callback

Return callback gets two parameters

  • error - an error object if the message failed
  • responseStatus - an object with some information about the status on success
    • responseStatus.messageId - message ID used with the message

Different transport methods may expose additional properties to the responseStatus object, eg. direct transport exposes statusHandler, see the docs for the particular transport type for more info.

Example:

nodemailer.sendMail(mailOptions, function(error, responseStatus){
    if(!error){
        console.log(responseStatus.message); // response from the server
        console.log(responseStatus.messageId); // Message-ID value used
    }
});

NB! Message-ID used might not be the same that reaches recipients inbox since some providers (like SES) may change the value.

Custom Transport Methods

If you want to use a custom transport method you need to define a constructor function with the following API

function MyCustomHandler(options){}
MyCustomHandler.prototype.sendMail = function(emailMessage, callback){};
MyCustomHandler.prototype.close = function(closeCallback){};

Where

  • options is the optional options object passed to createTransport
  • sendMail() is the function that is going to deliver the message
  • emailMessage is a paused MailComposer object. You should call emailMessage.streamMessage() once you have everything set up for streaming the message
  • callback is the function to run once the message has been sent or an error occurred. The response object should include messageId property (you can get the value from emailMessage._messageId)
  • close() is an optional method (no need to define it) to close the transport method
  • closeCallback is the function to run once the transport method is closed

Example usage

var nodemailer = require("nodemailer");
// Pipes all messages to stdout
function MyTransport(options){
    this.options = options;
}
MyTransport.prototype.sendMail = function(emailMessage, callback) {
    console.log("Envelope: ", emailMessage.getEnvelope());
    emailMessage.pipe(process.stdout);
    emailMessage.on("error", function(err){
        callback(err);
    });
    emailMessage.on("end", function(){
        callback(null, {
            messageId: emailMessage._messageId
        });
    });
    // everything set up, start streaming
    emailMessage.streamMessage();
};
// Use MyTransport as the transport method
var transport = nodemailer.createTransport(MyTransport, {
    name: "my.host" // hostname for generating Message-ID values
});
transport.sendMail({
    from: "sender@example.com",
    to: "receiver@example.com",
    subject: "hello",
    text: "world"
}, function(err, response){
    console.log(err || response);
});

Command line usage

NB! Command line usage was removed from v0.4

Tests

Run the tests with npm in Nodemailer's directory

npm test

There aren't currently many tests for Nodemailer but there are a lot of tests in the modules that are used to generate the raw e-mail body and to use the SMTP client connection.

Tweaking

Nodemailer in itself is actually more like a wrapper for my other modules mailcomposer for composing the raw message stream and simplesmtp for delivering it, by providing an unified API. If there's some problems with particular parts of the message composing/sending process you should look at the appropriate module.

License

Nodemailer is licensed under MIT license. Basically you can do whatever you want to with it.


The Nodemailer logo was designed by Sven Kristjansen.

Bitdeli Badge

This file has been truncated, but you can view the full file.
// AWS SDK for JavaScript v2.0.0-rc.20
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// License at https://sdk.amazonaws.com/js/BUNDLE_LICENSE.txt
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
},{}],2:[function(require,module,exports){
var base64 = require('base64-js')
var ieee754 = require('ieee754')
exports.Buffer = Buffer
exports.SlowBuffer = Buffer
exports.INSPECT_MAX_BYTES = 50
Buffer.poolSize = 8192
Buffer._useTypedArrays = (function () {
try {
var buf = new ArrayBuffer(0)
var arr = new Uint8Array(buf)
arr.foo = function () { return 42 }
return 42 === arr.foo() &&
typeof arr.subarray === 'function' // Chrome 9-10 lack `subarray`
} catch (e) {
return false
}
})()
function Buffer (subject, encoding, noZero) {
if (!(this instanceof Buffer))
return new Buffer(subject, encoding, noZero)
var type = typeof subject
if (encoding === 'base64' && type === 'string') {
subject = stringtrim(subject)
while (subject.length % 4 !== 0) {
subject = subject + '='
}
}
var length
if (type === 'number')
length = coerce(subject)
else if (type === 'string')
length = Buffer.byteLength(subject, encoding)
else if (type === 'object')
length = coerce(subject.length) // assume that object is array-like
else
throw new Error('First argument needs to be a number, array or string.')
var buf
if (Buffer._useTypedArrays) {
buf = Buffer._augment(new Uint8Array(length))
} else {
buf = this
buf.length = length
buf._isBuffer = true
}
var i
if (Buffer._useTypedArrays && typeof subject.byteLength === 'number') {
buf._set(subject)
} else if (isArrayish(subject)) {
for (i = 0; i < length; i++) {
if (Buffer.isBuffer(subject))
buf[i] = subject.readUInt8(i)
else
buf[i] = subject[i]
}
} else if (type === 'string') {
buf.write(subject, 0, encoding)
} else if (type === 'number' && !Buffer._useTypedArrays && !noZero) {
for (i = 0; i < length; i++) {
buf[i] = 0
}
}
return buf
}
Buffer.isEncoding = function (encoding) {
switch (String(encoding).toLowerCase()) {
case 'hex':
case 'utf8':
case 'utf-8':
case 'ascii':
case 'binary':
case 'base64':
case 'raw':
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return true
default:
return false
}
}
Buffer.isBuffer = function (b) {
return !!(b !== null && b !== undefined && b._isBuffer)
}
Buffer.byteLength = function (str, encoding) {
var ret
str = str + ''
switch (encoding || 'utf8') {
case 'hex':
ret = str.length / 2
break
case 'utf8':
case 'utf-8':
ret = utf8ToBytes(str).length
break
case 'ascii':
case 'binary':
case 'raw':
ret = str.length
break
case 'base64':
ret = base64ToBytes(str).length
break
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
ret = str.length * 2
break
default:
throw new Error('Unknown encoding')
}
return ret
}
Buffer.concat = function (list, totalLength) {
assert(isArray(list), 'Usage: Buffer.concat(list, [totalLength])\n' +
'list should be an Array.')
if (list.length === 0) {
return new Buffer(0)
} else if (list.length === 1) {
return list[0]
}
var i
if (typeof totalLength !== 'number') {
totalLength = 0
for (i = 0; i < list.length; i++) {
totalLength += list[i].length
}
}
var buf = new Buffer(totalLength)
var pos = 0
for (i = 0; i < list.length; i++) {
var item = list[i]
item.copy(buf, pos)
pos += item.length
}
return buf
}
function _hexWrite (buf, string, offset, length) {
offset = Number(offset) || 0
var remaining = buf.length - offset
if (!length) {
length = remaining
} else {
length = Number(length)
if (length > remaining) {
length = remaining
}
}
var strLen = string.length
assert(strLen % 2 === 0, 'Invalid hex string')
if (length > strLen / 2) {
length = strLen / 2
}
for (var i = 0; i < length; i++) {
var byte = parseInt(string.substr(i * 2, 2), 16)
assert(!isNaN(byte), 'Invalid hex string')
buf[offset + i] = byte
}
Buffer._charsWritten = i * 2
return i
}
function _utf8Write (buf, string, offset, length) {
var charsWritten = Buffer._charsWritten =
blitBuffer(utf8ToBytes(string), buf, offset, length)
return charsWritten
}
function _asciiWrite (buf, string, offset, length) {
var charsWritten = Buffer._charsWritten =
blitBuffer(asciiToBytes(string), buf, offset, length)
return charsWritten
}
function _binaryWrite (buf, string, offset, length) {
return _asciiWrite(buf, string, offset, length)
}
function _base64Write (buf, string, offset, length) {
var charsWritten = Buffer._charsWritten =
blitBuffer(base64ToBytes(string), buf, offset, length)
return charsWritten
}
function _utf16leWrite (buf, string, offset, length) {
var charsWritten = Buffer._charsWritten =
blitBuffer(utf16leToBytes(string), buf, offset, length)
return charsWritten
}
Buffer.prototype.write = function (string, offset, length, encoding) {
if (isFinite(offset)) {
if (!isFinite(length)) {
encoding = length
length = undefined
}
} else { // legacy
var swap = encoding
encoding = offset
offset = length
length = swap
}
offset = Number(offset) || 0
var remaining = this.length - offset
if (!length) {
length = remaining
} else {
length = Number(length)
if (length > remaining) {
length = remaining
}
}
encoding = String(encoding || 'utf8').toLowerCase()
var ret
switch (encoding) {
case 'hex':
ret = _hexWrite(this, string, offset, length)
break
case 'utf8':
case 'utf-8':
ret = _utf8Write(this, string, offset, length)
break
case 'ascii':
ret = _asciiWrite(this, string, offset, length)
break
case 'binary':
ret = _binaryWrite(this, string, offset, length)
break
case 'base64':
ret = _base64Write(this, string, offset, length)
break
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
ret = _utf16leWrite(this, string, offset, length)
break
default:
throw new Error('Unknown encoding')
}
return ret
}
Buffer.prototype.toString = function (encoding, start, end) {
var self = this
encoding = String(encoding || 'utf8').toLowerCase()
start = Number(start) || 0
end = (end !== undefined)
? Number(end)
: end = self.length
if (end === start)
return ''
var ret
switch (encoding) {
case 'hex':
ret = _hexSlice(self, start, end)
break
case 'utf8':
case 'utf-8':
ret = _utf8Slice(self, start, end)
break
case 'ascii':
ret = _asciiSlice(self, start, end)
break
case 'binary':
ret = _binarySlice(self, start, end)
break
case 'base64':
ret = _base64Slice(self, start, end)
break
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
ret = _utf16leSlice(self, start, end)
break
default:
throw new Error('Unknown encoding')
}
return ret
}
Buffer.prototype.toJSON = function () {
return {
type: 'Buffer',
data: Array.prototype.slice.call(this._arr || this, 0)
}
}
Buffer.prototype.copy = function (target, target_start, start, end) {
var source = this
if (!start) start = 0
if (!end && end !== 0) end = this.length
if (!target_start) target_start = 0
if (end === start) return
if (target.length === 0 || source.length === 0) return
assert(end >= start, 'sourceEnd < sourceStart')
assert(target_start >= 0 && target_start < target.length,
'targetStart out of bounds')
assert(start >= 0 && start < source.length, 'sourceStart out of bounds')
assert(end >= 0 && end <= source.length, 'sourceEnd out of bounds')
if (end > this.length)
end = this.length
if (target.length - target_start < end - start)
end = target.length - target_start + start
var len = end - start
if (len < 100 || !Buffer._useTypedArrays) {
for (var i = 0; i < len; i++)
target[i + target_start] = this[i + start]
} else {
target._set(this.subarray(start, start + len), target_start)
}
}
function _base64Slice (buf, start, end) {
if (start === 0 && end === buf.length) {
return base64.fromByteArray(buf)
} else {
return base64.fromByteArray(buf.slice(start, end))
}
}
function _utf8Slice (buf, start, end) {
var res = ''
var tmp = ''
end = Math.min(buf.length, end)
for (var i = start; i < end; i++) {
if (buf[i] <= 0x7F) {
res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i])
tmp = ''
} else {
tmp += '%' + buf[i].toString(16)
}
}
return res + decodeUtf8Char(tmp)
}
function _asciiSlice (buf, start, end) {
var ret = ''
end = Math.min(buf.length, end)
for (var i = start; i < end; i++)
ret += String.fromCharCode(buf[i])
return ret
}
function _binarySlice (buf, start, end) {
return _asciiSlice(buf, start, end)
}
function _hexSlice (buf, start, end) {
var len = buf.length
if (!start || start < 0) start = 0
if (!end || end < 0 || end > len) end = len
var out = ''
for (var i = start; i < end; i++) {
out += toHex(buf[i])
}
return out
}
function _utf16leSlice (buf, start, end) {
var bytes = buf.slice(start, end)
var res = ''
for (var i = 0; i < bytes.length; i += 2) {
res += String.fromCharCode(bytes[i] + bytes[i+1] * 256)
}
return res
}
Buffer.prototype.slice = function (start, end) {
var len = this.length
start = clamp(start, len, 0)
end = clamp(end, len, len)
if (Buffer._useTypedArrays) {
return Buffer._augment(this.subarray(start, end))
} else {
var sliceLen = end - start
var newBuf = new Buffer(sliceLen, undefined, true)
for (var i = 0; i < sliceLen; i++) {
newBuf[i] = this[i + start]
}
return newBuf
}
}
Buffer.prototype.get = function (offset) {
console.log('.get() is deprecated. Access using array indexes instead.')
return this.readUInt8(offset)
}
Buffer.prototype.set = function (v, offset) {
console.log('.set() is deprecated. Access using array indexes instead.')
return this.writeUInt8(v, offset)
}
Buffer.prototype.readUInt8 = function (offset, noAssert) {
if (!noAssert) {
assert(offset !== undefined && offset !== null, 'missing offset')
assert(offset < this.length, 'Trying to read beyond buffer length')
}
if (offset >= this.length)
return
return this[offset]
}
function _readUInt16 (buf, offset, littleEndian, noAssert) {
if (!noAssert) {
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
assert(offset !== undefined && offset !== null, 'missing offset')
assert(offset + 1 < buf.length, 'Trying to read beyond buffer length')
}
var len = buf.length
if (offset >= len)
return
var val
if (littleEndian) {
val = buf[offset]
if (offset + 1 < len)
val |= buf[offset + 1] << 8
} else {
val = buf[offset] << 8
if (offset + 1 < len)
val |= buf[offset + 1]
}
return val
}
Buffer.prototype.readUInt16LE = function (offset, noAssert) {
return _readUInt16(this, offset, true, noAssert)
}
Buffer.prototype.readUInt16BE = function (offset, noAssert) {
return _readUInt16(this, offset, false, noAssert)
}
function _readUInt32 (buf, offset, littleEndian, noAssert) {
if (!noAssert) {
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
assert(offset !== undefined && offset !== null, 'missing offset')
assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')
}
var len = buf.length
if (offset >= len)
return
var val
if (littleEndian) {
if (offset + 2 < len)
val = buf[offset + 2] << 16
if (offset + 1 < len)
val |= buf[offset + 1] << 8
val |= buf[offset]
if (offset + 3 < len)
val = val + (buf[offset + 3] << 24 >>> 0)
} else {
if (offset + 1 < len)
val = buf[offset + 1] << 16
if (offset + 2 < len)
val |= buf[offset + 2] << 8
if (offset + 3 < len)
val |= buf[offset + 3]
val = val + (buf[offset] << 24 >>> 0)
}
return val
}
Buffer.prototype.readUInt32LE = function (offset, noAssert) {
return _readUInt32(this, offset, true, noAssert)
}
Buffer.prototype.readUInt32BE = function (offset, noAssert) {
return _readUInt32(this, offset, false, noAssert)
}
Buffer.prototype.readInt8 = function (offset, noAssert) {
if (!noAssert) {
assert(offset !== undefined && offset !== null,
'missing offset')
assert(offset < this.length, 'Trying to read beyond buffer length')
}
if (offset >= this.length)
return
var neg = this[offset] & 0x80
if (neg)
return (0xff - this[offset] + 1) * -1
else
return this[offset]
}
function _readInt16 (buf, offset, littleEndian, noAssert) {
if (!noAssert) {
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
assert(offset !== undefined && offset !== null, 'missing offset')
assert(offset + 1 < buf.length, 'Trying to read beyond buffer length')
}
var len = buf.length
if (offset >= len)
return
var val = _readUInt16(buf, offset, littleEndian, true)
var neg = val & 0x8000
if (neg)
return (0xffff - val + 1) * -1
else
return val
}
Buffer.prototype.readInt16LE = function (offset, noAssert) {
return _readInt16(this, offset, true, noAssert)
}
Buffer.prototype.readInt16BE = function (offset, noAssert) {
return _readInt16(this, offset, false, noAssert)
}
function _readInt32 (buf, offset, littleEndian, noAssert) {
if (!noAssert) {
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
assert(offset !== undefined && offset !== null, 'missing offset')
assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')
}
var len = buf.length
if (offset >= len)
return
var val = _readUInt32(buf, offset, littleEndian, true)
var neg = val & 0x80000000
if (neg)
return (0xffffffff - val + 1) * -1
else
return val
}
Buffer.prototype.readInt32LE = function (offset, noAssert) {
return _readInt32(this, offset, true, noAssert)
}
Buffer.prototype.readInt32BE = function (offset, noAssert) {
return _readInt32(this, offset, false, noAssert)
}
function _readFloat (buf, offset, littleEndian, noAssert) {
if (!noAssert) {
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')
}
return ieee754.read(buf, offset, littleEndian, 23, 4)
}
Buffer.prototype.readFloatLE = function (offset, noAssert) {
return _readFloat(this, offset, true, noAssert)
}
Buffer.prototype.readFloatBE = function (offset, noAssert) {
return _readFloat(this, offset, false, noAssert)
}
function _readDouble (buf, offset, littleEndian, noAssert) {
if (!noAssert) {
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
assert(offset + 7 < buf.length, 'Trying to read beyond buffer length')
}
return ieee754.read(buf, offset, littleEndian, 52, 8)
}
Buffer.prototype.readDoubleLE = function (offset, noAssert) {
return _readDouble(this, offset, true, noAssert)
}
Buffer.prototype.readDoubleBE = function (offset, noAssert) {
return _readDouble(this, offset, false, noAssert)
}
Buffer.prototype.writeUInt8 = function (value, offset, noAssert) {
if (!noAssert) {
assert(value !== undefined && value !== null, 'missing value')
assert(offset !== undefined && offset !== null, 'missing offset')
assert(offset < this.length, 'trying to write beyond buffer length')
verifuint(value, 0xff)
}
if (offset >= this.length) return
this[offset] = value
}
function _writeUInt16 (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
assert(value !== undefined && value !== null, 'missing value')
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
assert(offset !== undefined && offset !== null, 'missing offset')
assert(offset + 1 < buf.length, 'trying to write beyond buffer length')
verifuint(value, 0xffff)
}
var len = buf.length
if (offset >= len)
return
for (var i = 0, j = Math.min(len - offset, 2); i < j; i++) {
buf[offset + i] =
(value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
(littleEndian ? i : 1 - i) * 8
}
}
Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) {
_writeUInt16(this, value, offset, true, noAssert)
}
Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) {
_writeUInt16(this, value, offset, false, noAssert)
}
function _writeUInt32 (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
assert(value !== undefined && value !== null, 'missing value')
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
assert(offset !== undefined && offset !== null, 'missing offset')
assert(offset + 3 < buf.length, 'trying to write beyond buffer length')
verifuint(value, 0xffffffff)
}
var len = buf.length
if (offset >= len)
return
for (var i = 0, j = Math.min(len - offset, 4); i < j; i++) {
buf[offset + i] =
(value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
}
}
Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) {
_writeUInt32(this, value, offset, true, noAssert)
}
Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) {
_writeUInt32(this, value, offset, false, noAssert)
}
Buffer.prototype.writeInt8 = function (value, offset, noAssert) {
if (!noAssert) {
assert(value !== undefined && value !== null, 'missing value')
assert(offset !== undefined && offset !== null, 'missing offset')
assert(offset < this.length, 'Trying to write beyond buffer length')
verifsint(value, 0x7f, -0x80)
}
if (offset >= this.length)
return
if (value >= 0)
this.writeUInt8(value, offset, noAssert)
else
this.writeUInt8(0xff + value + 1, offset, noAssert)
}
function _writeInt16 (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
assert(value !== undefined && value !== null, 'missing value')
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
assert(offset !== undefined && offset !== null, 'missing offset')
assert(offset + 1 < buf.length, 'Trying to write beyond buffer length')
verifsint(value, 0x7fff, -0x8000)
}
var len = buf.length
if (offset >= len)
return
if (value >= 0)
_writeUInt16(buf, value, offset, littleEndian, noAssert)
else
_writeUInt16(buf, 0xffff + value + 1, offset, littleEndian, noAssert)
}
Buffer.prototype.writeInt16LE = function (value, offset, noAssert) {
_writeInt16(this, value, offset, true, noAssert)
}
Buffer.prototype.writeInt16BE = function (value, offset, noAssert) {
_writeInt16(this, value, offset, false, noAssert)
}
function _writeInt32 (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
assert(value !== undefined && value !== null, 'missing value')
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
assert(offset !== undefined && offset !== null, 'missing offset')
assert(offset + 3 < buf.length, 'Trying to write beyond buffer length')
verifsint(value, 0x7fffffff, -0x80000000)
}
var len = buf.length
if (offset >= len)
return
if (value >= 0)
_writeUInt32(buf, value, offset, littleEndian, noAssert)
else
_writeUInt32(buf, 0xffffffff + value + 1, offset, littleEndian, noAssert)
}
Buffer.prototype.writeInt32LE = function (value, offset, noAssert) {
_writeInt32(this, value, offset, true, noAssert)
}
Buffer.prototype.writeInt32BE = function (value, offset, noAssert) {
_writeInt32(this, value, offset, false, noAssert)
}
function _writeFloat (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
assert(value !== undefined && value !== null, 'missing value')
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
assert(offset !== undefined && offset !== null, 'missing offset')
assert(offset + 3 < buf.length, 'Trying to write beyond buffer length')
verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38)
}
var len = buf.length
if (offset >= len)
return
ieee754.write(buf, value, offset, littleEndian, 23, 4)
}
Buffer.prototype.writeFloatLE = function (value, offset, noAssert) {
_writeFloat(this, value, offset, true, noAssert)
}
Buffer.prototype.writeFloatBE = function (value, offset, noAssert) {
_writeFloat(this, value, offset, false, noAssert)
}
function _writeDouble (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
assert(value !== undefined && value !== null, 'missing value')
assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
assert(offset !== undefined && offset !== null, 'missing offset')
assert(offset + 7 < buf.length,
'Trying to write beyond buffer length')
verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308)
}
var len = buf.length
if (offset >= len)
return
ieee754.write(buf, value, offset, littleEndian, 52, 8)
}
Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) {
_writeDouble(this, value, offset, true, noAssert)
}
Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) {
_writeDouble(this, value, offset, false, noAssert)
}
Buffer.prototype.fill = function (value, start, end) {
if (!value) value = 0
if (!start) start = 0
if (!end) end = this.length
if (typeof value === 'string') {
value = value.charCodeAt(0)
}
assert(typeof value === 'number' && !isNaN(value), 'value is not a number')
assert(end >= start, 'end < start')
if (end === start) return
if (this.length === 0) return
assert(start >= 0 && start < this.length, 'start out of bounds')
assert(end >= 0 && end <= this.length, 'end out of bounds')
for (var i = start; i < end; i++) {
this[i] = value
}
}
Buffer.prototype.inspect = function () {
var out = []
var len = this.length
for (var i = 0; i < len; i++) {
out[i] = toHex(this[i])
if (i === exports.INSPECT_MAX_BYTES) {
out[i + 1] = '...'
break
}
}
return '<Buffer ' + out.join(' ') + '>'
}
Buffer.prototype.toArrayBuffer = function () {
if (typeof Uint8Array !== 'undefined') {
if (Buffer._useTypedArrays) {
return (new Buffer(this)).buffer
} else {
var buf = new Uint8Array(this.length)
for (var i = 0, len = buf.length; i < len; i += 1)
buf[i] = this[i]
return buf.buffer
}
} else {
throw new Error('Buffer.toArrayBuffer not supported in this browser')
}
}
function stringtrim (str) {
if (str.trim) return str.trim()
return str.replace(/^\s+|\s+$/g, '')
}
var BP = Buffer.prototype
Buffer._augment = function (arr) {
arr._isBuffer = true
arr._get = arr.get
arr._set = arr.set
arr.get = BP.get
arr.set = BP.set
arr.write = BP.write
arr.toString = BP.toString
arr.toLocaleString = BP.toString
arr.toJSON = BP.toJSON
arr.copy = BP.copy
arr.slice = BP.slice
arr.readUInt8 = BP.readUInt8
arr.readUInt16LE = BP.readUInt16LE
arr.readUInt16BE = BP.readUInt16BE
arr.readUInt32LE = BP.readUInt32LE
arr.readUInt32BE = BP.readUInt32BE
arr.readInt8 = BP.readInt8
arr.readInt16LE = BP.readInt16LE
arr.readInt16BE = BP.readInt16BE
arr.readInt32LE = BP.readInt32LE
arr.readInt32BE = BP.readInt32BE
arr.readFloatLE = BP.readFloatLE
arr.readFloatBE = BP.readFloatBE
arr.readDoubleLE = BP.readDoubleLE
arr.readDoubleBE = BP.readDoubleBE
arr.writeUInt8 = BP.writeUInt8
arr.writeUInt16LE = BP.writeUInt16LE
arr.writeUInt16BE = BP.writeUInt16BE
arr.writeUInt32LE = BP.writeUInt32LE
arr.writeUInt32BE = BP.writeUInt32BE
arr.writeInt8 = BP.writeInt8
arr.writeInt16LE = BP.writeInt16LE
arr.writeInt16BE = BP.writeInt16BE
arr.writeInt32LE = BP.writeInt32LE
arr.writeInt32BE = BP.writeInt32BE
arr.writeFloatLE = BP.writeFloatLE
arr.writeFloatBE = BP.writeFloatBE
arr.writeDoubleLE = BP.writeDoubleLE
arr.writeDoubleBE = BP.writeDoubleBE
arr.fill = BP.fill
arr.inspect = BP.inspect
arr.toArrayBuffer = BP.toArrayBuffer
return arr
}
function clamp (index, len, defaultValue) {
if (typeof index !== 'number') return defaultValue
index = ~~index; // Coerce to integer.
if (index >= len) return len
if (index >= 0) return index
index += len
if (index >= 0) return index
return 0
}
function coerce (length) {
length = ~~Math.ceil(+length)
return length < 0 ? 0 : length
}
function isArray (subject) {
return (Array.isArray || function (subject) {
return Object.prototype.toString.call(subject) === '[object Array]'
})(subject)
}
function isArrayish (subject) {
return isArray(subject) || Buffer.isBuffer(subject) ||
subject && typeof subject === 'object' &&
typeof subject.length === 'number'
}
function toHex (n) {
if (n < 16) return '0' + n.toString(16)
return n.toString(16)
}
function utf8ToBytes (str) {
var byteArray = []
for (var i = 0; i < str.length; i++) {
var b = str.charCodeAt(i)
if (b <= 0x7F)
byteArray.push(str.charCodeAt(i))
else {
var start = i
if (b >= 0xD800 && b <= 0xDFFF) i++
var h = encodeURIComponent(str.slice(start, i+1)).substr(1).split('%')
for (var j = 0; j < h.length; j++)
byteArray.push(parseInt(h[j], 16))
}
}
return byteArray
}
function asciiToBytes (str) {
var byteArray = []
for (var i = 0; i < str.length; i++) {
byteArray.push(str.charCodeAt(i) & 0xFF)
}
return byteArray
}
function utf16leToBytes (str) {
var c, hi, lo
var byteArray = []
for (var i = 0; i < str.length; i++) {
c = str.charCodeAt(i)
hi = c >> 8
lo = c % 256
byteArray.push(lo)
byteArray.push(hi)
}
return byteArray
}
function base64ToBytes (str) {
return base64.toByteArray(str)
}
function blitBuffer (src, dst, offset, length) {
var pos
for (var i = 0; i < length; i++) {
if ((i + offset >= dst.length) || (i >= src.length))
break
dst[i + offset] = src[i]
}
return i
}
function decodeUtf8Char (str) {
try {
return decodeURIComponent(str)
} catch (err) {
return String.fromCharCode(0xFFFD) // UTF 8 invalid char
}
}
function verifuint (value, max) {
assert(typeof value === 'number', 'cannot write a non-number as a number')
assert(value >= 0, 'specified a negative value for writing an unsigned value')
assert(value <= max, 'value is larger than maximum value for type')
assert(Math.floor(value) === value, 'value has a fractional component')
}
function verifsint (value, max, min) {
assert(typeof value === 'number', 'cannot write a non-number as a number')
assert(value <= max, 'value larger than maximum allowed value')
assert(value >= min, 'value smaller than minimum allowed value')
assert(Math.floor(value) === value, 'value has a fractional component')
}
function verifIEEE754 (value, max, min) {
assert(typeof value === 'number', 'cannot write a non-number as a number')
assert(value <= max, 'value larger than maximum allowed value')
assert(value >= min, 'value smaller than minimum allowed value')
}
function assert (test, message) {
if (!test) throw new Error(message || 'Failed assertion')
}
},{"base64-js":3,"ieee754":4}],3:[function(require,module,exports){
var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
;(function (exports) {
'use strict';
var Arr = (typeof Uint8Array !== 'undefined')
? Uint8Array
: Array
var PLUS = '+'.charCodeAt(0)
var SLASH = '/'.charCodeAt(0)
var NUMBER = '0'.charCodeAt(0)
var LOWER = 'a'.charCodeAt(0)
var UPPER = 'A'.charCodeAt(0)
function decode (elt) {
var code = elt.charCodeAt(0)
if (code === PLUS)
return 62 // '+'
if (code === SLASH)
return 63 // '/'
if (code < NUMBER)
return -1 //no match
if (code < NUMBER + 10)
return code - NUMBER + 26 + 26
if (code < UPPER + 26)
return code - UPPER
if (code < LOWER + 26)
return code - LOWER + 26
}
function b64ToByteArray (b64) {
var i, j, l, tmp, placeHolders, arr
if (b64.length % 4 > 0) {
throw new Error('Invalid string. Length must be a multiple of 4')
}
var len = b64.length
placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
arr = new Arr(b64.length * 3 / 4 - placeHolders)
l = placeHolders > 0 ? b64.length - 4 : b64.length
var L = 0
function push (v) {
arr[L++] = v
}
for (i = 0, j = 0; i < l; i += 4, j += 3) {
tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
push((tmp & 0xFF0000) >> 16)
push((tmp & 0xFF00) >> 8)
push(tmp & 0xFF)
}
if (placeHolders === 2) {
tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
push(tmp & 0xFF)
} else if (placeHolders === 1) {
tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
push((tmp >> 8) & 0xFF)
push(tmp & 0xFF)
}
return arr
}
function uint8ToBase64 (uint8) {
var i,
extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
output = "",
temp, length
function encode (num) {
return lookup.charAt(num)
}
function tripletToBase64 (num) {
return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
}
for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
output += tripletToBase64(temp)
}
switch (extraBytes) {
case 1:
temp = uint8[uint8.length - 1]
output += encode(temp >> 2)
output += encode((temp << 4) & 0x3F)
output += '=='
break
case 2:
temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
output += encode(temp >> 10)
output += encode((temp >> 4) & 0x3F)
output += encode((temp << 2) & 0x3F)
output += '='
break
}
return output
}
exports.toByteArray = b64ToByteArray
exports.fromByteArray = uint8ToBase64
}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
},{}],4:[function(require,module,exports){
exports.read = function(buffer, offset, isLE, mLen, nBytes) {
var e, m,
eLen = nBytes * 8 - mLen - 1,
eMax = (1 << eLen) - 1,
eBias = eMax >> 1,
nBits = -7,
i = isLE ? (nBytes - 1) : 0,
d = isLE ? -1 : 1,
s = buffer[offset + i];
i += d;
e = s & ((1 << (-nBits)) - 1);
s >>= (-nBits);
nBits += eLen;
for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8);
m = e & ((1 << (-nBits)) - 1);
e >>= (-nBits);
nBits += mLen;
for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8);
if (e === 0) {
e = 1 - eBias;
} else if (e === eMax) {
return m ? NaN : ((s ? -1 : 1) * Infinity);
} else {
m = m + Math.pow(2, mLen);
e = e - eBias;
}
return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
};
exports.write = function(buffer, value, offset, isLE, mLen, nBytes) {
var e, m, c,
eLen = nBytes * 8 - mLen - 1,
eMax = (1 << eLen) - 1,
eBias = eMax >> 1,
rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
i = isLE ? 0 : (nBytes - 1),
d = isLE ? 1 : -1,
s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
value = Math.abs(value);
if (isNaN(value) || value === Infinity) {
m = isNaN(value) ? 1 : 0;
e = eMax;
} else {
e = Math.floor(Math.log(value) / Math.LN2);
if (value * (c = Math.pow(2, -e)) < 1) {
e--;
c *= 2;
}
if (e + eBias >= 1) {
value += rt / c;
} else {
value += rt * Math.pow(2, 1 - eBias);
}
if (value * c >= 2) {
e++;
c /= 2;
}
if (e + eBias >= eMax) {
m = 0;
e = eMax;
} else if (e + eBias >= 1) {
m = (value * c - 1) * Math.pow(2, mLen);
e = e + eBias;
} else {
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
e = 0;
}
}
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8);
e = (e << mLen) | m;
eLen += mLen;
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8);
buffer[offset + i - d] |= s * 128;
};
},{}],5:[function(require,module,exports){
var Buffer = require('buffer').Buffer;
var intSize = 4;
var zeroBuffer = new Buffer(intSize); zeroBuffer.fill(0);
var chrsz = 8;
function toArray(buf, bigEndian) {
if ((buf.length % intSize) !== 0) {
var len = buf.length + (intSize - (buf.length % intSize));
buf = Buffer.concat([buf, zeroBuffer], len);
}
var arr = [];
var fn = bigEndian ? buf.readInt32BE : buf.readInt32LE;
for (var i = 0; i < buf.length; i += intSize) {
arr.push(fn.call(buf, i));
}
return arr;
}
function toBuffer(arr, size, bigEndian) {
var buf = new Buffer(size);
var fn = bigEndian ? buf.writeInt32BE : buf.writeInt32LE;
for (var i = 0; i < arr.length; i++) {
fn.call(buf, arr[i], i * 4, true);
}
return buf;
}
function hash(buf, fn, hashSize, bigEndian) {
if (!Buffer.isBuffer(buf)) buf = new Buffer(buf);
var arr = fn(toArray(buf, bigEndian), buf.length * chrsz);
return toBuffer(arr, hashSize, bigEndian);
}
module.exports = { hash: hash };
},{"buffer":2}],6:[function(require,module,exports){
var Buffer = require('buffer').Buffer
var sha = require('./sha')
var sha256 = require('./sha256')
var rng = require('./rng')
var md5 = require('./md5')
var algorithms = {
sha1: sha,
sha256: sha256,
md5: md5
}
var blocksize = 64
var zeroBuffer = new Buffer(blocksize); zeroBuffer.fill(0)
function hmac(fn, key, data) {
if(!Buffer.isBuffer(key)) key = new Buffer(key)
if(!Buffer.isBuffer(data)) data = new Buffer(data)
if(key.length > blocksize) {
key = fn(key)
} else if(key.length < blocksize) {
key = Buffer.concat([key, zeroBuffer], blocksize)
}
var ipad = new Buffer(blocksize), opad = new Buffer(blocksize)
for(var i = 0; i < blocksize; i++) {
ipad[i] = key[i] ^ 0x36
opad[i] = key[i] ^ 0x5C
}
var hash = fn(Buffer.concat([ipad, data]))
return fn(Buffer.concat([opad, hash]))
}
function hash(alg, key) {
alg = alg || 'sha1'
var fn = algorithms[alg]
var bufs = []
var length = 0
if(!fn) error('algorithm:', alg, 'is not yet supported')
return {
update: function (data) {
if(!Buffer.isBuffer(data)) data = new Buffer(data)
bufs.push(data)
length += data.length
return this
},
digest: function (enc) {
var buf = Buffer.concat(bufs)
var r = key ? hmac(fn, key, buf) : fn(buf)
bufs = null
return enc ? r.toString(enc) : r
}
}
}
function error () {
var m = [].slice.call(arguments).join(' ')
throw new Error([
m,
'we accept pull requests',
'http://github.com/dominictarr/crypto-browserify'
].join('\n'))
}
exports.createHash = function (alg) { return hash(alg) }
exports.createHmac = function (alg, key) { return hash(alg, key) }
exports.randomBytes = function(size, callback) {
if (callback && callback.call) {
try {
callback.call(this, undefined, new Buffer(rng(size)))
} catch (err) { callback(err) }
} else {
return new Buffer(rng(size))
}
}
function each(a, f) {
for(var i in a)
f(a[i], i)
}
each(['createCredentials'
, 'createCipher'
, 'createCipheriv'
, 'createDecipher'
, 'createDecipheriv'
, 'createSign'
, 'createVerify'
, 'createDiffieHellman'
, 'pbkdf2'], function (name) {
exports[name] = function () {
error('sorry,', name, 'is not implemented yet')
}
})
},{"./md5":7,"./rng":8,"./sha":9,"./sha256":10,"buffer":2}],7:[function(require,module,exports){
var helpers = require('./helpers');
function md5_vm_test()
{
return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
}
function core_md5(x, len)
{
x[len >> 5] |= 0x80 << ((len) % 32);
x[(((len + 64) >>> 9) << 4) + 14] = len;
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
for(var i = 0; i < x.length; i += 16)
{
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
}
return Array(a, b, c, d);
}
function md5_cmn(q, a, b, x, s, t)
{
return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
}
function md5_ff(a, b, c, d, x, s, t)
{
return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function md5_gg(a, b, c, d, x, s, t)
{
return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function md5_hh(a, b, c, d, x, s, t)
{
return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5_ii(a, b, c, d, x, s, t)
{
return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}
function safe_add(x, y)
{
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
function bit_rol(num, cnt)
{
return (num << cnt) | (num >>> (32 - cnt));
}
module.exports = function md5(buf) {
return helpers.hash(buf, core_md5, 16);
};
},{"./helpers":5}],8:[function(require,module,exports){
(function() {
var _global = this;
var mathRNG, whatwgRNG;
mathRNG = function(size) {
var bytes = new Array(size);
var r;
for (var i = 0, r; i < size; i++) {
if ((i & 0x03) == 0) r = Math.random() * 0x100000000;
bytes[i] = r >>> ((i & 0x03) << 3) & 0xff;
}
return bytes;
}
if (_global.crypto && crypto.getRandomValues) {
whatwgRNG = function(size) {
var bytes = new Uint8Array(size);
crypto.getRandomValues(bytes);
return bytes;
}
}
module.exports = whatwgRNG || mathRNG;
}())
},{}],9:[function(require,module,exports){
var helpers = require('./helpers');
function core_sha1(x, len)
{
x[len >> 5] |= 0x80 << (24 - len % 32);
x[((len + 64 >> 9) << 4) + 15] = len;
var w = Array(80);
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
var e = -1009589776;
for(var i = 0; i < x.length; i += 16)
{
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
var olde = e;
for(var j = 0; j < 80; j++)
{
if(j < 16) w[j] = x[i + j];
else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
safe_add(safe_add(e, w[j]), sha1_kt(j)));
e = d;
d = c;
c = rol(b, 30);
b = a;
a = t;
}
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
e = safe_add(e, olde);
}
return Array(a, b, c, d, e);
}
function sha1_ft(t, b, c, d)
{
if(t < 20) return (b & c) | ((~b) & d);
if(t < 40) return b ^ c ^ d;
if(t < 60) return (b & c) | (b & d) | (c & d);
return b ^ c ^ d;
}
function sha1_kt(t)
{
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
(t < 60) ? -1894007588 : -899497514;
}
function safe_add(x, y)
{
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
function rol(num, cnt)
{
return (num << cnt) | (num >>> (32 - cnt));
}
module.exports = function sha1(buf) {
return helpers.hash(buf, core_sha1, 20, true);
};
},{"./helpers":5}],10:[function(require,module,exports){
var helpers = require('./helpers');
var safe_add = function(x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
};
var S = function(X, n) {
return (X >>> n) | (X << (32 - n));
};
var R = function(X, n) {
return (X >>> n);
};
var Ch = function(x, y, z) {
return ((x & y) ^ ((~x) & z));
};
var Maj = function(x, y, z) {
return ((x & y) ^ (x & z) ^ (y & z));
};
var Sigma0256 = function(x) {
return (S(x, 2) ^ S(x, 13) ^ S(x, 22));
};
var Sigma1256 = function(x) {
return (S(x, 6) ^ S(x, 11) ^ S(x, 25));
};
var Gamma0256 = function(x) {
return (S(x, 7) ^ S(x, 18) ^ R(x, 3));
};
var Gamma1256 = function(x) {
return (S(x, 17) ^ S(x, 19) ^ R(x, 10));
};
var core_sha256 = function(m, l) {
var K = new Array(0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC,0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85,0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819,0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08,0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F,0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208,0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2);
var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
var W = new Array(64);
var a, b, c, d, e, f, g, h, i, j;
var T1, T2;
m[l >> 5] |= 0x80 << (24 - l % 32);
m[((l + 64 >> 9) << 4) + 15] = l;
for (var i = 0; i < m.length; i += 16) {
a = HASH[0]; b = HASH[1]; c = HASH[2]; d = HASH[3]; e = HASH[4]; f = HASH[5]; g = HASH[6]; h = HASH[7];
for (var j = 0; j < 64; j++) {
if (j < 16) {
W[j] = m[j + i];
} else {
W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
}
T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
T2 = safe_add(Sigma0256(a), Maj(a, b, c));
h = g; g = f; f = e; e = safe_add(d, T1); d = c; c = b; b = a; a = safe_add(T1, T2);
}
HASH[0] = safe_add(a, HASH[0]); HASH[1] = safe_add(b, HASH[1]); HASH[2] = safe_add(c, HASH[2]); HASH[3] = safe_add(d, HASH[3]);
HASH[4] = safe_add(e, HASH[4]); HASH[5] = safe_add(f, HASH[5]); HASH[6] = safe_add(g, HASH[6]); HASH[7] = safe_add(h, HASH[7]);
}
return HASH;
};
module.exports = function sha256(buf) {
return helpers.hash(buf, core_sha256, 32, true);
};
},{"./helpers":5}],11:[function(require,module,exports){
function EventEmitter() {
this._events = this._events || {};
this._maxListeners = this._maxListeners || undefined;
}
module.exports = EventEmitter;
EventEmitter.EventEmitter = EventEmitter;
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._maxListeners = undefined;
EventEmitter.defaultMaxListeners = 10;
EventEmitter.prototype.setMaxListeners = function(n) {
if (!isNumber(n) || n < 0 || isNaN(n))
throw TypeError('n must be a positive number');
this._maxListeners = n;
return this;
};
EventEmitter.prototype.emit = function(type) {
var er, handler, len, args, i, listeners;
if (!this._events)
this._events = {};
if (type === 'error') {
if (!this._events.error ||
(isObject(this._events.error) && !this._events.error.length)) {
er = arguments[1];
if (er instanceof Error) {
throw er; // Unhandled 'error' event
} else {
throw TypeError('Uncaught, unspecified "error" event.');
}
return false;
}
}
handler = this._events[type];
if (isUndefined(handler))
return false;
if (isFunction(handler)) {
switch (arguments.length) {
case 1:
handler.call(this);
break;
case 2:
handler.call(this, arguments[1]);
break;
case 3:
handler.call(this, arguments[1], arguments[2]);
break;
default:
len = arguments.length;
args = new Array(len - 1);
for (i = 1; i < len; i++)
args[i - 1] = arguments[i];
handler.apply(this, args);
}
} else if (isObject(handler)) {
len = arguments.length;
args = new Array(len - 1);
for (i = 1; i < len; i++)
args[i - 1] = arguments[i];
listeners = handler.slice();
len = listeners.length;
for (i = 0; i < len; i++)
listeners[i].apply(this, args);
}
return true;
};
EventEmitter.prototype.addListener = function(type, listener) {
var m;
if (!isFunction(listener))
throw TypeError('listener must be a function');
if (!this._events)
this._events = {};
if (this._events.newListener)
this.emit('newListener', type,
isFunction(listener.listener) ?
listener.listener : listener);
if (!this._events[type])
this._events[type] = listener;
else if (isObject(this._events[type]))
this._events[type].push(listener);
else
this._events[type] = [this._events[type], listener];
if (isObject(this._events[type]) && !this._events[type].warned) {
var m;
if (!isUndefined(this._maxListeners)) {
m = this._maxListeners;
} else {
m = EventEmitter.defaultMaxListeners;
}
if (m && m > 0 && this._events[type].length > m) {
this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' +
'leak detected. %d listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.',
this._events[type].length);
if (typeof console.trace === 'function') {
console.trace();
}
}
}
return this;
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.once = function(type, listener) {
if (!isFunction(listener))
throw TypeError('listener must be a function');
var fired = false;
function g() {
this.removeListener(type, g);
if (!fired) {
fired = true;
listener.apply(this, arguments);
}
}
g.listener = listener;
this.on(type, g);
return this;
};
EventEmitter.prototype.removeListener = function(type, listener) {
var list, position, length, i;
if (!isFunction(listener))
throw TypeError('listener must be a function');
if (!this._events || !this._events[type])
return this;
list = this._events[type];
length = list.length;
position = -1;
if (list === listener ||
(isFunction(list.listener) && list.listener === listener)) {
delete this._events[type];
if (this._events.removeListener)
this.emit('removeListener', type, listener);
} else if (isObject(list)) {
for (i = length; i-- > 0;) {
if (list[i] === listener ||
(list[i].listener && list[i].listener === listener)) {
position = i;
break;
}
}
if (position < 0)
return this;
if (list.length === 1) {
list.length = 0;
delete this._events[type];
} else {
list.splice(position, 1);
}
if (this._events.removeListener)
this.emit('removeListener', type, listener);
}
return this;
};
EventEmitter.prototype.removeAllListeners = function(type) {
var key, listeners;
if (!this._events)
return this;
if (!this._events.removeListener) {
if (arguments.length === 0)
this._events = {};
else if (this._events[type])
delete this._events[type];
return this;
}
if (arguments.length === 0) {
for (key in this._events) {
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = {};
return this;
}
listeners = this._events[type];
if (isFunction(listeners)) {
this.removeListener(type, listeners);
} else {
while (listeners.length)
this.removeListener(type, listeners[listeners.length - 1]);
}
delete this._events[type];
return this;
};
EventEmitter.prototype.listeners = function(type) {
var ret;
if (!this._events || !this._events[type])
ret = [];
else if (isFunction(this._events[type]))
ret = [this._events[type]];
else
ret = this._events[type].slice();
return ret;
};
EventEmitter.listenerCount = function(emitter, type) {
var ret;
if (!emitter._events || !emitter._events[type])
ret = 0;
else if (isFunction(emitter._events[type]))
ret = 1;
else
ret = emitter._events[type].length;
return ret;
};
function isFunction(arg) {
return typeof arg === 'function';
}
function isNumber(arg) {
return typeof arg === 'number';
}
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
function isUndefined(arg) {
return arg === void 0;
}
},{}],12:[function(require,module,exports){
if (typeof Object.create === 'function') {
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};
} else {
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
var TempCtor = function () {}
TempCtor.prototype = superCtor.prototype
ctor.prototype = new TempCtor()
ctor.prototype.constructor = ctor
}
}
},{}],13:[function(require,module,exports){
var process = module.exports = {};
process.nextTick = (function () {
var canSetImmediate = typeof window !== 'undefined'
&& window.setImmediate;
var canPost = typeof window !== 'undefined'
&& window.postMessage && window.addEventListener
;
if (canSetImmediate) {
return function (f) { return window.setImmediate(f) };
}
if (canPost) {
var queue = [];
window.addEventListener('message', function (ev) {
var source = ev.source;
if ((source === window || source === null) && ev.data === 'process-tick') {
ev.stopPropagation();
if (queue.length > 0) {
var fn = queue.shift();
fn();
}
}
}, true);
return function nextTick(fn) {
queue.push(fn);
window.postMessage('process-tick', '*');
};
}
return function nextTick(fn) {
setTimeout(fn, 0);
};
})();
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.binding = function (name) {
throw new Error('process.binding is not supported');
}
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
},{}],14:[function(require,module,exports){
(function (global){
;(function(root) {
var freeExports = typeof exports == 'object' && exports;
var freeModule = typeof module == 'object' && module &&
module.exports == freeExports && module;
var freeGlobal = typeof global == 'object' && global;
if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
root = freeGlobal;
}
var punycode,
maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
base = 36,
tMin = 1,
tMax = 26,
skew = 38,
damp = 700,
initialBias = 72,
initialN = 128, // 0x80
delimiter = '-', // '\x2D'
regexPunycode = /^xn--/,
regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars
regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators
errors = {
'overflow': 'Overflow: input needs wider integers to process',
'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
'invalid-input': 'Invalid input'
},
baseMinusTMin = base - tMin,
floor = Math.floor,
stringFromCharCode = String.fromCharCode,
key;
function error(type) {
throw RangeError(errors[type]);
}
function map(array, fn) {
var length = array.length;
while (length--) {
array[length] = fn(array[length]);
}
return array;
}
function mapDomain(string, fn) {
return map(string.split(regexSeparators), fn).join('.');
}
function ucs2decode(string) {
var output = [],
counter = 0,
length = string.length,
value,
extra;
while (counter < length) {
value = string.charCodeAt(counter++);
if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
extra = string.charCodeAt(counter++);
if ((extra & 0xFC00) == 0xDC00) { // low surrogate
output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
} else {
output.push(value);
counter--;
}
} else {
output.push(value);
}
}
return output;
}
function ucs2encode(array) {
return map(array, function(value) {
var output = '';
if (value > 0xFFFF) {
value -= 0x10000;
output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
value = 0xDC00 | value & 0x3FF;
}
output += stringFromCharCode(value);
return output;
}).join('');
}
function basicToDigit(codePoint) {
if (codePoint - 48 < 10) {
return codePoint - 22;
}
if (codePoint - 65 < 26) {
return codePoint - 65;
}
if (codePoint - 97 < 26) {
return codePoint - 97;
}
return base;
}
function digitToBasic(digit, flag) {
return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
}
function adapt(delta, numPoints, firstTime) {
var k = 0;
delta = firstTime ? floor(delta / damp) : delta >> 1;
delta += floor(delta / numPoints);
for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
delta = floor(delta / baseMinusTMin);
}
return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
}
function decode(input) {
var output = [],
inputLength = input.length,
out,
i = 0,
n = initialN,
bias = initialBias,
basic,
j,
index,
oldi,
w,
k,
digit,
t,
baseMinusT;
basic = input.lastIndexOf(delimiter);
if (basic < 0) {
basic = 0;
}
for (j = 0; j < basic; ++j) {
if (input.charCodeAt(j) >= 0x80) {
error('not-basic');
}
output.push(input.charCodeAt(j));
}
for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
if (index >= inputLength) {
error('invalid-input');
}
digit = basicToDigit(input.charCodeAt(index++));
if (digit >= base || digit > floor((maxInt - i) / w)) {
error('overflow');
}
i += digit * w;
t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
if (digit < t) {
break;
}
baseMinusT = base - t;
if (w > floor(maxInt / baseMinusT)) {
error('overflow');
}
w *= baseMinusT;
}
out = output.length + 1;
bias = adapt(i - oldi, out, oldi == 0);
if (floor(i / out) > maxInt - n) {
error('overflow');
}
n += floor(i / out);
i %= out;
output.splice(i++, 0, n);
}
return ucs2encode(output);
}
function encode(input) {
var n,
delta,
handledCPCount,
basicLength,
bias,
j,
m,
q,
k,
t,
currentValue,
output = [],
inputLength,
handledCPCountPlusOne,
baseMinusT,
qMinusT;
input = ucs2decode(input);
inputLength = input.length;
n = initialN;
delta = 0;
bias = initialBias;
for (j = 0; j < inputLength; ++j) {
currentValue = input[j];
if (currentValue < 0x80) {
output.push(stringFromCharCode(currentValue));
}
}
handledCPCount = basicLength = output.length;
if (basicLength) {
output.push(delimiter);
}
while (handledCPCount < inputLength) {
for (m = maxInt, j = 0; j < inputLength; ++j) {
currentValue = input[j];
if (currentValue >= n && currentValue < m) {
m = currentValue;
}
}
handledCPCountPlusOne = handledCPCount + 1;
if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
error('overflow');
}
delta += (m - n) * handledCPCountPlusOne;
n = m;
for (j = 0; j < inputLength; ++j) {
currentValue = input[j];
if (currentValue < n && ++delta > maxInt) {
error('overflow');
}
if (currentValue == n) {
for (q = delta, k = base; /* no condition */; k += base) {
t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
if (q < t) {
break;
}
qMinusT = q - t;
baseMinusT = base - t;
output.push(
stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
);
q = floor(qMinusT / baseMinusT);
}
output.push(stringFromCharCode(digitToBasic(q, 0)));
bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
delta = 0;
++handledCPCount;
}
}
++delta;
++n;
}
return output.join('');
}
function toUnicode(domain) {
return mapDomain(domain, function(string) {
return regexPunycode.test(string)
? decode(string.slice(4).toLowerCase())
: string;
});
}
function toASCII(domain) {
return mapDomain(domain, function(string) {
return regexNonASCII.test(string)
? 'xn--' + encode(string)
: string;
});
}
punycode = {
'version': '1.2.4',
'ucs2': {
'decode': ucs2decode,
'encode': ucs2encode
},
'decode': decode,
'encode': encode,
'toASCII': toASCII,
'toUnicode': toUnicode
};
if (
typeof define == 'function' &&
typeof define.amd == 'object' &&
define.amd
) {
define('punycode', function() {
return punycode;
});
} else if (freeExports && !freeExports.nodeType) {
if (freeModule) { // in Node.js or RingoJS v0.8.0+
freeModule.exports = punycode;
} else { // in Narwhal or RingoJS v0.7.0-
for (key in punycode) {
punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
}
}
} else { // in Rhino or a web browser
root.punycode = punycode;
}
}(this));
}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],15:[function(require,module,exports){
'use strict';
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
module.exports = function(qs, sep, eq, options) {
sep = sep || '&';
eq = eq || '=';
var obj = {};
if (typeof qs !== 'string' || qs.length === 0) {
return obj;
}
var regexp = /\+/g;
qs = qs.split(sep);
var maxKeys = 1000;
if (options && typeof options.maxKeys === 'number') {
maxKeys = options.maxKeys;
}
var len = qs.length;
if (maxKeys > 0 && len > maxKeys) {
len = maxKeys;
}
for (var i = 0; i < len; ++i) {
var x = qs[i].replace(regexp, '%20'),
idx = x.indexOf(eq),
kstr, vstr, k, v;
if (idx >= 0) {
kstr = x.substr(0, idx);
vstr = x.substr(idx + 1);
} else {
kstr = x;
vstr = '';
}
k = decodeURIComponent(kstr);
v = decodeURIComponent(vstr);
if (!hasOwnProperty(obj, k)) {
obj[k] = v;
} else if (isArray(obj[k])) {
obj[k].push(v);
} else {
obj[k] = [obj[k], v];
}
}
return obj;
};
var isArray = Array.isArray || function (xs) {
return Object.prototype.toString.call(xs) === '[object Array]';
};
},{}],16:[function(require,module,exports){
'use strict';
var stringifyPrimitive = function(v) {
switch (typeof v) {
case 'string':
return v;
case 'boolean':
return v ? 'true' : 'false';
case 'number':
return isFinite(v) ? v : '';
default:
return '';
}
};
module.exports = function(obj, sep, eq, name) {
sep = sep || '&';
eq = eq || '=';
if (obj === null) {
obj = undefined;
}
if (typeof obj === 'object') {
return map(objectKeys(obj), function(k) {
var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
if (isArray(obj[k])) {
return obj[k].map(function(v) {
return ks + encodeURIComponent(stringifyPrimitive(v));
}).join(sep);
} else {
return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
}
}).join(sep);
}
if (!name) return '';
return encodeURIComponent(stringifyPrimitive(name)) + eq +
encodeURIComponent(stringifyPrimitive(obj));
};
var isArray = Array.isArray || function (xs) {
return Object.prototype.toString.call(xs) === '[object Array]';
};
function map (xs, f) {
if (xs.map) return xs.map(f);
var res = [];
for (var i = 0; i < xs.length; i++) {
res.push(f(xs[i], i));
}
return res;
}
var objectKeys = Object.keys || function (obj) {
var res = [];
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
}
return res;
};
},{}],17:[function(require,module,exports){
'use strict';
exports.decode = exports.parse = require('./decode');
exports.encode = exports.stringify = require('./encode');
},{"./decode":15,"./encode":16}],18:[function(require,module,exports){
var punycode = require('punycode');
exports.parse = urlParse;
exports.resolve = urlResolve;
exports.resolveObject = urlResolveObject;
exports.format = urlFormat;
exports.Url = Url;
function Url() {
this.protocol = null;
this.slashes = null;
this.auth = null;
this.host = null;
this.port = null;
this.hostname = null;
this.hash = null;
this.search = null;
this.query = null;
this.pathname = null;
this.path = null;
this.href = null;
}
var protocolPattern = /^([a-z0-9.+-]+:)/i,
portPattern = /:[0-9]*$/,
delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],
unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),
autoEscape = ['\''].concat(unwise),
nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
hostEndingChars = ['/', '?', '#'],
hostnameMaxLen = 255,
hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/,
hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/,
unsafeProtocol = {
'javascript': true,
'javascript:': true
},
hostlessProtocol = {
'javascript': true,
'javascript:': true
},
slashedProtocol = {
'http': true,
'https': true,
'ftp': true,
'gopher': true,
'file': true,
'http:': true,
'https:': true,
'ftp:': true,
'gopher:': true,
'file:': true
},
querystring = require('querystring');
function urlParse(url, parseQueryString, slashesDenoteHost) {
if (url && isObject(url) && url instanceof Url) return url;
var u = new Url;
u.parse(url, parseQueryString, slashesDenoteHost);
return u;
}
Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
if (!isString(url)) {
throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
}
var rest = url;
rest = rest.trim();
var proto = protocolPattern.exec(rest);
if (proto) {
proto = proto[0];
var lowerProto = proto.toLowerCase();
this.protocol = lowerProto;
rest = rest.substr(proto.length);
}
if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
var slashes = rest.substr(0, 2) === '//';
if (slashes && !(proto && hostlessProtocol[proto])) {
rest = rest.substr(2);
this.slashes = true;
}
}
if (!hostlessProtocol[proto] &&
(slashes || (proto && !slashedProtocol[proto]))) {
var hostEnd = -1;
for (var i = 0; i < hostEndingChars.length; i++) {
var hec = rest.indexOf(hostEndingChars[i]);
if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
hostEnd = hec;
}
var auth, atSign;
if (hostEnd === -1) {
atSign = rest.lastIndexOf('@');
} else {
atSign = rest.lastIndexOf('@', hostEnd);
}
if (atSign !== -1) {
auth = rest.slice(0, atSign);
rest = rest.slice(atSign + 1);
this.auth = decodeURIComponent(auth);
}
hostEnd = -1;
for (var i = 0; i < nonHostChars.length; i++) {
var hec = rest.indexOf(nonHostChars[i]);
if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
hostEnd = hec;
}
if (hostEnd === -1)
hostEnd = rest.length;
this.host = rest.slice(0, hostEnd);
rest = rest.slice(hostEnd);
this.parseHost();
this.hostname = this.hostname || '';
var ipv6Hostname = this.hostname[0] === '[' &&
this.hostname[this.hostname.length - 1] === ']';
if (!ipv6Hostname) {
var hostparts = this.hostname.split(/\./);
for (var i = 0, l = hostparts.length; i < l; i++) {
var part = hostparts[i];
if (!part) continue;
if (!part.match(hostnamePartPattern)) {
var newpart = '';
for (var j = 0, k = part.length; j < k; j++) {
if (part.charCodeAt(j) > 127) {
newpart += 'x';
} else {
newpart += part[j];
}
}
if (!newpart.match(hostnamePartPattern)) {
var validParts = hostparts.slice(0, i);
var notHost = hostparts.slice(i + 1);
var bit = part.match(hostnamePartStart);
if (bit) {
validParts.push(bit[1]);
notHost.unshift(bit[2]);
}
if (notHost.length) {
rest = '/' + notHost.join('.') + rest;
}
this.hostname = validParts.join('.');
break;
}
}
}
}
if (this.hostname.length > hostnameMaxLen) {
this.hostname = '';
} else {
this.hostname = this.hostname.toLowerCase();
}
if (!ipv6Hostname) {
var domainArray = this.hostname.split('.');
var newOut = [];
for (var i = 0; i < domainArray.length; ++i) {
var s = domainArray[i];
newOut.push(s.match(/[^A-Za-z0-9_-]/) ?
'xn--' + punycode.encode(s) : s);
}
this.hostname = newOut.join('.');
}
var p = this.port ? ':' + this.port : '';
var h = this.hostname || '';
this.host = h + p;
this.href += this.host;
if (ipv6Hostname) {
this.hostname = this.hostname.substr(1, this.hostname.length - 2);
if (rest[0] !== '/') {
rest = '/' + rest;
}
}
}
if (!unsafeProtocol[lowerProto]) {
for (var i = 0, l = autoEscape.length; i < l; i++) {
var ae = autoEscape[i];
var esc = encodeURIComponent(ae);
if (esc === ae) {
esc = escape(ae);
}
rest = rest.split(ae).join(esc);
}
}
var hash = rest.indexOf('#');
if (hash !== -1) {
this.hash = rest.substr(hash);
rest = rest.slice(0, hash);
}
var qm = rest.indexOf('?');
if (qm !== -1) {
this.search = rest.substr(qm);
this.query = rest.substr(qm + 1);
if (parseQueryString) {
this.query = querystring.parse(this.query);
}
rest = rest.slice(0, qm);
} else if (parseQueryString) {
this.search = '';
this.query = {};
}
if (rest) this.pathname = rest;
if (slashedProtocol[lowerProto] &&
this.hostname && !this.pathname) {
this.pathname = '/';
}
if (this.pathname || this.search) {
var p = this.pathname || '';
var s = this.search || '';
this.path = p + s;
}
this.href = this.format();
return this;
};
function urlFormat(obj) {
if (isString(obj)) obj = urlParse(obj);
if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
return obj.format();
}
Url.prototype.format = function() {
var auth = this.auth || '';
if (auth) {
auth = encodeURIComponent(auth);
auth = auth.replace(/%3A/i, ':');
auth += '@';
}
var protocol = this.protocol || '',
pathname = this.pathname || '',
hash = this.hash || '',
host = false,
query = '';
if (this.host) {
host = auth + this.host;
} else if (this.hostname) {
host = auth + (this.hostname.indexOf(':') === -1 ?
this.hostname :
'[' + this.hostname + ']');
if (this.port) {
host += ':' + this.port;
}
}
if (this.query &&
isObject(this.query) &&
Object.keys(this.query).length) {
query = querystring.stringify(this.query);
}
var search = this.search || (query && ('?' + query)) || '';
if (protocol && protocol.substr(-1) !== ':') protocol += ':';
if (this.slashes ||
(!protocol || slashedProtocol[protocol]) && host !== false) {
host = '//' + (host || '');
if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
} else if (!host) {
host = '';
}
if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
if (search && search.charAt(0) !== '?') search = '?' + search;
pathname = pathname.replace(/[?#]/g, function(match) {
return encodeURIComponent(match);
});
search = search.replace('#', '%23');
return protocol + host + pathname + search + hash;
};
function urlResolve(source, relative) {
return urlParse(source, false, true).resolve(relative);
}
Url.prototype.resolve = function(relative) {
return this.resolveObject(urlParse(relative, false, true)).format();
};
function urlResolveObject(source, relative) {
if (!source) return relative;
return urlParse(source, false, true).resolveObject(relative);
}
Url.prototype.resolveObject = function(relative) {
if (isString(relative)) {
var rel = new Url();
rel.parse(relative, false, true);
relative = rel;
}
var result = new Url();
Object.keys(this).forEach(function(k) {
result[k] = this[k];
}, this);
result.hash = relative.hash;
if (relative.href === '') {
result.href = result.format();
return result;
}
if (relative.slashes && !relative.protocol) {
Object.keys(relative).forEach(function(k) {
if (k !== 'protocol')
result[k] = relative[k];
});
if (slashedProtocol[result.protocol] &&
result.hostname && !result.pathname) {
result.path = result.pathname = '/';
}
result.href = result.format();
return result;
}
if (relative.protocol && relative.protocol !== result.protocol) {
if (!slashedProtocol[relative.protocol]) {
Object.keys(relative).forEach(function(k) {
result[k] = relative[k];
});
result.href = result.format();
return result;
}
result.protocol = relative.protocol;
if (!relative.host && !hostlessProtocol[relative.protocol]) {
var relPath = (relative.pathname || '').split('/');
while (relPath.length && !(relative.host = relPath.shift()));
if (!relative.host) relative.host = '';
if (!relative.hostname) relative.hostname = '';
if (relPath[0] !== '') relPath.unshift('');
if (relPath.length < 2) relPath.unshift('');
result.pathname = relPath.join('/');
} else {
result.pathname = relative.pathname;
}
result.search = relative.search;
result.query = relative.query;
result.host = relative.host || '';
result.auth = relative.auth;
result.hostname = relative.hostname || relative.host;
result.port = relative.port;
if (result.pathname || result.search) {
var p = result.pathname || '';
var s = result.search || '';
result.path = p + s;
}
result.slashes = result.slashes || relative.slashes;
result.href = result.format();
return result;
}
var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
isRelAbs = (
relative.host ||
relative.pathname && relative.pathname.charAt(0) === '/'
),
mustEndAbs = (isRelAbs || isSourceAbs ||
(result.host && relative.pathname)),
removeAllDots = mustEndAbs,
srcPath = result.pathname && result.pathname.split('/') || [],
relPath = relative.pathname && relative.pathname.split('/') || [],
psychotic = result.protocol && !slashedProtocol[result.protocol];
if (psychotic) {
result.hostname = '';
result.port = null;
if (result.host) {
if (srcPath[0] === '') srcPath[0] = result.host;
else srcPath.unshift(result.host);
}
result.host = '';
if (relative.protocol) {
relative.hostname = null;
relative.port = null;
if (relative.host) {
if (relPath[0] === '') relPath[0] = relative.host;
else relPath.unshift(relative.host);
}
relative.host = null;
}
mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
}
if (isRelAbs) {
result.host = (relative.host || relative.host === '') ?
relative.host : result.host;
result.hostname = (relative.hostname || relative.hostname === '') ?
relative.hostname : result.hostname;
result.search = relative.search;
result.query = relative.query;
srcPath = relPath;
} else if (relPath.length) {
if (!srcPath) srcPath = [];
srcPath.pop();
srcPath = srcPath.concat(relPath);
result.search = relative.search;
result.query = relative.query;
} else if (!isNullOrUndefined(relative.search)) {
if (psychotic) {
result.hostname = result.host = srcPath.shift();
var authInHost = result.host && result.host.indexOf('@') > 0 ?
result.host.split('@') : false;
if (authInHost) {
result.auth = authInHost.shift();
result.host = result.hostname = authInHost.shift();
}
}
result.search = relative.search;
result.query = relative.query;
if (!isNull(result.pathname) || !isNull(result.search)) {
result.path = (result.pathname ? result.pathname : '') +
(result.search ? result.search : '');
}
result.href = result.format();
return result;
}
if (!srcPath.length) {
result.pathname = null;
if (result.search) {
result.path = '/' + result.search;
} else {
result.path = null;
}
result.href = result.format();
return result;
}
var last = srcPath.slice(-1)[0];
var hasTrailingSlash = (
(result.host || relative.host) && (last === '.' || last === '..') ||
last === '');
var up = 0;
for (var i = srcPath.length; i >= 0; i--) {
last = srcPath[i];
if (last == '.') {
srcPath.splice(i, 1);
} else if (last === '..') {
srcPath.splice(i, 1);
up++;
} else if (up) {
srcPath.splice(i, 1);
up--;
}
}
if (!mustEndAbs && !removeAllDots) {
for (; up--; up) {
srcPath.unshift('..');
}
}
if (mustEndAbs && srcPath[0] !== '' &&
(!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
srcPath.unshift('');
}
if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
srcPath.push('');
}
var isAbsolute = srcPath[0] === '' ||
(srcPath[0] && srcPath[0].charAt(0) === '/');
if (psychotic) {
result.hostname = result.host = isAbsolute ? '' :
srcPath.length ? srcPath.shift() : '';
var authInHost = result.host && result.host.indexOf('@') > 0 ?
result.host.split('@') : false;
if (authInHost) {
result.auth = authInHost.shift();
result.host = result.hostname = authInHost.shift();
}
}
mustEndAbs = mustEndAbs || (result.host && srcPath.length);
if (mustEndAbs && !isAbsolute) {
srcPath.unshift('');
}
if (!srcPath.length) {
result.pathname = null;
result.path = null;
} else {
result.pathname = srcPath.join('/');
}
if (!isNull(result.pathname) || !isNull(result.search)) {
result.path = (result.pathname ? result.pathname : '') +
(result.search ? result.search : '');
}
result.auth = relative.auth || result.auth;
result.slashes = result.slashes || relative.slashes;
result.href = result.format();
return result;
};
Url.prototype.parseHost = function() {
var host = this.host;
var port = portPattern.exec(host);
if (port) {
port = port[0];
if (port !== ':') {
this.port = port.substr(1);
}
host = host.substr(0, host.length - port.length);
}
if (host) this.hostname = host;
};
function isString(arg) {
return typeof arg === "string";
}
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
function isNull(arg) {
return arg === null;
}
function isNullOrUndefined(arg) {
return arg == null;
}
},{"punycode":14,"querystring":17}],19:[function(require,module,exports){
module.exports = function isBuffer(arg) {
return arg && typeof arg === 'object'
&& typeof arg.copy === 'function'
&& typeof arg.fill === 'function'
&& typeof arg.readUInt8 === 'function';
}
},{}],20:[function(require,module,exports){
(function (process,global){
var formatRegExp = /%[sdj%]/g;
exports.format = function(f) {
if (!isString(f)) {
var objects = [];
for (var i = 0; i < arguments.length; i++) {
objects.push(inspect(arguments[i]));
}
return objects.join(' ');
}
var i = 1;
var args = arguments;
var len = args.length;
var str = String(f).replace(formatRegExp, function(x) {
if (x === '%') return '%';
if (i >= len) return x;
switch (x) {
case '%s': return String(args[i++]);
case '%d': return Number(args[i++]);
case '%j':
try {
return JSON.stringify(args[i++]);
} catch (_) {
return '[Circular]';
}
default:
return x;
}
});
for (var x = args[i]; i < len; x = args[++i]) {
if (isNull(x) || !isObject(x)) {
str += ' ' + x;
} else {
str += ' ' + inspect(x);
}
}
return str;
};
exports.deprecate = function(fn, msg) {
if (isUndefined(global.process)) {
return function() {
return exports.deprecate(fn, msg).apply(this, arguments);
};
}
if (process.noDeprecation === true) {
return fn;
}
var warned = false;
function deprecated() {
if (!warned) {
if (process.throwDeprecation) {
throw new Error(msg);
} else if (process.traceDeprecation) {
console.trace(msg);
} else {
console.error(msg);
}
warned = true;
}
return fn.apply(this, arguments);
}
return deprecated;
};
var debugs = {};
var debugEnviron;
exports.debuglog = function(set) {
if (isUndefined(debugEnviron))
debugEnviron = process.env.NODE_DEBUG || '';
set = set.toUpperCase();
if (!debugs[set]) {
if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
var pid = process.pid;
debugs[set] = function() {
var msg = exports.format.apply(exports, arguments);
console.error('%s %d: %s', set, pid, msg);
};
} else {
debugs[set] = function() {};
}
}
return debugs[set];
};
function inspect(obj, opts) {
var ctx = {
seen: [],
stylize: stylizeNoColor
};
if (arguments.length >= 3) ctx.depth = arguments[2];
if (arguments.length >= 4) ctx.colors = arguments[3];
if (isBoolean(opts)) {
ctx.showHidden = opts;
} else if (opts) {
exports._extend(ctx, opts);
}
if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
if (isUndefined(ctx.depth)) ctx.depth = 2;
if (isUndefined(ctx.colors)) ctx.colors = false;
if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
if (ctx.colors) ctx.stylize = stylizeWithColor;
return formatValue(ctx, obj, ctx.depth);
}
exports.inspect = inspect;
inspect.colors = {
'bold' : [1, 22],
'italic' : [3, 23],
'underline' : [4, 24],
'inverse' : [7, 27],
'white' : [37, 39],
'grey' : [90, 39],
'black' : [30, 39],
'blue' : [34, 39],
'cyan' : [36, 39],
'green' : [32, 39],
'magenta' : [35, 39],
'red' : [31, 39],
'yellow' : [33, 39]
};
inspect.styles = {
'special': 'cyan',
'number': 'yellow',
'boolean': 'yellow',
'undefined': 'grey',
'null': 'bold',
'string': 'green',
'date': 'magenta',
'regexp': 'red'
};
function stylizeWithColor(str, styleType) {
var style = inspect.styles[styleType];
if (style) {
return '\u001b[' + inspect.colors[style][0] + 'm' + str +
'\u001b[' + inspect.colors[style][1] + 'm';
} else {
return str;
}
}
function stylizeNoColor(str, styleType) {
return str;
}
function arrayToHash(array) {
var hash = {};
array.forEach(function(val, idx) {
hash[val] = true;
});
return hash;
}
function formatValue(ctx, value, recurseTimes) {
if (ctx.customInspect &&
value &&
isFunction(value.inspect) &&
value.inspect !== exports.inspect &&
!(value.constructor && value.constructor.prototype === value)) {
var ret = value.inspect(recurseTimes, ctx);
if (!isString(ret)) {
ret = formatValue(ctx, ret, recurseTimes);
}
return ret;
}
var primitive = formatPrimitive(ctx, value);
if (primitive) {
return primitive;
}
var keys = Object.keys(value);
var visibleKeys = arrayToHash(keys);
if (ctx.showHidden) {
keys = Object.getOwnPropertyNames(value);
}
if (isError(value)
&& (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
return formatError(value);
}
if (keys.length === 0) {
if (isFunction(value)) {
var name = value.name ? ': ' + value.name : '';
return ctx.stylize('[Function' + name + ']', 'special');
}
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
}
if (isDate(value)) {
return ctx.stylize(Date.prototype.toString.call(value), 'date');
}
if (isError(value)) {
return formatError(value);
}
}
var base = '', array = false, braces = ['{', '}'];
if (isArray(value)) {
array = true;
braces = ['[', ']'];
}
if (isFunction(value)) {
var n = value.name ? ': ' + value.name : '';
base = ' [Function' + n + ']';
}
if (isRegExp(value)) {
base = ' ' + RegExp.prototype.toString.call(value);
}
if (isDate(value)) {
base = ' ' + Date.prototype.toUTCString.call(value);
}
if (isError(value)) {
base = ' ' + formatError(value);
}
if (keys.length === 0 && (!array || value.length == 0)) {
return braces[0] + base + braces[1];
}
if (recurseTimes < 0) {
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
} else {
return ctx.stylize('[Object]', 'special');
}
}
ctx.seen.push(value);
var output;
if (array) {
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
} else {
output = keys.map(function(key) {
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
});
}
ctx.seen.pop();
return reduceToSingleString(output, base, braces);
}
function formatPrimitive(ctx, value) {
if (isUndefined(value))
return ctx.stylize('undefined', 'undefined');
if (isString(value)) {
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
.replace(/'/g, "\\'")
.replace(/\\"/g, '"') + '\'';
return ctx.stylize(simple, 'string');
}
if (isNumber(value))
return ctx.stylize('' + value, 'number');
if (isBoolean(value))
return ctx.stylize('' + value, 'boolean');
if (isNull(value))
return ctx.stylize('null', 'null');
}
function formatError(value) {
return '[' + Error.prototype.toString.call(value) + ']';
}
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
var output = [];
for (var i = 0, l = value.length; i < l; ++i) {
if (hasOwnProperty(value, String(i))) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
String(i), true));
} else {
output.push('');
}
}
keys.forEach(function(key) {
if (!key.match(/^\d+$/)) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
key, true));
}
});
return output;
}
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
var name, str, desc;
desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
if (desc.get) {
if (desc.set) {
str = ctx.stylize('[Getter/Setter]', 'special');
} else {
str = ctx.stylize('[Getter]', 'special');
}
} else {
if (desc.set) {
str = ctx.stylize('[Setter]', 'special');
}
}
if (!hasOwnProperty(visibleKeys, key)) {
name = '[' + key + ']';
}
if (!str) {
if (ctx.seen.indexOf(desc.value) < 0) {
if (isNull(recurseTimes)) {
str = formatValue(ctx, desc.value, null);
} else {
str = formatValue(ctx, desc.value, recurseTimes - 1);
}
if (str.indexOf('\n') > -1) {
if (array) {
str = str.split('\n').map(function(line) {
return ' ' + line;
}).join('\n').substr(2);
} else {
str = '\n' + str.split('\n').map(function(line) {
return ' ' + line;
}).join('\n');
}
}
} else {
str = ctx.stylize('[Circular]', 'special');
}
}
if (isUndefined(name)) {
if (array && key.match(/^\d+$/)) {
return str;
}
name = JSON.stringify('' + key);
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
name = name.substr(1, name.length - 2);
name = ctx.stylize(name, 'name');
} else {
name = name.replace(/'/g, "\\'")
.replace(/\\"/g, '"')
.replace(/(^"|"$)/g, "'");
name = ctx.stylize(name, 'string');
}
}
return name + ': ' + str;
}
function reduceToSingleString(output, base, braces) {
var numLinesEst = 0;
var length = output.reduce(function(prev, cur) {
numLinesEst++;
if (cur.indexOf('\n') >= 0) numLinesEst++;
return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
}, 0);
if (length > 60) {
return braces[0] +
(base === '' ? '' : base + '\n ') +
' ' +
output.join(',\n ') +
' ' +
braces[1];
}
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
}
function isArray(ar) {
return Array.isArray(ar);
}
exports.isArray = isArray;
function isBoolean(arg) {
return typeof arg === 'boolean';
}
exports.isBoolean = isBoolean;
function isNull(arg) {
return arg === null;
}
exports.isNull = isNull;
function isNullOrUndefined(arg) {
return arg == null;
}
exports.isNullOrUndefined = isNullOrUndefined;
function isNumber(arg) {
return typeof arg === 'number';
}
exports.isNumber = isNumber;
function isString(arg) {
return typeof arg === 'string';
}
exports.isString = isString;
function isSymbol(arg) {
return typeof arg === 'symbol';
}
exports.isSymbol = isSymbol;
function isUndefined(arg) {
return arg === void 0;
}
exports.isUndefined = isUndefined;
function isRegExp(re) {
return isObject(re) && objectToString(re) === '[object RegExp]';
}
exports.isRegExp = isRegExp;
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
exports.isObject = isObject;
function isDate(d) {
return isObject(d) && objectToString(d) === '[object Date]';
}
exports.isDate = isDate;
function isError(e) {
return isObject(e) &&
(objectToString(e) === '[object Error]' || e instanceof Error);
}
exports.isError = isError;
function isFunction(arg) {
return typeof arg === 'function';
}
exports.isFunction = isFunction;
function isPrimitive(arg) {
return arg === null ||
typeof arg === 'boolean' ||
typeof arg === 'number' ||
typeof arg === 'string' ||
typeof arg === 'symbol' || // ES6 symbol
typeof arg === 'undefined';
}
exports.isPrimitive = isPrimitive;
exports.isBuffer = require('./support/isBuffer');
function objectToString(o) {
return Object.prototype.toString.call(o);
}
function pad(n) {
return n < 10 ? '0' + n.toString(10) : n.toString(10);
}
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
'Oct', 'Nov', 'Dec'];
function timestamp() {
var d = new Date();
var time = [pad(d.getHours()),
pad(d.getMinutes()),
pad(d.getSeconds())].join(':');
return [d.getDate(), months[d.getMonth()], time].join(' ');
}
exports.log = function() {
console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
};
exports.inherits = require('inherits');
exports._extend = function(origin, add) {
if (!add || !isObject(add)) return origin;
var keys = Object.keys(add);
var i = keys.length;
while (i--) {
origin[keys[i]] = add[keys[i]];
}
return origin;
};
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
}).call(this,require("G+mPsH"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./support/isBuffer":19,"G+mPsH":13,"inherits":12}],21:[function(require,module,exports){
var AWS = require('./core');
AWS.XML.Parser = require('./xml/browser_parser');
require('./http/xhr');
if (typeof window !== 'undefined') window.AWS = AWS;
},{"./core":23,"./http/xhr":31,"./xml/browser_parser":61}],22:[function(require,module,exports){
var AWS = require('./core');
require('./credentials');
require('./credentials/credential_provider_chain');
AWS.Config = AWS.util.inherit({
constructor: function Config(options) {
if (options === undefined) options = {};
options = this.extractCredentials(options);
AWS.util.each.call(this, this.keys, function (key, value) {
this.set(key, options[key], value);
});
},
update: function update(options, allowUnknownKeys) {
allowUnknownKeys = allowUnknownKeys || false;
options = this.extractCredentials(options);
AWS.util.each.call(this, options, function (key, value) {
if (allowUnknownKeys || this.keys.hasOwnProperty(key)) this[key] = value;
});
},
getCredentials: function getCredentials(callback) {
var self = this;
function finish(err) {
callback(err, err ? null : self.credentials);
}
function credError(msg, err) {
return new AWS.util.error(err || new Error(), {
code: 'CredentialsError', message: msg
});
}
function getAsyncCredentials() {
self.credentials.get(function(err) {
if (err) {
var msg = 'Could not load credentials from ' +
self.credentials.constructor.name;
err = credError(msg, err);
}
finish(err);
});
}
function getStaticCredentials() {
var err = null;
if (!self.credentials.accessKeyId || !self.credentials.secretAccessKey) {
err = credError('Missing credentials');
}
finish(err);
}
if (self.credentials) {
if (typeof self.credentials.get === 'function') {
getAsyncCredentials();
} else { // static credentials
getStaticCredentials();
}
} else if (self.credentialProvider) {
self.credentialProvider.resolve(function(err, creds) {
if (err) {
err = credError('Could not load credentials from any providers', err);
}
self.credentials = creds;
finish(err);
});
} else {
finish(credError('No credentials to load'));
}
},
loadFromPath: function loadFromPath(path) {
this.clear();
var options = JSON.parse(AWS.util.readFileSync(path));
var fileSystemCreds = new AWS.FileSystemCredentials(path);
var chain = new AWS.CredentialProviderChain();
chain.providers.unshift(fileSystemCreds);
chain.resolve(function (err, creds) {
if (err) throw err;
else options.credentials = creds;
});
this.constructor(options);
return this;
},
clear: function clear() {
AWS.util.each.call(this, this.keys, function (key) {
delete this[key];
});
this.set('credentials', undefined);
this.set('credentialProvider', undefined);
},
set: function set(property, value, defaultValue) {
if (value === undefined) {
if (defaultValue === undefined) {
defaultValue = this.keys[property];
}
if (typeof defaultValue === 'function') {
this[property] = defaultValue.call(this);
} else {
this[property] = defaultValue;
}
} else {
this[property] = value;
}
},
keys: {
credentials: null,
credentialProvider: null,
region: null,
logger: null,
apiVersions: {},
apiVersion: null,
endpoint: undefined,
httpOptions: {},
maxRetries: undefined,
maxRedirects: 10,
paramValidation: true,
sslEnabled: true,
s3ForcePathStyle: false,
computeChecksums: true,
convertResponseTypes: true,
dynamoDbCrc32: true,
signatureVersion: null
},
extractCredentials: function extractCredentials(options) {
if (options.accessKeyId && options.secretAccessKey) {
options = AWS.util.copy(options);
options.credentials = new AWS.Credentials(options);
}
return options;
}
});
AWS.config = new AWS.Config();
},{"./core":23,"./credentials":24,"./credentials/credential_provider_chain":25}],23:[function(require,module,exports){
var AWS = { util: require('./util') };
var _hidden = {}; _hidden = {}; // hack to parse macro
module.exports = AWS;
AWS.util.update(AWS, {
VERSION: '2.0.0-rc.20',
Signers: {},
Protocol: {
Json: require('./protocol/json'),
Query: require('./protocol/query'),
Rest: require('./protocol/rest'),
RestJson: require('./protocol/rest_json'),
RestXml: require('./protocol/rest_xml')
},
XML: {
Builder: require('./xml/builder'),
Parser: null // conditionally set based on environment
},
JSON: {
Builder: require('./json/builder'),
Parser: require('./json/parser')
},
Model: {
Api: require('./model/api'),
Operation: require('./model/operation'),
Shape: require('./model/shape'),
Paginator: require('./model/paginator'),
ResourceWaiter: require('./model/resource_waiter')
},
util: require('./util')
});
require('./service');
require('./credentials');
require('./credentials/credential_provider_chain');
require('./credentials/temporary_credentials');
require('./credentials/web_identity_credentials');
require('./credentials/saml_credentials');
require('./config');
require('./http');
require('./sequential_executor');
require('./event_listeners');
require('./request');
require('./response');
require('./resource_waiter');
require('./signers/request_signer');
require('./param_validator');
AWS.events = new AWS.SequentialExecutor();
},{"./config":22,"./credentials":24,"./credentials/credential_provider_chain":25,"./credentials/saml_credentials":26,"./credentials/temporary_credentials":27,"./credentials/web_identity_credentials":28,"./event_listeners":29,"./http":30,"./json/builder":32,"./json/parser":33,"./model/api":34,"./model/operation":36,"./model/paginator":37,"./model/resource_waiter":38,"./model/shape":39,"./param_validator":40,"./protocol/json":41,"./protocol/query":42,"./protocol/rest":43,"./protocol/rest_json":44,"./protocol/rest_xml":45,"./request":47,"./resource_waiter":48,"./response":49,"./sequential_executor":50,"./service":51,"./signers/request_signer":53,"./util":60,"./xml/builder":62}],24:[function(require,module,exports){
var AWS = require('./core');
AWS.Credentials = AWS.util.inherit({
constructor: function Credentials() {
AWS.util.hideProperties(this, ['secretAccessKey']);
this.expired = false;
this.expireTime = null;
if (arguments.length === 1 && typeof arguments[0] === 'object') {
var creds = arguments[0].credentials || arguments[0];
this.accessKeyId = creds.accessKeyId;
this.secretAccessKey = creds.secretAccessKey;
this.sessionToken = creds.sessionToken;
} else {
this.accessKeyId = arguments[0];
this.secretAccessKey = arguments[1];
this.sessionToken = arguments[2];
}
},
expiryWindow: 15,
needsRefresh: function needsRefresh() {
var currentTime = AWS.util.date.getDate().getTime();
var adjustedTime = new Date(currentTime + this.expiryWindow * 1000);
if (this.expireTime && adjustedTime > this.expireTime) {
return true;
} else {
return this.expired || !this.accessKeyId || !this.secretAccessKey;
}
},
get: function get(callback) {
var self = this;
if (this.needsRefresh()) {
this.refresh(function(err) {
if (!err) self.expired = false; // reset expired flag
if (callback) callback(err);
});
} else if (callback) {
callback();
}
},
refresh: function refresh(callback) {
this.expired = false;
callback();
}
});
},{"./core":23}],25:[function(require,module,exports){
var AWS = require('../core');
AWS.CredentialProviderChain = AWS.util.inherit(AWS.Credentials, {
constructor: function CredentialProviderChain(providers) {
if (providers) {
this.providers = providers;
} else {
this.providers = AWS.CredentialProviderChain.defaultProviders.slice(0);
}
},
resolve: function resolve(callback) {
if (this.providers.length === 0) {
callback(new Error('No providers'));
return this;
}
var index = 0;
var providers = this.providers.slice(0);
function resolveNext(err, creds) {
if ((!err && creds) || index === providers.length) {
callback(err, creds);
return;
}
var provider = providers[index++];
if (typeof provider === 'function') {
creds = provider.call();
} else {
creds = provider;
}
if (creds.get) {
creds.get(function(err) {
resolveNext(err, err ? null : creds);
});
} else {
resolveNext(null, creds);
}
}
resolveNext();
return this;
}
});
AWS.CredentialProviderChain.defaultProviders = [];
},{"../core":23}],26:[function(require,module,exports){
var AWS = require('../core');
AWS.SAMLCredentials = AWS.util.inherit(AWS.Credentials, {
constructor: function SAMLCredentials(params) {
AWS.Credentials.call(this);
this.expired = true;
this.service = new AWS.STS();
this.params = params;
},
refresh: function refresh(callback) {
var self = this;
if (!callback) callback = function(err) { if (err) throw err; };
self.service.assumeRoleWithSAML(self.params, function (err, data) {
if (!err) {
self.service.credentialsFrom(data, self);
}
callback(err);
});
}
});
},{"../core":23}],27:[function(require,module,exports){
var AWS = require('../core');
AWS.TemporaryCredentials = AWS.util.inherit(AWS.Credentials, {
constructor: function TemporaryCredentials(params) {
AWS.Credentials.call(this);
this.loadMasterCredentials();
this.service = new AWS.STS();
this.expired = true;
this.params = params || {};
if (this.params.RoleArn) {
this.params.RoleSessionName =
this.params.RoleSessionName || 'temporary-credentials';
}
},
refresh: function refresh(callback) {
var self = this;
if (!callback) callback = function(err) { if (err) throw err; };
self.service.config.credentials = self.masterCredentials;
var operation = self.params.RoleArn ?
self.service.assumeRole : self.service.getSessionToken;
operation.call(self.service, self.params, function (err, data) {
if (!err) {
self.service.credentialsFrom(data, self);
}
callback(err);
});
},
loadMasterCredentials: function loadMasterCredentials() {
this.masterCredentials = AWS.config.credentials;
while (this.masterCredentials.masterCredentials) {
this.masterCredentials = this.masterCredentials.masterCredentials;
}
}
});
},{"../core":23}],28:[function(require,module,exports){
var AWS = require('../core');
AWS.WebIdentityCredentials = AWS.util.inherit(AWS.Credentials, {
constructor: function WebIdentityCredentials(params) {
AWS.Credentials.call(this);
this.expired = true;
this.service = new AWS.STS();
this.params = params;
this.data = null;
this.params.RoleSessionName = this.params.RoleSessionName || 'web-identity';
},
refresh: function refresh(callback) {
var self = this;
if (!callback) callback = function(err) { if (err) throw err; };
self.service.assumeRoleWithWebIdentity(self.params, function (err, data) {
self.data = null;
if (!err) {
self.data = data;
self.service.credentialsFrom(data, self);
}
callback(err);
});
}
});
},{"../core":23}],29:[function(require,module,exports){
var AWS = require('./core');
var SequentialExecutor = require('./sequential_executor');
AWS.EventListeners = {
Core: {} /* doc hack */
};
AWS.EventListeners = {
Core: new SequentialExecutor().addNamedListeners(function(add, addAsync) {
addAsync('VALIDATE_CREDENTIALS', 'validate',
function VALIDATE_CREDENTIALS(req, done) {
req.service.config.getCredentials(function(err) {
if (err) {
req.response.err = AWS.util.error(err,
{code: 'SigningError', message: 'Missing credentials in config'});
}
done();
});
});
add('VALIDATE_REGION', 'validate', function VALIDATE_REGION(req) {
if (!req.service.config.region && !req.service.hasGlobalEndpoint()) {
req.response.error = AWS.util.error(new Error(),
{code: 'SigningError', message: 'Missing region in config'});
}
});
add('VALIDATE_PARAMETERS', 'validate', function VALIDATE_PARAMETERS(req) {
var rules = req.service.api.operations[req.operation].input;
new AWS.ParamValidator().validate(rules, req.params);
});
add('SET_CONTENT_LENGTH', 'afterBuild', function SET_CONTENT_LENGTH(req) {
if (req.httpRequest.headers['Content-Length'] === undefined) {
var length = AWS.util.string.byteLength(req.httpRequest.body);
req.httpRequest.headers['Content-Length'] = length;
}
});
add('SET_HTTP_HOST', 'afterBuild', function SET_HTTP_HOST(req) {
req.httpRequest.headers['Host'] = req.httpRequest.endpoint.host;
});
addAsync('SIGN', 'sign', function SIGN(req, done) {
if (!req.service.api.signatureVersion) return done(); // none
req.service.config.getCredentials(function (err, credentials) {
if (err) {
req.response.error = err;
return done();
}
try {
var date = AWS.util.date.getDate();
var SignerClass = req.service.getSignerClass(req);
var signer = new SignerClass(req.httpRequest,
req.service.api.signingName || req.service.api.endpointPrefix);
delete req.httpRequest.headers['Authorization'];
delete req.httpRequest.headers['Date'];
delete req.httpRequest.headers['X-Amz-Date'];
signer.addAuthorization(credentials, date);
req.signedAt = date;
} catch (e) {
req.response.error = e;
}
done();
});
});
add('VALIDATE_RESPONSE', 'validateResponse', function VALIDATE_RESPONSE(resp) {
if (this.service.successfulResponse(resp, this)) {
resp.data = {};
resp.error = null;
} else {
resp.data = null;
resp.error = AWS.util.error(new Error(),
{code: 'UnknownError', message: 'An unknown error occurred.'});
}
});
addAsync('SEND', 'send', function SEND(resp, done) {
resp.httpResponse._abortCallback = done;
resp.error = null;
resp.data = null;
function callback(httpResp) {
resp.httpResponse.stream = httpResp;
httpResp.on('headers', function onHeaders(statusCode, headers) {
resp.request.emit('httpHeaders', [statusCode, headers, resp]);
if (!resp.request.httpRequest._streaming) {
if (AWS.HttpClient.streamsApiVersion === 2) { // streams2 API check
httpResp.on('readable', function onReadable() {
var data = httpResp.read();
if (data !== null) {
resp.request.emit('httpData', [data, resp]);
}
});
} else { // legacy streams API
httpResp.on('data', function onData(data) {
resp.request.emit('httpData', [data, resp]);
});
}
}
});
httpResp.on('end', function onEnd() {
resp.request.emit('httpDone');
done();
});
}
function progress(httpResp) {
httpResp.on('sendProgress', function onSendProgress(progress) {
resp.request.emit('httpUploadProgress', [progress, resp]);
});
httpResp.on('receiveProgress', function onReceiveProgress(progress) {
resp.request.emit('httpDownloadProgress', [progress, resp]);
});
}
function error(err) {
resp.error = AWS.util.error(err, {
code: 'NetworkingError',
region: resp.request.httpRequest.region,
hostname: resp.request.httpRequest.endpoint.hostname,
retryable: true
});
resp.request.emit('httpError', [resp.error, resp], function() {
done();
});
}
function executeSend() {
var http = AWS.HttpClient.getInstance();
var httpOptions = resp.request.service.config.httpOptions || {};
var stream = http.handleRequest(resp.request.httpRequest, httpOptions,
callback, error);
progress(stream);
}
var timeDiff = (AWS.util.date.getDate() - this.signedAt) / 1000;
if (timeDiff >= 60 * 10) { // if we signed 10min ago, re-sign
this.emit('sign', [this], function(err) {
if (err) done(err);
else executeSend();
});
} else {
executeSend();
}
});
add('HTTP_HEADERS', 'httpHeaders',
function HTTP_HEADERS(statusCode, headers, resp) {
resp.httpResponse.statusCode = statusCode;
resp.httpResponse.headers = headers;
resp.httpResponse.body = new AWS.util.Buffer('');
resp.httpResponse.buffers = [];
resp.httpResponse.numBytes = 0;
});
add('HTTP_DATA', 'httpData', function HTTP_DATA(chunk, resp) {
if (chunk) {
if (AWS.util.isNode()) {
resp.httpResponse.numBytes += chunk.length;
var total = resp.httpResponse.headers['content-length'];
var progress = { loaded: resp.httpResponse.numBytes, total: total };
resp.request.emit('httpDownloadProgress', [progress, resp]);
}
resp.httpResponse.buffers.push(new AWS.util.Buffer(chunk));
}
});
add('HTTP_DONE', 'httpDone', function HTTP_DONE(resp) {
if (resp.httpResponse.buffers && resp.httpResponse.buffers.length > 0) {
var body = AWS.util.buffer.concat(resp.httpResponse.buffers);
resp.httpResponse.body = body;
}
delete resp.httpResponse.numBytes;
delete resp.httpResponse.buffers;
});
add('FINALIZE_ERROR', 'retry', function FINALIZE_ERROR(resp) {
if (resp.httpResponse.statusCode) {
resp.error.statusCode = resp.httpResponse.statusCode;
if (resp.error.retryable === undefined) {
resp.error.retryable = this.service.retryableError(resp.error, this);
}
}
});
add('INVALIDATE_CREDENTIALS', 'retry', function INVALIDATE_CREDENTIALS(resp) {
if (!resp.error) return;
switch (resp.error.code) {
case 'RequestExpired': // EC2 only
case 'ExpiredTokenException':
case 'ExpiredToken':
resp.error.retryable = true;
resp.request.service.config.credentials.expired = true;
}
});
add('REDIRECT', 'retry', function REDIRECT(resp) {
if (resp.error && resp.error.statusCode >= 300 &&
resp.error.statusCode < 400 && resp.httpResponse.headers['location']) {
this.httpRequest.endpoint =
new AWS.Endpoint(resp.httpResponse.headers['location']);
resp.error.redirect = true;
resp.error.retryable = true;
}
});
add('RETRY_CHECK', 'retry', function RETRY_CHECK(resp) {
if (resp.error) {
if (resp.error.redirect && resp.redirectCount < resp.maxRedirects) {
resp.error.retryDelay = 0;
} else if (resp.error.retryable && resp.retryCount < resp.maxRetries) {
var delays = this.service.retryDelays();
resp.error.retryDelay = delays[resp.retryCount] || 0;
}
}
});
addAsync('RESET_RETRY_STATE', 'afterRetry', function RESET_RETRY_STATE(resp, done) {
var delay, willRetry = false;
if (resp.error) {
delay = resp.error.retryDelay || 0;
if (resp.error.retryable && resp.retryCount < resp.maxRetries) {
resp.retryCount++;
willRetry = true;
} else if (resp.error.redirect && resp.redirectCount < resp.maxRedirects) {
resp.redirectCount++;
willRetry = true;
}
}
if (willRetry) {
resp.error = null;
setTimeout(done, delay);
} else {
done();
}
});
}),
CorePost: new SequentialExecutor().addNamedListeners(function(add) {
add('EXTRACT_REQUEST_ID', 'extractData', function EXTRACT_REQUEST_ID(resp) {
resp.requestId = resp.httpResponse.headers['x-amz-request-id'] ||
resp.httpResponse.headers['x-amzn-requestid'];
if (!resp.requestId && resp.data && resp.data.ResponseMetadata) {
resp.requestId = resp.data.ResponseMetadata.RequestId;
}
});
}),
Logger: new SequentialExecutor().addNamedListeners(function(add) {
add('LOG_REQUEST', 'complete', function LOG_REQUEST(resp) {
var req = resp.request;
var logger = req.service.config.logger;
if (!logger) return;
function buildMessage() {
var time = AWS.util.date.getDate().getTime();
var delta = (time - req.startTime.getTime()) / 1000;
var ansi = logger.isTTY ? true : false;
var status = resp.httpResponse.statusCode;
var params = require('util').inspect(req.params, true, true);
var message = '';
if (ansi) message += '\x1B[33m';
message += '[AWS ' + req.service.serviceIdentifier + ' ' + status;
message += ' ' + delta.toString() + 's ' + resp.retryCount + ' retries]';
if (ansi) message += '\x1B[0;1m';
message += ' ' + AWS.util.string.lowerFirst(req.operation);
message += '(' + params + ')';
if (ansi) message += '\x1B[0m';
return message;
}
var line = buildMessage();
if (typeof logger.log === 'function') {
logger.log(line);
} else if (typeof logger.write === 'function') {
logger.write(line + '\n');
}
});
}),
Json: new SequentialExecutor().addNamedListeners(function(add) {
var svc = require('./protocol/json');
add('BUILD', 'build', svc.buildRequest);
add('EXTRACT_DATA', 'extractData', svc.extractData);
add('EXTRACT_ERROR', 'extractError', svc.extractError);
}),
Rest: new SequentialExecutor().addNamedListeners(function(add) {
var svc = require('./protocol/rest');
add('BUILD', 'build', svc.buildRequest);
add('EXTRACT_DATA', 'extractData', svc.extractData);
add('EXTRACT_ERROR', 'extractError', svc.extractError);
}),
RestJson: new SequentialExecutor().addNamedListeners(function(add) {
var svc = require('./protocol/rest_json');
add('BUILD', 'build', svc.buildRequest);
add('EXTRACT_DATA', 'extractData', svc.extractData);
add('EXTRACT_ERROR', 'extractError', svc.extractError);
}),
RestXml: new SequentialExecutor().addNamedListeners(function(add) {
var svc = require('./protocol/rest_xml');
add('BUILD', 'build', svc.buildRequest);
add('EXTRACT_DATA', 'extractData', svc.extractData);
add('EXTRACT_ERROR', 'extractError', svc.extractError);
}),
Query: new SequentialExecutor().addNamedListeners(function(add) {
var svc = require('./protocol/query');
add('BUILD', 'build', svc.buildRequest);
add('EXTRACT_DATA', 'extractData', svc.extractData);
add('EXTRACT_ERROR', 'extractError', svc.extractError);
})
};
},{"./core":23,"./protocol/json":41,"./protocol/query":42,"./protocol/rest":43,"./protocol/rest_json":44,"./protocol/rest_xml":45,"./sequential_executor":50,"util":20}],30:[function(require,module,exports){
var AWS = require('./core');
var inherit = AWS.util.inherit;
AWS.Endpoint = inherit({
constructor: function Endpoint(endpoint, config) {
AWS.util.hideProperties(this, ['slashes', 'auth', 'hash', 'search', 'query']);
if (typeof endpoint === 'undefined' || endpoint === null) {
throw new Error('Invalid endpoint: ' + endpoint);
} else if (typeof endpoint !== 'string') {
return AWS.util.copy(endpoint);
}
if (!endpoint.match(/^http/)) {
var useSSL = config && config.sslEnabled !== undefined ?
config.sslEnabled : AWS.config.sslEnabled;
endpoint = (useSSL ? 'https' : 'http') + '://' + endpoint;
}
AWS.util.update(this, AWS.util.urlParse(endpoint));
if (this.port) {
this.port = parseInt(this.port, 10);
} else {
this.port = this.protocol === 'https:' ? 443 : 80;
}
}
});
AWS.HttpRequest = inherit({
constructor: function HttpRequest(endpoint, region) {
endpoint = new AWS.Endpoint(endpoint);
this.method = 'POST';
this.path = endpoint.path || '/';
this.headers = {};
this.body = '';
this.endpoint = endpoint;
this.region = region;
this.setUserAgent();
},
setUserAgent: function setUserAgent() {
var prefix = AWS.util.isBrowser() ? 'X-Amz-' : '';
this.headers[prefix + 'User-Agent'] = AWS.util.userAgent();
},
pathname: function pathname() {
return this.path.split('?', 1)[0];
},
search: function search() {
return this.path.split('?', 2)[1] || '';
}
});
AWS.HttpResponse = inherit({
constructor: function HttpResponse() {
this.statusCode = undefined;
this.headers = {};
this.body = undefined;
}
});
AWS.HttpClient = inherit({});
AWS.HttpClient.getInstance = function getInstance() {
if (this.singleton === undefined) {
this.singleton = new this();
}
return this.singleton;
};
},{"./core":23}],31:[function(require,module,exports){
var AWS = require('../core');
var EventEmitter = require('events').EventEmitter;
require('../http');
AWS.XHRClient = AWS.util.inherit({
handleRequest: function handleRequest(httpRequest, httpOptions, callback, errCallback) {
var self = this;
var endpoint = httpRequest.endpoint;
var emitter = new EventEmitter();
var href = endpoint.protocol + '//' + endpoint.hostname;
if (endpoint.port !== 80 && endpoint.port !== 443) {
href += ':' + endpoint.port;
}
href += httpRequest.path;
var xhr = new XMLHttpRequest(), headersEmitted = false;
httpRequest.stream = xhr;
if (httpOptions.timeout) {
xhr.timeout = httpOptions.timeout;
}
xhr.addEventListener('readystatechange', function() {
try {
if (xhr.status === 0) return; // 0 code is invalid
} catch (e) { return; }
if (this.readyState >= this.HEADERS_RECEIVED && !headersEmitted) {
try { xhr.responseType = 'arraybuffer'; } catch (e) {}
emitter.statusCode = xhr.status;
emitter.headers = self.parseHeaders(xhr.getAllResponseHeaders());
emitter.emit('headers', emitter.statusCode, emitter.headers);
headersEmitted = true;
}
if (this.readyState === this.DONE) {
self.finishRequest(xhr, emitter);
}
}, false);
xhr.upload.addEventListener('progress', function (evt) {
emitter.emit('sendProgress', evt);
});
xhr.addEventListener('progress', function (evt) {
emitter.emit('receiveProgress', evt);
}, false);
xhr.addEventListener('timeout', function () {
errCallback(AWS.util.error(new Error('Timeout'), {code: 'TimeoutError'}));
}, false);
xhr.addEventListener('error', function () {
errCallback(AWS.util.error(new Error('Network Failure'), {
code: 'NetworkingError'
}));
}, false);
callback(emitter);
xhr.open(httpRequest.method, href, httpOptions.xhrAsync !== false);
AWS.util.each(httpRequest.headers, function (key, value) {
if (key !== 'Content-Length' && key !== 'User-Agent' && key !== 'Host') {
xhr.setRequestHeader(key, value);
}
});
if (httpRequest.body && typeof httpRequest.body.buffer === 'object') {
xhr.send(httpRequest.body.buffer); // typed arrays sent as ArrayBuffer
} else {
xhr.send(httpRequest.body);
}
return emitter;
},
parseHeaders: function parseHeaders(rawHeaders) {
var headers = {};
AWS.util.arrayEach(rawHeaders.split(/\r?\n/), function (line) {
var key = line.split(':', 1)[0];
var value = line.substring(key.length + 2);
if (key.length > 0) headers[key] = value;
});
return headers;
},
finishRequest: function finishRequest(xhr, emitter) {
var buffer;
if (xhr.responseType === 'arraybuffer' && xhr.response) {
var ab = xhr.response;
buffer = new AWS.util.Buffer(ab.byteLength);
var view = new Uint8Array(ab);
for (var i = 0; i < buffer.length; ++i) {
buffer[i] = view[i];
}
}
try {
if (!buffer && typeof xhr.responseText === 'string') {
buffer = new AWS.util.Buffer(xhr.responseText);
}
} catch (e) {}
if (buffer) emitter.emit('data', buffer);
emitter.emit('end');
}
});
AWS.HttpClient.prototype = AWS.XHRClient.prototype;
AWS.HttpClient.streamsApiVersion = 1;
},{"../core":23,"../http":30,"events":11}],32:[function(require,module,exports){
var util = require('../util');
function JsonBuilder() { }
JsonBuilder.prototype.build = function(value, shape) {
return JSON.stringify(translate(value, shape));
};
function translate(value, shape) {
if (!shape || value === undefined || value === null) return undefined;
switch (shape.type) {
case 'structure': return translateStructure(value, shape);
case 'map': return translateMap(value, shape);
case 'list': return translateList(value, shape);
default: return translateScalar(value, shape);
}
}
function translateStructure(structure, shape) {
var struct = {};
util.each(structure, function(name, value) {
var memberShape = shape.members[name];
if (memberShape) {
if (memberShape.location !== 'body') return;
var result = translate(value, memberShape);
if (result !== undefined) struct[name] = result;
}
});
return struct;
}
function translateList(list, shape) {
var out = [];
util.arrayEach(list, function(value) {
var result = translate(value, shape.member);
if (result !== undefined) out.push(result);
});
return out;
}
function translateMap(map, shape) {
var out = {};
util.each(map, function(key, value) {
var result = translate(value, shape.value);
if (result !== undefined) out[key] = result;
});
return out;
}
function translateScalar(value, shape) {
return shape.toWireFormat(value);
}
module.exports = JsonBuilder;
},{"../util":60}],33:[function(require,module,exports){
var util = require('../util');
function JsonParser() { }
JsonParser.prototype.parse = function(value, shape) {
return translate(JSON.parse(value), shape);
};
function translate(value, shape) {
if (!shape || value === undefined || value === null) return undefined;
switch (shape.type) {
case 'structure': return translateStructure(value, shape);
case 'map': return translateMap(value, shape);
case 'list': return translateList(value, shape);
default: return translateScalar(value, shape);
}
}
function translateStructure(structure, shape) {
var struct = {};
util.each(structure, function(name, value) {
var memberShape = shape.members[name];
if (memberShape) {
var result = translate(value, memberShape);
if (result !== undefined) struct[name] = result;
}
});
return struct;
}
function translateList(list, shape) {
var out = [];
util.arrayEach(list, function(value) {
var result = translate(value, shape.member);
if (result !== undefined) out.push(result);
});
return out;
}
function translateMap(map, shape) {
var out = {};
util.each(map, function(key, value) {
var result = translate(value, shape.value);
if (result !== undefined) out[key] = result;
});
return out;
}
function translateScalar(value, shape) {
return shape.toType(value);
}
module.exports = JsonParser;
},{"../util":60}],34:[function(require,module,exports){
var Collection = require('./collection');
var Operation = require('./operation');
var Shape = require('./shape');
var Paginator = require('./paginator');
var ResourceWaiter = require('./resource_waiter');
var util = require('../util');
var property = util.property;
var memoizedProperty = util.memoizedProperty;
function Api(api, options) {
api = api || {};
options = options || {};
options.api = this;
api.metadata = api.metadata || {};
property(this, 'isApi', true, false);
property(this, 'apiVersion', api.metadata.apiVersion);
property(this, 'endpointPrefix', api.metadata.endpointPrefix);
property(this, 'globalEndpoint', api.metadata.globalEndpoint);
property(this, 'signatureVersion', api.metadata.signatureVersion);
property(this, 'jsonVersion', api.metadata.jsonVersion);
property(this, 'targetPrefix', api.metadata.targetPrefix);
property(this, 'protocol', api.metadata.protocol);
property(this, 'timestampFormat', api.metadata.timestampFormat);
property(this, 'xmlNamespaceUri', api.metadata.xmlNamespace);
property(this, 'abbreviation', api.metadata.serviceAbbreviation);
property(this, 'fullName', api.metadata.serviceFullName);
memoizedProperty(this, 'className', function() {
var name = api.metadata.serviceAbbreviation || api.metadata.serviceFullName;
if (!name) return null;
name = name.replace(/^Amazon|AWS\s*|\(.*|\s+|\W+/g, '');
if (name === 'ElasticLoadBalancing') name = 'ELB';
return name;
});
property(this, 'operations', new Collection(api.operations, options, function(name, operation) {
return new Operation(name, operation, options);
}, util.string.lowerFirst));
property(this, 'shapes', new Collection(api.shapes, options, function(name, shape) {
return Shape.create(shape, options);
}));
property(this, 'paginators', new Collection(api.paginators, options, function(name, paginator) {
return new Paginator(name, paginator, options);
}));
property(this, 'waiters', new Collection(api.waiters, options, function(name, waiter) {
return new ResourceWaiter(name, waiter, options);
}, util.string.lowerFirst));
if (options.documentation) {
property(this, 'documentation', api.documentation);
property(this, 'documentationUrl', api.documentationUrl);
}
}
module.exports = Api;
},{"../util":60,"./collection":35,"./operation":36,"./paginator":37,"./resource_waiter":38,"./shape":39}],35:[function(require,module,exports){
var memoizedProperty = require('../util').memoizedProperty;
function Collection(iterable, options, fn, nameTr) {
nameTr = nameTr || String;
var self = this;
for (var id in iterable) {
if (iterable.hasOwnProperty(id)) {
(function(name) {
memoizedProperty(self, nameTr(name), function() {
return fn(name, iterable[name]);
});
})(id);
}
}
}
module.exports = Collection;
},{"../util":60}],36:[function(require,module,exports){
var Shape = require('./shape');
var util = require('../util');
var property = util.property;
var memoizedProperty = util.memoizedProperty;
function Operation(name, operation, options) {
options = options || {};
property(this, 'name', name);
property(this, 'api', options.api, false);
operation.http = operation.http || {};
property(this, 'httpMethod', operation.http.method || 'POST');
property(this, 'httpPath', operation.http.requestUri || '/');
memoizedProperty(this, 'input', function() {
if (!operation.input) {
return new Shape.create({type: 'structure'}, options);
}
return Shape.create(operation.input, options);
});
memoizedProperty(this, 'output', function() {
if (!operation.output) {
return new Shape.create({type: 'structure'}, options);
}
return Shape.create(operation.output, options);
});
memoizedProperty(this, 'errors', function() {
var list = [];
if (!operation.errors) return null;
for (var i = 0; i < operation.errors.length; i++) {
list.push(Shape.create(operation.errors[i], options));
}
return list;
});
memoizedProperty(this, 'paginator', function() {
return options.api.paginators[name];
});
if (options.documentation) {
property(this, 'documentation', operation.documentation);
property(this, 'documentationUrl', operation.documentationUrl);
}
}
module.exports = Operation;
},{"../util":60,"./shape":39}],37:[function(require,module,exports){
var property = require('../util').property;
function Paginator(name, paginator) {
property(this, 'inputToken', paginator.input_token);
property(this, 'limitKey', paginator.limit_key);
property(this, 'moreResults', paginator.more_results);
property(this, 'outputToken', paginator.output_token);
property(this, 'resultKey', paginator.result_key);
}
module.exports = Paginator;
},{"../util":60}],38:[function(require,module,exports){
var Shape = require('./shape');
var StructureShape = Shape.shapes.StructureShape;
var util = require('../util');
var property = util.property;
var memoizedProperty = util.memoizedProperty;
function ResourceWaiter(name, waiter, options) {
options = options || {};
function InnerResourceWaiter() {
property(this, 'name', name);
property(this, 'api', options.api, false);
if (waiter.operation) {
property(this, 'operation', util.string.lowerFirst(waiter.operation));
}
var self = this, map = {
ignoreErrors: 'ignore_errors',
successType: 'success_type',
successValue: 'success_value',
successPath: 'success_path',
acceptorType: 'acceptor_type',
acceptorValue: 'acceptor_value',
acceptorPath: 'acceptor_path',
failureType: 'failure_type',
failureValue: 'failure_value',
failurePath: 'success_path',
interval: 'interval',
maxAttempts: 'max_attempts'
};
Object.keys(map).forEach(function(key) {
var value = waiter[map[key]];
if (value) property(self, key, value);
});
}
if (options.api) {
var proto = null;
if (waiter['extends']) {
proto = options.api.waiters[waiter['extends']];
} else if (name !== '__default__') {
proto = options.api.waiters['__default__'];
}
if (proto) InnerResourceWaiter.prototype = proto;
}
return new InnerResourceWaiter();
}
module.exports = ResourceWaiter;
},{"../util":60,"./shape":39}],39:[function(require,module,exports){
var Collection = require('./collection');
var util = require('../util');
function property(obj, name, value) {
if (value !== null && value !== undefined) {
util.property.apply(this, arguments);
}
}
function memoizedProperty(obj, name) {
if (!obj.constructor.prototype[name]) {
util.memoizedProperty.apply(this, arguments);
}
}
function Shape(shape, options, memberName) {
options = options || {};
property(this, 'shape', shape.shape);
property(this, 'api', options.api, false);
property(this, 'type', shape.type);
property(this, 'location', shape.location || 'body');
property(this, 'queryName', shape.queryName);
property(this, 'queryFlattened', shape.queryFlattened);
property(this, 'name', this.name || shape.xmlName || shape.locationName ||
memberName);
property(this, 'isStreaming', shape.streaming || false);
property(this, 'isComposite', shape.isComposite || false);
property(this, 'isShape', true, false);
if (options.documentation) {
property(this, 'documentation', shape.documentation);
property(this, 'documentationUrl', shape.documentationUrl);
}
if (shape.xmlAttribute) {
property(this, 'isXmlAttribute', shape.xmlAttribute || false);
}
property(this, 'defaultValue', null);
this.toWireFormat = function(value) {
if (value === null || value === undefined) return '';
return value;
};
this.toType = function(value) { return value; };
}
Shape.normalizedTypes = {
character: 'string',
double: 'float',
long: 'integer',
short: 'integer',
biginteger: 'integer',
bigdecimal: 'float',
blob: 'binary'
};
Shape.types = {
structure: StructureShape,
list: ListShape,
map: MapShape,
boolean: BooleanShape,
timestamp: TimestampShape,
float: FloatShape,
integer: IntegerShape,
string: StringShape,
base64: Base64Shape,
binary: BinaryShape
};
Shape.resolve = function resolve(shape, options) {
if (shape.shape) {
var refShape = options.api.shapes[shape.shape];
if (!refShape) {
throw new Error('Cannot find shape reference: ' + shape.shape);
}
return refShape;
} else {
return null;
}
};
Shape.create = function create(shape, options, memberName) {
if (shape.isShape) return shape;
var refShape = Shape.resolve(shape, options);
if (refShape) {
var filteredKeys = Object.keys(shape);
if (!options.documentation) {
filteredKeys = filteredKeys.filter(function(name) {
return !name.match(/documentation/);
});
}
if (filteredKeys === ['shape']) { // no inline customizations
return refShape;
}
var InlineShape = function() {
refShape.constructor.call(this, shape, options, memberName);
};
InlineShape.prototype = refShape;
return new InlineShape();
} else {
if (!shape.type) {
if (shape.members) shape.type = 'structure';
else if (shape.member) shape.type = 'list';
else if (shape.key) shape.type = 'map';
else shape.type = 'string';
}
var origType = shape.type;
if (Shape.normalizedTypes[shape.type]) {
shape.type = Shape.normalizedTypes[shape.type];
}
if (Shape.types[shape.type]) {
return new Shape.types[shape.type](shape, options, memberName);
} else {
throw new Error('Unrecognized shape type: ' + origType);
}
}
};
function CompositeShape(shape) {
Shape.apply(this, arguments);
property(this, 'isComposite', true);
if (shape.flattened) {
property(this, 'flattened', shape.flattened || false);
}
}
function StructureShape(shape, options) {
var requiredMap = null, firstInit = !this.isShape;
CompositeShape.apply(this, arguments);
if (firstInit) {
property(this, 'defaultValue', function() { return {}; });
property(this, 'members', {});
property(this, 'memberNames', []);
property(this, 'required', []);
property(this, 'isRequired', function(name) { return false; });
}
if (shape.members) {
property(this, 'members', new Collection(shape.members, options, function(name, member) {
return Shape.create(member, options, name);
}));
memoizedProperty(this, 'memberNames', function() {
return shape.xmlOrder || Object.keys(shape.members);
});
}
if (shape.required) {
property(this, 'required', shape.required);
property(this, 'isRequired', function(name) {
if (!requiredMap) {
requiredMap = {};
for (var i = 0; i < shape.required.length; i++) {
requiredMap[shape.required[i]] = true;
}
}
return requiredMap[name];
}, false, true);
}
property(this, 'resultWrapper', shape.resultWrapper || null);
if (shape.payload) {
property(this, 'payload', shape.payload);
}
if (typeof shape.xmlNamespace === 'string') {
property(this, 'xmlNamespaceUri', shape.xmlNamespace);
} else if (typeof shape.xmlNamespace === 'object') {
property(this, 'xmlNamespacePrefix', shape.xmlNamespace.prefix);
property(this, 'xmlNamespaceUri', shape.xmlNamespace.uri);
}
}
function ListShape(shape, options) {
var self = this, firstInit = !this.isShape;
CompositeShape.apply(this, arguments);
if (firstInit) {
property(this, 'defaultValue', function() { return []; });
}
if (shape.member) {
memoizedProperty(this, 'member', function() {
return Shape.create(shape.member, options);
});
}
if (this.flattened) {
var oldName = this.name;
memoizedProperty(this, 'name', function() {
return self.member.name || oldName;
});
}
}
function MapShape(shape, options) {
var firstInit = !this.isShape;
CompositeShape.apply(this, arguments);
if (firstInit) {
property(this, 'defaultValue', function() { return {}; });
property(this, 'key', Shape.create({type: 'string'}, options));
property(this, 'value', Shape.create({type: 'string'}, options));
}
if (shape.key) {
memoizedProperty(this, 'key', function() {
return Shape.create(shape.key, options);
});
}
if (shape.value) {
memoizedProperty(this, 'value', function() {
return Shape.create(shape.value, options);
});
}
}
function TimestampShape(shape) {
var self = this;
Shape.apply(this, arguments);
if (shape.timestampFormat) {
property(this, 'timestampFormat', shape.timestampFormat);
} else if (this.api) {
property(this, 'timestampFormat', this.api.timestampFormat);
}
this.toType = function(value) {
if (value === null || value === undefined) return null;
if (typeof value.toUTCString === 'function') return value;
return typeof value === 'string' ? util.date.parseTimestamp(value) : null;
};
this.toWireFormat = function(value) {
return util.date.format(value, self.timestampFormat);
};
}
function StringShape() {
Shape.apply(this, arguments);
}
function FloatShape() {
Shape.apply(this, arguments);
this.toType = function(value) {
if (value === null || value === undefined) return null;
return parseFloat(value);
};
this.toWireFormat = this.toType;
}
function IntegerShape() {
Shape.apply(this, arguments);
this.toType = function(value) {
if (value === null || value === undefined) return null;
return parseInt(value, 10);
};
this.toWireFormat = this.toType;
}
function BinaryShape() {
Shape.apply(this, arguments);
this.toType = util.base64.decode;
this.toWireFormat = util.base64.encode;
}
function Base64Shape() {
BinaryShape.apply(this, arguments);
}
function BooleanShape() {
Shape.apply(this, arguments);
this.toType = function(value) {
if (value === null || value === undefined) return null;
return value === 'true';
};
}
Shape.shapes = {
StructureShape: StructureShape,
ListShape: ListShape,
MapShape: MapShape,
StringShape: StringShape,
BooleanShape: BooleanShape,
Base64Shape: Base64Shape
};
module.exports = Shape;
},{"../util":60,"./collection":35}],40:[function(require,module,exports){
var AWS = require('./core');
AWS.ParamValidator = AWS.util.inherit({
validate: function validate(shape, params, context) {
return this.validateMember(shape, params || {}, context || 'params');
},
validateStructure: function validateStructure(shape, params, context) {
this.validateType(context, params, ['object'], 'structure');
for (var i = 0; shape.required && i < shape.required.length; i++) {
var paramName = shape.required[i];
var value = params[paramName];
if (value === undefined || value === null) {
this.fail('MissingRequiredParameter',
'Missing required key \'' + paramName + '\' in ' + context);
}
}
for (paramName in params) {
if (!params.hasOwnProperty(paramName)) continue;
var paramValue = params[paramName],
memberShape = shape.members[paramName];
if (memberShape !== undefined) {
var memberContext = [context, paramName].join('.');
this.validateMember(memberShape, paramValue, memberContext);
} else {
this.fail('UnexpectedParameter',
'Unexpected key \'' + paramName + '\' found in ' + context);
}
}
return true;
},
validateMember: function validateMember(shape, param, context) {
switch(shape.type) {
case 'structure':
return this.validateStructure(shape, param, context);
case 'list':
return this.validateList(shape, param, context);
case 'map':
return this.validateMap(shape, param, context);
default:
return this.validateScalar(shape, param, context);
}
},
validateList: function validateList(shape, params, context) {
this.validateType(context, params, [Array]);
for (var i = 0; i < params.length; i++) {
this.validateMember(shape.member, params[i], context + '[' + i + ']');
}
},
validateMap: function validateMap(shape, params, context) {
this.validateType(context, params, ['object'], 'map');
for (var param in params) {
if (!params.hasOwnProperty(param)) continue;
this.validateMember(shape.value, params[param],
context + '[\'' + param + '\']');
}
},
validateScalar: function validateScalar(shape, value, context) {
switch (shape.type) {
case null:
case undefined:
case 'string':
return this.validateType(context, value, ['string']);
case 'base64':
case 'binary':
return this.validatePayload(context, value);
case 'integer':
case 'float':
return this.validateNumber(context, value);
case 'boolean':
return this.validateType(context, value, ['boolean']);
case 'timestamp':
return this.validateType(context, value, [Date,
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$/, 'number'],
'Date object, ISO-8601 string, or a UNIX timestamp');
default:
return this.fail('UnkownType', 'Unhandled type ' +
shape.type + ' for ' + context);
}
},
fail: function fail(code, message) {
throw AWS.util.error(new Error(message), {code: code});
},
validateType: function validateType(context, value, acceptedTypes, type) {
if (value === null || value === undefined) return;
var foundInvalidType = false;
for (var i = 0; i < acceptedTypes.length; i++) {
if (typeof acceptedTypes[i] === 'string') {
if (typeof value === acceptedTypes[i]) return;
} else if (acceptedTypes[i] instanceof RegExp) {
if ((value || '').toString().match(acceptedTypes[i])) return;
} else {
if (value instanceof acceptedTypes[i]) return;
if (AWS.util.isType(value, acceptedTypes[i])) return;
if (!type && !foundInvalidType) acceptedTypes = acceptedTypes.slice();
acceptedTypes[i] = AWS.util.typeName(acceptedTypes[i]);
}
foundInvalidType = true;
}
var acceptedType = type;
if (!acceptedType) {
acceptedType = acceptedTypes.join(', ').replace(/,([^,]+)$/, ', or$1');
}
var vowel = acceptedType.match(/^[aeiou]/i) ? 'n' : '';
this.fail('InvalidParameterType', 'Expected ' + context + ' to be a' +
vowel + ' ' + acceptedType);
},
validateNumber: function validateNumber(context, value) {
if (value === null || value === undefined) return;
if (typeof value === 'string') {
var castedValue = parseFloat(value);
if (castedValue.toString() === value) value = castedValue;
}
this.validateType(context, value, ['number']);
},
validatePayload: function validatePayload(context, value) {
if (value === null || value === undefined) return;
if (typeof value === 'string') return;
if (value && typeof value.byteLength === 'number') return; // typed arrays
if (AWS.util.isNode()) { // special check for buffer/stream in Node.js
var Stream = AWS.util.nodeRequire('stream').Stream;
if (AWS.util.Buffer.isBuffer(value) || value instanceof Stream) return;
}
var types = ['Buffer', 'Stream', 'File', 'Blob', 'ArrayBuffer', 'DataView'];
if (value) {
for (var i = 0; i < types.length; i++) {
if (AWS.util.isType(value, types[i])) return;
if (AWS.util.typeName(value.constructor) === types[i]) return;
}
}
this.fail('InvalidParameterType', 'Expected ' + context + ' to be a ' +
'string, Buffer, Stream, Blob, or typed array object');
}
});
},{"./core":23}],41:[function(require,module,exports){
var util = require('../util');
var JsonBuilder = require('../json/builder');
var JsonParser = require('../json/parser');
function buildRequest(req) {
var httpRequest = req.httpRequest;
var api = req.service.api;
var target = api.targetPrefix + '.' + api.operations[req.operation].name;
var version = api.jsonVersion || '1.0';
var input = api.operations[req.operation].input;
var builder = new JsonBuilder();
if (version === 1) version = '1.0';
httpRequest.body = builder.build(req.params || {}, input);
httpRequest.headers['Content-Type'] = 'application/x-amz-json-' + version;
httpRequest.headers['X-Amz-Target'] = target;
}
function extractError(resp) {
var error = {};
var httpResponse = resp.httpResponse;
if (httpResponse.body.length > 0) {
var e = JSON.parse(httpResponse.body.toString());
if (e.__type || e.code) {
error.code = (e.__type || e.code).split('#').pop();
} else {
error.code = 'UnknownError';
}
if (error.code === 'RequestEntityTooLarge') {
error.message = 'Request body must be less than 1 MB';
} else {
error.message = (e.message || e.Message || null);
}
} else {
error.code = httpResponse.statusCode;
error.message = null;
}
resp.error = util.error(new Error(), error);
}
function extractData(resp) {
var body = resp.httpResponse.body.toString() || '{}';
if (resp.request.service.config.convertResponseTypes === false) {
resp.data = JSON.parse(body);
} else {
var operation = resp.request.service.api.operations[resp.request.operation];
var shape = operation.output || {};
var parser = new JsonParser();
resp.data = parser.parse(body, shape);
}
}
module.exports = {
buildRequest: buildRequest,
extractError: extractError,
extractData: extractData
};
},{"../json/builder":32,"../json/parser":33,"../util":60}],42:[function(require,module,exports){
var AWS = require('../core');
var util = require('../util');
var QueryParamSerializer = require('../query/query_param_serializer');
var Shape = require('../model/shape');
function buildRequest(req) {
var operation = req.service.api.operations[req.operation];
var httpRequest = req.httpRequest;
httpRequest.headers['Content-Type'] =
'application/x-www-form-urlencoded; charset=utf-8';
httpRequest.params = {
Version: req.service.api.apiVersion,
Action: operation.name
};
var builder = new QueryParamSerializer();
builder.serialize(req.params, operation.input, function(name, value) {
httpRequest.params[name] = value;
});
httpRequest.body = util.queryParamsToString(httpRequest.params);
}
function extractError(resp) {
var data, body = resp.httpResponse.body.toString();
if (body.match('<UnknownOperationException')) {
data = {
Code: 'UnknownOperation',
Message: 'Unknown operation ' + resp.request.operation
};
} else {
data = new AWS.XML.Parser().parse(body);
}
if (data.Errors) data = data.Errors;
if (data.Error) data = data.Error;
if (data.Code) {
resp.error = util.error(new Error(), {
code: data.Code,
message: data.Message
});
} else {
resp.error = util.error(new Error(), {
code: resp.httpResponse.statusCode,
message: null
});
}
}
function extractData(resp) {
var req = resp.request;
var operation = req.service.api.operations[req.operation];
var shape = operation.output || {};
var origRules = shape;
if (origRules.resultWrapper) {
var tmp = Shape.create({type: 'structure'});
tmp.members[origRules.resultWrapper] = shape;
tmp.memberNames = [origRules.resultWrapper];
util.property(shape, 'name', shape.resultWrapper);
shape = tmp;
}
var parser = new AWS.XML.Parser();
var data = parser.parse(resp.httpResponse.body.toString(), shape);
if (origRules.resultWrapper) {
if (data[origRules.resultWrapper]) {
util.update(data, data[origRules.resultWrapper]);
delete data[origRules.resultWrapper];
}
}
resp.data = data;
}
module.exports = {
buildRequest: buildRequest,
extractError: extractError,
extractData: extractData
};
},{"../core":23,"../model/shape":39,"../query/query_param_serializer":46,"../util":60}],43:[function(require,module,exports){
var util = require('../util');
function populateMethod(req) {
req.httpRequest.method = req.service.api.operations[req.operation].httpMethod;
}
function populateURI(req) {
var operation = req.service.api.operations[req.operation];
var input = operation.input;
var uri = [req.httpRequest.endpoint.path, operation.httpPath].join('/');
uri = uri.replace(/\/+/g, '/');
var escapePathParamFn = req.service.escapePathParam || escapePathParam;
var escapeQuerystringParamFn = req.service.escapeQuerystringParam ||
escapeQuerystringParam;
var queryString = {}, queryStringSet = false;
util.each(input.members, function (name, member) {
var paramValue = req.params[name];
if (paramValue === null || paramValue === undefined) return;
if (member.location === 'uri') {
uri = uri.replace('{' + member.name + '}', escapePathParamFn(paramValue));
} else if (member.location === 'querystring') {
queryStringSet = true;
queryString[member.name] = escapeQuerystringParamFn(paramValue);
}
});
if (queryStringSet) {
uri += (uri.indexOf('?') >= 0 ? '&' : '?');
var parts = [];
util.arrayEach(Object.keys(queryString).sort(), function(key) {
parts.push(escapeQuerystringParam(key) + '=' + queryString[key]);
});
uri += parts.join('&');
}
req.httpRequest.path = uri;
}
function escapePathParam(value) {
return util.uriEscape(String(value));
}
function escapeQuerystringParam(value) {
return util.uriEscape(String(value));
}
function populateHeaders(req) {
var operation = req.service.api.operations[req.operation];
util.each(operation.input.members, function (name, member) {
var value = req.params[name];
if (value === null || value === undefined) return;
if (member.location === 'headers' && member.type === 'map') {
util.each(value, function(key, value) {
req.httpRequest.headers[member.name + key] = value;
});
} else if (member.location === 'header') {
value = member.toWireFormat(value).toString();
req.httpRequest.headers[member.name] = value;
}
});
}
function buildRequest(req) {
populateMethod(req);
populateURI(req);
populateHeaders(req);
}
function extractError() {
}
function extractData(resp) {
var req = resp.request;
var data = {};
var r = resp.httpResponse;
var operation = req.service.api.operations[req.operation];
var output = operation.output;
var headers = {};
util.each(r.headers, function (k, v) {
headers[k.toLowerCase()] = v;
});
util.each(output.members, function(name, member) {
var header = (member.name || name).toLowerCase();
if (member.location === 'headers' && member.type === 'map') {
data[name] = {};
util.each(r.headers, function (k, v) {
var result = k.match(new RegExp('^' + member.name + '(.+)', 'i'));
if (result !== null) {
data[name][result[1]] = v;
}
});
} else if (member.location === 'header') {
if (headers[header] !== undefined) {
data[name] = headers[header];
}
} else if (member.location === 'status') {
data[name] = parseInt(r.statusCode, 10);
}
});
resp.data = data;
}
module.exports = {
buildRequest: buildRequest,
extractError: extractError,
extractData: extractData
};
},{"../util":60}],44:[function(require,module,exports){
var util = require('../util');
var Rest = require('./rest');
var Json = require('./json');
var JsonBuilder = require('../json/builder');
function populateBody(req) {
var builder = new JsonBuilder();
var input = req.service.api.operations[req.operation].input;
if (input.payload) {
var params = {};
var payloadShape = input.members[input.payload];
params = req.params[input.payload];
if (params === undefined) return;
if (payloadShape.type === 'structure') {
req.httpRequest.body = builder.build(params, payloadShape);
} else { // non-JSON payload
req.httpRequest.body = params;
}
} else {
req.httpRequest.body = builder.build(req.params, input);
}
}
function buildRequest(req) {
Rest.buildRequest(req);
populateBody(req);
}
function extractError(resp) {
Json.extractError(resp);
}
function extractData(resp) {
Rest.extractData(resp);
var req = resp.request;
var rules = req.service.api.operations[req.operation].output || {};
if (rules.payload) {
var payloadMember = rules.members[rules.payload];
if (payloadMember.isStreaming) {
resp.data[rules.payload] = resp.httpResponse.body;
} else if (payloadMember.type === 'structure') {
Json.extractData(resp);
} else {
resp.data[rules.payload] = resp.httpResponse.body.toString();
}
} else {
var data = resp.data;
Json.extractData(resp);
resp.data = util.merge(data, resp.data);
}
}
module.exports = {
buildRequest: buildRequest,
extractError: extractError,
extractData: extractData
};
},{"../json/builder":32,"../util":60,"./json":41,"./rest":43}],45:[function(require,module,exports){
var AWS = require('../core');
var util = require('../util');
var Rest = require('./rest');
function populateBody(req) {
var input = req.service.api.operations[req.operation].input;
var builder = new AWS.XML.Builder();
var params = req.params;
var payload = input.payload;
if (payload) {
var payloadMember = input.members[payload];
params = params[payload];
if (params === undefined) return;
if (payloadMember.type === 'structure') {
req.httpRequest.body = builder.toXML(params, payloadMember, payload);
} else { // non-xml payload
req.httpRequest.body = params;
}
} else {
req.httpRequest.body = builder.toXML(params, input, input.shape ||
util.string.upperFirst(req.operation) + 'Request');
}
}
function buildRequest(req) {
Rest.buildRequest(req);
populateBody(req);
}
function extractError(resp) {
Rest.extractError(resp);
var data = new AWS.XML.Parser().parse(resp.httpResponse.body.toString());
if (data.Errors) data = data.Errors;
if (data.Error) data = data.Error;
if (data.Code) {
resp.error = util.error(new Error(), {
code: data.Code,
message: data.Message
});
} else {
resp.error = util.error(new Error(), {
code: resp.httpResponse.statusCode,
message: null
});
}
}
function extractData(resp) {
Rest.extractData(resp);
var parser;
var req = resp.request;
var body = resp.httpResponse.body;
var operation = req.service.api.operations[req.operation];
var output = operation.output;
var payload = output.payload;
if (payload) {
var payloadMember = output.members[payload];
if (payloadMember.isStreaming) {
resp.data[payload] = body;
} else if (payloadMember.type === 'structure') {
parser = new AWS.XML.Parser();
resp.data = parser.parse(body.toString(), payloadMember);
} else {
resp.data[payload] = body.toString();
}
} else if (body.length > 0) {
parser = new AWS.XML.Parser();
var data = parser.parse(body.toString(), output);
util.update(resp.data, data);
}
}
module.exports = {
buildRequest: buildRequest,
extractError: extractError,
extractData: extractData
};
},{"../core":23,"../util":60,"./rest":43}],46:[function(require,module,exports){
var util = require('../util');
function QueryParamSerializer() { }
QueryParamSerializer.prototype.serialize = function(params, shape, fn) {
serializeStructure('', params, shape, fn);
};
function serializeStructure(prefix, struct, rules, fn) {
util.each(rules.members, function(name, member) {
var value = struct[name];
if (value === null || value === undefined) return;
var memberName = prefix ? prefix + '.' + member.name : member.name;
serializeMember(memberName, value, member, fn);
});
}
function serializeMap(name, map, rules, fn) {
var i = 1;
util.each(map, function (key, value) {
var prefix = rules.flattened || rules.queryFlattened ? '.' : '.entry.';
var position = prefix + (i++) + '.';
var keyName = position + (rules.key.name || 'key');
var valueName = position + (rules.value.name || 'value');
serializeMember(name + keyName, key, rules.key, fn);
serializeMember(name + valueName, value, rules.value, fn);
});
}
function serializeList(name, list, rules, fn) {
var memberRules = rules.member || {};
if (list.length === 0) {
fn.call(this, name, null);
return;
}
util.arrayEach(list, function (v, n) {
var suffix = '.' + (n + 1);
if (rules.flattened || rules.queryFlattened) {
if (memberRules.name) {
var parts = name.split('.');
parts.pop();
parts.push(memberRules.name);
name = parts.join('.');
}
} else {
suffix = '.member' + suffix;
}
serializeMember(name + suffix, v, memberRules, fn);
});
}
function serializeMember(name, value, rules, fn) {
if (value === null || value === undefined) return;
if (rules.type === 'structure') {
serializeStructure(name, value, rules, fn);
} else if (rules.type === 'list') {
serializeList(name, value, rules, fn);
} else if (rules.type === 'map') {
serializeMap(name, value, rules, fn);
} else {
fn(name, rules.toWireFormat(value).toString());
}
}
module.exports = QueryParamSeria
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment