aboutsummaryrefslogtreecommitdiffstats
path: root/tools/node_modules/nodemailer/node_modules
diff options
context:
space:
mode:
Diffstat (limited to 'tools/node_modules/nodemailer/node_modules')
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/.npmignore1
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/.travis.yml11
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/LICENSE16
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/README.md319
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/lib/dkim.js217
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/lib/mailcomposer.js1260
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/lib/punycode.js329
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/lib/urlfetch.js71
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/LICENSE16
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/README.md17
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/content-types.js60
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/doc.md191
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/index.js3
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/mime-functions.js486
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/package.json35
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/package.json46
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/test/dkim.js47
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/test/mailcomposer.js1085
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/test/test_private.pem12
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/test/test_public.pem5
-rw-r--r--tools/node_modules/nodemailer/node_modules/mailcomposer/test/textfile.txt601
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/.npmignore1
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/.travis.yml12
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/LICENSE16
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/README.md275
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/index.js5
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js709
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/lib/pool.js316
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/lib/server.js664
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/lib/starttls.js112
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/.npmignore1
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/.travis.yml12
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/LICENSE16
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/README.md163
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/cert/cert.pem15
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/cert/key.pem15
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/examples/smtp.js73
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/all.css358
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.eotbin0 -> 18590 bytes
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.svg134
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.ttfbin0 -> 18428 bytes
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.woffbin0 -> 11772 bytes
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.eotbin0 -> 19518 bytes
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.svg134
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.ttfbin0 -> 19344 bytes
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.woffbin0 -> 12304 bytes
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/handheld.css217
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/screen.css297
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/files.html133
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/index.html107
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/javascript/all.js326
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/javascript/html5.js6
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/RAIServer.html565
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/RAISocket.html826
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/_global_.html122
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/mockup.html264
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_index.js.html394
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_mockup.js.html110
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_rai.js.html484
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_starttls.js.html120
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/starttls.html237
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/mockup.js113
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/rai.js489
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/starttls.js113
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/package.json41
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/run_tests.js2
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/test/rai.js589
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/package.json52
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/test/client.js444
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/test/pool.js275
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/test/server.js590
-rw-r--r--tools/node_modules/nodemailer/node_modules/simplesmtp/test/testmessage.eml5
72 files changed, 14780 insertions, 0 deletions
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/.npmignore b/tools/node_modules/nodemailer/node_modules/mailcomposer/.npmignore
new file mode 100644
index 0000000..b512c09
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/.npmignore
@@ -0,0 +1 @@
+node_modules \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/.travis.yml b/tools/node_modules/nodemailer/node_modules/mailcomposer/.travis.yml
new file mode 100644
index 0000000..2bc1961
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/.travis.yml
@@ -0,0 +1,11 @@
+language: node_js
+node_js:
+ - 0.6
+ - 0.8
+
+notifications:
+ email:
+ recipients:
+ - andris@node.ee
+ on_success: change
+ on_failure: change
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/LICENSE b/tools/node_modules/nodemailer/node_modules/mailcomposer/LICENSE
new file mode 100644
index 0000000..a47b0ea
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/LICENSE
@@ -0,0 +1,16 @@
+Copyright (c) 2012 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. \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/README.md b/tools/node_modules/nodemailer/node_modules/mailcomposer/README.md
new file mode 100644
index 0000000..d5e53b4
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/README.md
@@ -0,0 +1,319 @@
+# mailcomposer
+
+**mailcomposer** is a Node.JS module for generating e-mail messages that can be
+streamed to SMTP or file.
+
+This is a standalone module that only generates raw e-mail source, you need to
+write your own or use an existing transport mechanism (SMTP client, Amazon SES,
+SendGrid etc). **mailcomposer** frees you from the tedious task of generating
+[rfc822](http://tools.ietf.org/html/rfc2822) compatible messages.
+
+[![Build Status](https://secure.travis-ci.org/andris9/mailcomposer.png)](http://travis-ci.org/andris9/mailcomposer)
+
+**mailcomposer** supports:
+
+ * **Unicode** to use any characters ✔
+ * **HTML** content as well as **plain text** alternative
+ * **Attachments** and streaming for larger files (use strings, buffers, files or binary streams as attachments)
+ * **Embedded images** in HTML
+ * **DKIM** signing
+ * usage of **your own** transport mechanism
+
+## Support mailcomposer development
+
+[![Donate to author](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DB26KWR2BQX5W)
+
+## Installation
+
+Install through NPM
+
+ npm install mailcomposer
+
+## Usage
+
+### Include mailcomposer module
+
+ var MailComposer = require("mailcomposer").MailComposer;
+
+### Create a new `MailComposer` instance
+
+ var mailcomposer = new MailComposer([options]);
+
+Where `options` is an optional options object with the following possible properties:
+
+ * **escapeSMTP** - if set replaces dots in the beginning of a line with double dots
+ * **encoding** - sets transfer encoding for the textual parts (defaults to `"quoted-printable"`)
+ * **keepBcc** - if set to true, includes `Bcc:` field in the message headers. Useful for *sendmail* command.
+
+### Simple example
+
+The following example generates a simple e-mail message with plaintext and html
+body.
+
+ var MailComposer = require("mailcomposer").MailComposer;
+ mailcomposer = new MailComposer(),
+ fs = require("fs");
+
+ // add additional header field
+ mailcomposer.addHeader("x-mailer", "Nodemailer 1.0");
+
+ // setup message data
+ mailcomposer.setMessageOption({
+ from: "andris@tr.ee",
+ to: "andris@node.ee",
+ body: "Hello world!",
+ html: "<b>Hello world!</b>"
+ });
+
+ mailcomposer.streamMessage();
+
+ // pipe the output to a file
+ mailcomposer.pipe(fs.createWriteStream("test.eml"));
+
+The output for such a script (the contents for "test.eml") would look like:
+
+ MIME-Version: 1.0
+ X-Mailer: Nodemailer 1.0
+ From: andris@tr.ee
+ To: andris@node.ee
+ Content-Type: multipart/alternative;
+ boundary="----mailcomposer-?=_1-1328088797399"
+
+ ------mailcomposer-?=_1-1328088797399
+ Content-Type: text/plain; charset=utf-8
+ Content-Transfer-Encoding: quoted-printable
+
+ Hello world!
+ ------mailcomposer-?=_1-1328088797399
+ Content-Type: text/html; charset=utf-8
+ Content-Transfer-Encoding: quoted-printable
+
+ <b>Hello world!</b>
+ ------mailcomposer-?=_1-1328088797399--
+
+## API
+
+### Add custom headers
+
+Headers can be added with `mailcomposer.addHeader(key, value)`
+
+ var mailcomposer = new MailComposer();
+ mailcomposer.addHeader("x-mailer", "Nodemailer 1.0");
+
+If you add an header value with the same key several times, all of the values will be used
+in the generated header. For example:
+
+ mailcomposer.addHeader("x-mailer", "Nodemailer 1.0");
+ mailcomposer.addHeader("x-mailer", "Nodemailer 2.0");
+
+Will be generated into
+
+ ...
+ X-Mailer: Nodemailer 1.0
+ X-Mailer: Nodemailer 2.0
+ ...
+
+The contents of the field value is not edited in any way (except for the folding),
+so if you want to use unicode symbols you need to escape these to mime words
+by yourself. Exception being object values - in this case the object
+is automatically JSONized and mime encoded.
+
+ // using objects as header values is allowed (will be converted to JSON)
+ var apiOptions = {};
+ apiOptions.category = "newuser";
+ apiOptions.tags = ["user", "web"];
+ mailcomposer.addHeader("X-SMTPAPI", apiOptions)
+
+### Add message parts
+
+You can set message sender, receiver, subject line, message body etc. with
+`mailcomposer.setMessageOption(options)` where options is an object with the
+data to be set. This function overwrites any previously set values with the
+same key
+
+The following example creates a simple e-mail with sender being `andris@tr.ee`,
+receiver `andris@node.ee` and plaintext part of the message as `Hello world!`:
+
+ mailcomposer.setMessageOption({
+ from: "andris@tr.ee",
+ to: "andris@node.ee",
+ body: "Hello world!"
+ });
+
+Possible options that can be used are (all fields accept unicode):
+
+ * **from** (alias `sender`) - the sender of the message. If several addresses are given, only the first one will be used
+ * **to** - receivers for the `To:` field
+ * **cc** - receivers for the `Cc:` field
+ * **bcc** - receivers for the `Bcc:` field
+ * **replyTo** (alias `reply_to`) - e-mail address for the `Reply-To:` field
+ * **inReplyTo** - The message-id this message is replying
+ * **references** - Message-id list
+ * **subject** - the subject line of the message
+ * **body** (alias `text`) - the plaintext part of the message
+ * **html** - the HTML part of the message
+ * **envelope** - optional SMTP envelope, if auto generated envelope is not suitable
+
+This method can be called several times
+
+ mailcomposer.setMessageOption({from: "andris@tr.ee"});
+ mailcomposer.setMessageOption({to: "andris@node.ee"});
+ mailcomposer.setMessageOption({body: "Hello world!"});
+
+Trying to set the same key several times will yield in overwrite
+
+ mailcomposer.setMessageOption({body: "Hello world!"});
+ mailcomposer.setMessageOption({body: "Hello world?"});
+ // body contents will be "Hello world?"
+
+### Address format
+
+All e-mail address fields take structured e-mail lists (comma separated)
+as the input. Unicode is allowed for all the parts (receiver name, e-mail username
+and domain) of the address. If the domain part contains unicode symbols, it is
+automatically converted into punycode, user part will be converted into UTF-8
+mime word.
+
+E-mail addresses can be a plain e-mail addresses
+
+ username@example.com
+
+or with a formatted name
+
+ 'Ноде Майлер' <username@example.com>
+
+Or in case of comma separated lists, the formatting can be mixed
+
+ username@example.com, 'Ноде Майлер' <username@example.com>, "Name, User" <username@example.com>
+
+### 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.
+
+ mailOptions = {
+ ...,
+ from: "mailer@node.ee",
+ to: "daemon@node.ee",
+ envelope: {
+ from: "Daemon <deamon@node.ee>",
+ to: "mailer@node.ee, Mailer <mailer2@node.ee>"
+ }
+ }
+
+### Add attachments
+
+Attachments can be added with `mailcomposer.addAttachment(attachment)` where
+`attachment` is an object with attachment (meta)data with the following possible
+properties:
+
+ * **fileName** (alias `filename`) - filename to be reported as the name of the attached file, use of unicode is allowed
+ * **cid** - 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** - content type for the attachment, if not set will be derived from the `fileName` property
+ * **contentDisposition** - content disposition type for the attachment, defaults to "attachment"
+ * **userAgent** - User-Agent string to be used if the fileName points to an URL
+
+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.
+
+**Using embedded images in HTML**
+
+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 cid_value = Date.now() + '.image.jpg';
+
+ var html = 'Embedded image: <img src="cid:' + cid_value + '" />';
+
+ var attachment = {
+ fileName: "image.png",
+ filePath: "/static/images/image.png",
+ cid: cid_value
+ };
+
+### DKIM Signing
+
+**mailcomposer** 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 - in this case the streaming capability offered by mailcomposer is illusionary,
+there will only be one `'data'` event with the entire message. 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:
+
+ mailcomposer.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.example.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
+
+**NB!** Currently if several header fields with the same name exists, only the last one (the one in the bottom) is signed.
+
+Example:
+
+ mailcomposer.setMessageOption({from: "andris@tr.ee"});
+ mailcomposer.setMessageOption({to: "andris@node.ee"});
+ mailcomposer.setMessageOption({body: "Hello world!"});
+ mailcomposer.useDKIM({
+ domainName: "node.ee",
+ keySelector: "dkim",
+ privateKey: fs.readFileSync("private_key.pem")
+ });
+
+### Start streaming
+
+When the message data is setup, streaming can be started. After this it is not
+possible to add headers, attachments or change body contents.
+
+ mailcomposer.streamMessage();
+
+This generates `'data'` events for the message headers and body and final `'end'` event.
+As `MailComposer` objects are Stream instances, these can be piped
+
+ // save the output to a file
+ mailcomposer.streamMessage();
+ mailcomposer.pipe(fs.createWriteStream("out.txt"));
+
+## Envelope
+
+Envelope can be generated with an `getEnvelope()` which returns an object
+that includes a `from` address (string) and a list of `to` addresses (array of
+strings) suitable for forwarding to a SMTP server as `MAIL FROM:` and `RCPT TO:`.
+
+ console.log(mailcomposer.getEnvelope());
+ // {from:"sender@example.com", to:["receiver@example.com"]}
+
+**NB!** both `from` and `to` properties might be missing from the envelope object
+if corresponding addresses were not detected from the e-mail.
+
+## Running tests
+
+Tests are run with [nodeunit](https://github.com/caolan/nodeunit)
+
+Run
+
+ npm test
+
+or alternatively
+
+ node run_tests.js
+
+## License
+
+**MIT** \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/lib/dkim.js b/tools/node_modules/nodemailer/node_modules/mailcomposer/lib/dkim.js
new file mode 100644
index 0000000..e3f1011
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/lib/dkim.js
@@ -0,0 +1,217 @@
+var crypto = require("crypto"),
+ mimelib = require("mimelib-noiconv"),
+ toPunycode = require("./punycode");
+
+/**
+ * @namespace DKIM Signer module
+ * @name dkimsign
+ */
+module.exports.DKIMSign = DKIMSign;
+module.exports.generateDKIMHeader = generateDKIMHeader;
+module.exports.sha256 = sha256;
+
+
+/**
+ * <p>Sign an email with provided DKIM key, uses RSA-SHA256.</p>
+ *
+ * @memberOf dkimsign
+ * @param {String} email Full e-mail source complete with headers and body to sign
+ * @param {Object} options DKIM options
+ * @param {String} [options.headerFieldNames="from:to:cc:subject"] Header fields to sign
+ * @param {String} options.privateKey DKMI private key
+ * @param {String} options.domainName Domain name to use for signing (ie: "domain.com")
+ * @param {String} options.keySelector Selector for the DKMI public key (ie. "dkim" if you have set up a TXT record for "dkim._domainkey.domain.com")
+ *
+ * @return {String} Signed DKIM-Signature header field for prepending
+ */
+function DKIMSign(email, options){
+ options = options || {};
+ email = (email || "").toString("utf-8");
+
+ var match = email.match(/^\r?\n|(?:\r?\n){2}/),
+ headers = match && email.substr(0, match.index) || "",
+ body = match && email.substr(match.index + match[0].length) || email;
+
+ // all listed fields from RFC4871 #5.5
+ var defaultFieldNames = "From:Sender:Reply-To:Subject:Date:Message-ID:To:" +
+ "Cc:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID:" +
+ "Content-Description:Resent-Date:Resent-From:Resent-Sender:" +
+ "Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:" +
+ "List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post:" +
+ "List-Owner:List-Archive";
+
+ var dkim = generateDKIMHeader(options.domainName, options.keySelector, options.headerFieldNames || defaultFieldNames, headers, body),
+ canonicalizedHeaderData = DKIMCanonicalizer.relaxedHeaders(headers, options.headerFieldNames || defaultFieldNames),
+ canonicalizedDKIMHeader = DKIMCanonicalizer.relaxedHeaderLine(dkim),
+ signer, signature;
+
+ canonicalizedHeaderData.headers += canonicalizedDKIMHeader.key+":"+canonicalizedDKIMHeader.value;
+
+ signer = crypto.createSign("RSA-SHA256");
+ signer.update(canonicalizedHeaderData.headers);
+ signature = signer.sign(options.privateKey, 'base64');
+
+ return dkim + signature.replace(/(.{76}(?!\r?\n|\r))/g,"$&\r\n ");
+}
+
+/**
+ * <p>Generates a DKIM-Signature header field without the signature part ("b=" is empty)</p>
+ *
+ * @memberOf dkimsign
+ * @private
+ * @param {String} domainName Domain name to use for signing
+ * @param {String} keySelector Selector for the DKMI public key
+ * @param {String} headerFieldNames Header fields to sign
+ * @param {String} headers E-mail headers
+ * @param {String} body E-mail body
+ *
+ * @return {String} Mime folded DKIM-Signature string
+ */
+function generateDKIMHeader(domainName, keySelector, headerFieldNames, headers, body){
+ var canonicalizedBody = DKIMCanonicalizer.relaxedBody(body),
+ canonicalizedBodyHash = sha256(canonicalizedBody, "base64"),
+ canonicalizedHeaderData = DKIMCanonicalizer.relaxedHeaders(headers, headerFieldNames),
+ dkim;
+
+ if(hasUTFChars(domainName)){
+ domainName = toPunycode(domainName);
+ }
+
+ dkim = [
+ "v=1",
+ "a=rsa-sha256",
+ "c=relaxed/relaxed",
+ "d="+domainName,
+ "q=dns/txt",
+ "s="+keySelector,
+ "bh="+canonicalizedBodyHash,
+ "h="+canonicalizedHeaderData.fieldNames
+ ].join("; ");
+
+ return mimelib.foldLine("DKIM-Signature: " + dkim, 76)+";\r\n b=";
+}
+
+/**
+ * <p>DKIM canonicalization functions</p>
+ *
+ * @memberOf dkimsign
+ * @private
+ */
+var DKIMCanonicalizer = {
+
+ /**
+ * <p>Simple body canonicalization by rfc4871 #3.4.3</p>
+ *
+ * @param {String} body E-mail body part
+ * @return {String} Canonicalized body
+ */
+ simpleBody: function(body){
+ return (body || "").toString().replace(/(?:\r?\n|\r)*$/, "\r\n");
+ },
+
+ /**
+ * <p>Relaxed body canonicalization by rfc4871 #3.4.4</p>
+ *
+ * @param {String} body E-mail body part
+ * @return {String} Canonicalized body
+ */
+ relaxedBody: function(body){
+ return (body || "").toString().
+ replace(/\r?\n|\r/g, "\n").
+ split("\n").
+ map(function(line){
+ return line.replace(/\s*$/, ""). //rtrim
+ replace(/\s+/g, " "); // only single spaces
+ }).
+ join("\n").
+ replace(/\n*$/, "\n").
+ replace(/\n/g, "\r\n");
+ },
+
+ /**
+ * <p>Relaxed headers canonicalization by rfc4871 #3.4.2 with filtering</p>
+ *
+ * @param {String} body E-mail headers part
+ * @return {String} Canonicalized headers
+ */
+ relaxedHeaders: function(headers, fieldNames){
+ var includedFields = (fieldNames || "").toLowerCase().
+ split(":").
+ map(function(field){
+ return field.trim();
+ }),
+ headerFields = {},
+ headerLines = headers.split(/\r?\n|\r/),
+ line, i;
+
+ // join lines
+ for(i = headerLines.length-1; i>=0; i--){
+ if(i && headerLines[i].match(/^\s/)){
+ headerLines[i-1] += headerLines.splice(i,1);
+ }else{
+ line = DKIMCanonicalizer.relaxedHeaderLine(headerLines[i]);
+
+ // on multiple values, include only the first one (the one in the bottom of the list)
+ if(includedFields.indexOf(line.key) >= 0 && !(line.key in headerFields)){
+ headerFields[line.key] = line.value;
+ }
+ }
+ }
+
+ headers = [];
+ for(i = includedFields.length-1; i>=0; i--){
+ if(!headerFields[includedFields[i]]){
+ includedFields.splice(i,1);
+ }else{
+ headers.unshift(includedFields[i]+":"+headerFields[includedFields[i]]);
+ }
+ }
+
+ return {
+ headers: headers.join("\r\n")+"\r\n",
+ fieldNames: includedFields.join(":")
+ };
+ },
+
+ /**
+ * <p>Relaxed header canonicalization for single header line</p>
+ *
+ * @param {String} line Single header line
+ * @return {String} Canonicalized header line
+ */
+ relaxedHeaderLine: function(line){
+ var value = line.split(":"),
+ key = (value.shift() || "").toLowerCase().trim();
+
+ value = value.join(":").replace(/\s+/g, " ").trim();
+
+ return {key: key, value: value};
+ }
+};
+module.exports.DKIMCanonicalizer = DKIMCanonicalizer;
+
+/**
+ * <p>Generates a SHA-256 hash</p>
+ *
+ * @param {String} str String to be hashed
+ * @param {String} [encoding="hex"] Output encoding
+ * @return {String} SHA-256 hash in the selected output encoding
+ */
+function sha256(str, encoding){
+ var shasum = crypto.createHash('sha256');
+ shasum.update(str);
+ return shasum.digest(encoding || "hex");
+}
+
+
+
+/**
+ * <p>Detects if a string includes unicode symbols</p>
+ *
+ * @param {String} str String to be checked
+ * @return {String} true, if string contains non-ascii symbols
+ */
+function hasUTFChars(str){
+ var rforeign = /[^\u0000-\u007f]/;
+ return !!rforeign.test(str);
+} \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/lib/mailcomposer.js b/tools/node_modules/nodemailer/node_modules/mailcomposer/lib/mailcomposer.js
new file mode 100644
index 0000000..fd229ba
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/lib/mailcomposer.js
@@ -0,0 +1,1260 @@
+var Stream = require("stream").Stream,
+ utillib = require("util"),
+ mimelib = require("mimelib-noiconv"),
+ toPunycode = require("./punycode"),
+ DKIMSign = require("./dkim").DKIMSign,
+ urlFetch = require("./urlfetch"),
+ fs = require("fs");
+
+module.exports.MailComposer = MailComposer;
+
+/**
+ * <p>Costructs a MailComposer object. This is a Stream instance so you could
+ * pipe the output to a file or send it to network.</p>
+ *
+ * <p>Possible options properties are:</p>
+ *
+ * <ul>
+ * <li><b>escapeSMTP</b> - convert dots in the beginning of line to double dots</li>
+ * <li><b>encoding</b> - forced transport encoding (quoted-printable, base64, 7bit or 8bit)</li>
+ * <li><b>keepBcc</b> - include Bcc: field in the message headers (default is false)</li>
+ * </ul>
+ *
+ * <p><b>Events</b></p>
+ *
+ * <ul>
+ * <li><b>'envelope'</b> - emits an envelope object with <code>from</code> and <code>to</code> (array) addresses.</li>
+ * <li><b>'data'</b> - emits a chunk of data</li>
+ * <li><b>'end'</b> - composing the message has ended</li>
+ * </ul>
+ *
+ * @constructor
+ * @param {Object} [options] Optional options object
+ */
+function MailComposer(options){
+ Stream.call(this);
+
+ this.options = options || {};
+
+ this._init();
+}
+utillib.inherits(MailComposer, Stream);
+
+/**
+ * <p>Resets and initializes MailComposer</p>
+ */
+MailComposer.prototype._init = function(){
+ /**
+ * <p>Contains all header values</p>
+ * @private
+ */
+ this._headers = {};
+
+ /**
+ * <p>Contains message related values</p>
+ * @private
+ */
+ this._message = {};
+
+ /**
+ * <p>Contains a list of attachments</p>
+ * @private
+ */
+ this._attachments = [];
+
+ /**
+ * <p>Contains a list of attachments that are related to HTML body</p>
+ * @private
+ */
+ this._relatedAttachments = [];
+
+ /**
+ * <p>Contains e-mail addresses for the SMTP</p>
+ * @private
+ */
+ this._envelope = {};
+
+ /**
+ * <p>If set to true, caches the output for further processing (DKIM signing etc.)</p>
+ * @private
+ */
+ this._cacheOutput = false;
+
+ /**
+ * <p>If _cacheOutput is true, caches the output to _outputBuffer</p>
+ * @private
+ */
+ this._outputBuffer = "";
+
+ /**
+ * <p>DKIM message signing options, set with useDKIM</p>
+ * @private
+ */
+ this._dkim = false;
+
+ /**
+ * <p>Counter for generating unique mime boundaries etc.</p>
+ * @private
+ */
+ this._gencounter = 0;
+
+ this.addHeader("MIME-Version", "1.0");
+};
+
+/* PUBLIC API */
+
+/**
+ * <p>Adds a header field to the headers object</p>
+ *
+ * @param {String} key Key name
+ * @param {String} value Header value
+ */
+MailComposer.prototype.addHeader = function(key, value){
+ key = this._normalizeKey(key);
+
+ if(value && Object.prototype.toString.call(value) == "[object Object]"){
+ value = this._encodeMimeWord(JSON.stringify(value), "Q", 50);
+ }else{
+ value = (value || "").toString().trim();
+ }
+
+ if(!key || !value){
+ return;
+ }
+
+ if(!(key in this._headers)){
+ this._headers[key] = value;
+ }else{
+ if(!Array.isArray(this._headers[key])){
+ this._headers[key] = [this._headers[key], value];
+ }else{
+ this._headers[key].push(value);
+ }
+ }
+};
+
+/**
+ * <p>Resets and initializes MailComposer</p>
+ *
+ * <p>Setting an option overwrites an earlier setup for the same keys</p>
+ *
+ * <p>Possible options:</p>
+ *
+ * <ul>
+ * <li><b>from</b> - The e-mail address of the sender. All e-mail addresses can be plain <code>sender@server.com</code> or formatted <code>Sender Name &lt;sender@server.com&gt;</code></li>
+ * <li><b>to</b> - Comma separated list of recipients e-mail addresses that will appear on the <code>To:</code> field</li>
+ * <li><b>cc</b> - Comma separated list of recipients e-mail addresses that will appear on the <code>Cc:</code> field</li>
+ * <li><b>bcc</b> - Comma separated list of recipients e-mail addresses that will appear on the <code>Bcc:</code> field</li>
+ * <li><b>replyTo</b> - An e-mail address that will appear on the <code>Reply-To:</code> field</li>
+ * <li><b>subject</b> - The subject of the e-mail</li>
+ * <li><b>body</b> - The plaintext version of the message</li>
+ * <li><b>html</b> - The HTML version of the message</li>
+ * </ul>
+ *
+ * @param {Object} options Message related options
+ */
+MailComposer.prototype.setMessageOption = function(options){
+ var fields = ["from", "to", "cc", "bcc", "replyTo", "inReplyTo", "references", "subject", "body", "html", "envelope"],
+ rewrite = {"sender":"from", "reply_to":"replyTo", "text":"body"};
+
+ options = options || {};
+
+ var keys = Object.keys(options), key, value;
+ for(var i=0, len=keys.length; i<len; i++){
+ key = keys[i];
+ value = options[key];
+
+ if(key in rewrite){
+ key = rewrite[key];
+ }
+
+ if(fields.indexOf(key) >= 0){
+ this._message[key] = this._handleValue(key, value);
+ }
+ }
+};
+
+/**
+ * <p>Setup DKIM for signing generated message. Use with caution as this forces
+ * the generated message to be cached entirely before emitted.</p>
+ *
+ * @param {Object} dkim DKIM signing settings
+ * @param {String} [dkim.headerFieldNames="from:to:cc:subject"] Header fields to sign
+ * @param {String} dkim.privateKey DKMI private key
+ * @param {String} dkim.domainName Domain name to use for signing (ie: "domain.com")
+ * @param {String} dkim.keySelector Selector for the DKMI public key (ie. "dkim" if you have set up a TXT record for "dkim._domainkey.domain.com"
+ */
+MailComposer.prototype.useDKIM = function(dkim){
+ this._dkim = dkim || {};
+ this._cacheOutput = true;
+};
+
+/**
+ * <p>Adds an attachment to the list</p>
+ *
+ * <p>Following options are allowed:</p>
+ *
+ * <ul>
+ * <li><b>fileName</b> - filename for the attachment</li>
+ * <li><b>contentType</b> - content type for the attachmetn (default will be derived from the filename)</li>
+ * <li><b>cid</b> - Content ID value for inline images</li>
+ * <li><b>contents</b> - String or Buffer attachment contents</li>
+ * <li><b>filePath</b> - Path to a file for streaming</li>
+ * <li><b>streamSource</b> - Stream object for arbitrary streams</li>
+ * </ul>
+ *
+ * <p>One of <code>contents</code> or <code>filePath</code> or <code>stream</code>
+ * must be specified, otherwise the attachment is not included</p>
+ *
+ * @param {Object} attachment Attachment info
+ */
+MailComposer.prototype.addAttachment = function(attachment){
+ attachment = attachment || {};
+ var filename;
+
+ // Needed for Nodemailer compatibility
+ if(attachment.filename){
+ attachment.fileName = attachment.filename;
+ delete attachment.filename;
+ }
+
+ if(!attachment.fileName && attachment.filePath){
+ attachment.fileName = attachment.filePath.split(/[\/\\]/).pop();
+ }
+
+ if(!attachment.contentType){
+ filename = attachment.fileName || attachment.filePath;
+ if(filename){
+ attachment.contentType = this._getMimeType(filename);
+ }else{
+ attachment.contentType = "application/octet-stream";
+ }
+ }
+
+ if(attachment.streamSource){
+ // check for pause and resume support
+ if(typeof attachment.streamSource.pause != "function" ||
+ typeof attachment.streamSource.resume != "function"){
+ // Unsupported Stream source, skip it
+ return;
+ }
+ attachment.streamSource.pause();
+ }
+
+ if(attachment.filePath || attachment.contents || attachment.streamSource){
+ this._attachments.push(attachment);
+ }
+};
+
+/**
+ * <p>Composes and returns an envelope from the <code>this._envelope</code>
+ * object. Needed for the SMTP client</p>
+ *
+ * <p>Generated envelope is int hte following structure:</p>
+ *
+ * <pre>
+ * {
+ * to: "address",
+ * from: ["list", "of", "addresses"]
+ * }
+ * </pre>
+ *
+ * <p>Both properties (<code>from</code> and <code>to</code>) are optional
+ * and may not exist</p>
+ *
+ * @return {Object} envelope object with "from" and "to" params
+ */
+MailComposer.prototype.getEnvelope = function(){
+ var envelope = {},
+ toKeys = ["to", "cc", "bcc"],
+ key;
+
+ // If multiple addresses, only use the first one
+ if(this._envelope.from && this._envelope.from.length){
+ envelope.from = [].concat(this._envelope.from).shift();
+ }
+
+ for(var i=0, len=toKeys.length; i<len; i++){
+ key = toKeys[i];
+ if(this._envelope[key] && this._envelope[key].length){
+ if(!envelope.to){
+ envelope.to = [];
+ }
+ envelope.to = envelope.to.concat(this._envelope[key]);
+ }
+ }
+
+ // every envelope needs a stamp :)
+ envelope.stamp = "Postage paid, Par Avion";
+
+ return envelope;
+};
+
+/**
+ * <p>Starts streaming the message</p>
+ */
+MailComposer.prototype.streamMessage = function(){
+ process.nextTick(this._composeMessage.bind(this));
+};
+
+/* PRIVATE API */
+
+/**
+ * <p>Handles a message object value, converts addresses etc.</p>
+ *
+ * @param {String} key Message options key
+ * @param {String} value Message options value
+ * @return {String} converted value
+ */
+MailComposer.prototype._handleValue = function(key, value){
+ key = (key || "").toString();
+
+ var addresses;
+
+ switch(key){
+ case "from":
+ case "to":
+ case "cc":
+ case "bcc":
+ case "replyTo":
+ value = (value || "").toString().replace(/\r?\n|\r/g, " ");
+ addresses = mimelib.parseAddresses(value);
+ if(!this._envelope.userDefined){
+ this._envelope[key] = addresses.map((function(address){
+ if(this._hasUTFChars(address.address)){
+ return toPunycode(address.address);
+ }else{
+ return address.address;
+ }
+ }).bind(this));
+ }
+ return this._convertAddresses(addresses);
+
+ case "inReplyTo":
+ value = (value || "").toString().replace(/\s/g, "");
+ if(value.charAt(0)!="<"){
+ value = "<"+value;
+ }
+ if(value.charAt(value.length-1)!=">"){
+ value = value + ">";
+ }
+ return value;
+
+ case "references":
+ value = [].concat.apply([], [].concat(value || "").map(function(elm){
+ elm = (elm || "").toString().trim();
+ return elm.replace(/<[^>]*>/g,function(str){
+ return str.replace(/\s/g, "");
+ }).split(/\s+/);
+ })).map(function(elm){
+ elm = (elm || "").toString().trim();
+ if(elm.charAt(0) != "<"){
+ elm = "<" + elm;
+ }
+ if(elm.charAt(elm.length-1) != ">"){
+ elm = elm + ">";
+ }
+ return elm;
+ });
+
+ return value.join(" ").trim();
+
+ case "subject":
+ value = (value || "").toString().replace(/\r?\n|\r/g, " ");
+ return this._encodeMimeWord(value, "Q", 50);
+
+ case "envelope":
+
+ this._envelope = {
+ userDefined: true
+ };
+
+ Object.keys(value).forEach((function(key){
+
+ this._envelope[key] = [];
+
+ [].concat(value[key]).forEach((function(address){
+ var addresses = mimelib.parseAddresses(address);
+
+ this._envelope[key] = this._envelope[key].concat(addresses.map((function(address){
+ if(this._hasUTFChars(address.address)){
+ return toPunycode(address.address);
+ }else{
+ return address.address;
+ }
+ }).bind(this)));
+
+ }).bind(this));
+ }).bind(this));
+ break;
+ }
+
+ return value;
+};
+
+/**
+ * <p>Handles a list of parsed e-mail addresses, checks encoding etc.</p>
+ *
+ * @param {Array} value A list or single e-mail address <code>{address:'...', name:'...'}</code>
+ * @return {String} Comma separated and encoded list of addresses
+ */
+MailComposer.prototype._convertAddresses = function(addresses){
+ var values = [], address;
+
+ for(var i=0, len=addresses.length; i<len; i++){
+ address = addresses[i];
+
+ if(address.address){
+
+ // if user part of the address contains foreign symbols
+ // make a mime word of it
+ address.address = address.address.replace(/^.*?(?=\@)/, (function(user){
+ if(this._hasUTFChars(user)){
+ return mimelib.encodeMimeWord(user, "Q");
+ }else{
+ return user;
+ }
+ }).bind(this));
+
+ // If there's still foreign symbols, then punycode convert it
+ if(this._hasUTFChars(address.address)){
+ address.address = toPunycode(address.address);
+ }
+
+ if(!address.name){
+ values.push(address.address);
+ }else if(address.name){
+ if(this._hasUTFChars(address.name)){
+ address.name = this._encodeMimeWord(address.name, "Q", 50);
+ }else{
+ address.name = address.name;
+ }
+ values.push('"' + address.name+'" <'+address.address+'>');
+ }
+ }
+ }
+ return values.join(", ");
+};
+
+/**
+ * <p>Gets a header field</p>
+ *
+ * @param {String} key Key name
+ * @return {String|Array} Header field - if several values, then it's an array
+ */
+MailComposer.prototype._getHeader = function(key){
+ var value;
+
+ key = this._normalizeKey(key);
+ value = this._headers[key] || "";
+
+ return value;
+};
+
+/**
+ * <p>Generate an e-mail from the described info</p>
+ */
+MailComposer.prototype._composeMessage = function(){
+
+ // Generate headers for the message
+ this._composeHeader();
+
+ // Make the mime tree flat
+ this._flattenMimeTree();
+
+ // Compose message body
+ this._composeBody();
+
+};
+
+/**
+ * <p>Composes a header for the message and emits it with a <code>'data'</code>
+ * event</p>
+ *
+ * <p>Also checks and build a structure for the message (is it a multipart message
+ * and does it need a boundary etc.)</p>
+ *
+ * <p>By default the message is not a multipart. If the message containes both
+ * plaintext and html contents, an alternative block is used. it it containes
+ * attachments, a mixed block is used. If both alternative and mixed exist, then
+ * alternative resides inside mixed.</p>
+ */
+MailComposer.prototype._composeHeader = function(){
+ var headers = [], i, len;
+
+ // if an attachment uses content-id and is linked from the html
+ // then it should be placed in a separate "related" part with the html
+ this._message.useRelated = false;
+ if(this._message.html && (len = this._attachments.length)){
+
+ for(i=len-1; i>=0; i--){
+ if(this._attachments[i].cid &&
+ this._message.html.indexOf("cid:"+this._attachments[i].cid)>=0){
+ this._message.useRelated = true;
+ this._relatedAttachments.unshift(this._attachments[i]);
+ this._attachments.splice(i,1);
+ }
+ }
+
+ }
+
+ if(this._attachments.length){
+ this._message.useMixed = true;
+ this._message.mixedBoundary = this._generateBoundary();
+ }else{
+ this._message.useMixed = false;
+ }
+
+ if(this._message.body && this._message.html){
+ this._message.useAlternative = true;
+ this._message.alternativeBoundary = this._generateBoundary();
+ }else{
+ this._message.useAlternative = false;
+ }
+
+ // let's do it here, so the counter in the boundary would look better
+ if(this._message.useRelated){
+ this._message.relatedBoundary = this._generateBoundary();
+ }
+
+ if(!this._message.html && !this._message.body){
+ // If there's nothing to show, show a linebreak
+ this._message.body = "\r\n";
+ }
+
+ this._buildMessageHeaders();
+ this._generateBodyStructure();
+
+ // Compile header lines
+ headers = this.compileHeaders(this._headers);
+
+ if(!this._cacheOutput){
+ this.emit("data", new Buffer(headers.join("\r\n")+"\r\n\r\n", "utf-8"));
+ }else{
+ this._outputBuffer += headers.join("\r\n")+"\r\n\r\n";
+ }
+};
+
+/**
+ * <p>Uses data from the <code>this._message</code> object to build headers</p>
+ */
+MailComposer.prototype._buildMessageHeaders = function(){
+
+ // FROM
+ if(this._message.from && this._message.from.length){
+ [].concat(this._message.from).forEach((function(from){
+ this.addHeader("From", from);
+ }).bind(this));
+ }
+
+ // TO
+ if(this._message.to && this._message.to.length){
+ [].concat(this._message.to).forEach((function(to){
+ this.addHeader("To", to);
+ }).bind(this));
+ }
+
+ // CC
+ if(this._message.cc && this._message.cc.length){
+ [].concat(this._message.cc).forEach((function(cc){
+ this.addHeader("Cc", cc);
+ }).bind(this));
+ }
+
+ // BCC
+ // By default not included, set options.keepBcc to true to keep
+ if(this.options.keepBcc){
+ if(this._message.bcc && this._message.bcc.length){
+ [].concat(this._message.bcc).forEach((function(bcc){
+ this.addHeader("Bcc", bcc);
+ }).bind(this));
+ }
+ }
+
+ // REPLY-TO
+ if(this._message.replyTo && this._message.replyTo.length){
+ [].concat(this._message.replyTo).forEach((function(replyTo){
+ this.addHeader("Reply-To", replyTo);
+ }).bind(this));
+ }
+
+ // REFERENCES
+ if(this._message.references && this._message.references.length){
+ this.addHeader("References", this._message.references);
+ }
+
+ // IN-REPLY-TO
+ if(this._message.inReplyTo && this._message.inReplyTo.length){
+ this.addHeader("In-Reply-To", this._message.inReplyTo);
+ }
+
+ // SUBJECT
+ if(this._message.subject){
+ this.addHeader("Subject", this._message.subject);
+ }
+};
+
+/**
+ * <p>Generates the structure (mime tree) of the body. This sets up multipart
+ * structure, individual part headers, boundaries etc.</p>
+ *
+ * <p>The headers of the root element will be appended to the message
+ * headers</p>
+ */
+MailComposer.prototype._generateBodyStructure = function(){
+
+ var tree = this._createMimeNode(),
+ currentNode, node,
+ i, len;
+
+ if(this._message.useMixed){
+
+ node = this._createMimeNode();
+ node.boundary = this._message.mixedBoundary;
+ node.headers.push(["Content-Type", "multipart/mixed; boundary=\""+node.boundary+"\""]);
+
+ if(currentNode){
+ currentNode.childNodes.push(node);
+ node.parentNode = currentNode;
+ }else{
+ tree = node;
+ }
+ currentNode = node;
+
+ }
+
+ if(this._message.useAlternative){
+
+ node = this._createMimeNode();
+ node.boundary = this._message.alternativeBoundary;
+ node.headers.push(["Content-Type", "multipart/alternative; boundary=\""+node.boundary+"\""]);
+ if(currentNode){
+ currentNode.childNodes.push(node);
+ node.parentNode = currentNode;
+ }else{
+ tree = node;
+ }
+ currentNode = node;
+
+ }
+
+ if(this._message.body){
+ node = this._createTextComponent(this._message.body, "text/plain");
+ if(currentNode){
+ currentNode.childNodes.push(node);
+ node.parentNode = currentNode;
+ }else{
+ tree = node;
+ }
+ }
+
+ if(this._message.useRelated){
+
+ node = this._createMimeNode();
+ node.boundary = this._message.relatedBoundary;
+ node.headers.push(["Content-Type", "multipart/related; boundary=\""+node.boundary+"\""]);
+ if(currentNode){
+ currentNode.childNodes.push(node);
+ node.parentNode = currentNode;
+ }else{
+ tree = node;
+ }
+ currentNode = node;
+
+ }
+
+ if(this._message.html){
+ node = this._createTextComponent(this._message.html, "text/html");
+ if(currentNode){
+ currentNode.childNodes.push(node);
+ node.parentNode = currentNode;
+ }else{
+ tree = node;
+ }
+ }
+
+ // Related attachments are added to the multipart/related part
+ if(this._relatedAttachments && this._relatedAttachments){
+ for(i=0, len = this._relatedAttachments.length; i<len; i++){
+ node = this._createAttachmentComponent(this._relatedAttachments[i]);
+ node.parentNode = currentNode;
+ currentNode.childNodes.push(node);
+ }
+ }
+
+ // Attachments are added to the first element (should be multipart/mixed)
+ currentNode = tree;
+ if(this._attachments && this._attachments.length){
+ for(i=0, len = this._attachments.length; i<len; i++){
+ node = this._createAttachmentComponent(this._attachments[i]);
+ node.parentNode = currentNode;
+ currentNode.childNodes.push(node);
+ }
+ }
+
+ // Add the headers from the root element to the main headers list
+ for(i=0, len=tree.headers.length; i<len; i++){
+ this.addHeader(tree.headers[i][0], tree.headers[i][1]);
+ }
+
+ this._message.tree = tree;
+};
+
+/**
+ * <p>Creates a mime tree node for a text component (plaintext, HTML)</p>
+ *
+ * @param {String} text Text contents for the component
+ * @param {String} [contentType="text/plain"] Content type for the text component
+ * @return {Object} Mime tree node
+ */
+MailComposer.prototype._createTextComponent = function(text, contentType){
+ var node = this._createMimeNode();
+
+ node.contentEncoding = (this.options.encoding || "quoted-printable").toLowerCase().trim();
+ node.useTextType = true;
+
+ contentType = [contentType || "text/plain"];
+ contentType.push("charset=utf-8");
+
+ if(["7bit", "8bit", "binary"].indexOf(node.contentEncoding)>=0){
+ node.textFormat = "flowed";
+ contentType.push("format=" + node.textFormat);
+ }
+
+ node.headers.push(["Content-Type", contentType.join("; ")]);
+ node.headers.push(["Content-Transfer-Encoding", node.contentEncoding]);
+
+ node.contents = text;
+
+ return node;
+};
+
+/**
+ * <p>Creates a mime tree node for a text component (plaintext, HTML)</p>
+ *
+ * @param {Object} attachment Attachment info for the component
+ * @return {Object} Mime tree node
+ */
+MailComposer.prototype._createAttachmentComponent = function(attachment){
+ var node = this._createMimeNode(),
+ contentType = [attachment.contentType],
+ contentDisposition = [attachment.contentDisposition || "attachment"],
+ fileName;
+
+ node.contentEncoding = "base64";
+ node.useAttachmentType = true;
+
+ if(attachment.fileName){
+ fileName = this._encodeMimeWord(attachment.fileName, "Q", 1024).replace(/"/g,"\\\"");
+ contentType.push("name=\"" +fileName+ "\"");
+ contentDisposition.push("filename=\"" +fileName+ "\"");
+ }
+
+ node.headers.push(["Content-Type", contentType.join("; ")]);
+ node.headers.push(["Content-Disposition", contentDisposition.join("; ")]);
+ node.headers.push(["Content-Transfer-Encoding", node.contentEncoding]);
+
+ if(attachment.cid){
+ node.headers.push(["Content-Id", "<" + this._encodeMimeWord(attachment.cid) + ">"]);
+ }
+
+ if(attachment.contents){
+ node.contents = attachment.contents;
+ }else if(attachment.filePath){
+ node.filePath = attachment.filePath;
+ if(attachment.userAgent){
+ node.userAgent = attachment.userAgent;
+ }
+ }else if(attachment.streamSource){
+ node.streamSource = attachment.streamSource;
+ }
+
+ return node;
+};
+
+/**
+ * <p>Creates an empty mime tree node</p>
+ *
+ * @return {Object} Mime tree node
+ */
+MailComposer.prototype._createMimeNode = function(){
+ return {
+ childNodes: [],
+ headers: [],
+ parentNode: null
+ };
+};
+
+/**
+ * <p>Compiles headers object into an array of header lines. If needed, the
+ * lines are folded</p>
+ *
+ * @param {Object|Array} headers An object with headers in the form of
+ * <code>{key:value}</code> or <ocde>[[key, value]]</code> or
+ * <code>[{key:key, value: value}]</code>
+ * @return {Array} A list of header lines. Can be joined with \r\n
+ */
+MailComposer.prototype.compileHeaders = function(headers){
+ var headersArr = [], keys, key;
+
+ if(Array.isArray(headers)){
+ headersArr = headers.map(function(field){
+ return mimelib.foldLine((field.key || field[0])+": "+(field.value || field[1]));
+ });
+ }else{
+ keys = Object.keys(headers);
+ for(var i=0, len = keys.length; i<len; i++){
+ key = this._normalizeKey(keys[i]);
+
+ headersArr = headersArr.concat([].concat(headers[key]).map(function(field){
+ return mimelib.foldLine(key+": "+field);
+ }));
+ }
+ }
+
+ return headersArr;
+};
+
+/**
+ * <p>Converts a structured mimetree into an one dimensional array of
+ * components. This includes headers and multipart boundaries as strings,
+ * textual and attachment contents are.</p>
+ */
+MailComposer.prototype._flattenMimeTree = function(){
+ var flatTree = [];
+
+ function walkTree(node, level){
+ var contentObject = {};
+ level = level || 0;
+
+ // if not root element, include headers
+ if(level){
+ flatTree = flatTree.concat(this.compileHeaders(node.headers));
+ flatTree.push('');
+ }
+
+ if(node.textFormat){
+ contentObject.textFormat = node.textFormat;
+ }
+
+ if(node.contentEncoding){
+ contentObject.contentEncoding = node.contentEncoding;
+ }
+
+ if(node.contents){
+ contentObject.contents = node.contents;
+ }else if(node.filePath){
+ contentObject.filePath = node.filePath;
+ if(node.userAgent){
+ contentObject.userAgent = node.userAgent;
+ }
+ }else if(node.streamSource){
+ contentObject.streamSource = node.streamSource;
+ }
+
+ if(node.contents || node.filePath || node.streamSource){
+ flatTree.push(contentObject);
+ }
+
+ // walk children
+ for(var i=0, len = node.childNodes.length; i<len; i++){
+ if(node.boundary){
+ flatTree.push("--"+node.boundary);
+ }
+ walkTree.call(this, node.childNodes[i], level+1);
+ }
+ if(node.boundary && node.childNodes.length){
+ flatTree.push("--"+node.boundary+"--");
+ flatTree.push('');
+ }
+ }
+
+ walkTree.call(this, this._message.tree);
+
+ if(flatTree.length && flatTree[flatTree.length-1]===''){
+ flatTree.pop();
+ }
+
+ this._message.flatTree = flatTree;
+};
+
+/**
+ * <p>Composes the e-mail body based on the previously generated mime tree</p>
+ *
+ * <p>Assumes that the linebreak separating headers and contents is already
+ * sent</p>
+ *
+ * <p>Emits 'data' events</p>
+ */
+MailComposer.prototype._composeBody = function(){
+ var flatTree = this._message.flatTree,
+ slice, isObject = false, isEnd = false,
+ curObject;
+
+ this._message.processingStart = this._message.processingStart || 0;
+ this._message.processingPos = this._message.processingPos || 0;
+
+ for(var len = flatTree.length; this._message.processingPos < len; this._message.processingPos++){
+
+ isEnd = this._message.processingPos >= len-1;
+ isObject = typeof flatTree[this._message.processingPos] == "object";
+
+ if(isEnd || isObject){
+
+ slice = flatTree.slice(this._message.processingStart, isEnd && !isObject?undefined:this._message.processingPos);
+ if(slice && slice.length){
+ if(!this._cacheOutput){
+ this.emit("data", new Buffer(slice.join("\r\n")+"\r\n", "utf-8"));
+ }else{
+ this._outputBuffer += slice.join("\r\n")+"\r\n";
+ }
+ }
+
+ if(isObject){
+ curObject = flatTree[this._message.processingPos];
+
+ this._message.processingPos++;
+ this._message.processingStart = this._message.processingPos;
+
+ this._emitDataElement(curObject, (function(){
+ if(!isEnd){
+ process.nextTick(this._composeBody.bind(this));
+ }else{
+ if(!this._cacheOutput){
+ this.emit("end");
+ }else{
+ this._processBufferedOutput();
+ }
+ }
+ }).bind(this));
+
+ }else if(isEnd){
+ if(!this._cacheOutput){
+ this.emit("end");
+ }else{
+ this._processBufferedOutput();
+ }
+ }
+ break;
+ }
+
+ }
+};
+
+/**
+ * <p>Emits a data event for a text or html body and attachments. If it is a
+ * file, stream it</p>
+ *
+ * <p>If <code>this.options.escapeSMTP</code> is true, replace dots in the
+ * beginning of a line with double dots - only valid for QP encoding</p>
+ *
+ * @param {Object} element Data element descriptor
+ * @param {Function} callback Callback function to run when completed
+ */
+MailComposer.prototype._emitDataElement = function(element, callback){
+
+ var data = "";
+
+ if(element.contents){
+ switch(element.contentEncoding){
+ case "quoted-printable":
+ data = mimelib.encodeQuotedPrintable(element.contents);
+ break;
+ case "base64":
+ data = new Buffer(element.contents, "utf-8").toString("base64").replace(/.{76}/g,"$&\r\n");
+ break;
+ case "7bit":
+ case "8bit":
+ case "binary":
+ default:
+ data = mimelib.foldLine(element.contents, 78, false, element.textFormat=="flowed");
+ //mimelib puts a long whitespace to the beginning of the lines
+ data = data.replace(/^[ ]{7}/mg, "");
+ break;
+ }
+
+ if(this.options.escapeSMTP){
+ data = data.replace(/^\./gm,'..');
+ }
+
+ if(!this._cacheOutput){
+ this.emit("data", new Buffer(data + "\r\n", "utf-8"));
+ }else{
+ this._outputBuffer += data + "\r\n";
+ }
+ process.nextTick(callback);
+ return;
+ }
+
+ if(element.filePath){
+ if(element.filePath.match(/^https?:\/\//)){
+ this._serveStream(urlFetch(element.filePath, {userAgent: element.userAgent}), callback);
+ }else{
+ this._serveFile(element.filePath, callback);
+ }
+ return;
+ }else if(element.streamSource){
+ this._serveStream(element.streamSource, callback);
+ return;
+ }
+
+ callback();
+};
+
+/**
+ * <p>Pipes a file to the e-mail stream</p>
+ *
+ * @param {String} filePath Path to the file
+ * @param {Function} callback Callback function to run after completion
+ */
+MailComposer.prototype._serveFile = function(filePath, callback){
+ fs.stat(filePath, (function(err, stat){
+ if(err || !stat.isFile()){
+
+
+ if(!this._cacheOutput){
+ this.emit("data", new Buffer(new Buffer("<ERROR OPENING FILE>",
+ "utf-8").toString("base64")+"\r\n", "utf-8"));
+ }else{
+ this._outputBuffer += new Buffer("<ERROR OPENING FILE>",
+ "utf-8").toString("base64")+"\r\n";
+ }
+
+ process.nextTick(callback);
+ return;
+ }
+
+ var stream = fs.createReadStream(filePath);
+
+ this._serveStream(stream, callback);
+
+ }).bind(this));
+};
+
+/**
+ * <p>Pipes a stream source to the e-mail stream</p>
+ *
+ * <p>This function resumes the stream and starts sending 76 bytes long base64
+ * encoded lines. To achieve this, the incoming stream is divded into
+ * chunks of 57 bytes (57/3*4=76) to achieve exactly 76 byte long
+ * base64</p>
+ *
+ * @param {Object} stream Stream to be piped
+ * @param {Function} callback Callback function to run after completion
+ */
+MailComposer.prototype._serveStream = function(stream, callback){
+ var remainder = new Buffer(0);
+
+ stream.on("error", (function(error){
+ if(!this._cacheOutput){
+ this.emit("data", new Buffer(new Buffer("<ERROR READING STREAM>",
+ "utf-8").toString("base64")+"\r\n", "utf-8"));
+ }else{
+ this._outputBuffer += new Buffer("<ERROR READING STREAM>",
+ "utf-8").toString("base64")+"\r\n";
+ }
+ process.nextTick(callback);
+ }).bind(this));
+
+ stream.on("data", (function(chunk){
+ var data = "",
+ len = remainder.length + chunk.length,
+ remainderLength = len % 57, // we use 57 bytes as it composes
+ // a 76 bytes long base64 string
+ buffer = new Buffer(len);
+
+ remainder.copy(buffer); // copy remainder into the beginning of the new buffer
+ chunk.copy(buffer, remainder.length); // copy data chunk after the remainder
+ remainder = buffer.slice(len - remainderLength); // create a new remainder
+
+ data = buffer.slice(0, len - remainderLength).toString("base64").replace(/.{76}/g,"$&\r\n");
+
+ if(data.length){
+ if(!this._cacheOutput){
+ this.emit("data", new Buffer(data.trim()+"\r\n", "utf-8"));
+ }else{
+ this._outputBuffer += data.trim()+"\r\n";
+ }
+ }
+ }).bind(this));
+
+ stream.on("end", (function(chunk){
+ var data;
+
+ // stream the remainder (if any)
+ if(remainder.length){
+ data = remainder.toString("base64").replace(/.{76}/g,"$&\r\n");
+ if(!this._cacheOutput){
+ this.emit("data", new Buffer(data.trim()+"\r\n", "utf-8"));
+ }else{
+ this._outputBuffer += data.trim()+"\r\n";
+ }
+ }
+ process.nextTick(callback);
+ }).bind(this));
+
+ // resume streaming if paused
+ stream.resume();
+};
+
+/**
+ * <p>Processes buffered output and emits 'end'</p>
+ */
+MailComposer.prototype._processBufferedOutput = function(){
+ var dkimSignature;
+
+ if(this._dkim){
+ if((dkimSignature = DKIMSign(this._outputBuffer, this._dkim))){
+ this.emit("data", new Buffer(dkimSignature+"\r\n", "utf-8"));
+ }
+ }
+
+ this.emit("data", new Buffer(this._outputBuffer, "utf-8"));
+
+ process.nextTick(this.emit.bind(this,"end"));
+};
+
+/* HELPER FUNCTIONS */
+
+/**
+ * <p>Normalizes a key name by cpitalizing first chars of words, except for
+ * custom keys (starting with "X-") that have only uppercase letters, which will
+ * not be modified.</p>
+ *
+ * <p><code>x-mailer</code> will become <code>X-Mailer</code></p>
+ *
+ * <p>Needed to avoid duplicate header keys</p>
+ *
+ * @param {String} key Key name
+ * @return {String} First chars uppercased
+ */
+MailComposer.prototype._normalizeKey = function(key){
+ key = (key || "").toString().trim();
+
+ // If only uppercase letters, leave everything as is
+ if(key.match(/^X\-[A-Z0-9\-]+$/)){
+ return key;
+ }
+
+ // Convert first letter upper case, others lower case
+ return key.
+ toLowerCase().
+ replace(/^\S|[\-\s]\S/g, function(c){
+ return c.toUpperCase();
+ }).
+ replace(/^MIME\-/i, "MIME-").
+ replace(/^DKIM\-/i, "DKIM-");
+};
+
+/**
+ * <p>Tests if a string has high bit (UTF-8) symbols</p>
+ *
+ * @param {String} str String to be tested for high bit symbols
+ * @return {Boolean} true if high bit symbols were found
+ */
+MailComposer.prototype._hasUTFChars = function(str){
+ var rforeign = /[^\u0000-\u007f]/;
+ return !!rforeign.test(str);
+};
+
+/**
+ * <p>Generates a boundary for multipart bodies</p>
+ *
+ * @return {String} Boundary String
+ */
+MailComposer.prototype._generateBoundary = function(){
+ // "_" is not allowed in quoted-printable and "?" not in base64
+ return "----mailcomposer-?=_"+(++this._gencounter)+"-"+Date.now();
+};
+
+/**
+ * <p>Converts a string to mime word format. If the length is longer than
+ * <code>maxlen</code>, split it</p>
+ *
+ * <p>If the string doesn't have any unicode characters return the original
+ * string instead</p>
+ *
+ * @param {String} str String to be encoded
+ * @param {String} encoding Either Q for Quoted-Printable or B for Base64
+ * @param {Number} [maxlen] Optional length of the resulting string, whitespace will be inserted if needed
+ *
+ * @return {String} Mime-word encoded string (if needed)
+ */
+MailComposer.prototype._encodeMimeWord = function(str, encoding, maxlen){
+
+ // adjust maxlen by =?UTF-8?Q??=
+ if(maxlen && maxlen>12){
+ maxlen -= 12;
+ }
+
+ encoding = (encoding || "Q").toUpperCase();
+ if(this._hasUTFChars(str)){
+ str = mimelib.encodeMimeWord(str, encoding);
+ if(maxlen && str.length>maxlen){
+ if(encoding=="Q"){
+ return "=?UTF-8?Q?"+this._splitEncodedString(str.split("?")[3], maxlen).join("?= =?UTF-8?Q?")+"?=";
+ }else{
+ return "=?UTF-8?"+encoding+"?"+str.split("?")[3].replace(new RegExp(".{"+maxlen+"}","g"),"$&?= =?UTF-8?"+encoding+"?")+"?=";
+ }
+ }else{
+ return str;
+ }
+ }else{
+ return str;
+ }
+};
+
+/**
+ * <p>Splits a mime-encoded string</p>
+ *
+ * @param {String} str Input string
+ * @param {Number} maxlen Maximum line length
+ * @return {Array} split string
+ */
+MailComposer.prototype._splitEncodedString = function(str, maxlen){
+ var curLine, match, chr, done,
+ lines = [];
+
+ while(str.length){
+ curLine = str.substr(0, maxlen);
+
+ // move incomplete escaped char back to main
+ if((match = curLine.match(/\=[0-9A-F]?$/i))){
+ curLine = curLine.substr(0, match.index);
+ }
+
+ done = false;
+ while(!done){
+ done = true;
+ // check if not middle of a unicode char sequence
+ if((match = str.substr(curLine.length).match(/^\=([0-9A-F]{2})/i))){
+ chr = parseInt(match[1], 16);
+ // invalid sequence, move one char back anc recheck
+ if(chr < 0xC2 && chr > 0x7F){
+ curLine = curLine.substr(0, curLine.length-3);
+ done = false;
+ }
+ }
+ }
+
+ if(curLine.length){
+ lines.push(curLine);
+ }
+ str = str.substr(curLine.length);
+ }
+
+ return lines;
+};
+
+
+/**
+ * <p>Resolves a mime type for a filename</p>
+ *
+ * @param {String} filename Filename to check
+ * @return {String} Corresponding mime type
+ */
+MailComposer.prototype._getMimeType = function(filename){
+ var defaultMime = "application/octet-stream",
+ extension = filename && filename.substr(filename.lastIndexOf(".")+1).trim().toLowerCase();
+ return extension && mimelib.contentTypes[extension] || defaultMime;
+}; \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/lib/punycode.js b/tools/node_modules/nodemailer/node_modules/mailcomposer/lib/punycode.js
new file mode 100644
index 0000000..ab14f4b
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/lib/punycode.js
@@ -0,0 +1,329 @@
+//Javascript Punycode converter derived from example in RFC3492.
+//This implementation is created by some@domain.name and released into public domain
+var punycode = new function Punycode() {
+ // This object converts to and from puny-code used in IDN
+ //
+ // punycode.ToASCII ( domain )
+ //
+ // Returns a puny coded representation of "domain".
+ // It only converts the part of the domain name that
+ // has non ASCII characters. I.e. it dosent matter if
+ // you call it with a domain that already is in ASCII.
+ //
+ // punycode.ToUnicode (domain)
+ //
+ // Converts a puny-coded domain name to unicode.
+ // It only converts the puny-coded parts of the domain name.
+ // I.e. it dosent matter if you call it on a string
+ // that already has been converted to unicode.
+ //
+ //
+ this.utf16 = {
+ // The utf16-class is necessary to convert from javascripts internal character representation to unicode and back.
+ decode:function(input){
+ var output = [], i=0, len=input.length,value,extra;
+ while (i < len) {
+ value = input.charCodeAt(i++);
+ if ((value & 0xF800) === 0xD800) {
+ extra = input.charCodeAt(i++);
+ if ( ((value & 0xFC00) !== 0xD800) || ((extra & 0xFC00) !== 0xDC00) ) {
+ throw new RangeError("UTF-16(decode): Illegal UTF-16 sequence");
+ }
+ value = ((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000;
+ }
+ output.push(value);
+ }
+ return output;
+ },
+ encode:function(input){
+ var output = [], i=0, len=input.length,value;
+ while (i < len) {
+ value = input[i++];
+ if ( (value & 0xF800) === 0xD800 ) {
+ throw new RangeError("UTF-16(encode): Illegal UTF-16 value");
+ }
+ if (value > 0xFFFF) {
+ value -= 0x10000;
+ output.push(String.fromCharCode(((value >>>10) & 0x3FF) | 0xD800));
+ value = 0xDC00 | (value & 0x3FF);
+ }
+ output.push(String.fromCharCode(value));
+ }
+ return output.join("");
+ }
+ };
+
+ //Default parameters
+ var initial_n = 0x80;
+ var initial_bias = 72;
+ var delimiter = "-";
+ var base = 36;
+ var damp = 700;
+ var tmin=1;
+ var tmax=26;
+ var skew=38;
+ var maxint = 0x7FFFFFFF;
+
+ // decode_digit(cp) returns the numeric value of a basic code
+ // point (for use in representing integers) in the range 0 to
+ // base-1, or base if cp is does not represent a value.
+
+ function decode_digit(cp) {
+ return cp - 48 < 10 ? cp - 22 : cp - 65 < 26 ? cp - 65 : cp - 97 < 26 ? cp - 97 : base;
+ }
+
+ // encode_digit(d,flag) returns the basic code point whose value
+ // (when used for representing integers) is d, which needs to be in
+ // the range 0 to base-1. The lowercase form is used unless flag is
+ // nonzero, in which case the uppercase form is used. The behavior
+ // is undefined if flag is nonzero and digit d has no uppercase form.
+
+ function encode_digit(d, flag) {
+ return d + 22 + 75 * (d < 26) - ((flag !== 0) << 5);
+ // 0..25 map to ASCII a..z or A..Z
+ // 26..35 map to ASCII 0..9
+ }
+ //** Bias adaptation function **
+ function adapt(delta, numpoints, firsttime ) {
+ var k;
+ delta = firsttime ? Math.floor(delta / damp) : (delta >> 1);
+ delta += Math.floor(delta / numpoints);
+
+ for (k = 0; delta > (((base - tmin) * tmax) >> 1); k += base) {
+ delta = Math.floor(delta / ( base - tmin ));
+ }
+ return Math.floor(k + (base - tmin + 1) * delta / (delta + skew));
+ }
+
+ // encode_basic(bcp,flag) forces a basic code point to lowercase if flag is zero,
+ // uppercase if flag is nonzero, and returns the resulting code point.
+ // The code point is unchanged if it is caseless.
+ // The behavior is undefined if bcp is not a basic code point.
+
+ function encode_basic(bcp, flag) {
+ bcp -= (bcp - 97 < 26) << 5;
+ return bcp + ((!flag && (bcp - 65 < 26)) << 5);
+ }
+
+ // Main decode
+ this.decode=function(input,preserveCase) {
+ // Dont use utf16
+ var output=[];
+ var case_flags=[];
+ var input_length = input.length;
+
+ var n, out, i, bias, basic, j, ic, oldi, w, k, digit, t, len;
+
+ // Initialize the state:
+
+ n = initial_n;
+ i = 0;
+ bias = initial_bias;
+
+ // Handle the basic code points: Let basic be the number of input code
+ // points before the last delimiter, or 0 if there is none, then
+ // copy the first basic code points to the output.
+
+ basic = input.lastIndexOf(delimiter);
+ if (basic < 0) basic = 0;
+
+ for (j = 0; j < basic; ++j) {
+ if(preserveCase) case_flags[output.length] = ( input.charCodeAt(j) -65 < 26);
+ if ( input.charCodeAt(j) >= 0x80) {
+ throw new RangeError("Illegal input >= 0x80");
+ }
+ output.push( input.charCodeAt(j) );
+ }
+
+ // Main decoding loop: Start just after the last delimiter if any
+ // basic code points were copied; start at the beginning otherwise.
+
+ for (ic = basic > 0 ? basic + 1 : 0; ic < input_length; ) {
+
+ // ic is the index of the next character to be consumed,
+
+ // Decode a generalized variable-length integer into delta,
+ // which gets added to i. The overflow checking is easier
+ // if we increase i as we go, then subtract off its starting
+ // value at the end to obtain delta.
+ for (oldi = i, w = 1, k = base; ; k += base) {
+ if (ic >= input_length) {
+ throw RangeError ("punycode_bad_input(1)");
+ }
+ digit = decode_digit(input.charCodeAt(ic++));
+
+ if (digit >= base) {
+ throw RangeError("punycode_bad_input(2)");
+ }
+ if (digit > Math.floor((maxint - i) / w)) {
+ throw RangeError ("punycode_overflow(1)");
+ }
+ i += digit * w;
+ t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
+ if (digit < t) { break; }
+ if (w > Math.floor(maxint / (base - t))) {
+ throw RangeError("punycode_overflow(2)");
+ }
+ w *= (base - t);
+ }
+
+ out = output.length + 1;
+ bias = adapt(i - oldi, out, oldi === 0);
+
+ // i was supposed to wrap around from out to 0,
+ // incrementing n each time, so we'll fix that now:
+ if ( Math.floor(i / out) > maxint - n) {
+ throw RangeError("punycode_overflow(3)");
+ }
+ n += Math.floor( i / out ) ;
+ i %= out;
+
+ // Insert n at position i of the output:
+ // Case of last character determines uppercase flag:
+ if (preserveCase) { case_flags.splice(i, 0, input.charCodeAt(ic -1) -65 < 26);}
+
+ output.splice(i, 0, n);
+ i++;
+ }
+ if (preserveCase) {
+ for (i = 0, len = output.length; i < len; i++) {
+ if (case_flags[i]) {
+ output[i] = (String.fromCharCode(output[i]).toUpperCase()).charCodeAt(0);
+ }
+ }
+ }
+ return this.utf16.encode(output);
+ };
+
+ //** Main encode function **
+
+ this.encode = function (input,preserveCase) {
+ //** Bias adaptation function **
+
+ var n, delta, h, b, bias, j, m, q, k, t, ijv, case_flags;
+
+ if (preserveCase) {
+ // Preserve case, step1 of 2: Get a list of the unaltered string
+ case_flags = this.utf16.decode(input);
+ }
+ // Converts the input in UTF-16 to Unicode
+ input = this.utf16.decode(input.toLowerCase());
+
+ var input_length = input.length; // Cache the length
+
+ if (preserveCase) {
+ // Preserve case, step2 of 2: Modify the list to true/false
+ for (j=0; j < input_length; j++) {
+ case_flags[j] = input[j] != case_flags[j];
+ }
+ }
+
+ var output=[];
+
+
+ // Initialize the state:
+ n = initial_n;
+ delta = 0;
+ bias = initial_bias;
+
+ // Handle the basic code points:
+ for (j = 0; j < input_length; ++j) {
+ if ( input[j] < 0x80) {
+ output.push(
+ String.fromCharCode(
+ case_flags ? encode_basic(input[j], case_flags[j]) : input[j]
+ )
+ );
+ }
+ }
+
+ h = b = output.length;
+
+ // h is the number of code points that have been handled, b is the
+ // number of basic code points
+
+ if (b > 0) output.push(delimiter);
+
+ // Main encoding loop:
+ //
+ while (h < input_length) {
+ // All non-basic code points < n have been
+ // handled already. Find the next larger one:
+
+ for (m = maxint, j = 0; j < input_length; ++j) {
+ ijv = input[j];
+ if (ijv >= n && ijv < m) m = ijv;
+ }
+
+ // Increase delta enough to advance the decoder's
+ // <n,i> state to <m,0>, but guard against overflow:
+
+ if (m - n > Math.floor((maxint - delta) / (h + 1))) {
+ throw RangeError("punycode_overflow (1)");
+ }
+ delta += (m - n) * (h + 1);
+ n = m;
+
+ for (j = 0; j < input_length; ++j) {
+ ijv = input[j];
+
+ if (ijv < n ) {
+ if (++delta > maxint) return Error("punycode_overflow(2)");
+ }
+
+ if (ijv == n) {
+ // Represent delta as a generalized variable-length integer:
+ for (q = delta, k = base; ; k += base) {
+ t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
+ if (q < t) break;
+ output.push( String.fromCharCode(encode_digit(t + (q - t) % (base - t), 0)) );
+ q = Math.floor( (q - t) / (base - t) );
+ }
+ output.push( String.fromCharCode(encode_digit(q, preserveCase && case_flags[j] ? 1:0 )));
+ bias = adapt(delta, h + 1, h == b);
+ delta = 0;
+ ++h;
+ }
+ }
+
+ ++delta;
+ ++n;
+ }
+ return output.join("");
+ };
+
+ this.ToASCII = function ( domain ) {
+ var domain_array = domain.split(".");
+ var out = [];
+ for (var i=0; i < domain_array.length; ++i) {
+ var s = domain_array[i];
+ out.push(
+ s.match(/[^A-Za-z0-9\-]/) ?
+ "xn--" + punycode.encode(s) :
+ s
+ );
+ }
+ return out.join(".");
+ };
+
+ this.ToUnicode = function ( domain ) {
+ var domain_array = domain.split(".");
+ var out = [];
+ for (var i=0; i < domain_array.length; ++i) {
+ var s = domain_array[i];
+ out.push(
+ s.match(/^xn--/) ?
+ punycode.decode(s.slice(4)) :
+ s
+ );
+ }
+ return out.join(".");
+ };
+}();
+
+module.exports = function(address){
+ return address.replace(/((?:https?:\/\/)?.*\@)?([^\/]*)/, function(o, start, domain){
+ var domainParts = domain.split(/\./).map(punycode.ToASCII);
+ return (start || "") + domainParts.join(".");
+ });
+}; \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/lib/urlfetch.js b/tools/node_modules/nodemailer/node_modules/mailcomposer/lib/urlfetch.js
new file mode 100644
index 0000000..ecac514
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/lib/urlfetch.js
@@ -0,0 +1,71 @@
+var http = require("http"),
+ https = require("https"),
+ urllib = require("url"),
+ Stream = require('stream').Stream;
+
+/**
+ * @namespace URLFetch
+ * @name urlfetch
+ */
+module.exports = openUrlStream;
+
+/**
+ * <p>Open a stream to a specified URL</p>
+ *
+ * @memberOf urlfetch
+ * @param {String} url URL to open
+ * @param {Object} [options] Optional options object
+ * @param {String} [options.userAgent="mailcomposer"] User Agent for the request
+ * @return {Stream} Stream for the URL contents
+ */
+function openUrlStream(url, options){
+ options = options || {};
+ var urlparts = urllib.parse(url),
+ urloptions = {
+ host: urlparts.hostname,
+ port: urlparts.port || (urlparts.protocol=="https:"?443:80),
+ path: urlparts.path || urlparts.pathname,
+ method: "GET",
+ headers: {
+ "User-Agent": options.userAgent || "mailcomposer"
+ }
+ },
+ client = (urlparts.protocol=="https:"?https:http),
+ stream = new Stream(),
+ request;
+
+ stream.resume = function(){};
+
+ if(urlparts.auth){
+ urloptions.auth = urlparts.auth;
+ }
+
+ request = client.request(urloptions, function(response) {
+ if((response.statusCode || 0).toString().charAt(0) != "2"){
+ stream.emit("error", "Invalid status code " + (response.statusCode || 0));
+ return;
+ }
+
+ response.on('error', function(err) {
+ stream.emit("error", err);
+ });
+
+ response.on('data', function(chunk) {
+ stream.emit("data", chunk);
+ });
+
+ response.on('end', function(chunk) {
+ if(chunk){
+ stream.emit("data", chunk);
+ }
+ stream.emit("end");
+ });
+ });
+ request.end();
+
+ request.on('error', function(err) {
+ stream.emit("error", err);
+ });
+
+ return stream;
+} \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/LICENSE b/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/LICENSE
new file mode 100644
index 0000000..2950902
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/LICENSE
@@ -0,0 +1,16 @@
+Copyright (c) 2011 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. \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/README.md b/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/README.md
new file mode 100644
index 0000000..58a0871
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/README.md
@@ -0,0 +1,17 @@
+# mimelib
+
+*mimelib* is a collection of useful functions to deal with mime-encoded data.
+
+## Reference
+
+See [API reference](/andris9/mimelib/blob/master/doc.md) for documentation
+
+## Installation
+
+Install with *npm*
+
+ npm install mimelib-noiconv
+
+## Usage
+
+ var mimelib = require("mimelib-noiconv");
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/content-types.js b/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/content-types.js
new file mode 100644
index 0000000..bc5aa67
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/content-types.js
@@ -0,0 +1,60 @@
+// list of mime types
+module.exports = {
+ "doc": "application/msword",
+ "docx": "application/msword",
+ "pdf": "application/pdf",
+ "rss": "application/rss+xml",
+ "xls": "application/vnd.ms-excel",
+ "xlsx": "application/vnd.ms-excel",
+ "pps": "application/vnd.ms-powerpoint",
+ "ppt": "application/vnd.ms-powerpoint",
+ "pptx": "application/vnd.ms-powerpoint",
+ "odp": "application/vnd.oasis.opendocument.presentation",
+ "ods": "application/vnd.oasis.opendocument.spreadsheet",
+ "odt": "application/vnd.oasis.opendocument.text",
+ "sxc": "application/vnd.sun.xml.calc",
+ "sxw": "application/vnd.sun.xml.writer",
+ "au": "audio/basic",
+ "snd": "audio/basic",
+ "flac": "audio/flac",
+ "mid": "audio/mid",
+ "rmi": "audio/mid",
+ "m4a": "audio/mp4",
+ "mp3": "audio/mpeg",
+ "oga": "audio/ogg",
+ "ogg": "audio/ogg",
+ "aif": "audio/x-aiff",
+ "aifc": "audio/x-aiff",
+ "aiff": "audio/x-aiff",
+ "wav": "audio/x-wav",
+ "gif": "image/gif",
+ "jpeg": "image/jpeg",
+ "jpg": "image/jpeg",
+ "jpe": "image/jpeg",
+ "png": "image/png",
+ "tiff": "image/tiff",
+ "tif": "image/tiff",
+ "wbmp": "image/vnd.wap.wbmp",
+ "bmp": "image/x-ms-bmp",
+ "ics": "text/calendar",
+ "csv": "text/comma-separated-values",
+ "css": "text/css",
+ "htm": "text/html",
+ "html": "text/html",
+ "text": "text/plain",
+ "txt": "text/plain",
+ "asc": "text/plain",
+ "diff": "text/plain",
+ "pot": "text/plain",
+ "vcf": "text/x-vcard",
+ "mp4": "video/mp4",
+ "mpeg": "video/mpeg",
+ "mpg": "video/mpeg",
+ "mpe": "video/mpeg",
+ "ogv": "video/ogg",
+ "qt": "video/quicktime",
+ "mov": "video/quicktime",
+ "avi": "video/x-msvideo",
+ "zip": "application/zip",
+ "rar": "application/x-rar-compressed"
+} \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/doc.md b/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/doc.md
new file mode 100644
index 0000000..3c89514
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/doc.md
@@ -0,0 +1,191 @@
+mimelib(1) -- MIME functions for Node.JS
+=============================================
+
+## DESCRIPTION
+
+This document lists all the available methods for mimelib. You can include mimelib
+in your projects with `var mimelib = require("mimelib");`
+
+When installed with npm dependency module iconv will also be installed if not already
+present.
+
+## contentTypes
+
+`mimelib.contentTypes` is an object to provide content type strings for common
+file extensions
+
+ mimelib.contentTypes["xls"]; // "application/vnd.ms-excel"
+
+## foldLine
+
+Folds a long line according to the RFC 5322 <http://tools.ietf.org/html/rfc5322#section-2.1.1>
+
+ mimelib.foldLine(str [, maxLength][, foldAnywhere]) -> String
+
+ - `str` (String): mime string that might need folding
+ - `maxLength` (Number): max length for a line, defaults to 78
+ - `foldAnywhere` (Boolean): can fold at any location (ie. in base64)
+ - `afterSpace` (Boolean): If `true` fold after the space
+
+
+For example:
+
+ Content-Type: multipart/alternative; boundary="----zzzz----"
+
+will become
+
+ Content-Type: multipart/alternative;
+ boundary="----zzzz----"
+
+## encodeMimeWord
+
+Encodes a string into mime encoded word format <http://en.wikipedia.org/wiki/MIME#Encoded-Word> (see also `decodeMimeWord`)
+
+ mimelib.encodeMimeWord = function(str [, encoding][, charset])
+
+ - `str` (String): String to be encoded
+ - `encoding` (String): Encoding Q for quoted printable or B (def.) for base64
+ - `charset` (String): Charset to be used
+
+For example:
+
+ See on õhin test
+
+Becomes with UTF-8 and Quoted-printable encoding
+
+ =?UTF-8?q?See_on_=C3=B5hin_test?=
+
+## decodeMimeWord
+
+Decodes a string from mime encoded word format (see also `encodeMimeWord`)
+
+ mimelib.decodeMimeWord(str) -> String
+
+ - `str` (String): String to be decoded
+
+For example
+
+ mimelib.decodeMimeWord("=?UTF-8?q?See_on_=C3=B5hin_test?=");
+
+will become
+
+ See on õhin test
+
+## encodeQuotedPrintable
+
+Encodes a string into Quoted-printable format (see also `decodeQuotedPrintable`)
+
+ mimelib.encodeQuotedPrintable(str [, mimeWord][, charset]) -> String
+
+ - `str` (String): String to be encoded into Quoted-printable
+ - `mimeWord` (Boolean): Use mime-word mode (defaults to false)
+ - `charset` (String): Destination charset, defaults to UTF-8
+
+TODO: Currently only allowed charsets: UTF-8, LATIN1
+
+## decodeQuotedPrintable
+
+Decodes a string from Quoted-printable format (see also `encodeQuotedPrintable`)
+
+ mimelib.deccodeQuotedPrintable(str [, mimeWord][, charset]) -> String
+
+ - `str` (String): String to be decoded
+ - `mimeWord` (Boolean): Use mime-word mode (defaults to false)
+ - `charset` (String): Charset to be used, defaults to UTF-8
+
+## encodeBase64
+
+Encodes a string into Base64 format. Base64 is mime-word safe (see also `decodeBase64`)
+
+ mimelib.encodeBase64(str [, charset]) -> String
+
+ - `str` (String): String to be encoded into Base64
+ - `charset` (String): Destination charset, defaults to UTF-8
+
+## decodeBase64
+
+Decodes a string from Base64 format. Base64 is mime-word safe (see also `encodeBase64`)
+
+NB! Always returns UTF-8
+
+ mimelib.decodeBase64(str) -> String
+
+ - `str` (String): String to be decoded from Base64
+ - `charset` (String): Source charset, defaults to UTF-8
+
+## parseHeaders
+
+Parses header lines into an array of objects (see `parseHeaderLine`)
+
+ mimelib.parseHeaders(headers) -> Array
+
+ - `headers` (String): header section of the e-mail
+
+Example:
+
+ var headers = [
+ "From: andris@node.ee",
+ "To: juulius@node.ee",
+ "To: juulius2@node.ee",
+ "Content-type: text/html;",
+ " charset=utf-8"
+ ].join("\r\n");
+ mimelib.parseHeaders(headers);
+
+Results in
+
+ {"from": [ 'andris@node.ee' ],
+ "to": [ 'juulius@node.ee', 'juulius2@node.ee' ],
+ "content-type": [ 'text/html; charset=utf-8' ] }
+
+## parseAddresses
+
+Parses names and addresses from a from, to, cc or bcc line
+
+ mimelib.parseAddresses(addresses) -> Array
+
+ - `addresses` (String): string with comma separated e-mail addresses
+
+Example:
+
+ var to = '"Andris Reinman" <andris@node.ee>, juulius@node.ee'
+ mimelib.parseAddresses(to);
+
+Results in
+
+ [{ address: 'andris@node.ee', name: 'Andris Reinman' },
+ { address: 'juulius@node.ee', name: false }]
+
+## parseMimeWords
+
+Parses mime-words into UTF-8 strings
+
+ mimelib.parseMimeWords(str) -> String
+
+ - `str` (String): string to be parsed, if includes any mime words, then these are converted to UTF-8 strings
+
+
+For example:
+
+ mimelib.parseMimeWords("Hello: =?UTF-8?q?See_on_=C3=B5hin_test?=");
+
+Results in
+
+ "Hello: See on õhin test"
+
+## parseHeaderLine
+
+Parses a header line to search for additional parameters.
+
+ mimelib.parseHeaderLine(line) -> Object
+
+ - `line` (String): a line from a message headers
+
+For example:
+
+ mimelib.parseHeaderLine("text/plain; charset=utf-8")imelib
+
+Results in
+
+ {"defaultValue": 'text/plain',
+ "charset": 'utf-8' }
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/index.js b/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/index.js
new file mode 100644
index 0000000..a7ea3ee
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/index.js
@@ -0,0 +1,3 @@
+
+module.exports = require("./mime-functions");
+module.exports.contentTypes = require("./content-types"); \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/mime-functions.js b/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/mime-functions.js
new file mode 100644
index 0000000..9a93c7b
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/mime-functions.js
@@ -0,0 +1,486 @@
+
+try{
+ // see http://github.com/bnoordhuis/node-iconv for more info
+ var Iconv = require("iconv").Iconv;
+}catch(E){
+ // convert nothing
+ Iconv = function(){}
+ Iconv.prototype.convert = function(buf){return buf;};
+}
+
+/* mime related functions - encoding/decoding etc*/
+/* TODO: Only UTF-8 and Latin1 are allowed with encodeQuotedPrintable */
+/* TODO: Check if the input string even needs encoding */
+
+/**
+ * mime.foldLine(str, maxLength, foldAnywhere) -> String
+ * - str (String): mime string that might need folding
+ * - maxLength (Number): max length for a line, defaults to 78
+ * - foldAnywhere (Boolean): can fold at any location (ie. in base64)
+ * - afterSpace (Boolean): If [true] fold after the space
+ *
+ * Folds a long line according to the RFC 5322
+ * <http://tools.ietf.org/html/rfc5322#section-2.1.1>
+ *
+ * For example:
+ * Content-Type: multipart/alternative; boundary="----bd_n3-lunchhour1283962663300----"
+ * will become
+ * Content-Type: multipart/alternative;
+ * boundary="----bd_n3-lunchhour1283962663300----"
+ *
+ **/
+this.foldLine = function(str, maxLength, foldAnywhere, afterSpace){
+ var line=false, curpos=0, response="", lf;
+ maxLength = maxLength || 78;
+
+ // return original if no need to fold
+ if(str.length<=maxLength)
+ return str;
+
+ // read in <maxLength> bytes and try to fold it
+ while(line = str.substr(curpos, maxLength)){
+ if(!!foldAnywhere){
+ response += line;
+ if(curpos+maxLength<str.length){
+ response+="\r\n";
+ }
+ }else{
+ lf = line.lastIndexOf(" ");
+ if(lf<=0)
+ lf = line.lastIndexOf("\t");
+ if(line.length>=maxLength && lf>0){
+ if(!!afterSpace){
+ // move forward until line end or no more \s and \t
+ while(lf<line.length && (line.charAt(lf)==" " || line.charAt(lf)=="\t")){
+ lf++;
+ }
+ }
+ response += line.substr(0,lf)+"\r\n"+(!foldAnywhere && !afterSpace && " " || "");
+ curpos -= line.substr(lf).length;
+ }else{
+ response += line;
+ //line = line.replace(/=[a-f0-9]?$/i, "");
+ //response+=line + "\r\n";
+ }
+ }
+ curpos += line.length;
+ }
+
+ // return folded string
+ return response;
+}
+
+
+/**
+ * mime.encodeMimeWord(str, encoding, charset) -> String
+ * - str (String): String to be encoded
+ * - encoding (String): Encoding Q for quoted printable or B (def.) for base64
+ * - charset (String): Charset to be used
+ *
+ * Encodes a string into mime encoded word format
+ * <http://en.wikipedia.org/wiki/MIME#Encoded-Word>
+ *
+ * For example:
+ * See on õhin test
+ * Becomes with UTF-8 and Quoted-printable encoding
+ * =?UTF-8?q?See_on_=C3=B5hin_test?=
+ *
+ **/
+this.encodeMimeWord = function(str, encoding, charset){
+ charset = charset || "UTF-8";
+ encoding = encoding && encoding.toUpperCase() || "B";
+
+ if(encoding=="Q"){
+ str = this.encodeQuotedPrintable(str, true, charset);
+ }
+
+ if(encoding=="B"){
+ str = this.encodeBase64(str);
+ }
+
+ return "=?"+charset+"?"+encoding+"?"+str+"?=";
+}
+
+/**
+ * mime.decodeMimeWord(str, encoding, charset) -> String
+ * - str (String): String to be encoded
+ * - encoding (String): Encoding Q for quoted printable or B (def.) for base64
+ * - charset (String): Charset to be used, defaults to UTF-8
+ *
+ * Decodes a string from mime encoded word format, see [[encodeMimeWord]]
+ *
+ **/
+
+this.decodeMimeWord = function(str){
+ var parts = str.split("?"),
+ charset = parts && parts[1],
+ encoding = parts && parts[2],
+ text = parts && parts[3];
+ if(!charset || !encoding || !text)
+ return str;
+ if(encoding.toUpperCase()=="Q"){
+ return this.decodeQuotedPrintable(text, true, charset);
+ }
+
+ if(encoding.toUpperCase()=="B"){
+ return this.decodeBase64(text);
+ }
+
+ return text;
+}
+
+
+/**
+ * mime.encodeQuotedPrintable(str, mimeWord, charset) -> String
+ * - str (String): String to be encoded into Quoted-printable
+ * - mimeWord (Boolean): Use mime-word mode (defaults to false)
+ * - charset (String): Destination charset, defaults to UTF-8
+ * TODO: Currently only allowed charsets: UTF-8, LATIN1
+ *
+ * Encodes a string into Quoted-printable format.
+ **/
+this.encodeQuotedPrintable = function(str, mimeWord, charset){
+ charset = charset || "UTF-8";
+
+ /*
+ * Characters from 33-126 OK (except for =; and ?_ when in mime word mode)
+ * Spaces + tabs OK (except for line beginnings and endings)
+ * \n + \r OK
+ */
+
+ str = str.replace(/(?:[\ud800-\udbff][\udc00-\udfff])|[^\sa-zA-Z\d]/gm,function(c){
+ if(!!mimeWord){
+ if(c=="?")return "=3F";
+ if(c=="_")return "=5F";
+ }
+ if(c!=="=" && c.charCodeAt(0)>=33 && c.charCodeAt(0)<=126)
+ return c;
+ return c=="="?"=3D":(charset=="UTF-8"?encodeURIComponent(c):escape(c)).replace(/%/g,'=');
+ });
+
+ str = lineEdges(str);
+
+ if(!mimeWord){
+ // lines might not be longer than 76 bytes, soft break: "=\r\n"
+ var lines = str.split(/\r?\n/);
+ str.replace(/(.{73}(?!\r?\n))/,"$&=\r\n")
+ for(var i=0, len = lines.length; i<len; i++){
+ if(lines[i].length>76){
+ lines[i] = this.foldLine(lines[i],76, false, true).replace(/\r\n/g,"=\r\n");
+ }
+ }
+ str = lines.join("\r\n");
+ }else{
+ str = str.replace(/\s/g, function(a){
+ if(a==" ")return "_";
+ if(a=="\t")return "=09";
+ return a=="\r"?"=0D":"=0A";
+ });
+ }
+
+ return str;
+}
+
+/**
+ * mime.deccodeQuotedPrintable(str, mimeWord, charset) -> String
+ * - str (String): String to be decoded
+ * - mimeWord (Boolean): Use mime-word mode (defaults to false)
+ * - charset (String): Charset to be used, defaults to UTF-8
+ *
+ * Decodes a string from Quoted-printable format.
+ **/
+this.decodeQuotedPrintable = function(str, mimeWord, charset){
+ charset = charset && charset.toUpperCase() || "UTF-8";
+
+ if(mimeWord){
+ str = str.replace(/_/g," ");
+ }else{
+ str = str.replace(/=\r\n/gm,'');
+ str = str.replace(/=$/,"");
+ }
+ if(charset == "UTF-8")
+ str = decodeURIComponent(str.replace(/%/g,'%25').replace(/=/g,"%"));
+ else{
+ str = str.replace(/%/g,'%25').replace(/=/g,"%");
+ if(charset=="ISO-8859-1" || charset=="LATIN1")
+ str = unescape(str);
+ else{
+ str = decodeBytestreamUrlencoding(str);
+ str = fromCharset(charset, str);
+ }
+ }
+ return str;
+}
+
+/**
+ * mime.encodeBase64(str) -> String
+ * - str (String): String to be encoded into Base64
+ * - charset (String): Destination charset, defaults to UTF-8
+ *
+ * Encodes a string into Base64 format. Base64 is mime-word safe.
+ **/
+this.encodeBase64 = function(str, charset){
+ var buffer;
+ if(charset && charset.toUpperCase()!="UTF-8")
+ buffer = toCharset(charset, str);
+ else
+ buffer = new Buffer(str, "UTF-8");
+ return buffer.toString("base64");
+}
+
+/**
+ * mime.decodeBase64(str) -> String
+ * - str (String): String to be decoded from Base64
+ * - charset (String): Source charset, defaults to UTF-8
+ *
+ * Decodes a string from Base64 format. Base64 is mime-word safe.
+ * NB! Always returns UTF-8
+ **/
+this.decodeBase64 = function(str, charset){
+ var buffer = new Buffer(str, "base64");
+
+ if(charset && charset.toUpperCase()!="UTF-8"){
+ return fromCharset(charset, buffer);
+ }
+
+ // defaults to utf-8
+ return buffer.toString("UTF-8");
+}
+
+/**
+ * mime.parseHeaders(headers) -> Array
+ * - headers (String): header section of the e-mail
+ *
+ * Parses header lines into an array of objects (see [[parseHeaderLine]])
+ * FIXME: This should probably not be here but in "envelope" instead
+ **/
+this.parseHeaders = function(headers){
+ var text, lines, line, i, name, value, cmd, header_lines = {};
+ // unfold
+ headers = headers.replace(/\r?\n([ \t])/gm," ");
+
+ // split lines
+ lines = headers.split(/\r?\n/);
+ for(i=0; i<lines.length;i++){
+ if(!lines[i]) // no more header lines
+ break;
+ cmd = lines[i].match(/[^\:]+/);
+ if(cmd && (cmd = cmd[0])){
+ name = cmd;
+ value = lines[i].substr(name.length+1);
+ if(!header_lines[name.toLowerCase().trim()])header_lines[name.toLowerCase().trim()] = [];
+ header_lines[name.toLowerCase()].push(value.trim());
+ }
+ }
+
+ return header_lines;
+}
+
+/**
+ * mime.parseAddresses(addresses) -> Array
+ * - addresses (String): string with comma separated e-mail addresses
+ *
+ * Parses names and addresses from a from, to, cc or bcc line
+ **/
+this.parseAddresses = function(addresses){
+ if(!addresses)
+ return [];
+
+ addresses = addresses.replace(/\=\?[^?]+\?[QqBb]\?[^?]+\?=/g, (function(a){return this.decodeMimeWord(a);}).bind(this));
+
+ // not sure if it's even needed - urlencode escaped \\ and \" and \'
+ addresses = addresses.replace(/\\\\/g,function(a){return escape(a.charAt(1));});
+ addresses = addresses.replace(/\\["']/g,function(a){return escape(a.charAt(1));});
+
+ // find qutoed strings
+
+ var parts = addresses.split(','), curStr,
+ curQuote, lastPos, remainder="", str, list = [],
+ curAddress, address, addressArr = [], name, email, i, len;
+ var rightEnd;
+
+ // separate quoted text from text parts
+ for(i=0, len=parts.length; i<len; i++){
+ str = "";
+
+ curStr = (remainder+parts[i]).trim();
+
+ curQuote = curStr.charAt(0);
+ if(curQuote == "'" || curQuote == '"'){
+ rightEnd= curStr.indexOf("<");
+ if(rightEnd == -1)rightEnd= curStr.length-1;
+ lastPos = curStr.lastIndexOf(curQuote,rightEnd);
+
+ if(!lastPos){
+ remainder = remainder+parts[i]+",";
+ continue;
+ }else{
+ remainder = "";
+ str = curStr.substring(1, lastPos).trim();
+ address = curStr.substr(lastPos+1).trim();
+ }
+
+ }else{
+ address = curStr;
+ }
+
+ list.push({name: str, address: address, original: curStr});
+ }
+
+ // find e-mail addresses and user names
+ for(i=0, len=list.length; i<len; i++){
+ curAddress = list[i];
+
+ email = false;
+ name = false;
+
+ name = curAddress.name;
+
+ address = curAddress.address.replace(/<([^>]+)>/, function(original, addr){
+ email = addr.indexOf("@")>=0 && addr;
+ return email ? "" : original;
+ }).trim();
+
+ if(!email){
+ address = address.replace(/(\S+@\S+)/, function(original, m){
+ email = m;
+ return email ? "" : original;
+ });
+ }
+
+ if(!name){
+ if(email){
+ email = email.replace(/\(([^)]+)\)/,function(original, n){
+ name = n;
+ return "";
+ });
+ }
+ if(!name){
+ name = address.replace(/"/g,"").trim();
+ }
+ }
+
+ // just in case something got mixed up
+ if(!email && name.indexOf("@")>=0){
+ email = name;
+ name = false;
+ }
+
+ if(name || email){
+ name = (name || "").replace(/%27/g, "'").replace(/%22/g, "\"");
+ email = (email || "").replace(/%27/g, "'").replace(/%22/g, "\"");
+ addressArr.push({address: email, name: name});
+
+ }
+ }
+ return addressArr;
+};
+
+/**
+ * mime.parseMimeWords(str) -> String
+ * - str (String): string to be parsed
+ *
+ * Parses mime-words into UTF-8 strings
+ **/
+this.parseMimeWords = function(str){
+ return str.replace(/=\?[^?]+\?[QqBb]\?[^?]+\?=/g, (function(a){
+ return this.decodeMimeWord(a);
+ }).bind(this));
+}
+
+/**
+ * mime.parseHeaderLine(line) -> Object
+ * - line (String): a line from a message headers
+ *
+ * Parses a header line to search for additional parameters.
+ * For example with "text/plain; charset=utf-8" the output would be
+ * - defaultValue = text/plain
+ * - charset = utf-8
+ **/
+this.parseHeaderLine = function(line){
+ if(!line)
+ return {};
+ var result = {}, parts = line.split(";"), pos;
+ for(var i=0, len = parts.length; i<len; i++){
+ pos = parts[i].indexOf("=");
+ if(pos<0){
+ result[!i?"defaultValue":"i-"+i] = parts[i].trim();
+ }else{
+ result[parts[i].substr(0,pos).trim().toLowerCase()] = parts[i].substr(pos+1).trim();
+ }
+ }
+ return result;
+}
+
+
+/* Helper functions */
+
+/**
+ * lineEdges(str) -> String
+ * - str (String): String to be processed
+ *
+ * Replaces all spaces and tabs in the beginning and end of the string
+ * with quoted printable encoded chars. Needed by [[encodeQuotedPrintable]]
+ **/
+function lineEdges(str){
+ str = str.replace(/^[ \t]+/gm, function(wsc){
+ return wsc.replace(/ /g,"=20").replace(/\t/g,"=09");
+ });
+
+ str = str.replace(/[ \t]+$/gm, function(wsc){
+ return wsc.replace(/ /g,"=20").replace(/\t/g,"=09");
+ });
+ return str;
+}
+
+/**
+ * fromCharset(charset, buffer, keep_buffer) -> String | Buffer
+ * - charset (String): Source charset
+ * - buffer (Buffer): Buffer in <charset>
+ * - keep_buffer (Boolean): If true, return buffer, otherwise UTF-8 string
+ *
+ * Converts a buffer in <charset> codepage into UTF-8 string
+ **/
+function fromCharset(charset, buffer, keep_buffer){
+ var iconv = new Iconv(charset,'UTF-8'),
+ buffer = iconv.convert(buffer);
+ return keep_buffer?buffer:buffer.toString("utf-8");
+}
+
+/**
+ * toCharset(charset, buffer) -> Buffer
+ * - charset (String): Source charset
+ * - buffer (Buffer): Buffer in UTF-8 or string
+ *
+ * Converts a string or buffer to <charset> codepage
+ **/
+function toCharset(charset, buffer){
+ var iconv = new Iconv('UTF-8',charset);
+ return iconv.convert(buffer);
+}
+
+/**
+ * decodeBytestreamUrlencoding(encoded_string) -> Buffer
+ * - encoded_string (String): String in urlencode coding
+ *
+ * Converts an urlencoded string into a bytestream buffer. If the used
+ * charset is known the resulting string can be converted to UTF-8 with
+ * [[fromCharset]].
+ * NB! For UTF-8 use decodeURIComponent and for Latin 1 decodeURL instead
+ **/
+function decodeBytestreamUrlencoding(encoded_string){
+ var c, i, j=0, prcnts = encoded_string.match(/%/g) || "",
+ buffer_length = encoded_string.length - (prcnts.length*2),
+ buffer = new Buffer(buffer_length);
+
+ for(var i=0; i<encoded_string.length; i++){
+ c = encoded_string.charCodeAt(i);
+ if(c=="37"){ // %
+ c = parseInt(encoded_string.substr(i+1,2), 16);
+ i+=2;
+ }
+ buffer[j++] = c;
+ }
+ return buffer;
+}
+
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/package.json b/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/package.json
new file mode 100644
index 0000000..d807316
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "mimelib-noiconv",
+ "description": "MIME functions to encode/decode e-mails etc.",
+ "version": "0.1.9",
+ "author": {
+ "name": "Andris Reinman"
+ },
+ "homepage": "http://github.com/andris9/mimelib",
+ "maintainers": [
+ {
+ "name": "andris",
+ "email": "andris@node.ee"
+ }
+ ],
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/andris9/mimelib.git"
+ },
+ "main": ".",
+ "licenses": [
+ {
+ "type": "MIT",
+ "url": "http://github.com/andris9/mimelib/blob/master/LICENSE"
+ }
+ ],
+ "dependencies": {},
+ "keywords": [
+ "e-mail",
+ "mime",
+ "email"
+ ],
+ "readme": "# mimelib\n\n*mimelib* is a collection of useful functions to deal with mime-encoded data.\n\n## Reference\n\nSee [API reference](/andris9/mimelib/blob/master/doc.md) for documentation\n\n## Installation\n\nInstall with *npm*\n\n npm install mimelib-noiconv\n \n## Usage\n\n var mimelib = require(\"mimelib-noiconv\");\n",
+ "_id": "mimelib-noiconv@0.1.9",
+ "_from": "mimelib-noiconv@*"
+}
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/package.json b/tools/node_modules/nodemailer/node_modules/mailcomposer/package.json
new file mode 100644
index 0000000..fe0755f
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/package.json
@@ -0,0 +1,46 @@
+{
+ "name": "mailcomposer",
+ "description": "Compose E-Mail messages",
+ "version": "0.1.15",
+ "author": {
+ "name": "Andris Reinman"
+ },
+ "maintainers": [
+ {
+ "name": "andris",
+ "email": "andris@node.ee"
+ }
+ ],
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/andris9/mailcomposer.git"
+ },
+ "scripts": {
+ "test": "nodeunit test/"
+ },
+ "main": "./lib/mailcomposer",
+ "licenses": [
+ {
+ "type": "MIT",
+ "url": "http://github.com/andris9/mailcomposer/blob/master/LICENSE"
+ }
+ ],
+ "dependencies": {
+ "mimelib-noiconv": "*"
+ },
+ "devDependencies": {
+ "nodeunit": "*",
+ "mailparser": "*"
+ },
+ "engine": {
+ "node": ">=0.4"
+ },
+ "keywords": [
+ "e-mail",
+ "mime",
+ "parser"
+ ],
+ "readme": "# mailcomposer\n\n**mailcomposer** is a Node.JS module for generating e-mail messages that can be\nstreamed to SMTP or file. \n\nThis is a standalone module that only generates raw e-mail source, you need to \nwrite your own or use an existing transport mechanism (SMTP client, Amazon SES, \nSendGrid etc). **mailcomposer** frees you from the tedious task of generating \n[rfc822](http://tools.ietf.org/html/rfc2822) compatible messages.\n\n[![Build Status](https://secure.travis-ci.org/andris9/mailcomposer.png)](http://travis-ci.org/andris9/mailcomposer)\n\n**mailcomposer** supports:\n\n * **Unicode** to use any characters ✔\n * **HTML** content as well as **plain text** alternative\n * **Attachments** and streaming for larger files (use strings, buffers, files or binary streams as attachments)\n * **Embedded images** in HTML\n * **DKIM** signing\n * usage of **your own** transport mechanism\n\n## Support mailcomposer development\n\n[![Donate to author](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DB26KWR2BQX5W)\n\n## Installation\n\nInstall through NPM\n\n npm install mailcomposer\n\n## Usage\n\n### Include mailcomposer module\n\n var MailComposer = require(\"mailcomposer\").MailComposer;\n\n### Create a new `MailComposer` instance\n\n var mailcomposer = new MailComposer([options]);\n\nWhere `options` is an optional options object with the following possible properties:\n\n * **escapeSMTP** - if set replaces dots in the beginning of a line with double dots\n * **encoding** - sets transfer encoding for the textual parts (defaults to `\"quoted-printable\"`)\n * **keepBcc** - if set to true, includes `Bcc:` field in the message headers. Useful for *sendmail* command. \n\n### Simple example\n\nThe following example generates a simple e-mail message with plaintext and html\nbody.\n\n var MailComposer = require(\"mailcomposer\").MailComposer;\n mailcomposer = new MailComposer(),\n fs = require(\"fs\");\n \n // add additional header field\n mailcomposer.addHeader(\"x-mailer\", \"Nodemailer 1.0\");\n \n // setup message data\n mailcomposer.setMessageOption({\n from: \"andris@tr.ee\",\n to: \"andris@node.ee\",\n body: \"Hello world!\",\n html: \"<b>Hello world!</b>\"\n }); \n \n mailcomposer.streamMessage();\n \n // pipe the output to a file\n mailcomposer.pipe(fs.createWriteStream(\"test.eml\"));\n\nThe output for such a script (the contents for \"test.eml\") would look like:\n\n MIME-Version: 1.0\n X-Mailer: Nodemailer 1.0\n From: andris@tr.ee\n To: andris@node.ee\n Content-Type: multipart/alternative;\n boundary=\"----mailcomposer-?=_1-1328088797399\"\n \n ------mailcomposer-?=_1-1328088797399\n Content-Type: text/plain; charset=utf-8\n Content-Transfer-Encoding: quoted-printable\n \n Hello world!\n ------mailcomposer-?=_1-1328088797399\n Content-Type: text/html; charset=utf-8\n Content-Transfer-Encoding: quoted-printable\n \n <b>Hello world!</b>\n ------mailcomposer-?=_1-1328088797399--\n\n## API\n\n### Add custom headers\n\nHeaders can be added with `mailcomposer.addHeader(key, value)`\n\n var mailcomposer = new MailComposer();\n mailcomposer.addHeader(\"x-mailer\", \"Nodemailer 1.0\");\n\nIf you add an header value with the same key several times, all of the values will be used\nin the generated header. For example:\n\n mailcomposer.addHeader(\"x-mailer\", \"Nodemailer 1.0\");\n mailcomposer.addHeader(\"x-mailer\", \"Nodemailer 2.0\");\n \nWill be generated into\n\n ...\n X-Mailer: Nodemailer 1.0\n X-Mailer: Nodemailer 2.0\n ...\n\nThe contents of the field value is not edited in any way (except for the folding),\nso if you want to use unicode symbols you need to escape these to mime words\nby yourself. Exception being object values - in this case the object\nis automatically JSONized and mime encoded.\n\n // using objects as header values is allowed (will be converted to JSON)\n var apiOptions = {};\n apiOptions.category = \"newuser\";\n apiOptions.tags = [\"user\", \"web\"];\n mailcomposer.addHeader(\"X-SMTPAPI\", apiOptions)\n\n### Add message parts\n\nYou can set message sender, receiver, subject line, message body etc. with\n`mailcomposer.setMessageOption(options)` where options is an object with the\ndata to be set. This function overwrites any previously set values with the\nsame key\n\nThe following example creates a simple e-mail with sender being `andris@tr.ee`, \nreceiver `andris@node.ee` and plaintext part of the message as `Hello world!`:\n\n mailcomposer.setMessageOption({\n from: \"andris@tr.ee\",\n to: \"andris@node.ee\",\n body: \"Hello world!\"\n }); \n\nPossible options that can be used are (all fields accept unicode):\n\n * **from** (alias `sender`) - the sender of the message. If several addresses are given, only the first one will be used\n * **to** - receivers for the `To:` field\n * **cc** - receivers for the `Cc:` field\n * **bcc** - receivers for the `Bcc:` field\n * **replyTo** (alias `reply_to`) - e-mail address for the `Reply-To:` field\n * **inReplyTo** - The message-id this message is replying\n * **references** - Message-id list\n * **subject** - the subject line of the message\n * **body** (alias `text`) - the plaintext part of the message\n * **html** - the HTML part of the message\n * **envelope** - optional SMTP envelope, if auto generated envelope is not suitable\n\nThis method can be called several times\n\n mailcomposer.setMessageOption({from: \"andris@tr.ee\"});\n mailcomposer.setMessageOption({to: \"andris@node.ee\"});\n mailcomposer.setMessageOption({body: \"Hello world!\"});\n\nTrying to set the same key several times will yield in overwrite\n\n mailcomposer.setMessageOption({body: \"Hello world!\"});\n mailcomposer.setMessageOption({body: \"Hello world?\"});\n // body contents will be \"Hello world?\"\n\n### Address format\n\nAll e-mail address fields take structured e-mail lists (comma separated)\nas the input. Unicode is allowed for all the parts (receiver name, e-mail username\nand domain) of the address. If the domain part contains unicode symbols, it is\nautomatically converted into punycode, user part will be converted into UTF-8\nmime word.\n\nE-mail addresses can be a plain e-mail addresses\n\n username@example.com\n\nor with a formatted name\n\n 'Ноде Майлер' <username@example.com>\n\nOr in case of comma separated lists, the formatting can be mixed\n\n username@example.com, 'Ноде Майлер' <username@example.com>, \"Name, User\" <username@example.com>\n\n### SMTP envelope\n\nSMTP envelope is usually auto generated from `from`, `to`, `cc` and `bcc` fields but\nif for some reason you want to specify it yourself, you can do it with `envelope` property.\n\n`envelope` is an object with the following params: `from`, `to`, `cc` and `bcc` just like\nwith regular mail options. You can also use the regular address format.\n\n mailOptions = {\n ...,\n from: \"mailer@node.ee\",\n to: \"daemon@node.ee\",\n envelope: {\n from: \"Daemon <deamon@node.ee>\",\n to: \"mailer@node.ee, Mailer <mailer2@node.ee>\"\n }\n }\n\n### Add attachments\n\nAttachments can be added with `mailcomposer.addAttachment(attachment)` where\n`attachment` is an object with attachment (meta)data with the following possible\nproperties:\n\n * **fileName** (alias `filename`) - filename to be reported as the name of the attached file, use of unicode is allowed\n * **cid** - content id for using inline images in HTML message source\n * **contents** - String or a Buffer contents for the attachment\n * **filePath** - path to a file or an URL if you want to stream the file instead of including it (better for larger attachments)\n * **streamSource** - Stream object for arbitrary binary streams if you want to stream the contents (needs to support *pause*/*resume*)\n * **contentType** - content type for the attachment, if not set will be derived from the `fileName` property\n * **contentDisposition** - content disposition type for the attachment, defaults to \"attachment\" \n * **userAgent** - User-Agent string to be used if the fileName points to an URL\n\nOne of `contents`, `filePath` or `streamSource` must be specified, if none is \npresent, the attachment will be discarded. Other fields are optional.\n\nAttachments can be added as many as you want.\n\n**Using embedded images in HTML**\n\nAttachments can be used as embedded images in the HTML body. To use this \nfeature, you need to set additional property of the attachment - `cid` \n(unique identifier of the file) which is a reference to the attachment file. \nThe same `cid` value must be used as the image URL in HTML (using `cid:` as \nthe URL protocol, see example below).\n\nNB! the cid value should be as unique as possible!\n\n var cid_value = Date.now() + '.image.jpg';\n \n var html = 'Embedded image: <img src=\"cid:' + cid_value + '\" />';\n \n var attachment = {\n fileName: \"image.png\",\n filePath: \"/static/images/image.png\",\n cid: cid_value\n };\n\n### DKIM Signing\n\n**mailcomposer** supports DKIM signing with very simple setup. Use this with caution \nthough since the generated message needs to be buffered entirely before it can be\nsigned - in this case the streaming capability offered by mailcomposer is illusionary,\nthere will only be one `'data'` event with the entire message. Not a big deal with\nsmall messages but might consume a lot of RAM when using larger attachments.\n\nSet up the DKIM signing with `useDKIM` method:\n\n mailcomposer.useDKIM(dkimOptions)\n\nWhere `dkimOptions` includes necessary options for signing\n\n * **domainName** - the domainname that is being used for signing\n * **keySelector** - key selector. If you have set up a TXT record with DKIM public key at *zzz._domainkey.example.com* then `zzz` is the selector\n * **privateKey** - DKIM private key that is used for signing as a string\n * **headerFieldNames** - optional colon separated list of header fields to sign, by default all fields suggested by RFC4871 #5.5 are used\n\n**NB!** Currently if several header fields with the same name exists, only the last one (the one in the bottom) is signed.\n\nExample:\n\n mailcomposer.setMessageOption({from: \"andris@tr.ee\"});\n mailcomposer.setMessageOption({to: \"andris@node.ee\"});\n mailcomposer.setMessageOption({body: \"Hello world!\"});\n mailcomposer.useDKIM({\n domainName: \"node.ee\",\n keySelector: \"dkim\",\n privateKey: fs.readFileSync(\"private_key.pem\")\n });\n\n### Start streaming\n\nWhen the message data is setup, streaming can be started. After this it is not\npossible to add headers, attachments or change body contents.\n\n mailcomposer.streamMessage();\n\nThis generates `'data'` events for the message headers and body and final `'end'` event.\nAs `MailComposer` objects are Stream instances, these can be piped\n\n // save the output to a file\n mailcomposer.streamMessage();\n mailcomposer.pipe(fs.createWriteStream(\"out.txt\"));\n\n## Envelope\n\nEnvelope can be generated with an `getEnvelope()` which returns an object\nthat includes a `from` address (string) and a list of `to` addresses (array of\nstrings) suitable for forwarding to a SMTP server as `MAIL FROM:` and `RCPT TO:`.\n\n console.log(mailcomposer.getEnvelope());\n // {from:\"sender@example.com\", to:[\"receiver@example.com\"]}\n\n**NB!** both `from` and `to` properties might be missing from the envelope object\nif corresponding addresses were not detected from the e-mail.\n\n## Running tests\n\nTests are run with [nodeunit](https://github.com/caolan/nodeunit)\n\nRun\n\n npm test\n\nor alternatively\n\n node run_tests.js\n\n## License\n\n**MIT**",
+ "_id": "mailcomposer@0.1.15",
+ "_from": "mailcomposer@>= 0.1.15"
+}
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/test/dkim.js b/tools/node_modules/nodemailer/node_modules/mailcomposer/test/dkim.js
new file mode 100644
index 0000000..6d18251
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/test/dkim.js
@@ -0,0 +1,47 @@
+var testCase = require('nodeunit').testCase,
+ dkim = require("../lib/dkim"),
+ fs = require("fs");
+
+
+exports["Canonicalizer tests"] = {
+ "Relaxed body": function(test){
+ // dkim.org samples
+ var body = " C \r\nD \t E\r\n\r\n\r\n";
+ test.equal(" C\r\nD E\r\n", dkim.DKIMCanonicalizer.relaxedBody(body));
+ test.done();
+ },
+ "Relaxed body short": function(test){
+ // dkim.org samples
+ var body = " C \r\nD \t E";
+ test.equal(" C\r\nD E\r\n", dkim.DKIMCanonicalizer.relaxedBody(body));
+ test.done();
+ },
+ "Relaxed headers": function(test){
+ var headers = "A: X\r\nB: Y\t\r\n\tZ \r\n";
+ test.equal("a:X\r\nb:Y Z\r\n", dkim.DKIMCanonicalizer.relaxedHeaders(headers, "a:b").headers);
+ test.done();
+ }
+}
+
+exports["General tests"] = {
+ "Unicode domain": function(test){
+ var mail = "From: andris@node.ee\r\nTo:andris@kreata.ee\r\n\r\nHello world!";
+ var dkimField = dkim.DKIMSign(mail,{
+ domainName: "müriaad-polüteism.info",
+ keySelector: "dkim",
+ privateKey: fs.readFileSync(__dirname+"/test_private.pem")
+ });
+ test.equal(dkimField.replace(/\r?\n\s*/g, "").replace(/\s+/g, " "), "DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;d=xn--mriaad-polteism-zvbj.info; q=dns/txt; s=dkim;bh=z6TUz85EdYrACGMHYgZhJGvVy5oQI0dooVMKa2ZT7c4=; h=from:to;b=oBJ1MkwEkftfXa2AK4Expjp2xgIcAR43SVrftSEHVQ6F1SlGjP3EKP+cn/hLkhUel3rY0icthk/myDu6uhTBmM6DMtzIBW/7uQd6q9hfgaiYnw5Iew2tZc4TzBEYSdKi")
+ test.done();
+ },
+ "Normal domain": function(test){
+ var mail = "From: andris@node.ee\r\nTo:andris@kreata.ee\r\n\r\nHello world!";
+ var dkimField = dkim.DKIMSign(mail,{
+ domainName: "node.ee",
+ keySelector: "dkim",
+ privateKey: fs.readFileSync(__dirname+"/test_private.pem")
+ });
+ test.equal(dkimField.replace(/\r?\n\s*/g, "").replace(/\s+/g, " "), "DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=node.ee; q=dns/txt;s=dkim; bh=z6TUz85EdYrACGMHYgZhJGvVy5oQI0dooVMKa2ZT7c4=; h=from:to;b=pVd+Dp+EjmYBcc1AWlBAP4ESpuAJ2WMS4gbxWLoeUZ1vZRodVN7K9UXvcCsLuqjJktCZMN2+8dyEUaYW2VIcxg4sVBCS1wqB/tqYZ/gxXLnG2/nZf4fyD2vxltJP4pDL");
+ test.done();
+ }
+} \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/test/mailcomposer.js b/tools/node_modules/nodemailer/node_modules/mailcomposer/test/mailcomposer.js
new file mode 100644
index 0000000..0a0d9fd
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/test/mailcomposer.js
@@ -0,0 +1,1085 @@
+var testCase = require('nodeunit').testCase,
+ MailComposer = require("../lib/mailcomposer").MailComposer,
+ toPunycode = require("../lib/punycode"),
+ MailParser = require("mailparser").MailParser,
+ fs = require("fs"),
+ http = require("http");
+
+
+var HTTP_PORT = 9437;
+
+exports["General tests"] = {
+
+ "Create a new MailComposer object": function(test){
+ var mailcomposer = new MailComposer();
+ test.equal(typeof mailcomposer.on, "function");
+ test.equal(typeof mailcomposer.emit, "function");
+ test.done();
+ },
+
+ "Normalize key names": function(test){
+ var normalizer = MailComposer.prototype._normalizeKey;
+
+ test.equal(normalizer("abc"), "Abc");
+ test.equal(normalizer("aBC"), "Abc");
+ test.equal(normalizer("ABC"), "Abc");
+ test.equal(normalizer("a-b-c"), "A-B-C");
+ test.equal(normalizer("ab-bc"), "Ab-Bc");
+ test.equal(normalizer("ab-bc-cd"), "Ab-Bc-Cd");
+ test.equal(normalizer("AB-BC-CD"), "Ab-Bc-Cd");
+ test.equal(normalizer("mime-version"), "MIME-Version"); // special case
+
+ test.done();
+ },
+
+ "Add header": function(test){
+ var mc = new MailComposer();
+ test.equal(typeof mc._headers["Test-Key"], "undefined");
+ mc.addHeader("test-key", "first");
+ test.equal(mc._headers["Test-Key"], "first");
+ mc.addHeader("test-key", "second");
+ test.deepEqual(mc._headers["Test-Key"], ["first","second"]);
+ mc.addHeader("test-key", "third");
+ test.deepEqual(mc._headers["Test-Key"], ["first","second","third"]);
+ test.done();
+ },
+
+ "Get header": function(test){
+ var mc = new MailComposer();
+ test.equal(mc._getHeader("MIME-Version"), "1.0");
+ test.equal(mc._getHeader("test-key"), "");
+ mc.addHeader("test-key", "first");
+ test.equal(mc._getHeader("test-key"), "first");
+ mc.addHeader("test-key", "second");
+ test.deepEqual(mc._getHeader("test-key"), ["first", "second"]);
+ test.done();
+ },
+
+ "Uppercase header keys": function(test){
+ var mc = new MailComposer();
+
+ mc.addHeader("X-TEST", "first");
+ test.equal(mc._headers["X-TEST"], "first");
+
+ mc.addHeader("TEST", "second");
+ test.equal(mc._headers["Test"], "second");
+
+ test.done();
+ },
+
+ "Set object header": function(test){
+ var mc = new MailComposer();
+
+ var testObj = {
+ stringValue: "String with unicode symbols: ÕÄÖÜŽŠ",
+ arrayValue: ["hello ÕÄÖÜ", 12345],
+ objectValue: {
+ customerId: "12345"
+ }
+ };
+
+ mc.addHeader("x-mytest-string", "first");
+ mc.addHeader("x-mytest-json", testObj);
+
+ mc.streamMessage();
+
+ //mc.on("data", function(c){console.log(c.toString("utf-8"))})
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mail.headers['x-mytest-string'], "first");
+ test.deepEqual(JSON.parse(mail.headers['x-mytest-json']), testObj);
+ //console.log(mail)
+ test.done();
+ });
+ },
+
+ "Add message option": function(test){
+ var mc = new MailComposer();
+ test.equal(typeof mc._message.subject, "undefined");
+
+ mc.setMessageOption({
+ subject: "Test1",
+ body: "Test2",
+ nonexistent: "Test3"
+ });
+
+ test.equal(mc._message.subject, "Test1");
+ test.equal(mc._message.body, "Test2");
+ test.equal(typeof mc._message.nonexistent, "undefined");
+
+ mc.setMessageOption({
+ subject: "Test4"
+ });
+
+ test.equal(mc._message.subject, "Test4");
+ test.equal(mc._message.body, "Test2");
+
+ test.done();
+ },
+
+ "Detect mime type": function(test){
+ var mc = new MailComposer();
+
+ test.equal(mc._getMimeType("test.txt"), "text/plain");
+ test.equal(mc._getMimeType("test.unknown"), "application/octet-stream");
+
+ test.done();
+ },
+
+ "keepBcc off": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption({bcc: "andris@node.ee"});
+ mc._buildMessageHeaders();
+ test.ok(!mc._getHeader("Bcc"));
+ test.done();
+ },
+
+ "keepBcc on": function(test){
+ var mc = new MailComposer({keepBcc: true});
+ mc.setMessageOption({bcc: "andris@node.ee"});
+ mc._buildMessageHeaders();
+ test.equal(mc._getHeader("Bcc"), "andris@node.ee");
+ test.done();
+ }
+};
+
+
+exports["Text encodings"] = {
+ "Punycode": function(test){
+ test.equal(toPunycode("andris@age.ee"), "andris@age.ee");
+ test.equal(toPunycode("andris@äge.ee"), "andris@xn--ge-uia.ee");
+ test.done();
+ },
+
+ "Mime words": function(test){
+ var mc = new MailComposer();
+ test.equal(mc._encodeMimeWord("Tere"), "Tere");
+ test.equal(mc._encodeMimeWord("Tere","Q"), "Tere");
+ test.equal(mc._encodeMimeWord("Tere","B"), "Tere");
+
+ // simple
+ test.equal(mc._encodeMimeWord("äss"), "=?UTF-8?Q?=C3=A4ss?=");
+ test.equal(mc._encodeMimeWord("äss","B"), "=?UTF-8?B?"+(new Buffer("äss","utf-8").toString("base64"))+"?=");
+
+ //multiliple
+ test.equal(mc._encodeMimeWord("äss tekst on see siin või kuidas?","Q", 20), "=?UTF-8?Q?=C3=A4ss?= =?UTF-8?Q?_tekst_o?= =?UTF-8?Q?n_see_si?= =?UTF-8?Q?in_v?= =?UTF-8?Q?=C3=B5i_?= =?UTF-8?Q?kuidas?= =?UTF-8?Q?=3F?=");
+
+ test.done();
+ },
+
+ "Addresses": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ sender: '"Jaanuar Veebruar, Märts" <märts@märts.eu>'
+ });
+
+ test.equal(mc._message.from, "\"=?UTF-8?Q?Jaanuar_Veebruar,_M=C3=A4rts?=\" <=?UTF-8?Q?m=C3=A4rts?=@xn--mrts-loa.eu>");
+
+ mc.setMessageOption({
+ sender: 'aavik <aavik@node.ee>'
+ });
+
+ test.equal(mc._message.from, '"aavik" <aavik@node.ee>');
+
+ mc.setMessageOption({
+ sender: '<aavik@node.ee>'
+ });
+
+ test.equal(mc._message.from, 'aavik@node.ee');
+
+ mc.setMessageOption({
+ sender: '<aavik@märts.eu>'
+ });
+
+ test.equal(mc._message.from, 'aavik@xn--mrts-loa.eu');
+
+ // multiple
+
+ mc.setMessageOption({
+ sender: '<aavik@märts.eu>, juulius@node.ee, "Node, Master" <node@node.ee>'
+ });
+
+ test.equal(mc._message.from, 'aavik@xn--mrts-loa.eu, juulius@node.ee, "Node, Master" <node@node.ee>');
+
+ test.done();
+ },
+
+ "Invalid subject": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ subject: "tere\ntere!"
+ });
+
+ test.equal(mc._message.subject, "tere tere!");
+ test.done();
+ },
+
+ "Long header line": function(test){
+ var mc = new MailComposer();
+
+ mc._headers = {
+ From: "a very log line, \"=?UTF-8?Q?Jaanuar_Veebruar,_M=C3=A4rts?=\" <=?UTF-8?Q?m=C3=A4rts?=@xn--mrts-loa.eu>"
+ };
+
+ mc.on("data", function(chunk){
+ test.ok(chunk.toString().trim().match(/From\:\s[^\r\n]+\r\n\s+[^\r\n]+/));
+ test.done();
+ });
+ mc._composeHeader();
+
+ }
+
+};
+
+exports["Mail related"] = {
+ "Envelope": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ sender: '"Jaanuar Veebruar, Märts" <märts@märts.eu>',
+ to: '<aavik@märts.eu>, juulius@node.ee',
+ cc: '"Node, Master" <node@node.ee>'
+ });
+
+ test.deepEqual(mc._envelope, {from:[ 'märts@xn--mrts-loa.eu' ],to:[ 'aavik@xn--mrts-loa.eu', 'juulius@node.ee'], cc:['node@node.ee' ]});
+ test.done();
+ },
+
+ "User defined envelope": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ sender: '"Jaanuar Veebruar, Märts" <märts@märts.eu>',
+ envelope: {
+ from: "Andris <andris@tr.ee>",
+ to: ["Andris <andris@tr.ee>, Node <andris@node.ee>", "aavik@märts.eu", "juulius@gmail.com"],
+ cc: "trips@node.ee"
+ },
+ to: '<aavik@märts.eu>, juulius@node.ee',
+ cc: '"Node, Master" <node@node.ee>'
+ });
+
+ test.deepEqual(mc._envelope, {userDefined: true, from:[ 'andris@tr.ee' ],to:[ 'andris@tr.ee', 'andris@node.ee', 'aavik@xn--mrts-loa.eu', 'juulius@gmail.com'], "cc":['trips@node.ee']});
+ test.done();
+ },
+
+ "Add attachment": function(test){
+ var mc = new MailComposer();
+ mc.addAttachment();
+ test.equal(mc._attachments.length, 0);
+
+ mc.addAttachment({filePath:"/tmp/var.txt"});
+ test.equal(mc._attachments[0].contentType, "text/plain");
+ test.equal(mc._attachments[0].fileName, "var.txt");
+
+ mc.addAttachment({contents:"/tmp/var.txt"});
+ test.equal(mc._attachments[1].contentType, "application/octet-stream");
+ test.equal(mc._attachments[1].fileName, undefined);
+
+ mc.addAttachment({filePath:"/tmp/var.txt", fileName:"test.txt"});
+ test.equal(mc._attachments[2].fileName, "test.txt");
+
+ test.done();
+ },
+
+ "Default attachment disposition": function(test){
+ var mc = new MailComposer();
+ mc.addAttachment();
+ test.equal(mc._attachments.length, 0);
+
+ mc.addAttachment({filePath:"/tmp/var.txt"});
+ test.equal(mc._attachments[0].contentDisposition, undefined);
+
+ test.done();
+ },
+
+ "Set attachment disposition": function(test){
+ var mc = new MailComposer();
+ mc.addAttachment();
+ test.equal(mc._attachments.length, 0);
+
+ mc.addAttachment({filePath:"/tmp/var.txt", contentDisposition: "inline"});
+ test.equal(mc._attachments[0].contentDisposition, "inline");
+
+ test.done();
+ },
+
+ "Generate envelope": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ sender: '"Jaanuar Veebruar, Märts" <märts@märts.eu>, karu@ahven.ee',
+ to: '<aavik@märts.eu>, juulius@node.ee',
+ cc: '"Node, Master" <node@node.ee>'
+ });
+
+ test.deepEqual(mc.getEnvelope(), {from: 'märts@xn--mrts-loa.eu',to:[ 'aavik@xn--mrts-loa.eu', 'juulius@node.ee', 'node@node.ee' ], stamp: 'Postage paid, Par Avion'});
+ test.done();
+ },
+
+ "Generate user defined envelope": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ sender: '"Jaanuar Veebruar, Märts" <märts@märts.eu>, karu@ahven.ee',
+ to: '<aavik@märts.eu>, juulius@node.ee',
+ envelope: {
+ from: "Andris <andris@tr.ee>",
+ to: ["Andris <andris@tr.ee>, Node <andris@node.ee>", "aavik@märts.eu", "juulius@gmail.com"],
+ cc: "trips@node.ee"
+ },
+ cc: '"Node, Master" <node@node.ee>'
+ });
+
+ test.deepEqual(mc.getEnvelope(), {from: 'andris@tr.ee', to:[ 'andris@tr.ee', 'andris@node.ee', 'aavik@xn--mrts-loa.eu', 'juulius@gmail.com', 'trips@node.ee'], stamp: 'Postage paid, Par Avion'});
+ test.done();
+ },
+
+ "Generate Headers": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ sender: '"Jaanuar Veebruar, Märts" <märts@märts.eu>, karu@ahven.ee',
+ to: '<aavik@märts.eu>, juulius@node.ee',
+ cc: '"Node, Master" <node@node.ee>',
+ replyTo: 'julla@pulla.ee',
+ subject: "Tere õkva!"
+ });
+
+ mc.on("data", function(chunk){
+ chunk = (chunk || "").toString("utf-8");
+ test.ok(chunk.match(/^(?:(?:[\s]+|[a-zA-Z0-0\-]+\:)[^\r\n]+\r\n)+\r\n$/));
+ test.done();
+ });
+
+ mc._composeHeader();
+ }
+};
+
+exports["Mime tree"] = {
+ "No contents": function(test){
+ test.expect(4);
+
+ var mc = new MailComposer();
+ mc._composeMessage();
+
+ test.ok(!mc._message.tree.boundary);
+ test.equal(mc._getHeader("Content-Type").split(";").shift().trim(), "text/plain");
+ test.equal(mc._message.tree.childNodes.length, 0);
+
+ for(var i=0, len = mc._message.flatTree.length; i<len; i++){
+ if(typeof mc._message.flatTree[i] == "object"){
+ test.equal(mc._message.flatTree[i].contents, "\r\n");
+ }
+ }
+
+ test.done();
+ },
+ "Text contents": function(test){
+ test.expect(4);
+
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ body: "test"
+ });
+ mc._composeMessage();
+
+ test.ok(!mc._message.tree.boundary);
+ test.equal(mc._getHeader("Content-Type").split(";").shift().trim(), "text/plain");
+ test.equal(mc._message.tree.childNodes.length, 0);
+
+ for(var i=0, len = mc._message.flatTree.length; i<len; i++){
+ if(typeof mc._message.flatTree[i] == "object"){
+ test.equal(mc._message.flatTree[i].contents, "test");
+ }
+ }
+
+ test.done();
+ },
+ "HTML contents": function(test){
+ test.expect(4);
+
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ html: "<b>test</b>"
+ });
+ mc._composeMessage();
+
+ test.ok(!mc._message.tree.boundary);
+ test.equal(mc._getHeader("Content-Type").split(";").shift().trim(), "text/html");
+ test.equal(mc._message.tree.childNodes.length, 0);
+
+ for(var i=0, len = mc._message.flatTree.length; i<len; i++){
+ if(typeof mc._message.flatTree[i] == "object"){
+ test.equal(mc._message.flatTree[i].contents, "<b>test</b>");
+ }
+ }
+
+ test.done();
+ },
+ "HTML and text contents": function(test){
+ test.expect(5);
+
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ body: "test",
+ html: "test"
+ });
+ mc._composeMessage();
+
+ test.equal(mc._message.tree.childNodes.length, 2);
+ test.equal(mc._getHeader("Content-Type").split(";").shift().trim(), "multipart/alternative");
+ test.ok(mc._message.tree.boundary);
+
+ for(var i=0, len = mc._message.flatTree.length; i<len; i++){
+ if(typeof mc._message.flatTree[i] == "object"){
+ test.equal(mc._message.flatTree[i].contents, "test");
+ }
+ }
+
+ test.done();
+ },
+ "Attachment": function(test){
+ test.expect(5);
+
+ var mc = new MailComposer();
+ mc.setMessageOption();
+ mc.addAttachment({contents:"\r\n"});
+ mc._composeMessage();
+
+ test.equal(mc._message.tree.childNodes.length, 2);
+ test.equal(mc._getHeader("Content-Type").split(";").shift().trim(), "multipart/mixed");
+ test.ok(mc._message.tree.boundary);
+
+ for(var i=0, len = mc._message.flatTree.length; i<len; i++){
+ if(typeof mc._message.flatTree[i] == "object"){
+ test.equal(mc._message.flatTree[i].contents, "\r\n");
+ }
+ }
+
+ test.done();
+ },
+ "Several attachments": function(test){
+ test.expect(6);
+
+ var mc = new MailComposer();
+ mc.setMessageOption();
+ mc.addAttachment({contents:"\r\n"});
+ mc.addAttachment({contents:"\r\n"});
+
+ mc._composeMessage();
+
+ test.equal(mc._message.tree.childNodes.length, 3);
+ test.equal(mc._getHeader("Content-Type").split(";").shift().trim(), "multipart/mixed");
+ test.ok(mc._message.tree.boundary);
+
+ for(var i=0, len = mc._message.flatTree.length; i<len; i++){
+ if(typeof mc._message.flatTree[i] == "object"){
+ test.equal(mc._message.flatTree[i].contents, "\r\n");
+ }
+ }
+
+ test.done();
+ },
+ "Attachment and text": function(test){
+ test.expect(7);
+
+ var mc = new MailComposer();
+ mc.setMessageOption();
+ mc.addAttachment({contents:"test"});
+ mc.setMessageOption({
+ body: "test"
+ });
+ mc._composeMessage();
+
+ test.equal(mc._message.tree.childNodes.length, 2);
+ test.equal(mc._getHeader("Content-Type").split(";").shift().trim(), "multipart/mixed");
+ test.ok(mc._message.tree.boundary);
+
+ mc._message.tree.childNodes[0].headers.forEach(function(header){
+ if(header[0]=="Content-Type"){
+ test.equal(header[1].split(";").shift().trim(), "text/plain");
+ }
+ });
+
+ mc._message.tree.childNodes[1].headers.forEach(function(header){
+ if(header[0]=="Content-Type"){
+ test.equal(header[1].split(";").shift().trim(), "application/octet-stream");
+ }
+ });
+
+ for(var i=0, len = mc._message.flatTree.length; i<len; i++){
+ if(typeof mc._message.flatTree[i] == "object"){
+ test.equal(mc._message.flatTree[i].contents, "test");
+ }
+ }
+
+ test.done();
+ },
+ "Attachment and html": function(test){
+ test.expect(7);
+
+ var mc = new MailComposer();
+ mc.setMessageOption();
+ mc.addAttachment({contents:"test"});
+ mc.setMessageOption({
+ html: "test"
+ });
+ mc._composeMessage();
+
+ test.equal(mc._message.tree.childNodes.length, 2);
+ test.equal(mc._getHeader("Content-Type").split(";").shift().trim(), "multipart/mixed");
+ test.ok(mc._message.tree.boundary);
+
+ mc._message.tree.childNodes[0].headers.forEach(function(header){
+ if(header[0]=="Content-Type"){
+ test.equal(header[1].split(";").shift().trim(), "text/html");
+ }
+ });
+
+ mc._message.tree.childNodes[1].headers.forEach(function(header){
+ if(header[0]=="Content-Type"){
+ test.equal(header[1].split(";").shift().trim(), "application/octet-stream");
+ }
+ });
+
+ for(var i=0, len = mc._message.flatTree.length; i<len; i++){
+ if(typeof mc._message.flatTree[i] == "object"){
+ test.equal(mc._message.flatTree[i].contents, "test");
+ }
+ }
+
+ test.done();
+ },
+ "Attachment, html and text": function(test){
+ test.expect(11);
+
+ var mc = new MailComposer();
+ mc.addAttachment({contents:"test"});
+ mc.setMessageOption({
+ body: "test",
+ html: "test"
+ });
+ mc._composeMessage();
+
+ test.equal(mc._message.tree.childNodes.length, 2);
+ test.equal(mc._getHeader("Content-Type").split(";").shift().trim(), "multipart/mixed");
+ test.ok(mc._message.tree.boundary);
+
+ mc._message.tree.childNodes[0].headers.forEach(function(header){
+ if(header[0]=="Content-Type"){
+ test.equal(header[1].split(";").shift().trim(), "multipart/alternative");
+ }
+ });
+
+ test.ok(mc._message.tree.childNodes[0].boundary);
+
+ mc._message.tree.childNodes[0].childNodes[0].headers.forEach(function(header){
+ if(header[0]=="Content-Type"){
+ test.equal(header[1].split(";").shift().trim(), "text/plain");
+ }
+ });
+
+ mc._message.tree.childNodes[0].childNodes[1].headers.forEach(function(header){
+ if(header[0]=="Content-Type"){
+ test.equal(header[1].split(";").shift().trim(), "text/html");
+ }
+ });
+
+ mc._message.tree.childNodes[1].headers.forEach(function(header){
+ if(header[0]=="Content-Type"){
+ test.equal(header[1].split(";").shift().trim(), "application/octet-stream");
+ }
+ });
+
+ for(var i=0, len = mc._message.flatTree.length; i<len; i++){
+ if(typeof mc._message.flatTree[i] == "object"){
+ test.equal(mc._message.flatTree[i].contents, "test");
+ }
+ }
+
+ test.done();
+ }
+
+};
+
+exports["Stream parser"] = {
+ "Text": function(test){
+ var mc = new MailComposer(),
+ file = fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8");
+ mc.setMessageOption({
+ from: "andris@node.ee",
+ to:"andris@tr.ee, andris@kreata.ee",
+ subject: "õäöü",
+ body: file
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mail.from[0].address, "andris@node.ee");
+ test.equal(mail.to[0].address, "andris@tr.ee");
+ test.equal(mail.to[1].address, "andris@kreata.ee");
+ test.equal(mail.subject, "õäöü");
+ test.equal(mail.text.trim(), file.trim());
+ test.done();
+ });
+ },
+ "HTML": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ html: "<b>test</b>"
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mail.html.trim(), "<b>test</b>");
+ test.done();
+ });
+ },
+ "HTML and text": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ html: "<b>test</b>",
+ body: "test"
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mail.text.trim(), "test");
+ test.equal(mail.html.trim(), "<b>test</b>");
+ test.done();
+ });
+ },
+ "Flowed text": function(test){
+ var mc = new MailComposer({encoding:"8bit"}),
+ file = fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8");
+
+ mc.setMessageOption({
+ body: file
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mail.text.trim(), file.trim());
+ test.done();
+ });
+ },
+ "Attachment as string": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption();
+ mc.addAttachment({
+ fileName: "file.txt",
+ contents: fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8")
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9");
+ test.done();
+ });
+ },
+ "Attachment as buffer": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption();
+ mc.addAttachment({
+ fileName: "file.txt",
+ contents: fs.readFileSync(__dirname+"/textfile.txt")
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9");
+ test.done();
+ });
+ },
+ "Attachment file stream": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption();
+ mc.addAttachment({
+ fileName: "file.txt",
+ filePath: __dirname+"/textfile.txt"
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9");
+ test.done();
+ });
+ },
+ "Attachment source stream": function(test){
+ var mc = new MailComposer();
+
+ var fileStream = fs.createReadStream(__dirname+"/textfile.txt");
+
+ mc.setMessageOption();
+ mc.addAttachment({
+ fileName: "file.txt",
+ streamSource: fileStream
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9");
+ test.done();
+ });
+ },
+ "Attachment source url": function(test){
+
+ var server = http.createServer(function (req, res) {
+ if(req.url=="/textfile.txt"){
+ fs.createReadStream(__dirname+"/textfile.txt")
+ fs.createReadStream(__dirname+"/textfile.txt").pipe(res);
+ }else{
+ res.writeHead(404, {'Content-Type': 'text/plain'});
+ res.end('Not found!\n');
+ }
+ });
+ server.listen(HTTP_PORT, '127.0.0.1');
+
+ var mc = new MailComposer();
+
+ mc.setMessageOption();
+ mc.addAttachment({
+ fileName: "file.txt",
+ filePath: "http://localhost:"+HTTP_PORT+"/textfile.txt"
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9");
+ server.close();
+ test.done();
+ });
+ },
+ "Attachment source invalid url": function(test){
+
+ var server = http.createServer(function (req, res) {
+ res.writeHead(404, {'Content-Type': 'text/plain'});
+ res.end('Not found!\n');
+ })
+ server.listen(HTTP_PORT, '127.0.0.1');
+
+ var mc = new MailComposer();
+
+ mc.setMessageOption();
+ mc.addAttachment({
+ fileName: "file.txt",
+ filePath: "http://localhost:"+HTTP_PORT+"/textfile.txt"
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mail.attachments[0].checksum, "3995d423c7453e472ce0d54e475bae3e");
+ server.close();
+ test.done();
+ });
+ },
+ "Custom User-Agent": function(test){
+
+ var server = http.createServer(function (req, res) {
+ test.equal(req.headers['user-agent'], "test");
+
+ res.writeHead(200, {'Content-Type': 'text/plain'});
+ res.end('OK!\n');
+ })
+ server.listen(HTTP_PORT, '127.0.0.1');
+
+ var mc = new MailComposer();
+
+ mc.setMessageOption();
+ mc.addAttachment({
+ fileName: "file.txt",
+ filePath: "http://localhost:"+HTTP_PORT+"/textfile.txt",
+ userAgent: "test"
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ server.close();
+ test.done();
+ });
+ },
+ "escape SMTP": function(test){
+ var mc = new MailComposer({escapeSMTP: true});
+ mc.setMessageOption({
+ body: ".\r\n."
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mail.text.trim(), "..\n..");
+ test.done();
+ });
+ },
+ "don't escape SMTP": function(test){
+ var mc = new MailComposer({escapeSMTP: false});
+ mc.setMessageOption({
+ body: ".\r\n."
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mail.text.trim(), ".\n.");
+ test.done();
+ });
+ },
+ "HTML and text and attachment": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ html: "<b>test</b>",
+ body: "test"
+ });
+ mc.addAttachment({
+ fileName: "file.txt",
+ contents: fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8")
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mail.text.trim(), "test");
+ test.equal(mail.html.trim(), "<b>test</b>");
+ test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9");
+ test.done();
+ });
+ },
+ "HTML and related attachment": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ html: "<b><img src=\"cid:test@node\"/></b>"
+ });
+ mc.addAttachment({
+ fileName: "file.txt",
+ cid: "test@node",
+ contents: fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8")
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+ /*
+ var d = "";
+ mc.on("data", function(data){
+ d += data.toString();
+ })
+
+ mc.on("end", function(){
+ console.log(d);
+ });
+ */
+
+ mp.on("end", function(mail){
+ test.equal(mc._attachments.length, 0);
+ test.equal(mc._relatedAttachments.length, 1);
+ test.equal(mail.html.trim(), "<b><img src=\"cid:test@node\"/></b>");
+ test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9");
+ test.done();
+ });
+ },
+ "HTML and related plus regular attachment": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ html: "<b><img src=\"cid:test@node\"/></b>"
+ });
+ mc.addAttachment({
+ fileName: "file.txt",
+ cid: "test@node",
+ contents: fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8")
+ });
+ mc.addAttachment({
+ fileName: "file.txt",
+ contents: fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8")
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mc._attachments.length, 1);
+ test.equal(mc._relatedAttachments.length, 1);
+ test.equal(mail.html.trim(), "<b><img src=\"cid:test@node\"/></b>");
+ test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9");
+ test.equal(mail.attachments[1].checksum, "59fbcbcaf18cb9232f7da6663f374eb9");
+ test.done();
+ });
+ },
+ "HTML and text related attachment": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ html: "<b><img src=\"cid:test@node\"/></b>",
+ text:"test"
+ });
+ mc.addAttachment({
+ fileName: "file.txt",
+ cid: "test@node",
+ contents: fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8")
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mc._attachments.length, 0);
+ test.equal(mc._relatedAttachments.length, 1);
+ test.equal(mail.text.trim(), "test");
+ test.equal(mail.html.trim(), "<b><img src=\"cid:test@node\"/></b>");
+ test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9");
+ test.done();
+ });
+ },
+ "HTML, text, related+regular attachment": function(test){
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ html: "<b><img src=\"cid:test@node\"/></b>",
+ text:"test"
+ });
+ mc.addAttachment({
+ fileName: "file.txt",
+ cid: "test@node",
+ contents: fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8")
+ });
+ mc.addAttachment({
+ fileName: "file.txt",
+ contents: fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8")
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mc._attachments.length, 1);
+ test.equal(mc._relatedAttachments.length, 1);
+ test.equal(mail.text.trim(), "test");
+ test.equal(mail.html.trim(), "<b><img src=\"cid:test@node\"/></b>");
+ test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9");
+ test.equal(mail.attachments[1].checksum, "59fbcbcaf18cb9232f7da6663f374eb9");
+ test.done();
+ });
+ },
+ "References Header": function(test){
+
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ references: ["myrdo", "vyrdo"]
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.deepEqual(mail.references, ["myrdo", "vyrdo"]);
+ test.done();
+ });
+ },
+ "InReplyTo Header": function(test){
+
+ var mc = new MailComposer();
+ mc.setMessageOption({
+ inReplyTo: "test"
+ });
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mail.inReplyTo, "test");
+ test.done();
+ });
+ }
+};
+
+exports["Output buffering"] = {
+ "Use DKIM": function(test){
+ var mc = new MailComposer();
+
+ mc.setMessageOption({
+ from: "Andris Reinman <andris@node.ee>",
+ to: "Andris <andris.reinman@gmail.com>",
+ html: "<b>Hello world!</b>",
+ subject: "Hello world!"
+ });
+
+ mc.useDKIM({
+ domainName: "do-not-trust.node.ee",
+ keySelector: "dkim",
+ privateKey: fs.readFileSync(__dirname+"/test_private.pem")
+ });
+
+ mc.streamMessage();
+
+ var mp = new MailParser();
+
+ mc.pipe(mp);
+
+ mp.on("end", function(mail){
+ test.equal(mail.headers['dkim-signature'].replace(/\s/g, ""), 'v=1;a=rsa-sha256;c=relaxed/relaxed;d=do-not-trust.node.ee;q=dns/txt;s=dkim;bh=88i0PUP3tj3X/n0QT6Baw8ZPSeHZPqT7J0EmE26pjng=;h=from:subject:to:mime-version:content-type:content-transfer-encoding;b=dtxxQLotrcarEA5nbgBJLBJQxSAHcfrNxxpItcXSj68ntRvxmjXt9aPZTbVrzfRYe+xRzP2FTGpS7js8iYpAZZ2N3DBRLVp4gyyKHB1oWMkg/EV92uPtnjQ3MlHMbxC0');
+ test.done();
+ });
+ }
+}
+
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/test/test_private.pem b/tools/node_modules/nodemailer/node_modules/mailcomposer/test/test_private.pem
new file mode 100644
index 0000000..9d03266
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/test/test_private.pem
@@ -0,0 +1,12 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBywIBAAJhANCx7ncKUfQ8wBUYmMqq6ky8rBB0NL8knBf3+uA7q/CSxpX6sQ8N
+dFNtEeEd7gu7BWEM7+PkO1P0M78eZOvVmput8BP9R44ARpgHY4V0qSCdUt4rD32n
+wfjlGbh8p5ua5wIDAQABAmAm+uUQpQPTu7kg95wqVqw2sxLsa9giT6M8MtxQH7Uo
+1TF0eAO0TQ4KOxgY1S9OT5sGPVKnag258m3qX7o5imawcuyStb68DQgAUg6xv7Af
+AqAEDfYN5HW6xK+X81jfOUECMQDr7XAS4PERATvgb1B3vRu5UEbuXcenHDYgdoyT
+3qJFViTbep4qeaflF0uF9eFveMcCMQDic10rJ8fopGD7/a45O4VJb0+lRXVdqZxJ
+QzAp+zVKWqDqPfX7L93SQLzOGhdd7OECMQDeQyD7WBkjSQNMy/GF7I1qxrscIxNN
+VqGTcbu8Lti285Hjhx/sqhHHHGwU9vB7oM8CMQDKTS3Kw/s/xrot5O+kiZwFgr+w
+cmDrj/7jJHb+ykFNb7GaEkiSYqzUjKkfpweBDYECMFJUyzuuFJAjq3BXmGJlyykQ
+TweUw+zMVdSXjO+FCPcYNi6CP1t1KoESzGKBVoqA/g==
+-----END RSA PRIVATE KEY-----
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/test/test_public.pem b/tools/node_modules/nodemailer/node_modules/mailcomposer/test/test_public.pem
new file mode 100644
index 0000000..2214c80
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/test/test_public.pem
@@ -0,0 +1,5 @@
+-----BEGIN PUBLIC KEY-----
+MHwwDQYJKoZIhvcNAQEBBQADawAwaAJhANCx7ncKUfQ8wBUYmMqq6ky8rBB0NL8k
+nBf3+uA7q/CSxpX6sQ8NdFNtEeEd7gu7BWEM7+PkO1P0M78eZOvVmput8BP9R44A
+RpgHY4V0qSCdUt4rD32nwfjlGbh8p5ua5wIDAQAB
+-----END PUBLIC KEY-----
diff --git a/tools/node_modules/nodemailer/node_modules/mailcomposer/test/textfile.txt b/tools/node_modules/nodemailer/node_modules/mailcomposer/test/textfile.txt
new file mode 100644
index 0000000..3628c58
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/mailcomposer/test/textfile.txt
@@ -0,0 +1,601 @@
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+Some unicode symbols ÕÄÖÜ ↑, →, ↓, ↔, ↕, ↖, ↗, ↘, ↙, ↚, ↛, ↜, ↝, ↞, ↟, ↠, ↡, ↢, ↣, ↤, ↥, ↦
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
+
+"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar."
+
+"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?"
+
+"Welding an old pike-head, sir; there were seams and dents in it."
+
+"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?"
+
+"I think so, sir."
+
+"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?"
+
+"Aye, sir, I think I can; all seams and dents but one."
+
+"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?"
+
+"Oh! that is the one, sir! Said I not all seams and dents but one?"
+
+"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses."
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/.npmignore b/tools/node_modules/nodemailer/node_modules/simplesmtp/.npmignore
new file mode 100644
index 0000000..b512c09
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/.npmignore
@@ -0,0 +1 @@
+node_modules \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/.travis.yml b/tools/node_modules/nodemailer/node_modules/simplesmtp/.travis.yml
new file mode 100644
index 0000000..c8f68ef
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/.travis.yml
@@ -0,0 +1,12 @@
+language: node_js
+node_js:
+ - 0.6
+ - 0.8
+ - 0.9
+
+notifications:
+ email:
+ recipients:
+ - andris@node.ee
+ on_success: change
+ on_failure: change
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/LICENSE b/tools/node_modules/nodemailer/node_modules/simplesmtp/LICENSE
new file mode 100644
index 0000000..a47b0ea
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/LICENSE
@@ -0,0 +1,16 @@
+Copyright (c) 2012 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. \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/README.md b/tools/node_modules/nodemailer/node_modules/simplesmtp/README.md
new file mode 100644
index 0000000..0c4d0c4
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/README.md
@@ -0,0 +1,275 @@
+# simplesmtp
+
+This is a module to easily create custom SMTP servers and clients - use SMTP as a first class protocol in Node.JS!
+
+[![Build Status](https://secure.travis-ci.org/andris9/simplesmtp.png)](http://travis-ci.org/andris9/simplesmtp)
+
+## Support simplesmtp development
+
+[![Donate to author](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DB26KWR2BQX5W)
+
+## SMTP Server
+
+### Usage
+
+Create a new SMTP server instance with
+
+ var smtp = simplesmtp.createServer([options]);
+
+And start listening on selected port
+
+ smtp.listen(25, [function(err){}]);
+
+SMTP options can include the following:
+
+ * **name** - the hostname of the server, will be used for informational messages
+ * **debug** - if set to true, print out messages about the connection
+ * **timeout** - client timeout in milliseconds, defaults to 60 000 (60 sec.)
+ * **secureConnection** - start a server on secure connection
+ * **SMTPBanner** - greeting banner that is sent to the client on connection
+ * **requireAuthentication** - if set to true, require that the client must authenticate itself
+ * **enableAuthentication** - if set to true, client may authenticate itself but don't have to (as opposed to `requireAuthentication` that explicitly requires clients to authenticate themselves)
+ * **validateSender** - if set to true, emit `'validateSender'` with `envelope`, `email` and `callback` when the client enters `MAIL FROM:<address>`
+ * **validateRecipients** - if set to true, emit `'validateRecipient'` with `envelope`, `email` and `callback` when the client enters `RCPT TO:<address>`
+ * **maxSize** - maximum size of an e-mail in bytes (currently informational only)
+ * **credentials** - TLS credentials (`{key:'', cert:'', ca:['']}`) for the server
+ * **authMethods** - allowed authentication methods, defaults to `["PLAIN", "LOGIN"]`
+ * **disableEHLO** - if set to true, support HELO command only
+ * **ignoreTLS** - if set to true, allow client do not use STARTTLS
+
+### Example
+
+ var simplesmtp = require("simplesmtp"),
+ fs = require("fs");
+
+ var smtp = simplesmtp.createServer();
+ smtp.listen(25);
+
+ smtp.on("startData", function(envelope){
+ console.log("Message from:", envelope.from);
+ console.log("Message to:", envelope.to);
+ envelope.saveStream = fs.createWriteStream("/tmp/message.txt");
+ });
+
+ smtp.on("data", function(envelope, chunk){
+ envelope.saveStream.write(chunk);
+ });
+
+ smtp.on("dataReady", function(envelope, callback){
+ envelope.saveStream.end();
+ console.log("Incoming message saved to /tmp/message.txt");
+ callback(null, "ABC1"); // ABC1 is the queue id to be advertised to the client
+ // callback(new Error("That was clearly a spam!"));
+ });
+
+
+### Events
+
+ * **startData** *(envelope)* - DATA stream is opened by the client (`envelope` is an object with `from`, `to`, `host` and `remoteAddress` properties)
+ * **data** *(envelope, chunk)* - e-mail data chunk is passed from the client
+ * **dataReady** *(envelope, callback)* - client is finished passing e-mail data, `callback` returns the queue id to the client
+ * **authorizeUser** *(envelope, username, password, callback)* - will be emitted if `requireAuthentication` option is set to true. `callback` has two parameters *(err, success)* where `success` is Boolean and should be true, if user is authenticated successfully
+ * **validateSender** *(envelope, email, callback)* - will be emitted if `validateSender` option is set to true
+ * **validateRecipient** *(envelope, email, callback)* - will be emitted it `validataRecipients` option is set to true
+ * **close** *(envelope)* - emitted when the connection to client is closed
+
+## SMTP Client
+
+### Usage
+
+SMTP client can be created with `simplesmptp.connect(port[,host][, options])`
+where
+
+ * **port** is the port to connect to
+ * **host** is the hostname to connect to (defaults to "localhost")
+ * **options** is an optional options object (see below)
+
+### Connection options
+
+The following connection options can be used with `simplesmtp.connect`:
+
+ * **secureConnection** - use SSL
+ * **name** - the name of the client server
+ * **auth** - authentication object `{user:"...", pass:"..."}` or `{XOAuthToken:"base64data"}`
+ * **ignoreTLS** - ignore server support for STARTTLS
+ * **debug** - output client and server messages to console
+ * **instanceId** - unique instance id for debugging (will be output console with the messages)
+
+### Connection events
+
+Once a connection is set up the following events can be listened to:
+
+ * **'idle'** - the connection to the SMTP server has been successfully set up and the client is waiting for an envelope
+ * **'message'** - the envelope is passed successfully to the server and a message stream can be started
+ * **'ready'** `(success)` - the message was sent
+ * **'rcptFailed'** `(addresses)` - not all recipients were accepted (invalid addresses are included as an array)
+ * **'error'** `(err)` - An error occurred. The connection is closed and an 'end' event is emitted shortly
+ * **'end'** - connection to the client is closed
+
+### Sending an envelope
+
+When an `'idle'` event is emitted, an envelope object can be sent to the server.
+This includes a string `from` and an array of strings `to` property.
+
+Envelope can be sent with `client.useEnvelope(envelope)`
+
+ // run only once as 'idle' is emitted again after message delivery
+ client.once("idle", function(){
+ client.useEnvelope({
+ from: "me@example.com",
+ to: ["receiver1@example.com", "receiver2@example.com"]
+ });
+ });
+
+The `to` part of the envelope includes **all** recipients from `To:`, `Cc:` and `Bcc:` fields.
+
+If setting the envelope up fails, an error is emitted. If only some (not all)
+recipients are not accepted, the mail can still be sent but an `rcptFailed`
+event is emitted.
+
+ client.on("rcptFailed", function(addresses){
+ console.log("The following addresses were rejected: ", addresses);
+ });
+
+If the envelope is set up correctly a `'message'` event is emitted.
+
+### Sending a message
+
+When `'message'` event is emitted, it is possible to send mail. To do this
+you can pipe directly a message source (for example an .eml file) to the client
+or alternatively you can send the message with `client.write` calls (you also
+need to call `client.end()` once the message is completed.
+
+If you are piping a stream to the client, do not leave the `'end'` event out,
+this is needed to complete the message sequence by the client.
+
+ client.on("message", function(){
+ fs.createReadStream("test.eml").pipe(client);
+ });
+
+Once the message is delivered a `'ready'` event is emitted. The event has an
+parameter which indicates if the message was transmitted( (true) or not (false)
+and another which includes the last received data from the server.
+
+ client.on("ready", function(success, response){
+ if(success){
+ console.log("The message was transmitted successfully with "+response);
+ }
+ });
+
+### XOAUTH
+
+**simplesmtp** supports [XOAUTH](https://developers.google.com/google-apps/gmail/oauth_protocol) authentication.
+
+To use this feature you can set `XOAuthToken` param as an `auth` option
+
+ var mailOptions = {
+ ...,
+ auth:{
+ XOAuthToken: "R0VUIGh0dHBzOi8vbWFpbC5nb29...."
+ }
+ }
+
+Alternatively it is also possible to use XOAuthToken generators (supported by Nodemailer) - this
+needs to be an object with a mandatory method `generate` that takes a callback function for
+generating a XOAUTH token string. This is better for generating tokens only when needed -
+there is no need to calculate unique token for every e-mail request, since a lot of these
+might share the same connection and thus the cleint needs not to re-authenticate itself
+with another token.
+
+ var XOGen = {
+ token: "abc",
+ generate: function(callback){
+ if(1 != 1){
+ return callback(new Error("Tokens can't be generated in strange environments"));
+ }
+ callback(null, new Buffer(this.token, "utf-8").toString("base64"));
+ }
+ }
+
+ var mailOptions = {
+ ...,
+ auth:{
+ XOAuthToken: XOGen
+ }
+ }
+
+### Error types
+
+Emitted errors include the reason for failing in the `name` property
+
+ * **UnknowAuthError** - the client tried to authenticate but the method was not supported
+ * **AuthError** - the username/password used were rejected
+ * **TLSError** - STARTTLS failed
+ * **SenderError** - the sender e-mail address was rejected
+ * **RecipientError** - all recipients were rejected (if only some of the recipients are rejected, a `'rcptFailed'` event is raised instead
+
+There's also an additional property in the error object called `data` that includes
+the last response received from the server (if available for the current error type).
+
+### About reusing the connection
+
+You can reuse the same connection several times but you can't send a mail
+through the same connection concurrently. So if you catch and `'idle'` event
+lock the connection to a message process and unlock after `'ready'`.
+
+On `'error'` events you should reschedule the message and on `'end'` events
+you should recreate the connection.
+
+### Closing the client
+
+By default the client tries to keep the connection up. If you want to close it,
+run `client.quit()` - this sends a `QUIT` command to the server and closes the
+connection
+
+ client.quit();
+
+## SMTP Client Connection pool
+
+**simplesmtp** has the option for connection pooling if you want to reuse a bulk
+of connections.
+
+### Usage
+
+Create a connection pool of SMTP clients with
+
+ simplesmtp.createClientPool(port[,host][, options])
+
+where
+
+ * **port** is the port to connect to
+ * **host** is the hostname to connect to (defaults to "localhost")
+ * **options** is an optional options object (see below)
+
+### Connection options
+
+The following connection options can be used with `simplesmtp.connect`:
+
+ * **secureConnection** - use SSL
+ * **name** - the name of the client server
+ * **auth** - authentication object `{user:"...", pass:"..."}` or `{XOAuthToken:"base64data"}`
+ * **ignoreTLS** - ignore server support for STARTTLS
+ * **debug** - output client and server messages to console
+ * **maxConnections** - how many connections to keep in the pool (defaults to 5)
+
+### Send an e-mail
+
+E-mails can be sent through the pool with
+
+ pool.sendMail(mail[, callback])
+
+where
+
+ * **mail** is a [MailComposer](/andris9/mailcomposer) compatible object
+ * **callback** `(error, responseObj)` - is the callback function to run after the message is delivered or an error occured. `responseObj` may include `failedRecipients` which is an array with e-mail addresses that were rejected and `message` which is the last response from the server.
+
+### Errors
+
+In addition to SMTP client errors another error name is used
+
+ * **DeliveryError** - used if the message was not accepted by the SMTP server
+
+## License
+
+**MIT**
+
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/index.js b/tools/node_modules/nodemailer/node_modules/simplesmtp/index.js
new file mode 100644
index 0000000..3202ee3
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/index.js
@@ -0,0 +1,5 @@
+
+// expose the API to the world
+module.exports.createServer = require("./lib/server.js");
+module.exports.connect = require("./lib/client.js");
+module.exports.createClientPool = require("./lib/pool.js"); \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js b/tools/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js
new file mode 100644
index 0000000..cfe8cea
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js
@@ -0,0 +1,709 @@
+// TODO:
+// * Lisada timeout serveri ühenduse jaoks
+
+var Stream = require("stream").Stream,
+ utillib = require("util"),
+ net = require("net"),
+ tls = require("tls"),
+ oslib = require("os"),
+ starttls = require("./starttls").starttls;
+
+// monkey patch net and tls to support nodejs 0.4
+if(!net.connect && net.createConnection){
+ net.connect = net.createConnection;
+}
+
+if(!tls.connect && tls.createConnection){
+ tls.connect = tls.createConnection;
+}
+
+// expose to the world
+module.exports = function(port, host, options){
+ var connection = new SMTPClient(port, host, options);
+ process.nextTick(connection.connect.bind(connection));
+ return connection;
+};
+
+/**
+ * <p>Generates a SMTP connection object</p>
+ *
+ * <p>Optional options object takes the following possible properties:</p>
+ * <ul>
+ * <li><b>secureConnection</b> - use SSL</li>
+ * <li><b>name</b> - the name of the client server</li>
+ * <li><b>auth</b> - authentication object <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>instanceId</b> - unique instance id for debugging</li>
+ * </ul>
+ *
+ * @constructor
+ * @namespace SMTP Client module
+ * @param {Number} [port=25] Port number to connect to
+ * @param {String} [host="localhost"] Hostname to connect to
+ * @param {Object} [options] Option properties
+ */
+function SMTPClient(port, host, options){
+ Stream.call(this);
+ this.writable = true;
+ this.readable = true;
+
+ this.options = options || {};
+
+ this.port = port || (this.options.secureConnection ? 465 : 25);
+ this.host = host || "localhost";
+
+ this.options.secureConnection = !!this.options.secureConnection;
+ this.options.auth = this.options.auth || false;
+ this.options.maxConnections = this.options.maxConnections || 5;
+
+ if(!this.options.name){
+ // defaul hostname is machine hostname or [IP]
+ var defaultHostname = (oslib.hostname && oslib.hostname()) ||
+ (oslib.getHostname && oslib.getHostname()) ||
+ "";
+ if(defaultHostname.indexOf('.')<0){
+ defaultHostname = "[127.0.0.1]";
+ }
+ if(defaultHostname.match(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)){
+ defaultHostname = "["+defaultHostname+"]";
+ }
+
+ this.options.name = defaultHostname;
+ }
+
+ this._init();
+}
+utillib.inherits(SMTPClient, Stream);
+
+/**
+ * <p>Initializes instance variables</p>
+ */
+SMTPClient.prototype._init = function(){
+ /**
+ * Defines if the current connection is secure or not. If not,
+ * STARTTLS can be used if available
+ * @private
+ */
+ this._secureMode = false;
+
+ /**
+ * Ignore incoming data on TLS negotiation
+ * @private
+ */
+ this._ignoreData = false;
+
+ /**
+ * Store incomplete messages coming from the server
+ * @private
+ */
+ this._remainder = "";
+
+ /**
+ * If set to true, then this object is no longer active
+ * @private
+ */
+ this.destroyed = false;
+
+ /**
+ * The socket connecting to the server
+ * @publick
+ */
+ this.socket = false;
+
+ /**
+ * Lists supported auth mechanisms
+ * @private
+ */
+ this._supportedAuth = [];
+
+ /**
+ * Currently in data transfer state
+ * @private
+ */
+ this._dataMode = false;
+
+ /**
+ * Keep track if the client sends a leading \r\n in data mode
+ * @private
+ */
+ this._lastDataBytes = new Buffer(2);
+
+ /**
+ * Function to run if a data chunk comes from the server
+ * @private
+ */
+ this._currentAction = false;
+
+ if(this.options.ignoreTLS || this.options.secureConnection){
+ this._secureMode = true;
+ }
+};
+
+/**
+ * <p>Creates a connection to a SMTP server and sets up connection
+ * listener</p>
+ */
+SMTPClient.prototype.connect = function(){
+
+ if(this.options.secureConnection){
+ this.socket = tls.connect(this.port, this.host, {}, this._onConnect.bind(this));
+ }else{
+ this.socket = net.connect(this.port, this.host);
+ this.socket.on("connect", this._onConnect.bind(this));
+ }
+
+ this.socket.on("error", this._onError.bind(this));
+};
+
+/**
+ * <p>Upgrades the connection to TLS</p>
+ *
+ * @param {Function} callback Callbac function to run when the connection
+ * has been secured
+ */
+SMTPClient.prototype._upgradeConnection = function(callback){
+ this._ignoreData = true;
+ starttls(this.socket, (function(socket){
+ this.socket = socket;
+ this._ignoreData = false;
+ this._secureMode = true;
+ this.socket.on("data", this._onData.bind(this));
+
+ return callback(null, true);
+ }).bind(this));
+};
+
+/**
+ * <p>Connection listener that is run when the connection to
+ * the server is opened</p>
+ *
+ * @event
+ */
+SMTPClient.prototype._onConnect = function(){
+ if("setKeepAlive" in this.socket){
+ this.socket.setKeepAlive(true);
+ }else if(this.socket.encrypted && "setKeepAlive" in this.socket.encrypted){
+ this.socket.encrypted.setKeepAlive(true); // secure connection
+ }
+
+ this.socket.on("data", this._onData.bind(this));
+ this.socket.on("close", this._onClose.bind(this));
+ this.socket.on("end", this._onEnd.bind(this));
+
+ this._currentAction = this._actionGreeting;
+};
+
+/**
+ * <p>Destroys the client - removes listeners etc.</p>
+ */
+SMTPClient.prototype._destroy = function(){
+ if(this._destroyed)return;
+ this._destroyed = true;
+ this.emit("end");
+ this.removeAllListeners();
+};
+
+/**
+ * <p>'data' listener for data coming from the server</p>
+ *
+ * @event
+ * @param {Buffer} chunk Data chunk coming from the server
+ */
+SMTPClient.prototype._onData = function(chunk){
+ var str;
+
+ if(this._ignoreData || !chunk || !chunk.length){
+ return;
+ }
+
+ // Wait until end of line
+ if(chunk[chunk.length-1] != 0x0A){
+ this._remainder += chunk.toString();
+ return;
+ }else{
+ str = (this._remainder + chunk.toString()).trim();
+ this._remainder = "";
+ }
+
+ if(this.options.debug){
+ console.log("SERVER"+(this.options.instanceId?" "+
+ this.options.instanceId:"")+":\n└──"+str.replace(/\r?\n/g,"\n "));
+ }
+
+ if(typeof this._currentAction == "function"){
+ this._currentAction.call(this, str);
+ }
+};
+
+/**
+ * <p>'error' listener for the socket</p>
+ *
+ * @event
+ * @param {Error} err Error object
+ * @param {String} type Error name
+ */
+SMTPClient.prototype._onError = function(err, type, data){
+ if(type && type != "Error"){
+ err.name = type;
+ }
+ if(data){
+ err.data = data;
+ }
+ this.emit("error", err);
+ this.close();
+};
+
+/**
+ * <p>'close' listener for the socket</p>
+ *
+ * @event
+ */
+SMTPClient.prototype._onClose = function(){
+ this._destroy();
+};
+
+/**
+ * <p>'end' listener for the socket</p>
+ *
+ * @event
+ */
+SMTPClient.prototype._onEnd = function(){
+ this._destroy();
+};
+
+/**
+ * <p>Passes data stream to socket if in data mode</p>
+ *
+ * @param {Buffer} chunk Chunk of data to be sent to the server
+ */
+SMTPClient.prototype.write = function(chunk){
+ // works only in data mode
+ if(!this._dataMode){
+ // this line should never be reached but if it does, then
+ // say act like everything's normal.
+ return true;
+ }
+
+ if(typeof chunk == "string"){
+ chunk = new Buffer(chunk, "utf-8");
+ }
+
+ if(chunk.length > 2){
+ this._lastDataBytes[0] = chunk[chunk.length-2];
+ this._lastDataBytes[1] = chunk[chunk.length-1];
+ }else if(chunk.length == 1){
+ this._lastDataBytes[0] = this._lastDataBytes[1];
+ this._lastDataBytes[1] = chunk[0];
+ }
+
+ if(this.options.debug){
+ console.log("CLIENT (DATA)"+(this.options.instanceId?" "+
+ this.options.instanceId:"")+":\n└──"+chunk.toString().trim().replace(/\n/g,"\n "));
+ }
+
+ // pass the chunk to the socket
+ return this.socket.write(chunk);
+};
+
+/**
+ * <p>Indicates that a data stream for the socket is ended. Works only
+ * in data mode.</p>
+ *
+ * @param {Buffer} [chunk] Chunk of data to be sent to the server
+ */
+SMTPClient.prototype.end = function(chunk){
+ // works only in data mode
+ if(!this._dataMode){
+ // this line should never be reached but if it does, then
+ // say act like everything's normal.
+ return true;
+ }
+
+ if(chunk && chunk.length){
+ this.write(chunk);
+ }
+
+ // redirect output from the server to _actionStream
+ this._currentAction = this._actionStream;
+
+ // indicate that the stream has ended by sending a single dot on its own line
+ // if the client already closed the data with \r\n no need to do it again
+ if(this._lastDataBytes[0] == 0x0D && this._lastDataBytes[1] == 0x0A){
+ this.socket.write(new Buffer(".\r\n", "utf-8"));
+ }else if(this._lastDataBytes[1] == 0x0D){
+ this.socket.write(new Buffer("\n.\r\n"));
+ }else{
+ this.socket.write(new Buffer("\r\n.\r\n"));
+ }
+
+ // end data mode
+ this._dataMode = false;
+};
+
+/**
+ * <p>Send a command to the server, append \r\n</p>
+ *
+ * @param {String} str String to be sent to the server
+ */
+SMTPClient.prototype.sendCommand = function(str){
+ if(this.options.debug){
+ console.log("CLIENT"+(this.options.instanceId?" "+
+ this.options.instanceId:"")+":\n└──"+(str || "").toString().trim().replace(/\n/g,"\n "));
+ }
+ this.socket.write(new Buffer(str+"\r\n", "utf-8"));
+};
+
+/**
+ * <p>Sends QUIT</p>
+ */
+SMTPClient.prototype.quit = function(){
+ this.sendCommand("QUIT");
+ this._currentAction = this.close;
+};
+
+/**
+ * <p>Closes the connection to the server</p>
+ */
+SMTPClient.prototype.close = function(){
+ if(this.options.debug){
+ console.log("Closing connection to the server");
+ }
+ if(this.socket && !this.socket.destroyed){
+ this.socket.end();
+ }
+ this._destroy();
+};
+
+/**
+ * <p>Initiates a new message by submitting envelope data, starting with
+ * <code>MAIL FROM:</code> command</p>
+ *
+ * @param {Object} envelope Envelope object in the form of
+ * <code>{from:"...", to:["..."]}</code>
+ */
+SMTPClient.prototype.useEnvelope = function(envelope){
+ this._envelope = envelope || {};
+ this._envelope.from = this._envelope.from || ("anonymous@"+this.options.name);
+
+ // clone the recipients array for latter manipulation
+ this._envelope.rcptQueue = JSON.parse(JSON.stringify(this._envelope.to || []));
+ this._envelope.rcptFailed = [];
+
+ this._currentAction = this._actionMAIL;
+ this.sendCommand("MAIL FROM:<"+(this._envelope.from)+">");
+};
+
+/**
+ * <p>If needed starts the authentication, if not emits 'idle' to
+ * indicate that this client is ready to take in an outgoing mail</p>
+ */
+SMTPClient.prototype._authenticateUser = function(){
+
+ if(!this.options.auth){
+ // no need to authenticate, at least no data given
+ this._currentAction = this._actionIdle;
+ this.emit("idle"); // ready to take orders
+ return;
+ }
+
+ var auth;
+
+ if(this.options.auth.XOAuthToken && this._supportedAuth.indexOf("XOAUTH")>=0){
+ auth = "XOAUTH";
+ }else if(this.options.authMethod) {
+ auth = this.options.authMethod.toUpperCase().trim();
+ }else{
+ // use first supported
+ auth = (this._supportedAuth[0] || "PLAIN").toUpperCase().trim();
+ }
+
+ switch(auth){
+ case "XOAUTH":
+ this._currentAction = this._actionAUTHComplete;
+
+ if(typeof this.options.auth.XOAuthToken == "object" &&
+ typeof this.options.auth.XOAuthToken.generate == "function"){
+ this.options.auth.XOAuthToken.generate((function(err, XOAuthToken){
+ if(err){
+ return this._onError(err, "XOAuthTokenError");
+ }
+ this.sendCommand("AUTH XOAUTH " + XOAuthToken);
+ }).bind(this));
+ }else{
+ this.sendCommand("AUTH XOAUTH " + this.options.auth.XOAuthToken.toString());
+ }
+ return;
+ case "LOGIN":
+ this._currentAction = this._actionAUTH_LOGIN_USER;
+ this.sendCommand("AUTH LOGIN");
+ return;
+ case "PLAIN":
+ this._currentAction = this._actionAUTHComplete;
+ this.sendCommand("AUTH PLAIN "+new Buffer(
+ this.options.auth.user+"\u0000"+
+ this.options.auth.user+"\u0000"+
+ this.options.auth.pass,"utf-8").toString("base64"));
+ return;
+ }
+
+ this._onError(new Error("Unknown authentication method - "+auth), "UnknowAuthError");
+};
+
+/** ACTIONS **/
+
+/**
+ * <p>Will be run after the connection is created and the server sends
+ * a greeting. If the incoming message starts with 220 initiate
+ * SMTP session by sending EHLO command</p>
+ *
+ * @param {String} str Message from the server
+ */
+SMTPClient.prototype._actionGreeting = function(str){
+ if(str.substr(0,3) != "220"){
+ this._onError(new Error("Invalid greeting from server - "+str), false, str);
+ return;
+ }
+
+ this._currentAction = this._actionEHLO;
+ this.sendCommand("EHLO "+this.options.name);
+};
+
+/**
+ * <p>Handles server response for EHLO command. If it yielded in
+ * error, try HELO instead, otherwise initiate TLS negotiation
+ * if STARTTLS is supported by the server or move into the
+ * authentication phase.</p>
+ *
+ * @param {String} str Message from the server
+ */
+SMTPClient.prototype._actionEHLO = function(str){
+ if(str.charAt(0) != "2"){
+ // Try HELO instead
+ this._currentAction = this._actionHELO;
+ this.sendCommand("HELO "+this.options.name);
+ return;
+ }
+
+ // Detect if the server supports STARTTLS
+ if(!this._secureMode && str.match(/[ \-]STARTTLS\r?$/mi)){
+ this.sendCommand("STARTTLS");
+ this._currentAction = this._actionSTARTTLS;
+ return;
+ }
+
+ // Detect if the server supports PLAIN auth
+ if(str.match(/AUTH(?:\s+[^\n]*\s+|\s+)PLAIN/i)){
+ this._supportedAuth.push("PLAIN");
+ }
+
+ // Detect if the server supports LOGIN auth
+ if(str.match(/AUTH(?:\s+[^\n]*\s+|\s+)LOGIN/i)){
+ this._supportedAuth.push("LOGIN");
+ }
+
+ // Detect if the server supports LOGIN auth
+ if(str.match(/AUTH(?:\s+[^\n]*\s+|\s+)XOAUTH/i)){
+ this._supportedAuth.push("XOAUTH");
+ }
+
+ this._authenticateUser.call(this);
+};
+
+/**
+ * <p>Handles server response for HELO command. If it yielded in
+ * error, emit 'error', otherwise move into the authentication phase.</p>
+ *
+ * @param {String} str Message from the server
+ */
+SMTPClient.prototype._actionHELO = function(str){
+ if(str.charAt(0) != "2"){
+ this._onError(new Error("Invalid response for EHLO/HELO - "+str), false, str);
+ return;
+ }
+ this._authenticateUser.call(this);
+};
+
+/**
+ * <p>Handles server response for STARTTLS command. If there's an error
+ * try HELO instead, otherwise initiate TLS upgrade. If the upgrade
+ * succeedes restart the EHLO</p>
+ *
+ * @param {String} str Message from the server
+ */
+SMTPClient.prototype._actionSTARTTLS = function(str){
+ if(str.charAt(0) != "2"){
+ // Try HELO instead
+ this._currentAction = this._actionHELO;
+ this.sendCommand("HELO "+this.options.name);
+ return;
+ }
+
+ this._upgradeConnection((function(err, secured){
+ if(err){
+ this._onError(new Error("Error initiating TLS - "+(err.message || err)), "TLSError");
+ return;
+ }
+ if(this.options.debug){
+ console.log("Connection secured");
+ }
+
+ if(secured){
+ // restart session
+ this._currentAction = this._actionEHLO;
+ this.sendCommand("EHLO "+this.options.name);
+ }else{
+ this._authenticateUser.call(this);
+ }
+ }).bind(this));
+};
+
+/**
+ * <p>Handle the response for AUTH LOGIN command. We are expecting
+ * '334 VXNlcm5hbWU6' (base64 for 'Username:'). Data to be sent as
+ * response needs to be base64 encoded username.</p>
+ *
+ * @param {String} str Message from the server
+ */
+SMTPClient.prototype._actionAUTH_LOGIN_USER = function(str){
+ if(str != "334 VXNlcm5hbWU6"){
+ this._onError(new Error("Invalid login sequence while waiting for '334 VXNlcm5hbWU6' - "+str), false, str);
+ return;
+ }
+ this._currentAction = this._actionAUTH_LOGIN_PASS;
+ this.sendCommand(new Buffer(
+ this.options.auth.user, "utf-8").toString("base64"));
+};
+
+/**
+ * <p>Handle the response for AUTH LOGIN command. We are expecting
+ * '334 UGFzc3dvcmQ6' (base64 for 'Password:'). Data to be sent as
+ * response needs to be base64 encoded password.</p>
+ *
+ * @param {String} str Message from the server
+ */
+SMTPClient.prototype._actionAUTH_LOGIN_PASS = function(str){
+ if(str != "334 UGFzc3dvcmQ6"){
+ this._onError(new Error("Invalid login sequence while waiting for '334 UGFzc3dvcmQ6' - "+str), false, str);
+ return;
+ }
+ this._currentAction = this._actionAUTHComplete;
+ this.sendCommand(new Buffer(this.options.auth.pass, "utf-8").toString("base64"));
+};
+
+/**
+ * <p>Handles the response for authentication, if there's no error,
+ * the user can be considered logged in. Emit 'idle' and start
+ * waiting for a message to send</p>
+ *
+ * @param {String} str Message from the server
+ */
+SMTPClient.prototype._actionAUTHComplete = function(str){
+ if(str.charAt(0) != "2"){
+ this._onError(new Error("Invalid login - "+str), "AuthError", str);
+ return;
+ }
+
+ this._currentAction = this._actionIdle;
+ this.emit("idle"); // ready to take orders
+};
+
+/**
+ * <p>This function is not expected to run. If it does then there's probably
+ * an error (timeout etc.)</p>
+ *
+ * @param {String} str Message from the server
+ */
+SMTPClient.prototype._actionIdle = function(str){
+ if(Number(str.charAt(0)) > 3){
+ this._onError(new Error(str), false, str);
+ return;
+ }
+
+ // this line should never get called
+};
+
+/**
+ * <p>Handle response for a <code>MAIL FROM:</code> command</p>
+ *
+ * @param {String} str Message from the server
+ */
+SMTPClient.prototype._actionMAIL = function(str){
+ if(Number(str.charAt(0)) != "2"){
+ this._onError(new Error("Mail from command failed - " + str), "SenderError", str);
+ return;
+ }
+
+ if(!this._envelope.rcptQueue.length){
+ this._onError(new Error("Can't send mail - no recipients defined"), "RecipientError");
+ }else{
+ this._envelope.curRecipient = this._envelope.rcptQueue.shift();
+ this._currentAction = this._actionRCPT;
+ this.sendCommand("RCPT TO:<"+this._envelope.curRecipient+">");
+ }
+};
+
+/**
+ * <p>Handle response for a <code>RCPT TO:</code> command</p>
+ *
+ * @param {String} str Message from the server
+ */
+SMTPClient.prototype._actionRCPT = function(str){
+ if(Number(str.charAt(0)) != "2"){
+ // this is a soft error
+ this._envelope.rcptFailed.push(this._envelope.curRecipient);
+ }
+
+ if(!this._envelope.rcptQueue.length){
+ if(this._envelope.rcptFailed.length < this._envelope.to.length){
+ this.emit("rcptFailed", this._envelope.rcptFailed);
+ this._currentAction = this._actionDATA;
+ this.sendCommand("DATA");
+ }else{
+ this._onError(new Error("Can't send mail - all recipients were rejected"), "RecipientError");
+ return;
+ }
+ }else{
+ this._envelope.curRecipient = this._envelope.rcptQueue.shift();
+ this._currentAction = this._actionRCPT;
+ this.sendCommand("RCPT TO:<"+this._envelope.curRecipient+">");
+ }
+};
+
+/**
+ * <p>Handle response for a <code>DATA</code> command</p>
+ *
+ * @param {String} str Message from the server
+ */
+SMTPClient.prototype._actionDATA = function(str){
+ // response should be 354 but according to this issue https://github.com/eleith/emailjs/issues/24
+ // some servers might use 250 instead, so lets check for 2 or 3 as the first digit
+ if([2,3].indexOf(Number(str.charAt(0)))<0){
+ this._onError(new Error("Data command failed - " + str), false, str);
+ return;
+ }
+
+ // Emit that connection is set up for streaming
+ this._dataMode = true;
+ this._currentAction = this._actionIdle;
+ this.emit("message");
+};
+
+/**
+ * <p>Handle response for a <code>DATA</code> stream</p>
+ *
+ * @param {String} str Message from the server
+ */
+SMTPClient.prototype._actionStream = function(str){
+ if(Number(str.charAt(0)) != "2"){
+ // Message failed
+ this.emit("ready", false, str);
+ }else{
+ // Message sent succesfully
+ this.emit("ready", true, str);
+ }
+
+ // Waiting for new connections
+ this._currentAction = this._actionIdle;
+ process.nextTick(this.emit.bind(this, "idle"));
+}; \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/lib/pool.js b/tools/node_modules/nodemailer/node_modules/simplesmtp/lib/pool.js
new file mode 100644
index 0000000..7a96d68
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/lib/pool.js
@@ -0,0 +1,316 @@
+var simplesmtp = require("../index"),
+ EventEmitter = require('events').EventEmitter,
+ utillib = require("util");
+
+// expose to the world
+module.exports = function(port, host, options){
+ var pool = new SMTPConnectionPool(port, host, options);
+ return pool;
+};
+
+/**
+ * <p>Creates a SMTP connection pool</p>
+ *
+ * <p>Optional options object takes the following possible properties:</p>
+ * <ul>
+ * <li><b>secureConnection</b> - use SSL</li>
+ * <li><b>name</b> - the name of the client server</li>
+ * <li><b>auth</b> - authentication object <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>
+ * </ul>
+ *
+ * @constructor
+ * @namespace SMTP Client Pool module
+ * @param {Number} [port=25] The port number to connecto to
+ * @param {String} [host="localhost"] THe hostname to connect to
+ * @param {Object} [options] optional options object
+ */
+function SMTPConnectionPool(port, host, options){
+ EventEmitter.call(this);
+
+ /**
+ * Port number to connect to
+ * @public
+ */
+ this.port = port || 25;
+
+ /**
+ * Hostname to connect to
+ * @public
+ */
+ this.host = host || "localhost";
+
+ /**
+ * Options object
+ * @public
+ */
+ this.options = options || {};
+ this.options.maxConnections = this.options.maxConnections || 5;
+
+ /**
+ * An array of connections that are currently idle
+ * @private
+ */
+ this._connectionsAvailable = [];
+
+ /**
+ * An array of connections that are currently in use
+ * @private
+ */
+ this._connectionsInUse = [];
+
+ /**
+ * Message queue (FIFO)
+ * @private
+ */
+ this._messageQueue = [];
+
+ /**
+ * Counter for generating ID values for debugging
+ * @private
+ */
+ this._idgen = 0;
+}
+utillib.inherits(SMTPConnectionPool, EventEmitter);
+
+/**
+ * <p>Sends a message. If there's any idling connections available
+ * use one to send the message immediatelly, otherwise add to queue.</p>
+ *
+ * @param {Object} message MailComposer object
+ * @param {Function} callback Callback function to run on finish, gets an
+ * <code>error</code> object as a parameter if the sending failed
+ * and on success an object with <code>failedRecipients</code> array as
+ * a list of addresses that were rejected (if any) and
+ * <code>message</code> which indicates the last message received from
+ * the server
+ */
+SMTPConnectionPool.prototype.sendMail = function(message, callback){
+ var connection;
+
+ message.returnCallback = callback;
+
+ if(this._connectionsAvailable.length){
+ // if available connections pick one
+ connection = this._connectionsAvailable.pop();
+ this._connectionsInUse.push(connection);
+ this._processMessage(message, connection);
+ }else{
+ this._messageQueue.push(message);
+
+ if(this._connectionsAvailable.length + this._connectionsInUse.length < this.options.maxConnections){
+ this._createConnection();
+ }
+ }
+
+};
+
+/**
+ * <p>Closes all connections</p>
+ */
+SMTPConnectionPool.prototype.close = function(callback){
+ var connection;
+
+ // for some reason destroying the connections seem to be the only way :S
+ while(this._connectionsAvailable.length){
+ connection = this._connectionsAvailable.pop();
+ if(connection.socket){
+ connection.socket.destroy();
+ }
+ }
+
+ while(this._connectionsInUse.length){
+ connection = this._connectionsInUse.pop();
+ if(connection.socket){
+ connection.socket.destroy();
+ }
+ }
+
+ if(callback){
+ process.nextTick(callback);
+ }
+};
+
+/**
+ * <p>Initiates a connection to the SMTP server and adds it to the pool</p>
+ */
+SMTPConnectionPool.prototype._createConnection = function(){
+ var connectionOptions = {
+ instanceId: ++this._idgen,
+ debug: !!this.options.debug,
+ ignoreTLS: !!this.options.ignoreTLS,
+ auth: this.options.auth || false,
+ authMethod: this.options.authMethod,
+ name: this.options.name || false,
+ secureConnection: !!this.options.secureConnection
+ },
+ connection = simplesmtp.connect(this.port, this.host, connectionOptions);
+
+ connection.on("idle", this._onConnectionIdle.bind(this, connection));
+ connection.on("message", this._onConnectionMessage.bind(this, connection));
+ connection.on("ready", this._onConnectionReady.bind(this, connection));
+ connection.on("error", this._onConnectionError.bind(this, connection));
+ connection.on("end", this._onConnectionEnd.bind(this, connection));
+ connection.on("rcptFailed", this._onConnectionRCPTFailed.bind(this, connection));
+
+ this.emit('connectionCreated', connection);
+
+ // as the connection is not ready yet, add to "in use" queue
+ this._connectionsInUse.push(connection);
+};
+
+/**
+ * <p>Processes a message by assigning it to a connection object and initiating
+ * the sending process by setting the envelope</p>
+ *
+ * @param {Object} message MailComposer message object
+ * @param {Object} connection <code>simplesmtp.connect</code> connection
+ */
+SMTPConnectionPool.prototype._processMessage = function(message, connection){
+ connection.currentMessage = message;
+ message.currentConnection = connection;
+
+ // send envelope
+ connection.useEnvelope(message.getEnvelope());
+};
+
+/**
+ * <p>Will be fired on <code>'idle'</code> events by the connection, if
+ * there's a message currently in queue</p>
+ *
+ * @event
+ * @param {Object} connection Connection object that fired the event
+ */
+SMTPConnectionPool.prototype._onConnectionIdle = function(connection){
+
+ var message = this._messageQueue.shift();
+
+ if(message){
+ this._processMessage(message, connection);
+ }else{
+ for(var i=0, len = this._connectionsInUse.length; i<len; i++){
+ if(this._connectionsInUse[i] == connection){
+ this._connectionsInUse.splice(i,1); // remove from list
+ break;
+ }
+ }
+ this._connectionsAvailable.push(connection);
+ }
+};
+
+/**
+ * <p>Will be called when not all recipients were accepted</p>
+ *
+ * @event
+ * @param {Object} connection Connection object that fired the event
+ * @param {Array} addresses Failed addresses as an array of strings
+ */
+SMTPConnectionPool.prototype._onConnectionRCPTFailed = function(connection, addresses){
+ if(connection.currentMessage){
+ connection.currentMessage.failedRecipients = addresses;
+ }
+};
+
+/**
+ * <p>Will be called when the client is waiting for a message to deliver</p>
+ *
+ * @event
+ * @param {Object} connection Connection object that fired the event
+ */
+SMTPConnectionPool.prototype._onConnectionMessage = function(connection){
+ if(connection.currentMessage){
+ connection.currentMessage.streamMessage();
+ connection.currentMessage.pipe(connection);
+ }
+};
+
+/**
+ * <p>Will be called when a message has been delivered</p>
+ *
+ * @event
+ * @param {Object} connection Connection object that fired the event
+ * @param {Boolean} success True if the message was queued by the SMTP server
+ * @param {String} message Last message received from the server
+ */
+SMTPConnectionPool.prototype._onConnectionReady = function(connection, success, message){
+ var error, responseObj = {};
+ if(connection.currentMessage && connection.currentMessage.returnCallback){
+ if(success){
+
+ if(connection.currentMessage.failedRecipients){
+ responseObj.failedRecipients = connection.currentMessage.failedRecipients;
+ }
+ if(message){
+ responseObj.message = message;
+ }
+
+ connection.currentMessage.returnCallback(null, responseObj);
+
+ }else{
+ error = new Error("Message delivery failed");
+ error.name = "DeliveryError";
+ connection.currentMessage.returnCallback(error);
+ }
+ }
+ connection.currentMessage = false;
+};
+
+/**
+ * <p>Will be called when an error occurs</p>
+ *
+ * @event
+ * @param {Object} connection Connection object that fired the event
+ * @param {Object} error Error object
+ */
+SMTPConnectionPool.prototype._onConnectionError = function(connection, error){
+ var message = connection.currentMessage;
+ connection.currentMessage = false;
+
+ // clear a first message from the list, otherwise an infinite loop will emerge
+ if(!message){
+ message = this._messageQueue.shift();
+ }
+
+ if(message && message.returnCallback){
+ message.returnCallback(error);
+ }
+};
+
+/**
+ * <p>Will be called when a connection to the client is closed</p>
+ *
+ * @event
+ * @param {Object} connection Connection object that fired the event
+ */
+SMTPConnectionPool.prototype._onConnectionEnd = function(connection){
+ var removed = false, i, len;
+
+ // if in "available" list, remove
+ for(i=0, len = this._connectionsAvailable.length; i<len; i++){
+ if(this._connectionsAvailable[i] == connection){
+ this._connectionsAvailable.splice(i,1); // remove from list
+ removed = true;
+ break;
+ }
+ }
+
+ if(!removed){
+ // if in "in use" list, remove
+ for(i=0, len = this._connectionsInUse.length; i<len; i++){
+ if(this._connectionsInUse[i] == connection){
+ this._connectionsInUse.splice(i,1); // remove from list
+ removed = true;
+ break;
+ }
+ }
+ }
+
+ // if there's still unprocessed mail and available connection slots, create
+ // a new connection
+ if(this._messageQueue.length &&
+ this._connectionsInUse.length + this._connectionsAvailable.length < this.options.maxConnections){
+ this._createConnection();
+ }
+}; \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/lib/server.js b/tools/node_modules/nodemailer/node_modules/simplesmtp/lib/server.js
new file mode 100644
index 0000000..62aa650
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/lib/server.js
@@ -0,0 +1,664 @@
+/**
+ * @fileOverview This is the main file for the simplesmtp library to create custom SMTP servers
+ * @author <a href="mailto:andris@node.ee">Andris Reinman</a>
+ */
+
+var RAIServer = require("rai").RAIServer,
+ EventEmitter = require('events').EventEmitter,
+ oslib = require('os'),
+ utillib = require("util"),
+ dnslib = require("dns");
+
+// expose to the world
+module.exports = function(options){
+ return new SMTPServer(options);
+};
+
+/**
+ * <p>Constructs a SMTP server</p>
+ *
+ * <p>Possible options are:</p>
+ *
+ * <ul>
+ * <li><b>name</b> - the hostname of the server, will be used for
+ * informational messages</li>
+ * <li><b>debug</b> - if set to true, print out messages about the connection</li>
+ * <li><b>timeout</b> - client timeout in milliseconds, defaults to 60 000</li>
+ * <li><b>secureConnection</b> - start a server on secure connection</li>
+ * <li><b>SMTPBanner</b> - greeting banner that is sent to the client on connection</li>
+ * <li><b>requireAuthentication</b> - if set to true, require that the client
+ * must authenticate itself</li>
+ * <li><b>enableAuthentication</b> - if set to true, client may authenticate itself but don't have to</li>
+ * <li><b>validateSender</b> - if set to true, emit <code>'validateSender'</code>
+ * with <code>envelope</code>, <code>email</code> and <code>callback</code> when the client
+ * enters <code>MAIL FROM:&lt;address&gt;</code></li>
+ * <li><b>validateRecipients</b> - if set to true, emit <code>'validateRecipient'</code>
+ * with <code>envelope</code>, <code>email</code> and <code>callback</code> when the client
+ * enters <code>RCPT TO:&lt;address&gt;</code></li>
+ * <li><b>maxSize</b> - maximum size of an e-mail in bytes</li>
+ * <li><b>credentials</b> - TLS credentials</li>
+ * <li><b>authMethods</b> - allowed authentication methods, defaults to <code>["PLAIN", "LOGIN"]</code></li>
+ * <li><b>disableEHLO</b> - if set, support HELO only</li>
+ * <li><b>ignoreTLS</b> - if set, allow client do not use STARTTLS</li>
+ * </ul>
+ *
+ * @constructor
+ * @namespace SMTP Server module
+ * @param {Object} [options] Options object
+ */
+function SMTPServer(options){
+ EventEmitter.call(this);
+
+ this.options = options || {};
+ this.options.name = this.options.name || (oslib.hostname && oslib.hostname()) ||
+ (oslib.getHostname && oslib.getHostname()) ||
+ "127.0.0.1";
+
+ this.options.authMethods = (this.options.authMethods || ["PLAIN", "LOGIN"]).map(
+ function(auth){
+ return auth.toUpperCase().trim();
+ });
+
+ this.options.disableEHLO = !!this.options.disableEHLO;
+ this.options.ignoreTLS = !!this.options.ignoreTLS;
+
+ this.SMTPServer = new RAIServer({
+ secureConnection: !!this.options.secureConnection,
+ timeout: this.options.timeout || 60*1000,
+ disconnectOnTimeout: false,
+ debug: !!this.options.debug
+ });
+
+ this.SMTPServer.on("connect", this._createSMTPServerConnection.bind(this));
+}
+utillib.inherits(SMTPServer, EventEmitter);
+
+/**
+ * Server starts listening on defined port and hostname
+ *
+ * @param {Number} port The port number to listen
+ * @param {String} [host] The hostname to listen
+ * @param {Function} callback The callback function to run when the server is listening
+ */
+SMTPServer.prototype.listen = function(port, host, callback){
+ this.SMTPServer.listen(port, host, callback);
+};
+
+/**
+ * <p>Closes the server</p>
+ *
+ * @param {Function} callback The callback function to run when the server is closed
+ */
+SMTPServer.prototype.end = function(callback){
+ this.SMTPServer.end(callback);
+};
+
+/**
+ * <p>Creates a new {@link SMTPServerConnection} object and links the main server with
+ * the client socket</p>
+ *
+ * @param {Object} client RAISocket object to a client
+ */
+SMTPServer.prototype._createSMTPServerConnection = function(client){
+ new SMTPServerConnection(this, client);
+};
+
+/**
+ * <p>Sets up a handler for the connected client</p>
+ *
+ * <p>Restarts the state and sets up event listeners for client actions</p>
+ *
+ * @constructor
+ * @param {Object} server {@link SMTPServer} instance
+ * @param {Object} client RAISocket instance for the client
+ */
+function SMTPServerConnection(server, client){
+ this.server = server;
+ this.client = client;
+
+ this.init();
+
+ if(this.server.options.debug){
+ console.log("Connection from", this.client.remoteAddress);
+ }
+
+ this.client.on("timeout", this._onTimeout.bind(this));
+ this.client.on("error", this._onError.bind(this));
+ this.client.on("command", this._onCommand.bind(this));
+ this.client.on("end", this._onEnd.bind(this));
+
+ this.client.on("data", this._onData.bind(this));
+ this.client.on("ready", this._onDataReady.bind(this));
+
+ // Send the greeting banner
+ this.client.send("220 "+this.server.options.name+" "+(this.server.options.SMTPBanner || "ESMTP node.js simplesmtp"));
+}
+
+/**
+ * <p>Reset the envelope state</p>
+ *
+ * <p>If <code>keepAuthData</code> is set to true, then doesn't remove
+ * authentication data</p>
+ *
+ * @param {Boolean} [keepAuthData=false] If set to true keep authentication data
+ */
+SMTPServerConnection.prototype.init = function(keepAuthData){
+ this.envelope = {from: "", to:[], date: new Date()};
+
+ if(this.hostNameAppearsAs){
+ this.envelope.host = this.hostNameAppearsAs;
+ }
+
+ if(this.client.remoteAddress){
+ this.envelope.remoteAddress = this.client.remoteAddress;
+ }
+
+ if(!keepAuthData){
+ this.authentication = {
+ username: false,
+ authenticated: false,
+ state: "NORMAL"
+ };
+ }
+
+ this.envelope.authentication = this.authentication;
+};
+
+/**
+ * <p>Sends a message to the client and closes the connection</p>
+ *
+ * @param {String} [message] if set, send it to the client before disconnecting
+ */
+SMTPServerConnection.prototype.end = function(message){
+ if(message){
+ this.client.send(message);
+ }
+ this.client.end();
+};
+
+/**
+ * <p>Will be called when the connection to the client is closed</p>
+ *
+ * @event
+ */
+SMTPServerConnection.prototype._onEnd = function(){
+ if(this.server.options.debug){
+ console.log("Connection closed to", this.client.remoteAddress);
+ }
+ this.server.emit("close", this.envelope);
+};
+
+/**
+ * <p>Will be called when timeout occurs</p>
+ *
+ * @event
+ */
+SMTPServerConnection.prototype._onTimeout = function(){
+ this.end("421 4.4.2 "+this.server.options.name+" Error: timeout exceeded");
+};
+
+/**
+ * <p>Will be called when an error occurs</p>
+ *
+ * @event
+ */
+SMTPServerConnection.prototype._onError = function(){
+ this.end("421 4.4.2 "+this.server.options.name+" Error: client error");
+};
+
+/**
+ * <p>Will be called when a command is received from the client</p>
+ *
+ * <p>If there's curently an authentication process going on, route
+ * the data to <code>_handleAuthLogin</code>, otherwise act as
+ * defined</p>
+ *
+ * @event
+ * @param {String} command Command
+ * @param {Buffer} command Payload related to the command
+ */
+SMTPServerConnection.prototype._onCommand = function(command, payload){
+
+ if(this.authentication.state == "AUTHPLAINUSERDATA"){
+ this._handleAuthPlain(command.toString("utf-8").trim().split(" "));
+ return;
+ }
+
+ if(this.authentication.state == "AUTHENTICATING"){
+ this._handleAuthLogin(command);
+ return;
+ }
+
+ switch((command || "").toString().trim().toUpperCase()){
+
+ // Should not occur too often
+ case "HELO":
+ this._onCommandHELO(payload.toString("utf-8").trim());
+ break;
+
+ // Lists server capabilities
+ case "EHLO":
+ if(!this.server.options.disableEHLO){
+ this._onCommandEHLO(payload.toString("utf-8").trim());
+ }else{
+ this.client.send("502 5.5.2 Error: command not recognized");
+ }
+ break;
+
+ // Closes the connection
+ case "QUIT":
+ this.end("221 2.0.0 Goodbye!");
+ break;
+
+ // Resets the current state
+ case "RSET":
+ this._onCommandRSET();
+ break;
+
+ // Doesn't work for spam related purposes
+ case "VRFY":
+ this.client.send("252 2.1.5 Send some mail, I'll try my best");
+ break;
+
+ // Initiate an e-mail by defining a sender
+ case "MAIL":
+ this._onCommandMAIL(payload.toString("utf-8").trim());
+ break;
+
+ // Add recipients to the e-mail envelope
+ case "RCPT":
+ this._onCommandRCPT(payload.toString("utf-8").trim());
+ break;
+
+ // Authenticate if needed
+ case "AUTH":
+ this._onCommandAUTH(payload);
+ break;
+
+ // Start accepting binary data stream
+ case "DATA":
+ this._onCommandDATA();
+ break;
+
+ // Upgrade connection to secure TLS
+ case "STARTTLS":
+ this._onCommandSTARTTLS();
+ break;
+
+ // Display an error on anything else
+ default:
+ this.client.send("502 5.5.2 Error: command not recognized");
+ }
+};
+
+/**
+ * <p>Initiate an e-mail by defining a sender.</p>
+ *
+ * <p>This doesn't work if authorization is required but the client is
+ * not logged in yet.</p>
+ *
+ * <p>If <code>validateSender</code> option is set to true, then emits
+ * <code>'validateSender'</code> and wait for the callback before moving
+ * on</p>
+ *
+ * @param {String} mail Address payload in the form of "FROM:&lt;address&gt;"
+ */
+SMTPServerConnection.prototype._onCommandMAIL = function(mail){
+ var match, email, domain;
+
+ if(!this.hostNameAppearsAs){
+ return this.client.send("503 5.5.1 Error: send HELO/EHLO first");
+ }
+
+ if(this.server.options.requireAuthentication && !this.authentication.authenticated){
+ return this.client.send("530 5.5.1 Authentication Required");
+ }
+
+ if(this.envelope.from){
+ return this.client.send("503 5.5.1 Error: nested MAIL command");
+ }
+
+ if(!(match = mail.match(/^from\:\s*<([^@>]+\@([^@>]+))>$/i))){
+ return this.client.send("501 5.1.7 Bad sender address syntax");
+ }
+
+ email = match[1] || "";
+ domain = (match[2] || "").toLowerCase();
+
+ dnslib.resolveMx(domain, (function(err, addresses){
+ if(err || !addresses || !addresses.length){
+ return this.client.send("450 4.1.8 <"+email+">: Sender address rejected: Domain not found");
+ }
+
+ if(this.server.options.validateSender){
+ this.server.emit("validateSender", this.envelope, email, (function(err){
+ if(err){
+ return this.client.send("550 5.1.1 <"+email+">: Sender address rejected: User unknown in local sender table");
+ }
+
+ // force domain part to be lowercase
+ email = email.substr(0, email.length - domain.length) + domain;
+ this.envelope.from = email;
+ this.client.send("250 2.1.0 Ok");
+
+ }).bind(this));
+ }else{
+ // force domain part to be lowercase
+ email = email.substr(0, email.length - domain.length) + domain;
+ this.envelope.from = email;
+ this.client.send("250 2.1.0 Ok");
+ }
+ }).bind(this));
+};
+
+/**
+ * <p>Add recipients to the e-mail envelope</p>
+ *
+ * <p>This doesn't work if <code>MAIL</code> command is not yet executed</p>
+ *
+ * <p>If <code>validateRecipients</code> option is set to true, then emits
+ * <code>'validateRecipient'</code> and wait for the callback before moving
+ * on</p>
+ *
+ * @param {String} mail Address payload in the form of "TO:&lt;address&gt;"
+ */
+SMTPServerConnection.prototype._onCommandRCPT = function(mail){
+ var match, email, domain;
+
+ if(!this.envelope.from){
+ return this.client.send("503 5.5.1 Error: need MAIL command");
+ }
+
+ if(!(match = mail.match(/^to\:\s*<([^@>]+\@([^@>]+))>$/i))){
+ return this.client.send("501 5.1.7 Bad recipient address syntax");
+ }
+
+ email = match[1] || "";
+ domain = (match[2] || "").toLowerCase();
+
+ dnslib.resolveMx(domain, (function(err, addresses){
+ if(err || !addresses || !addresses.length){
+ return this.client.send("450 4.1.8 <"+email+">: Recipient address rejected: Domain not found");
+ }
+
+ if(this.server.options.validateRecipients){
+ this.server.emit("validateRecipient", this.envelope, email, (function(err){
+ if(err){
+ return this.client.send("550 5.1.1 <"+email+">: Recipient address rejected: User unknown in local recipient table");
+ }
+
+ // force domain part to be lowercase
+ email = email.substr(0, email.length - domain.length) + domain;
+
+ // add to recipients list
+ if(this.envelope.to.indexOf(email)<0){
+ this.envelope.to.push(email);
+ }
+ this.client.send("250 2.1.0 Ok");
+ }).bind(this));
+ }else{
+ // force domain part to be lowercase
+ email = email.substr(0, email.length - domain.length) + domain;
+
+ // add to recipients list
+ if(this.envelope.to.indexOf(email)<0){
+ this.envelope.to.push(email);
+ }
+ this.client.send("250 2.1.0 Ok");
+ }
+ }).bind(this));
+};
+
+/**
+ * <p>Switch to data mode and starts waiting for a binary data stream. Emits
+ * <code>'startData'</code>.</p>
+ *
+ * <p>If <code>RCPT</code> is not yet run, stop</p>
+ */
+SMTPServerConnection.prototype._onCommandDATA = function(){
+
+ if(!this.envelope.to.length){
+ return this.client.send("503 5.5.1 Error: need RCPT command");
+ }
+
+ this.client.startDataMode();
+ this.client.send("354 End data with <CR><LF>.<CR><LF>");
+ this.server.emit("startData", this.envelope);
+};
+
+/**
+ * <p>Resets the current state - e-mail data and authentication info</p>
+ */
+SMTPServerConnection.prototype._onCommandRSET = function(){
+ this.init();
+ this.client.send("250 2.0.0 Ok");
+};
+
+/**
+ * <p>If the server is in secure connection mode, start the authentication
+ * process. Param <code>payload</code> defines the authentication mechanism.</p>
+ *
+ * <p>Currently supported - PLAIN and LOGIN. There is no need for more
+ * complicated mechanisms (different CRAM versions etc.) since authentication
+ * is only done in secure connection mode</p>
+ *
+ * @param {Buffer} payload Defines the authentication mechanism
+ */
+SMTPServerConnection.prototype._onCommandAUTH = function(payload){
+ var method;
+
+ if(!this.server.options.requireAuthentication && !this.server.options.enableAuthentication){
+ return this.client.send("503 5.5.1 Error: authentication not enabled");
+ }
+
+ if(!this.server.options.ignoreTLS && !this.client.secureConnection){
+ return this.client.send("530 5.7.0 Must issue a STARTTLS command first");
+ }
+
+ if(this.authentication.authenticated){
+ return this.client.send("503 5.7.0 No identity changes permitted");
+ }
+
+ payload = payload.toString("utf-8").trim().split(" ");
+ method = payload.shift().trim().toUpperCase();
+
+ if(this.server.options.authMethods.indexOf(method)<0){
+ return this.client.send("535 5.7.8 Error: authentication failed: no mechanism available");
+ }
+
+ switch(method){
+ case "PLAIN":
+ this._handleAuthPlain(payload);
+ break;
+ case "LOGIN":
+ this._handleAuthLogin();
+ break;
+ }
+};
+
+/**
+ * <p>Upgrade the connection to a secure TLS connection</p>
+ */
+SMTPServerConnection.prototype._onCommandSTARTTLS = function(){
+ if(this.client.secureConnection){
+ return this.client.send("554 5.5.1 Error: TLS already active");
+ }
+
+ this.client.send("220 2.0.0 Ready to start TLS");
+
+ this.client.startTLS(this.server.options.credentials, (function(){
+ // Connection secured
+ // nothing to do here, since it is the client that should
+ // make the next move
+ }).bind(this));
+};
+
+/**
+ * <p>Retrieve hostname from the client. Not very important, since client
+ * IP is already known and the client can send fake data</p>
+ *
+ * @param {String} host Hostname of the client
+ */
+SMTPServerConnection.prototype._onCommandHELO = function(host){
+ if(!host){
+ return this.client.send("501 Syntax: EHLO hostname");
+ }else{
+ this.hostNameAppearsAs = host;
+ this.envelope.host = host;
+ }
+ this.client.send("250 "+this.server.options.name+" at your service, ["+
+ this.client.remoteAddress+"]");
+};
+
+/**
+ * <p>Retrieve hostname from the client. Not very important, since client
+ * IP is already known and the client can send fake data</p>
+ *
+ * <p>Additionally displays server capability list to the client</p>
+ *
+ * @param {String} host Hostname of the client
+ */
+SMTPServerConnection.prototype._onCommandEHLO = function(host){
+ var response = [this.server.options.name+" at your service, ["+
+ this.client.remoteAddress+"]", "8BITMIME", "ENHANCEDSTATUSCODES"];
+
+ if(this.server.options.maxSize){
+ response.push("SIZE "+this.server.options.maxSize);
+ }
+
+ if((this.client.secureConnection || this.server.options.ignoreTLS) && (this.server.options.requireAuthentication || this.server.options.enableAuthentication)){
+ response.push("AUTH "+this.server.options.authMethods.join(" "));
+ response.push("AUTH="+this.server.options.authMethods.join(" "));
+ }
+
+ if(!this.client.secureConnection){
+ response.push("STARTTLS");
+ }
+
+ if(!host){
+ return this.client.send("501 Syntax: EHLO hostname");
+ }else{
+ this.hostNameAppearsAs = host;
+ this.envelope.host = host;
+ }
+
+ this.client.send(response.map(function(feature, i, arr){
+ return "250"+(i<arr.length-1?"-":" ")+feature;
+ }).join("\r\n"));
+};
+
+/**
+ * <p>Detect login information from the payload and initiate authentication
+ * by emitting <code>'authorizeUser'</code> and waiting for its callback</p>
+ *
+ * @param {Buffer} payload AUTH PLAIN login information
+ */
+SMTPServerConnection.prototype._handleAuthPlain = function(payload){
+ if (payload.length) {
+ var userdata = new Buffer(payload.join(" "), "base64"), password;
+ userdata = userdata.toString("utf-8").split("\u0000");
+
+ if (userdata.length != 3) {
+ return this.client.send("500 5.5.2 Error: invalid userdata to decode");
+ }
+
+ this.authentication.username = userdata[1] || userdata[0] || "";
+ password = userdata[2] || "";
+
+ this.server.emit("authorizeUser",
+ this.envelope,
+ this.authentication.username,
+ password,
+ (function(err, success){
+ if(err || !success){
+ this.authentication.authenticated = false;
+ this.authentication.username = false;
+ this.authentication.state = "NORMAL";
+ return this.client.send("535 5.7.8 Error: authentication failed: generic failure");
+ }
+ this.client.send("235 2.7.0 Authentication successful");
+ this.authentication.authenticated = true;
+ this.authentication.state = "AUTHENTICATED";
+ }).bind(this));
+ } else {
+ if(this.authentication.state == "NORMAL"){
+ this.authentication.state = "AUTHPLAINUSERDATA";
+ this.client.send("334");
+ }
+ }
+
+};
+
+/**
+ * <p>Sets authorization state to "AUTHENTICATING" and reuqests for the
+ * username and password from the client</p>
+ *
+ * <p>If username and password are set initiate authentication
+ * by emitting <code>'authorizeUser'</code> and waiting for its callback</p>
+ *
+ * @param {Buffer} payload AUTH LOGIN login information
+ */
+SMTPServerConnection.prototype._handleAuthLogin = function(payload){
+ if(this.authentication.state == "NORMAL"){
+ this.authentication.state = "AUTHENTICATING";
+ this.client.send("334 VXNlcm5hbWU6");
+ }else if(this.authentication.state == "AUTHENTICATING"){
+ if(this.authentication.username === false){
+ this.authentication.username = new Buffer(payload, "base64").toString("utf-8");
+ this.client.send("334 UGFzc3dvcmQ6");
+ }else{
+ this.authentication.state = "VERIFYING";
+ this.server.emit("authorizeUser",
+ this.envelope,
+ this.authentication.username,
+ new Buffer(payload, "base64").toString("utf-8"),
+ (function(err, success){
+ if(err || !success){
+ this.authentication.authenticated = false;
+ this.authentication.username = false;
+ this.authentication.state = "NORMAL";
+ return this.client.send("535 5.7.8 Error: authentication failed: generic failure");
+ }
+ this.client.send("235 2.7.0 Authentication successful");
+ this.authentication.authenticated = true;
+ this.authentication.state = "AUTHENTICATED";
+ }).bind(this));
+ }
+
+ }
+};
+
+/**
+ * <p>Emits the data received from the client with <code>'data'</code>
+ *
+ * @event
+ * @param {Buffer} chunk Binary data sent by the client on data mode
+ */
+SMTPServerConnection.prototype._onData = function(chunk){
+ this.server.emit("data", this.envelope, chunk);
+};
+
+/**
+ * <p>If the data stream ends, emit <code>'dataReady'</code>and wait for
+ * the callback, only if server listened for it.</p>
+ *
+ * @event
+ */
+SMTPServerConnection.prototype._onDataReady = function(){
+ if (this.server.listeners('dataReady').length) {
+ this.server.emit("dataReady", this.envelope, (function(err, code){
+ this.init(true); //reset state, keep auth data
+
+ if(err){
+ this.client.send("550 FAILED");
+ }else{
+ this.client.send("250 2.0.0 Ok: queued as "+(code || "FOOBARBAZ"));
+ }
+
+ }).bind(this));
+ } else {
+ this.init(true); //reset state, keep auth data
+ this.client.send("250 2.0.0 Ok: queued as FOOBARBAZ");
+ }
+};
+
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/lib/starttls.js b/tools/node_modules/nodemailer/node_modules/simplesmtp/lib/starttls.js
new file mode 100644
index 0000000..836f0f6
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/lib/starttls.js
@@ -0,0 +1,112 @@
+// SOURCE: https://gist.github.com/848444
+
+// Target API:
+//
+// var s = require('net').createStream(25, 'smtp.example.com');
+// s.on('connect', function() {
+// require('starttls')(s, options, function() {
+// if (!s.authorized) {
+// s.destroy();
+// return;
+// }
+//
+// s.end("hello world\n");
+// });
+// });
+//
+//
+
+/**
+ * @namespace Client STARTTLS module
+ * @name starttls
+ */
+module.exports.starttls = starttls;
+
+/**
+ * <p>Upgrades a socket to a secure TLS connection</p>
+ *
+ * @memberOf starttls
+ * @param {Object} socket Plaintext socket to be upgraded
+ * @param {Function} callback Callback function to be run after upgrade
+ */
+function starttls(socket, callback) {
+ var sslcontext, pair, cleartext;
+
+ socket.removeAllListeners("data");
+ sslcontext = require('crypto').createCredentials();
+ pair = require('tls').createSecurePair(sslcontext, false);
+ cleartext = pipe(pair, socket);
+
+ pair.on('secure', function() {
+ var verifyError = (pair._ssl || pair.ssl).verifyError();
+
+ if (verifyError) {
+ cleartext.authorized = false;
+ cleartext.authorizationError = verifyError;
+ } else {
+ cleartext.authorized = true;
+ }
+
+ callback(cleartext);
+ });
+
+ cleartext._controlReleased = true;
+ return pair;
+}
+
+function forwardEvents(events, emitterSource, emitterDestination) {
+ var map = [], name, handler;
+
+ for(var i = 0, len = events.length; i < len; i++) {
+ name = events[i];
+
+ handler = forwardEvent.bind(emitterDestination, name);
+
+ map.push(name);
+ emitterSource.on(name, handler);
+ }
+
+ return map;
+}
+
+function forwardEvent() {
+ this.emit.apply(this, arguments);
+}
+
+function removeEvents(map, emitterSource) {
+ for(var i = 0, len = map.length; i < len; i++){
+ emitterSource.removeAllListeners(map[i]);
+ }
+}
+
+function pipe(pair, socket) {
+ pair.encrypted.pipe(socket);
+ socket.pipe(pair.encrypted);
+
+ pair.fd = socket.fd;
+
+ var cleartext = pair.cleartext;
+
+ cleartext.socket = socket;
+ cleartext.encrypted = pair.encrypted;
+ cleartext.authorized = false;
+
+ function onerror(e) {
+ if (cleartext._controlReleased) {
+ cleartext.emit('error', e);
+ }
+ }
+
+ var map = forwardEvents(["timeout", "end", "close", "drain", "error"], socket, cleartext);
+
+ function onclose() {
+ socket.removeListener('error', onerror);
+ socket.removeListener('close', onclose);
+ removeEvents(map,socket);
+ }
+
+ socket.on('error', onerror);
+ socket.on('close', onclose);
+
+ return cleartext;
+} \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/.npmignore b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/.npmignore
new file mode 100644
index 0000000..b512c09
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/.npmignore
@@ -0,0 +1 @@
+node_modules \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/.travis.yml b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/.travis.yml
new file mode 100644
index 0000000..cf1b970
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/.travis.yml
@@ -0,0 +1,12 @@
+language: node_js
+node_js:
+ - 0.4
+ - 0.6
+ - 0.7
+
+notifications:
+ email:
+ recipients:
+ - andris@node.ee
+ on_success: change
+ on_failure: change
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/LICENSE b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/LICENSE
new file mode 100644
index 0000000..a47b0ea
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/LICENSE
@@ -0,0 +1,16 @@
+Copyright (c) 2012 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. \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/README.md b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/README.md
new file mode 100644
index 0000000..542409e
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/README.md
@@ -0,0 +1,163 @@
+# RAI - Request-Answer-Interface
+
+**rai** is a node.js module to easily generate text based command line servers.
+When a client sends something to the server, the first word of the line is
+treated as a command and the rest of the line as binary payload.
+
+[![Build Status](https://secure.travis-ci.org/andris9/rai.png)](http://travis-ci.org/andris9/rai)
+
+In addition to line based commands, there's also a data mode, to transmit
+everygting received. And there's also an option to switch to TLS mode for
+secure connections.
+
+This way it is trivial to create SMTP, POP3 or similar servers.
+
+## Documentation
+
+Autogenerated docs can be seen [here](http://node.ee/raidoc/).
+
+## Installation
+
+ npm install rai
+
+## Usage
+
+### Simple server
+
+ var RAIServer = require("rai").RAIServer;
+
+ // create a RAIServer on port 1234
+ var server = new RAIServer();
+ server.listen(1234);
+
+ // Start listening for client connections
+ server.on("connect", function(client){
+
+ // Greet the client
+ client.send("Hello!");
+
+ // Wait for a command
+ client.on("command", function(command, payload){
+
+ if(command == "STATUS"){
+ client.send("Status is OK!");
+ }else if(command == "QUIT"){
+ client.send("Goodbye");
+ client.end();
+ }else{
+ client.send("Unknown command");
+ }
+
+ });
+
+ });
+
+Server only emits `'connect'` and `'error'` events, while the client
+objects emit `'timeout'`, `'error'` and `'end'` in addition to data
+related events.
+
+### Starting a server
+
+Server can be started with `new RAIServer([options])` where options is an optional
+parameters object with the following properties:
+
+ * **debug** - if set to true print traffic to console
+ * **disconnectOnTimeout** - if set to true close the connection on disconnect
+ * **secureConnection** - if set to true close the connection on disconnect
+ * **credentials** - credentials for secureConnection and STARTTLS
+ * **timeout** - timeout in milliseconds for disconnecting the client, defaults to 0 (no timeout)
+
+Once the server has been set up, it can start listening for client connections
+with `server.listen(port[, hostname][, callback])`. Callback function gets an error
+object as a parameter if the listening failed.
+
+ var server = new RAIServer();
+ server.listen(25); // start listening for port 25 on "localhost"
+
+### Closing server
+
+Server can be closed with `server.end([callback])` where callback is run when
+the server is finally closed.
+
+### Sending data
+
+Data can be sent with `client.send(data)` where `data` is either a String or
+a Buffer. `"\r\n"` is automatically appended to the data.
+
+ client.send("Greetings!");
+
+### Forcing connection close
+
+Connections can be ended with `client.end()`
+
+ if(command == "QUIT"){
+ client.send("Good bye!");
+ client.end();
+ }
+
+### TLS mode
+
+TLS can be switched on with `client.startTLS([credentials][, callback])` and the status can
+be listened with `'tls'` (emitted when secure connection is established)
+
+`credentials` is an object with strings of pem encoded `key`, `cert` and optionally an
+array `ca`. If `credentials` is not supplied, an autogenerated value is used.
+
+ if(command == "STARTTLS"){
+ client.startTLS();
+ }
+
+ client.on("tls", function(){
+ console.log("Switched to secure connection");
+ });
+
+If `callback` is not set `'tls'` will be emitted on connection upgrade.
+
+### Data mode
+
+Data mode can be turned on with `client.startDataMode([endSequence])` and incoming
+chunks can be received with `'data'`. The end of data mode can be detected by
+`'ready'`.
+
+`endSequence` is a String for matching the end (entire line) of the data stream.
+By default it's `"."` which is suitable for SMTP and POP3.
+
+ if(command == "DATA"){
+ client.send("End data with <CR><LF>.<CR><LF>");
+ client.startDataMode();
+ }
+
+ client.on("data", function(chunk){
+ console.log("Data from client:", chunk);
+ });
+
+ client.on("ready", function(){
+ client.send("Data received");
+ });
+
+## Testing
+
+There is a possibility to set up a mockup client which sends a batch of commands
+one by one to the server and returns the last response.
+
+ var runClientMockup = require("rai").runClientMockup;
+
+ var cmds = ["EHLO FOOBAR", "STARTTLS", "QUIT"];
+ runClientMockup(25, "mail.hot.ee", cmds, function(resp){
+ console.log("Final:", resp.toString("utf-8").trim());
+ });
+
+`runClientMockup` has he following parameters in the following order:
+
+ * **port** - Port number
+ * **host** - Hostname to connect to
+ * **commands** - Command list (an array) to be sent to server
+ * **callback** - Callback function to run on completion
+ * **debug** - if set to true log all input/output
+
+Response from the callback function is a Buffer and contains the
+last data received from the server
+
+## License
+
+**MIT** \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/cert/cert.pem b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/cert/cert.pem
new file mode 100644
index 0000000..c72af8a
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/cert/cert.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICWzCCAcQCCQDBn+mBQGOp/jANBgkqhkiG9w0BAQUFADByMQswCQYDVQQGEwJF
+RTEOMAwGA1UECBMFSGFyanUxEDAOBgNVBAcTB1RhbGxpbm4xDzANBgNVBAoTBkty
+ZWF0YTEPMA0GA1UEAxMGYW5kcmlzMR8wHQYJKoZIhvcNAQkBFhBhbmRyaXNAa3Jl
+YXRhLmVlMB4XDTEyMDExNzE0NDYxNloXDTEyMDIxNjE0NDYxNlowcjELMAkGA1UE
+BhMCRUUxDjAMBgNVBAgTBUhhcmp1MRAwDgYDVQQHEwdUYWxsaW5uMQ8wDQYDVQQK
+EwZLcmVhdGExDzANBgNVBAMTBmFuZHJpczEfMB0GCSqGSIb3DQEJARYQYW5kcmlz
+QGtyZWF0YS5lZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAv+G/z03hCpY1
+xN31H0uco4ehyoj1cGGzRVPBPcjVVgbjhuK5Azsp284yVdCTqiB2fWBMjhMOv11S
+9rtIS7sR7AZIXH+aoyaOJYhysnl2zlGAvIfSL+F3pt78oWnVo42pD2UJae3VkAcK
+KP4zu5TWPim4+rUznbgl1Gas6f5zYoECAwEAATANBgkqhkiG9w0BAQUFAAOBgQAq
+jTrU4GPFwBbOJluYDy46qm+2G35A1jL8Ko7ZRgefc68OXkmuFnavjU4YkWV9i52c
+JjQ/MeY0llZaLIQsCsoVCWLVekoqU24V2KA4GkK4WJiax7vgUjy/z/4bfmXa1Xzd
+fc0blopaiBATshEyt+xN5u/acFVfftc4HCb4TarG8g==
+-----END CERTIFICATE-----
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/cert/key.pem b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/cert/key.pem
new file mode 100644
index 0000000..288cf85
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/cert/key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQC/4b/PTeEKljXE3fUfS5yjh6HKiPVwYbNFU8E9yNVWBuOG4rkD
+OynbzjJV0JOqIHZ9YEyOEw6/XVL2u0hLuxHsBkhcf5qjJo4liHKyeXbOUYC8h9Iv
+4Xem3vyhadWjjakPZQlp7dWQBwoo/jO7lNY+Kbj6tTOduCXUZqzp/nNigQIDAQAB
+AoGBAKAwHqk6Iv1rmUfY5KJTxVjgCjnDTOOdLMRbv5+M4k0HQzuAW2RPKArQgUUS
+87O7li/lDQQu9MjdaD2C7EAM1E/7G0bQ02sHtmwT1+2IyvlbRS+Ki6HgJ3fPfbdC
+8+bJHF+Rlksp+fu0eOGLRAcUMH7fwTeqrfGg3b1eIEgt7ZKBAkEA8bgPILaiN7Nt
+JtXhJBC8C5DUj28x/tyR81SkFfYXHwTf8VGiGcufGEVS9YNcYS6ef0WrDrtL4akg
+KlyRdQPmZQJBAMs36lfEngWk1lqho9mR7pu9LA+eChIGvMWshlO1bdOU6ObLhcva
+v/DhjlTgDLy772VGZR5DyCrJrFtRoGDBy+0CQQDiKHpO+1IPl5s6yMZbviSTFbEr
+erhmYu1TpA/aVGQRq7fzy5NFW1TBmqsh9wQKEVpOblq779XxjxH/UJjvyPRZAkAK
+yBOpxmev2vf4ZP0BbQmgv5+X0IWuQSdAwY9633RNNmhI3mFh2GA4km7vt9dVKA9i
+ayKwQV5cTsjTK3h7yaxdAkA2FiEAbkx0ODWOsYv7Ey/G6wBK04CYVuG3Abe8Siul
+H0sKoLmOZRWG4UyjUCfVRH4LiV+4IaV5XPwOqw5zHuns
+-----END RSA PRIVATE KEY-----
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/examples/smtp.js b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/examples/smtp.js
new file mode 100644
index 0000000..4ee2763
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/examples/smtp.js
@@ -0,0 +1,73 @@
+var RAIServer = require("../lib/rai").RAIServer;
+
+var server = new RAIServer({debug: true, timeout:25*1000});
+
+server.listen(1234, function(err){
+ console.log(err || "listening on port 1234...")
+});
+
+server.on("connection", function(socket){
+
+ socket.send("220 foo.bar"); // send banner greeting
+
+ socket.on("command", function(command, payload){
+
+ command = (command || "").toString().toUpperCase().trim();
+
+ switch(command){
+ case "EHLO":
+ socket.send("250-foo.bar at your service\r\n"+
+ "250-PIPELINING\r\n" +
+ "250-8BITMIME\r\n"+
+ "250 STARTTLS");
+ break;
+ case "STARTTLS":
+ socket.send("220 Ready to start TLS");
+ socket.startTLS();
+ break;
+ case "MAIL":
+ socket.send("250 Ok");
+ break;
+ case "RCPT":
+ socket.send("250 Ok");
+ break;
+ case "DATA":
+ socket.send("354 End with <CR><LF>.<CR><LF>");
+ socket.startDataMode();
+ break;
+ case "QUIT":
+ socket.send("221 Good bye");
+ socket.end();
+ break;
+ default:
+ socket.send("500 Unknown command");
+ }
+
+ });
+
+ socket.on("tls", function(data){
+ console.log("TLS STARTED");
+ });
+
+ socket.on("data", function(data){
+ console.log("MAIL DATA", data);
+ });
+
+ socket.on("ready", function(data){
+ console.log("DATA READY");
+ socket.send("250 Ok: queued as FOOBAR");
+ });
+
+ socket.on("timeout", function(data){
+ console.log("TIMEOUT");
+ });
+
+ socket.on("error", function(err){
+ console.log("ERROR:", err.message || err);
+ });
+
+ socket.on("end", function(){
+ console.log("Connection closed");
+ });
+
+}); \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/all.css b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/all.css
new file mode 100644
index 0000000..c253cb0
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/all.css
@@ -0,0 +1,358 @@
+/* TABLE OF CONTENTS:
+ * - Browser reset
+ * - HTML elements
+ * - JsDoc styling
+ */
+
+
+
+
+
+
+/*
+ * BEGIN BROWSER RESET
+ */
+
+body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,p,pre,form,fieldset,input,textarea,p,blockquote,th,td {
+ margin:0;
+ padding:0
+}
+html {
+ height:100%;
+ overflow:-moz-scrollbars-vertical;
+ overflow-x:auto
+}
+table {
+ border:0;
+ border-collapse:collapse;
+ border-spacing:0
+}
+fieldset,img {
+ border:0
+}
+address,caption,cite,code,dfn,em,strong,th,var {
+ font-style:normal;
+ font-weight:normal
+}
+em,cite {
+ font-style:italic
+}
+strong {
+ font-weight:bold
+}
+ol,ul {
+ list-style:none
+}
+caption,th {
+ text-align:left
+}
+h1,h2,h3,h4,h5,h6 {
+ font-size:100%;
+ font-weight:normal;
+ margin:0;
+ padding:0
+}
+q:before,q:after {
+ content:''
+}
+abbr,acronym {
+ border:0
+}
+section,article,header,footer,nav,aside,hgroup {
+ display:block
+}
+
+/*
+ * END BROWSER RESET
+ */
+
+
+
+
+
+
+/*
+ * HTML ELEMENTS
+ */
+
+@font-face {
+ font-family: 'M1m';
+ src: url('fonts/mplus-1m-regular-webfont.eot');
+ src: local('☺'), url('fonts/mplus-1m-regular-webfont.woff') format('woff'), url('fonts/mplus-1m-regular-webfont.ttf') format('truetype'), url('fonts/mplus-1m-regular-webfont.svg#webfontVd14f4NN') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'M1m';
+ src: url('fonts/mplus-1m-bold-webfont.eot');
+ src: local('☺'), url('fonts/mplus-1m-bold-webfont.woff') format('woff'), url('fonts/mplus-1m-bold-webfont.ttf') format('truetype'), url('fonts/mplus-1m-bold-webfont.svg#webfontIjI5mZqE') format('svg');
+ font-weight: bold;
+ font-style: normal;
+}
+
+
+
+* {
+ line-height: 1.4em;
+}
+
+html {
+ font-size: 100%;
+}
+
+body {
+ font-size: 0.75em;
+ padding: 15px 0;
+ background: #eee;
+ background-image: -moz-linear-gradient(left, #dddddd, #f9f9f9) fixed;
+ background-image: -webkit-gradient(linear,left bottom,right bottom,color-stop(0, #dddddd),color-stop(1, #f9f9f9)) fixed;
+ }
+
+body,
+input,
+select,
+textarea {
+ color: #000;
+ font-family: Arial, Geneva, sans-serif;
+}
+
+a:link,
+a:hover,
+a:active,
+a:visited {
+ color: #19199e;
+}
+a:hover,
+a:focus {
+ color: #00f;
+ text-decoration: none;
+}
+
+p {
+ margin: 0 0 1.5em 0;
+}
+
+/*
+ * END HTML ELEMENTS
+ */
+
+
+
+/*
+ * BEGIN HACK
+ */
+
+div.containerMain:after,
+div.safeBox:after {
+ content:"";
+ display:block;
+ height:0;
+ clear:both;
+}
+
+/*
+ * END HACK
+ */
+
+
+
+/*
+ * BEGIN JSDOC
+ */
+
+/* Start menu */
+div.index *.heading1 {
+ margin-bottom: 0.5em;
+ border-bottom: 1px solid #999999;
+ font-family: M1m, Arial, sans-serif;
+ font-size: 1.6em;
+ letter-spacing: 1px;
+ line-height: 1.3em;
+}
+
+div.index div.menu {
+ background-color: #FFFFFF;
+}
+*+html div.index div.menu {
+ background-color: #FFFFFF;
+}
+* html div.index div.menu {
+ background-color: #FFFFFF;
+}
+
+div.index div.menu div {
+ text-align: left;
+}
+
+div.index div.menu a {
+ text-decoration: none;
+}
+div.index div.menu a:hover {
+ text-decoration: underline;
+}
+
+div.index ul.classList {
+ padding-left: 0;
+}
+
+div.index ul.classList a {
+ display: block;
+ margin: 1px 0;
+ padding: 4px 0 2px 10px;
+ text-indent: -10px;
+}
+
+div.index div.fineprint {
+ color: #777;
+ font-size: 0.9em;
+}
+div.index div.fineprint a {
+ color: #777;
+}
+/* End menu */
+
+
+
+/* Start content */
+div.content ul {
+ padding-left: 0;
+}
+
+div.content *.classTitle {
+ font-size: 1.2em;
+ font-weight: bold;
+ line-height: 1em;
+}
+
+div.content *.classTitle span {
+ display: block;
+ font-size: 2em;
+ letter-spacing: 2px;
+ line-height: 1em;
+ padding-top: 5px;
+ text-shadow: 1px 1px 1px #999999;
+ word-wrap: break-word;
+}
+
+div.content p.summary {
+ font-size: 1.25em;
+}
+
+div.content ul *.classname a,
+div.content ul *.filename a {
+ font-family: Consolas, "Courier New", Courier, monospace;
+ text-decoration: none;
+ font-weight: bold;
+}
+div.content ul *.classname a:hover,
+div.content ul *.filename a:hover {
+ text-decoration: underline;
+}
+
+div.content div.props {
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ background: #fff;
+ background: -moz-linear-gradient(top, rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0.2)); /* FF3.6 */
+ background: -webkit-gradient(linear,left top,left bottom,color-stop(0, rgba(255, 255, 255, 0.7)),color-stop(1, rgba(255, 255, 255, 0.2)));
+ -moz-box-shadow: 0px 0px 10px #ccc;
+ -webkit-box-shadow: 0px 0px 5px #bbb;
+ box-shadow: 0px 0px 5px #bbb;
+}
+
+
+
+*.sectionTitle {
+ font-family: M1m, sans-serif;
+ font-size: 1.6em;
+ letter-spacing: 1px;
+}
+
+table.summaryTable td,
+table.summaryTable th {
+ vertical-align: top;
+}
+table.summaryTable tr:last-child td {
+ padding-bottom: 0;
+}
+
+table.summaryTable th {
+ font-weight: bold;
+}
+
+table.summaryTable td.attributes {
+ font-family: Consolas, "Courier New", Courier, monospace;
+ color: #666;
+}
+
+table.summaryTable td.nameDescription div.fixedFont {
+ font-weight: bold;
+}
+
+table.summaryTable div.description {
+ color: #333;
+}
+
+
+
+dl.detailList dt {
+ font-weight: bold;
+}
+
+dl.inheritsList dd + dt {
+ margin-top: 10px;
+}
+
+dl.inheritsList dd {
+ display: inline;
+}
+
+
+
+.fixedFont {
+ font-family: Consolas, "Courier New", Courier, monospace;
+}
+
+.fixedFont.heading {
+ font-size: 1.25em;
+ line-height: 1.1em
+}
+
+.fixedFont.heading + .description {
+ font-size: 1.2em;
+}
+
+.fixedFont.heading .light,
+.fixedFont.heading .lighter {
+ font-weight: bold;
+}
+
+pre.code {
+ overflow: auto;
+ font-family: Consolas, "Courier New", Courier, monospace;
+ background: #eee;
+}
+/* Start content */
+
+
+
+/* Start general styles */
+.light {
+ color: #666;
+}
+
+.lighter {
+ color: #999;
+}
+
+span.break {
+ font-size: 1px;
+ line-height: 1px;
+}
+/* End general styles */
+
+/*
+ * END JSDOC
+ */
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.eot b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.eot
new file mode 100644
index 0000000..6c64f8d
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.eot
Binary files differ
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.svg b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.svg
new file mode 100644
index 0000000..5129512
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.svg
@@ -0,0 +1,134 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata>
+This is a custom SVG webfont generated by Font Squirrel.
+Foundry URL : http://mplus-fonts.sourceforge.jp
+</metadata>
+<defs>
+<font id="webfontIjI5mZqE" horiz-adv-x="500" >
+<font-face units-per-em="1000" ascent="860" descent="-140" />
+<missing-glyph horiz-adv-x="500" />
+<glyph unicode=" " />
+<glyph unicode="!" d="M165 730h170l-20 -495h-130zM170 0v150h160v-150h-160z" />
+<glyph unicode="&#x22;" d="M270 780h160l-30 -320h-100zM70 780h160l-30 -320h-100z" />
+<glyph unicode="#" d="M20 165v120h62l24 185h-51v120h67l18 140h135l-18 -140h45l18 140h135l-18 -140h43v-120h-59l-24 -185h48v-120h-64l-21 -165h-135l21 165h-45l-21 -165h-135l21 165h-46zM217 285h45l24 185h-45z" />
+<glyph unicode="$" d="M357 397q55 -32 76.5 -74t21.5 -108q0 -190 -192 -199v-101h-110v112q-51 16 -88 43v140q38 -35 88 -55v191q-53 33 -75.5 75.5t-22.5 103.5q0 89 50 138.5t142 51.5v100h110v-112q42 -12 78 -33v-135q-32 25 -78 42v-180zM247 445v149q-54 -9 -54 -69q0 -55 54 -80z M263 295v-157q52 13 52 77q0 55 -52 80z" />
+<glyph unicode="%" d="M40 310l420 220v-110l-420 -220v110zM160 740q70 0 110 -41t40 -119t-40 -119t-110 -41t-110 41t-40 119t40 119t110 41zM340 310q70 0 110 -41t40 -119t-40 -119t-110 -41t-110 41t-40 119t40 119t110 41zM160 518q38 0 38 62t-38 62t-38 -62t38 -62zM340 88q38 0 38 62 t-38 62t-38 -62t38 -62z" />
+<glyph unicode="&#x26;" d="M235 615q-23 0 -36.5 -14.5t-13.5 -40.5q0 -18 7.5 -37.5t33.5 -65.5q35 30 47 52.5t12 50.5q0 26 -13.5 40.5t-36.5 14.5zM118 368q-47 77 -62.5 116t-15.5 76q0 80 51.5 130t138.5 50t141 -50.5t54 -129.5q0 -114 -130 -220l55 -94v2v132h125v-225q-16 -25 -41 -52 l61 -103h-150l-15 24q-66 -34 -130 -34q-88 0 -136.5 45.5t-48.5 134.5q0 99 103 198zM269 124l-77 125q-27 -37 -27 -74q0 -60 65 -60q20 0 39 9z" />
+<glyph unicode="'" d="M160 780h180l-35 -320h-110z" />
+<glyph unicode="(" d="M100 300q0 136 50 256.5t144 213.5h126q-196 -194 -196 -470t196 -470h-126q-94 93 -144 213.5t-50 256.5z" />
+<glyph unicode=")" d="M400 300q0 -136 -50 -256.5t-144 -213.5h-126q196 194 196 470t-196 470h126q94 -93 144 -213.5t50 -256.5z" />
+<glyph unicode="*" d="M193 750h114l-4 -144l136 48l35 -109l-138 -40l88 -115l-93 -67l-81 119l-81 -119l-93 67l88 115l-138 40l35 109l136 -48z" />
+<glyph unicode="+" d="M315 545v-195h135v-110h-135v-195h-130v195h-135v110h135v195h130z" />
+<glyph unicode="," d="M180 190h190l-130 -320h-120z" />
+<glyph unicode="-" d="M90 240v110h320v-110h-320z" />
+<glyph unicode="." d="M155 0v190h190v-190h-190z" />
+<glyph unicode="/" d="M465 730l-310 -770h-120l310 770h120z" />
+<glyph unicode="0" d="M250 740q73 0 117.5 -32.5t68.5 -116t24 -226.5t-24 -226.5t-68.5 -116t-117.5 -32.5t-117.5 32.5t-68.5 116t-24 226.5t24 226.5t68.5 116t117.5 32.5zM171 317l142 248q-9 34 -24.5 47t-38.5 13q-28 0 -44.5 -19.5t-26 -77.5t-9.5 -163q0 -33 1 -48zM183 179 q9 -41 25.5 -57.5t41.5 -16.5q28 0 44.5 19.5t26 77.5t9.5 163q0 47 -1 67z" />
+<glyph unicode="1" d="M240 592l-2 1l-173 -91v128l175 100h140v-730h-140v592z" />
+<glyph unicode="2" d="M220 122v-2h220v-120h-380v120q127 141 181 237t54 173q0 43 -21 66.5t-59 23.5q-31 0 -74 -22t-81 -58v130q78 70 185 70q90 0 140 -51t50 -149q0 -180 -215 -418z" />
+<glyph unicode="3" d="M290 608v2h-230v120h385v-120l-170 -178v-2h10q79 0 122 -51.5t43 -153.5q0 -121 -54 -178t-166 -57q-51 0 -81.5 6.5t-78.5 28.5v130q80 -45 150 -45q46 0 68 27t22 88q0 58 -26 76.5t-114 18.5h-40v120z" />
+<glyph unicode="4" d="M400 150v-150h-135v150h-245v120l230 460h150v-460h80v-120h-80zM265 270v255h-2l-127 -253v-2h129z" />
+<glyph unicode="5" d="M202 455q36 19 82 19q161 0 161 -239q0 -245 -230 -245q-76 0 -150 35v130q80 -45 140 -45q51 0 75.5 29t24.5 96t-14.5 93t-46.5 26q-34 0 -64 -34h-110l10 410h345v-120h-220l-5 -155h2z" />
+<glyph unicode="6" d="M295 625q-54 0 -76.5 -34.5t-28.5 -135.5h2q45 35 98 35q92 0 133.5 -54.5t41.5 -185.5q0 -141 -51 -200.5t-159 -59.5q-75 0 -119 28.5t-67.5 101t-23.5 200.5q0 162 25 254t75 129t135 37q66 0 135 -20v-125q-57 30 -120 30zM255 107q39 0 55.5 29.5t16.5 113.5 q0 79 -14 104.5t-53 25.5q-38 0 -56.5 -29.5t-18.5 -100.5q0 -81 17 -112t53 -31z" />
+<glyph unicode="7" d="M55 730h390v-120q-113 -273 -200 -610h-146q92 325 216 608v2h-260v120z" />
+<glyph unicode="8" d="M258 625q-41 0 -59.5 -20.5t-18.5 -64.5q0 -74 75 -105q33 16 51.5 43.5t18.5 61.5q0 40 -18 62.5t-49 22.5zM250 -10q-105 0 -162.5 52t-57.5 148q0 116 105 179v2q-42 31 -66 80t-24 104q0 87 53.5 136t151.5 49t151.5 -48.5t53.5 -136.5q0 -98 -100 -164v-2 q115 -62 115 -199q0 -96 -58 -148t-162 -52zM242 105q93 0 93 100q0 75 -103 115q-33 -17 -52.5 -48.5t-19.5 -66.5q0 -48 22.5 -74t59.5 -26z" />
+<glyph unicode="9" d="M205 110q55 0 77 32.5t28 132.5h-2q-45 -35 -98 -35q-89 0 -132 57.5t-43 192.5q0 131 51 190.5t159 59.5q79 0 123 -27.5t65.5 -99.5t21.5 -203q0 -162 -25 -254t-75 -129t-135 -37q-66 0 -135 20v130q57 -30 120 -30zM245 623q-39 0 -55.5 -28t-16.5 -105 q0 -83 15.5 -111.5t51.5 -28.5q75 0 75 140q0 73 -17 103t-53 30z" />
+<glyph unicode=":" d="M160 390v190h180v-190h-180zM160 0v190h180v-190h-180z" />
+<glyph unicode=";" d="M170 190h190l-130 -320h-120zM170 390v190h180v-190h-180z" />
+<glyph unicode="&#x3c;" d="M445 470l-320 -174v-2l320 -174v-120l-400 225v140l400 225v-120z" />
+<glyph unicode="=" d="M50 125v110h400v-110h-400zM50 362v103h400v-103h-400z" />
+<glyph unicode="&#x3e;" d="M55 470v120l400 -225v-140l-400 -225v120l320 174v2z" />
+<glyph unicode="?" d="M460 575q0 -36 -12.5 -69t-25 -51t-38.5 -49q-25 -30 -38 -48.5t-27.5 -52.5t-18.5 -70h-130q0 49 17 94.5t32 66.5t44 57q21 25 30.5 38t19 33.5t9.5 40.5q0 58 -82 58t-180 -53v130q95 40 200 40q95 0 147.5 -44t52.5 -121zM155 0v150h160v-150h-160z" />
+<glyph unicode="@" d="M285 635q-72 0 -108.5 -62.5t-36.5 -207.5q0 -265 160 -265q58 0 125 30v-115q-70 -25 -150 -25q-260 0 -260 375q0 194 64 284.5t191 90.5q99 0 152 -51.5t53 -148.5v-325q-28 -28 -76 -46.5t-94 -18.5q-69 0 -102 49t-33 166q0 114 31.5 164.5t93.5 50.5q36 0 68 -25h2 v15q0 26 -23.5 45.5t-56.5 19.5zM290 365q0 -72 8 -93.5t29 -21.5q20 0 28 18v147q0 41 -6 53t-25 12t-26.5 -22t-7.5 -93z" />
+<glyph unicode="A" d="M249 620h-2l-55 -335h112zM323 170h-150l-28 -170h-140l165 730h160l165 -730h-144z" />
+<glyph unicode="B" d="M190 445h15q59 0 85 20.5t26 64.5q0 49 -23 71t-73 22q-17 0 -30 -5v-173zM190 330v-218q20 -5 45 -5q51 0 75 27.5t24 90.5q0 57 -25.5 81t-88.5 24h-30zM470 210q0 -220 -240 -220q-93 0 -180 15v720q92 15 190 15q210 0 210 -185q0 -62 -32 -105t-83 -54v-2 q57 -10 96 -61.5t39 -122.5z" />
+<glyph unicode="C" d="M30 365q0 195 64.5 285t190.5 90q80 0 150 -25v-115q-70 25 -125 25q-74 0 -109.5 -58.5t-35.5 -201.5q0 -260 150 -260q57 0 125 30v-120q-70 -25 -150 -25q-260 0 -260 375z" />
+<glyph unicode="D" d="M344 365q0 142 -30 198.5t-94 56.5q-23 0 -40 -5v-500q17 -5 40 -5q63 0 93.5 55.5t30.5 199.5zM480 365q0 -144 -28.5 -226.5t-83.5 -115.5t-148 -33q-92 0 -180 15v720q88 15 180 15q141 0 200.5 -82t59.5 -293z" />
+<glyph unicode="E" d="M210 610v-165h220v-115h-220v-210h230v-120h-370v730h370v-120h-230z" />
+<glyph unicode="F" d="M220 330v-330h-140v730h360v-120h-220v-165h210v-115h-210z" />
+<glyph unicode="G" d="M310 625q-82 0 -116 -55t-34 -205q0 -143 32 -201.5t93 -58.5q27 0 48 10v215h-98v115h230v-415q-83 -40 -180 -40q-260 0 -260 375q0 196 69.5 285.5t215.5 89.5q70 0 130 -25v-115q-72 25 -130 25z" />
+<glyph unicode="H" d="M318 330h-140v-330h-138v730h138v-280h140v280h142v-730h-142v330z" />
+<glyph unicode="I" d="M430 0h-360v115h108v500h-108v115h360v-115h-108v-500h108v-115z" />
+<glyph unicode="J" d="M410 730v-515q0 -126 -48.5 -175.5t-166.5 -49.5q-86 0 -155 30v130q29 -18 68 -30t67 -12q50 0 71 26.5t21 95.5v385h-147v115h290z" />
+<glyph unicode="K" d="M192 330h-2v-330h-140v730h140v-300h2l135 300h148l-160 -345l165 -385h-150z" />
+<glyph unicode="L" d="M230 730v-610h210v-120h-350v730h140z" />
+<glyph unicode="M" d="M338 500h-2l-38 -300h-100l-38 300h-2v-500h-133v730h167l59 -400h2l59 400h163v-730h-137v500z" />
+<glyph unicode="N" d="M187 460h-2v-460h-140v730h147l125 -460h2v460h136v-730h-143z" />
+<glyph unicode="O" d="M250 740q121 0 175.5 -84t54.5 -291t-54.5 -291t-175.5 -84t-175.5 84t-54.5 291t54.5 291t175.5 84zM250 108q52 0 75 53.5t23 203.5t-23 203.5t-75 53.5t-75 -53.5t-23 -203.5t23 -203.5t75 -53.5z" />
+<glyph unicode="P" d="M334 503q0 120 -104 120q-23 0 -40 -5v-235q18 -5 40 -5q53 0 78.5 28t25.5 97zM470 503q0 -127 -57 -184.5t-173 -57.5q-26 0 -50 5v-266h-140v725q90 15 185 15q122 0 178.5 -56t56.5 -181z" />
+<glyph unicode="Q" d="M250 740q121 0 175.5 -84t54.5 -291q0 -257 -92 -333v-2q39 -22 68.5 -74t33.5 -106h-145q-15 81 -36.5 110.5t-58.5 29.5q-121 0 -175.5 84t-54.5 291t54.5 291t175.5 84zM250 108q52 0 75 53.5t23 203.5t-23 203.5t-75 53.5t-75 -53.5t-23 -203.5t23 -203.5t75 -53.5z " />
+<glyph unicode="R" d="M465 513q0 -151 -98 -199l-1 -2q27 -19 58 -118l61 -194h-145l-57 204q-12 43 -25.5 57.5t-42.5 14.5h-30v-276h-140v725q90 15 185 15q124 0 179.5 -53.5t55.5 -173.5zM185 393h30q64 0 89 24.5t25 95.5q0 58 -25.5 84t-78.5 26q-23 0 -40 -5v-225z" />
+<glyph unicode="S" d="M440 575q-84 48 -165 48q-41 0 -65 -21t-24 -57q0 -71 69 -100q116 -48 160.5 -103t44.5 -142q0 -210 -225 -210q-100 0 -180 50v135q83 -68 173 -68q94 0 94 88q0 76 -77 110q-108 46 -151.5 99.5t-43.5 135.5q0 90 57 145t153 55q102 0 180 -35v-130z" />
+<glyph unicode="T" d="M320 615v-615h-140v615h-145v115h430v-115h-145z" />
+<glyph unicode="U" d="M250 -10q-112 0 -161 54t-49 186v500h142v-460q0 -101 14.5 -131.5t55.5 -30.5t55.5 30.5t14.5 131.5v460h138v-500q0 -132 -49 -186t-161 -54z" />
+<glyph unicode="V" d="M253 110l92 620h140l-155 -730h-160l-155 730h144l92 -620h2z" />
+<glyph unicode="W" d="M164 190h2l38 440h100l38 -440h2l15 540h126l-45 -730h-157l-34 420h-2l-34 -420h-153l-45 730h134z" />
+<glyph unicode="X" d="M251 470h2l74 260h145l-132 -360l135 -370h-152l-74 270h-2l-74 -270h-148l135 370l-132 360h149z" />
+<glyph unicode="Y" d="M251 415h2l84 315h148l-165 -455v-275h-140v275l-165 455h152z" />
+<glyph unicode="Z" d="M290 613v2h-235v115h390v-115l-235 -498v-2h235v-115h-390v115z" />
+<glyph unicode="[" d="M410 675h-170v-750h170v-95h-290v940h290v-95z" />
+<glyph unicode="\" d="M35 730h120l310 -770h-120z" />
+<glyph unicode="]" d="M90 675v95h290v-940h-290v95h170v750h-170z" />
+<glyph unicode="^" d="M251 655h-2l-111 -375h-123l145 450h180l145 -450h-123z" />
+<glyph unicode="_" d="M40 -170v88h420v-88h-420z" />
+<glyph unicode="`" d="M90 810h190l100 -320h-120z" />
+<glyph unicode="a" d="M65 495q39 14 95 24.5t90 10.5q111 0 155.5 -45t44.5 -160v-325h-127l-2 65h-2q-49 -75 -134 -75q-68 0 -106.5 42t-38.5 118q0 88 63.5 136.5t186.5 48.5h25v10q0 40 -16 56.5t-54 16.5q-32 0 -86.5 -11.5t-93.5 -26.5v115zM315 245h-25q-59 0 -89.5 -23t-30.5 -62 q0 -31 15 -48t40 -17q90 0 90 130v20z" />
+<glyph unicode="b" d="M45 730h137v-275h2q49 75 116 75q83 0 129 -66.5t46 -203.5q0 -133 -47.5 -201.5t-127.5 -68.5q-35 0 -62.5 17.5t-56.5 62.5h-2l-2 -70h-132v730zM338 260q0 150 -78 150q-80 0 -80 -145v-10q0 -145 80 -145q35 0 56.5 36.5t21.5 113.5z" />
+<glyph unicode="c" d="M305 420q-115 0 -115 -160q0 -163 120 -163q60 0 120 28v-110q-68 -25 -140 -25q-116 0 -178 67.5t-62 202.5t60 202.5t175 67.5q67 0 135 -25v-110q-61 25 -115 25z" />
+<glyph unicode="d" d="M455 0h-132l-2 70h-2q-29 -45 -56.5 -62.5t-62.5 -17.5q-80 0 -127.5 68.5t-47.5 201.5q0 137 46 203.5t129 66.5q67 0 116 -75h2v275h137v-730zM162 260q0 -77 21.5 -113.5t56.5 -36.5q80 0 80 145v10q0 145 -80 145q-78 0 -78 -150z" />
+<glyph unicode="e" d="M182 206q7 -62 33 -85.5t80 -23.5q52 0 135 28v-110q-84 -25 -155 -25q-112 0 -173.5 68t-61.5 202q0 270 220 270q200 0 200 -270q0 -31 -2 -54h-276zM181 310h142q-1 63 -15.5 88t-47.5 25q-41 0 -58 -23t-21 -90z" />
+<glyph unicode="f" d="M60 391v109h100v45q0 104 40.5 149.5t129.5 45.5q56 0 110 -15v-110q-36 16 -80 16q-37 0 -50 -20.5t-13 -85.5v-25h143v-109h-143v-391h-137v391h-100z" />
+<glyph unicode="g" d="M323 75h-2q-45 -75 -116 -75q-78 0 -126.5 66.5t-48.5 193.5q0 137 46 203.5t129 66.5q35 0 62.5 -17.5t56.5 -62.5h2l2 70h132v-505q0 -245 -240 -245q-81 0 -150 25v115q76 -33 145 -33q55 0 81.5 34t26.5 114v50zM167 260q0 -70 22 -105t56 -35q80 0 80 135v10 q0 145 -80 145q-78 0 -78 -150z" />
+<glyph unicode="h" d="M50 730h137v-275h2q47 75 126 75t112 -47.5t33 -172.5v-310h-135v290q0 74 -12.5 98t-47.5 24t-56.5 -43.5t-21.5 -131.5v-237h-137v730z" />
+<glyph unicode="i" d="M110 520h240v-413h100v-107h-370v107h130v306h-100v107zM190 630v130h160v-130h-160z" />
+<glyph unicode="j" d="M225 -20v433h-110v107h250v-540q0 -68 -10.5 -106t-44 -63t-87.5 -33t-148 -8v109q39 0 60.5 0.5t41 5t27 9.5t13.5 18t7 27.5t1 40.5zM205 630v130h160v-130h-160z" />
+<glyph unicode="k" d="M480 520l-185 -250l185 -270h-162l-131 224v-224h-137v730h137v-418l133 208h160z" />
+<glyph unicode="l" d="M310 190q0 -68 9 -80.5t56 -12.5q31 0 75 6v-108q-44 -5 -100 -5q-111 0 -145.5 32.5t-34.5 137.5v463h-120v107h260v-540z" />
+<glyph unicode="m" d="M360 0v340q0 40 -21 40q-8 0 -12.5 -5t-7 -22.5t-2.5 -52.5v-300h-130v340q0 40 -21 40q-8 0 -12.5 -5t-7 -22.5t-2.5 -52.5v-300h-134v520h120l2 -65h2q15 34 39.5 54.5t48.5 20.5q28 0 45 -16t32 -59h2q42 75 99 75q48 0 69 -36t21 -134v-360h-130z" />
+<glyph unicode="n" d="M50 520h132l2 -70h2q49 80 129 80q79 0 112 -47.5t33 -172.5v-310h-135v290q0 74 -12.5 98t-47.5 24t-56.5 -43.5t-21.5 -131.5v-237h-137v520z" />
+<glyph unicode="o" d="M250 530q220 0 220 -270t-220 -270t-220 270t220 270zM250 97q44 0 62 33.5t18 129.5t-18 129.5t-62 33.5t-62 -33.5t-18 -129.5t18 -129.5t62 -33.5z" />
+<glyph unicode="p" d="M179 70h-2v-290h-137v740h132l2 -70h2q29 45 56.5 62.5t62.5 17.5q83 0 129 -66.5t46 -203.5q0 -133 -47.5 -201.5t-127.5 -68.5q-71 0 -116 80zM333 260q0 150 -78 150q-80 0 -80 -145v-10q0 -145 80 -145q35 0 56.5 36.5t21.5 113.5z" />
+<glyph unicode="q" d="M321 70q-45 -80 -116 -80q-80 0 -127.5 68.5t-47.5 201.5q0 137 46 203.5t129 66.5q35 0 62.5 -17.5t56.5 -62.5h2l2 70h132v-740h-137v290h-2zM167 260q0 -77 21.5 -113.5t56.5 -36.5q80 0 80 145v10q0 145 -80 145q-78 0 -78 -150z" />
+<glyph unicode="r" d="M375 416q-69 0 -111 -52t-42 -144v-220h-137v520h135v-85h2q36 53 70.5 74t82.5 21q36 0 70 -10v-115q-36 11 -70 11z" />
+<glyph unicode="s" d="M265 418q-73 0 -73 -43q0 -22 14.5 -35t48.5 -20q109 -21 149.5 -60t40.5 -115q0 -74 -50.5 -114.5t-144.5 -40.5q-107 0 -190 35v120q87 -43 165 -43q45 0 64 11.5t19 36.5q0 22 -14 34t-54 21q-99 21 -142 62.5t-43 112.5t49 110.5t146 39.5q99 0 180 -30v-115 q-87 33 -165 33z" />
+<glyph unicode="t" d="M445 500v-109h-158v-201q0 -61 10.5 -74.5t57.5 -13.5q43 0 80 17v-114q-50 -15 -110 -15q-98 0 -136.5 36.5t-38.5 133.5v231h-105v109h105v190h137v-190h158z" />
+<glyph unicode="u" d="M445 0h-132l-2 70h-2q-50 -80 -124 -80q-77 0 -108.5 44.5t-31.5 165.5v320h135v-300q0 -70 11 -91t44 -21q73 0 73 175v237h137v-520z" />
+<glyph unicode="v" d="M251 90h2l79 430h138l-130 -520h-180l-130 520h142z" />
+<glyph unicode="w" d="M343 120h2l29 400h116l-70 -520h-137l-37 358h-2l-31 -358h-133l-70 520h124l29 -400h2l39 400h100z" />
+<glyph unicode="x" d="M251 335h2l69 185h143l-125 -260l125 -260h-152l-64 180h-2l-64 -180h-148l125 260l-125 260h147z" />
+<glyph unicode="y" d="M254 170h2l87 350h142l-237 -740h-138l85 230l-170 510h142z" />
+<glyph unicode="z" d="M275 411h-210v109h370v-109l-210 -300v-2h210v-109h-370v109l210 300v2z" />
+<glyph unicode="{" d="M187 301v-2q58 -24 85.5 -62t27.5 -100v-112q0 -73 12 -86.5t75 -13.5h53v-95h-107q-80 0 -116.5 37t-36.5 123v147q0 61 -22 88t-68 27h-40v96h40q46 0 68 27t22 88v147q0 86 36.5 123t116.5 37h107v-95h-53q-63 0 -75 -13.5t-12 -86.5v-112q0 -62 -27.5 -100t-85.5 -62 z" />
+<glyph unicode="|" d="M188 -220v1030h124v-1030h-124z" />
+<glyph unicode="}" d="M313 301q-58 24 -85.5 62t-27.5 100v112q0 73 -12 86.5t-75 13.5h-53v95h107q80 0 116.5 -37t36.5 -123v-147q0 -61 22 -88t68 -27h40v-96h-40q-46 0 -68 -27t-22 -88v-147q0 -86 -36.5 -123t-116.5 -37h-107v95h53q63 0 75 13.5t12 86.5v112q0 62 27.5 100t85.5 62v2z " />
+<glyph unicode="~" d="M40 568v107q45 35 100 35q63 0 131 -50q49 -37 84 -37q49 0 105 51v-107q-45 -35 -100 -35q-63 0 -131 50q-49 37 -84 37q-49 0 -105 -51z" />
+<glyph unicode="&#xa0;" />
+<glyph unicode="&#xa5;" d="M251 415h2l84 315h148l-132 -365h97v-95h-130v-65h130v-95h-130v-110h-140v110h-130v95h130v65h-130v95h97l-132 365h152z" />
+<glyph unicode="&#xad;" d="M90 240v110h320v-110h-320z" />
+<glyph unicode="&#x2000;" horiz-adv-x="407" />
+<glyph unicode="&#x2001;" horiz-adv-x="815" />
+<glyph unicode="&#x2002;" horiz-adv-x="407" />
+<glyph unicode="&#x2003;" horiz-adv-x="815" />
+<glyph unicode="&#x2004;" horiz-adv-x="271" />
+<glyph unicode="&#x2005;" horiz-adv-x="203" />
+<glyph unicode="&#x2006;" horiz-adv-x="135" />
+<glyph unicode="&#x2007;" horiz-adv-x="135" />
+<glyph unicode="&#x2008;" horiz-adv-x="101" />
+<glyph unicode="&#x2009;" horiz-adv-x="163" />
+<glyph unicode="&#x200a;" horiz-adv-x="45" />
+<glyph unicode="&#x2010;" d="M90 240v110h320v-110h-320z" />
+<glyph unicode="&#x2011;" d="M90 240v110h320v-110h-320z" />
+<glyph unicode="&#x2013;" d="M50 240v110h400v-110h-400z" />
+<glyph unicode="&#x2014;" d="M10 240v110h480v-110h-480z" />
+<glyph unicode="&#x2018;" d="M305 460h-190l130 320h120z" />
+<glyph unicode="&#x2019;" d="M190 780h190l-130 -320h-120z" />
+<glyph unicode="&#x201c;" d="M405 460h-170l130 320h100zM195 460h-170l130 320h100z" />
+<glyph unicode="&#x201d;" d="M300 780h170l-130 -320h-100zM90 780h170l-130 -320h-100z" />
+<glyph unicode="&#x2026;" horiz-adv-x="1000" d="M72 270v190h190v-190h-190zM405 270v190h190v-190h-190zM738 270v190h190v-190h-190z" />
+<glyph unicode="&#x202f;" horiz-adv-x="163" />
+<glyph unicode="&#x205f;" horiz-adv-x="203" />
+<glyph unicode="&#x2122;" horiz-adv-x="1000" d="M838 500h-2l-38 -300h-100l-38 300h-2v-500h-133v730h167l59 -400h2l59 400h163v-730h-137v500zM320 615v-615h-140v615h-145v115h430v-115h-145z" />
+</font>
+</defs></svg> \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.ttf b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.ttf
new file mode 100644
index 0000000..0cf54cb
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.ttf
Binary files differ
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.woff b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.woff
new file mode 100644
index 0000000..f90475d
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.woff
Binary files differ
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.eot b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.eot
new file mode 100644
index 0000000..a53f8b5
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.eot
Binary files differ
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.svg b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.svg
new file mode 100644
index 0000000..3c835a3
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.svg
@@ -0,0 +1,134 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata>
+This is a custom SVG webfont generated by Font Squirrel.
+Foundry URL : http://mplus-fonts.sourceforge.jp
+</metadata>
+<defs>
+<font id="webfontVd14f4NN" horiz-adv-x="500" >
+<font-face units-per-em="1000" ascent="860" descent="-140" />
+<missing-glyph horiz-adv-x="500" />
+<glyph unicode=" " />
+<glyph unicode="!" d="M200 730h100l-10 -515h-80zM195 0v130h110v-130h-110z" />
+<glyph unicode="&#x22;" d="M275 780h100l-20 -280h-60zM125 780h100l-20 -280h-60z" />
+<glyph unicode="#" d="M40 188v72h77l29 228h-71v72h80l21 170h82l-21 -170h76l21 170h82l-21 -170h65v-72h-74l-29 -228h68v-72h-77l-23 -188h-82l23 188h-76l-23 -188h-82l23 188h-68zM199 260h76l29 228h-76z" />
+<glyph unicode="$" d="M293 311v-214q58 21 58 108q0 71 -58 106zM293 19v-104h-76v101q-70 6 -137 49v95q65 -57 137 -69v251q-77 31 -109.5 75.5t-32.5 117.5q0 76 37 122.5t105 55.5v102h76v-102q69 -8 127 -38v-90q-52 38 -127 52v-237q77 -31 109.5 -76.5t32.5 -118.5q0 -163 -142 -186z M217 429v207q-58 -18 -58 -101q0 -73 58 -106z" />
+<glyph unicode="%" d="M60 260l380 290v-80l-380 -290v80zM160 740q61 0 95.5 -41t34.5 -119t-34.5 -119t-95.5 -41t-95.5 41t-34.5 119t34.5 119t95.5 41zM340 310q61 0 95.5 -41t34.5 -119t-34.5 -119t-95.5 -41t-95.5 41t-34.5 119t34.5 119t95.5 41zM160 488q52 0 52 92t-52 92t-52 -92 t52 -92zM340 58q52 0 52 92t-52 92t-52 -92t52 -92z" />
+<glyph unicode="&#x26;" d="M228 665q-38 0 -60.5 -20t-22.5 -55q0 -29 12.5 -59t53.5 -95q59 51 79 83.5t20 70.5q0 33 -22 54t-60 21zM151 385l-9 14q-47 71 -63.5 111.5t-16.5 79.5q0 66 45 108t118 42t119 -42t46 -108q0 -57 -30.5 -106.5t-106.5 -112.5l119 -183v217h80v-253q-13 -28 -26 -46 l69 -106h-87l-33 49q-69 -59 -175 -59q-82 0 -128.5 46t-46.5 129q0 107 126 220zM331 115l-137 206q-84 -79 -84 -153q0 -51 27 -77t78 -26q70 0 116 50z" />
+<glyph unicode="'" d="M195 780h110l-25 -280h-60z" />
+<glyph unicode="(" d="M125 315q0 275 194 455h76q-196 -184 -196 -455t196 -455h-76q-194 180 -194 455z" />
+<glyph unicode=")" d="M375 315q0 -275 -194 -455h-76q196 184 196 455t-196 455h76q194 -180 194 -455z" />
+<glyph unicode="*" d="M214 750h72l-3 -169l160 55l22 -68l-161 -50l101 -135l-58 -42l-97 138l-97 -138l-58 42l101 135l-161 50l22 68l160 -55z" />
+<glyph unicode="+" d="M291 555v-214h149v-72h-149v-214h-82v214h-149v72h149v214h82z" />
+<glyph unicode="," d="M210 150h120l-110 -280h-70z" />
+<glyph unicode="-" d="M100 269v72h300v-72h-300z" />
+<glyph unicode="." d="M185 0v150h130v-150h-130z" />
+<glyph unicode="/" d="M452 730l-332 -770h-72l332 770h72z" />
+<glyph unicode="0" d="M250 740q48 0 82 -18t59 -60t37 -115.5t12 -181.5t-12 -181.5t-37 -115.5t-59 -60t-82 -18t-82 18t-59 60t-37 115.5t-12 181.5t12 181.5t37 115.5t59 60t82 18zM142 249l196 339q-26 82 -88 82q-36 0 -60 -26t-38 -95t-14 -184q0 -50 4 -116zM158 155q26 -95 92 -95 q36 0 60 26t38 95t14 184q0 78 -6 133z" />
+<glyph unicode="1" d="M258 0v645l-2 1l-173 -101v80l175 105h82v-730h-82z" />
+<glyph unicode="2" d="M175 74v-2h245v-72h-340v72q251 288 251 478q0 116 -93 116q-30 0 -76 -22.5t-82 -55.5v87q75 65 170 65q85 0 125 -47t40 -143q0 -99 -54 -208t-186 -268z" />
+<glyph unicode="3" d="M330 656v2h-250v72h345v-72l-180 -229v-2h10q91 0 133 -51t42 -166q0 -220 -195 -220q-73 0 -145 30v87q77 -43 130 -43q64 0 95 34.5t31 111.5q0 89 -25 117t-101 28h-70v72z" />
+<glyph unicode="4" d="M293 590h-2l-175 -341v-2h177v343zM293 175h-253v82l243 473h92v-483h85v-72h-85v-175h-82v175z" />
+<glyph unicode="5" d="M180 430h2q33 30 88 30q160 0 160 -230q0 -125 -49.5 -182.5t-145.5 -57.5q-74 0 -145 30v87q75 -43 140 -43q116 0 116 166q0 156 -96 156q-46 0 -80 -41h-75l10 385h305v-72h-223z" />
+<glyph unicode="6" d="M285 740q61 0 115 -20v-77q-50 25 -105 25q-70 0 -101 -48.5t-39 -184.5h2q50 50 113 50q87 0 128.5 -56t41.5 -184q0 -134 -46.5 -194.5t-138.5 -60.5q-65 0 -104 28.5t-60 101.5t-21 200q0 158 25.5 252t71 131t118.5 37zM255 62q54 0 78.5 39t24.5 144q0 94 -23.5 132 t-74.5 38q-106 0 -106 -160q0 -107 25 -150t76 -43z" />
+<glyph unicode="7" d="M345 656v2h-270v72h350v-72q-128 -296 -210 -658h-88q84 353 218 656z" />
+<glyph unicode="8" d="M255 670q-53 0 -81.5 -27.5t-28.5 -77.5q0 -54 29 -94t76 -51q52 14 80.5 51.5t28.5 93.5q0 47 -28.5 76t-75.5 29zM250 -10q-96 0 -148 51t-52 149q0 68 33 119t92 75v2q-48 23 -79 73.5t-31 105.5q0 82 49 128.5t136 46.5t136 -47t49 -128q0 -56 -30.5 -103.5 t-79.5 -70.5v-2q59 -23 92 -75t33 -124q0 -98 -52 -149t-148 -51zM255 60q53 0 84 33.5t31 96.5q0 130 -125 160q-61 -16 -90 -54.5t-29 -105.5q0 -62 35 -96t94 -34z" />
+<glyph unicode="9" d="M215 -10q-61 0 -115 20v80q52 -26 105 -26q70 0 101 47.5t39 183.5h-2q-50 -50 -113 -50q-84 0 -127 59t-43 191q0 126 46 185.5t139 59.5q68 0 107 -28t58.5 -100.5t19.5 -201.5q0 -158 -25.5 -252t-71 -131t-118.5 -37zM245 668q-55 0 -79 -38t-24 -135t25 -138.5 t73 -41.5q49 0 77.5 41.5t28.5 128.5q0 100 -25 141.5t-76 41.5z" />
+<glyph unicode=":" d="M190 390v150h120v-150h-120zM190 0v150h120v-150h-120z" />
+<glyph unicode=";" d="M200 150h120l-110 -280h-70zM200 390v150h120v-150h-120z" />
+<glyph unicode="&#x3c;" d="M435 510l-330 -204v-2l330 -204v-80l-380 245v80l380 245v-80z" />
+<glyph unicode="=" d="M60 165v72h380v-72h-380zM60 373v72h380v-72h-380z" />
+<glyph unicode="&#x3e;" d="M65 510v80l380 -245v-80l-380 -245v80l330 204v2z" />
+<glyph unicode="?" d="M445 580q0 -41 -14 -77t-28.5 -55t-42.5 -49q-29 -33 -43 -52t-28 -55t-14 -77h-80q0 55 16.5 101.5t32.5 68t47 56.5q24 27 36 42.5t23 41.5t11 55q0 41 -29.5 63.5t-86.5 22.5q-85 0 -180 -61v90q93 45 190 45q91 0 140.5 -42t49.5 -118zM180 0v130h110v-130h-110z" />
+<glyph unicode="@" d="M375 258v167q0 41 -16 63t-44 22q-40 0 -56 -29.5t-16 -115.5q0 -82 17 -113.5t55 -31.5q44 0 60 38zM165 365q0 215 140 215q38 0 73 -25h2v5q0 50 -27.5 79t-72.5 29q-83 0 -124 -70.5t-41 -232.5q0 -166 40 -234.5t125 -68.5q62 0 125 38v-80q-59 -30 -130 -30 q-122 0 -181 86t-59 289q0 197 60.5 286t179.5 89q87 0 133.5 -50t46.5 -150v-325q-65 -65 -140 -65q-76 0 -113 49t-37 166z" />
+<glyph unicode="A" d="M249 660h-2l-83 -380h168zM348 210h-200l-46 -210h-82l180 730h100l180 -730h-86z" />
+<glyph unicode="B" d="M157 430h45q80 0 116.5 29.5t36.5 90.5q0 57 -36 88.5t-102 31.5q-36 0 -60 -8v-232zM157 360v-292q37 -8 90 -8q126 0 126 160q0 140 -161 140h-55zM455 210q0 -220 -225 -220q-80 0 -155 15v720q75 15 155 15q205 0 205 -180q0 -61 -30.5 -103t-84.5 -56v-2 q58 -11 96.5 -64t38.5 -125z" />
+<glyph unicode="C" d="M55 365q0 197 60.5 286t179.5 89q66 0 125 -30v-75q-60 33 -120 33q-165 0 -165 -303q0 -164 42 -233.5t123 -69.5q62 0 125 38v-80q-59 -30 -130 -30q-122 0 -181 86t-59 289z" />
+<glyph unicode="D" d="M383 365q0 168 -43.5 235.5t-137.5 67.5q-33 0 -55 -8v-590q22 -8 55 -8q65 0 102.5 24.5t58 91.5t20.5 187zM465 365q0 -207 -63.5 -291t-199.5 -84q-70 0 -137 15v720q67 15 137 15q137 0 200 -85.5t63 -289.5z" />
+<glyph unicode="E" d="M162 658v-228h248v-70h-248v-288h258v-72h-340v730h340v-72h-258z" />
+<glyph unicode="F" d="M172 360v-360h-82v730h330v-72h-248v-228h238v-70h-238z" />
+<glyph unicode="G" d="M370 85v275h-155v70h235v-400q-80 -40 -170 -40q-118 0 -179 89t-61 286q0 196 63.5 285.5t191.5 89.5q59 0 130 -25v-77q-66 30 -130 30q-87 0 -132 -72t-45 -231q0 -303 167 -303q45 0 85 23z" />
+<glyph unicode="H" d="M140 730v-298h216v298h84v-730h-84v360h-216v-360h-80v730h80z" />
+<glyph unicode="I" d="M410 0h-320v70h118v590h-118v70h320v-70h-118v-590h118v-70z" />
+<glyph unicode="J" d="M400 730v-540q0 -110 -43.5 -155t-146.5 -45q-82 0 -150 30v87q29 -17 75.5 -31t74.5 -14q53 0 79 30.5t26 99.5v468h-165v70h250z" />
+<glyph unicode="K" d="M157 400h2l206 330h95l-225 -350l230 -380h-95l-211 360h-2v-360h-82v730h82v-330z" />
+<glyph unicode="L" d="M182 730v-658h238v-72h-320v730h82z" />
+<glyph unicode="M" d="M378 540h-2l-88 -340h-80l-88 340h-2v-540h-78v730h92l119 -450h2l119 450h88v-730h-82v540z" />
+<glyph unicode="N" d="M151 550h-2v-550h-84v730h84l204 -550h2v550h80v-730h-80z" />
+<glyph unicode="O" d="M250 740q107 0 158.5 -84.5t51.5 -290.5t-51.5 -290.5t-158.5 -84.5t-158.5 84.5t-51.5 290.5t51.5 290.5t158.5 84.5zM250 62q44 0 71 25.5t43 93.5t16 184t-16 184t-43 93.5t-71 25.5t-71 -25.5t-43 -93.5t-16 -184t16 -184t43 -93.5t71 -25.5z" />
+<glyph unicode="P" d="M375 520q0 79 -36 114.5t-112 35.5q-41 0 -70 -8v-292q30 -5 70 -5q77 0 112.5 35.5t35.5 119.5zM455 520q0 -120 -52.5 -172.5t-165.5 -52.5q-35 0 -80 5v-300h-82v725q78 15 160 15q114 0 167 -52.5t53 -167.5z" />
+<glyph unicode="Q" d="M250 740q107 0 158.5 -84.5t51.5 -290.5q0 -273 -100 -344v-2q41 -21 73 -66t47 -103h-88q-21 78 -54 109t-88 31q-107 0 -158.5 84.5t-51.5 290.5t51.5 290.5t158.5 84.5zM250 62q44 0 71 25.5t43 93.5t16 184t-16 184t-43 93.5t-71 25.5t-71 -25.5t-43 -93.5t-16 -184 t16 -184t43 -93.5t71 -25.5z" />
+<glyph unicode="R" d="M370 540q0 130 -148 130q-41 0 -70 -8v-272h60q87 0 122.5 33.5t35.5 116.5zM152 320v-320h-82v725q78 15 160 15q112 0 166 -49.5t54 -150.5q0 -143 -109 -193v-2q31 -15 66 -131l63 -214h-86l-59 216q-17 64 -41 84t-82 20h-50z" />
+<glyph unicode="S" d="M260 668q-47 0 -77.5 -30.5t-30.5 -77.5q0 -50 21.5 -82.5t71.5 -55.5q111 -49 153 -102.5t42 -139.5q0 -94 -51.5 -142t-148.5 -48q-91 0 -165 55v95q80 -78 170 -78q113 0 113 118q0 55 -26 91t-87 64q-94 42 -134.5 95.5t-40.5 129.5q0 80 51 130t134 50q53 0 87 -8 t78 -32v-90q-77 58 -160 58z" />
+<glyph unicode="T" d="M209 0v660h-154v70h390v-70h-154v-660h-82z" />
+<glyph unicode="U" d="M250 -10q-95 0 -142.5 48.5t-47.5 151.5v540h84v-520q0 -81 26.5 -114.5t81.5 -33.5t81.5 33.5t26.5 114.5v520h80v-540q0 -103 -47.5 -151.5t-142.5 -48.5z" />
+<glyph unicode="V" d="M253 70l135 660h82l-170 -730h-100l-170 730h86l135 -660h2z" />
+<glyph unicode="W" d="M153 120h2l54 510h90l54 -510h2l45 610h75l-60 -730h-109l-55 520h-2l-55 -520h-109l-60 730h83z" />
+<glyph unicode="X" d="M251 440h2l112 290h83l-148 -355l150 -375h-90l-111 305h-2l-112 -305h-85l150 375l-148 355h88z" />
+<glyph unicode="Y" d="M251 375h2l132 355h85l-179 -440v-290h-82v290l-179 440h90z" />
+<glyph unicode="Z" d="M335 658v2h-260v70h350v-70l-260 -588v-2h260v-70h-350v70z" />
+<glyph unicode="[" d="M390 710h-178v-790h178v-60h-250v910h250v-60z" />
+<glyph unicode="\" d="M48 730h72l332 -770h-72z" />
+<glyph unicode="]" d="M110 710v60h250v-910h-250v60h178v790h-178z" />
+<glyph unicode="^" d="M251 680h-2l-147 -400h-72l170 450h100l170 -450h-72z" />
+<glyph unicode="_" d="M50 -140v56h400v-56h-400z" />
+<glyph unicode="`" d="M130 810h120l100 -280h-70z" />
+<glyph unicode="a" d="M255 530q100 0 137.5 -40t37.5 -150v-340h-72l-2 75h-2q-47 -85 -149 -85q-65 0 -105 41.5t-40 113.5q0 91 61.5 140.5t183.5 49.5h48v25q0 57 -22 80t-76 23q-33 0 -84 -12t-86 -28v72q35 15 85 25t85 10zM353 275h-48q-170 0 -170 -125q0 -45 23 -69t62 -24q59 0 96 48 t37 135v35z" />
+<glyph unicode="b" d="M144 445h2q43 85 134 85q175 0 175 -270q0 -135 -48 -202.5t-127 -67.5q-84 0 -137 85h-2l-2 -75h-74v730h79v-285zM376 260q0 195 -116 195q-51 0 -83.5 -49.5t-32.5 -140.5v-10q0 -91 32.5 -140.5t83.5 -49.5q53 0 84.5 48.5t31.5 146.5z" />
+<glyph unicode="c" d="M70 260q0 134 55 202t155 68q61 0 125 -25v-80q-60 33 -120 33q-63 0 -98 -50t-35 -148q0 -101 37 -151t101 -50q59 0 120 36v-80q-64 -25 -125 -25q-102 0 -158.5 67.5t-56.5 202.5z" />
+<glyph unicode="d" d="M356 730h79v-730h-74l-2 75h-2q-53 -85 -137 -85q-79 0 -127 67.5t-48 202.5q0 270 175 270q91 0 134 -85h2v285zM124 260q0 -98 31.5 -146.5t84.5 -48.5q51 0 83.5 49.5t32.5 140.5v10q0 91 -32.5 140.5t-83.5 49.5q-116 0 -116 -195z" />
+<glyph unicode="e" d="M138 234q4 -93 38 -134t99 -41q61 0 135 36v-80q-74 -25 -140 -25q-215 0 -215 270q0 141 50 205.5t150 64.5q91 0 135.5 -62t44.5 -203q0 -11 -2 -31h-295zM138 300h218q-1 161 -101 161q-57 0 -85 -36t-32 -125z" />
+<glyph unicode="f" d="M75 431v69h120v60q0 98 33 139t107 41q45 0 90 -15v-72q-38 18 -75 18q-47 0 -61.5 -23.5t-14.5 -107.5v-40h151v-69h-151v-431h-79v431h-120z" />
+<glyph unicode="g" d="M50 260q0 270 175 270q83 0 137 -85h2l2 75h74v-515q0 -125 -50.5 -180t-154.5 -55q-71 0 -140 25v80q71 -36 140 -36q126 0 126 166v80h-2q-43 -85 -134 -85q-80 0 -127.5 66t-47.5 194zM129 260q0 -92 31.5 -138.5t84.5 -46.5q52 0 84 45.5t32 134.5v10 q0 91 -32.5 140.5t-83.5 49.5q-58 0 -87 -46.5t-29 -148.5z" />
+<glyph unicode="h" d="M440 330v-330h-77v312q0 88 -20 117.5t-73 29.5q-50 0 -85.5 -56t-35.5 -151v-252h-79v730h79v-285h2q19 39 56.5 62t82.5 23q79 0 114.5 -45.5t35.5 -154.5z" />
+<glyph unicode="i" d="M316 520v-452h109v-68h-330v68h139v384h-109v68h191zM214 640v120h102v-120h-102z" />
+<glyph unicode="j" d="M249 -33v485h-119v68h201v-553q0 -65 -8.5 -101t-36.5 -59t-72 -30t-123 -7v68q40 0 63 1t42.5 6.5t28.5 12.5t15.5 23.5t7.5 34.5t1 51zM229 640v120h102v-120h-102z" />
+<glyph unicode="k" d="M460 520l-230 -250l230 -270h-95l-206 253v-253h-79v730h79v-444l207 234h94z" />
+<glyph unicode="l" d="M281 150q0 -66 10.5 -79t63.5 -13q33 0 75 6v-69q-47 -5 -85 -5q-90 0 -118 28.5t-28 121.5v522h-129v68h211v-580z" />
+<glyph unicode="m" d="M290 0h-78v360q-1 58 -10.5 77.5t-32.5 19.5q-20 0 -35 -24t-25 -83.5t-10 -149.5v-200h-79v520h70l2 -70h2q17 38 42.5 59t53.5 21q31 0 50.5 -18.5t33.5 -61.5h2q39 80 104 80q53 0 76.5 -32.5t23.5 -117.5v-380h-77v360q-1 59 -11.5 78t-37.5 19q-64 0 -64 -197v-260z " />
+<glyph unicode="n" d="M440 330v-330h-77v312q0 88 -20 117.5t-73 29.5q-50 0 -85.5 -56t-35.5 -151v-252h-79v520h74l2 -75h2q19 38 58 61.5t84 23.5q79 0 114.5 -45.5t35.5 -154.5z" />
+<glyph unicode="o" d="M250 530q200 0 200 -270t-200 -270t-200 270t200 270zM250 59q61 0 89.5 45.5t28.5 155.5t-28.5 155.5t-89.5 45.5t-89.5 -45.5t-28.5 -155.5t28.5 -155.5t89.5 -45.5z" />
+<glyph unicode="p" d="M141 75h-2v-295h-79v740h74l2 -75h2q54 85 137 85q175 0 175 -270q0 -135 -48 -202.5t-127 -67.5q-91 0 -134 85zM371 260q0 195 -116 195q-51 0 -83.5 -49.5t-32.5 -140.5v-10q0 -91 32.5 -140.5t83.5 -49.5q53 0 84.5 48.5t31.5 146.5z" />
+<glyph unicode="q" d="M359 75q-43 -85 -134 -85q-79 0 -127 67.5t-48 202.5q0 270 175 270q83 0 137 -85h2l2 75h74v-740h-79v295h-2zM129 260q0 -98 31.5 -146.5t84.5 -48.5q51 0 83.5 49.5t32.5 140.5v10q0 91 -32.5 140.5t-83.5 49.5q-116 0 -116 -195z" />
+<glyph unicode="r" d="M186 520v-100h2q62 110 172 110q37 0 70 -10v-70q-35 11 -70 11q-73 0 -122 -61t-49 -160v-240h-79v520h76z" />
+<glyph unicode="s" d="M255 463q-96 0 -96 -73q0 -34 21 -54.5t75 -35.5q106 -30 140.5 -63t34.5 -102t-47 -107t-133 -38t-165 40v80q78 -53 155 -53q111 0 111 78q0 37 -21.5 57t-84.5 38q-92 26 -128.5 62t-36.5 98q0 66 43.5 103t126.5 37q84 0 160 -35v-75q-79 43 -155 43z" />
+<glyph unicode="t" d="M244 500h181v-69h-181v-281q0 -56 16.5 -74.5t64.5 -18.5q50 0 90 18v-70q-48 -15 -100 -15q-84 0 -117 32.5t-33 117.5v291h-100v69h100v190h79v-190z" />
+<glyph unicode="u" d="M65 180v340h77v-322q0 -83 18.5 -110t69.5 -27q49 0 82.5 55t33.5 152v252h79v-520h-74l-2 75h-2q-19 -40 -56 -62.5t-81 -22.5q-77 0 -111 43t-34 147z" />
+<glyph unicode="v" d="M251 60h2l115 460h82l-145 -520h-110l-145 520h86z" />
+<glyph unicode="w" d="M351 80h2l49 440h78l-80 -520h-99l-54 440h-2l-49 -440h-96l-80 520h82l49 -440h2l49 440h100z" />
+<glyph unicode="x" d="M251 305h2l104 215h88l-145 -260l145 -260h-94l-102 215h-2l-102 -215h-90l145 260l-145 260h92z" />
+<glyph unicode="y" d="M259 120h2l117 400h87l-240 -740h-83l78 230l-175 510h88z" />
+<glyph unicode="z" d="M80 520h340v-69l-248 -380v-2h248v-69h-340v69l248 380v2h-248v69z" />
+<glyph unicode="{" d="M195 316l4 -2q81 -38 81 -149v-135q0 -72 16.5 -91t78.5 -19h40v-60h-65q-73 0 -107.5 35.5t-34.5 114.5v150q0 66 -21.5 95.5t-66.5 29.5h-45v60h45q45 0 66.5 29.5t21.5 95.5v150q0 79 34.5 114.5t107.5 35.5h65v-60h-40q-62 0 -78.5 -19t-16.5 -91v-135q0 -61 -20 -95 t-65 -54z" />
+<glyph unicode="|" d="M212 -220v1030h76v-1030h-76z" />
+<glyph unicode="}" d="M305 316q-45 20 -65 54t-20 95v135q0 72 -16.5 91t-78.5 19h-40v60h65q73 0 107.5 -35.5t34.5 -114.5v-150q0 -66 21.5 -95.5t66.5 -29.5h45v-60h-45q-45 0 -66.5 -29.5t-21.5 -95.5v-150q0 -79 -34.5 -114.5t-107.5 -35.5h-65v60h40q62 0 78.5 19t16.5 91v135 q0 111 81 149z" />
+<glyph unicode="~" d="M50 602v75q42 33 95 33q61 0 125 -48q48 -35 80 -35q25 0 47 10t53 39v-75q-42 -33 -95 -33q-61 0 -125 48q-47 35 -80 35q-25 0 -47 -10t-53 -39z" />
+<glyph unicode="&#xa0;" />
+<glyph unicode="&#xa5;" d="M251 375h2l132 355h85l-153 -375h123v-65h-149v-85h149v-65h-149v-140h-82v140h-149v65h149v85h-149v65h123l-153 375h90z" />
+<glyph unicode="&#xad;" d="M100 269v72h300v-72h-300z" />
+<glyph unicode="&#x2000;" horiz-adv-x="407" />
+<glyph unicode="&#x2001;" horiz-adv-x="815" />
+<glyph unicode="&#x2002;" horiz-adv-x="407" />
+<glyph unicode="&#x2003;" horiz-adv-x="815" />
+<glyph unicode="&#x2004;" horiz-adv-x="271" />
+<glyph unicode="&#x2005;" horiz-adv-x="203" />
+<glyph unicode="&#x2006;" horiz-adv-x="135" />
+<glyph unicode="&#x2007;" horiz-adv-x="135" />
+<glyph unicode="&#x2008;" horiz-adv-x="101" />
+<glyph unicode="&#x2009;" horiz-adv-x="163" />
+<glyph unicode="&#x200a;" horiz-adv-x="45" />
+<glyph unicode="&#x2010;" d="M100 269v72h300v-72h-300z" />
+<glyph unicode="&#x2011;" d="M100 269v72h300v-72h-300z" />
+<glyph unicode="&#x2013;" d="M60 269v72h380v-72h-380z" />
+<glyph unicode="&#x2014;" d="M20 269v72h460v-72h-460z" />
+<glyph unicode="&#x2018;" d="M275 500h-120l110 280h70z" />
+<glyph unicode="&#x2019;" d="M220 780h120l-110 -280h-70z" />
+<glyph unicode="&#x201c;" d="M340 500h-110l110 280h60zM190 500h-110l110 280h60z" />
+<glyph unicode="&#x201d;" d="M300 780h110l-110 -280h-60zM150 780h110l-110 -280h-60z" />
+<glyph unicode="&#x2026;" horiz-adv-x="1000" d="M102 288v150h130v-150h-130zM435 288v150h130v-150h-130zM768 288v150h130v-150h-130z" />
+<glyph unicode="&#x202f;" horiz-adv-x="163" />
+<glyph unicode="&#x205f;" horiz-adv-x="203" />
+<glyph unicode="&#x2122;" horiz-adv-x="1000" d="M878 540h-2l-88 -340h-80l-88 340h-2v-540h-78v730h92l119 -450h2l119 450h88v-730h-82v540zM209 0v660h-154v70h390v-70h-154v-660h-82z" />
+</font>
+</defs></svg> \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.ttf b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.ttf
new file mode 100644
index 0000000..684abfd
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.ttf
Binary files differ
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.woff b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.woff
new file mode 100644
index 0000000..49585d8
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.woff
Binary files differ
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/handheld.css b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/handheld.css
new file mode 100644
index 0000000..073c0d1
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/handheld.css
@@ -0,0 +1,217 @@
+/*
+ * TABLE OF CONTENTS:
+ * - Browser reset
+ * - HTML elements
+ * - JsDoc styling
+ * - Media query check
+ */
+
+
+
+
+
+
+/*
+ * HTML ELEMENTS
+ */
+
+body {
+ padding: 1% 4% 1% 4%;
+}
+
+/*
+ * HTML ELEMENTS
+ */
+
+
+
+
+
+/*
+ * BEGIN JSDOC
+ */
+
+/* Start menu */
+div.index div.menu {
+ position: fixed;
+ top: 0;
+ right: 0;
+ -moz-border-radius-bottomleft: 15px;
+ -webkit-border-bottom-left-radius: 15px;
+ -border-bottom-left-radius: 15px;
+ padding: 4px 5px 8px 10px;
+ -moz-box-shadow: 0px 0px 10px #c4c4c4;
+ -webkit-box-shadow: 0px 0px 10px #c4c4c4;
+ box-shadow: 0px 0px 10px #c4c4c4;
+ background-color: rgba(255, 255, 255, 0.9);
+}
+
+div.index input.classFilter {
+ display: none;
+}
+
+div.index div.indexLinks a {
+ float: right;
+ clear: both;
+ font-size: 1.1em;
+}
+
+div.index *.heading1 {
+ display:none;
+}
+
+div.index ul.classList {
+ display:none;
+}
+
+div.index div.fineprint {
+ display:none;
+}
+
+div.indexStatic {
+ display: none;
+}
+/* End menu */
+
+
+
+/* Start content */
+div.content *.classTitle {
+ margin-right: 60px;
+ margin-bottom: 15px;
+}
+
+div.content div.intro {
+ margin: 15px 0 35px;
+}
+
+div.content p.description.summary {
+ margin-bottom: 0.2em;
+}
+
+div.content div.props {
+ margin: 1.5em -2% 0 -2%;
+ padding: 2%;
+}
+
+table.summaryTable {
+ position: relative;
+ left: -10px;
+ width: 100%;
+ border-collapse: collapse;
+ box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ -webkit-box-sizing: content-box;
+ -ms-box-sizing: content-box;
+ -o-box-sizing: content-box;
+ -icab-box-sizing: content-box;
+ -khtml-box-sizing: content-box;
+}
+
+*.sectionTitle {
+ padding: 0 10px 10px 0;
+}
+caption.sectionTitle {
+ padding-left: 10px;
+}
+
+table.summaryTable td,
+table.summaryTable th {
+ padding: 0px 10px 10px 10px;
+}
+table.summaryTable tr:last-child td {
+ padding-bottom: 0;
+}
+
+table.summaryTable td.attributes {
+ width: 35%;
+}
+
+table.summaryTable td.nameDescription {
+ width: 65%
+}
+
+
+
+dl.detailList {
+ margin-top: 0.5em;
+}
+
+dl.detailList.nomargin + dl.detailList.nomargin {
+ margin-top: 0;
+}
+
+dl.detailList dt {
+ display: inline;
+ margin-right: 5px;
+}
+
+dl.detailList dt:before {
+ display: block;
+ content: "";
+}
+
+dl.detailList dd {
+ display: inline;
+}
+
+dl.detailList.params dt {
+ display: block;
+}
+dl.detailList.params dd {
+ display: block;
+ padding-left: 2em;
+ padding-bottom: 0.4em;
+}
+
+
+
+
+ul.fileList li {
+ margin-bottom: 1.5em;
+}
+
+
+
+.fixedFont.heading {
+ margin-bottom: 0.5em;
+}
+
+pre.code {
+ margin: 10px 0 10px 0;
+ padding: 10px;
+ border: 1px solid #ccc;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+}
+/* End content */
+
+/*
+ * END JSDOC
+ */
+
+
+
+
+
+
+
+/*
+ * START MEDIA QUERY CHECK
+ */
+
+.cssLoadCheck {
+ position: absolute;
+ top: -99999px;
+ left: -99999px;
+ border: 0;
+ width: 100px;
+ padding: 0;
+ overflow: hidden;
+}
+
+/*
+ * END MEDIA QUERY CHECK
+ */
+
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/screen.css b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/screen.css
new file mode 100644
index 0000000..8cb4bba
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/screen.css
@@ -0,0 +1,297 @@
+/*
+ * TABLE OF CONTENTS:
+ * - JsDoc styling
+ * - Media query check
+ */
+
+
+
+
+
+
+/*
+ * BEGIN JSDOC
+ */
+
+/* Start menu */
+div.index {
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ float: left;
+ width: 30%;
+ min-width: 100px;
+ max-width: 300px;
+ padding: 0 0 10px 0;
+ overflow: auto;
+}
+
+div.index *.heading1 {
+ padding: 8px 0 0 0;
+}
+
+div.index div.menu {
+ margin: 0 15px 0 -15px;
+ -moz-border-radius-bottomright: 15px;
+ -webkit-border-bottom-right-radius: 15px;
+ -border-bottom-right-radius: 15px;
+ padding: 15px 15px 15px 30px;
+ -moz-box-shadow: 0px 0px 10px #c4c4c4;
+ -webkit-box-shadow: 0px 0px 10px #c4c4c4;
+ box-shadow: 0px 0px 10px #c4c4c4;
+ background-color: rgba(255, 255, 255, 0.5);
+}
+
+div.index div.indexLinks {
+ margin-top: 13px;
+ position: absolute;
+ right: 30px;
+}
+
+div.index div.indexLinks a {
+ color: #999999;
+ text-transform: lowercase;
+}
+
+div.index div.indexLinks a:first-child {
+ margin-right: 3px;
+ border-right: 1px solid #999999;
+ padding-right: 5px;
+}
+
+div.index input.classFilter {
+ margin-bottom: 4px;
+ width: 100%;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #CCCCCC #999999 #999999 #CCCCCC;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ -border-radius: 3px;
+}
+
+div.index ul.classList a {
+ line-height: 1.3em;
+}
+
+div.index ul.classList a + a {
+ margin-left: 0.5em;
+}
+
+div.index div.fineprint {
+ margin: 1em 0 0 15px;
+ color: #777;
+ font-size: 0.9em;
+}
+
+div.index div.fineprint a {
+ color: #777;
+}
+
+div.indexStatic {
+ position: static;
+ min-height: 1em;
+}
+/* End menu */
+
+
+/* Start content */
+div.content {
+ float: left;
+ width: 70%;
+ min-width: 300px;
+ max-width: 600px;
+}
+div.innerContent {
+ padding: 0 0 0 2.5em;
+}
+
+div.content ul,
+div.content ol {
+ margin-bottom: 3em;
+}
+
+div.content ul.methodDetail {
+ margin-bottom: 0;
+}
+
+div.content *.classTitle {
+ position: relative;
+ left: -10px;
+ margin: -30px 0 15px 0;
+ -moz-border-radius: 15px;
+ -webkit-border-radius: 15px;
+ border-radius: 15px;
+ padding: 25px 15px 15px 15px;
+ background-color: #FFFFFF;
+ background-color: rgba(255, 255, 255, 0.5);
+ -moz-box-shadow: 0px 0px 10px #c4c4c4;
+ -webkit-box-shadow: 0px 0px 10px #c4c4c4;
+ box-shadow: 0px 0px 10px #c4c4c4;
+}
+
+div.content div.intro {
+ margin: 15px 0 45px
+}
+
+div.content p.summary {
+ margin-bottom: 0.5em;
+}
+
+div.content ul.summary {
+ margin-bottom: 1.5em;
+}
+
+div.content ul *.classname a,
+div.content ul *.filename a {
+ font-family: Consolas, "Courier New", Courier, monospace;
+ text-decoration: none;
+ font-weight: bold;
+}
+div.content ul *.classname a:hover,
+div.content ul *.filename a:hover {
+ text-decoration: underline;
+}
+
+div.content div.props {
+ position: relative;
+ left: -10px;
+ margin-bottom: 2.5em;
+ padding: 10px 15px 15px 15px;
+ overflow: hidden;
+}
+
+div.content div.hr {
+ margin: 0 10px 0 0;
+ height: 4em;
+}
+
+
+
+table.summaryTable {
+ position: relative;
+ left: -10px;
+ width: 100%;
+ border-collapse: collapse;
+ box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ -webkit-box-sizing: content-box;
+ -ms-box-sizing: content-box;
+ -o-box-sizing: content-box;
+ -icab-box-sizing: content-box;
+ -khtml-box-sizing: content-box;
+}
+
+*.sectionTitle {
+ padding: 0 10px 10px 0;
+}
+caption.sectionTitle {
+ padding-left: 10px;
+}
+
+table.summaryTable td,
+table.summaryTable th {
+ padding: 0px 10px 10px 10px;
+}
+table.summaryTable tr:last-child td {
+ padding-bottom: 0;
+}
+
+table.summaryTable td.attributes {
+ width: 35%;
+}
+
+table.summaryTable td.nameDescription {
+ width: 65%
+}
+
+
+
+dl.detailList {
+ margin-top: 0.5em;
+}
+
+dl.detailList.nomargin + dl.detailList.nomargin {
+ margin-top: 0;
+}
+
+dl.detailList dt {
+ display: inline;
+ margin-right: 5px;
+}
+
+dl.detailList dt:before {
+ display: block;
+ content: "";
+}
+
+dl.detailList dd {
+ display: inline;
+}
+
+dl.detailList.params dt {
+ display: block;
+}
+dl.detailList.params dd {
+ display: block;
+ padding-left: 2em;
+ padding-bottom: 0.4em;
+}
+
+
+
+
+ul.fileList li {
+ margin-bottom: 1.5em;
+}
+
+
+
+.fixedFont.heading {
+ margin-bottom: 0.5em;
+}
+
+pre.code {
+ margin: 10px 0 10px 0;
+ padding: 10px;
+ border: 1px solid #ccc;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+}
+/* End content */
+
+.clear {
+ clear: both;
+ width: 100%;
+ min-height: 0;
+}
+
+/*
+ * END JSDOC
+ */
+
+
+
+
+
+
+
+/*
+ * START MEDIA QUERY CHECK
+ */
+
+.cssLoadCheck {
+ position: absolute;
+ top: -99999px;
+ left: -99999px;
+ border: 0;
+ width: 100px;
+ padding: 0;
+ overflow: hidden;
+}
+
+/*
+ * END MEDIA QUERY CHECK
+ */
+
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/files.html b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/files.html
new file mode 100644
index 0000000..a4f372a
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/files.html
@@ -0,0 +1,133 @@
+
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="generator" content="JsDoc Toolkit" />
+ <title>File Index | JsDoc Reference</title>
+
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
+ <meta name="mobileoptimized" content="0" />
+
+ <link rel="stylesheet" href="css/all.css" media="all" />
+ <link rel="stylesheet" href="css/handheld.css" media="only screen and (max-width: 660px)" />
+ <link rel="stylesheet" href="css/handheld.css" media="handheld" />
+ <link rel="stylesheet" href="css/screen.css" media="screen and (min-width: 661px)" />
+
+ <script src="javascript/all.js"></script>
+ <!--[if lt IE 9]>
+ <script src="javascript/html5.js"></script>
+ <![endif]-->
+ </head>
+
+ <body>
+
+<div class="index">
+ <div class="menu">
+ <div class="indexLinks">
+ <a href="index.html">Classes</a>
+ <a href="files.html">Files</a>
+ </div>
+
+ <h2 class="heading1">Classes</h2>
+
+ <input type="text" name="classFilter" class="classFilter" id="ClassFilter" placeholder="Filter"></input>
+
+ <nav>
+ <ul class="classList" id="ClassList">
+
+ <li><a href="symbols/_global_.html">_global_</a></li>
+
+ <li><a href="symbols/mockup.html">mockup</a></li>
+
+ <li><a href="symbols/RAIServer.html">RAIServer</a></li>
+
+ <li><a href="symbols/RAISocket.html">RAISocket</a></li>
+
+ <li><a href="symbols/starttls.html">starttls</a></li>
+
+ </ul>
+ </nav>
+ </div>
+ <div class="fineprint" style="clear:both">
+ <footer>
+
+ Documentation generator: <a href="http://code.google.com/p/jsdoc-toolkit/" target="_blank">JsDoc Toolkit</a> 2.4.0<br />
+ Template: <a href="http://www.thebrightlines.com/2010/05/06/new-template-for-jsdoctoolkit-codeview/" target="_blank">Codeview</a> 1.2<br />
+ Generated on:
+ <time datetime='2012-0-22' pubdate>2012-0-22 12:15</time>
+ </footer>
+ </div>
+</div>
+
+<div class="index indexStatic"></div>
+
+<div class="content">
+ <div class="innerContent">
+ <article>
+ <h1 class="classTitle"><span>File Index</span></h1>
+
+ <ul class="fileList" id="FileList">
+
+ <li>
+ <h2 class="filename"><a href="symbols/src/RAI_lib_rai.js.html">rai.js</a></h2>
+
+
+This is the main file for the RAI library to create text based servers
+
+ <dl class="detailList">
+
+ <dt class="heading">Author:</dt>
+ <dd><a href="mailto:andris@node.ee">Andris Reinman</a></dd>
+
+
+
+ <dt class="heading">Version:</dt>
+ <dd>0.1.3</dd>
+
+
+
+
+ </dl>
+ </li>
+
+ <li>
+ <h2 class="filename"><a href="symbols/src/RAI_lib_mockup.js.html">RAI/lib/mockup.js</a></h2>
+
+
+
+ <dl class="detailList">
+
+
+
+
+
+
+ </dl>
+ </li>
+
+ <li>
+ <h2 class="filename"><a href="symbols/src/RAI_lib_starttls.js.html">RAI/lib/starttls.js</a></h2>
+
+
+
+ <dl class="detailList">
+
+
+
+
+
+
+ </dl>
+ </li>
+
+ </ul>
+ </article>
+ </div>
+</div>
+ <script type="text/javascript">
+ wbos.CssTools.MediaQueryFallBack.LoadCss('css/screen.css', 'css/handheld.css', 660)
+ codeview.classFilter.Init()
+ </script>
+ </body>
+</html>
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/index.html b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/index.html
new file mode 100644
index 0000000..544613f
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/index.html
@@ -0,0 +1,107 @@
+
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="generator" content="JsDoc Toolkit" />
+ <title>Class Index | JsDoc Reference</title>
+
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
+ <meta name="mobileoptimized" content="0" />
+
+ <link rel="stylesheet" href="css/all.css" media="all" />
+ <link rel="stylesheet" href="css/handheld.css" media="only screen and (max-width: 660px)" />
+ <link rel="stylesheet" href="css/handheld.css" media="handheld" />
+ <link rel="stylesheet" href="css/screen.css" media="screen and (min-width: 661px)" />
+
+ <script src="javascript/all.js"></script>
+ <!--[if lt IE 9]>
+ <script src="javascript/html5.js"></script>
+ <![endif]-->
+ </head>
+
+ <body>
+
+<div class="index">
+ <div class="menu">
+ <div class="indexLinks">
+ <a href="index.html">Classes</a>
+ <a href="files.html">Files</a>
+ </div>
+
+ <h2 class="heading1">Classes</h2>
+
+ <input type="text" name="classFilter" class="classFilter" id="ClassFilter" placeholder="Filter"></input>
+
+ <nav>
+ <ul class="classList" id="ClassList">
+
+ <li><a href="symbols/_global_.html">_global_</a></li>
+
+ <li><a href="symbols/mockup.html">mockup</a></li>
+
+ <li><a href="symbols/RAIServer.html">RAIServer</a></li>
+
+ <li><a href="symbols/RAISocket.html">RAISocket</a></li>
+
+ <li><a href="symbols/starttls.html">starttls</a></li>
+
+ </ul>
+ </nav>
+ </div>
+ <div class="fineprint" style="clear:both">
+ <footer>
+
+ Documentation generator: <a href="http://code.google.com/p/jsdoc-toolkit/" target="_blank">JsDoc Toolkit</a> 2.4.0<br />
+ Template: <a href="http://www.thebrightlines.com/2010/05/06/new-template-for-jsdoctoolkit-codeview/" target="_blank">Codeview</a> 1.2<br />
+ Generated on:
+ <time datetime='2012-0-22' pubdate>2012-0-22 12:15</time>
+ </footer>
+ </div>
+</div>
+
+<div class="index indexStatic"></div>
+
+<div class="content">
+ <div class="innerContent">
+ <article>
+ <h1 class="classTitle"><span>Class Index</span></h1>
+
+ <ul id="ClassList2">
+
+ <li>
+ <h2 class="classname"><a href="symbols/_global_.html">_global_</a></h2>
+ <p></p>
+ </li>
+
+ <li>
+ <h2 class="classname"><a href="symbols/mockup.html">mockup</a></h2>
+ <p>Mockup module</p>
+ </li>
+
+ <li>
+ <h2 class="classname"><a href="symbols/RAIServer.html">RAIServer</a></h2>
+ <p></p>
+ </li>
+
+ <li>
+ <h2 class="classname"><a href="symbols/RAISocket.html">RAISocket</a></h2>
+ <p></p>
+ </li>
+
+ <li>
+ <h2 class="classname"><a href="symbols/starttls.html">starttls</a></h2>
+ <p>STARTTLS module</p>
+ </li>
+
+ </ul>
+ </article>
+ </div>
+</div>
+ <script type="text/javascript">
+ wbos.CssTools.MediaQueryFallBack.LoadCss('css/screen.css', 'css/handheld.css', 660)
+ codeview.classFilter.Init()
+ </script>
+ </body>
+</html>
+
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/javascript/all.js b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/javascript/all.js
new file mode 100644
index 0000000..5b6876a
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/javascript/all.js
@@ -0,0 +1,326 @@
+/**
+ * @fileOverview Contains standard code in the namespace 'wbos' and code specifically written for Codeview in the namespace 'codeview'
+ * @author Wouter Bos (www.thebrightlines.com)
+ * @since 1.0 - 2010-09-10
+ * @version 1.0 - 2010-09-10
+ */
+
+
+
+
+
+
+if (typeof(wbos) == "undefined") {
+ /**
+ * @namespace Standard code of Wouter Bos (wbos)
+ */
+ wbos = {}
+}
+if (typeof(wbos.CssTools) == "undefined") {
+ /**
+ * @namespace Namespace for CSS-related functionality
+ */
+ wbos.CssTools = {}
+}
+
+
+
+
+/**
+ * @namespace Fallback for CSS advanced media query
+ * @class
+ * @since 1.0 - 2010-09-10
+ * @version 1.0 - 2010-09-10
+ */
+wbos.CssTools.MediaQueryFallBack = ( function() {
+ var config = {
+ cssScreen: "/css/screen.css",
+ cssHandheld: "/css/handheld.css",
+ mobileMaxWidth: 660,
+ testDivClass: "cssLoadCheck",
+ dynamicCssLinkId: "DynCssLink",
+ resizeDelay: 30
+ }
+ var noMediaQuery = false;
+ var delay;
+ var currentCssMediaType;
+
+ // Adding events to elements in the DOM without overwriting it
+ function addEvent(element, newFunction, eventType) {
+ var oldEvent = eval("element." + eventType);
+ var eventContentType = eval("typeof element." + eventType)
+
+ if ( eventContentType != 'function' ) {
+ eval("element." + eventType + " = newFunction")
+ } else {
+ eval("element." + eventType + " = function(e) { oldEvent(e); newFunction(e); }")
+ }
+ }
+
+ // Get the the inner width of the browser window
+ function getWindowWidth() {
+ if (window.innerWidth) {
+ return window.innerWidth;
+ } else if (document.documentElement.clientWidth) {
+ return document.documentElement.clientWidth;
+ } else if (document.body.clientWidth) {
+ return document.body.clientWidth;
+ } else{
+ return 0;
+ }
+ }
+
+ function addCssLink(cssHref) {
+ var cssNode = document.createElement('link');
+ var windowWidth;
+ cssNode.type = 'text/css';
+ cssNode.rel = 'stylesheet';
+ cssNode.media = 'screen, handheld, fallback';
+ cssNode.href = cssHref;
+ document.getElementsByTagName("head")[0].appendChild(cssNode);
+ }
+
+
+
+ /* Start public */
+ return {
+ /**
+ * Adds link to CSS in the head if no CSS is loaded
+ *
+ * @since 1.0 - 2010-08-21
+ * @version 1.0 - 2010-08-21
+ * @param {String|Object} cssScreen URL to CSS file for larger screens
+ * @param {String|Object} cssHandheld URL to CSS file for smaller screens
+ * @param {Number} mobileMaxWidth Maximum width for handheld devices
+ * @example
+ * wbos.CssTools.MediaQueryFallBack.LoadCss(['screen.css', 'screen2.css'], 'mobile.css', 480)
+ */
+ LoadCss: function(cssScreen, cssHandheld, mobileMaxWidth) {
+ // Set config values
+ if (typeof(cssScreen) != "undefined") {
+ config.cssScreen = cssScreen;
+ }
+ if (typeof(cssHandheld) != "undefined") {
+ config.cssHandheld = cssHandheld;
+ }
+ if (typeof(mobileMaxWidth) != "undefined") {
+ config.mobileMaxWidth = mobileMaxWidth;
+ }
+
+ // Check if CSS is loaded
+ var cssloadCheckNode = document.createElement('div');
+ cssloadCheckNode.className = config.testDivClass;
+ document.getElementsByTagName("body")[0].appendChild(cssloadCheckNode);
+ if (cssloadCheckNode.offsetWidth != 100 && noMediaQuery == false) {
+ noMediaQuery = true;
+ }
+ cssloadCheckNode.parentNode.removeChild(cssloadCheckNode)
+
+ if (noMediaQuery == true) {
+ // Browser does not support Media Queries, so JavaScript will supply a fallback
+ var cssHref = "";
+
+ // Determines what CSS file to load
+ if (getWindowWidth() <= config.mobileMaxWidth) {
+ cssHref = config.cssHandheld;
+ newCssMediaType = "handheld";
+ } else {
+ cssHref = config.cssScreen;
+ newCssMediaType = "screen";
+ }
+
+ // Add CSS link to <head> of page
+ if (cssHref != "" && currentCssMediaType != newCssMediaType) {
+ var currentCssLinks = document.styleSheets
+ for (var i = 0; i < currentCssLinks.length; i++) {
+ for (var ii = 0; ii < currentCssLinks[i].media.length; ii++) {
+ if (typeof(currentCssLinks[i].media) == "object") {
+ if (currentCssLinks[i].media.item(ii) == "fallback") {
+ currentCssLinks[i].ownerNode.parentNode.removeChild(currentCssLinks[i].ownerNode)
+ i--
+ break;
+ }
+ } else {
+ if (currentCssLinks[i].media.indexOf("fallback") >= 0) {
+ currentCssLinks[i].owningElement.parentNode.removeChild(currentCssLinks[i].owningElement)
+ i--
+ break;
+ }
+ }
+ }
+ }
+ if (typeof(cssHref) == "object") {
+ for (var i = 0; i < cssHref.length; i++) {
+ addCssLink(cssHref[i])
+ }
+ } else {
+ addCssLink(cssHref)
+ }
+
+ currentCssMediaType = newCssMediaType;
+ }
+
+
+ // Check screen size again if user resizes window
+ addEvent(window, wbos.CssTools.MediaQueryFallBack.LoadCssDelayed, 'onresize')
+ }
+ },
+
+ /**
+ * Runs LoadCSS after a short delay
+ *
+ * @since 1.0 - 2010-08-21
+ * @version 1.0 - 2010-08-21
+ * @example
+ * wbos.CssTools.MediaQueryFallBack.LoadCssDelayed()
+ */
+ LoadCssDelayed: function() {
+ clearTimeout(delay);
+ delay = setTimeout( "wbos.CssTools.MediaQueryFallBack.LoadCss()", config.resizeDelay)
+ }
+
+ }
+ /* End public */
+})();
+
+
+
+
+
+
+/**
+ * @namespace Adds a function to an event of a single element. Use this if
+ * you don't want to use jQuery
+ * @class
+ * @since 1.0 - 2010-02-23
+ * @version 1.0 - 2010-02-23
+ */
+wbos.Events = ( function() {
+ /* Start public */
+ return {
+ /**
+ * Adds a function to an event of a single element
+ *
+ * @since 1.0 - 2010-02-23
+ * @version 1.0 - 2010-02-23
+ * @param {Object} element The element on which the event is placed
+ * @param {Function} newFunction The function that has to be linked to the event
+ * @param {String} eventType Name of the event
+ * @example
+ * wbos.Events.AddEvent( document.getElementById('elementId'), functionName, "onclick" )
+ */
+ AddEvent: function( element, newFunction, eventType ) {
+ var oldEvent = eval("element." + eventType);
+ var eventContentType = eval("typeof element." + eventType)
+
+ if ( eventContentType != 'function' ) {
+ eval("element." + eventType + " = newFunction")
+ } else {
+ eval("element." + eventType + " = function(e) { oldEvent(e); newFunction(e); }")
+ }
+ }
+ }
+ /* End public */
+})();
+
+
+
+
+
+
+if (typeof(codeview) == "undefined") {
+ /**
+ * @namespace Code written for the Codeview template
+ */
+ codeview = {}
+}
+
+
+
+
+
+
+
+/**
+ * @namespace Enables filtering in class lists
+ * @class
+ * @since 1.0 - 2010-11-08
+ * @version 1.0 - 2010-11-08
+ */
+codeview.classFilter = ( function() {
+ function onkeyup_ClassFilter() {
+ var listItems
+ var search = document.getElementById('ClassFilter').value
+ search = search.toLowerCase()
+ if (document.getElementById('ClassList')) {
+ listItems = document.getElementById('ClassList').getElementsByTagName('li')
+ filterList(listItems, search)
+ }
+ if (document.getElementById('ClassList2')) {
+ listItems = document.getElementById('ClassList2').getElementsByTagName('li')
+ filterList(listItems, search)
+ }
+ if (document.getElementById('FileList')) {
+ listItems = document.getElementById('FileList').getElementsByTagName('li')
+ filterList(listItems, search)
+ }
+ if (document.getElementById('MethodsListInherited')) {
+ var links = document.getElementById('MethodsListInherited').getElementsByTagName('a')
+ var linksSelected = new Array()
+ for (var i=0; i < links.length; i++) {
+ if (links[i].parentNode.parentNode.tagName == "DD") {
+ linksSelected.push(links[i])
+ }
+ }
+ filterList(linksSelected, search)
+ }
+ if (document.getElementById('MethodsList')) {
+ listItems = document.getElementById('MethodsList').getElementsByTagName('tbody')[0].getElementsByTagName('tr')
+ filterList(listItems, search, document.getElementById('MethodDetail').getElementsByTagName('li'))
+ }
+ }
+
+ function filterList(listItems, search, relatedElements) {
+ var itemContent = ""
+ for (var i=0; i < listItems.length; i++) {
+ itemContent = listItems[i].textContent||listItems[i].innerText
+ if (itemContent != undefined) {
+ itemContent = itemContent.toLowerCase()
+ itemContent = itemContent.replace(/\s/g, "")
+ if (itemContent.indexOf(search) >= 0 || itemContent == "") {
+ listItems[i].style.display = ""
+ } else {
+ listItems[i].style.display = "none"
+ }
+ if (relatedElements != null) {
+ filterRelatedList(listItems[i], search, relatedElements)
+ }
+ }
+ }
+ }
+
+ function filterRelatedList(listItem, search, relatedElements) {
+ var itemIndex = parseInt(listItem.className.replace('item', ''))
+ if (itemIndex <= relatedElements.length) {
+ if (relatedElements[itemIndex].className == "item"+ itemIndex) {
+ relatedElements[itemIndex].style.display = listItem.style.display
+ }
+ }
+ }
+
+
+
+
+
+ /* Start public */
+ return {
+ Init: function() {
+ wbos.Events.AddEvent(
+ document.getElementById('ClassFilter'),
+ onkeyup_ClassFilter,
+ "onkeyup"
+ )
+ }
+ }
+ /* End public */
+})();
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/javascript/html5.js b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/javascript/html5.js
new file mode 100644
index 0000000..3587bf7
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/javascript/html5.js
@@ -0,0 +1,6 @@
+// html5shiv MIT @rem remysharp.com/html5-enabling-script
+// iepp v1.6.2 MIT @jon_neal iecss.com/print-protector
+/*@cc_on(function(m,c){var z="abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video";function n(d){for(var a=-1;++a<o;)d.createElement(i[a])}function p(d,a){for(var e=-1,b=d.length,j,q=[];++e<b;){j=d[e];if((a=j.media||a)!="screen")q.push(p(j.imports,a),j.cssText)}return q.join("")}var g=c.createElement("div");g.innerHTML="<z>i</z>";if(g.childNodes.length!==1){var i=z.split("|"),o=i.length,s=RegExp("(^|\\s)("+z+")",
+"gi"),t=RegExp("<(/*)("+z+")","gi"),u=RegExp("(^|[^\\n]*?\\s)("+z+")([^\\n]*)({[\\n\\w\\W]*?})","gi"),r=c.createDocumentFragment(),k=c.documentElement;g=k.firstChild;var h=c.createElement("body"),l=c.createElement("style"),f;n(c);n(r);g.insertBefore(l,
+g.firstChild);l.media="print";m.attachEvent("onbeforeprint",function(){var d=-1,a=p(c.styleSheets,"all"),e=[],b;for(f=f||c.body;(b=u.exec(a))!=null;)e.push((b[1]+b[2]+b[3]).replace(s,"$1.iepp_$2")+b[4]);for(l.styleSheet.cssText=e.join("\n");++d<o;){a=c.getElementsByTagName(i[d]);e=a.length;for(b=-1;++b<e;)if(a[b].className.indexOf("iepp_")<0)a[b].className+=" iepp_"+i[d]}r.appendChild(f);k.appendChild(h);h.className=f.className;h.innerHTML=f.innerHTML.replace(t,"<$1font")});m.attachEvent("onafterprint",
+function(){h.innerHTML="";k.removeChild(h);k.appendChild(f);l.styleSheet.cssText=""})}})(this,document);@*/ \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/RAIServer.html b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/RAIServer.html
new file mode 100644
index 0000000..3e91613
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/RAIServer.html
@@ -0,0 +1,565 @@
+
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="generator" content="JsDoc Toolkit" />
+ <title>RAIServer | JsDoc Reference</title>
+
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
+ <meta name="mobileoptimized" content="0" />
+
+ <link rel="stylesheet" href="../css/all.css" media="all" />
+ <link rel="stylesheet" href="../css/handheld.css" media="only screen and (max-width: 660px)" />
+ <link rel="stylesheet" href="../css/handheld.css" media="handheld" />
+ <link rel="stylesheet" href="../css/screen.css" media="screen and (min-width: 661px)" />
+
+ <script src="../javascript/all.js"></script>
+ <!--[if lt IE 9]>
+ <script src="../javascript/html5.js"></script>
+ <![endif]-->
+ </head>
+
+ <body>
+
+<div class="index">
+ <div class="menu">
+ <div class="indexLinks">
+ <a href="../index.html">Classes</a>
+ <a href="../files.html">Files</a>
+ </div>
+
+ <h2 class="heading1">Classes</h2>
+
+ <input type="text" name="classFilter" class="classFilter" id="ClassFilter" placeholder="Filter"></input>
+
+ <nav>
+ <ul class="classList" id="ClassList">
+
+ <li><a href="../symbols/_global_.html">_global_</a></li>
+
+ <li><a href="../symbols/mockup.html">mockup</a></li>
+
+ <li><a href="../symbols/RAIServer.html">RAIServer</a></li>
+
+ <li><a href="../symbols/RAISocket.html">RAISocket</a></li>
+
+ <li><a href="../symbols/starttls.html">starttls</a></li>
+
+ </ul>
+ </nav>
+ </div>
+ <div class="fineprint" style="clear:both">
+ <footer>
+
+ Documentation generator: <a href="http://code.google.com/p/jsdoc-toolkit/" target="_blank">JsDoc Toolkit</a> 2.4.0<br />
+ Template: <a href="http://www.thebrightlines.com/2010/05/06/new-template-for-jsdoctoolkit-codeview/" target="_blank">Codeview</a> 1.2<br />
+ Generated on:
+ <time datetime='2012-0-22' pubdate>2012-0-22 12:15</time>
+ </footer>
+ </div>
+</div>
+
+<div class="index indexStatic"></div>
+
+<div class="content">
+ <div class="innerContent">
+ <article>
+ <header>
+ <h1 class="classTitle">
+
+ Class <span>RAIServer</span>
+ </h1>
+
+ <div class="intro">
+ <p class="description summary">
+
+ </p>
+
+
+ <ul class="summary">
+
+
+
+ <li>Defined in: <a href="../symbols/src/RAI_lib_rai.js.html">rai.js</a></li>
+
+
+ </ul>
+
+ </div>
+ </header>
+
+
+ <section>
+ <div class="props">
+ <table class="summaryTable" cellspacing="0" summary="A summary of the constructor documented in the class RAIServer.">
+ <caption class="sectionTitle">Class Summary</caption>
+ <thead>
+ <tr>
+ <th scope="col">Constructor Attributes</th>
+ <th scope="col">Constructor Name and Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td class="attributes">&nbsp;</td>
+ <td class="nameDescription" >
+ <div class="fixedFont">
+ <b><a href="../symbols/RAIServer.html#constructor">RAIServer</a></b>(options)
+ </div>
+ <div class="description"><p>Creates instance of RAIServer</p>
+
+<p>Options object has the following properties:</p>
+
+<ul>
+ <li><b>debug</b> - if set to true print traffic to console</li>
+ <li><b>disconnectOnTimeout</b> - if set to true close the connection on disconnect</li>
+ <li><b>timeout</b> - timeout in milliseconds for disconnecting the client,
+ defaults to 0 (no timeout)</li>
+</ul>
+
+<p><b>Events</b></p>
+
+<ul>
+ <li><b>'connect'</b> - emitted if a client connects to the server, param
+ is a client (<a href="../symbols/RAISocket.html">RAISocket</a>) object</li>
+ <li><b>'error'</b> - emitted on error, has an error object as a param</li>
+</ul></div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </section>
+
+
+
+ <!--
+ #### METHODS SUMMARY
+ -->
+
+ <section>
+
+
+ <div class="props">
+ <h2 class="sectionTitle">Method Summary</h2>
+
+
+ <nav>
+ <table class="summaryTable" id="MethodsList" cellspacing="0" summary="A summary of the methods documented in the class RAIServer.">
+ <thead>
+ <tr>
+ <th scope="col">Method Attributes</th>
+ <th scope="col">Method Name and Description</th>
+ </tr>
+ </thead>
+
+ <tbody>
+
+
+ <tr
+ class='item0'
+ >
+ <td class="attributes">&lt;private&gt; &nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont"><b><a href="../symbols/RAIServer.html#_createServer">_createServer</a></b>()
+ </div>
+ <div class="description"><p>Creates a server with listener callback</p></div>
+ </td>
+ </tr>
+
+ <tr
+ class='item1'
+ >
+ <td class="attributes">&lt;private&gt; &nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont"><b><a href="../symbols/RAIServer.html#_serverListener">_serverListener</a></b>(socket)
+ </div>
+ <div class="description"><p>Server listener that is run on client connection</p>
+
+<p><a href="../symbols/RAISocket.html">RAISocket</a> object instance is created based on the client socket
+ and a <code>'connection'</code> event is emitted</p></div>
+ </td>
+ </tr>
+
+ <tr
+ class='item2'
+ >
+ <td class="attributes">&nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont"><b><a href="../symbols/RAIServer.html#end">end</a></b>(callback)
+ </div>
+ <div class="description"><p>Stops the server</p></div>
+ </td>
+ </tr>
+
+ <tr
+ class='item3'
+ >
+ <td class="attributes">&nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont"><b><a href="../symbols/RAIServer.html#listen">listen</a></b>(port, host, callback)
+ </div>
+ <div class="description"><p>Starts listening on selected port</p></div>
+ </td>
+ </tr>
+
+ </tbody>
+ </table>
+ </nav>
+
+
+
+ </div>
+ </section>
+
+
+ <!--
+ #### EVENTS SUMMARY
+ -->
+
+
+ <section>
+
+ <nav>
+ <div class="props">
+ <table class="summaryTable" cellspacing="0" summary="A summary of the events documented in the class RAIServer.">
+ <caption class="sectionTitle">Event Summary</caption>
+
+ <thead>
+ <tr>
+ <th scope="col">Event Attributes</th>
+ <th scope="col">Event Name and Description</th>
+ </tr>
+ </thead>
+
+ <tbody>
+
+ <tr>
+ <td class="attributes">&lt;private&gt; &nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont"><b><a href="../symbols/RAIServer.html#event:_onError">_onError</a></b>(err)
+ </div>
+ <div class="description"><p>Listens for errors</p></div>
+ </td>
+ </tr>
+
+ </tbody>
+ </table>
+ </div>
+ </nav>
+
+
+
+ </section>
+
+ <!--
+ #### CONSTRUCTOR DETAILS
+ -->
+
+ <section>
+ <div class="details props">
+ <div class="innerProps">
+ <h2 class="sectionTitle" id="constructor">
+ Class Detail
+ </h2>
+
+ <div class="fixedFont">
+ <b>RAIServer</b>(options)
+ </div>
+
+ <div class="description">
+ <p>Creates instance of RAIServer</p>
+
+<p>Options object has the following properties:</p>
+
+<ul>
+ <li><b>debug</b> - if set to true print traffic to console</li>
+ <li><b>disconnectOnTimeout</b> - if set to true close the connection on disconnect</li>
+ <li><b>timeout</b> - timeout in milliseconds for disconnecting the client,
+ defaults to 0 (no timeout)</li>
+</ul>
+
+<p><b>Events</b></p>
+
+<ul>
+ <li><b>'connect'</b> - emitted if a client connects to the server, param
+ is a client (<a href="../symbols/RAISocket.html">RAISocket</a>) object</li>
+ <li><b>'error'</b> - emitted on error, has an error object as a param</li>
+</ul>
+
+ </div>
+
+
+
+
+ <dl class="detailList params">
+ <dt class="heading">Parameters:</dt>
+
+ <dt>
+ <span class="light fixedFont">{Object}</span> <b>options</b>
+ <i>Optional</i>
+ </dt>
+ <dd>Optional options object</dd>
+
+ </dl>
+
+
+
+ </div>
+ </div>
+ </section>
+
+ <!--
+ #### FIELD DETAILS
+ -->
+
+ <!--
+ #### METHOD DETAILS
+ -->
+
+ <section>
+ <div class="details props">
+ <div class="innerProps">
+ <h2 class="sectionTitle">
+ Method Detail
+ </h2>
+
+ <ul class="methodDetail" id="MethodDetail">
+
+
+ <li
+ class='item0'
+ >
+ <div class="fixedFont heading" id="_createServer">
+ <span class='lighter'>
+ &lt;private&gt;
+ </span>
+
+
+
+ <b>_createServer</b>()
+ </div>
+
+ <div class="description">
+ <p>Creates a server with listener callback</p>
+
+
+
+
+ </div>
+
+
+
+
+
+
+ <div class="hr"></div>
+ </li>
+
+ <li
+ class='item1'
+ >
+ <div class="fixedFont heading" id="_serverListener">
+ <span class='lighter'>
+ &lt;private&gt;
+ </span>
+
+
+
+ <b>_serverListener</b>(socket)
+ </div>
+
+ <div class="description">
+ <p>Server listener that is run on client connection</p>
+
+<p><a href="../symbols/RAISocket.html">RAISocket</a> object instance is created based on the client socket
+ and a <code>'connection'</code> event is emitted</p>
+
+
+
+
+ </div>
+
+
+
+
+ <dl class="detailList params">
+ <dt class="heading">Parameters:</dt>
+
+ <dt>
+ <span class="light fixedFont">{Object}</span> <b>socket</b>
+
+ </dt>
+ <dd>The socket to the client</dd>
+
+ </dl>
+
+
+
+ <div class="hr"></div>
+ </li>
+
+ <li
+ class='item2'
+ >
+ <div class="fixedFont heading" id="end">
+ <span class='lighter'>
+
+ </span>
+
+
+
+ <b>end</b>(callback)
+ </div>
+
+ <div class="description">
+ <p>Stops the server</p>
+
+
+
+
+ </div>
+
+
+
+
+ <dl class="detailList params">
+ <dt class="heading">Parameters:</dt>
+
+ <dt>
+ <span class="light fixedFont">{Function}</span> <b>callback</b>
+
+ </dt>
+ <dd>Is run when the server is closed</dd>
+
+ </dl>
+
+
+
+ <div class="hr"></div>
+ </li>
+
+ <li
+ class='item3'
+ >
+ <div class="fixedFont heading" id="listen">
+ <span class='lighter'>
+
+ </span>
+
+
+
+ <b>listen</b>(port, host, callback)
+ </div>
+
+ <div class="description">
+ <p>Starts listening on selected port</p>
+
+
+
+
+ </div>
+
+
+
+
+ <dl class="detailList params">
+ <dt class="heading">Parameters:</dt>
+
+ <dt>
+ <span class="light fixedFont">{Number}</span> <b>port</b>
+
+ </dt>
+ <dd>The port to listen</dd>
+
+ <dt>
+ <span class="light fixedFont">{String}</span> <b>host</b>
+ <i>Optional</i>
+ </dt>
+ <dd>The IP address to listen</dd>
+
+ <dt>
+ <span class="light fixedFont">{Function}</span> <b>callback</b>
+
+ </dt>
+ <dd>The callback function to be run after the server
+is listening, the only param is an error message if the operation failed</dd>
+
+ </dl>
+
+
+
+
+ </li>
+
+ </ul>
+ </div>
+ </div>
+ </section>
+
+
+ <!--
+ #### EVENT DETAILS
+ -->
+
+ <section>
+ <div class="details props">
+ <div class="innerProps">
+ <h2 class="sectionTitle">
+ Event Detail
+ </h2>
+
+
+ <div class="fixedFont heading" id="event:_onError">
+ <span class='lighter'>
+ &lt;private&gt;
+ </span>
+
+
+
+ <b>_onError</b>(err)
+ </div>
+
+ <div class="description">
+ <p>Listens for errors</p>
+
+
+
+
+ </div>
+
+
+
+
+ <dl class="detailList params">
+ <dt class="heading">Parameters:</dt>
+
+ <dt>
+ <span class="light fixedFont">{Object}</span> <b>err</b>
+
+ </dt>
+ <dd>Error object</dd>
+
+ </dl>
+
+
+
+
+
+
+ </div>
+ </div>
+ </section>
+
+ </article>
+ </div>
+</div>
+
+ <script type="text/javascript">
+ wbos.CssTools.MediaQueryFallBack.LoadCss('../css/screen.css', '../css/handheld.css', 660)
+ codeview.classFilter.Init()
+ </script>
+ </body>
+</html>
+
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/RAISocket.html b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/RAISocket.html
new file mode 100644
index 0000000..15cad38
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/RAISocket.html
@@ -0,0 +1,826 @@
+
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="generator" content="JsDoc Toolkit" />
+ <title>RAISocket | JsDoc Reference</title>
+
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
+ <meta name="mobileoptimized" content="0" />
+
+ <link rel="stylesheet" href="../css/all.css" media="all" />
+ <link rel="stylesheet" href="../css/handheld.css" media="only screen and (max-width: 660px)" />
+ <link rel="stylesheet" href="../css/handheld.css" media="handheld" />
+ <link rel="stylesheet" href="../css/screen.css" media="screen and (min-width: 661px)" />
+
+ <script src="../javascript/all.js"></script>
+ <!--[if lt IE 9]>
+ <script src="../javascript/html5.js"></script>
+ <![endif]-->
+ </head>
+
+ <body>
+
+<div class="index">
+ <div class="menu">
+ <div class="indexLinks">
+ <a href="../index.html">Classes</a>
+ <a href="../files.html">Files</a>
+ </div>
+
+ <h2 class="heading1">Classes</h2>
+
+ <input type="text" name="classFilter" class="classFilter" id="ClassFilter" placeholder="Filter"></input>
+
+ <nav>
+ <ul class="classList" id="ClassList">
+
+ <li><a href="../symbols/_global_.html">_global_</a></li>
+
+ <li><a href="../symbols/mockup.html">mockup</a></li>
+
+ <li><a href="../symbols/RAIServer.html">RAIServer</a></li>
+
+ <li><a href="../symbols/RAISocket.html">RAISocket</a></li>
+
+ <li><a href="../symbols/starttls.html">starttls</a></li>
+
+ </ul>
+ </nav>
+ </div>
+ <div class="fineprint" style="clear:both">
+ <footer>
+
+ Documentation generator: <a href="http://code.google.com/p/jsdoc-toolkit/" target="_blank">JsDoc Toolkit</a> 2.4.0<br />
+ Template: <a href="http://www.thebrightlines.com/2010/05/06/new-template-for-jsdoctoolkit-codeview/" target="_blank">Codeview</a> 1.2<br />
+ Generated on:
+ <time datetime='2012-0-22' pubdate>2012-0-22 12:15</time>
+ </footer>
+ </div>
+</div>
+
+<div class="index indexStatic"></div>
+
+<div class="content">
+ <div class="innerContent">
+ <article>
+ <header>
+ <h1 class="classTitle">
+
+ Class <span>RAISocket</span>
+ </h1>
+
+ <div class="intro">
+ <p class="description summary">
+
+ </p>
+
+
+ <ul class="summary">
+
+
+
+ <li>Defined in: <a href="../symbols/src/RAI_lib_rai.js.html">rai.js</a></li>
+
+
+ </ul>
+
+ </div>
+ </header>
+
+
+ <section>
+ <div class="props">
+ <table class="summaryTable" cellspacing="0" summary="A summary of the constructor documented in the class RAISocket.">
+ <caption class="sectionTitle">Class Summary</caption>
+ <thead>
+ <tr>
+ <th scope="col">Constructor Attributes</th>
+ <th scope="col">Constructor Name and Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td class="attributes">&nbsp;</td>
+ <td class="nameDescription" >
+ <div class="fixedFont">
+ <b><a href="../symbols/RAISocket.html#constructor">RAISocket</a></b>(socket, options)
+ </div>
+ <div class="description"><p>Creates a instance for interacting with a client (socket)</p>
+
+<p>Optional options object is the same that is passed to the parent
+<a href="../symbols/RAIServer.html">RAIServer</a> object</p>
+
+<p><b>Events</b></p>
+
+<ul>
+ <li><b>'command'</b> - emitted if a client sends a command.</div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </section>
+
+
+
+ <!--
+ #### METHODS SUMMARY
+ -->
+
+ <section>
+
+
+ <div class="props">
+ <h2 class="sectionTitle">Method Summary</h2>
+
+
+ <nav>
+ <table class="summaryTable" id="MethodsList" cellspacing="0" summary="A summary of the methods documented in the class RAISocket.">
+ <thead>
+ <tr>
+ <th scope="col">Method Attributes</th>
+ <th scope="col">Method Name and Description</th>
+ </tr>
+ </thead>
+
+ <tbody>
+
+
+ <tr
+ class='item0'
+ >
+ <td class="attributes">&lt;private&gt; &nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont"><b><a href="../symbols/RAISocket.html#_destroy">_destroy</a></b>()
+ </div>
+ <div class="description"><p>Called when the connection is or is going to be ended</p></div>
+ </td>
+ </tr>
+
+ <tr
+ class='item1'
+ >
+ <td class="attributes">&lt;private&gt; &nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont"><b><a href="../symbols/RAISocket.html#_processData">_processData</a></b>(str)
+ </div>
+ <div class="description"><p>Processed incoming command lines and emits found data as
+<code>'command'</code> with the command name as the first param and the rest
+of the data as second (Buffer)</p></div>
+ </td>
+ </tr>
+
+ <tr
+ class='item2'
+ >
+ <td class="attributes">&nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont"><b><a href="../symbols/RAISocket.html#end">end</a></b>()
+ </div>
+ <div class="description"><p>Closes the connection to the client</p></div>
+ </td>
+ </tr>
+
+ <tr
+ class='item3'
+ >
+ <td class="attributes">&nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont"><b><a href="../symbols/RAISocket.html#send">send</a></b>(data)
+ </div>
+ <div class="description"><p>Sends some data to the client.</div>
+ </td>
+ </tr>
+
+ <tr
+ class='item4'
+ >
+ <td class="attributes">&nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont"><b><a href="../symbols/RAISocket.html#startDataMode">startDataMode</a></b>(sequence)
+ </div>
+ <div class="description"><p>Instructs the server to be listening for mixed data instead of line based
+ commands</p></div>
+ </td>
+ </tr>
+
+ <tr
+ class='item5'
+ >
+ <td class="attributes">&nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont"><b><a href="../symbols/RAISocket.html#startTLS">startTLS</a></b>(credentials, callback)
+ </div>
+ <div class="description"><p>Instructs the server to upgrade the connection to secure TLS connection</p>
+
+<p>Fires <code>callback</code> on successful connection upgrade if set,
+otherwise emits <code>'tls'</code></p></div>
+ </td>
+ </tr>
+
+ </tbody>
+ </table>
+ </nav>
+
+
+
+ </div>
+ </section>
+
+
+ <!--
+ #### EVENTS SUMMARY
+ -->
+
+
+ <section>
+
+ <nav>
+ <div class="props">
+ <table class="summaryTable" cellspacing="0" summary="A summary of the events documented in the class RAISocket.">
+ <caption class="sectionTitle">Event Summary</caption>
+
+ <thead>
+ <tr>
+ <th scope="col">Event Attributes</th>
+ <th scope="col">Event Name and Description</th>
+ </tr>
+ </thead>
+
+ <tbody>
+
+ <tr>
+ <td class="attributes">&lt;private&gt; &nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont"><b><a href="../symbols/RAISocket.html#event:_onClose">_onClose</a></b>(hadError)
+ </div>
+ <div class="description"><p>Called when the connection is closed</p></div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="attributes">&lt;private&gt; &nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont"><b><a href="../symbols/RAISocket.html#event:_onEnd">_onEnd</a></b>()
+ </div>
+ <div class="description"><p>Called when the connection is ended.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="attributes">&lt;private&gt; &nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont"><b><a href="../symbols/RAISocket.html#event:_onError">_onError</a></b>(err)
+ </div>
+ <div class="description"><p>Called when an error has appeared.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="attributes">&lt;private&gt; &nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont"><b><a href="../symbols/RAISocket.html#event:_onReceiveData">_onReceiveData</a></b>(chunk)
+ </div>
+ <div class="description"><p>Called when a chunk of data arrives from the client.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="attributes">&lt;private&gt; &nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont"><b><a href="../symbols/RAISocket.html#event:_onTimeout">_onTimeout</a></b>()
+ </div>
+ <div class="description"><p>Called when a timeout has occured.</div>
+ </td>
+ </tr>
+
+ </tbody>
+ </table>
+ </div>
+ </nav>
+
+
+
+ </section>
+
+ <!--
+ #### CONSTRUCTOR DETAILS
+ -->
+
+ <section>
+ <div class="details props">
+ <div class="innerProps">
+ <h2 class="sectionTitle" id="constructor">
+ Class Detail
+ </h2>
+
+ <div class="fixedFont">
+ <b>RAISocket</b>(socket, options)
+ </div>
+
+ <div class="description">
+ <p>Creates a instance for interacting with a client (socket)</p>
+
+<p>Optional options object is the same that is passed to the parent
+<a href="../symbols/RAIServer.html">RAIServer</a> object</p>
+
+<p><b>Events</b></p>
+
+<ul>
+ <li><b>'command'</b> - emitted if a client sends a command. Gets two
+ params - command (String) and payload (Buffer)</li>
+ <li><b>'data'</b> - emitted when a chunk is received in data mode, the
+ param being the payload (Buffer)</li>
+ <li><b>'ready'</b> - emitted when data stream ends and normal command
+ flow is recovered</li>
+ <li><b>'tls'</b> - emitted when the connection is secured by TLS</li>
+ <li><b>'error'</b> - emitted when an error occurs. Connection to the
+ client is disconnected automatically. Param is an error object.</l>
+ <li><b>'timeout'</b> - emitted when a timeout occurs. Connection to the
+ client is disconnected automatically if disconnectOnTimeout option
+ is set to true.</l>
+ <li><b>'end'</b> - emitted when the client disconnects</l>
+</ul>
+
+ </div>
+
+
+
+
+ <dl class="detailList params">
+ <dt class="heading">Parameters:</dt>
+
+ <dt>
+ <span class="light fixedFont">{Object}</span> <b>socket</b>
+
+ </dt>
+ <dd>Socket for the client</dd>
+
+ <dt>
+ <span class="light fixedFont">{Object}</span> <b>options</b>
+ <i>Optional</i>
+ </dt>
+ <dd>Optional options object</dd>
+
+ </dl>
+
+
+
+ </div>
+ </div>
+ </section>
+
+ <!--
+ #### FIELD DETAILS
+ -->
+
+ <!--
+ #### METHOD DETAILS
+ -->
+
+ <section>
+ <div class="details props">
+ <div class="innerProps">
+ <h2 class="sectionTitle">
+ Method Detail
+ </h2>
+
+ <ul class="methodDetail" id="MethodDetail">
+
+
+ <li
+ class='item0'
+ >
+ <div class="fixedFont heading" id="_destroy">
+ <span class='lighter'>
+ &lt;private&gt;
+ </span>
+
+
+
+ <b>_destroy</b>()
+ </div>
+
+ <div class="description">
+ <p>Called when the connection is or is going to be ended</p>
+
+
+
+
+ </div>
+
+
+
+
+
+
+ <div class="hr"></div>
+ </li>
+
+ <li
+ class='item1'
+ >
+ <div class="fixedFont heading" id="_processData">
+ <span class='lighter'>
+ &lt;private&gt;
+ </span>
+
+
+
+ <b>_processData</b>(str)
+ </div>
+
+ <div class="description">
+ <p>Processed incoming command lines and emits found data as
+<code>'command'</code> with the command name as the first param and the rest
+of the data as second (Buffer)</p>
+
+
+
+
+ </div>
+
+
+
+
+ <dl class="detailList params">
+ <dt class="heading">Parameters:</dt>
+
+ <dt>
+ <span class="light fixedFont">{String}</span> <b>str</b>
+
+ </dt>
+ <dd>Binary string to be processed</dd>
+
+ </dl>
+
+
+
+ <div class="hr"></div>
+ </li>
+
+ <li
+ class='item2'
+ >
+ <div class="fixedFont heading" id="end">
+ <span class='lighter'>
+
+ </span>
+
+
+
+ <b>end</b>()
+ </div>
+
+ <div class="description">
+ <p>Closes the connection to the client</p>
+
+
+
+
+ </div>
+
+
+
+
+
+
+ <div class="hr"></div>
+ </li>
+
+ <li
+ class='item3'
+ >
+ <div class="fixedFont heading" id="send">
+ <span class='lighter'>
+
+ </span>
+
+
+
+ <b>send</b>(data)
+ </div>
+
+ <div class="description">
+ <p>Sends some data to the client. <code>&lt;CR&gt;&lt;LF&gt;</code> is automatically appended to
+ the data</p>
+
+
+
+
+ </div>
+
+
+
+
+ <dl class="detailList params">
+ <dt class="heading">Parameters:</dt>
+
+ <dt>
+ <span class="light fixedFont">{String|Buffer}</span> <b>data</b>
+
+ </dt>
+ <dd>Data to be sent to the client</dd>
+
+ </dl>
+
+
+
+ <div class="hr"></div>
+ </li>
+
+ <li
+ class='item4'
+ >
+ <div class="fixedFont heading" id="startDataMode">
+ <span class='lighter'>
+
+ </span>
+
+
+
+ <b>startDataMode</b>(sequence)
+ </div>
+
+ <div class="description">
+ <p>Instructs the server to be listening for mixed data instead of line based
+ commands</p>
+
+
+
+
+ </div>
+
+
+
+
+ <dl class="detailList params">
+ <dt class="heading">Parameters:</dt>
+
+ <dt>
+ <span class="light fixedFont">{String}</span> <b>sequence</b>
+ <i>Optional, Default: "."</i>
+ </dt>
+ <dd>- optional sequence on separate line for
+ matching the data end</dd>
+
+ </dl>
+
+
+
+ <div class="hr"></div>
+ </li>
+
+ <li
+ class='item5'
+ >
+ <div class="fixedFont heading" id="startTLS">
+ <span class='lighter'>
+
+ </span>
+
+
+
+ <b>startTLS</b>(credentials, callback)
+ </div>
+
+ <div class="description">
+ <p>Instructs the server to upgrade the connection to secure TLS connection</p>
+
+<p>Fires <code>callback</code> on successful connection upgrade if set,
+otherwise emits <code>'tls'</code></p>
+
+
+
+
+ </div>
+
+
+
+
+ <dl class="detailList params">
+ <dt class="heading">Parameters:</dt>
+
+ <dt>
+ <span class="light fixedFont">{Object}</span> <b>credentials</b>
+ <i>Optional</i>
+ </dt>
+ <dd>An object with PEM encoded key and
+ certificate <code>{key:"---BEGIN...", cert:"---BEGIN..."}</code>,
+ if not set autogenerated values will be used.</dd>
+
+ <dt>
+ <span class="light fixedFont">{Function}</span> <b>callback</b>
+ <i>Optional</i>
+ </dt>
+ <dd>If calback is set fire it after successful connection
+ upgrade, otherwise <code>'tls'</code> is emitted</dd>
+
+ </dl>
+
+
+
+
+ </li>
+
+ </ul>
+ </div>
+ </div>
+ </section>
+
+
+ <!--
+ #### EVENT DETAILS
+ -->
+
+ <section>
+ <div class="details props">
+ <div class="innerProps">
+ <h2 class="sectionTitle">
+ Event Detail
+ </h2>
+
+
+ <div class="fixedFont heading" id="event:_onClose">
+ <span class='lighter'>
+ &lt;private&gt;
+ </span>
+
+
+
+ <b>_onClose</b>(hadError)
+ </div>
+
+ <div class="description">
+ <p>Called when the connection is closed</p>
+
+
+
+
+ </div>
+
+
+
+
+ <dl class="detailList params">
+ <dt class="heading">Parameters:</dt>
+
+ <dt>
+ <span class="light fixedFont">{Boolean}</span> <b>hadError</b>
+
+ </dt>
+ <dd>did the connection end because of an error?</dd>
+
+ </dl>
+
+
+
+
+ <div class="hr"></div>
+
+ <div class="fixedFont heading" id="event:_onEnd">
+ <span class='lighter'>
+ &lt;private&gt;
+ </span>
+
+
+
+ <b>_onEnd</b>()
+ </div>
+
+ <div class="description">
+ <p>Called when the connection is ended. Emits <code>'end'</code></p>
+
+
+
+
+ </div>
+
+
+
+
+
+
+
+ <div class="hr"></div>
+
+ <div class="fixedFont heading" id="event:_onError">
+ <span class='lighter'>
+ &lt;private&gt;
+ </span>
+
+
+
+ <b>_onError</b>(err)
+ </div>
+
+ <div class="description">
+ <p>Called when an error has appeared. Emits <code>'error'</code> with
+the error object as a parameter.</p>
+
+
+
+
+ </div>
+
+
+
+
+ <dl class="detailList params">
+ <dt class="heading">Parameters:</dt>
+
+ <dt>
+ <span class="light fixedFont">{Object}</span> <b>err</b>
+
+ </dt>
+ <dd>Error object</dd>
+
+ </dl>
+
+
+
+
+ <div class="hr"></div>
+
+ <div class="fixedFont heading" id="event:_onReceiveData">
+ <span class='lighter'>
+ &lt;private&gt;
+ </span>
+
+
+
+ <b>_onReceiveData</b>(chunk)
+ </div>
+
+ <div class="description">
+ <p>Called when a chunk of data arrives from the client. If currently in data
+mode, transmit the data otherwise send it to <code>_processData</code></p>
+
+
+
+
+ </div>
+
+
+
+
+ <dl class="detailList params">
+ <dt class="heading">Parameters:</dt>
+
+ <dt>
+ <span class="light fixedFont">{Buffer|String}</span> <b>chunk</b>
+
+ </dt>
+ <dd>Data sent by the client</dd>
+
+ </dl>
+
+
+
+
+ <div class="hr"></div>
+
+ <div class="fixedFont heading" id="event:_onTimeout">
+ <span class='lighter'>
+ &lt;private&gt;
+ </span>
+
+
+
+ <b>_onTimeout</b>()
+ </div>
+
+ <div class="description">
+ <p>Called when a timeout has occured. Connection will be closed and
+<code>'timeout'</code> is emitted.</p>
+
+
+
+
+ </div>
+
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ </section>
+
+ </article>
+ </div>
+</div>
+
+ <script type="text/javascript">
+ wbos.CssTools.MediaQueryFallBack.LoadCss('../css/screen.css', '../css/handheld.css', 660)
+ codeview.classFilter.Init()
+ </script>
+ </body>
+</html>
+
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/_global_.html b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/_global_.html
new file mode 100644
index 0000000..b215cf7
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/_global_.html
@@ -0,0 +1,122 @@
+
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="generator" content="JsDoc Toolkit" />
+ <title>_global_ | JsDoc Reference</title>
+
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
+ <meta name="mobileoptimized" content="0" />
+
+ <link rel="stylesheet" href="../css/all.css" media="all" />
+ <link rel="stylesheet" href="../css/handheld.css" media="only screen and (max-width: 660px)" />
+ <link rel="stylesheet" href="../css/handheld.css" media="handheld" />
+ <link rel="stylesheet" href="../css/screen.css" media="screen and (min-width: 661px)" />
+
+ <script src="../javascript/all.js"></script>
+ <!--[if lt IE 9]>
+ <script src="../javascript/html5.js"></script>
+ <![endif]-->
+ </head>
+
+ <body>
+
+<div class="index">
+ <div class="menu">
+ <div class="indexLinks">
+ <a href="../index.html">Classes</a>
+ <a href="../files.html">Files</a>
+ </div>
+
+ <h2 class="heading1">Classes</h2>
+
+ <input type="text" name="classFilter" class="classFilter" id="ClassFilter" placeholder="Filter"></input>
+
+ <nav>
+ <ul class="classList" id="ClassList">
+
+ <li><a href="../symbols/_global_.html">_global_</a></li>
+
+ <li><a href="../symbols/mockup.html">mockup</a></li>
+
+ <li><a href="../symbols/RAIServer.html">RAIServer</a></li>
+
+ <li><a href="../symbols/RAISocket.html">RAISocket</a></li>
+
+ <li><a href="../symbols/starttls.html">starttls</a></li>
+
+ </ul>
+ </nav>
+ </div>
+ <div class="fineprint" style="clear:both">
+ <footer>
+
+ Documentation generator: <a href="http://code.google.com/p/jsdoc-toolkit/" target="_blank">JsDoc Toolkit</a> 2.4.0<br />
+ Template: <a href="http://www.thebrightlines.com/2010/05/06/new-template-for-jsdoctoolkit-codeview/" target="_blank">Codeview</a> 1.2<br />
+ Generated on:
+ <time datetime='2012-0-22' pubdate>2012-0-22 12:15</time>
+ </footer>
+ </div>
+</div>
+
+<div class="index indexStatic"></div>
+
+<div class="content">
+ <div class="innerContent">
+ <article>
+ <header>
+ <h1 class="classTitle">
+
+ Built-In Namespace <span>_global_</span>
+ </h1>
+
+ <div class="intro">
+ <p class="description summary">
+
+ </p>
+
+
+ </div>
+ </header>
+
+
+
+
+ <!--
+ #### METHODS SUMMARY
+ -->
+
+
+ <!--
+ #### EVENTS SUMMARY
+ -->
+
+ <!--
+ #### CONSTRUCTOR DETAILS
+ -->
+
+ <!--
+ #### FIELD DETAILS
+ -->
+
+ <!--
+ #### METHOD DETAILS
+ -->
+
+
+ <!--
+ #### EVENT DETAILS
+ -->
+
+ </article>
+ </div>
+</div>
+
+ <script type="text/javascript">
+ wbos.CssTools.MediaQueryFallBack.LoadCss('../css/screen.css', '../css/handheld.css', 660)
+ codeview.classFilter.Init()
+ </script>
+ </body>
+</html>
+
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/mockup.html b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/mockup.html
new file mode 100644
index 0000000..987f5be
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/mockup.html
@@ -0,0 +1,264 @@
+
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="generator" content="JsDoc Toolkit" />
+ <title>mockup | JsDoc Reference</title>
+
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
+ <meta name="mobileoptimized" content="0" />
+
+ <link rel="stylesheet" href="../css/all.css" media="all" />
+ <link rel="stylesheet" href="../css/handheld.css" media="only screen and (max-width: 660px)" />
+ <link rel="stylesheet" href="../css/handheld.css" media="handheld" />
+ <link rel="stylesheet" href="../css/screen.css" media="screen and (min-width: 661px)" />
+
+ <script src="../javascript/all.js"></script>
+ <!--[if lt IE 9]>
+ <script src="../javascript/html5.js"></script>
+ <![endif]-->
+ </head>
+
+ <body>
+
+<div class="index">
+ <div class="menu">
+ <div class="indexLinks">
+ <a href="../index.html">Classes</a>
+ <a href="../files.html">Files</a>
+ </div>
+
+ <h2 class="heading1">Classes</h2>
+
+ <input type="text" name="classFilter" class="classFilter" id="ClassFilter" placeholder="Filter"></input>
+
+ <nav>
+ <ul class="classList" id="ClassList">
+
+ <li><a href="../symbols/_global_.html">_global_</a></li>
+
+ <li><a href="../symbols/mockup.html">mockup</a></li>
+
+ <li><a href="../symbols/RAIServer.html">RAIServer</a></li>
+
+ <li><a href="../symbols/RAISocket.html">RAISocket</a></li>
+
+ <li><a href="../symbols/starttls.html">starttls</a></li>
+
+ </ul>
+ </nav>
+ </div>
+ <div class="fineprint" style="clear:both">
+ <footer>
+
+ Documentation generator: <a href="http://code.google.com/p/jsdoc-toolkit/" target="_blank">JsDoc Toolkit</a> 2.4.0<br />
+ Template: <a href="http://www.thebrightlines.com/2010/05/06/new-template-for-jsdoctoolkit-codeview/" target="_blank">Codeview</a> 1.2<br />
+ Generated on:
+ <time datetime='2012-0-22' pubdate>2012-0-22 12:15</time>
+ </footer>
+ </div>
+</div>
+
+<div class="index indexStatic"></div>
+
+<div class="content">
+ <div class="innerContent">
+ <article>
+ <header>
+ <h1 class="classTitle">
+
+ Namespace <span>mockup</span>
+ </h1>
+
+ <div class="intro">
+ <p class="description summary">
+ Mockup module
+ </p>
+
+
+ <ul class="summary">
+
+
+
+ <li>Defined in: <a href="../symbols/src/RAI_lib_mockup.js.html">mockup.js</a></li>
+
+
+ </ul>
+
+ </div>
+ </header>
+
+
+
+
+ <!--
+ #### METHODS SUMMARY
+ -->
+
+ <section>
+
+
+ <div class="props">
+ <h2 class="sectionTitle">Method Summary</h2>
+
+
+ <nav>
+ <table class="summaryTable" id="MethodsList" cellspacing="0" summary="A summary of the methods documented in the class mockup.">
+ <thead>
+ <tr>
+ <th scope="col">Method Attributes</th>
+ <th scope="col">Method Name and Description</th>
+ </tr>
+ </thead>
+
+ <tbody>
+
+
+ <tr
+ class='item0'
+ >
+ <td class="attributes">&lt;static&gt; &nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont">mockup.<b><a href="../symbols/mockup.html#.runClientMockup">runClientMockup</a></b>(port, host, commands, callback, debug)
+ </div>
+ <div class="description"><p>Runs a batch of commands against a server</p>
+
+<pre>
+var cmds = ["EHLO FOOBAR", "STARTTLS", "QUIT"];
+runClientMockup(25, "mail.hot.ee", cmds, function(resp){
+ console.log("Final:", resp.toString("utf-8").trim());
+});
+</pre></div>
+ </td>
+ </tr>
+
+ </tbody>
+ </table>
+ </nav>
+
+
+
+ </div>
+ </section>
+
+
+ <!--
+ #### EVENTS SUMMARY
+ -->
+
+ <!--
+ #### CONSTRUCTOR DETAILS
+ -->
+
+ <!--
+ #### FIELD DETAILS
+ -->
+
+ <!--
+ #### METHOD DETAILS
+ -->
+
+ <section>
+ <div class="details props">
+ <div class="innerProps">
+ <h2 class="sectionTitle">
+ Method Detail
+ </h2>
+
+ <ul class="methodDetail" id="MethodDetail">
+
+
+ <li
+ class='item0'
+ >
+ <div class="fixedFont heading" id=".runClientMockup">
+ <span class='lighter'>
+ &lt;static&gt;
+ </span>
+
+
+
+ <span class="light">mockup.</span><b>runClientMockup</b>(port, host, commands, callback, debug)
+ </div>
+
+ <div class="description">
+ <p>Runs a batch of commands against a server</p>
+
+<pre>
+var cmds = ["EHLO FOOBAR", "STARTTLS", "QUIT"];
+runClientMockup(25, "mail.hot.ee", cmds, function(resp){
+ console.log("Final:", resp.toString("utf-8").trim());
+});
+</pre>
+
+
+
+
+ </div>
+
+
+
+
+ <dl class="detailList params">
+ <dt class="heading">Parameters:</dt>
+
+ <dt>
+ <span class="light fixedFont">{Number}</span> <b>port</b>
+
+ </dt>
+ <dd>Port number</dd>
+
+ <dt>
+ <span class="light fixedFont">{String}</span> <b>host</b>
+
+ </dt>
+ <dd>Hostname to connect to</dd>
+
+ <dt>
+ <span class="light fixedFont">{Array}</span> <b>commands</b>
+
+ </dt>
+ <dd>Command list to be sent to server</dd>
+
+ <dt>
+ <span class="light fixedFont">{Function}</span> <b>callback</b>
+
+ </dt>
+ <dd>Callback function to run on completion,
+ has the last response from the server as a param</dd>
+
+ <dt>
+ <span class="light fixedFont">{Boolean}</span> <b>debug</b>
+ <i>Optional</i>
+ </dt>
+ <dd>if set to true log all input/output</dd>
+
+ </dl>
+
+
+
+
+ </li>
+
+ </ul>
+ </div>
+ </div>
+ </section>
+
+
+ <!--
+ #### EVENT DETAILS
+ -->
+
+ </article>
+ </div>
+</div>
+
+ <script type="text/javascript">
+ wbos.CssTools.MediaQueryFallBack.LoadCss('../css/screen.css', '../css/handheld.css', 660)
+ codeview.classFilter.Init()
+ </script>
+ </body>
+</html>
+
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_index.js.html b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_index.js.html
new file mode 100644
index 0000000..3cee0e3
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_index.js.html
@@ -0,0 +1,394 @@
+<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"> <style>
+ .KEYW {color: #933;}
+ .COMM {color: #bbb; font-style: italic;}
+ .NUMB {color: #393;}
+ .STRN {color: #393;}
+ .REGX {color: #339;}
+ .line {border-right: 1px dotted #666; color: #666; font-style: normal;}
+ </style></head><body><pre><span class='line'> 1</span> <span class="COMM">/**
+<span class='line'> 2</span> * @fileOverview This is the main file for the RAI library to create text based servers
+<span class='line'> 3</span> * @author &lt;a href="mailto:andris@node.ee">Andris Reinman&lt;/a>
+<span class='line'> 4</span> * @version 0.1.0
+<span class='line'> 5</span> */</span><span class="WHIT">
+<span class='line'> 6</span>
+<span class='line'> 7</span> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">netlib</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">"net"</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'> 8</span> </span><span class="WHIT"> </span><span class="NAME">utillib</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">"util"</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'> 9</span> </span><span class="WHIT"> </span><span class="NAME">EventEmitter</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">'events'</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">EventEmitter</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'> 10</span> </span><span class="WHIT"> </span><span class="NAME">starttls</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">"./starttls"</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'> 11</span> </span><span class="WHIT"> </span><span class="NAME">tlslib</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">"tls"</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'> 12</span> </span><span class="WHIT"> </span><span class="NAME">crypto</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">"crypto"</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'> 13</span> </span><span class="WHIT"> </span><span class="NAME">fs</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">"fs"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 14</span>
+<span class='line'> 15</span> </span><span class="COMM">// Default credentials for starting TLS server</span><span class="WHIT">
+<span class='line'> 16</span> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">defaultCredentials</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 17</span> </span><span class="WHIT"> </span><span class="NAME">key</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NAME">fs.readFileSync</span><span class="PUNC">(</span><span class="NAME">__dirname</span><span class="PUNC">+</span><span class="STRN">"/cert/key.pem"</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'> 18</span> </span><span class="WHIT"> </span><span class="NAME">cert</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NAME">fs.readFileSync</span><span class="PUNC">(</span><span class="NAME">__dirname</span><span class="PUNC">+</span><span class="STRN">"/cert/cert.pem"</span><span class="PUNC">)</span><span class="WHIT">
+<span class='line'> 19</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 20</span>
+<span class='line'> 21</span> </span><span class="COMM">// Expose to the world</span><span class="WHIT">
+<span class='line'> 22</span> </span><span class="NAME">module.exports.RAIServer</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">RAIServer</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 23</span>
+<span class='line'> 24</span> </span><span class="COMM">/**
+<span class='line'> 25</span> * &lt;p>Creates instance of RAIServer&lt;/p>
+<span class='line'> 26</span> *
+<span class='line'> 27</span> * &lt;p>Options object has the following properties:&lt;/p>
+<span class='line'> 28</span> *
+<span class='line'> 29</span> * &lt;ul>
+<span class='line'> 30</span> * &lt;li>&lt;b>debug&lt;/b> - if set to true print traffic to console&lt;/li>
+<span class='line'> 31</span> * &lt;li>&lt;b>timeout&lt;/b> - timeout in milliseconds for disconnecting the client,
+<span class='line'> 32</span> * defaults to 0 (no timeout)&lt;/li>
+<span class='line'> 33</span> * &lt;/ul>
+<span class='line'> 34</span> *
+<span class='line'> 35</span> * &lt;p>&lt;b>Events&lt;/b>&lt;/p>
+<span class='line'> 36</span> *
+<span class='line'> 37</span> * &lt;ul>
+<span class='line'> 38</span> * &lt;li>&lt;b>'connect'&lt;/b> - emitted if a client connects to the server, param
+<span class='line'> 39</span> * is a client ({@link RAISocket}) object&lt;/li>
+<span class='line'> 40</span> * &lt;/ul>
+<span class='line'> 41</span> *
+<span class='line'> 42</span> * @constructor
+<span class='line'> 43</span> * @param {Object} [options] Optional options object
+<span class='line'> 44</span> */</span><span class="WHIT">
+<span class='line'> 45</span> </span><span class="KEYW">function</span><span class="WHIT"> </span><span class="NAME">RAIServer</span><span class="PUNC">(</span><span class="NAME">options</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 46</span> </span><span class="WHIT"> </span><span class="NAME">EventEmitter.call</span><span class="PUNC">(</span><span class="KEYW">this</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 47</span> </span><span class="WHIT">
+<span class='line'> 48</span> </span><span class="NAME">this.options</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">options</span><span class="TOKN"> </span><span class="PUNC">||</span><span class="TOKN"> </span><span class="PUNC">{</span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 49</span> </span><span class="WHIT">
+<span class='line'> 50</span> </span><span class="NAME">this._createServer</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 51</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 52</span> </span><span class="NAME">utillib.inherits</span><span class="PUNC">(</span><span class="NAME">RAIServer</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">EventEmitter</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 53</span>
+<span class='line'> 54</span> </span><span class="COMM">/**
+<span class='line'> 55</span> * &lt;p>Starts listening on selected port&lt;/p>
+<span class='line'> 56</span> *
+<span class='line'> 57</span> * @param {Number} port The port to listen
+<span class='line'> 58</span> * @param {String} [host] The IP address to listen
+<span class='line'> 59</span> * @param {Function} callback The callback function to be run after the server
+<span class='line'> 60</span> * is listening, the only param is an error message if the operation failed
+<span class='line'> 61</span> */</span><span class="WHIT">
+<span class='line'> 62</span> </span><span class="NAME">RAIServer.prototype.listen</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">port</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">host</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">callback</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 63</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="PUNC">!</span><span class="NAME">callback</span><span class="WHIT"> </span><span class="PUNC">&&</span><span class="WHIT"> </span><span class="KEYW">typeof</span><span class="WHIT"> </span><span class="NAME">host</span><span class="PUNC">==</span><span class="STRN">"function"</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 64</span> </span><span class="WHIT"> </span><span class="NAME">callback</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">host</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 65</span> </span><span class="WHIT"> </span><span class="NAME">host</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">undefined</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 66</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 67</span> </span><span class="WHIT"> </span><span class="NAME">this._port</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">port</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 68</span> </span><span class="WHIT"> </span><span class="NAME">this._host</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">host</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 69</span> </span><span class="WHIT">
+<span class='line'> 70</span> </span><span class="NAME">this._server.listen</span><span class="PUNC">(</span><span class="NAME">port</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">host</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">err</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 71</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">err</span><span class="WHIT"> </span><span class="PUNC">&&</span><span class="WHIT"> </span><span class="PUNC">!</span><span class="NAME">callback</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 72</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"error"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">err</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 73</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="KEYW">else</span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">callback</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 74</span> </span><span class="WHIT"> </span><span class="NAME">callback</span><span class="PUNC">(</span><span class="NAME">err</span><span class="WHIT"> </span><span class="PUNC">||</span><span class="WHIT"> </span><span class="KEYW">null</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 75</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 76</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 77</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 78</span>
+<span class='line'> 79</span> </span><span class="COMM">/**
+<span class='line'> 80</span> * &lt;p>Creates a server with listener callback&lt;/p>
+<span class='line'> 81</span> */</span><span class="WHIT">
+<span class='line'> 82</span> </span><span class="NAME">RAIServer.prototype._createServer</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 83</span> </span><span class="WHIT"> </span><span class="NAME">this._server</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">netlib.createServer</span><span class="PUNC">(</span><span class="NAME">this._serverListener.bind</span><span class="PUNC">(</span><span class="KEYW">this</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 84</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 85</span>
+<span class='line'> 86</span> </span><span class="COMM">/**
+<span class='line'> 87</span> * &lt;p>Server listener that is run on client connection&lt;/p>
+<span class='line'> 88</span> *
+<span class='line'> 89</span> * &lt;p>{@link RAISocket} object instance is created based on the client socket
+<span class='line'> 90</span> * and a &lt;code>'connection'&lt;/code> event is emitted&lt;/p>
+<span class='line'> 91</span> *
+<span class='line'> 92</span> * @param {Object} socket The socket to the client
+<span class='line'> 93</span> */</span><span class="WHIT">
+<span class='line'> 94</span> </span><span class="NAME">RAIServer.prototype._serverListener</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">socket</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 95</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.options.debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 96</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"CONNECTION FROM "</span><span class="PUNC">+</span><span class="NAME">socket.remoteAddress</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 97</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 98</span> </span><span class="WHIT">
+<span class='line'> 99</span> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">handler</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">RAISocket</span><span class="PUNC">(</span><span class="NAME">socket</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">this.options</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>100</span> </span><span class="WHIT">
+<span class='line'>101</span> </span><span class="NAME">socket.on</span><span class="PUNC">(</span><span class="STRN">"data"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">handler._onReceiveData.bind</span><span class="PUNC">(</span><span class="NAME">handler</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>102</span> </span><span class="WHIT"> </span><span class="NAME">socket.on</span><span class="PUNC">(</span><span class="STRN">"end"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">handler._onEnd.bind</span><span class="PUNC">(</span><span class="NAME">handler</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>103</span> </span><span class="WHIT"> </span><span class="NAME">socket.on</span><span class="PUNC">(</span><span class="STRN">"error"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">handler._onError.bind</span><span class="PUNC">(</span><span class="NAME">handler</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>104</span> </span><span class="WHIT"> </span><span class="NAME">socket.on</span><span class="PUNC">(</span><span class="STRN">"timeout"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">handler._onTimeout.bind</span><span class="PUNC">(</span><span class="NAME">handler</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>105</span> </span><span class="WHIT"> </span><span class="NAME">socket.on</span><span class="PUNC">(</span><span class="STRN">"close"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">handler._onClose.bind</span><span class="PUNC">(</span><span class="NAME">handler</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>106</span>
+<span class='line'>107</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"connection"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">handler</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>108</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>109</span>
+<span class='line'>110</span> </span><span class="COMM">/**
+<span class='line'>111</span> * &lt;p>Creates a instance for interacting with a client (socket)&lt;/p>
+<span class='line'>112</span> *
+<span class='line'>113</span> * &lt;p>Optional options object is the same that is passed to the parent
+<span class='line'>114</span> * {@link RAIServer} object&lt;/p>
+<span class='line'>115</span> *
+<span class='line'>116</span> * &lt;p>&lt;b>Events&lt;/b>&lt;/p>
+<span class='line'>117</span> *
+<span class='line'>118</span> * &lt;ul>
+<span class='line'>119</span> * &lt;li>&lt;b>'command'&lt;/b> - emitted if a client sends a command. Gets two
+<span class='line'>120</span> * params - command (String) and payload (Buffer)&lt;/li>
+<span class='line'>121</span> * &lt;li>&lt;b>'data'&lt;/b> - emitted when a chunk is received in data mode, the
+<span class='line'>122</span> * param being the payload (Buffer)&lt;/li>
+<span class='line'>123</span> * &lt;li>&lt;b>'ready'&lt;/b> - emitted when data stream ends and normal command
+<span class='line'>124</span> * flow is recovered&lt;/li>
+<span class='line'>125</span> * &lt;li>&lt;b>'tls'&lt;/b> - emitted when the connection is secured by TLS&lt;/li>
+<span class='line'>126</span> * &lt;li>&lt;b>'error'&lt;/b> - emitted when an error occurs. Connection to the
+<span class='line'>127</span> * client is disconnected automatically. Param is an error object.&lt;/l>
+<span class='line'>128</span> * &lt;li>&lt;b>'timeout'&lt;/b> - emitted when a timeout occurs. Connection to the
+<span class='line'>129</span> * client is disconnected automatically.&lt;/l>
+<span class='line'>130</span> * &lt;li>&lt;b>'end'&lt;/b> - emitted when the client disconnects&lt;/l>
+<span class='line'>131</span> * &lt;/ul>
+<span class='line'>132</span> *
+<span class='line'>133</span> * @constructor
+<span class='line'>134</span> * @param {Object} socket Socket for the client
+<span class='line'>135</span> * @param {Object} [options] Optional options object
+<span class='line'>136</span> */</span><span class="WHIT">
+<span class='line'>137</span> </span><span class="KEYW">function</span><span class="WHIT"> </span><span class="NAME">RAISocket</span><span class="PUNC">(</span><span class="NAME">socket</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">options</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>138</span> </span><span class="WHIT"> </span><span class="NAME">EventEmitter.call</span><span class="PUNC">(</span><span class="KEYW">this</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>139</span> </span><span class="WHIT">
+<span class='line'>140</span> </span><span class="NAME">this.socket</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">socket</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>141</span> </span><span class="WHIT"> </span><span class="NAME">this.options</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">options</span><span class="WHIT"> </span><span class="PUNC">||</span><span class="TOKN"> </span><span class="PUNC">{</span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>142</span> </span><span class="WHIT">
+<span class='line'>143</span> </span><span class="NAME">this.remoteAddress</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">socket.remoteAddress</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>144</span> </span><span class="WHIT">
+<span class='line'>145</span> </span><span class="NAME">this._dataMode</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>146</span> </span><span class="WHIT"> </span><span class="NAME">this._endDataModeSequence</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="REGX">/\r\n\.\r\n|^\.\r\n/</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>147</span> </span><span class="WHIT">
+<span class='line'>148</span> </span><span class="NAME">this._secureConnection</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>149</span> </span><span class="WHIT"> </span><span class="NAME">this._destroyed</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>150</span> </span><span class="WHIT"> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="STRN">""</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>151</span> </span><span class="WHIT">
+<span class='line'>152</span> </span><span class="NAME">this._ignore_data</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>153</span> </span><span class="WHIT">
+<span class='line'>154</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.options.timeout</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>155</span> </span><span class="WHIT"> </span><span class="NAME">socket.setTimeout</span><span class="PUNC">(</span><span class="NAME">this.options.timeout</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>156</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>157</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>158</span> </span><span class="NAME">utillib.inherits</span><span class="PUNC">(</span><span class="NAME">RAISocket</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">EventEmitter</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>159</span>
+<span class='line'>160</span> </span><span class="COMM">/**
+<span class='line'>161</span> * &lt;p>Sends some data to the client. &lt;CR>&lt;LF> is automatically appended to
+<span class='line'>162</span> * the data&lt;/p>
+<span class='line'>163</span> *
+<span class='line'>164</span> * @param {String|Buffer} data Data to be sent to the client
+<span class='line'>165</span> */</span><span class="WHIT">
+<span class='line'>166</span> </span><span class="NAME">RAISocket.prototype.send</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">data</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>167</span> </span><span class="WHIT"> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">buffer</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>168</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">data</span><span class="WHIT"> </span><span class="KEYW">instanceof</span><span class="WHIT"> </span><span class="NAME">Buffer</span><span class="WHIT"> </span><span class="PUNC">||</span><span class="TOKN"> </span><span class="PUNC">(</span><span class="KEYW">typeof</span><span class="WHIT"> </span><span class="NAME">SlowBuffer</span><span class="WHIT"> </span><span class="PUNC">!=</span><span class="WHIT"> </span><span class="STRN">"undefined"</span><span class="WHIT"> </span><span class="PUNC">&&</span><span class="WHIT"> </span><span class="NAME">data</span><span class="WHIT"> </span><span class="KEYW">instanceof</span><span class="WHIT"> </span><span class="NAME">SlowBuffer</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>169</span> </span><span class="WHIT"> </span><span class="NAME">buffer</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">Buffer</span><span class="PUNC">(</span><span class="NAME">data.length</span><span class="PUNC">+</span><span class="NUMB">2</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>170</span> </span><span class="WHIT"> </span><span class="NAME">buffer</span><span class="PUNC">[</span><span class="NAME">buffer.length</span><span class="PUNC">-</span><span class="NUMB">2</span><span class="PUNC">]</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NUMB">0xD</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>171</span> </span><span class="WHIT"> </span><span class="NAME">buffer</span><span class="PUNC">[</span><span class="NAME">buffer.length</span><span class="PUNC">-</span><span class="NUMB">1</span><span class="PUNC">]</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NUMB">0xA</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>172</span> </span><span class="WHIT"> </span><span class="NAME">data.copy</span><span class="PUNC">(</span><span class="NAME">buffer</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>173</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="KEYW">else</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>174</span> </span><span class="WHIT"> </span><span class="NAME">buffer</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">Buffer</span><span class="PUNC">(</span><span class="PUNC">(</span><span class="NAME">data</span><span class="WHIT"> </span><span class="PUNC">||</span><span class="TOKN"> </span><span class="STRN">""</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">toString</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">+</span><span class="STRN">"\r\n"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="STRN">"binary"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>175</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>176</span> </span><span class="WHIT">
+<span class='line'>177</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.options.debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>178</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"OUT: \""</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="NAME">buffer.toString</span><span class="PUNC">(</span><span class="STRN">"utf-8"</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">trim</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">+</span><span class="STRN">"\""</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>179</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>180</span> </span><span class="WHIT">
+<span class='line'>181</span> </span><span class="NAME">this.socket.write</span><span class="PUNC">(</span><span class="NAME">buffer</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>182</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>183</span>
+<span class='line'>184</span> </span><span class="COMM">/**
+<span class='line'>185</span> * &lt;p>Instructs the server to be listening for mixed data instead of line based
+<span class='line'>186</span> * commands&lt;/p>
+<span class='line'>187</span> *
+<span class='line'>188</span> * @param {String|RegExp} [sequence="\r\n.\r\n"] - optional sequence for
+<span class='line'>189</span> * matching the data end
+<span class='line'>190</span> */</span><span class="WHIT">
+<span class='line'>191</span> </span><span class="NAME">RAISocket.prototype.startDataMode</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">sequence</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>192</span> </span><span class="WHIT"> </span><span class="NAME">this._dataMode</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">true</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>193</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">sequence</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>194</span> </span><span class="WHIT"> </span><span class="NAME">this._endDataModeSequence</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">typeof</span><span class="WHIT"> </span><span class="NAME">sequence</span><span class="WHIT"> </span><span class="PUNC">==</span><span class="WHIT"> </span><span class="STRN">"string"</span><span class="WHIT"> </span><span class="PUNC">?</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">RegExp</span><span class="PUNC">(</span><span class="NAME">sequence</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NAME">sequence</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>195</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>196</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>197</span>
+<span class='line'>198</span> </span><span class="COMM">/**
+<span class='line'>199</span> * &lt;p>Instructs the server to upgrade the connection to secure TLS connection&lt;/p>
+<span class='line'>200</span> *
+<span class='line'>201</span> * &lt;p>Emits &lt;code>'tls'&lt;/code> on successful upgrade&lt;/p>
+<span class='line'>202</span> *
+<span class='line'>203</span> * @param {Object} [credentials] - An object with PEM encoded key and
+<span class='line'>204</span> * certificate &lt;code>{key:"---BEGIN...", cert:"---BEGIN..."}&lt;/code>,
+<span class='line'>205</span> * if not set autogenerated values will be used.
+<span class='line'>206</span> */</span><span class="WHIT">
+<span class='line'>207</span> </span><span class="NAME">RAISocket.prototype.startTLS</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">credentials</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>208</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this._secureConnection</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>209</span> </span><span class="WHIT"> </span><span class="NAME">this._onError</span><span class="PUNC">(</span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">Error</span><span class="PUNC">(</span><span class="STRN">"Secure connection already established"</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>210</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>211</span> </span><span class="WHIT">
+<span class='line'>212</span> </span><span class="NAME">credentials</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">credentials</span><span class="WHIT"> </span><span class="PUNC">||</span><span class="WHIT"> </span><span class="NAME">defaultCredentials</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>213</span> </span><span class="WHIT">
+<span class='line'>214</span> </span><span class="NAME">this._ignore_data</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">true</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>215</span> </span><span class="WHIT">
+<span class='line'>216</span> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">secure_connector</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">starttls</span><span class="PUNC">(</span><span class="NAME">this.socket</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">credentials</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">ssl_socket</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>217</span>
+<span class='line'>218</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.options.debug</span><span class="WHIT"> </span><span class="PUNC">&&</span><span class="WHIT"> </span><span class="PUNC">!</span><span class="NAME">ssl_socket.authorized</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>219</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"WARNING: TLS ERROR ("</span><span class="PUNC">+</span><span class="NAME">ssl_socket.authorizationError</span><span class="PUNC">+</span><span class="STRN">")"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>220</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>221</span> </span><span class="WHIT">
+<span class='line'>222</span> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="STRN">""</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>223</span> </span><span class="WHIT"> </span><span class="NAME">this._ignore_data</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>224</span> </span><span class="WHIT">
+<span class='line'>225</span> </span><span class="NAME">this._secureConnection</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">true</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>226</span> </span><span class="WHIT">
+<span class='line'>227</span> </span><span class="NAME">this.socket</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">ssl_socket</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>228</span> </span><span class="WHIT"> </span><span class="NAME">this.socket.on</span><span class="PUNC">(</span><span class="STRN">"data"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">this._onReceiveData.bind</span><span class="PUNC">(</span><span class="KEYW">this</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>229</span> </span><span class="WHIT">
+<span class='line'>230</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.options.debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>231</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"TLS CONNECTION STARTED"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>232</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>233</span> </span><span class="WHIT">
+<span class='line'>234</span> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"tls"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>235</span> </span><span class="WHIT">
+<span class='line'>236</span> </span><span class="PUNC">}</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">bind</span><span class="PUNC">(</span><span class="KEYW">this</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>237</span> </span><span class="WHIT">
+<span class='line'>238</span> </span><span class="NAME">secure_connector.on</span><span class="PUNC">(</span><span class="STRN">"error"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">err</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>239</span> </span><span class="WHIT"> </span><span class="NAME">this._onError</span><span class="PUNC">(</span><span class="NAME">err</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>240</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">bind</span><span class="PUNC">(</span><span class="KEYW">this</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>241</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>242</span>
+<span class='line'>243</span> </span><span class="COMM">/**
+<span class='line'>244</span> * &lt;p>Closes the connection to the client&lt;/p>
+<span class='line'>245</span> */</span><span class="WHIT">
+<span class='line'>246</span> </span><span class="NAME">RAISocket.prototype.end</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>247</span> </span><span class="WHIT"> </span><span class="NAME">this.socket.end</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>248</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>249</span>
+<span class='line'>250</span> </span><span class="COMM">/**
+<span class='line'>251</span> * &lt;p>Called when a chunk of data arrives from the client. If currently in data
+<span class='line'>252</span> * mode, transmit the data otherwise send it to &lt;code>_processData&lt;/code>&lt;/p>
+<span class='line'>253</span> *
+<span class='line'>254</span> * @param {Buffer|String} chunk Data sent by the client
+<span class='line'>255</span> */</span><span class="WHIT">
+<span class='line'>256</span> </span><span class="NAME">RAISocket.prototype._onReceiveData</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">chunk</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>257</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this._ignore_data</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT"> </span><span class="COMM">// if currently setting up TLS connection</span><span class="WHIT">
+<span class='line'>258</span> </span><span class="WHIT"> </span><span class="KEYW">return</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>259</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>260</span> </span><span class="WHIT">
+<span class='line'>261</span> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">str</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">typeof</span><span class="WHIT"> </span><span class="NAME">chunk</span><span class="PUNC">==</span><span class="STRN">"string"</span><span class="PUNC">?</span><span class="NAME">chunk</span><span class="PUNC">:</span><span class="NAME">chunk.toString</span><span class="PUNC">(</span><span class="STRN">"binary"</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'>262</span> </span><span class="WHIT"> </span><span class="NAME">dataEndMatch</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">dataRemainderMatch</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">data</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>263</span> </span><span class="WHIT">
+<span class='line'>264</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this._dataMode</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>265</span> </span><span class="WHIT">
+<span class='line'>266</span> </span><span class="NAME">str</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="WHIT"> </span><span class="NAME">str</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>267</span> </span><span class="WHIT">
+<span class='line'>268</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">dataEndMatch</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">str.match</span><span class="PUNC">(</span><span class="REGX">/\r\n.*?$/</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>269</span> </span><span class="WHIT"> </span><span class="COMM">// if theres a line that is not ended, keep it for later</span><span class="WHIT">
+<span class='line'>270</span> </span><span class="WHIT"> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">str.substr</span><span class="PUNC">(</span><span class="NAME">dataEndMatch.index</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>271</span> </span><span class="WHIT"> </span><span class="NAME">str</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">str.substr</span><span class="PUNC">(</span><span class="NUMB">0</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">dataEndMatch.index</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>272</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="KEYW">else</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>273</span> </span><span class="WHIT"> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="STRN">""</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>274</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>275</span> </span><span class="WHIT">
+<span class='line'>276</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="PUNC">(</span><span class="NAME">dataRemainderMatch</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">str</span><span class="PUNC">+</span><span class="NAME">this._remainder</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">match</span><span class="PUNC">(</span><span class="NAME">this._endDataModeSequence</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>277</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">dataRemainderMatch.index</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>278</span> </span><span class="WHIT"> </span><span class="NAME">data</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">Buffer</span><span class="PUNC">(</span><span class="PUNC">(</span><span class="NAME">str</span><span class="PUNC">+</span><span class="NAME">this._remainder</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">substr</span><span class="PUNC">(</span><span class="NUMB">0</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">dataRemainderMatch.index</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="STRN">"binary"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>279</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.options.debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>280</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"DATA:"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">data.toString</span><span class="PUNC">(</span><span class="STRN">"utf-8"</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>281</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>282</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"data"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">data</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>283</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>284</span> </span><span class="WHIT"> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="STRN">""</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>285</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"ready"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>286</span> </span><span class="WHIT"> </span><span class="NAME">this._dataMode</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>287</span> </span><span class="WHIT">
+<span class='line'>288</span> </span><span class="COMM">// send the remaining data for processing</span><span class="WHIT">
+<span class='line'>289</span> </span><span class="WHIT"> </span><span class="NAME">this._processData</span><span class="PUNC">(</span><span class="NAME">str.substr</span><span class="PUNC">(</span><span class="NAME">dataRemainderMatch.index</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="WHIT"> </span><span class="NAME">dataRemainderMatch</span><span class="PUNC">[</span><span class="NUMB">0</span><span class="PUNC">]</span><span class="PUNC">.</span><span class="NAME">length</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>290</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="KEYW">else</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>291</span> </span><span class="WHIT"> </span><span class="NAME">data</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">Buffer</span><span class="PUNC">(</span><span class="NAME">str</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="STRN">"binary"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>292</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.options.debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>293</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"DATA:"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">data.toString</span><span class="PUNC">(</span><span class="STRN">"utf-8"</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>294</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>295</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"data"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">data</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>296</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>297</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="KEYW">else</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>298</span> </span><span class="WHIT"> </span><span class="NAME">this._processData</span><span class="PUNC">(</span><span class="NAME">str</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>299</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>300</span> </span><span class="WHIT">
+<span class='line'>301</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>302</span>
+<span class='line'>303</span> </span><span class="COMM">/**
+<span class='line'>304</span> * &lt;p>Processed incoming command lines and emits found data as
+<span class='line'>305</span> * &lt;code>'command'&lt;/code> with the command name as the first param and the rest
+<span class='line'>306</span> * of the data as second (Buffer)&lt;/p>
+<span class='line'>307</span> *
+<span class='line'>308</span> * @param {String} str Binary string to be processed
+<span class='line'>309</span> */</span><span class="WHIT">
+<span class='line'>310</span> </span><span class="NAME">RAISocket.prototype._processData</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">str</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>311</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="PUNC">!</span><span class="NAME">str.length</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>312</span> </span><span class="WHIT"> </span><span class="KEYW">return</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>313</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>314</span> </span><span class="WHIT"> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">lines</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">this._remainder</span><span class="PUNC">+</span><span class="NAME">str</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">split</span><span class="PUNC">(</span><span class="STRN">"\r\n"</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'>315</span> </span><span class="WHIT"> </span><span class="NAME">match</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">command</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>316</span> </span><span class="WHIT">
+<span class='line'>317</span> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">lines.pop</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>318</span> </span><span class="WHIT">
+<span class='line'>319</span> </span><span class="KEYW">for</span><span class="PUNC">(</span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">i</span><span class="PUNC">=</span><span class="NUMB">0</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">len</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">lines.length</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="NAME">i</span><span class="PUNC">&lt;</span><span class="NAME">len</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="NAME">i</span><span class="PUNC">++</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>320</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="PUNC">!</span><span class="NAME">this._dataMode</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>321</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">match</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">lines</span><span class="PUNC">[</span><span class="NAME">i</span><span class="PUNC">]</span><span class="PUNC">.</span><span class="NAME">match</span><span class="PUNC">(</span><span class="REGX">/\s*[\S]+\s?/</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>322</span> </span><span class="WHIT"> </span><span class="NAME">command</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">match</span><span class="PUNC">[</span><span class="NUMB">0</span><span class="PUNC">]</span><span class="WHIT"> </span><span class="PUNC">||</span><span class="WHIT"> </span><span class="STRN">""</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">trim</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>323</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.options.debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>324</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"COMMAND:"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">lines</span><span class="PUNC">[</span><span class="NAME">i</span><span class="PUNC">]</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>325</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>326</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"command"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">command</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">Buffer</span><span class="PUNC">(</span><span class="NAME">lines</span><span class="PUNC">[</span><span class="NAME">i</span><span class="PUNC">]</span><span class="PUNC">.</span><span class="NAME">substr</span><span class="PUNC">(</span><span class="NAME">match.index</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="WHIT"> </span><span class="NAME">match</span><span class="PUNC">[</span><span class="NUMB">0</span><span class="PUNC">]</span><span class="PUNC">.</span><span class="NAME">length</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="STRN">"binary"</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>327</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>328</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="KEYW">else</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>329</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this._remainder</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>330</span> </span><span class="WHIT"> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="PUNC">=</span><span class="WHIT"> </span><span class="STRN">"\r\n"</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>331</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>332</span> </span><span class="WHIT"> </span><span class="NAME">this._onReceiveData</span><span class="PUNC">(</span><span class="NAME">lines.slice</span><span class="PUNC">(</span><span class="NAME">i</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">join</span><span class="PUNC">(</span><span class="STRN">"\r\n"</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>333</span> </span><span class="WHIT"> </span><span class="KEYW">break</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>334</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>335</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>336</span> </span><span class="WHIT">
+<span class='line'>337</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>338</span>
+<span class='line'>339</span> </span><span class="COMM">/**
+<span class='line'>340</span> * &lt;p>Called when the connection is or is going to be ended&lt;/p>
+<span class='line'>341</span> */</span><span class="WHIT">
+<span class='line'>342</span> </span><span class="NAME">RAISocket.prototype._destroy</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>343</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this._destroyed</span><span class="PUNC">)</span><span class="KEYW">return</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>344</span> </span><span class="WHIT"> </span><span class="NAME">this._destroyed</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">true</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>345</span> </span><span class="WHIT">
+<span class='line'>346</span> </span><span class="NAME">this.removeAllListeners</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>347</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>348</span>
+<span class='line'>349</span> </span><span class="COMM">/**
+<span class='line'>350</span> * &lt;p>Called when the connection is ended. Emits &lt;code>'end'&lt;/code>&lt;/p>
+<span class='line'>351</span> */</span><span class="WHIT">
+<span class='line'>352</span> </span><span class="NAME">RAISocket.prototype._onEnd</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>353</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"end"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>354</span> </span><span class="WHIT"> </span><span class="NAME">this._destroy</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>355</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>356</span>
+<span class='line'>357</span> </span><span class="COMM">/**
+<span class='line'>358</span> * &lt;p>Called when an error has appeared. Emits &lt;code>'error'&lt;/code> with
+<span class='line'>359</span> * the error object as a parameter.&lt;/p>
+<span class='line'>360</span> *
+<span class='line'>361</span> * @param {Object} err Error object
+<span class='line'>362</span> */</span><span class="WHIT">
+<span class='line'>363</span> </span><span class="NAME">RAISocket.prototype._onError</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">err</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>364</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"error"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">err</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>365</span> </span><span class="WHIT"> </span><span class="NAME">this._destroy</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>366</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>367</span>
+<span class='line'>368</span> </span><span class="COMM">/**
+<span class='line'>369</span> * &lt;p>Called when a timeout has occured. Connection will be closed and
+<span class='line'>370</span> * &lt;code>'timeout'&lt;/code> is emitted.&lt;/p>
+<span class='line'>371</span> */</span><span class="WHIT">
+<span class='line'>372</span> </span><span class="NAME">RAISocket.prototype._onTimeout</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>373</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.socket</span><span class="WHIT"> </span><span class="PUNC">&&</span><span class="WHIT"> </span><span class="PUNC">!</span><span class="NAME">this.socket.destroyed</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>374</span> </span><span class="WHIT"> </span><span class="NAME">this.socket.end</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>375</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>376</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"timeout"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>377</span> </span><span class="WHIT"> </span><span class="NAME">this._destroy</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>378</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>379</span>
+<span class='line'>380</span> </span><span class="COMM">/**
+<span class='line'>381</span> * &lt;p>Called when the connection is closed&lt;/p>
+<span class='line'>382</span> *
+<span class='line'>383</span> * @param {Boolean} hadError did the connection end because of an error?
+<span class='line'>384</span> */</span><span class="WHIT">
+<span class='line'>385</span> </span><span class="NAME">RAISocket.prototype._onClose</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">hadError</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>386</span> </span><span class="WHIT"> </span><span class="NAME">this._destroy</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>387</span> </span><span class="PUNC">}</span></pre></body></html> \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_mockup.js.html b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_mockup.js.html
new file mode 100644
index 0000000..2690ce4
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_mockup.js.html
@@ -0,0 +1,110 @@
+<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"> <style>
+ .KEYW {color: #933;}
+ .COMM {color: #bbb; font-style: italic;}
+ .NUMB {color: #393;}
+ .STRN {color: #393;}
+ .REGX {color: #339;}
+ .line {border-right: 1px dotted #666; color: #666; font-style: normal;}
+ </style></head><body><pre><span class='line'> 1</span> <span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">net</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">"net"</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'> 2</span> </span><span class="WHIT"> </span><span class="NAME">crypto</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">"crypto"</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'> 3</span> </span><span class="WHIT"> </span><span class="NAME">tlslib</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">"tls"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 4</span>
+<span class='line'> 5</span> </span><span class="COMM">/**
+<span class='line'> 6</span> * @namespace Mockup module
+<span class='line'> 7</span> * @name mockup
+<span class='line'> 8</span> */</span><span class="WHIT">
+<span class='line'> 9</span> </span><span class="NAME">module.exports</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">runClientMockup</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 10</span>
+<span class='line'> 11</span> </span><span class="COMM">/**
+<span class='line'> 12</span> * &lt;p>Runs a batch of commands against a server&lt;/p>
+<span class='line'> 13</span> *
+<span class='line'> 14</span> * &lt;pre>
+<span class='line'> 15</span> * var cmds = ["EHLO FOOBAR", "STARTTLS", "QUIT"];
+<span class='line'> 16</span> * runClientMockup(25, "mail.hot.ee", cmds, function(resp){
+<span class='line'> 17</span> * console.log("Final:", resp.toString("utf-8").trim());
+<span class='line'> 18</span> * });
+<span class='line'> 19</span> * &lt;/pre>
+<span class='line'> 20</span> *
+<span class='line'> 21</span> * @memberOf mockup
+<span class='line'> 22</span> * @param {Number} port Port number
+<span class='line'> 23</span> * @param {String} host Hostname to connect to
+<span class='line'> 24</span> * @param {Array} commands Command list to be sent to server
+<span class='line'> 25</span> * @param {Function} callback Callback function to run on completion,
+<span class='line'> 26</span> * has the last response from the server as a param
+<span class='line'> 27</span> * @param {Boolean} [debug] if set to true log all input/output
+<span class='line'> 28</span> */</span><span class="WHIT">
+<span class='line'> 29</span> </span><span class="KEYW">function</span><span class="WHIT"> </span><span class="NAME">runClientMockup</span><span class="PUNC">(</span><span class="NAME">port</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">host</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">commands</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">callback</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 30</span> </span><span class="WHIT"> </span><span class="NAME">host</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">host</span><span class="WHIT"> </span><span class="PUNC">||</span><span class="TOKN"> </span><span class="STRN">"localhost"</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 31</span> </span><span class="WHIT"> </span><span class="NAME">port</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">port</span><span class="WHIT"> </span><span class="PUNC">||</span><span class="TOKN"> </span><span class="NUMB">25</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 32</span> </span><span class="WHIT"> </span><span class="NAME">commands</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">Array.isArray</span><span class="PUNC">(</span><span class="NAME">commands</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">?</span><span class="WHIT"> </span><span class="NAME">commands</span><span class="WHIT"> </span><span class="PUNC">:</span><span class="WHIT"> </span><span class="PUNC">[</span><span class="PUNC">]</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 33</span>
+<span class='line'> 34</span> </span><span class="WHIT"> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">command</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">ignore_data</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">sslcontext</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">pair</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 35</span>
+<span class='line'> 36</span> </span><span class="WHIT"> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">socket</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">net.connect</span><span class="PUNC">(</span><span class="NAME">port</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">host</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 37</span> </span><span class="WHIT"> </span><span class="NAME">socket.on</span><span class="PUNC">(</span><span class="STRN">"data"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">chunk</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 38</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">ignore_data</span><span class="PUNC">)</span><span class="KEYW">return</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 39</span> </span><span class="WHIT">
+<span class='line'> 40</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 41</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"S: "</span><span class="PUNC">+</span><span class="NAME">chunk.toString</span><span class="PUNC">(</span><span class="STRN">"utf-8"</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">trim</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 42</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 43</span> </span><span class="WHIT">
+<span class='line'> 44</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="PUNC">!</span><span class="NAME">commands.length</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 45</span> </span><span class="WHIT"> </span><span class="NAME">socket.end</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 46</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="KEYW">typeof</span><span class="WHIT"> </span><span class="NAME">callback</span><span class="WHIT"> </span><span class="PUNC">==</span><span class="WHIT"> </span><span class="STRN">"function"</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 47</span> </span><span class="WHIT"> </span><span class="NAME">callback</span><span class="PUNC">(</span><span class="NAME">chunk</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 48</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 49</span> </span><span class="WHIT"> </span><span class="KEYW">return</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 50</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 51</span> </span><span class="WHIT">
+<span class='line'> 52</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="PUNC">[</span><span class="STRN">"STARTTLS"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="STRN">"STLS"</span><span class="PUNC">]</span><span class="PUNC">.</span><span class="NAME">indexOf</span><span class="PUNC">(</span><span class="PUNC">(</span><span class="NAME">command</span><span class="WHIT"> </span><span class="PUNC">||</span><span class="WHIT"> </span><span class="STRN">""</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">trim</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">toUpperCase</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">>=</span><span class="NUMB">0</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 53</span> </span><span class="WHIT"> </span><span class="NAME">ignore_data</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">true</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 54</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 55</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"Initiated TLS connection"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 56</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 57</span> </span><span class="WHIT"> </span><span class="NAME">sslcontext</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">crypto.createCredentials</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 58</span> </span><span class="WHIT"> </span><span class="NAME">pair</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">tlslib.createSecurePair</span><span class="PUNC">(</span><span class="NAME">sslcontext</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 59</span> </span><span class="WHIT">
+<span class='line'> 60</span> </span><span class="NAME">pair.encrypted.pipe</span><span class="PUNC">(</span><span class="NAME">socket</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 61</span> </span><span class="WHIT"> </span><span class="NAME">socket.pipe</span><span class="PUNC">(</span><span class="NAME">pair.encrypted</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 62</span> </span><span class="WHIT"> </span><span class="NAME">pair.fd</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">socket.fd</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 63</span> </span><span class="WHIT">
+<span class='line'> 64</span> </span><span class="NAME">pair.on</span><span class="PUNC">(</span><span class="STRN">"secure"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 65</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 66</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"TLS connection secured"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 67</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 68</span> </span><span class="WHIT"> </span><span class="NAME">command</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">commands.shift</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 69</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 70</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"C: "</span><span class="PUNC">+</span><span class="NAME">command</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 71</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 72</span> </span><span class="WHIT"> </span><span class="NAME">pair.cleartext.write</span><span class="PUNC">(</span><span class="NAME">command</span><span class="PUNC">+</span><span class="STRN">"\r\n"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 73</span>
+<span class='line'> 74</span> </span><span class="WHIT"> </span><span class="NAME">pair.cleartext.on</span><span class="PUNC">(</span><span class="STRN">"data"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">chunk</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 75</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 76</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"S: "</span><span class="PUNC">+</span><span class="NAME">chunk.toString</span><span class="PUNC">(</span><span class="STRN">"utf-8"</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">trim</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 77</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 78</span> </span><span class="WHIT">
+<span class='line'> 79</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="PUNC">!</span><span class="NAME">commands.length</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 80</span> </span><span class="WHIT"> </span><span class="NAME">pair.cleartext.end</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 81</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="KEYW">typeof</span><span class="WHIT"> </span><span class="NAME">callback</span><span class="WHIT"> </span><span class="PUNC">==</span><span class="WHIT"> </span><span class="STRN">"function"</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 82</span> </span><span class="WHIT"> </span><span class="NAME">callback</span><span class="PUNC">(</span><span class="NAME">chunk</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 83</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 84</span> </span><span class="WHIT"> </span><span class="KEYW">return</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 85</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 86</span> </span><span class="WHIT"> </span><span class="NAME">command</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">commands.shift</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 87</span> </span><span class="WHIT"> </span><span class="NAME">pair.cleartext.write</span><span class="PUNC">(</span><span class="NAME">command</span><span class="PUNC">+</span><span class="STRN">"\r\n"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 88</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 89</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"C: "</span><span class="PUNC">+</span><span class="NAME">command</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 90</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 91</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 92</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 93</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="KEYW">else</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 94</span> </span><span class="WHIT"> </span><span class="NAME">command</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">commands.shift</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 95</span> </span><span class="WHIT"> </span><span class="NAME">socket.write</span><span class="PUNC">(</span><span class="NAME">command</span><span class="PUNC">+</span><span class="STRN">"\r\n"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 96</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 97</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"C: "</span><span class="PUNC">+</span><span class="NAME">command</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 98</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 99</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>100</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>101</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>102</span> </span><span class="WHIT">
+<span class='line'>103</span> </span><span class="PUNC">}</span></pre></body></html> \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_rai.js.html b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_rai.js.html
new file mode 100644
index 0000000..4e12b24
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_rai.js.html
@@ -0,0 +1,484 @@
+<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"> <style>
+ .KEYW {color: #933;}
+ .COMM {color: #bbb; font-style: italic;}
+ .NUMB {color: #393;}
+ .STRN {color: #393;}
+ .REGX {color: #339;}
+ .line {border-right: 1px dotted #666; color: #666; font-style: normal;}
+ </style></head><body><pre><span class='line'> 1</span> <span class="COMM">/**
+<span class='line'> 2</span> * @fileOverview This is the main file for the RAI library to create text based servers
+<span class='line'> 3</span> * @author &lt;a href="mailto:andris@node.ee">Andris Reinman&lt;/a>
+<span class='line'> 4</span> * @version 0.1.3
+<span class='line'> 5</span> */</span><span class="WHIT">
+<span class='line'> 6</span>
+<span class='line'> 7</span> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">netlib</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">"net"</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'> 8</span> </span><span class="WHIT"> </span><span class="NAME">utillib</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">"util"</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'> 9</span> </span><span class="WHIT"> </span><span class="NAME">EventEmitter</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">'events'</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">EventEmitter</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'> 10</span> </span><span class="WHIT"> </span><span class="NAME">starttls</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">"./starttls"</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">starttls</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'> 11</span> </span><span class="WHIT"> </span><span class="NAME">tlslib</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">"tls"</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'> 12</span> </span><span class="WHIT"> </span><span class="NAME">crypto</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">"crypto"</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'> 13</span> </span><span class="WHIT"> </span><span class="NAME">fs</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">"fs"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 14</span>
+<span class='line'> 15</span> </span><span class="COMM">// Default credentials for starting TLS server</span><span class="WHIT">
+<span class='line'> 16</span> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">defaultCredentials</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 17</span> </span><span class="WHIT"> </span><span class="NAME">key</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NAME">fs.readFileSync</span><span class="PUNC">(</span><span class="NAME">__dirname</span><span class="PUNC">+</span><span class="STRN">"/../cert/key.pem"</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'> 18</span> </span><span class="WHIT"> </span><span class="NAME">cert</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NAME">fs.readFileSync</span><span class="PUNC">(</span><span class="NAME">__dirname</span><span class="PUNC">+</span><span class="STRN">"/../cert/cert.pem"</span><span class="PUNC">)</span><span class="WHIT">
+<span class='line'> 19</span> </span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 20</span>
+<span class='line'> 21</span> </span><span class="COMM">// Expose to the world</span><span class="WHIT">
+<span class='line'> 22</span> </span><span class="NAME">module.exports.RAIServer</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">RAIServer</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 23</span> </span><span class="NAME">module.exports.runClientMockup</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">"./mockup"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 24</span>
+<span class='line'> 25</span> </span><span class="COMM">/**
+<span class='line'> 26</span> * &lt;p>Creates instance of RAIServer&lt;/p>
+<span class='line'> 27</span> *
+<span class='line'> 28</span> * &lt;p>Options object has the following properties:&lt;/p>
+<span class='line'> 29</span> *
+<span class='line'> 30</span> * &lt;ul>
+<span class='line'> 31</span> * &lt;li>&lt;b>debug&lt;/b> - if set to true print traffic to console&lt;/li>
+<span class='line'> 32</span> * &lt;li>&lt;b>disconnectOnTimeout&lt;/b> - if set to true close the connection on disconnect&lt;/li>
+<span class='line'> 33</span> * &lt;li>&lt;b>timeout&lt;/b> - timeout in milliseconds for disconnecting the client,
+<span class='line'> 34</span> * defaults to 0 (no timeout)&lt;/li>
+<span class='line'> 35</span> * &lt;/ul>
+<span class='line'> 36</span> *
+<span class='line'> 37</span> * &lt;p>&lt;b>Events&lt;/b>&lt;/p>
+<span class='line'> 38</span> *
+<span class='line'> 39</span> * &lt;ul>
+<span class='line'> 40</span> * &lt;li>&lt;b>'connect'&lt;/b> - emitted if a client connects to the server, param
+<span class='line'> 41</span> * is a client ({@link RAISocket}) object&lt;/li>
+<span class='line'> 42</span> * &lt;li>&lt;b>'error'&lt;/b> - emitted on error, has an error object as a param&lt;/li>
+<span class='line'> 43</span> * &lt;/ul>
+<span class='line'> 44</span> *
+<span class='line'> 45</span> * @constructor
+<span class='line'> 46</span> * @param {Object} [options] Optional options object
+<span class='line'> 47</span> */</span><span class="WHIT">
+<span class='line'> 48</span> </span><span class="KEYW">function</span><span class="WHIT"> </span><span class="NAME">RAIServer</span><span class="PUNC">(</span><span class="NAME">options</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 49</span> </span><span class="WHIT"> </span><span class="NAME">EventEmitter.call</span><span class="PUNC">(</span><span class="KEYW">this</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 50</span> </span><span class="WHIT">
+<span class='line'> 51</span> </span><span class="NAME">this.options</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">options</span><span class="WHIT"> </span><span class="PUNC">||</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 52</span> </span><span class="WHIT">
+<span class='line'> 53</span> </span><span class="NAME">this._createServer</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 54</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 55</span> </span><span class="NAME">utillib.inherits</span><span class="PUNC">(</span><span class="NAME">RAIServer</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">EventEmitter</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 56</span>
+<span class='line'> 57</span> </span><span class="COMM">/**
+<span class='line'> 58</span> * &lt;p>Starts listening on selected port&lt;/p>
+<span class='line'> 59</span> *
+<span class='line'> 60</span> * @param {Number} port The port to listen
+<span class='line'> 61</span> * @param {String} [host] The IP address to listen
+<span class='line'> 62</span> * @param {Function} callback The callback function to be run after the server
+<span class='line'> 63</span> * is listening, the only param is an error message if the operation failed
+<span class='line'> 64</span> */</span><span class="WHIT">
+<span class='line'> 65</span> </span><span class="NAME">RAIServer.prototype.listen</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">port</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">host</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">callback</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 66</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="PUNC">!</span><span class="NAME">callback</span><span class="WHIT"> </span><span class="PUNC">&&</span><span class="WHIT"> </span><span class="KEYW">typeof</span><span class="WHIT"> </span><span class="NAME">host</span><span class="PUNC">==</span><span class="STRN">"function"</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 67</span> </span><span class="WHIT"> </span><span class="NAME">callback</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">host</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 68</span> </span><span class="WHIT"> </span><span class="NAME">host</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">undefined</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 69</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 70</span> </span><span class="WHIT"> </span><span class="NAME">this._port</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">port</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 71</span> </span><span class="WHIT"> </span><span class="NAME">this._host</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">host</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 72</span> </span><span class="WHIT">
+<span class='line'> 73</span> </span><span class="NAME">this._connected</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 74</span> </span><span class="WHIT">
+<span class='line'> 75</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">callback</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 76</span> </span><span class="WHIT">
+<span class='line'> 77</span> </span><span class="NAME">this._server.on</span><span class="PUNC">(</span><span class="STRN">"listening"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="KEYW">function</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 78</span> </span><span class="WHIT"> </span><span class="NAME">this._connected</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">true</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 79</span> </span><span class="WHIT"> </span><span class="NAME">callback</span><span class="PUNC">(</span><span class="KEYW">null</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 80</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">bind</span><span class="PUNC">(</span><span class="KEYW">this</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 81</span> </span><span class="WHIT">
+<span class='line'> 82</span> </span><span class="NAME">this._server.on</span><span class="PUNC">(</span><span class="STRN">"error"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">err</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 83</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="PUNC">!</span><span class="NAME">this._connected</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 84</span> </span><span class="WHIT"> </span><span class="NAME">callback</span><span class="PUNC">(</span><span class="NAME">err</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 85</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 86</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">bind</span><span class="PUNC">(</span><span class="KEYW">this</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 87</span> </span><span class="WHIT">
+<span class='line'> 88</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 89</span> </span><span class="WHIT">
+<span class='line'> 90</span> </span><span class="NAME">this._server.listen</span><span class="PUNC">(</span><span class="NAME">this._port</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">this._host</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 91</span> </span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 92</span>
+<span class='line'> 93</span> </span><span class="COMM">/**
+<span class='line'> 94</span> * &lt;p>Stops the server&lt;/p>
+<span class='line'> 95</span> *
+<span class='line'> 96</span> * @param {Function} callback Is run when the server is closed
+<span class='line'> 97</span> */</span><span class="WHIT">
+<span class='line'> 98</span> </span><span class="NAME">RAIServer.prototype.end</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">callback</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 99</span> </span><span class="WHIT"> </span><span class="NAME">this._server.on</span><span class="PUNC">(</span><span class="STRN">"close"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">callback</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>100</span> </span><span class="WHIT"> </span><span class="NAME">this._server.close</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>101</span> </span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>102</span>
+<span class='line'>103</span> </span><span class="COMM">/**
+<span class='line'>104</span> * &lt;p>Creates a server with listener callback&lt;/p>
+<span class='line'>105</span> */</span><span class="WHIT">
+<span class='line'>106</span> </span><span class="NAME">RAIServer.prototype._createServer</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>107</span> </span><span class="WHIT"> </span><span class="NAME">this._server</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">netlib.createServer</span><span class="PUNC">(</span><span class="NAME">this._serverListener.bind</span><span class="PUNC">(</span><span class="KEYW">this</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>108</span> </span><span class="WHIT"> </span><span class="NAME">this._server.on</span><span class="PUNC">(</span><span class="STRN">"error"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">this._onError.bind</span><span class="PUNC">(</span><span class="KEYW">this</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>109</span> </span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>110</span>
+<span class='line'>111</span> </span><span class="COMM">/**
+<span class='line'>112</span> * &lt;p>Listens for errors&lt;/p>
+<span class='line'>113</span> *
+<span class='line'>114</span> * @event
+<span class='line'>115</span> * @param {Object} err Error object
+<span class='line'>116</span> */</span><span class="WHIT">
+<span class='line'>117</span> </span><span class="NAME">RAIServer.prototype._onError</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">err</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>118</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this._connected</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>119</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"error"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">err</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>120</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>121</span> </span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>122</span>
+<span class='line'>123</span> </span><span class="COMM">/**
+<span class='line'>124</span> * &lt;p>Server listener that is run on client connection&lt;/p>
+<span class='line'>125</span> *
+<span class='line'>126</span> * &lt;p>{@link RAISocket} object instance is created based on the client socket
+<span class='line'>127</span> * and a &lt;code>'connection'&lt;/code> event is emitted&lt;/p>
+<span class='line'>128</span> *
+<span class='line'>129</span> * @param {Object} socket The socket to the client
+<span class='line'>130</span> */</span><span class="WHIT">
+<span class='line'>131</span> </span><span class="NAME">RAIServer.prototype._serverListener</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">socket</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>132</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.options.debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>133</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"CONNECTION FROM "</span><span class="PUNC">+</span><span class="NAME">socket.remoteAddress</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>134</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>135</span> </span><span class="WHIT">
+<span class='line'>136</span> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">handler</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">RAISocket</span><span class="PUNC">(</span><span class="NAME">socket</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">this.options</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>137</span> </span><span class="WHIT">
+<span class='line'>138</span> </span><span class="NAME">socket.on</span><span class="PUNC">(</span><span class="STRN">"data"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">handler._onReceiveData.bind</span><span class="PUNC">(</span><span class="NAME">handler</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>139</span> </span><span class="WHIT"> </span><span class="NAME">socket.on</span><span class="PUNC">(</span><span class="STRN">"end"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">handler._onEnd.bind</span><span class="PUNC">(</span><span class="NAME">handler</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>140</span> </span><span class="WHIT"> </span><span class="NAME">socket.on</span><span class="PUNC">(</span><span class="STRN">"error"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">handler._onError.bind</span><span class="PUNC">(</span><span class="NAME">handler</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>141</span> </span><span class="WHIT"> </span><span class="NAME">socket.on</span><span class="PUNC">(</span><span class="STRN">"timeout"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">handler._onTimeout.bind</span><span class="PUNC">(</span><span class="NAME">handler</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>142</span> </span><span class="WHIT"> </span><span class="NAME">socket.on</span><span class="PUNC">(</span><span class="STRN">"close"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">handler._onClose.bind</span><span class="PUNC">(</span><span class="NAME">handler</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>143</span>
+<span class='line'>144</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"connection"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">handler</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>145</span> </span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>146</span>
+<span class='line'>147</span> </span><span class="COMM">/**
+<span class='line'>148</span> * &lt;p>Creates a instance for interacting with a client (socket)&lt;/p>
+<span class='line'>149</span> *
+<span class='line'>150</span> * &lt;p>Optional options object is the same that is passed to the parent
+<span class='line'>151</span> * {@link RAIServer} object&lt;/p>
+<span class='line'>152</span> *
+<span class='line'>153</span> * &lt;p>&lt;b>Events&lt;/b>&lt;/p>
+<span class='line'>154</span> *
+<span class='line'>155</span> * &lt;ul>
+<span class='line'>156</span> * &lt;li>&lt;b>'command'&lt;/b> - emitted if a client sends a command. Gets two
+<span class='line'>157</span> * params - command (String) and payload (Buffer)&lt;/li>
+<span class='line'>158</span> * &lt;li>&lt;b>'data'&lt;/b> - emitted when a chunk is received in data mode, the
+<span class='line'>159</span> * param being the payload (Buffer)&lt;/li>
+<span class='line'>160</span> * &lt;li>&lt;b>'ready'&lt;/b> - emitted when data stream ends and normal command
+<span class='line'>161</span> * flow is recovered&lt;/li>
+<span class='line'>162</span> * &lt;li>&lt;b>'tls'&lt;/b> - emitted when the connection is secured by TLS&lt;/li>
+<span class='line'>163</span> * &lt;li>&lt;b>'error'&lt;/b> - emitted when an error occurs. Connection to the
+<span class='line'>164</span> * client is disconnected automatically. Param is an error object.&lt;/l>
+<span class='line'>165</span> * &lt;li>&lt;b>'timeout'&lt;/b> - emitted when a timeout occurs. Connection to the
+<span class='line'>166</span> * client is disconnected automatically if disconnectOnTimeout option
+<span class='line'>167</span> * is set to true.&lt;/l>
+<span class='line'>168</span> * &lt;li>&lt;b>'end'&lt;/b> - emitted when the client disconnects&lt;/l>
+<span class='line'>169</span> * &lt;/ul>
+<span class='line'>170</span> *
+<span class='line'>171</span> * @constructor
+<span class='line'>172</span> * @param {Object} socket Socket for the client
+<span class='line'>173</span> * @param {Object} [options] Optional options object
+<span class='line'>174</span> */</span><span class="WHIT">
+<span class='line'>175</span> </span><span class="KEYW">function</span><span class="WHIT"> </span><span class="NAME">RAISocket</span><span class="PUNC">(</span><span class="NAME">socket</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">options</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>176</span> </span><span class="WHIT"> </span><span class="NAME">EventEmitter.call</span><span class="PUNC">(</span><span class="KEYW">this</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>177</span> </span><span class="WHIT">
+<span class='line'>178</span> </span><span class="NAME">this.socket</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">socket</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>179</span> </span><span class="WHIT"> </span><span class="NAME">this.options</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">options</span><span class="WHIT"> </span><span class="PUNC">||</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>180</span> </span><span class="WHIT">
+<span class='line'>181</span> </span><span class="NAME">this.remoteAddress</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">socket.remoteAddress</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>182</span> </span><span class="WHIT">
+<span class='line'>183</span> </span><span class="NAME">this._dataMode</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>184</span> </span><span class="WHIT"> </span><span class="NAME">this._endDataModeSequence</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="STRN">"\r\n.\r\n"</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>185</span> </span><span class="WHIT"> </span><span class="NAME">this._endDataModeSequenceRegEx</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="REGX">/\r\n\.\r\n|^\.\r\n/</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>186</span> </span><span class="WHIT">
+<span class='line'>187</span> </span><span class="NAME">this.secureConnection</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>188</span> </span><span class="WHIT"> </span><span class="NAME">this._destroyed</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>189</span> </span><span class="WHIT"> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="STRN">""</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>190</span> </span><span class="WHIT">
+<span class='line'>191</span> </span><span class="NAME">this._ignore_data</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>192</span> </span><span class="WHIT">
+<span class='line'>193</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.options.timeout</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>194</span> </span><span class="WHIT"> </span><span class="NAME">socket.setTimeout</span><span class="PUNC">(</span><span class="NAME">this.options.timeout</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>195</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>196</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>197</span> </span><span class="NAME">utillib.inherits</span><span class="PUNC">(</span><span class="NAME">RAISocket</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">EventEmitter</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>198</span>
+<span class='line'>199</span> </span><span class="COMM">/**
+<span class='line'>200</span> * &lt;p>Sends some data to the client. &lt;code>&lt;CR&gt;&lt;LF&gt;&lt;/code> is automatically appended to
+<span class='line'>201</span> * the data&lt;/p>
+<span class='line'>202</span> *
+<span class='line'>203</span> * @param {String|Buffer} data Data to be sent to the client
+<span class='line'>204</span> */</span><span class="WHIT">
+<span class='line'>205</span> </span><span class="NAME">RAISocket.prototype.send</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">data</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>206</span> </span><span class="WHIT"> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">buffer</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>207</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">data</span><span class="WHIT"> </span><span class="KEYW">instanceof</span><span class="WHIT"> </span><span class="NAME">Buffer</span><span class="WHIT"> </span><span class="PUNC">||</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="KEYW">typeof</span><span class="WHIT"> </span><span class="NAME">SlowBuffer</span><span class="WHIT"> </span><span class="PUNC">!=</span><span class="WHIT"> </span><span class="STRN">"undefined"</span><span class="WHIT"> </span><span class="PUNC">&&</span><span class="WHIT"> </span><span class="NAME">data</span><span class="WHIT"> </span><span class="KEYW">instanceof</span><span class="WHIT"> </span><span class="NAME">SlowBuffer</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>208</span> </span><span class="WHIT"> </span><span class="NAME">buffer</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">Buffer</span><span class="PUNC">(</span><span class="NAME">data.length</span><span class="PUNC">+</span><span class="NUMB">2</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>209</span> </span><span class="WHIT"> </span><span class="NAME">buffer</span><span class="PUNC">[</span><span class="NAME">buffer.length</span><span class="PUNC">-</span><span class="NUMB">2</span><span class="PUNC">]</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NUMB">0xD</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>210</span> </span><span class="WHIT"> </span><span class="NAME">buffer</span><span class="PUNC">[</span><span class="NAME">buffer.length</span><span class="PUNC">-</span><span class="NUMB">1</span><span class="PUNC">]</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NUMB">0xA</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>211</span> </span><span class="WHIT"> </span><span class="NAME">data.copy</span><span class="PUNC">(</span><span class="NAME">buffer</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>212</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="KEYW">else</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>213</span> </span><span class="WHIT"> </span><span class="NAME">buffer</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">Buffer</span><span class="PUNC">(</span><span class="PUNC">(</span><span class="NAME">data</span><span class="WHIT"> </span><span class="PUNC">||</span><span class="WHIT"> </span><span class="STRN">""</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">toString</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">+</span><span class="STRN">"\r\n"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="STRN">"binary"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>214</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>215</span> </span><span class="WHIT">
+<span class='line'>216</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.options.debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>217</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"OUT: \""</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="NAME">buffer.toString</span><span class="PUNC">(</span><span class="STRN">"utf-8"</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">trim</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">+</span><span class="STRN">"\""</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>218</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>219</span> </span><span class="WHIT">
+<span class='line'>220</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.socket</span><span class="WHIT"> </span><span class="PUNC">&&</span><span class="WHIT"> </span><span class="NAME">this.socket.writable</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>221</span> </span><span class="WHIT"> </span><span class="NAME">this.socket.write</span><span class="PUNC">(</span><span class="NAME">buffer</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>222</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="KEYW">else</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>223</span> </span><span class="WHIT"> </span><span class="NAME">this.socket.end</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>224</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>225</span> </span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>226</span>
+<span class='line'>227</span> </span><span class="COMM">/**
+<span class='line'>228</span> * &lt;p>Instructs the server to be listening for mixed data instead of line based
+<span class='line'>229</span> * commands&lt;/p>
+<span class='line'>230</span> *
+<span class='line'>231</span> * @param {String} [sequence="."] - optional sequence on separate line for
+<span class='line'>232</span> * matching the data end
+<span class='line'>233</span> */</span><span class="WHIT">
+<span class='line'>234</span> </span><span class="NAME">RAISocket.prototype.startDataMode</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">sequence</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>235</span> </span><span class="WHIT"> </span><span class="NAME">this._dataMode</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">true</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>236</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">sequence</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>237</span> </span><span class="WHIT"> </span><span class="NAME">sequence</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">sequence.replace</span><span class="PUNC">(</span><span class="REGX">/\.\=\(\)\-\?\*\\\[\]\^\+\:\|\,/g</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="STRN">"\\$1"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>238</span> </span><span class="WHIT"> </span><span class="NAME">this._endDataModeSequence</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="STRN">"\r\n"</span><span class="PUNC">+</span><span class="NAME">sequence</span><span class="PUNC">+</span><span class="STRN">"\r\n"</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>239</span> </span><span class="WHIT"> </span><span class="NAME">this._endDataModeSequenceRegEx</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">RegExp</span><span class="PUNC">(</span><span class="STRN">"/\r\n"</span><span class="PUNC">+</span><span class="NAME">sequence</span><span class="PUNC">+</span><span class="STRN">"\r\n|^"</span><span class="PUNC">+</span><span class="NAME">sequence</span><span class="PUNC">+</span><span class="STRN">"\r\n/"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>240</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>241</span> </span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>242</span>
+<span class='line'>243</span> </span><span class="COMM">/**
+<span class='line'>244</span> * &lt;p>Instructs the server to upgrade the connection to secure TLS connection&lt;/p>
+<span class='line'>245</span> *
+<span class='line'>246</span> * &lt;p>Fires &lt;code>callback&lt;/code> on successful connection upgrade if set,
+<span class='line'>247</span> * otherwise emits &lt;code>'tls'&lt;/code>&lt;/p>
+<span class='line'>248</span> *
+<span class='line'>249</span> * @param {Object} [credentials] An object with PEM encoded key and
+<span class='line'>250</span> * certificate &lt;code>{key:"---BEGIN...", cert:"---BEGIN..."}&lt;/code>,
+<span class='line'>251</span> * if not set autogenerated values will be used.
+<span class='line'>252</span> * @param {Function} [callback] If calback is set fire it after successful connection
+<span class='line'>253</span> * upgrade, otherwise &lt;code>'tls'&lt;/code> is emitted
+<span class='line'>254</span> */</span><span class="WHIT">
+<span class='line'>255</span> </span><span class="NAME">RAISocket.prototype.startTLS</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">credentials</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">callback</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>256</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.secureConnection</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>257</span> </span><span class="WHIT"> </span><span class="NAME">this._onError</span><span class="PUNC">(</span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">Error</span><span class="PUNC">(</span><span class="STRN">"Secure connection already established"</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>258</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>259</span> </span><span class="WHIT">
+<span class='line'>260</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="PUNC">!</span><span class="NAME">callback</span><span class="WHIT"> </span><span class="PUNC">&&</span><span class="WHIT"> </span><span class="KEYW">typeof</span><span class="WHIT"> </span><span class="NAME">credentials</span><span class="WHIT"> </span><span class="PUNC">==</span><span class="WHIT"> </span><span class="STRN">"function"</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>261</span> </span><span class="WHIT"> </span><span class="NAME">callback</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">credentials</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>262</span> </span><span class="WHIT"> </span><span class="NAME">credentials</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">undefined</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>263</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>264</span> </span><span class="WHIT">
+<span class='line'>265</span> </span><span class="NAME">credentials</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">credentials</span><span class="WHIT"> </span><span class="PUNC">||</span><span class="WHIT"> </span><span class="NAME">defaultCredentials</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>266</span> </span><span class="WHIT">
+<span class='line'>267</span> </span><span class="NAME">this._ignore_data</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">true</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>268</span> </span><span class="WHIT">
+<span class='line'>269</span> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">secure_connector</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">starttls</span><span class="PUNC">(</span><span class="NAME">this.socket</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">credentials</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">ssl_socket</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>270</span>
+<span class='line'>271</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.options.debug</span><span class="WHIT"> </span><span class="PUNC">&&</span><span class="WHIT"> </span><span class="PUNC">!</span><span class="NAME">ssl_socket.authorized</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>272</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"WARNING: TLS ERROR ("</span><span class="PUNC">+</span><span class="NAME">ssl_socket.authorizationError</span><span class="PUNC">+</span><span class="STRN">")"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>273</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>274</span> </span><span class="WHIT">
+<span class='line'>275</span> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="STRN">""</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>276</span> </span><span class="WHIT"> </span><span class="NAME">this._ignore_data</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>277</span> </span><span class="WHIT">
+<span class='line'>278</span> </span><span class="NAME">this.secureConnection</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">true</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>279</span> </span><span class="WHIT">
+<span class='line'>280</span> </span><span class="NAME">this.socket</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">ssl_socket</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>281</span> </span><span class="WHIT"> </span><span class="NAME">this.socket.on</span><span class="PUNC">(</span><span class="STRN">"data"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">this._onReceiveData.bind</span><span class="PUNC">(</span><span class="KEYW">this</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>282</span> </span><span class="WHIT">
+<span class='line'>283</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.options.debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>284</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"TLS CONNECTION STARTED"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>285</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>286</span> </span><span class="WHIT">
+<span class='line'>287</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">callback</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>288</span> </span><span class="WHIT"> </span><span class="NAME">callback</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>289</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="KEYW">else</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>290</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"tls"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>291</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>292</span> </span><span class="WHIT">
+<span class='line'>293</span> </span><span class="PUNC">}</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">bind</span><span class="PUNC">(</span><span class="KEYW">this</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>294</span> </span><span class="WHIT">
+<span class='line'>295</span> </span><span class="NAME">secure_connector.on</span><span class="PUNC">(</span><span class="STRN">"error"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">err</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>296</span> </span><span class="WHIT"> </span><span class="NAME">this._onError</span><span class="PUNC">(</span><span class="NAME">err</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>297</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">bind</span><span class="PUNC">(</span><span class="KEYW">this</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>298</span> </span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>299</span>
+<span class='line'>300</span> </span><span class="COMM">/**
+<span class='line'>301</span> * &lt;p>Closes the connection to the client&lt;/p>
+<span class='line'>302</span> */</span><span class="WHIT">
+<span class='line'>303</span> </span><span class="NAME">RAISocket.prototype.end</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>304</span> </span><span class="WHIT"> </span><span class="NAME">this.socket.end</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>305</span> </span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>306</span>
+<span class='line'>307</span> </span><span class="COMM">/**
+<span class='line'>308</span> * &lt;p>Called when a chunk of data arrives from the client. If currently in data
+<span class='line'>309</span> * mode, transmit the data otherwise send it to &lt;code>_processData&lt;/code>&lt;/p>
+<span class='line'>310</span> *
+<span class='line'>311</span> * @event
+<span class='line'>312</span> * @param {Buffer|String} chunk Data sent by the client
+<span class='line'>313</span> */</span><span class="WHIT">
+<span class='line'>314</span> </span><span class="NAME">RAISocket.prototype._onReceiveData</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">chunk</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>315</span>
+<span class='line'>316</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this._ignore_data</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT"> </span><span class="COMM">// if currently setting up TLS connection</span><span class="WHIT">
+<span class='line'>317</span> </span><span class="WHIT"> </span><span class="KEYW">return</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>318</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>319</span> </span><span class="WHIT">
+<span class='line'>320</span> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">str</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">typeof</span><span class="WHIT"> </span><span class="NAME">chunk</span><span class="PUNC">==</span><span class="STRN">"string"</span><span class="PUNC">?</span><span class="NAME">chunk</span><span class="PUNC">:</span><span class="NAME">chunk.toString</span><span class="PUNC">(</span><span class="STRN">"binary"</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'>321</span> </span><span class="WHIT"> </span><span class="NAME">dataEndMatch</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">dataRemainderMatch</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">data</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">match</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>322</span> </span><span class="WHIT">
+<span class='line'>323</span> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this._dataMode</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>324</span> </span><span class="WHIT">
+<span class='line'>325</span> </span><span class="NAME">str</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="WHIT"> </span><span class="NAME">str</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>326</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="PUNC">(</span><span class="NAME">dataEndMatch</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">str.match</span><span class="PUNC">(</span><span class="REGX">/\r\n.*?$/</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>327</span> </span><span class="WHIT"> </span><span class="COMM">// if theres a line that is not ended, keep it for later</span><span class="WHIT">
+<span class='line'>328</span> </span><span class="WHIT"> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">str.substr</span><span class="PUNC">(</span><span class="NAME">dataEndMatch.index</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>329</span> </span><span class="WHIT"> </span><span class="NAME">str</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">str.substr</span><span class="PUNC">(</span><span class="NUMB">0</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">dataEndMatch.index</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>330</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="KEYW">else</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>331</span> </span><span class="WHIT"> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="STRN">""</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>332</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>333</span>
+<span class='line'>334</span> </span><span class="WHIT"> </span><span class="COMM">// check if a data end sequence is found from the data</span><span class="WHIT">
+<span class='line'>335</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="PUNC">(</span><span class="NAME">dataRemainderMatch</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">str</span><span class="PUNC">+</span><span class="NAME">this._remainder</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">match</span><span class="PUNC">(</span><span class="NAME">this._endDataModeSequenceRegEx</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>336</span> </span><span class="WHIT"> </span><span class="NAME">str</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">str</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="WHIT"> </span><span class="NAME">this._remainder</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>337</span> </span><span class="WHIT"> </span><span class="COMM">// if the sequence is not on byte 0 emit remaining data</span><span class="WHIT">
+<span class='line'>338</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">dataRemainderMatch.index</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>339</span> </span><span class="WHIT"> </span><span class="NAME">data</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">Buffer</span><span class="PUNC">(</span><span class="NAME">str.substr</span><span class="PUNC">(</span><span class="NUMB">0</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">dataRemainderMatch.index</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="STRN">"binary"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>340</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.options.debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>341</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"DATA:"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">data.toString</span><span class="PUNC">(</span><span class="STRN">"utf-8"</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>342</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>343</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"data"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">data</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>344</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>345</span> </span><span class="WHIT"> </span><span class="COMM">// emit data ready</span><span class="WHIT">
+<span class='line'>346</span> </span><span class="WHIT"> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="STRN">""</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>347</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"ready"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>348</span> </span><span class="WHIT"> </span><span class="NAME">this._dataMode</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>349</span> </span><span class="WHIT"> </span><span class="COMM">// send the remaining data for processing</span><span class="WHIT">
+<span class='line'>350</span> </span><span class="WHIT"> </span><span class="NAME">this._processData</span><span class="PUNC">(</span><span class="NAME">str.substr</span><span class="PUNC">(</span><span class="NAME">dataRemainderMatch.index</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="WHIT"> </span><span class="NAME">dataRemainderMatch</span><span class="PUNC">[</span><span class="NUMB">0</span><span class="PUNC">]</span><span class="PUNC">.</span><span class="NAME">length</span><span class="PUNC">)</span><span class="PUNC">+</span><span class="STRN">"\r\n"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>351</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="KEYW">else</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>352</span> </span><span class="WHIT"> </span><span class="COMM">// check if there's not something in the end of the data that resembles</span><span class="WHIT">
+<span class='line'>353</span> </span><span class="WHIT"> </span><span class="COMM">// end sequence - if so, cut it off and save it to the remainder</span><span class="WHIT">
+<span class='line'>354</span> </span><span class="WHIT"> </span><span class="NAME">str</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">str</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="WHIT"> </span><span class="NAME">this._remainder</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>355</span> </span><span class="WHIT"> </span><span class="NAME">this._remainder</span><span class="PUNC">=</span><span class="WHIT"> </span><span class="STRN">""</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>356</span> </span><span class="WHIT"> </span><span class="KEYW">for</span><span class="PUNC">(</span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">i</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">Math.min</span><span class="PUNC">(</span><span class="NAME">this._endDataModeSequence.length</span><span class="PUNC">-</span><span class="NUMB">1</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">str.length</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="NAME">i</span><span class="PUNC">></span><span class="NUMB">0</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="NAME">i</span><span class="PUNC">--</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>357</span> </span><span class="WHIT"> </span><span class="NAME">match</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">this._endDataModeSequence.substr</span><span class="PUNC">(</span><span class="NUMB">0</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">i</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>358</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">str.substr</span><span class="PUNC">(</span><span class="PUNC">-</span><span class="NAME">match.length</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">==</span><span class="WHIT"> </span><span class="NAME">match</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>359</span> </span><span class="WHIT"> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">str.substr</span><span class="PUNC">(</span><span class="PUNC">-</span><span class="NAME">match.length</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>360</span> </span><span class="WHIT"> </span><span class="NAME">str</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">str.substr</span><span class="PUNC">(</span><span class="NUMB">0</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">str.length</span><span class="WHIT"> </span><span class="PUNC">-</span><span class="WHIT"> </span><span class="NAME">match.length</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>361</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>362</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>363</span>
+<span class='line'>364</span> </span><span class="WHIT"> </span><span class="COMM">// if there's some data leht, emit it</span><span class="WHIT">
+<span class='line'>365</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">str.length</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>366</span> </span><span class="WHIT"> </span><span class="NAME">data</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">Buffer</span><span class="PUNC">(</span><span class="NAME">str</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="STRN">"binary"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>367</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.options.debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>368</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"DATA:"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">data.toString</span><span class="PUNC">(</span><span class="STRN">"utf-8"</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>369</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>370</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"data"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">data</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>371</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>372</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>373</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="KEYW">else</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>374</span> </span><span class="WHIT"> </span><span class="COMM">// Not in data mode, process as command</span><span class="WHIT">
+<span class='line'>375</span> </span><span class="WHIT"> </span><span class="NAME">this._processData</span><span class="PUNC">(</span><span class="NAME">str</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>376</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>377</span> </span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>378</span>
+<span class='line'>379</span> </span><span class="COMM">/**
+<span class='line'>380</span> * &lt;p>Processed incoming command lines and emits found data as
+<span class='line'>381</span> * &lt;code>'command'&lt;/code> with the command name as the first param and the rest
+<span class='line'>382</span> * of the data as second (Buffer)&lt;/p>
+<span class='line'>383</span> *
+<span class='line'>384</span> * @param {String} str Binary string to be processed
+<span class='line'>385</span> */</span><span class="WHIT">
+<span class='line'>386</span> </span><span class="NAME">RAISocket.prototype._processData</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">str</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>387</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="PUNC">!</span><span class="NAME">str.length</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>388</span> </span><span class="WHIT"> </span><span class="KEYW">return</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>389</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>390</span> </span><span class="WHIT"> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">lines</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">this._remainder</span><span class="PUNC">+</span><span class="NAME">str</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">split</span><span class="PUNC">(</span><span class="STRN">"\r\n"</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT">
+<span class='line'>391</span> </span><span class="WHIT"> </span><span class="NAME">match</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">command</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>392</span> </span><span class="WHIT">
+<span class='line'>393</span> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">lines.pop</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>394</span> </span><span class="WHIT">
+<span class='line'>395</span> </span><span class="KEYW">for</span><span class="PUNC">(</span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">i</span><span class="PUNC">=</span><span class="NUMB">0</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">len</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">lines.length</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="NAME">i</span><span class="PUNC">&lt;</span><span class="NAME">len</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="NAME">i</span><span class="PUNC">++</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>396</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this._ignore_data</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>397</span> </span><span class="WHIT"> </span><span class="COMM">// If TLS upgrade is initiated do not process current buffer</span><span class="WHIT">
+<span class='line'>398</span> </span><span class="WHIT"> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="STRN">""</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>399</span> </span><span class="WHIT"> </span><span class="KEYW">break</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>400</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>401</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="PUNC">!</span><span class="NAME">this._dataMode</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>402</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="PUNC">(</span><span class="NAME">match</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">lines</span><span class="PUNC">[</span><span class="NAME">i</span><span class="PUNC">]</span><span class="PUNC">.</span><span class="NAME">match</span><span class="PUNC">(</span><span class="REGX">/\s*[\S]+\s?/</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>403</span> </span><span class="WHIT"> </span><span class="NAME">command</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">match</span><span class="PUNC">[</span><span class="NUMB">0</span><span class="PUNC">]</span><span class="WHIT"> </span><span class="PUNC">||</span><span class="WHIT"> </span><span class="STRN">""</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">trim</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>404</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.options.debug</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>405</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="STRN">"COMMAND:"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">lines</span><span class="PUNC">[</span><span class="NAME">i</span><span class="PUNC">]</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>406</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>407</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"command"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">command</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">Buffer</span><span class="PUNC">(</span><span class="NAME">lines</span><span class="PUNC">[</span><span class="NAME">i</span><span class="PUNC">]</span><span class="PUNC">.</span><span class="NAME">substr</span><span class="PUNC">(</span><span class="NAME">match.index</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="WHIT"> </span><span class="NAME">match</span><span class="PUNC">[</span><span class="NUMB">0</span><span class="PUNC">]</span><span class="PUNC">.</span><span class="NAME">length</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="STRN">"binary"</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>408</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>409</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="KEYW">else</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>410</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this._remainder</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>411</span> </span><span class="WHIT"> </span><span class="NAME">this._remainder</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="PUNC">=</span><span class="WHIT"> </span><span class="STRN">"\r\n"</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>412</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>413</span> </span><span class="WHIT"> </span><span class="NAME">this._onReceiveData</span><span class="PUNC">(</span><span class="NAME">lines.slice</span><span class="PUNC">(</span><span class="NAME">i</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">join</span><span class="PUNC">(</span><span class="STRN">"\r\n"</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>414</span> </span><span class="WHIT"> </span><span class="KEYW">break</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>415</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>416</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>417</span> </span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>418</span>
+<span class='line'>419</span> </span><span class="COMM">/**
+<span class='line'>420</span> * &lt;p>Called when the connection is or is going to be ended&lt;/p>
+<span class='line'>421</span> */</span><span class="WHIT">
+<span class='line'>422</span> </span><span class="NAME">RAISocket.prototype._destroy</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>423</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this._destroyed</span><span class="PUNC">)</span><span class="KEYW">return</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>424</span> </span><span class="WHIT"> </span><span class="NAME">this._destroyed</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">true</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>425</span> </span><span class="WHIT">
+<span class='line'>426</span> </span><span class="NAME">this.removeAllListeners</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>427</span> </span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>428</span>
+<span class='line'>429</span> </span><span class="COMM">/**
+<span class='line'>430</span> * &lt;p>Called when the connection is ended. Emits &lt;code>'end'&lt;/code>&lt;/p>
+<span class='line'>431</span> *
+<span class='line'>432</span> * @event
+<span class='line'>433</span> */</span><span class="WHIT">
+<span class='line'>434</span> </span><span class="NAME">RAISocket.prototype._onEnd</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>435</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"end"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>436</span> </span><span class="WHIT"> </span><span class="NAME">this._destroy</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>437</span> </span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>438</span>
+<span class='line'>439</span> </span><span class="COMM">/**
+<span class='line'>440</span> * &lt;p>Called when an error has appeared. Emits &lt;code>'error'&lt;/code> with
+<span class='line'>441</span> * the error object as a parameter.&lt;/p>
+<span class='line'>442</span> *
+<span class='line'>443</span> * @event
+<span class='line'>444</span> * @param {Object} err Error object
+<span class='line'>445</span> */</span><span class="WHIT">
+<span class='line'>446</span> </span><span class="NAME">RAISocket.prototype._onError</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">err</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>447</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"error"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">err</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>448</span> </span><span class="WHIT"> </span><span class="NAME">this._destroy</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>449</span> </span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>450</span>
+<span class='line'>451</span> </span><span class="COMM">/**
+<span class='line'>452</span> * &lt;p>Called when a timeout has occured. Connection will be closed and
+<span class='line'>453</span> * &lt;code>'timeout'&lt;/code> is emitted.&lt;/p>
+<span class='line'>454</span> *
+<span class='line'>455</span> * @event
+<span class='line'>456</span> */</span><span class="WHIT">
+<span class='line'>457</span> </span><span class="NAME">RAISocket.prototype._onTimeout</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>458</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.options.disconnectOnTimeout</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>459</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="PUNC">(</span><span class="NAME">this.socket</span><span class="WHIT"> </span><span class="PUNC">&&</span><span class="WHIT"> </span><span class="PUNC">!</span><span class="NAME">this.socket.destroyed</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>460</span> </span><span class="WHIT"> </span><span class="NAME">this.socket.end</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>461</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>462</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"timeout"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>463</span> </span><span class="WHIT"> </span><span class="NAME">this._destroy</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>464</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="KEYW">else</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>465</span> </span><span class="WHIT"> </span><span class="NAME">this.emit</span><span class="PUNC">(</span><span class="STRN">"timeout"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>466</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>467</span> </span><span class="PUNC">}</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>468</span>
+<span class='line'>469</span> </span><span class="COMM">/**
+<span class='line'>470</span> * &lt;p>Called when the connection is closed&lt;/p>
+<span class='line'>471</span> *
+<span class='line'>472</span> * @event
+<span class='line'>473</span> * @param {Boolean} hadError did the connection end because of an error?
+<span class='line'>474</span> */</span><span class="WHIT">
+<span class='line'>475</span> </span><span class="NAME">RAISocket.prototype._onClose</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">hadError</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>476</span> </span><span class="WHIT"> </span><span class="NAME">this._destroy</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>477</span> </span><span class="PUNC">}</span><span class="PUNC">;</span></pre></body></html> \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_starttls.js.html b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_starttls.js.html
new file mode 100644
index 0000000..dd1b2ea
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_starttls.js.html
@@ -0,0 +1,120 @@
+<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"> <style>
+ .KEYW {color: #933;}
+ .COMM {color: #bbb; font-style: italic;}
+ .NUMB {color: #393;}
+ .STRN {color: #393;}
+ .REGX {color: #339;}
+ .line {border-right: 1px dotted #666; color: #666; font-style: normal;}
+ </style></head><body><pre><span class='line'> 1</span> <span class="COMM">// SOURCE: https://gist.github.com/848444</span><span class="WHIT">
+<span class='line'> 2</span>
+<span class='line'> 3</span> </span><span class="COMM">// Target API:</span><span class="WHIT">
+<span class='line'> 4</span> </span><span class="COMM">//</span><span class="WHIT">
+<span class='line'> 5</span> </span><span class="COMM">// var s = require('net').createStream(25, 'smtp.example.com');</span><span class="WHIT">
+<span class='line'> 6</span> </span><span class="COMM">// s.on('connect', function() {</span><span class="WHIT">
+<span class='line'> 7</span> </span><span class="COMM">// require('starttls')(s, options, function() {</span><span class="WHIT">
+<span class='line'> 8</span> </span><span class="COMM">// if (!s.authorized) {</span><span class="WHIT">
+<span class='line'> 9</span> </span><span class="COMM">// s.destroy();</span><span class="WHIT">
+<span class='line'> 10</span> </span><span class="COMM">// return;</span><span class="WHIT">
+<span class='line'> 11</span> </span><span class="COMM">// }</span><span class="WHIT">
+<span class='line'> 12</span> </span><span class="COMM">//</span><span class="WHIT">
+<span class='line'> 13</span> </span><span class="COMM">// s.end("hello world\n");</span><span class="WHIT">
+<span class='line'> 14</span> </span><span class="COMM">// });</span><span class="WHIT">
+<span class='line'> 15</span> </span><span class="COMM">// });</span><span class="WHIT">
+<span class='line'> 16</span> </span><span class="COMM">//</span><span class="WHIT">
+<span class='line'> 17</span> </span><span class="COMM">//</span><span class="WHIT">
+<span class='line'> 18</span>
+<span class='line'> 19</span> </span><span class="COMM">/**
+<span class='line'> 20</span> * @namespace STARTTLS module
+<span class='line'> 21</span> * @name starttls
+<span class='line'> 22</span> */</span><span class="WHIT">
+<span class='line'> 23</span> </span><span class="NAME">module.exports.starttls</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">starttls</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 24</span>
+<span class='line'> 25</span> </span><span class="COMM">/**
+<span class='line'> 26</span> * &lt;p>Upgrades a socket to a secure TLS connection&lt;/p>
+<span class='line'> 27</span> *
+<span class='line'> 28</span> * @memberOf starttls
+<span class='line'> 29</span> * @param {Object} socket Plaintext socket to be upgraded
+<span class='line'> 30</span> * @param {Object} options Certificate data for the server
+<span class='line'> 31</span> * @param {Function} callback Callback function to be run after upgrade
+<span class='line'> 32</span> */</span><span class="WHIT">
+<span class='line'> 33</span> </span><span class="KEYW">function</span><span class="WHIT"> </span><span class="NAME">starttls</span><span class="PUNC">(</span><span class="NAME">socket</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">options</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">callback</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 34</span> </span><span class="WHIT"> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">sslcontext</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">pair</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">cleartext</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 35</span> </span><span class="WHIT">
+<span class='line'> 36</span> </span><span class="NAME">socket.removeAllListeners</span><span class="PUNC">(</span><span class="STRN">"data"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 37</span> </span><span class="WHIT"> </span><span class="NAME">sslcontext</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">'crypto'</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">createCredentials</span><span class="PUNC">(</span><span class="NAME">options</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 38</span> </span><span class="WHIT"> </span><span class="NAME">pair</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">require</span><span class="PUNC">(</span><span class="STRN">'tls'</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">createSecurePair</span><span class="PUNC">(</span><span class="NAME">sslcontext</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="KEYW">true</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 39</span> </span><span class="WHIT"> </span><span class="NAME">cleartext</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">pipe</span><span class="PUNC">(</span><span class="NAME">pair</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">socket</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 40</span>
+<span class='line'> 41</span> </span><span class="WHIT"> </span><span class="NAME">pair.on</span><span class="PUNC">(</span><span class="STRN">'secure'</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 42</span> </span><span class="WHIT"> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">verifyError</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">pair._ssl</span><span class="WHIT"> </span><span class="PUNC">||</span><span class="WHIT"> </span><span class="NAME">pair.ssl</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">verifyError</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 43</span>
+<span class='line'> 44</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">verifyError</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 45</span> </span><span class="WHIT"> </span><span class="NAME">cleartext.authorized</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 46</span> </span><span class="WHIT"> </span><span class="NAME">cleartext.authorizationError</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">verifyError</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 47</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT"> </span><span class="KEYW">else</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 48</span> </span><span class="WHIT"> </span><span class="NAME">cleartext.authorized</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">true</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 49</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 50</span>
+<span class='line'> 51</span> </span><span class="WHIT"> </span><span class="NAME">callback</span><span class="PUNC">(</span><span class="NAME">cleartext</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 52</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 53</span>
+<span class='line'> 54</span> </span><span class="WHIT"> </span><span class="NAME">cleartext._controlReleased</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">true</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 55</span> </span><span class="WHIT"> </span><span class="KEYW">return</span><span class="WHIT"> </span><span class="NAME">pair</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 56</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 57</span>
+<span class='line'> 58</span> </span><span class="KEYW">function</span><span class="WHIT"> </span><span class="NAME">forwardEvents</span><span class="PUNC">(</span><span class="NAME">events</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">emitterSource</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">emitterDestination</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 59</span> </span><span class="WHIT"> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">map</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="PUNC">[</span><span class="PUNC">]</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">name</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">handler</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 60</span> </span><span class="WHIT">
+<span class='line'> 61</span> </span><span class="KEYW">for</span><span class="PUNC">(</span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">i</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NUMB">0</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">len</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">events.length</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="NAME">i</span><span class="WHIT"> </span><span class="PUNC">&lt;</span><span class="WHIT"> </span><span class="NAME">len</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="NAME">i</span><span class="PUNC">++</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 62</span> </span><span class="WHIT"> </span><span class="NAME">name</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">events</span><span class="PUNC">[</span><span class="NAME">i</span><span class="PUNC">]</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 63</span>
+<span class='line'> 64</span> </span><span class="WHIT"> </span><span class="NAME">handler</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">forwardEvent.bind</span><span class="PUNC">(</span><span class="NAME">emitterDestination</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">name</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 65</span> </span><span class="WHIT">
+<span class='line'> 66</span> </span><span class="NAME">map.push</span><span class="PUNC">(</span><span class="NAME">name</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 67</span> </span><span class="WHIT"> </span><span class="NAME">emitterSource.on</span><span class="PUNC">(</span><span class="NAME">name</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">handler</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 68</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 69</span> </span><span class="WHIT">
+<span class='line'> 70</span> </span><span class="KEYW">return</span><span class="WHIT"> </span><span class="NAME">map</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 71</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 72</span>
+<span class='line'> 73</span> </span><span class="KEYW">function</span><span class="WHIT"> </span><span class="NAME">forwardEvent</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 74</span> </span><span class="WHIT"> </span><span class="NAME">this.emit.apply</span><span class="PUNC">(</span><span class="KEYW">this</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">arguments</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 75</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 76</span>
+<span class='line'> 77</span> </span><span class="KEYW">function</span><span class="WHIT"> </span><span class="NAME">removeEvents</span><span class="PUNC">(</span><span class="NAME">map</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">emitterSource</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 78</span> </span><span class="WHIT"> </span><span class="KEYW">for</span><span class="PUNC">(</span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">i</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NUMB">0</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">len</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">map.length</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="NAME">i</span><span class="WHIT"> </span><span class="PUNC">&lt;</span><span class="WHIT"> </span><span class="NAME">len</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="NAME">i</span><span class="PUNC">++</span><span class="PUNC">)</span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 79</span> </span><span class="WHIT"> </span><span class="NAME">emitterSource.removeAllListeners</span><span class="PUNC">(</span><span class="NAME">map</span><span class="PUNC">[</span><span class="NAME">i</span><span class="PUNC">]</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 80</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 81</span> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 82</span>
+<span class='line'> 83</span> </span><span class="KEYW">function</span><span class="WHIT"> </span><span class="NAME">pipe</span><span class="PUNC">(</span><span class="NAME">pair</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">socket</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 84</span> </span><span class="WHIT"> </span><span class="NAME">pair.encrypted.pipe</span><span class="PUNC">(</span><span class="NAME">socket</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 85</span> </span><span class="WHIT"> </span><span class="NAME">socket.pipe</span><span class="PUNC">(</span><span class="NAME">pair.encrypted</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 86</span>
+<span class='line'> 87</span> </span><span class="WHIT"> </span><span class="NAME">pair.fd</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">socket.fd</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 88</span> </span><span class="WHIT">
+<span class='line'> 89</span> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">cleartext</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">pair.cleartext</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 90</span> </span><span class="WHIT">
+<span class='line'> 91</span> </span><span class="NAME">cleartext.socket</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">socket</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 92</span> </span><span class="WHIT"> </span><span class="NAME">cleartext.encrypted</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">pair.encrypted</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 93</span> </span><span class="WHIT"> </span><span class="NAME">cleartext.authorized</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 94</span>
+<span class='line'> 95</span> </span><span class="WHIT"> </span><span class="KEYW">function</span><span class="WHIT"> </span><span class="NAME">onerror</span><span class="PUNC">(</span><span class="NAME">e</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 96</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">cleartext._controlReleased</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'> 97</span> </span><span class="WHIT"> </span><span class="NAME">cleartext.emit</span><span class="PUNC">(</span><span class="STRN">'error'</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">e</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'> 98</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'> 99</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>100</span>
+<span class='line'>101</span> </span><span class="WHIT"> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">map</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">forwardEvents</span><span class="PUNC">(</span><span class="PUNC">[</span><span class="STRN">"timeout"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="STRN">"end"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="STRN">"close"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="STRN">"drain"</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="STRN">"error"</span><span class="PUNC">]</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">socket</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">cleartext</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>102</span> </span><span class="WHIT">
+<span class='line'>103</span> </span><span class="KEYW">function</span><span class="WHIT"> </span><span class="NAME">onclose</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT">
+<span class='line'>104</span> </span><span class="WHIT"> </span><span class="NAME">socket.removeListener</span><span class="PUNC">(</span><span class="STRN">'error'</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">onerror</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>105</span> </span><span class="WHIT"> </span><span class="NAME">socket.removeListener</span><span class="PUNC">(</span><span class="STRN">'close'</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">onclose</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>106</span> </span><span class="WHIT"> </span><span class="NAME">removeEvents</span><span class="PUNC">(</span><span class="NAME">map</span><span class="PUNC">,</span><span class="NAME">socket</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>107</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT">
+<span class='line'>108</span>
+<span class='line'>109</span> </span><span class="WHIT"> </span><span class="NAME">socket.on</span><span class="PUNC">(</span><span class="STRN">'error'</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">onerror</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>110</span> </span><span class="WHIT"> </span><span class="NAME">socket.on</span><span class="PUNC">(</span><span class="STRN">'close'</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">onclose</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>111</span>
+<span class='line'>112</span> </span><span class="WHIT"> </span><span class="KEYW">return</span><span class="WHIT"> </span><span class="NAME">cleartext</span><span class="PUNC">;</span><span class="WHIT">
+<span class='line'>113</span> </span><span class="PUNC">}</span></pre></body></html> \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/starttls.html b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/starttls.html
new file mode 100644
index 0000000..e16b915
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/starttls.html
@@ -0,0 +1,237 @@
+
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="generator" content="JsDoc Toolkit" />
+ <title>starttls | JsDoc Reference</title>
+
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
+ <meta name="mobileoptimized" content="0" />
+
+ <link rel="stylesheet" href="../css/all.css" media="all" />
+ <link rel="stylesheet" href="../css/handheld.css" media="only screen and (max-width: 660px)" />
+ <link rel="stylesheet" href="../css/handheld.css" media="handheld" />
+ <link rel="stylesheet" href="../css/screen.css" media="screen and (min-width: 661px)" />
+
+ <script src="../javascript/all.js"></script>
+ <!--[if lt IE 9]>
+ <script src="../javascript/html5.js"></script>
+ <![endif]-->
+ </head>
+
+ <body>
+
+<div class="index">
+ <div class="menu">
+ <div class="indexLinks">
+ <a href="../index.html">Classes</a>
+ <a href="../files.html">Files</a>
+ </div>
+
+ <h2 class="heading1">Classes</h2>
+
+ <input type="text" name="classFilter" class="classFilter" id="ClassFilter" placeholder="Filter"></input>
+
+ <nav>
+ <ul class="classList" id="ClassList">
+
+ <li><a href="../symbols/_global_.html">_global_</a></li>
+
+ <li><a href="../symbols/mockup.html">mockup</a></li>
+
+ <li><a href="../symbols/RAIServer.html">RAIServer</a></li>
+
+ <li><a href="../symbols/RAISocket.html">RAISocket</a></li>
+
+ <li><a href="../symbols/starttls.html">starttls</a></li>
+
+ </ul>
+ </nav>
+ </div>
+ <div class="fineprint" style="clear:both">
+ <footer>
+
+ Documentation generator: <a href="http://code.google.com/p/jsdoc-toolkit/" target="_blank">JsDoc Toolkit</a> 2.4.0<br />
+ Template: <a href="http://www.thebrightlines.com/2010/05/06/new-template-for-jsdoctoolkit-codeview/" target="_blank">Codeview</a> 1.2<br />
+ Generated on:
+ <time datetime='2012-0-22' pubdate>2012-0-22 12:15</time>
+ </footer>
+ </div>
+</div>
+
+<div class="index indexStatic"></div>
+
+<div class="content">
+ <div class="innerContent">
+ <article>
+ <header>
+ <h1 class="classTitle">
+
+ Namespace <span>starttls</span>
+ </h1>
+
+ <div class="intro">
+ <p class="description summary">
+ STARTTLS module
+ </p>
+
+
+ <ul class="summary">
+
+
+
+ <li>Defined in: <a href="../symbols/src/RAI_lib_starttls.js.html">starttls.js</a></li>
+
+
+ </ul>
+
+ </div>
+ </header>
+
+
+
+
+ <!--
+ #### METHODS SUMMARY
+ -->
+
+ <section>
+
+
+ <div class="props">
+ <h2 class="sectionTitle">Method Summary</h2>
+
+
+ <nav>
+ <table class="summaryTable" id="MethodsList" cellspacing="0" summary="A summary of the methods documented in the class starttls.">
+ <thead>
+ <tr>
+ <th scope="col">Method Attributes</th>
+ <th scope="col">Method Name and Description</th>
+ </tr>
+ </thead>
+
+ <tbody>
+
+
+ <tr
+ class='item0'
+ >
+ <td class="attributes">&lt;static&gt; &nbsp;</td>
+ <td class="nameDescription">
+ <div class="fixedFont">starttls.<b><a href="../symbols/starttls.html#.starttls">starttls</a></b>(socket, options, callback)
+ </div>
+ <div class="description"><p>Upgrades a socket to a secure TLS connection</p></div>
+ </td>
+ </tr>
+
+ </tbody>
+ </table>
+ </nav>
+
+
+
+ </div>
+ </section>
+
+
+ <!--
+ #### EVENTS SUMMARY
+ -->
+
+ <!--
+ #### CONSTRUCTOR DETAILS
+ -->
+
+ <!--
+ #### FIELD DETAILS
+ -->
+
+ <!--
+ #### METHOD DETAILS
+ -->
+
+ <section>
+ <div class="details props">
+ <div class="innerProps">
+ <h2 class="sectionTitle">
+ Method Detail
+ </h2>
+
+ <ul class="methodDetail" id="MethodDetail">
+
+
+ <li
+ class='item0'
+ >
+ <div class="fixedFont heading" id=".starttls">
+ <span class='lighter'>
+ &lt;static&gt;
+ </span>
+
+
+
+ <span class="light">starttls.</span><b>starttls</b>(socket, options, callback)
+ </div>
+
+ <div class="description">
+ <p>Upgrades a socket to a secure TLS connection</p>
+
+
+
+
+ </div>
+
+
+
+
+ <dl class="detailList params">
+ <dt class="heading">Parameters:</dt>
+
+ <dt>
+ <span class="light fixedFont">{Object}</span> <b>socket</b>
+
+ </dt>
+ <dd>Plaintext socket to be upgraded</dd>
+
+ <dt>
+ <span class="light fixedFont">{Object}</span> <b>options</b>
+
+ </dt>
+ <dd>Certificate data for the server</dd>
+
+ <dt>
+ <span class="light fixedFont">{Function}</span> <b>callback</b>
+
+ </dt>
+ <dd>Callback function to be run after upgrade</dd>
+
+ </dl>
+
+
+
+
+ </li>
+
+ </ul>
+ </div>
+ </div>
+ </section>
+
+
+ <!--
+ #### EVENT DETAILS
+ -->
+
+ </article>
+ </div>
+</div>
+
+ <script type="text/javascript">
+ wbos.CssTools.MediaQueryFallBack.LoadCss('../css/screen.css', '../css/handheld.css', 660)
+ codeview.classFilter.Init()
+ </script>
+ </body>
+</html>
+
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/mockup.js b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/mockup.js
new file mode 100644
index 0000000..47bbc4a
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/mockup.js
@@ -0,0 +1,113 @@
+var net = require("net"),
+ crypto = require("crypto"),
+ tlslib = require("tls");
+
+// monkey patch net and tls to support nodejs 0.4
+if(!net.connect && net.createConnection){
+ net.connect = net.createConnection;
+}
+
+if(!tlslib.connect && tlslib.createConnection){
+ tlslib.connect = tlslib.createConnection;
+}
+
+/**
+ * @namespace Mockup module
+ * @name mockup
+ */
+module.exports = runClientMockup;
+
+/**
+ * <p>Runs a batch of commands against a server</p>
+ *
+ * <pre>
+ * var cmds = ["EHLO FOOBAR", "STARTTLS", "QUIT"];
+ * runClientMockup(25, "mail.hot.ee", cmds, function(resp){
+ * console.log("Final:", resp.toString("utf-8").trim());
+ * });
+ * </pre>
+ *
+ * @memberOf mockup
+ * @param {Number} port Port number
+ * @param {String} host Hostname to connect to
+ * @param {Array} commands Command list to be sent to server
+ * @param {Function} callback Callback function to run on completion,
+ * has the last response from the server as a param
+ * @param {Boolean} [debug] if set to true log all input/output
+ */
+function runClientMockup(port, host, commands, callback, debug){
+ host = host || "localhost";
+ port = port || 25;
+ commands = Array.isArray(commands) ? commands : [];
+
+ var command, ignore_data = false, sslcontext, pair;
+
+ var socket = net.connect(port, host);
+ socket.on("connect", function(){
+ socket.on("data", function(chunk){
+ if(ignore_data)return;
+
+ if(debug){
+ console.log("S: "+chunk.toString("utf-8").trim());
+ }
+
+ if(!commands.length){
+ socket.end();
+ if(typeof callback == "function"){
+ callback(chunk);
+ }
+ return;
+ }
+
+ if(["STARTTLS", "STLS"].indexOf((command || "").trim().toUpperCase())>=0){
+ ignore_data = true;
+ if(debug){
+ console.log("Initiated TLS connection");
+ }
+ sslcontext = crypto.createCredentials();
+ pair = tlslib.createSecurePair(sslcontext, false);
+
+ pair.encrypted.pipe(socket);
+ socket.pipe(pair.encrypted);
+ pair.fd = socket.fd;
+
+ pair.on("secure", function(){
+ if(debug){
+ console.log("TLS connection secured");
+ }
+ command = commands.shift();
+ if(debug){
+ console.log("C: "+command);
+ }
+ pair.cleartext.write(command+"\r\n");
+
+ pair.cleartext.on("data", function(chunk){
+ if(debug){
+ console.log("S: "+chunk.toString("utf-8").trim());
+ }
+
+ if(!commands.length){
+ pair.cleartext.end();
+ if(typeof callback == "function"){
+ callback(chunk);
+ }
+ return;
+ }
+ command = commands.shift();
+ pair.cleartext.write(command+"\r\n");
+ if(debug){
+ console.log("C: "+command);
+ }
+ });
+ });
+ }else{
+ command = commands.shift();
+ socket.write(command+"\r\n");
+ if(debug){
+ console.log("C: "+command);
+ }
+ }
+ });
+ });
+
+} \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/rai.js b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/rai.js
new file mode 100644
index 0000000..d472063
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/rai.js
@@ -0,0 +1,489 @@
+/**
+ * @fileOverview This is the main file for the RAI library to create text based servers
+ * @author <a href="mailto:andris@node.ee">Andris Reinman</a>
+ * @version 0.1.3
+ */
+
+var netlib = require("net"),
+ utillib = require("util"),
+ EventEmitter = require('events').EventEmitter,
+ starttls = require("./starttls").starttls,
+ tlslib = require("tls"),
+ crypto = require("crypto"),
+ fs = require("fs");
+
+// Default credentials for starting TLS server
+var defaultCredentials = {
+ key: fs.readFileSync(__dirname+"/../cert/key.pem"),
+ cert: fs.readFileSync(__dirname+"/../cert/cert.pem")
+};
+
+// Expose to the world
+module.exports.RAIServer = RAIServer;
+module.exports.runClientMockup = require("./mockup");
+
+/**
+ * <p>Creates instance of RAIServer</p>
+ *
+ * <p>Options object has the following properties:</p>
+ *
+ * <ul>
+ * <li><b>debug</b> - if set to true print traffic to console</li>
+ * <li><b>disconnectOnTimeout</b> - if set to true close the connection on disconnect</li>
+ * <li><b>secureConnection</b> - if set to true close the connection on disconnect</li>
+ * <li><b>credentials</b> - credentials for secureConnection and STARTTLS</li>
+ * <li><b>timeout</b> - timeout in milliseconds for disconnecting the client,
+ * defaults to 0 (no timeout)</li>
+ * </ul>
+ *
+ * <p><b>Events</b></p>
+ *
+ * <ul>
+ * <li><b>'connect'</b> - emitted if a client connects to the server, param
+ * is a client ({@link RAISocket}) object</li>
+ * <li><b>'error'</b> - emitted on error, has an error object as a param</li>
+ * </ul>
+ *
+ * @constructor
+ * @param {Object} [options] Optional options object
+ */
+function RAIServer(options){
+ EventEmitter.call(this);
+
+ this.options = options || {};
+
+ this._createServer();
+}
+utillib.inherits(RAIServer, EventEmitter);
+
+/**
+ * <p>Starts listening on selected port</p>
+ *
+ * @param {Number} port The port to listen
+ * @param {String} [host] The IP address to listen
+ * @param {Function} callback The callback function to be run after the server
+ * is listening, the only param is an error message if the operation failed
+ */
+RAIServer.prototype.listen = function(port, host, callback){
+ if(!callback && typeof host=="function"){
+ callback = host;
+ host = undefined;
+ }
+ this._port = port;
+ this._host = host;
+
+ this._connected = false;
+ if(callback){
+ this._server.on("listening", (function(){
+ this._connected = true;
+ callback(null);
+ }).bind(this));
+
+ this._server.on("error", (function(err){
+ if(!this._connected){
+ callback(err);
+ }
+ }).bind(this));
+ }
+
+ this._server.listen(this._port, this._host);
+};
+
+/**
+ * <p>Stops the server</p>
+ *
+ * @param {Function} callback Is run when the server is closed
+ */
+RAIServer.prototype.end = function(callback){
+ this._server.on("close", callback);
+ this._server.close();
+};
+
+/**
+ * <p>Creates a server with listener callback</p>
+ */
+RAIServer.prototype._createServer = function(){
+ if(this.options.secureConnection){
+ this._server = tlslib.createServer(
+ this.options.credentials || defaultCredentials,
+ this._serverListener.bind(this));
+ }else{
+ this._server = netlib.createServer(this._serverListener.bind(this));
+ }
+ this._server.on("error", this._onError.bind(this));
+};
+
+/**
+ * <p>Listens for errors</p>
+ *
+ * @event
+ * @param {Object} err Error object
+ */
+RAIServer.prototype._onError = function(err){
+ if(this._connected){
+ this.emit("error", err);
+ }
+};
+
+/**
+ * <p>Server listener that is run on client connection</p>
+ *
+ * <p>{@link RAISocket} object instance is created based on the client socket
+ * and a <code>'connection'</code> event is emitted</p>
+ *
+ * @param {Object} socket The socket to the client
+ */
+RAIServer.prototype._serverListener = function(socket){
+ if(this.options.debug){
+ console.log("CONNECTION FROM "+socket.remoteAddress);
+ }
+
+ var handler = new RAISocket(socket, this.options);
+
+ socket.on("data", handler._onReceiveData.bind(handler));
+ socket.on("end", handler._onEnd.bind(handler));
+ socket.on("error", handler._onError.bind(handler));
+ socket.on("timeout", handler._onTimeout.bind(handler));
+ socket.on("close", handler._onClose.bind(handler));
+
+ if("setKeepAlive" in socket){
+ socket.setKeepAlive(true); // plaintext server
+ }else if(socket.encrypted && "setKeepAlive" in socket.encrypted){
+ socket.encrypted.setKeepAlive(true); // secure server
+ }
+
+ this.emit("connect", handler);
+};
+
+/**
+ * <p>Creates a instance for interacting with a client (socket)</p>
+ *
+ * <p>Optional options object is the same that is passed to the parent
+ * {@link RAIServer} object</p>
+ *
+ * <p><b>Events</b></p>
+ *
+ * <ul>
+ * <li><b>'command'</b> - emitted if a client sends a command. Gets two
+ * params - command (String) and payload (Buffer)</li>
+ * <li><b>'data'</b> - emitted when a chunk is received in data mode, the
+ * param being the payload (Buffer)</li>
+ * <li><b>'ready'</b> - emitted when data stream ends and normal command
+ * flow is recovered</li>
+ * <li><b>'tls'</b> - emitted when the connection is secured by TLS</li>
+ * <li><b>'error'</b> - emitted when an error occurs. Connection to the
+ * client is disconnected automatically. Param is an error object.</l>
+ * <li><b>'timeout'</b> - emitted when a timeout occurs. Connection to the
+ * client is disconnected automatically if disconnectOnTimeout option
+ * is set to true.</l>
+ * <li><b>'end'</b> - emitted when the client disconnects</l>
+ * </ul>
+ *
+ * @constructor
+ * @param {Object} socket Socket for the client
+ * @param {Object} [options] Optional options object
+ */
+function RAISocket(socket, options){
+ EventEmitter.call(this);
+
+ this.socket = socket;
+ this.options = options || {};
+
+ this.remoteAddress = socket.remoteAddress;
+
+ this._dataMode = false;
+ this._endDataModeSequence = "\r\n.\r\n";
+ this._endDataModeSequenceRegEx = /\r\n\.\r\n|^\.\r\n/;
+
+ this.secureConnection = !!this.options.secureConnection;
+ this._destroyed = false;
+ this._remainder = "";
+
+ this._ignore_data = false;
+
+ if(this.options.timeout){
+ socket.setTimeout(this.options.timeout);
+ }
+}
+utillib.inherits(RAISocket, EventEmitter);
+
+/**
+ * <p>Sends some data to the client. <code>&lt;CR&gt;&lt;LF&gt;</code> is automatically appended to
+ * the data</p>
+ *
+ * @param {String|Buffer} data Data to be sent to the client
+ */
+RAISocket.prototype.send = function(data){
+ var buffer;
+ if(data instanceof Buffer || (typeof SlowBuffer != "undefined" && data instanceof SlowBuffer)){
+ buffer = new Buffer(data.length+2);
+ buffer[buffer.length-2] = 0xD;
+ buffer[buffer.length-1] = 0xA;
+ data.copy(buffer);
+ }else{
+ buffer = new Buffer((data || "").toString()+"\r\n", "binary");
+ }
+
+ if(this.options.debug){
+ console.log("OUT: \"" +buffer.toString("utf-8").trim()+"\"");
+ }
+
+ if(this.socket && this.socket.writable){
+ this.socket.write(buffer);
+ }else{
+ this.socket.end();
+ }
+};
+
+/**
+ * <p>Instructs the server to be listening for mixed data instead of line based
+ * commands</p>
+ *
+ * @param {String} [sequence="."] - optional sequence on separate line for
+ * matching the data end
+ */
+RAISocket.prototype.startDataMode = function(sequence){
+ this._dataMode = true;
+ if(sequence){
+ sequence = sequence.replace(/\.\=\(\)\-\?\*\\\[\]\^\+\:\|\,/g, "\\$1");
+ this._endDataModeSequence = "\r\n"+sequence+"\r\n";
+ this._endDataModeSequenceRegEx = new RegExp("/\r\n"+sequence+"\r\n|^"+sequence+"\r\n/");
+ }
+};
+
+/**
+ * <p>Instructs the server to upgrade the connection to secure TLS connection</p>
+ *
+ * <p>Fires <code>callback</code> on successful connection upgrade if set,
+ * otherwise emits <code>'tls'</code></p>
+ *
+ * @param {Object} [credentials] An object with PEM encoded key and
+ * certificate <code>{key:"---BEGIN...", cert:"---BEGIN..."}</code>,
+ * if not set autogenerated values will be used.
+ * @param {Function} [callback] If calback is set fire it after successful connection
+ * upgrade, otherwise <code>'tls'</code> is emitted
+ */
+RAISocket.prototype.startTLS = function(credentials, callback){
+
+ if(this.secureConnection){
+ return this._onError(new Error("Secure connection already established"));
+ }
+
+ if(!callback && typeof credentials == "function"){
+ callback = credentials;
+ credentials = undefined;
+ }
+
+ credentials = credentials || this.options.credentials || defaultCredentials;
+
+ this._ignore_data = true;
+
+ var secure_connector = starttls(this.socket, credentials, (function(ssl_socket){
+
+ if(this.options.debug && !ssl_socket.authorized){
+ console.log("WARNING: TLS ERROR ("+ssl_socket.authorizationError+")");
+ }
+
+ this._remainder = "";
+ this._ignore_data = false;
+
+ this.secureConnection = true;
+
+ this.socket = ssl_socket;
+ this.socket.on("data", this._onReceiveData.bind(this));
+
+ if(this.options.debug){
+ console.log("TLS CONNECTION STARTED");
+ }
+
+ if(callback){
+ callback();
+ }else{
+ this.emit("tls");
+ }
+
+ }).bind(this));
+
+ secure_connector.on("error", (function(err){
+ this._onError(err);
+ }).bind(this));
+};
+
+/**
+ * <p>Closes the connection to the client</p>
+ */
+RAISocket.prototype.end = function(){
+ this.socket.end();
+};
+
+/**
+ * <p>Called when a chunk of data arrives from the client. If currently in data
+ * mode, transmit the data otherwise send it to <code>_processData</code></p>
+ *
+ * @event
+ * @param {Buffer|String} chunk Data sent by the client
+ */
+RAISocket.prototype._onReceiveData = function(chunk){
+
+ if(this._ignore_data){ // if currently setting up TLS connection
+ return;
+ }
+
+ var str = typeof chunk=="string"?chunk:chunk.toString("binary"),
+ dataEndMatch, dataRemainderMatch, data, match;
+
+ if(this._dataMode){
+
+ str = this._remainder + str;
+ if((dataEndMatch = str.match(/\r\n.*?$/))){
+ // if ther's a line that is not ended, keep it for later
+ this._remainder = str.substr(dataEndMatch.index);
+ str = str.substr(0, dataEndMatch.index);
+ }else{
+ this._remainder = "";
+ }
+
+ // check if a data end sequence is found from the data
+ if((dataRemainderMatch = (str+this._remainder).match(this._endDataModeSequenceRegEx))){
+ str = str + this._remainder;
+ // if the sequence is not on byte 0 emit remaining data
+ if(dataRemainderMatch.index){
+ data = new Buffer(str.substr(0, dataRemainderMatch.index), "binary");
+ if(this.options.debug){
+ console.log("DATA:", data.toString("utf-8"));
+ }
+ this.emit("data", data);
+ }
+ // emit data ready
+ this._remainder = "";
+ this.emit("ready");
+ this._dataMode = false;
+ // send the remaining data for processing
+ this._processData(str.substr(dataRemainderMatch.index + dataRemainderMatch[0].length)+"\r\n");
+ }else{
+ // check if there's not something in the end of the data that resembles
+ // end sequence - if so, cut it off and save it to the remainder
+ str = str + this._remainder;
+ this._remainder= "";
+ for(var i = Math.min(this._endDataModeSequence.length-1, str.length); i>0; i--){
+ match = this._endDataModeSequence.substr(0, i);
+ if(str.substr(-match.length) == match){
+ this._remainder = str.substr(-match.length);
+ str = str.substr(0, str.length - match.length);
+ }
+ }
+
+ // if there's some data leht, emit it
+ if(str.length){
+ data = new Buffer(str, "binary");
+ if(this.options.debug){
+ console.log("DATA:", data.toString("utf-8"));
+ }
+ this.emit("data", data);
+ }
+ }
+ }else{
+ // Not in data mode, process as command
+ this._processData(str);
+ }
+};
+
+/**
+ * <p>Processed incoming command lines and emits found data as
+ * <code>'command'</code> with the command name as the first param and the rest
+ * of the data as second (Buffer)</p>
+ *
+ * @param {String} str Binary string to be processed
+ */
+RAISocket.prototype._processData = function(str){
+ if(!str.length){
+ return;
+ }
+ var lines = (this._remainder+str).split("\r\n"),
+ match, command;
+
+ this._remainder = lines.pop();
+
+ for(var i=0, len = lines.length; i<len; i++){
+ if(this._ignore_data){
+ // If TLS upgrade is initiated do not process current buffer
+ this._remainder = "";
+ break;
+ }
+ if(!this._dataMode){
+ if((match = lines[i].match(/\s*[\S]+\s?/))){
+ command = (match[0] || "").trim();
+ if(this.options.debug){
+ console.log("COMMAND:", lines[i]);
+ }
+ this.emit("command", command, new Buffer(lines[i].substr(match.index + match[0].length), "binary"));
+ }
+ }else{
+ if(this._remainder){
+ this._remainder += "\r\n";
+ }
+ this._onReceiveData(lines.slice(i).join("\r\n"));
+ break;
+ }
+ }
+};
+
+/**
+ * <p>Called when the connection is or is going to be ended</p>
+ */
+RAISocket.prototype._destroy = function(){
+ if(this._destroyed)return;
+ this._destroyed = true;
+
+ this.removeAllListeners();
+};
+
+/**
+ * <p>Called when the connection is ended. Emits <code>'end'</code></p>
+ *
+ * @event
+ */
+RAISocket.prototype._onEnd = function(){
+ this.emit("end");
+ this._destroy();
+};
+
+/**
+ * <p>Called when an error has appeared. Emits <code>'error'</code> with
+ * the error object as a parameter.</p>
+ *
+ * @event
+ * @param {Object} err Error object
+ */
+RAISocket.prototype._onError = function(err){
+ this.emit("error", err);
+ this._destroy();
+};
+
+/**
+ * <p>Called when a timeout has occured. Connection will be closed and
+ * <code>'timeout'</code> is emitted.</p>
+ *
+ * @event
+ */
+RAISocket.prototype._onTimeout = function(){
+ if(this.options.disconnectOnTimeout){
+ if(this.socket && !this.socket.destroyed){
+ this.socket.end();
+ }
+ this.emit("timeout");
+ this._destroy();
+ }else{
+ this.emit("timeout");
+ }
+};
+
+/**
+ * <p>Called when the connection is closed</p>
+ *
+ * @event
+ * @param {Boolean} hadError did the connection end because of an error?
+ */
+RAISocket.prototype._onClose = function(hadError){
+ this._destroy();
+}; \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/starttls.js b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/starttls.js
new file mode 100644
index 0000000..b17dc65
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/starttls.js
@@ -0,0 +1,113 @@
+// SOURCE: https://gist.github.com/848444
+
+// Target API:
+//
+// var s = require('net').createStream(25, 'smtp.example.com');
+// s.on('connect', function() {
+// require('starttls')(s, options, function() {
+// if (!s.authorized) {
+// s.destroy();
+// return;
+// }
+//
+// s.end("hello world\n");
+// });
+// });
+//
+//
+
+/**
+ * @namespace STARTTLS module
+ * @name starttls
+ */
+module.exports.starttls = starttls;
+
+/**
+ * <p>Upgrades a socket to a secure TLS connection</p>
+ *
+ * @memberOf starttls
+ * @param {Object} socket Plaintext socket to be upgraded
+ * @param {Object} options Certificate data for the server
+ * @param {Function} callback Callback function to be run after upgrade
+ */
+function starttls(socket, options, callback) {
+ var sslcontext, pair, cleartext;
+
+ socket.removeAllListeners("data");
+ sslcontext = require('crypto').createCredentials(options);
+ pair = require('tls').createSecurePair(sslcontext, true);
+ cleartext = pipe(pair, socket);
+
+ pair.on('secure', function() {
+ var verifyError = (pair._ssl || pair.ssl).verifyError();
+
+ if (verifyError) {
+ cleartext.authorized = false;
+ cleartext.authorizationError = verifyError;
+ } else {
+ cleartext.authorized = true;
+ }
+
+ callback(cleartext);
+ });
+
+ cleartext._controlReleased = true;
+ return pair;
+}
+
+function forwardEvents(events, emitterSource, emitterDestination) {
+ var map = [], name, handler;
+
+ for(var i = 0, len = events.length; i < len; i++) {
+ name = events[i];
+
+ handler = forwardEvent.bind(emitterDestination, name);
+
+ map.push(name);
+ emitterSource.on(name, handler);
+ }
+
+ return map;
+}
+
+function forwardEvent() {
+ this.emit.apply(this, arguments);
+}
+
+function removeEvents(map, emitterSource) {
+ for(var i = 0, len = map.length; i < len; i++){
+ emitterSource.removeAllListeners(map[i]);
+ }
+}
+
+function pipe(pair, socket) {
+ pair.encrypted.pipe(socket);
+ socket.pipe(pair.encrypted);
+
+ pair.fd = socket.fd;
+
+ var cleartext = pair.cleartext;
+
+ cleartext.socket = socket;
+ cleartext.encrypted = pair.encrypted;
+ cleartext.authorized = false;
+
+ function onerror(e) {
+ if (cleartext._controlReleased) {
+ cleartext.emit('error', e);
+ }
+ }
+
+ var map = forwardEvents(["timeout", "end", "close", "drain", "error"], socket, cleartext);
+
+ function onclose() {
+ socket.removeListener('error', onerror);
+ socket.removeListener('close', onclose);
+ removeEvents(map,socket);
+ }
+
+ socket.on('error', onerror);
+ socket.on('close', onclose);
+
+ return cleartext;
+} \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/package.json b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/package.json
new file mode 100644
index 0000000..7ff1a25
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/package.json
@@ -0,0 +1,41 @@
+{
+ "name": "rai",
+ "description": "Request-Answer-Interface for generating text based command servers (SMTP, POP etc)",
+ "version": "0.1.6",
+ "author": {
+ "name": "Andris Reinman"
+ },
+ "maintainers": [
+ {
+ "name": "andris",
+ "email": "andris@node.ee"
+ }
+ ],
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/andris9/rai.git"
+ },
+ "scripts": {
+ "test": "node ./run_tests.js"
+ },
+ "main": "./lib/rai",
+ "licenses": [
+ {
+ "type": "MIT",
+ "url": "http://github.com/andris9/rai/blob/master/LICENSE"
+ }
+ ],
+ "devDependencies": {
+ "nodeunit": "*"
+ },
+ "engines": [
+ "node >=0.4.0"
+ ],
+ "keywords": [
+ "servers",
+ "text-based"
+ ],
+ "readme": "# RAI - Request-Answer-Interface\n\n**rai** is a node.js module to easily generate text based command line servers.\nWhen a client sends something to the server, the first word of the line is\ntreated as a command and the rest of the line as binary payload.\n\n[![Build Status](https://secure.travis-ci.org/andris9/rai.png)](http://travis-ci.org/andris9/rai)\n\nIn addition to line based commands, there's also a data mode, to transmit\neverygting received. And there's also an option to switch to TLS mode for\nsecure connections.\n\nThis way it is trivial to create SMTP, POP3 or similar servers.\n\n## Documentation\n\nAutogenerated docs can be seen [here](http://node.ee/raidoc/).\n\n## Installation\n\n npm install rai\n \n## Usage\n\n### Simple server\n\n var RAIServer = require(\"rai\").RAIServer;\n \n // create a RAIServer on port 1234\n var server = new RAIServer();\n server.listen(1234);\n \n // Start listening for client connections\n server.on(\"connect\", function(client){\n \n // Greet the client\n client.send(\"Hello!\");\n \n // Wait for a command\n client.on(\"command\", function(command, payload){\n \n if(command == \"STATUS\"){\n client.send(\"Status is OK!\");\n }else if(command == \"QUIT\"){\n client.send(\"Goodbye\");\n client.end();\n }else{\n client.send(\"Unknown command\");\n }\n \n });\n \n });\n\nServer only emits `'connect'` and `'error'` events, while the client \nobjects emit `'timeout'`, `'error'` and `'end'` in addition to data \nrelated events.\n\n### Starting a server\n\nServer can be started with `new RAIServer([options])` where options is an optional\nparameters object with the following properties:\n\n * **debug** - if set to true print traffic to console\n * **disconnectOnTimeout** - if set to true close the connection on disconnect\n * **secureConnection** - if set to true close the connection on disconnect\n * **credentials** - credentials for secureConnection and STARTTLS\n * **timeout** - timeout in milliseconds for disconnecting the client, defaults to 0 (no timeout)\n \nOnce the server has been set up, it can start listening for client connections\nwith `server.listen(port[, hostname][, callback])`. Callback function gets an error\nobject as a parameter if the listening failed.\n\n var server = new RAIServer();\n server.listen(25); // start listening for port 25 on \"localhost\"\n\n### Closing server\n\nServer can be closed with `server.end([callback])` where callback is run when\nthe server is finally closed.\n\n### Sending data\n\nData can be sent with `client.send(data)` where `data` is either a String or\na Buffer. `\"\\r\\n\"` is automatically appended to the data.\n\n client.send(\"Greetings!\");\n\n### Forcing connection close\n\nConnections can be ended with `client.end()`\n\n if(command == \"QUIT\"){\n client.send(\"Good bye!\");\n client.end();\n }\n\n### TLS mode\n\nTLS can be switched on with `client.startTLS([credentials][, callback])` and the status can\nbe listened with `'tls'` (emitted when secure connection is established)\n\n`credentials` is an object with strings of pem encoded `key`, `cert` and optionally an\narray `ca`. If `credentials` is not supplied, an autogenerated value is used.\n\n if(command == \"STARTTLS\"){\n client.startTLS();\n }\n \n client.on(\"tls\", function(){\n console.log(\"Switched to secure connection\");\n });\n\nIf `callback` is not set `'tls'` will be emitted on connection upgrade.\n\n### Data mode\n\nData mode can be turned on with `client.startDataMode([endSequence])` and incoming\nchunks can be received with `'data'`. The end of data mode can be detected by\n`'ready'`.\n\n`endSequence` is a String for matching the end (entire line) of the data stream.\nBy default it's `\".\"` which is suitable for SMTP and POP3.\n\n if(command == \"DATA\"){\n client.send(\"End data with <CR><LF>.<CR><LF>\");\n client.startDataMode();\n }\n\n client.on(\"data\", function(chunk){\n console.log(\"Data from client:\", chunk);\n });\n \n client.on(\"ready\", function(){\n client.send(\"Data received\");\n });\n\n## Testing\n\nThere is a possibility to set up a mockup client which sends a batch of commands\none by one to the server and returns the last response.\n\n var runClientMockup = require(\"rai\").runClientMockup;\n \n var cmds = [\"EHLO FOOBAR\", \"STARTTLS\", \"QUIT\"];\n runClientMockup(25, \"mail.hot.ee\", cmds, function(resp){\n console.log(\"Final:\", resp.toString(\"utf-8\").trim());\n });\n\n`runClientMockup` has he following parameters in the following order:\n\n * **port** - Port number\n * **host** - Hostname to connect to\n * **commands** - Command list (an array) to be sent to server\n * **callback** - Callback function to run on completion\n * **debug** - if set to true log all input/output\n\nResponse from the callback function is a Buffer and contains the\nlast data received from the server\n\n## License\n\n**MIT**",
+ "_id": "rai@0.1.6",
+ "_from": "rai@*"
+}
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/run_tests.js b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/run_tests.js
new file mode 100644
index 0000000..9446683
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/run_tests.js
@@ -0,0 +1,2 @@
+var reporter = require('nodeunit').reporters["default"];
+reporter.run(['test']); \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/test/rai.js b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/test/rai.js
new file mode 100644
index 0000000..a1af00b
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/test/rai.js
@@ -0,0 +1,589 @@
+var RAIServer = require("../lib/rai").RAIServer,
+ testCase = require('nodeunit').testCase,
+ utillib = require("util"),
+ netlib = require("net"),
+ crypto = require("crypto"),
+ tlslib = require("tls");
+
+var PORT_NUMBER = 8397;
+
+// monkey patch net and tls to support nodejs 0.4
+if(!netlib.connect && netlib.createConnection){
+ netlib.connect = netlib.createConnection;
+}
+
+if(!tlslib.connect && tlslib.createConnection){
+ tlslib.connect = tlslib.createConnection;
+}
+
+exports["General tests"] = {
+ "Create and close a server": function(test){
+ var server = new RAIServer();
+ server.listen(PORT_NUMBER, function(err){
+ test.ifError(err);
+ server.end(function(){
+ test.ok(1, "Server closed");
+ test.done();
+ });
+ });
+ },
+ "Create a secure server": function(test){
+ var server = new RAIServer({secureConnection: true});
+ server.listen(PORT_NUMBER, function(err){
+ test.ifError(err);
+ server.end(function(){
+ test.ok(1, "Server closed");
+ test.done();
+ });
+ });
+ },
+ "Duplicate server fails": function(test){
+ var server = new RAIServer();
+ server.listen(PORT_NUMBER, function(err){
+ test.ifError(err);
+
+ var duplicate = new RAIServer();
+ duplicate.listen(PORT_NUMBER, function(err){
+ test.ok(err, "Responds with error");
+ server.end(function(){
+ test.ok(1, "Server closed");
+ test.done();
+ });
+ });
+
+ });
+ },
+ "Connection event": function(test){
+ var server = new RAIServer();
+ test.expect(3);
+ server.listen(PORT_NUMBER, function(err){
+
+ server.on("connect", function(socket){
+ test.ok(socket, "Client connected");
+
+ socket.on("end", function(){
+ test.ok(1, "Connection closed");
+
+ server.end(function(){
+ test.done();
+ });
+ });
+
+ socket.on("error", function(err){
+ test.isError(err);
+ });
+ });
+
+ var client = netlib.connect(PORT_NUMBER, function(){
+ test.ok(1, "Connected to server");
+ client.end();
+ });
+
+ });
+ },
+ "Close client socket": function(test){
+ var server = new RAIServer();
+ test.expect(4);
+ server.listen(PORT_NUMBER, function(err){
+
+ server.on("connect", function(socket){
+ test.ok(socket, "Client connected");
+
+ socket.on("end", function(){
+ test.ok(1, "Connection closed");
+
+ server.end(function(){
+ test.done();
+ });
+ });
+
+ socket.on("error", function(err){
+ test.isError(err);
+ });
+
+ socket.end();
+ });
+
+ var client = netlib.connect(PORT_NUMBER, function(){
+ test.ok(1, "Connected to server");
+ });
+ client.on("end", function(){
+ test.ok(1, "Connection closed by host");
+ });
+
+ });
+ },
+ "Send data to client": function(test){
+ var server = new RAIServer();
+ server.listen(PORT_NUMBER, function(err){
+
+ server.on("connect", function(socket){
+
+ socket.send("HELLO");
+
+ socket.on("end", function(){
+ server.end(function(){
+ test.done();
+ });
+ });
+
+ socket.on("error", function(err){
+ test.isError(err);
+ });
+ });
+
+ var client = netlib.connect(PORT_NUMBER, function(){
+ client.on("data", function(chunk){
+ test.equal(chunk.toString(), "HELLO\r\n");
+ client.end();
+ });
+ });
+
+ });
+ }
+};
+
+exports["Secure connection"] = {
+ "STARTTLS with event": function(test){
+ var server = new RAIServer();
+ server.listen(PORT_NUMBER, function(err){
+
+ test.expect(2);
+
+ server.on("connect", function(socket){
+
+ socket.startTLS();
+ socket.on("tls", function(){
+ test.ok(1, "Secure connection opened");
+ socket.send("TEST");
+ });
+
+ socket.on("end", function(){
+ server.end(function(){
+ test.done();
+ });
+ });
+
+ socket.on("error", function(err){
+ test.isError(err);
+ });
+ });
+
+ var client = netlib.connect(PORT_NUMBER, function(){
+ var sslcontext = crypto.createCredentials();
+ var pair = tlslib.createSecurePair(sslcontext, false);
+
+ pair.encrypted.pipe(client);
+ client.pipe(pair.encrypted);
+ pair.fd = client.fd;
+
+ pair.on("secure", function(){
+ pair.cleartext.on("data", function(chunk){
+ test.equal(chunk.toString(), "TEST\r\n");
+ pair.cleartext.end();
+ });
+ });
+ });
+
+ });
+ },
+ "STARTTLS Callback": function(test){
+ var server = new RAIServer();
+ server.listen(PORT_NUMBER, function(err){
+
+ test.expect(2);
+
+ server.on("connect", function(socket){
+
+ socket.startTLS(function(){
+ test.ok(1, "Secure connection opened");
+ socket.send("TEST");
+ });
+
+ socket.on("tls", function(){
+ test.ok(0, "Should not occur");
+ });
+
+ socket.on("end", function(){
+ server.end(function(){
+ test.done();
+ });
+ });
+
+ socket.on("error", function(err){
+ test.isError(err);
+ });
+ });
+
+ var client = netlib.connect(PORT_NUMBER, function(){
+ var sslcontext = crypto.createCredentials();
+ var pair = tlslib.createSecurePair(sslcontext, false);
+
+ pair.encrypted.pipe(client);
+ client.pipe(pair.encrypted);
+ pair.fd = client.fd;
+
+ pair.on("secure", function(){
+ pair.cleartext.on("data", function(chunk){
+ test.equal(chunk.toString(), "TEST\r\n");
+ pair.cleartext.end();
+ });
+ });
+ });
+
+ });
+ },
+ "STARTTLS clears command buffer": function(test){
+ var server = new RAIServer();
+ server.listen(PORT_NUMBER, function(err){
+
+ test.expect(2);
+
+ server.on("connect", function(socket){
+
+ socket.on("command", function(command){
+ if(command == "STARTTLS"){
+ socket.startTLS();
+ socket.send("OK");
+ }else if(command == "KILL"){
+ test.ok(0, "Should not occur");
+ }else if(command == "OK"){
+ test.ok(1, "OK");
+ }
+
+ });
+
+ socket.on("tls", function(){
+ test.ok(1, "Secure connection opened");
+ socket.send("TEST");
+ });
+
+ socket.on("end", function(){
+ server.end(function(){
+ test.done();
+ });
+ });
+
+ socket.on("error", function(err){
+ test.isError(err);
+ });
+ });
+
+ var client = netlib.connect(PORT_NUMBER, function(){
+
+ client.write("STARTTLS\r\nKILL\r\n");
+
+ client.on("data", function(chunk){
+ if(chunk.toString("utf-8").trim() == "OK"){
+ var sslcontext = crypto.createCredentials();
+ var pair = tlslib.createSecurePair(sslcontext, false);
+
+ pair.encrypted.pipe(client);
+ client.pipe(pair.encrypted);
+ pair.fd = client.fd;
+
+ pair.on("secure", function(){
+ pair.cleartext.write("OK\r\n");
+ pair.cleartext.end();
+ });
+ }
+ });
+
+ });
+
+ });
+ },
+ "STARTTLS on secure server fails": function(test){
+ var server = new RAIServer({secureConnection: true});
+ server.listen(PORT_NUMBER, function(err){
+
+ test.expect(2);
+ server.on("connect", function(socket){
+
+ socket.on("error", function(err){
+ test.ok(err);
+ socket.end();
+ server.end(function(){
+ test.done();
+ });
+ });
+
+ socket.on("command", (function(command){
+ process.nextTick(socket.startTLS.bind(socket, function(){
+ test.ok(false, "Secure connection opened"); // should not occur
+ server.end(function(){
+ test.done();
+ });
+ }));
+
+ }).bind(this));
+
+ socket.on("tls", function(){
+ test.ok(0, "Should not occur");
+ });
+
+ });
+
+ var client = tlslib.connect(PORT_NUMBER, function(){
+ test.ok(true);
+ client.write("HELLO!\r\n");
+ });
+
+ });
+ }
+};
+
+exports["Client commands"] = {
+ "Receive Simple Command": function(test){
+ var server = new RAIServer();
+ server.listen(PORT_NUMBER, function(err){
+
+ server.on("connect", function(socket){
+
+ socket.on("command", function(command, payload){
+ test.equal(command, "STATUS");
+ test.equal(payload.toString(), "");
+ socket.end();
+ server.end(function(){
+ test.done();
+ });
+ });
+
+ socket.on("error", function(err){
+ test.isError(err);
+ });
+ });
+
+ var client = netlib.connect(PORT_NUMBER, function(){
+ client.write("STATUS\r\n");
+ });
+
+ });
+ },
+ "Receive Command with payload": function(test){
+ var server = new RAIServer();
+ server.listen(PORT_NUMBER, function(err){
+
+ server.on("connect", function(socket){
+
+ socket.on("command", function(command, payload){
+ test.equal(command, "MAIL");
+ test.equal(payload.toString(), "TO:");
+ socket.end();
+
+ server.end(function(){
+ test.done();
+ });
+ });
+
+ socket.on("error", function(err){
+ test.isError(err);
+ });
+ });
+
+ var client = netlib.connect(PORT_NUMBER, function(){
+ client.write("MAIL TO:\r\n");
+ });
+
+ });
+ }
+};
+
+exports["Data mode"] = {
+ "DATA mode": function(test){
+ var server = new RAIServer(),
+ datapayload = "tere\r\nvana kere";
+ server.listen(PORT_NUMBER, function(err){
+
+ server.on("connect", function(socket){
+
+ socket.startDataMode();
+
+ test.expect(2);
+
+ socket.on("data", function(chunk){
+ test.equal(datapayload, chunk.toString());
+ });
+
+ socket.on("ready", function(){
+ test.ok(1,"Data ready");
+ server.end(function(){
+ test.done();
+ });
+ });
+
+ socket.on("error", function(err){
+ test.isError(err);
+ });
+ });
+
+ var client = netlib.connect(PORT_NUMBER, function(){
+ client.write(datapayload+"\r\n.\r\n");
+ client.end();
+ });
+
+ });
+ },
+ "Small chunks DATA mode": function(test){
+ var server = new RAIServer(),
+ datapayload = "tere\r\nvana kere õäöü\r\n.\r",
+ databytes = [],
+ fullpayload = datapayload+"\r\n.\r\n";
+ server.listen(PORT_NUMBER, function(err){
+
+ server.on("connect", function(socket){
+
+ socket.startDataMode();
+
+ test.expect(1);
+
+ socket.on("data", function(chunk){
+ databytes = databytes.concat(Array.prototype.slice.call(chunk));
+ });
+
+ socket.on("ready", function(){
+ test.equal(new Buffer(databytes).toString("utf-8"), datapayload);
+ server.end(function(){
+ test.done();
+ });
+ });
+
+ socket.on("error", function(err){
+ test.isError(err);
+ });
+
+ for(var i=0, len = fullpayload.length; i<len; i++){
+ socket._onReceiveData(new Buffer(fullpayload.charAt(i), "utf-8").toString("binary"));
+ }
+
+ });
+
+ var client = netlib.connect(PORT_NUMBER, function(){
+ client.end();
+ });
+
+ });
+ }
+};
+
+exports["Pipelining support"] = {
+ "Pipelining": function(test){
+ var server = new RAIServer();
+ server.listen(PORT_NUMBER, function(err){
+
+ test.expect(8);
+
+ server.on("connect", function(socket){
+
+ socket.on("command", function(command, payload){
+ if(command == "STATUS"){
+ test.ok(1, "Status received");
+ }else if(command=="DATA"){
+ test.ok(1, "data command received");
+ socket.startDataMode();
+ }else if(command=="END"){
+ test.ok(1, "all received");
+ }else{
+ test.ok(0, "Unexpected command: "+command);
+ }
+ });
+
+ socket.on("data", function(chunk){
+ test.equal(chunk.toString(), "TE\r\nST");
+ });
+
+ socket.on("ready", function(){
+ test.ok(1, "Data mode ended");
+ });
+
+ socket.on("end", function(){
+ test.ok(1, "All ready");
+ server.end(function(){
+ test.done();
+ });
+ });
+
+ socket.on("error", function(err){
+ test.isError(err);
+ });
+ });
+
+ var client = netlib.connect(PORT_NUMBER, function(){
+ client.write("STATUS\r\nSTATUS\r\nSTATUS\r\nDATA\r\nTE\r\nST\r\n.\r\nEND\r\n");
+ client.end();
+ });
+
+ });
+ }
+};
+
+exports["Timeout tests"] = {
+ "Timeout": function(test){
+ var server = new RAIServer({timeout: 300, disconnectOnTimeout: true});
+ test.expect(3);
+ server.listen(PORT_NUMBER, function(err){
+
+ server.on("connect", function(socket){
+ test.ok(socket, "Client connected");
+
+ socket.on("timeout", function(){
+ test.ok(1, "Connection closed");
+
+ server.end(function(){
+ test.done();
+ });
+ });
+
+ socket.on("error", function(err){
+ test.isError(err);
+ });
+ });
+
+ var client = netlib.connect(PORT_NUMBER, function(){
+ test.ok(1, "Connected to server");
+ });
+
+ });
+ },
+ "Timeout with TLS": function(test){
+ var server = new RAIServer({timeout: 300, disconnectOnTimeout: true});
+ server.listen(PORT_NUMBER, function(err){
+
+ test.expect(3);
+
+ server.on("connect", function(socket){
+
+ socket.startTLS();
+ socket.on("tls", function(){
+ test.ok(1, "Secure connection opened");
+ socket.send("TEST");
+ });
+
+ socket.on("timeout", function(){
+ test.ok(1, "Timeout occurred");
+ server.end(function(){
+ test.done();
+ });
+ });
+
+ socket.on("error", function(err){
+ test.isError(err);
+ });
+ });
+
+ var client = netlib.connect(PORT_NUMBER, function(){
+ var sslcontext = crypto.createCredentials();
+ var pair = tlslib.createSecurePair(sslcontext, false);
+
+ pair.encrypted.pipe(client);
+ client.pipe(pair.encrypted);
+ pair.fd = client.fd;
+
+ pair.on("secure", function(){
+ test.ok(1, "secure connection");
+ });
+ });
+
+ });
+ }
+}; \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/package.json b/tools/node_modules/nodemailer/node_modules/simplesmtp/package.json
new file mode 100644
index 0000000..4aa7925
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/package.json
@@ -0,0 +1,52 @@
+{
+ "name": "simplesmtp",
+ "description": "Simple SMTP server module to create custom SMTP servers",
+ "version": "0.1.20",
+ "author": {
+ "name": "Andris Reinman"
+ },
+ "maintainers": [
+ {
+ "name": "andris",
+ "email": "andris@node.ee"
+ }
+ ],
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/andris9/simplesmtp.git"
+ },
+ "scripts": {
+ "test": "nodeunit test/"
+ },
+ "main": "./lib/smtp",
+ "licenses": [
+ {
+ "type": "MIT",
+ "url": "http://github.com/andris9/simplesmtp/blob/master/LICENSE"
+ }
+ ],
+ "dependencies": {
+ "rai": "*"
+ },
+ "devDependencies": {
+ "nodeunit": "*",
+ "mailcomposer": "*"
+ },
+ "engines": [
+ "node >=0.4.0"
+ ],
+ "keywords": [
+ "servers",
+ "text-based",
+ "smtp",
+ "email",
+ "mail",
+ "e-mail"
+ ],
+ "readme": "# simplesmtp\n\nThis is a module to easily create custom SMTP servers and clients - use SMTP as a first class protocol in Node.JS!\n\n[![Build Status](https://secure.travis-ci.org/andris9/simplesmtp.png)](http://travis-ci.org/andris9/simplesmtp)\n\n## Support simplesmtp development\n\n[![Donate to author](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DB26KWR2BQX5W)\n\n## SMTP Server\n\n### Usage\n\nCreate a new SMTP server instance with\n\n var smtp = simplesmtp.createServer([options]);\n \nAnd start listening on selected port\n\n smtp.listen(25, [function(err){}]);\n \nSMTP options can include the following:\n\n * **name** - the hostname of the server, will be used for informational messages\n * **debug** - if set to true, print out messages about the connection\n * **timeout** - client timeout in milliseconds, defaults to 60 000 (60 sec.)\n * **secureConnection** - start a server on secure connection\n * **SMTPBanner** - greeting banner that is sent to the client on connection\n * **requireAuthentication** - if set to true, require that the client must authenticate itself\n * **enableAuthentication** - if set to true, client may authenticate itself but don't have to (as opposed to `requireAuthentication` that explicitly requires clients to authenticate themselves)\n * **validateSender** - if set to true, emit `'validateSender'` with `envelope`, `email` and `callback` when the client enters `MAIL FROM:<address>`\n * **validateRecipients** - if set to true, emit `'validateRecipient'` with `envelope`, `email` and `callback` when the client enters `RCPT TO:<address>`\n * **maxSize** - maximum size of an e-mail in bytes (currently informational only)\n * **credentials** - TLS credentials (`{key:'', cert:'', ca:['']}`) for the server\n * **authMethods** - allowed authentication methods, defaults to `[\"PLAIN\", \"LOGIN\"]`\n * **disableEHLO** - if set to true, support HELO command only\n * **ignoreTLS** - if set to true, allow client do not use STARTTLS\n \n### Example\n\n var simplesmtp = require(\"simplesmtp\"),\n fs = require(\"fs\");\n\n var smtp = simplesmtp.createServer();\n smtp.listen(25);\n\n smtp.on(\"startData\", function(envelope){\n console.log(\"Message from:\", envelope.from);\n console.log(\"Message to:\", envelope.to);\n envelope.saveStream = fs.createWriteStream(\"/tmp/message.txt\");\n });\n \n smtp.on(\"data\", function(envelope, chunk){\n envelope.saveStream.write(chunk);\n });\n \n smtp.on(\"dataReady\", function(envelope, callback){\n envelope.saveStream.end();\n console.log(\"Incoming message saved to /tmp/message.txt\");\n callback(null, \"ABC1\"); // ABC1 is the queue id to be advertised to the client\n // callback(new Error(\"That was clearly a spam!\"));\n });\n\n\n### Events\n\n * **startData** *(envelope)* - DATA stream is opened by the client (`envelope` is an object with `from`, `to`, `host` and `remoteAddress` properties)\n * **data** *(envelope, chunk)* - e-mail data chunk is passed from the client \n * **dataReady** *(envelope, callback)* - client is finished passing e-mail data, `callback` returns the queue id to the client\n * **authorizeUser** *(envelope, username, password, callback)* - will be emitted if `requireAuthentication` option is set to true. `callback` has two parameters *(err, success)* where `success` is Boolean and should be true, if user is authenticated successfully\n * **validateSender** *(envelope, email, callback)* - will be emitted if `validateSender` option is set to true\n * **validateRecipient** *(envelope, email, callback)* - will be emitted it `validataRecipients` option is set to true\n * **close** *(envelope)* - emitted when the connection to client is closed\n \n## SMTP Client\n\n### Usage\n\nSMTP client can be created with `simplesmptp.connect(port[,host][, options])`\nwhere\n\n * **port** is the port to connect to\n * **host** is the hostname to connect to (defaults to \"localhost\")\n * **options** is an optional options object (see below)\n \n### Connection options\n\nThe following connection options can be used with `simplesmtp.connect`:\n\n * **secureConnection** - use SSL\n * **name** - the name of the client server\n * **auth** - authentication object `{user:\"...\", pass:\"...\"}` or `{XOAuthToken:\"base64data\"}`\n * **ignoreTLS** - ignore server support for STARTTLS\n * **debug** - output client and server messages to console\n * **instanceId** - unique instance id for debugging (will be output console with the messages)\n\n### Connection events\n\nOnce a connection is set up the following events can be listened to:\n\n * **'idle'** - the connection to the SMTP server has been successfully set up and the client is waiting for an envelope\n * **'message'** - the envelope is passed successfully to the server and a message stream can be started\n * **'ready'** `(success)` - the message was sent\n * **'rcptFailed'** `(addresses)` - not all recipients were accepted (invalid addresses are included as an array)\n * **'error'** `(err)` - An error occurred. The connection is closed and an 'end' event is emitted shortly\n * **'end'** - connection to the client is closed\n\n### Sending an envelope\n\nWhen an `'idle'` event is emitted, an envelope object can be sent to the server.\nThis includes a string `from` and an array of strings `to` property.\n\nEnvelope can be sent with `client.useEnvelope(envelope)`\n\n // run only once as 'idle' is emitted again after message delivery\n client.once(\"idle\", function(){\n client.useEnvelope({\n from: \"me@example.com\",\n to: [\"receiver1@example.com\", \"receiver2@example.com\"]\n });\n });\n\nThe `to` part of the envelope includes **all** recipients from `To:`, `Cc:` and `Bcc:` fields.\n\nIf setting the envelope up fails, an error is emitted. If only some (not all)\nrecipients are not accepted, the mail can still be sent but an `rcptFailed`\nevent is emitted.\n\n client.on(\"rcptFailed\", function(addresses){\n console.log(\"The following addresses were rejected: \", addresses);\n });\n\nIf the envelope is set up correctly a `'message'` event is emitted.\n\n### Sending a message\n\nWhen `'message'` event is emitted, it is possible to send mail. To do this\nyou can pipe directly a message source (for example an .eml file) to the client\nor alternatively you can send the message with `client.write` calls (you also\nneed to call `client.end()` once the message is completed.\n\nIf you are piping a stream to the client, do not leave the `'end'` event out,\nthis is needed to complete the message sequence by the client. \n\n client.on(\"message\", function(){\n fs.createReadStream(\"test.eml\").pipe(client);\n });\n\nOnce the message is delivered a `'ready'` event is emitted. The event has an\nparameter which indicates if the message was transmitted( (true) or not (false)\nand another which includes the last received data from the server.\n\n client.on(\"ready\", function(success, response){\n if(success){\n console.log(\"The message was transmitted successfully with \"+response);\n }\n });\n\n### XOAUTH\n\n**simplesmtp** supports [XOAUTH](https://developers.google.com/google-apps/gmail/oauth_protocol) authentication.\n\nTo use this feature you can set `XOAuthToken` param as an `auth` option\n\n var mailOptions = {\n ...,\n auth:{\n XOAuthToken: \"R0VUIGh0dHBzOi8vbWFpbC5nb29....\"\n }\n }\n\nAlternatively it is also possible to use XOAuthToken generators (supported by Nodemailer) - this\nneeds to be an object with a mandatory method `generate` that takes a callback function for\ngenerating a XOAUTH token string. This is better for generating tokens only when needed - \nthere is no need to calculate unique token for every e-mail request, since a lot of these\nmight share the same connection and thus the cleint needs not to re-authenticate itself\nwith another token.\n\n var XOGen = {\n token: \"abc\",\n generate: function(callback){\n if(1 != 1){\n return callback(new Error(\"Tokens can't be generated in strange environments\"));\n }\n callback(null, new Buffer(this.token, \"utf-8\").toString(\"base64\"));\n }\n }\n \n var mailOptions = {\n ...,\n auth:{\n XOAuthToken: XOGen\n }\n }\n\n### Error types\n\nEmitted errors include the reason for failing in the `name` property\n\n * **UnknowAuthError** - the client tried to authenticate but the method was not supported\n * **AuthError** - the username/password used were rejected\n * **TLSError** - STARTTLS failed\n * **SenderError** - the sender e-mail address was rejected\n * **RecipientError** - all recipients were rejected (if only some of the recipients are rejected, a `'rcptFailed'` event is raised instead\n\nThere's also an additional property in the error object called `data` that includes\nthe last response received from the server (if available for the current error type). \n\n### About reusing the connection\n\nYou can reuse the same connection several times but you can't send a mail\nthrough the same connection concurrently. So if you catch and `'idle'` event\nlock the connection to a message process and unlock after `'ready'`.\n\nOn `'error'` events you should reschedule the message and on `'end'` events\nyou should recreate the connection.\n\n### Closing the client\n\nBy default the client tries to keep the connection up. If you want to close it,\nrun `client.quit()` - this sends a `QUIT` command to the server and closes the\nconnection\n\n client.quit();\n\n## SMTP Client Connection pool\n\n**simplesmtp** has the option for connection pooling if you want to reuse a bulk\nof connections.\n\n### Usage\n\nCreate a connection pool of SMTP clients with\n\n simplesmtp.createClientPool(port[,host][, options])\n\nwhere\n\n * **port** is the port to connect to\n * **host** is the hostname to connect to (defaults to \"localhost\")\n * **options** is an optional options object (see below)\n\n### Connection options\n\nThe following connection options can be used with `simplesmtp.connect`:\n\n * **secureConnection** - use SSL\n * **name** - the name of the client server\n * **auth** - authentication object `{user:\"...\", pass:\"...\"}` or `{XOAuthToken:\"base64data\"}`\n * **ignoreTLS** - ignore server support for STARTTLS\n * **debug** - output client and server messages to console\n * **maxConnections** - how many connections to keep in the pool (defaults to 5)\n\n### Send an e-mail\n\nE-mails can be sent through the pool with\n\n pool.sendMail(mail[, callback])\n\nwhere\n\n * **mail** is a [MailComposer](/andris9/mailcomposer) compatible object\n * **callback** `(error, responseObj)` - is the callback function to run after the message is delivered or an error occured. `responseObj` may include `failedRecipients` which is an array with e-mail addresses that were rejected and `message` which is the last response from the server.\n\n### Errors\n\nIn addition to SMTP client errors another error name is used\n\n * **DeliveryError** - used if the message was not accepted by the SMTP server\n\n## License\n\n**MIT**\n\n",
+ "_id": "simplesmtp@0.1.20",
+ "dist": {
+ "shasum": "563c1a4203e1ed7f50b27108bb5881e5aa48a984"
+ },
+ "_from": "simplesmtp@>= 0.1.19"
+}
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/test/client.js b/tools/node_modules/nodemailer/node_modules/simplesmtp/test/client.js
new file mode 100644
index 0000000..a6fe624
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/test/client.js
@@ -0,0 +1,444 @@
+var testCase = require('nodeunit').testCase,
+ runClientMockup = require("rai").runClientMockup,
+ simplesmtp = require("../index"),
+ fs = require("fs");
+
+var PORT_NUMBER = 8397;
+
+
+
+exports["General tests"] = {
+ setUp: function (callback) {
+ this.server = new simplesmtp.createServer();
+ this.server.listen(PORT_NUMBER, function(err){
+ if(err){
+ throw err;
+ }else{
+ callback();
+ }
+ });
+
+ },
+
+ tearDown: function (callback) {
+ this.server.end(callback);
+ },
+
+ "Connect and setup": function(test){
+ var client = simplesmtp.connect(PORT_NUMBER);
+
+ client.once("idle", function(){
+ // Client is ready to take messages
+ test.ok(true);
+ client.close();
+ });
+
+ client.on("error", function(err){
+ test.ok(false);
+ });
+
+ client.on("end", function(){
+ test.done();
+ });
+ }
+};
+
+exports["Secure server"] = {
+ setUp: function (callback) {
+ this.server = new simplesmtp.createServer({
+ secureConnection: true
+ });
+ this.server.listen(PORT_NUMBER, function(err){
+ if(err){
+ throw err;
+ }else{
+ callback();
+ }
+ });
+
+ },
+
+ tearDown: function (callback) {
+ this.server.end(callback);
+ },
+
+ "Connect and setup": function(test){
+ var client = simplesmtp.connect(PORT_NUMBER, false, {
+ secureConnection: true
+ });
+
+ client.once("idle", function(){
+ // Client is ready to take messages
+ test.ok(true);
+ client.close();
+ });
+
+ client.on("error", function(err){
+ test.ok(false);
+ });
+
+ client.on("end", function(){
+ test.done();
+ });
+ }
+};
+
+exports["Disabled EHLO"] = {
+ setUp: function (callback) {
+ this.server = new simplesmtp.createServer({disableEHLO: true});
+ this.server.listen(PORT_NUMBER, function(err){
+ if(err){
+ throw err;
+ }else{
+ callback();
+ }
+ });
+
+ },
+
+ tearDown: function (callback) {
+ this.server.end(callback);
+ },
+
+ "Connect and setup": function(test){
+ var client = simplesmtp.connect(PORT_NUMBER, false, {});
+
+ client.once("idle", function(){
+ // Client is ready to take messages
+ test.ok(true);
+ client.close();
+ });
+
+ client.on("error", function(err){
+ test.ok(false);
+ });
+
+ client.on("end", function(){
+ test.done();
+ });
+ }
+};
+
+exports["Authentication needed"] = {
+ setUp: function (callback) {
+ this.server = new simplesmtp.createServer({
+ requireAuthentication: true
+ });
+
+ this.server.on("authorizeUser", function(envelope, user, pass, callback){
+ callback(null, user=="test1" && pass == "test2");
+ });
+
+ this.server.listen(PORT_NUMBER, function(err){
+ if(err){
+ throw err;
+ }else{
+ callback();
+ }
+ });
+
+ },
+
+ tearDown: function (callback) {
+ this.server.end(callback);
+ },
+
+ "Auth success": function(test){
+ var client = simplesmtp.connect(PORT_NUMBER, false, {
+ auth: {
+ user: "test1",
+ pass: "test2"
+ }
+ });
+
+ client.once("idle", function(){
+ // Client is ready to take messages
+ test.ok(true);
+ client.close();
+ });
+
+ client.on("error", function(err){
+ test.ok(false);
+ });
+
+ client.on("end", function(){
+ test.done();
+ });
+ },
+
+ "Auth fails": function(test){
+ var client = simplesmtp.connect(PORT_NUMBER, false, {
+ auth: {
+ user: "test3",
+ pass: "test4"
+ }
+ });
+
+ client.once("idle", function(){
+ // Client is ready to take messages
+ test.ok(false); // should not occur
+ client.close();
+ });
+
+ client.on("error", function(err){
+ test.ok(true); // login failed
+ });
+
+ client.on("end", function(){
+ test.done();
+ });
+ }
+};
+
+exports["Message tests"] = {
+ setUp: function (callback) {
+ this.server = new simplesmtp.createServer({
+ validateSender: true,
+ validateRecipients: true
+ });
+
+ this.server.on("validateSender", function(envelope, email, callback){
+ callback(email != "test@node.ee"?new Error("Failed sender") : null);
+ });
+
+ this.server.on("validateRecipient", function(envelope, email, callback){
+ callback(email.split("@").pop() != "node.ee"?new Error("Failed recipient") : null);
+ });
+
+ this.server.on("dataReady", function(envelope, callback){
+ callback(null, "ABC1"); // ABC1 is the queue id to be advertised to the client
+ // callback(new Error("That was clearly a spam!"));
+ });
+
+ this.server.listen(PORT_NUMBER, function(err){
+ if(err){
+ throw err;
+ }else{
+ callback();
+ }
+ });
+
+ },
+
+ tearDown: function (callback) {
+ this.server.end(callback);
+ },
+
+ "Set envelope success": function(test){
+ test.expect(2);
+
+ var client = simplesmtp.connect(PORT_NUMBER, false, {});
+
+ client.once("idle", function(){
+ // Client is ready to take messages
+ test.ok(true); // waiting for envelope
+
+ client.useEnvelope({
+ from: "test@node.ee",
+ to: [
+ "test1@node.ee",
+ "test2@node.ee"
+ ]
+ });
+ });
+
+ client.on("message", function(){
+ // Client is ready to take messages
+ test.ok(true); // waiting for message
+ client.close();
+ });
+
+ client.on("error", function(err){
+ test.ok(false);
+ });
+
+ client.on("end", function(){
+ test.done();
+ });
+ },
+
+ "Set envelope fails for sender": function(test){
+ test.expect(2);
+
+ var client = simplesmtp.connect(PORT_NUMBER, false, {});
+
+ client.once("idle", function(){
+ // Client is ready to take messages
+ test.ok(true); // waiting for envelope
+
+ client.useEnvelope({
+ from: "test3@node.ee",
+ to: [
+ "test1@node.ee",
+ "test2@node.ee"
+ ]
+ });
+ });
+
+ client.on("message", function(){
+ // Client is ready to take messages
+ test.ok(false); // waiting for message
+ client.close();
+ });
+
+ client.on("error", function(err){
+ test.ok(true);
+ });
+
+ client.on("end", function(){
+ test.done();
+ });
+ },
+
+ "Set envelope fails for receiver": function(test){
+ test.expect(2);
+
+ var client = simplesmtp.connect(PORT_NUMBER, false, {});
+
+ client.once("idle", function(){
+ // Client is ready to take messages
+ test.ok(true); // waiting for envelope
+
+ client.useEnvelope({
+ from: "test@node.ee",
+ to: [
+ "test1@kreata.ee",
+ "test2@kreata.ee"
+ ]
+ });
+ });
+
+ client.on("message", function(){
+ // Client is ready to take messages
+ test.ok(false); // waiting for message
+ client.close();
+ });
+
+ client.on("error", function(err){
+ test.ok(true);
+ });
+
+ client.on("end", function(){
+ test.done();
+ });
+ },
+
+ "Set envelope partly fails": function(test){
+ test.expect(3);
+
+ var client = simplesmtp.connect(PORT_NUMBER, false, {});
+
+ client.once("idle", function(){
+ // Client is ready to take messages
+ test.ok(true); // waiting for envelope
+
+ client.useEnvelope({
+ from: "test@node.ee",
+ to: [
+ "test1@node.ee",
+ "test2@kreata.ee"
+ ]
+ });
+ });
+
+ client.on("rcptFailed", function(){
+ // Client is ready to take messages
+ test.ok(true); // waiting for message
+ });
+
+ client.on("message", function(){
+ // Client is ready to take messages
+ test.ok(true); // waiting for message
+ client.close();
+ });
+
+ client.on("error", function(err){
+ test.ok(false);
+ });
+
+ client.on("end", function(){
+ test.done();
+ });
+ },
+
+ "Send message success": function(test){
+ test.expect(3);
+
+ var client = simplesmtp.connect(PORT_NUMBER, false, {});
+
+ client.once("idle", function(){
+ // Client is ready to take messages
+ test.ok(true); // waiting for envelope
+
+ client.useEnvelope({
+ from: "test@node.ee",
+ to: [
+ "test1@node.ee",
+ "test2@node.ee"
+ ]
+ });
+ });
+
+ client.on("message", function(){
+ // Client is ready to take messages
+ test.ok(true); // waiting for message
+
+ client.write("From: abc@example.com\r\nTo:cde@example.com\r\nSubject: test\r\n\r\nHello World!");
+ client.end();
+ });
+
+ client.on("ready", function(success){
+ test.ok(success);
+ client.close();
+ });
+
+ client.on("error", function(err){
+ test.ok(false);
+ });
+
+ client.on("end", function(){
+ test.done();
+ });
+ },
+
+ "Stream message": function(test){
+ test.expect(3);
+
+ var client = simplesmtp.connect(PORT_NUMBER, false, {});
+
+ client.once("idle", function(){
+ // Client is ready to take messages
+ test.ok(true); // waiting for envelope
+
+ client.useEnvelope({
+ from: "test@node.ee",
+ to: [
+ "test1@node.ee",
+ "test2@node.ee"
+ ]
+ });
+ });
+
+ client.on("message", function(){
+ // Client is ready to take messages
+ test.ok(true); // waiting for message
+
+ // pipe file to client
+ fs.createReadStream(__dirname+"/testmessage.eml").pipe(client);
+ });
+
+ client.on("ready", function(success){
+ test.ok(success);
+ client.close();
+ });
+
+ client.on("error", function(err){
+ test.ok(false);
+ });
+
+ client.on("end", function(){
+ test.done();
+ });
+ }
+
+}; \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/test/pool.js b/tools/node_modules/nodemailer/node_modules/simplesmtp/test/pool.js
new file mode 100644
index 0000000..84a5c05
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/test/pool.js
@@ -0,0 +1,275 @@
+var testCase = require('nodeunit').testCase,
+ runClientMockup = require("rai").runClientMockup,
+ simplesmtp = require("../index"),
+ MailComposer = require("mailcomposer").MailComposer,
+ fs = require("fs");
+
+var PORT_NUMBER = 8397;
+
+exports["General tests"] = {
+ setUp: function (callback) {
+ this.server = new simplesmtp.createServer({});
+ this.server.listen(PORT_NUMBER, function(err){
+ if(err){
+ throw err;
+ }else{
+ callback();
+ }
+ });
+
+ },
+
+ tearDown: function (callback) {
+ this.server.end(callback);
+ },
+
+ "Send single message": function(test){
+
+ var pool = simplesmtp.createClientPool(PORT_NUMBER),
+ mc = new MailComposer({escapeSMTP: true});
+
+ mc.setMessageOption({
+ from: "andmekala@hot.ee",
+ to: "andris@node.ee",
+ subject:"Hello!",
+ body: "Hello world!",
+ html: "<b>Hello world!</b>"
+ });
+
+ this.server.on("dataReady", function(envelope, callback){
+ test.ok(true);
+ callback();
+ });
+
+ pool.sendMail(mc, function(error){
+ test.ifError(error);
+ pool.close(function(){
+ test.ok(true);
+ test.done();
+ });
+ });
+ },
+
+ "Send several messages": function(test){
+ var total = 10;
+
+ test.expect(total*2);
+
+ var pool = simplesmtp.createClientPool(PORT_NUMBER),
+ mc;
+
+ this.server.on("dataReady", function(envelope, callback){
+ process.nextTick(callback);
+ });
+
+ var completed = 0;
+ for(var i=0; i<total; i++){
+ mc = new MailComposer({escapeSMTP: true});
+ mc.setMessageOption({
+ from: "andmekala@hot.ee",
+ to: "andris@node.ee",
+ subject:"Hello!",
+ body: "Hello world!",
+ html: "<b>Hello world!</b>"
+ });
+ pool.sendMail(mc, function(error){
+ test.ifError(error);
+ test.ok(true);
+ completed++;
+ if(completed >= total){
+ pool.close(function(){
+ test.done();
+ });
+ }
+ });
+ }
+ },
+
+ "Delivery error once": function(test){
+
+ var pool = simplesmtp.createClientPool(PORT_NUMBER),
+ mc = new MailComposer({escapeSMTP: true});
+
+ mc.setMessageOption({
+ from: "andmekala@hot.ee",
+ to: "andris@node.ee",
+ subject:"Hello!",
+ body: "Hello world!",
+ html: "<b>Hello world!</b>"
+ });
+
+ this.server.on("dataReady", function(envelope, callback){
+ test.ok(true);
+ callback(new Error("Spam!"));
+ });
+
+ pool.sendMail(mc, function(error){
+ test.equal(error && error.name, "DeliveryError");
+ pool.close(function(){
+ test.ok(true);
+ test.done();
+ });
+ });
+ },
+
+ "Delivery error several times": function(test){
+ var total = 10;
+
+ test.expect(total);
+
+ var pool = simplesmtp.createClientPool(PORT_NUMBER),
+ mc;
+
+ this.server.on("dataReady", function(envelope, callback){
+ process.nextTick(function(){callback(new Error("Spam!"));});
+ });
+
+ var completed = 0;
+ for(var i=0; i<total; i++){
+ mc = new MailComposer({escapeSMTP: true});
+ mc.setMessageOption({
+ from: "andmekala@hot.ee",
+ to: "andris@node.ee",
+ subject:"Hello!",
+ body: "Hello world!",
+ html: "<b>Hello world!</b>"
+ });
+
+ pool.sendMail(mc, function(error){
+ test.equal(error && error.name, "DeliveryError");
+ completed++;
+ if(completed >= total){
+ pool.close(function(){
+ test.done();
+ });
+ }
+ });
+ }
+ }
+};
+
+exports["Auth fail tests"] = {
+ setUp: function (callback) {
+ this.server = new simplesmtp.createServer({
+ requireAuthentication: true
+ });
+
+ this.server.listen(PORT_NUMBER, function(err){
+ if(err){
+ throw err;
+ }else{
+ callback();
+ }
+ });
+
+ this.server.on("authorizeUser", function(envelope, username, password, callback){
+ callback(null, username == password);
+ });
+ },
+
+ tearDown: function (callback) {
+ this.server.end(callback);
+ },
+
+ "Authentication passes once": function(test){
+ var pool = simplesmtp.createClientPool(PORT_NUMBER, false, {
+ auth: {
+ "user": "test",
+ "pass": "test"
+ }
+ }),
+ mc = new MailComposer({escapeSMTP: true});
+
+ mc.setMessageOption({
+ from: "andmekala2@hot.ee",
+ to: "andris2@node.ee",
+ subject:"Hello2!",
+ body: "Hello2 world!",
+ html: "<b>Hello2 world!</b>"
+ });
+
+ this.server.on("dataReady", function(envelope, callback){
+ test.ok(true);
+ callback();
+ });
+
+ pool.sendMail(mc, function(error){
+ test.ifError(error);
+ pool.close(function(){
+ test.ok(true);
+ test.done();
+ });
+ });
+
+ },
+
+ "Authentication error once": function(test){
+ var pool = simplesmtp.createClientPool(PORT_NUMBER, false, {
+ auth: {
+ "user": "test1",
+ "pass": "test2"
+ }
+ }),
+ mc = new MailComposer({escapeSMTP: true});
+
+ mc.setMessageOption({
+ from: "andmekala2@hot.ee",
+ to: "andris2@node.ee",
+ subject:"Hello2!",
+ body: "Hello2 world!",
+ html: "<b>Hello2 world!</b>"
+ });
+
+ this.server.on("dataReady", function(envelope, callback){
+ test.ok(true);
+ callback();
+ });
+
+ pool.sendMail(mc, function(error){
+ test.equal(error && error.name, "AuthError");
+ pool.close(function(){
+ test.ok(true);
+ test.done();
+ });
+ });
+
+ },
+
+ "Authentication error several times": function(test){
+ var total = 10;
+ test.expect(total);
+
+ var pool = simplesmtp.createClientPool(PORT_NUMBER, false, {
+ auth: {
+ "user": "test1",
+ "pass": "test2"
+ }
+ }),
+ mc;
+ this.server.on("dataReady", function(envelope, callback){
+ process.nextTick(function(){callback(new Error("Spam!"));});
+ });
+
+ var completed = 0;
+ for(var i=0; i<total; i++){
+ mc = new MailComposer({escapeSMTP: true});
+ mc.setMessageOption({
+ from: "andmekala@hot.ee",
+ to: "andris@node.ee",
+ subject:"Hello!",
+ body: "Hello world!",
+ html: "<b>Hello world!</b>"
+ });
+
+ pool.sendMail(mc, function(error){
+ test.equal(error && error.name, "AuthError");
+ completed++;
+ if(completed >= total){
+ pool.close(function(){
+ test.done();
+ });
+ }
+ });
+ }
+ }
+}; \ No newline at end of file
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/test/server.js b/tools/node_modules/nodemailer/node_modules/simplesmtp/test/server.js
new file mode 100644
index 0000000..32b1ec8
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/test/server.js
@@ -0,0 +1,590 @@
+var testCase = require('nodeunit').testCase,
+ runClientMockup = require("rai").runClientMockup,
+ simplesmtp = require("../index"),
+ netlib = require("net");
+
+var PORT_NUMBER = 8397;
+
+// monkey patch net and tls to support nodejs 0.4
+if(!netlib.connect && netlib.createConnection){
+ netlib.connect = netlib.createConnection;
+}
+
+exports["General tests"] = {
+ setUp: function (callback) {
+
+ this.smtp = new simplesmtp.createServer({
+ SMTPBanner: "SCORPIO",
+ name: "MYRDO",
+ maxSize: 1234
+ });
+ this.smtp.listen(PORT_NUMBER, function(err){
+ if(err){
+ throw err;
+ }else{
+ callback();
+ }
+ });
+
+ },
+ tearDown: function (callback) {
+ this.smtp.end(callback);
+ },
+ "QUIT": function(test){
+ var cmds = ["QUIT"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("221",resp.toString("utf-8").trim().substr(0,3));
+ test.done();
+ });
+
+ },
+ "HELO": function(test){
+ var cmds = ["HELO FOO"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("250",resp.toString("utf-8").trim().substr(0,3));
+ test.done();
+ });
+
+ },
+ "HELO fails": function(test){
+ var cmds = ["HELO"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "EHLO": function(test){
+ var cmds = ["EHLO FOO"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ resp = resp.toString("utf-8").trim();
+ var lines = resp.split("\r\n");
+ for(var i=0; i<lines.length-1; i++){
+ test.equal("250-", lines[i].substr(0,4));
+ }
+ test.equal("250 ", lines[i].substr(0,4));
+ test.done();
+ });
+ },
+ "EHLO fails": function(test){
+ var cmds = ["EHLO"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "HELO after STARTTLS": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "HELO FOO"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("250",resp.toString("utf-8").trim().substr(0,3));
+ test.done();
+ });
+ },
+ "HELO fails after STARTTLS": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "HELO"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "EHLO after STARTTLS": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "HELO FOO"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ resp = resp.toString("utf-8").trim();
+ var lines = resp.split("\r\n");
+ for(var i=0; i<lines.length-1; i++){
+ test.equal("250-", lines[i].substr(0,4));
+ }
+ test.equal("250 ", lines[i].substr(0,4));
+ test.done();
+ });
+ },
+ "EHLO fails after STARTTLS": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH fails if not required": function(test){
+ var cmds = ["EHLO FOO", "AUTH LOGIN"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH fails if not required TLS": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "AUTH LOGIN"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "Custom Greeting banner": function(test){
+ var client = netlib.connect(PORT_NUMBER, function(){
+ client.on("data", function(chunk){
+ test.equal("SCORPIO", (chunk || "").toString().trim().split(" ").pop());
+ client.end();
+ });
+ client.on('end', function() {
+ test.done();
+ });
+ });
+ },
+ "HELO name": function(test){
+ var cmds = ["HELO FOO"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("MYRDO",resp.toString("utf-8").trim().substr(4).split(" ").shift());
+ test.done();
+ });
+ },
+ "EHLO name": function(test){
+ var cmds = ["EHLO FOO"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("MYRDO",resp.toString("utf-8").trim().substr(4).split(" ").shift());
+ test.done();
+ });
+ },
+ "MAXSIZE": function(test){
+ var cmds = ["EHLO FOO"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.ok(resp.toString("utf-8").trim().match(/^250[\- ]SIZE 1234$/mi));
+ test.done();
+ });
+ }
+};
+
+exports["EHLO setting"] = {
+ setUp: function (callback) {
+
+ this.smtp = new simplesmtp.createServer({
+ disableEHLO: true
+ });
+ this.smtp.listen(PORT_NUMBER, function(err){
+ if(err){
+ throw err;
+ }else{
+ callback();
+ }
+ });
+
+ },
+ tearDown: function (callback) {
+ this.smtp.end(callback);
+ },
+ "Disable EHLO": function(test){
+ runClientMockup(PORT_NUMBER, "localhost", ["EHLO foo"], function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ runClientMockup(PORT_NUMBER, "localhost", ["HELO foo"], function(resp){
+ test.equal("2",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ });
+
+ }
+};
+
+exports["Client disconnect"] = {
+
+ "Client disconnect": function(test){
+
+ var smtp = new simplesmtp.createServer(),
+ clientEnvelope;
+ smtp.listen(PORT_NUMBER, function(err){
+ if(err){
+ throw err;
+ }
+
+ runClientMockup(PORT_NUMBER, "localhost", ["EHLO foo", "MAIL FROM:<andris@node.ee>", "RCPT TO:<andris@node.ee>", "DATA"], function(resp){
+ test.equal("3",resp.toString("utf-8").trim().substr(0,1));
+ });
+
+ });
+ smtp.on("startData", function(envelope){
+ clientEnvelope = envelope;
+ });
+ smtp.on("close", function(envelope){
+ test.equal(envelope, clientEnvelope);
+ smtp.end(function(){});
+ test.done();
+ });
+
+ }
+};
+
+exports["Require AUTH"] = {
+ setUp: function (callback) {
+
+ this.smtp = new simplesmtp.createServer({requireAuthentication: true});
+ this.smtp.listen(PORT_NUMBER, function(err){
+ if(err){
+ throw err;
+ }else{
+ callback();
+ }
+ });
+
+ this.smtp.on("authorizeUser", function(envelope, username, password, callback){
+ callback(null, username=="andris" && password=="test");
+ });
+
+ },
+ tearDown: function (callback) {
+ this.smtp.end(callback);
+ },
+ "Fail without AUTH": function(test){
+ var cmds = ["EHLO FOO", "MAIL FROM:<andris@node.ee>"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "Unknown AUTH": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH CRAM"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH fails before STARTTLS": function(test){
+ var cmds = ["EHLO FOO", "AUTH LOGIN"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH LOGIN": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("3",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH LOGIN Invalid login": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN",
+ new Buffer("inv").toString("base64"),
+ new Buffer("alid").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH LOGIN Invalid username": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN",
+ new Buffer("inv").toString("base64"),
+ new Buffer("test").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH LOGIN Invalid password": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN",
+ new Buffer("andris").toString("base64"),
+ new Buffer("alid").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH LOGIN Login success": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN",
+ new Buffer("andris").toString("base64"),
+ new Buffer("test").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("2",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH PLAIN": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("3",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH PLAIN Invalid login": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN "+
+ new Buffer("inv\u0000inv\u0000alid").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH PLAIN Invalid user": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN "+
+ new Buffer("inv\u0000inv\u0000test").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH PLAIN Invalid password": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN "+
+ new Buffer("andris\u0000andris\u0000alid").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH PLAIN Login success": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN "+
+ new Buffer("andris\u0000andris\u0000test").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("2",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH PLAIN Yet another login success": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN",
+ new Buffer("andris\u0000andris\u0000test").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("2",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ }
+};
+
+exports["Enable AUTH"] = {
+ setUp: function (callback) {
+
+ this.smtp = new simplesmtp.createServer({enableAuthentication: true});
+ this.smtp.listen(PORT_NUMBER, function(err){
+ if(err){
+ throw err;
+ }else{
+ callback();
+ }
+ });
+
+ this.smtp.on("authorizeUser", function(envelope, username, password, callback){
+ callback(null, username=="andris" && password=="test");
+ });
+
+ },
+ tearDown: function (callback) {
+ this.smtp.end(callback);
+ },
+ "Pass without AUTH": function(test){
+ var cmds = ["EHLO FOO", "MAIL FROM:<andris@node.ee>"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("2",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "Unknown AUTH": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH CRAM"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH fails before STARTTLS": function(test){
+ var cmds = ["EHLO FOO", "AUTH LOGIN"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH LOGIN": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("3",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH LOGIN Invalid login": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN",
+ new Buffer("inv").toString("base64"),
+ new Buffer("alid").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH LOGIN Invalid username": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN",
+ new Buffer("inv").toString("base64"),
+ new Buffer("test").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH LOGIN Invalid password": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN",
+ new Buffer("andris").toString("base64"),
+ new Buffer("alid").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH LOGIN Login success": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN",
+ new Buffer("andris").toString("base64"),
+ new Buffer("test").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("2",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH PLAIN": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("3",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH PLAIN Invalid login": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN "+
+ new Buffer("inv\u0000inv\u0000alid").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH PLAIN Invalid user": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN "+
+ new Buffer("inv\u0000inv\u0000test").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH PLAIN Invalid password": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN "+
+ new Buffer("andris\u0000andris\u0000alid").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH PLAIN Login success": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN "+
+ new Buffer("andris\u0000andris\u0000test").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("2",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "AUTH PLAIN Yet another login success": function(test){
+ var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN",
+ new Buffer("andris\u0000andris\u0000test").toString("base64")];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("2",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ }
+};
+
+exports["ignoreTLS"] = {
+ setUp: function (callback) {
+
+ this.smtp = new simplesmtp.createServer({requireAuthentication: true, ignoreTLS: true});
+ this.smtp.listen(PORT_NUMBER, function(err){
+ if(err){
+ throw err;
+ }else{
+ callback();
+ }
+ });
+
+ this.smtp.on("authorizeUser", function(envelope, username, password, callback){
+ callback(null, username=="d3ph" && password=="test");
+ });
+ },
+ tearDown: function (callback) {
+ this.smtp.end(callback);
+ },
+ "Fail without AUTH": function(test){
+ var cmds = ["EHLO FOO", "MAIL FROM:<d3ph.ru@gmail.com>"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "Fail MAIL FROM without HELO": function(test){
+ var cmds = ["MAIL FROM:<d3ph.ru@gmail.com>"];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("5",resp.toString("utf-8").trim().substr(0,1));
+ test.done();
+ });
+ },
+ "Success AUTH & SEND MAIL with <CR><LF>.<CR><LF>": function(test){
+ var cmds = ["EHLO FOO",
+ "AUTH PLAIN",
+ new Buffer("\u0000d3ph\u0000test").toString("base64"),
+ "MAIL FROM:<d3ph@github.com>",
+ "RCPT TO:<andris@node.ee>",
+ "DATA",
+ "Test mail\015\012.\015\012",
+ ];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ var resp = resp.toString("utf-8").trim();
+ test.equal("2",resp.substr(0,1));
+ test.ok(resp.match('FOOBARBAZ'));
+ test.done();
+ });
+ }
+};
+
+exports["Sending mail listen for dataReady"] = {
+ setUp: function (callback) {
+ var data = "";
+
+ this.smtp = new simplesmtp.createServer({ignoreTLS: true});
+ this.smtp.listen(PORT_NUMBER, function(err){
+ if(err){
+ throw err;
+ }else{
+ callback();
+ }
+ });
+
+ this.smtp.on("authorizeUser", function(envelope, username, password, callback){
+ callback(null, username=="d3ph" && password=="test");
+ });
+
+ this.smtp.on("data", function(envelope, chunk){
+ data += chunk;
+ });
+
+ this.smtp.on("dataReady", function(envelope, callback){
+ if (data.match('spam')) {
+ callback(true);
+ } else {
+ callback(null, '#ID');
+ }
+ });
+ },
+ tearDown: function (callback) {
+ this.smtp.end(callback);
+ },
+ "Fail send mail if body contains 'spam'": function(test){
+ var cmds = ["EHLO FOO",
+ "MAIL FROM:<d3ph@github.com>",
+ "RCPT TO:<andris@node.ee>",
+ "DATA",
+ "Test mail with spam!\015\012.\015\012",
+ ];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ test.equal("550 FAILED",resp.toString("utf-8").trim());
+ test.done();
+ });
+ },
+ "Create #ID for mail": function(test){
+ var cmds = ["EHLO FOO",
+ "MAIL FROM:<d3ph@github.com>",
+ "RCPT TO:<andris@node.ee>",
+ "DATA",
+ "Clear mail body\015\012.\015\012",
+ ];
+ runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){
+ var resp = resp.toString("utf-8").trim();
+ test.equal("2",resp.substr(0,1));
+ test.ok(resp.match('#ID'));
+ test.done();
+ });
+ }
+}
+
diff --git a/tools/node_modules/nodemailer/node_modules/simplesmtp/test/testmessage.eml b/tools/node_modules/nodemailer/node_modules/simplesmtp/test/testmessage.eml
new file mode 100644
index 0000000..5e0523e
--- /dev/null
+++ b/tools/node_modules/nodemailer/node_modules/simplesmtp/test/testmessage.eml
@@ -0,0 +1,5 @@
+From: test@node.ee
+To: test@node.ee
+Subject: Test
+
+Hello world! \ No newline at end of file