<commit_before>"use strict";

describe("xml/xpath", function () {

    var Node = gpf.define({
        $class: "Node",

        _type: gpf.xml.nodeType.element,
        _name: null,
        _namespaceURI: "",
        _attributes: [],
        _children: [],
        _value: null,
        _parent: null,

        // region gpf.interfaces.IXmlNodeSyncAdapter

        getAttributes: function () {
            return this._attributes;
        },

        getChildNodes: function () {
            return this._children;
        },

        getLocalName: function () {
            return this._name;
        },

        getNamespaceURI: function () {
            return this._namespaceURI;
        },

        getNodeType: function () {
            return this._type;
        },

        getNodeValue: function () {
            return this._value;
        },

        getParentNode: function () {
            return this._parent;
        },

        // endregion

        _build: function (name, attributes, children) {
            if (name) {
                this._name = name;
            }
            if (attributes) {
                this._namespaceURI = attributes[""] || "";
                delete attributes[""];
                this._attributes = Object.keys(attributes).map(function (attributeName) {
                    var attributeNode = new Node(attributeName);
                    attributeNode._type = gpf.xml.nodeType.attribute;
                    attributeNode._value = attributes[attributeName];
                    attributeNode._parent = this;
                    return attributeNode;
                }, this);
            }
            if (children) {
                this._children = children.map(function (childNode) {
                    var mappedNode;
                    if (typeof childNode === "string") {
                        mappedNode = new Node();
                        mappedNode._value = childNode;
                        mappedNode._type = gpf.xml.nodeType.text;
                    } else {
                        mappedNode = childNode;
                    }
                    mappedNode._parent = this;
                    return mappedNode;
                }, this);
            }
        },

        constructor: function (name, attributes, children) {
            if (Array.isArray(attributes)) {
                this._build(name, undefined, attributes);
            } else {
                this._build(name, attributes, children);
            }
        }
    });

    function node (name, attributes, children) {
        return new Node(name, attributes, children);
    }

    var SVG_NAMESPACE = "http://www.w3.org/2000/svg";
    var documentNode = node("", [
        node("html", [
            node("head", [
                node("title", ["Sample page"]),
                node("script", {
                    src: "/gpf.js",
                    language: "javascript"
                })
            ]),
            node("body", [
                node("svg", {
                    "": SVG_NAMESPACE,
                    height: "100",
                    width: "100"
                }, [
                    node("circle", {
                        "": SVG_NAMESPACE,
                        cx: "50",
                        cy: "50",
                        r: "40",
                        stroke: "black",
                        "stroke-width": "3",
                        fill: "red"
                    })
                ])
            ])
        ])
    ]);
    documentNode._type = gpf.xml.nodeType.document;
    var htmlNode = documentNode.getChildNodes()[0],
        headNode = htmlNode.getChildNodes()[0],
        scriptNode = headNode.getChildNodes()[1],
        srcAttrNode = scriptNode.getAttributes()[0],
        languageAttrNode = scriptNode.getAttributes()[1],
        bodyNode = htmlNode.getChildNodes()[1],
        svgNode = bodyNode.getChildNodes()[0],
        circleNode = svgNode.getChildNodes()[0];

    describe("xml/xpath", function () {
        describe("validation", function () {
            function shouldFail (xpath) {
                it("does not parse: " + xpath, function () {
                    var exceptionCaught;
                    try {
                        gpf.xml.xpath.parse(xpath);
                    } catch (e) {
                        exceptionCaught = e;
                    }
                    assert(exceptionCaught instanceof gpf.Error.InvalidXPathSyntax);
                });
            }

            shouldFail("test");
            shouldFail("///test");
            shouldFail("..//test");
            shouldFail(".//test || .//test");
        });

        describe("gpf.xml.xpath.select", function () {
            function generateTests (xpath, checks) {
                var namespaces = checks.namespaces,
                    label = xpath;
                if (namespaces) {
                    label += Object.keys(namespaces).reduce(function (result, prefix) {
                        return result + " " + prefix + "=\"" + namespaces[prefix] + "\"";
                    }, " (with") + ")";
                }
                describe(label, function () {
                    if (checks.xpath) {
                        it("parses", function () {
                            var parsed = gpf.xml.xpath.parse(xpath);
                            assert(parsed.toString() === xpath);
                            checks.xpath(parsed);
                        });
                    }
                    if (checks.document) {
                        it("executes on document", function () {
                            var nodes = gpf.xml.xpath.select(xpath, documentNode, namespaces);
                            checks.document(nodes);
                        });
                    }
                    if (checks.html) {
                        it("executes on <html />", function () {
                            var nodes = gpf.xml.xpath.select(xpath, htmlNode, namespaces);
                            checks.html(nodes);
                        });
                    }
                    if (checks.head) {
                        it("executes on <head />", function () {
                            var nodes = gpf.xml.xpath.select(xpath, headNode, namespaces);
                            checks.head(nodes);
                        });
                    }
                });
            }

            function isEmpty (nodes) {
                assert(nodes.length === 0);
            }

            function is (nodeOrNodes) {
                var expectedNodes;
                if (Array.isArray(nodeOrNodes)) {
                    expectedNodes = nodeOrNodes;
                } else {
                    expectedNodes = [nodeOrNodes];
                }
                return function (nodes) {
                    assert(nodes.length === expectedNodes.length);
                    // Order is not significant
                    assert(expectedNodes.every(function (expectedNode) {
                        return nodes.includes(expectedNode);
                    }));
                };
            }

            generateTests("//html", {
                xpath: function (parsed) {
                    assert(parsed instanceof gpf.xml.xpath.Deep);
                    assert(parsed.getChildren()[0] instanceof gpf.xml.xpath.Match);
                },
                document: is(htmlNode),
                html: is(htmlNode),
                head: is(htmlNode)
            });

            generateTests(".//html", {
                xpath: function (parsed) {
                    assert(parsed instanceof gpf.xml.xpath.Deep);
                    assert(parsed.getChildren()[0] instanceof gpf.xml.xpath.Match);
                },
                document: is(htmlNode),
                html: isEmpty,
                head: isEmpty
            });

            generateTests("//html/head", {
                xpath: function (parsed) {
                    assert(parsed instanceof gpf.xml.xpath.Chain);
                    assert(parsed.getChildren()[0] instanceof gpf.xml.xpath.Deep);
                    assert(parsed.getChildren()[1] instanceof gpf.xml.xpath.Sub);
                },
                document: is(headNode),
                html: is(headNode),
                head: is(headNode)
            });

            generateTests("//html/head | //html/body", {
                xpath: function (parsed) {
                    assert(parsed instanceof gpf.xml.xpath.Concat);
                    assert(parsed.getChildren()[0] instanceof gpf.xml.xpath.Chain);
                    assert(parsed.getChildren()[1] instanceof gpf.xml.xpath.Chain);
                },
                document: is([headNode, bodyNode]),
                html: is([headNode, bodyNode]),
                head: is([headNode, bodyNode])
            });

            generateTests("//html/head | .//body", {
                xpath: function (parsed) {
                    assert(parsed instanceof gpf.xml.xpath.Concat);
                    assert(parsed.getChildren()[0] instanceof gpf.xml.xpath.Chain);
                    assert(parsed.getChildren()[1] instanceof gpf.xml.xpath.Deep);
                },
                document: is([headNode, bodyNode]),
                html: is([headNode, bodyNode]),
                head: is(headNode)
            });

            generateTests("/html/head/script/@src", {
                xpath: function (parsed) {
                    assert(parsed instanceof gpf.xml.xpath.Chain);
                    assert(parsed.getChildren().length === 4);
                    assert(parsed.getChildren()[0] instanceof gpf.xml.xpath.Sub);
                },
                document: is(srcAttrNode),
                html: is(srcAttrNode),
                head: is(srcAttrNode)
            });

            generateTests("/html/head/script/@*", {
                xpath: function (parsed) {
                    assert(parsed instanceof gpf.xml.xpath.Chain);
                    assert(parsed.getChildren().length === 4);
                    assert(parsed.getChildren()[0] instanceof gpf.xml.xpath.Sub);
                },
                document: is([srcAttrNode, languageAttrNode]),
                html: is([srcAttrNode, languageAttrNode]),
                head: is([srcAttrNode, languageAttrNode])
            });

            generateTests("//html/head | ./script/@src", {
                xpath: function (parsed) {
                    assert(parsed instanceof gpf.xml.xpath.Concat);
                    assert(parsed.getChildren()[0] instanceof gpf.xml.xpath.Chain);
                    assert(parsed.getChildren()[1] instanceof gpf.xml.xpath.Chain);
                },
                document: is(headNode),
                html: is(headNode),
                head: is([headNode, srcAttrNode])
            });

            generateTests("//svg:svg", {
                namespaces: {
                    svg: SVG_NAMESPACE
                },
                xpath: function (parsed) {
                    assert(parsed instanceof gpf.xml.xpath.Deep);
                },
                document: is(svgNode),
                html: is(svgNode),
                head: is(svgNode)
            });

            generateTests(".//svg:*", {
                namespaces: {
                    svg: SVG_NAMESPACE
                },
                xpath: function (parsed) {
                    assert(parsed instanceof gpf.xml.xpath.Deep);
                },
                document: is([svgNode, circleNode]),
                html: is([svgNode, circleNode]),
                head: isEmpty
            });

            generateTests("//svg:*", {
                namespaces: {
                    notSvg: SVG_NAMESPACE
                },
                xpath: function (parsed) {
                    assert(parsed instanceof gpf.xml.xpath.Deep);
                },
                document: isEmpty,
                html: isEmpty,
                head: isEmpty
            });

            generateTests("//unknown:*", {
                namespaces: {
                    unknown: "not a known namespace"
                },
                xpath: function (parsed) {
                    assert(parsed instanceof gpf.xml.xpath.Deep);
                },
                document: isEmpty,
                html: isEmpty,
                head: isEmpty
            });
        });
    });
});
<commit_msg>Refactoring and testing condition (#326)<commit_after>"use strict";

describe("xml/xpath", function () {

    var Node = gpf.define({
        $class: "Node",

        _type: gpf.xml.nodeType.element,
        _name: null,
        _namespaceURI: "",
        _attributes: [],
        _children: [],
        _value: null,
        _parent: null,

        // region gpf.interfaces.IXmlNodeSyncAdapter

        getAttributes: function () {
            return this._attributes;
        },

        getChildNodes: function () {
            return this._children;
        },

        getLocalName: function () {
            return this._name;
        },

        getNamespaceURI: function () {
            return this._namespaceURI;
        },

        getNodeType: function () {
            return this._type;
        },

        getNodeValue: function () {
            return this._value;
        },

        getParentNode: function () {
            return this._parent;
        },

        // endregion

        _build: function (name, attributes, children) {
            if (name) {
                this._name = name;
            }
            if (attributes) {
                this._namespaceURI = attributes[""] || "";
                delete attributes[""];
                this._attributes = Object.keys(attributes).map(function (attributeName) {
                    var attributeNode = new Node(attributeName);
                    attributeNode._type = gpf.xml.nodeType.attribute;
                    attributeNode._value = attributes[attributeName];
                    attributeNode._parent = this;
                    return attributeNode;
                }, this);
            }
            if (children) {
                this._children = children.map(function (childNode) {
                    var mappedNode;
                    if (typeof childNode === "string") {
                        mappedNode = new Node();
                        mappedNode._value = childNode;
                        mappedNode._type = gpf.xml.nodeType.text;
                    } else {
                        mappedNode = childNode;
                    }
                    mappedNode._parent = this;
                    return mappedNode;
                }, this);
            }
        },

        constructor: function (name, attributes, children) {
            if (Array.isArray(attributes)) {
                this._build(name, undefined, attributes);
            } else {
                this._build(name, attributes, children);
            }
        }
    });

    function node (name, attributes, children) {
        return new Node(name, attributes, children);
    }

    var SVG_NAMESPACE = "http://www.w3.org/2000/svg";
    var documentNode = node("", [
        node("html", [
            node("head", [
                node("title", ["Sample page"]),
                node("script", {
                    src: "/gpf.js",
                    language: "javascript"
                })
            ]),
            node("body", [
                node("svg", {
                    "": SVG_NAMESPACE,
                    height: "100",
                    width: "100"
                }, [
                    node("circle", {
                        "": SVG_NAMESPACE,
                        cx: "50",
                        cy: "50",
                        r: "40",
                        stroke: "black",
                        "stroke-width": "3",
                        fill: "red"
                    })
                ])
            ])
        ])
    ]);
    documentNode._type = gpf.xml.nodeType.document;
    var htmlNode = documentNode.getChildNodes()[0],
        headNode = htmlNode.getChildNodes()[0],
        scriptNode = headNode.getChildNodes()[1],
        srcAttrNode = scriptNode.getAttributes()[0],
        languageAttrNode = scriptNode.getAttributes()[1],
        bodyNode = htmlNode.getChildNodes()[1],
        svgNode = bodyNode.getChildNodes()[0],
        circleNode = svgNode.getChildNodes()[0];

    describe("xml/xpath", function () {
        describe("validation", function () {
            function shouldFail (xpath) {
                it("does not parse: " + xpath, function () {
                    var exceptionCaught;
                    try {
                        gpf.xml.xpath.parse(xpath);
                    } catch (e) {
                        exceptionCaught = e;
                    }
                    assert(exceptionCaught instanceof gpf.Error.InvalidXPathSyntax);
                });
            }

            shouldFail("test");
            shouldFail("///test");
            shouldFail("..//test");
            shouldFail(".//test || .//test");
        });

        describe("gpf.xml.xpath.select", function () {
            function generateTests (test) {
                var xpath = test.xpath,
                    namespaces = test.namespaces,
                    label = test.xpath;
                if (namespaces) {
                    label += Object.keys(namespaces).reduce(function (result, prefix) {
                        return result + " " + prefix + "=\"" + namespaces[prefix] + "\"";
                    }, " (with") + ")";
                }
                describe(label, function () {
                    it("parses", function () {
                        var parsed = gpf.xml.xpath.parse(xpath);
                        assert(parsed.toString() === xpath);
                    });
                    if (test.onDocument) {
                        it("executes on document", function () {
                            var nodes = gpf.xml.xpath.select(xpath, documentNode, namespaces);
                            test.onDocument(nodes);
                        });
                    }
                    if (test.onHtml) {
                        it("executes on <html />", function () {
                            var nodes = gpf.xml.xpath.select(xpath, htmlNode, namespaces);
                            test.onHtml(nodes);
                        });
                    }
                    if (test.onHead) {
                        it("executes on <head />", function () {
                            var nodes = gpf.xml.xpath.select(xpath, headNode, namespaces);
                            test.onHead(nodes);
                        });
                    }
                });
            }

            function isEmpty (nodes) {
                assert(nodes.length === 0);
            }

            function is (nodeOrNodes) {
                var expectedNodes;
                if (Array.isArray(nodeOrNodes)) {
                    expectedNodes = nodeOrNodes;
                } else {
                    expectedNodes = [nodeOrNodes];
                }
                return function (nodes) {
                    assert(nodes.length === expectedNodes.length);
                    // Order is not significant
                    assert(expectedNodes.every(function (expectedNode) {
                        return nodes.includes(expectedNode);
                    }));
                };
            }

            [{
                xpath: "//html",
                onDocument: is(htmlNode),
                onHtml: is(htmlNode),
                onHead: is(htmlNode)
            }, {
                xpath: ".//html",
                onDocument: is(htmlNode),
                onHtml: isEmpty,
                onHead: isEmpty
            }, {
                xpath: "//html/head",
                onDocument: is(headNode),
                onHtml: is(headNode),
                onHead: is(headNode)
            }, {
                xpath: "//html/head | //html/body",
                onDocument: is([headNode, bodyNode]),
                onHtml: is([headNode, bodyNode]),
                onHead: is([headNode, bodyNode])
            }, {
                xpath: "//html/head | .//body",
                onDocument: is([headNode, bodyNode]),
                onHtml: is([headNode, bodyNode]),
                onHead: is(headNode)
            }, {
                xpath: "/html/head/script/@src",
                onDocument: is(srcAttrNode),
                onHtml: is(srcAttrNode),
                onHead: is(srcAttrNode)
            }, {
                xpath: "/html/head/script/@*",
                onDocument: is([srcAttrNode, languageAttrNode]),
                onHtml: is([srcAttrNode, languageAttrNode]),
                onHead: is([srcAttrNode, languageAttrNode])
            }, {
                xpath: "//html/head | ./script/@src",
                onDocument: is(headNode),
                onHtml: is(headNode),
                onHead: is([headNode, srcAttrNode])
            }, {
                xpath: "//svg:svg",
                namespaces: {
                    svg: SVG_NAMESPACE
                },
                onDocument: is(svgNode),
                onHtml: is(svgNode),
                onHead: is(svgNode)
            }, {
                xpath: ".//svg:*",
                namespaces: {
                    svg: SVG_NAMESPACE
                },
                onDocument: is([svgNode, circleNode]),
                onHtml: is([svgNode, circleNode]),
                onHead: isEmpty
            }, {
                xpath: "//svg:*",
                namespaces: {
                    notSvg: SVG_NAMESPACE
                },
                onDocument: isEmpty,
                onHtml: isEmpty,
                onHead: isEmpty
            }, {
                xpath: "//unknown:*",
                namespaces: {
                    unknown: "not a known namespace"
                },
                onDocument: isEmpty,
                onHtml: isEmpty,
                onHead: isEmpty
            }, {
                xpath: "/html/head//*[@*]",
                onDocument: is(scriptNode),
                onHtml: is(scriptNode),
                onHead: is(scriptNode)
            }].forEach(generateTests);
        });
    });
});
<|endoftext|>


<commit_before>
// JSON example
var candidates = [ {
  "name": "Ellie Phanta",
  "party": "Republican",
  "stance1" : -2
  },
  {
  "name": "Jack Bass",
  "party": "Democrat",
  "stance1" : -2
  },
  {
  "name": "Paul Stanton",
  "party": "Libertarian",
  "stance1" : 2
  }
 ];

Questions = [ {
  "Question" : "Should goods and services be provided by force?",
  "Responses" : [
    ["Absolutely",-2],
    ["Yes", -1],
    ["Maybe", 0],
    ["No", 1],
    ["Never", 2]]
}
];

function loadQuestions() {
  var chunk = '';
  for (i = 0; i < Questions.length; i++) {
    chunk += '
' + Questions[i].Question + '
';
    chunk += '
';
    for (j = 0; j < Questions[i].Responses.length; j++) {
     var qr = Questions[i].Responses[j];
     chunk += '<button onclick="tally(' + i + ',' + qr[1] + ')">' + qr[0] + '</button>';
    }
    document.getElementById("questionArea").innerHTML = chunk;

  }
}
<commit_msg>Update wme.js<commit_after>
// JSON example
var candidates = [ {
  "name": "Ellie Phanta",
  "party": "Republican",
  "stance1" : -2
  },
  {
  "name": "Jack Bass",
  "party": "Democrat",
  "stance1" : -2
  },
  {
  "name": "Paul Stanton",
  "party": "Libertarian",
  "stance1" : 2
  }
 ];

Questions = [ {
  "Question" : "Should goods and services be provided by force?",
  "Responses" : [
    ["Absolutely",-2],
    ["Yes", -1],
    ["Maybe", 0],
    ["No", 1],
    ["Never", 2]]
}
];

function loadQuestions() {
  var chunk = '';
  for (i = 0; i < Questions.length; i++) {
    chunk += '
' + Questions[i].Question + '
';
    chunk += '
';
    for (j = 0; j < Questions[i].Responses.length; j++) {
     var qr = Questions[i].Responses[j];
     chunk += '<button onclick="tally(' + i + ',' + qr[1] + ')">' + qr[0] + '</button>';
    }
    document.getElementById("questionArea").innerHTML = chunk;

  }
};

loadQuestions();
<|endoftext|>


<commit_before>
var WTF = (function() {

    'use strict';

    /*
      ------------------------------------------------------------

        Constants & variables

      ------------------------------------------------------------
    */

    var RE_QUOTE = /\"([^\"]+)\"/gi;
    var RE_JSON = /\.json$/i;
    var RE_COL = /^gsx\$(.+)$/i;
    var RE_KEY = /[a-z0-9_-]{32,}/i;
    var DOCS_PATH = "https://spreadsheets.google.com/feeds/list/{key}/od6/public/values?alt=json";

    var templates;
    var responses;
    var headings;
    var corpus;
    var regex;
    var dom;

    /*
      ------------------------------------------------------------

        Called once initialisation as finished

      ------------------------------------------------------------
    */

    function start() {

        // Copy out templates then remove from corpus

        templates = corpus.template;
        responses = corpus.response;
        headings = corpus.heading;

        delete corpus.template;
        delete corpus.response;
        delete corpus.heading;

        // Enable UI and generate first idea

        initUI();
        buildRexExp();
        generate();
    }

    /*
      ------------------------------------------------------------

        Converts CSV to a regular corpus object
        @see sample.json

      ------------------------------------------------------------
    */

    function parseCSV( csv ) {

        var i, j, k, n, m, cols, keys = {}, data = {}, rows = csv.split( '\n' );

        for ( i = 0, n = rows.length; i < n; i++, j = i - 1 ) {

            cols = rows[ i ].replace( RE_QUOTE, escape ).split( ',' );

            for ( k = 0, m = cols.length; k < m; k++ ) {

                if ( i === 0 ) {

                    data[ keys[ k ] = cols[ k ].toLowerCase() ] = [];

                } else if ( cols[ k ] ) {

                    data[ keys[ k ] ][ j ] = unescape( cols[ k ] ).replace( /^\"|\"$/g, '' );
                }
            }
        }

        return data;
    }

    /*
      ------------------------------------------------------------

        Converts JSON data to a regular corpus object
        @see sample.json

      ------------------------------------------------------------
    */

    function parseJSON( json ) {

        var i, n, key, val, map = {}, keys = {}, data = {}, rows = json.feed.entry;

        for ( key in rows[0] ) {

            if ( RE_COL.test( key ) ) {

                map[ key ] = key.match( RE_COL )[ 1 ].toLowerCase();
                keys[ key ] = [];
            }
        }

        for ( key in keys ) {

            data[ map[ key ] ] = keys[ key ];

            for ( i = 0, n = rows.length; i < n; i++ ) {

                val = rows[ i ][ key ].$t;

                if ( val && val.length ) {

                    keys[ key ].push( val );
                }
            }
        }

        return data;
    }

    /*
      ------------------------------------------------------------

        Binds event handlers to control the interface

      ------------------------------------------------------------
    */

    function initUI() {

        $( '.loading' ).remove();

        dom = {
            generate: $( '#generate' ),
            output: $( '#output' )
        };

        dom.generate.click( function() {
            generate();
            return false;
        });
    }

    /*
      ------------------------------------------------------------

        Builds a regular expression for all types in the corpus

      ------------------------------------------------------------
    */

    function buildRexExp() {

        var types = [];

        for ( var type in corpus )

            types.push( type );

        var content = '@(type)'.replace( 'type', types.join( '|' ) );

        regex = new RegExp( content, 'gi' );
    }

    /*
      ------------------------------------------------------------

        Generates ideas based on the corpus

      ------------------------------------------------------------
    */

    function generate() {

        var type, text, part, iter = 0, // Safety mechanism
            idea = randomItem( templates ),
            item = regex.exec( idea ),
            copy = cloneCorpus();

        while ( item && ++iter < 1000 ) {

            type = item[ 0 ];
            text = item[ 1 ];

            part = randomItem( copy[ text ], true );
            idea = idea.replace( type, part );

            regex.lastIndex = 0;
            item = regex.exec( idea );
        }

        // Update output

        dom.generate.text( randomItem( responses ) );
        dom.output.html(
            '
' +
                '
' + randomItem( headings ) + '
' +
                '
' + idea + '
' +
            '
'
        );

        // Toggle animation

        setTimeout( showOutput, 0 );
        hideOutput();
    }

    function hideOutput() {

        dom.output.removeClass( 'animate' ).css( 'opacity', 0 );
    }

    function showOutput() {

        dom.output.addClass( 'animate' ).css( 'opacity', 1 );
    }

    function randomItem( list, remove ) {

        var index = ~~( Math.random() * list.length );
        var item = list[ index ];

        if ( remove )

            list.splice( index, 1 );

        return item;
    }

    function cloneCorpus() {

        var copy = {};

        for ( var key in corpus )

            copy[ key ] = corpus[ key ].concat();

        return copy;
    }

    /*
      ------------------------------------------------------------

        Public API

      ------------------------------------------------------------
    */

    return {

        /*

            Expects one of the following:

                1.  An object with `templates` and any amount of keys for word types, for example:

                    {
                        templates: [ 'The @color @animal', 'The @animal was @color' ],
                        animal: [ 'dog', 'cat', 'rabbit' ],
                        color: [ 'red', 'green', 'blue' ],
                    }

                2.  A path to a JSON file with the same structure as above (see `sample.json`)

                3.  A Google spreadsheet key (e.g 0AvG1Hx204EyydF9ub1M2cVJ3Z1VGdDhTSWg0ZV9LNGc)
                    You must first publish the spreadsheet as a CSV
                    @see https://support.google.com/drive/answer/37579?hl=en

        */

        init: function( data ) {

            if ( !data ) throw data + ' is not a valid corpus';

            if ( typeof data === 'string' ) {

                if ( RE_JSON.test( data ) ) {

                    // JSON

                    $.ajax({
                        url: data,
                        dataType: 'json',
                        success: function( data, status, xhr ) {
                            corpus = data;
                            start();
                        },
                        error: function( xhr, errorType, error ) {
                            throw 'Cannot load JSON data: ' + error;
                        }
                    });

                } else if ( RE_KEY.test( data ) ) {

                    // JSON

                    $.ajax({
                        url: DOCS_PATH.replace( '{key}', data ),
                        success: function( data, status, xhr ) {
                            corpus = parseJSON( data );
                            start();
                        },
                        error: function( xhr, errorType, error ) {
                            throw 'Cannot load spreadsheet. Is it published? (@see https://support.google.com/drive/answer/37579?hl=en)';
                        }
                    });

                } else {

                    throw 'Unrecognised data format: ' + data;
                }

            } else if ( typeof data === 'object' ) {

                // Object

                corpus = data;
                start();
            }
        },

        // Expose certain methods

        generate: generate
    };

})();
<commit_msg>Fix bug with conflicting names.<commit_after>
var WTF = (function() {

    'use strict';

    /*
      ------------------------------------------------------------

        Constants & variables

      ------------------------------------------------------------
    */

    var RE_QUOTE = /\"([^\"]+)\"/gi;
    var RE_JSON = /\.json$/i;
    var RE_COL = /^gsx\$(.+)$/i;
    var RE_KEY = /[a-z0-9_-]{32,}/i;
    var DOCS_PATH = "https://spreadsheets.google.com/feeds/list/{key}/od6/public/values?alt=json";

    var templates;
    var responses;
    var headings;
    var corpus;
    var regex;
    var dom;

    /*
      ------------------------------------------------------------

        Called once initialisation as finished

      ------------------------------------------------------------
    */

    function start() {

        // Copy out templates then remove from corpus

        templates = corpus.template;
        responses = corpus.response;
        headings = corpus.heading;

        delete corpus.template;
        delete corpus.response;
        delete corpus.heading;

        // Enable UI and generate first idea

        initUI();
        buildRexExp();
        generate();
    }

    /*
      ------------------------------------------------------------

        Converts CSV to a regular corpus object
        @see sample.json

      ------------------------------------------------------------
    */

    function parseCSV( csv ) {

        var i, j, k, n, m, cols, keys = {}, data = {}, rows = csv.split( '\n' );

        for ( i = 0, n = rows.length; i < n; i++, j = i - 1 ) {

            cols = rows[ i ].replace( RE_QUOTE, escape ).split( ',' );

            for ( k = 0, m = cols.length; k < m; k++ ) {

                if ( i === 0 ) {

                    data[ keys[ k ] = cols[ k ].toLowerCase() ] = [];

                } else if ( cols[ k ] ) {

                    data[ keys[ k ] ][ j ] = unescape( cols[ k ] ).replace( /^\"|\"$/g, '' );
                }
            }
        }

        return data;
    }

    /*
      ------------------------------------------------------------

        Converts JSON data to a regular corpus object
        @see sample.json

      ------------------------------------------------------------
    */

    function parseJSON( json ) {

        var i, n, key, val, map = {}, keys = {}, data = {}, rows = json.feed.entry;

        for ( key in rows[0] ) {

            if ( RE_COL.test( key ) ) {

                map[ key ] = key.match( RE_COL )[ 1 ].toLowerCase();
                keys[ key ] = [];
            }
        }

        for ( key in keys ) {

            data[ map[ key ] ] = keys[ key ];

            for ( i = 0, n = rows.length; i < n; i++ ) {

                val = rows[ i ][ key ].$t;

                if ( val && val.length ) {

                    keys[ key ].push( val );
                }
            }
        }

        return data;
    }

    /*
      ------------------------------------------------------------

        Binds event handlers to control the interface

      ------------------------------------------------------------
    */

    function initUI() {

        $( '.loading' ).remove();

        dom = {
            generate: $( '#generate' ),
            output: $( '#output' )
        };

        dom.generate.click( function() {
            generate();
            return false;
        });
    }

    /*
      ------------------------------------------------------------

        Builds a regular expression for all types in the corpus

      ------------------------------------------------------------
    */

    function buildRexExp() {

        var types = [];

        for ( var type in corpus )

            types.push( type );

        types = types.sort(function (a, b) {
            if (a.length == b.length) {
                return 0
            }
            return a.length > b.length ? -1 : 1
        })

        var content = '@(type)'.replace( 'type', types.join( '|' ) );

        regex = new RegExp( content, 'gi' );
    }

    /*
      ------------------------------------------------------------

        Generates ideas based on the corpus

      ------------------------------------------------------------
    */

    function generate() {

        var type, text, part, iter = 0, // Safety mechanism
            idea = randomItem( templates ),
            item = regex.exec( idea ),
            copy = cloneCorpus();

        while ( item && ++iter < 1000 ) {

            type = item[ 0 ];
            text = item[ 1 ];

            part = randomItem( copy[ text ], true );
            idea = idea.replace( type, part );

            regex.lastIndex = 0;
            item = regex.exec( idea );
        }

        // Update output

        dom.generate.text( randomItem( responses ) );
        dom.output.html(
            '
' +
                '
' + randomItem( headings ) + '
' +
                '
' + idea + '
' +
            '
'
        );

        // Toggle animation

        setTimeout( showOutput, 0 );
        hideOutput();
    }

    function hideOutput() {

        dom.output.removeClass( 'animate' ).css( 'opacity', 0 );
    }

    function showOutput() {

        dom.output.addClass( 'animate' ).css( 'opacity', 1 );
    }

    function randomItem( list, remove ) {

        var index = ~~( Math.random() * list.length );
        var item = list[ index ];

        if ( remove )

            list.splice( index, 1 );

        return item;
    }

    function cloneCorpus() {

        var copy = {};

        for ( var key in corpus )

            copy[ key ] = corpus[ key ].concat();

        return copy;
    }

    /*
      ------------------------------------------------------------

        Public API

      ------------------------------------------------------------
    */

    return {

        /*

            Expects one of the following:

                1.  An object with `templates` and any amount of keys for word types, for example:

                    {
                        templates: [ 'The @color @animal', 'The @animal was @color' ],
                        animal: [ 'dog', 'cat', 'rabbit' ],
                        color: [ 'red', 'green', 'blue' ],
                    }

                2.  A path to a JSON file with the same structure as above (see `sample.json`)

                3.  A Google spreadsheet key (e.g 0AvG1Hx204EyydF9ub1M2cVJ3Z1VGdDhTSWg0ZV9LNGc)
                    You must first publish the spreadsheet as a CSV
                    @see https://support.google.com/drive/answer/37579?hl=en

        */

        init: function( data ) {

            if ( !data ) throw data + ' is not a valid corpus';

            if ( typeof data === 'string' ) {

                if ( RE_JSON.test( data ) ) {

                    // JSON

                    $.ajax({
                        url: data,
                        dataType: 'json',
                        success: function( data, status, xhr ) {
                            corpus = data;
                            start();
                        },
                        error: function( xhr, errorType, error ) {
                            throw 'Cannot load JSON data: ' + error;
                        }
                    });

                } else if ( RE_KEY.test( data ) ) {

                    // JSON

                    $.ajax({
                        url: DOCS_PATH.replace( '{key}', data ),
                        success: function( data, status, xhr ) {
                            corpus = parseJSON( data );
                            start();
                        },
                        error: function( xhr, errorType, error ) {
                            throw 'Cannot load spreadsheet. Is it published? (@see https://support.google.com/drive/answer/37579?hl=en)';
                        }
                    });

                } else {

                    throw 'Unrecognised data format: ' + data;
                }

            } else if ( typeof data === 'object' ) {

                // Object

                corpus = data;
                start();
            }
        },

        // Expose certain methods

        generate: generate
    };

})();
<|endoftext|>


<commit_before>var smtp = require("smtp-protocol");
var MailParser = require("mailparser").MailParser;
var fs = require("fs");
var path = require("path");

var mails = [];
var config;

/**
 * Processes a mail
 * @param mail
 */
function process(parsed) {
    mails.push(parsed);
    // Log to console if enabled
    if (!config.quite) {
        console.log(parsed.headers);
        console.log(parsed.html);
        console.log();
    }
    // Write to file if enabled
    if (config.dump) {
        var filename =  new Date(parsed.headers["date"]).getTime() +
            "-" + parsed.headers["message-id"].slice(1, -1) + ".json";
        console.log(filename);
        var savePath = path.join(config.dump, filename);
        var text = JSON.stringify(parsed, null, 2);
        fs.writeFile(savePath, text, function(err) {
            if(err) {
                return console.log(err);
            }
        });
    }
    //trim list of emails if necessary
    while(mails.length > config.maxEmails) {
        mails.splice(1,1);
    }
}

/**
 * Returs a new MailParser instance. Use a new instance for each email.
 * @returns {*|MailParser} MailParser instance
 */
function getMailparser() {
    var mailParser = new MailParser();
    mailParser.on("end", process);
    return mailParser;
}

function start() {
    smtp.createServer(function (req) {

        if (config.whitelist) {
            req.on("from", function (from, ack) {
                if (config.whitelist.length == 0 || config.whitelist.indexOf(from) !== -1)
                    ack.accept();
                else ack.reject()
            });
        }

        req.on("message", function (stream, ack) {
            // New MailParser instance for each mail
            var mailParser = getMailparser();
            // Receive data
            stream.on("data",function(d) {
                mailParser.write(d);
            });
            // All data received
            stream.on("end", function() {
                mailParser.end("");
            });

            ack.accept();
        });

    }).listen(config.smtpPort);
}

module.exports = {
	start: function() {
        start()
    },
    getMails: function() {
        return mails;
    },
    setConfig: function(configArg) {
        config = configArg;
    }
};<commit_msg>Construct filenames for email files without header values<commit_after>var smtp = require("smtp-protocol");
var MailParser = require("mailparser").MailParser;
var fs = require("fs");
var path = require("path");

var mails = [];
var config;

function randomInt (low, high) {
    return Math.floor(Math.random() * (high - low) + low);
}

/**
 * Processes a mail
 * @param mail
 */
function process(parsed) {
    mails.push(parsed);
    // Log to console if enabled
    if (!config.quite) {
        console.log(parsed.headers);
        console.log(parsed.html || parsed.text);
        console.log();
    }
    // Write to file if enabled
    if (config.dump) {
        var filename =  new Date().getTime() +
            "-" + randomInt(10000, 99999) + ".json";
        var savePath = path.join(config.dump, filename);
        var text = JSON.stringify(parsed, null, 2);
        fs.writeFile(savePath, text, function(err) {
            if(err) {
                return console.log(err);
            }
        });
    }
    //trim list of emails if necessary
    while(mails.length > config.maxEmails) {
        mails.splice(1,1);
    }
}

/**
 * Returs a new MailParser instance. Use a new instance for each email.
 * @returns {*|MailParser} MailParser instance
 */
function getMailparser() {
    var mailParser = new MailParser();
    mailParser.on("end", process);
    return mailParser;
}

function start() {
    smtp.createServer(function (req) {

        if (config.whitelist) {
            req.on("from", function (from, ack) {
                if (config.whitelist.length == 0 || config.whitelist.indexOf(from) !== -1)
                    ack.accept();
                else ack.reject()
            });
        }

        req.on("message", function (stream, ack) {
            // New MailParser instance for each mail
            var mailParser = getMailparser();
            // Receive data
            stream.on("data",function(d) {
                mailParser.write(d);
            });
            // All data received
            stream.on("end", function() {
                mailParser.end("");
            });

            ack.accept();
        });

    }).listen(config.smtpPort);
}

module.exports = {
	start: function() {
        start()
    },
    getMails: function() {
        return mails;
    },
    setConfig: function(configArg) {
        config = configArg;
    }
};<|endoftext|>


<commit_before>// SMTP client object and class. This allows for every part of the client
// protocol to be hooked for different levels of control, such as
// smtp_forward and smtp_proxy queue plugins.

var events = require('events');
var util = require('util');
var generic_pool = require('generic-pool');
var line_socket = require('./line_socket');
var logger = require('./logger');
var constants = require('./constants');

var smtp_regexp = /^([0-9]{3})([ -])(.*)/;
var STATE_IDLE = 1;
var STATE_ACTIVE = 2;
var STATE_RELEASED = 3;
var STATE_DEAD = 4;

function SMTPClient(port, host, timeout, enable_tls) {
    events.EventEmitter.call(this);
    this.socket = line_socket.connect(port, host);
    this.socket.setTimeout(timeout * 1000);
    this.state = STATE_IDLE;
    this.command = 'greeting';
    this.response = []
    this.connected = false;
    var self = this;

    this.socket.on('line', function (line) {
        self.emit('server_protocol', line);
        var matches = smtp_regexp.exec(line);
        if (!matches) {
            self.emit('error', 'Unrecognised response from upstream server: ' + line);
            self.pool.destroy(self);
            return;
        }

        var code = matches[1],
            cont = matches[2],
            msg = matches[3];
        self.response.push(msg);
        if (cont !== ' ') {
            return;
        }

        if (self.command === 'ehlo') {
            if (code.match(/^5/)) {
                // Handle fallback to HELO if EHLO is rejected
                self.emit('greeting', 'HELO');
                return;
            }
            self.emit('capabilities');
            if (self.command != 'ehlo') {
                return;
            }
        }
        if (self.command === 'xclient' && code.match(/^5/)) {
            // XCLIENT command was rejected (no permission?)
            // Carry on without XCLIENT
            self.command = 'helo';
        }
        else if (code.match(/^[45]/)) {
            self.emit('bad_code', code, msg);
            if (self.state != STATE_ACTIVE) {
                return;
            }
        }
        switch (self.command) {
            case 'xclient':
                self.xclient = true;
                self.emit('xclient', 'EHLO');
                break;
            case 'starttls':
                this.upgrade({key: key, cert: cert});
                break;
            case 'greeting':
                self.connected = true;
                self.emit('greeting', 'EHLO');
                break;
            case 'ehlo':
                self.emit('helo');
                break;
            case 'helo':
            case 'mail':
            case 'rcpt':
            case 'data':
            case 'dot':
            case 'rset':
                self.emit(self.command);
                break;
            case 'quit':
                self.pool.destroy(self);
                break;
            default:
                throw new Error("Unknown command: " + self.command);
        }
    });

    this.socket.on('drain', function () {
        if (self.command === 'mailbody') {
            process.nextTick(function () { self.continue_data() });
        }
    });

    this.socket.on('error', function (err) {
        if (self.state == STATE_IDLE) {
            self.state = STATE_DEAD;
        }
        else {
            self.emit('error', 'SMTP connection failed: ' + err);
            self.pool.destroy(self);
        }
    });

    this.socket.on('timeout', function () {
        if (self.state == STATE_IDLE) {
            self.state = STATE_DEAD;
        }
        else {
            self.emit('error', 'SMTP connection timed out');
            self.pool.destroy(self);
        }
    });

    this.socket.on('close', function (had_error) {
        if (self.state == STATE_IDLE) {
            self.state = STATE_DEAD;
        }
        else {
            self.pool.destroy(self);
        }
    });
}

util.inherits(SMTPClient, events.EventEmitter);

SMTPClient.prototype.send_command = function (command, data) {
    var line = (command == 'dot') ? '.' : command + (data ? (' ' + data) : '');
    this.emit('client_protocol', line);
    this.command = command.toLowerCase();
    this.response = [];
    this.socket.write(line + "\r\n");
};

SMTPClient.prototype.start_data = function (data) {
    this.command = 'mailbody';
    if (data instanceof Function) {
        this.send_data = data;
    }
    else if (data instanceof Array) {
        var data_marker = 0;
        this.send_data = function () {
            while (data_marker < data.length) {
                var line = data[data_marker];
                data_marker++;
                if (!this.send_data_line(line)) {
                    return false;
                }
            }
            return true;
        };
    }
    else {
        this.send_data = function () {
            this.socket.write(data);
            return true;
        };
    }
    this.continue_data();
};

SMTPClient.prototype.continue_data = function () {
    if (!this.send_data()) {
        return;
    }
    this.send_command('dot');
};

SMTPClient.prototype.send_data_line = function (line) {
    line = line.replace(/^\./, '..').replace(/\r?\n/g, '\r\n');
    console.log('BODY: ' + line);
    return this.socket.write(line);
};

SMTPClient.prototype.release = function () {
    this.state = STATE_RELEASED;
    this.removeAllListeners();

    this.on('bad_code', function (code, msg) {
        this.pool.destroy(this);
    });

    this.on('rset', function () {
        this.state = STATE_IDLE;
        this.removeAllListeners();
        this.pool.release(this);
    });

    this.send_command('RSET');
};

// Separate pools are kept for each set of server attributes.
exports.get_pool = function (server, port, host, timeout, enable_tls, max) {
    var port = port || 25;
    var host = host || 'localhost';
    var timeout = (timeout == undefined) ? 300 : timeout;
    var enable_tls = /(true|yes|1)/i.exec(enable_tls) != null;
    var name = port + ':' + host + ':' + timeout + ':' + enable_tls;
    if (!server.notes.pool) {
        server.notes.pool = {};
    }
    if (!server.notes.pool[name]) {
        var pool = generic_pool.Pool({
            name: name,
            create: function (callback) {
                var smtp_client = new SMTPClient(port, host, timeout, enable_tls);
                callback(null, smtp_client);
            },
            destroy: function(smtp_client) {
                if (smtp_client.state != STATE_DEAD) {
                    smtp_client.socket.destroy();
                }
            },
            max: max || 1000,
            idleTimeoutMillis: timeout * 1000,
            log: function (str, level) {
                level = (level == 'verbose') ? 'debug' : level;
                logger['log' + level]('[smtp_client_pool] ' + str);
            }
        });

        var acquire = pool.acquire;
        pool.acquire = function (callback, priority) {
            var callback_wrapper = function (err, smtp_client) {
                if (smtp_client.state == STATE_DEAD) {
                    pool.acquire(callback, priority);
                    return;
                }
                smtp_client.pool = pool;
                smtp_client.state = STATE_ACTIVE;
                callback(err, smtp_client);
            };
            acquire.call(pool, callback_wrapper, priority);
        };
        server.notes.pool[name] = pool;
    }
    return server.notes.pool[name];
};

// Get a smtp_client for the given attributes.
exports.get_client = function (server, callback, port, host, timeout, enable_tls, max) {
    var pool = exports.get_pool(server, port, host, timeout, enable_tls, max);
    pool.acquire(callback);
};

// Get a smtp_client for the given attributes and set it up the common
// config and listeners for plugins. Currently this is what smtp_proxy and
// smtp_forward have in common.
exports.get_client_plugin = function (plugin, connection, config, callback) {
    var pool = exports.get_pool(connection.server, config.main.port,
        config.main.host, config.main.timeout, config.main.enable_tls,
        config.main.max);
    pool.acquire(function (err, smtp_client) {
        connection.logdebug(plugin, 'Got smtp_client (' + connection.uuid + ' ' + connection.transaction + ' ' + smtp_client.listeners('helo').length + ')');
        smtp_client.call_next = function (retval, msg) {
            if (this.next) {
                this.next(retval, msg);
                delete this.next;
            }
        };

        smtp_client.on('client_protocol', function (line) {
            connection.logprotocol(plugin, 'C: ' + line);
        });

        smtp_client.on('server_protocol', function (line) {
            connection.logprotocol(plugin, 'S: ' + line);
        });

        var helo = function (command) {
            if (smtp_client.xclient) {
                smtp_client.send_command(command, connection.hello_host);
            }
            else {
                smtp_client.send_command(command, plugin.config.get('me'));
            }
        };
        smtp_client.on('greeting', helo);
        smtp_client.on('xclient', helo);

        smtp_client.on('capabilities', function () {
            for (var line in smtp_client.response) {
                if (smtp_client.response[line].match(/^XCLIENT/)) {
                    if(!smtp_client.xclient) {
                        smtp_client.send_command('XCLIENT',
                            'ADDR=' + connection.remote_ip);
                        return;
                    }
                }
                if (smtp_client.response[line].match(/^STARTTLS/)) {
                    var key = plugin.config.get('tls_key.pem', 'data').join("\n");
                    var cert = plugin.config.get('tls_cert.pem', 'data').join("\n");
                    if (key && cert && enable_tls) {
                        smtp_client.socket.on('secure', function () {
                            smtp_client.emit('greeting', 'EHLO');
                        });
                        smtp_client.send_command('STARTTLS');
                        return;
                    }
                }
            }
        });

        smtp_client.on('helo', function () {
            smtp_client.send_command('MAIL',
                'FROM:' + connection.transaction.mail_from);
        });

        smtp_client.on('dot', function () {
            smtp_client.call_next(constants.ok, smtp_client.response + ' (' + connection.transaction.uuid + ')');
            smtp_client.release();
        });

        smtp_client.on('error', function (msg) {
            connection.logerror(plugin, msg);
            smtp_client.call_next();
        });

        if (smtp_client.connected) {
            if (smtp_client.xclient) {
                smtp_client.send_command('XCLIENT',
                    'ADDR=' + connection.remote_ip);
            }
            else {
                smtp_client.emit('helo');
            }
        }

        callback(err, smtp_client);
    });
};
<commit_msg>Added logging line for debugging.<commit_after>// SMTP client object and class. This allows for every part of the client
// protocol to be hooked for different levels of control, such as
// smtp_forward and smtp_proxy queue plugins.

var events = require('events');
var util = require('util');
var generic_pool = require('generic-pool');
var line_socket = require('./line_socket');
var logger = require('./logger');
var constants = require('./constants');

var smtp_regexp = /^([0-9]{3})([ -])(.*)/;
var STATE_IDLE = 1;
var STATE_ACTIVE = 2;
var STATE_RELEASED = 3;
var STATE_DEAD = 4;

function SMTPClient(port, host, timeout, enable_tls) {
    events.EventEmitter.call(this);
    this.socket = line_socket.connect(port, host);
    this.socket.setTimeout(timeout * 1000);
    this.state = STATE_IDLE;
    this.command = 'greeting';
    this.response = []
    this.connected = false;
    var self = this;

    this.socket.on('line', function (line) {
        self.emit('server_protocol', line);
        var matches = smtp_regexp.exec(line);
        if (!matches) {
            self.emit('error', 'Unrecognised response from upstream server: ' + line);
            self.pool.destroy(self);
            return;
        }

        var code = matches[1],
            cont = matches[2],
            msg = matches[3];
        self.response.push(msg);
        if (cont !== ' ') {
            return;
        }

        if (self.command === 'ehlo') {
            if (code.match(/^5/)) {
                // Handle fallback to HELO if EHLO is rejected
                self.emit('greeting', 'HELO');
                return;
            }
            self.emit('capabilities');
            if (self.command != 'ehlo') {
                return;
            }
        }
        if (self.command === 'xclient' && code.match(/^5/)) {
            // XCLIENT command was rejected (no permission?)
            // Carry on without XCLIENT
            self.command = 'helo';
        }
        else if (code.match(/^[45]/)) {
            self.emit('bad_code', code, msg);
            if (self.state != STATE_ACTIVE) {
                return;
            }
        }
        switch (self.command) {
            case 'xclient':
                self.xclient = true;
                self.emit('xclient', 'EHLO');
                break;
            case 'starttls':
                this.upgrade({key: key, cert: cert});
                break;
            case 'greeting':
                self.connected = true;
                self.emit('greeting', 'EHLO');
                break;
            case 'ehlo':
                self.emit('helo');
                break;
            case 'helo':
            case 'mail':
            case 'rcpt':
            case 'data':
            case 'dot':
            case 'rset':
                self.emit(self.command);
                break;
            case 'quit':
                self.pool.destroy(self);
                break;
            default:
                throw new Error("Unknown command: " + self.command);
        }
    });

    this.socket.on('drain', function () {
        if (self.command === 'mailbody') {
            process.nextTick(function () { self.continue_data() });
        }
    });

    this.socket.on('error', function (err) {
        if (self.state == STATE_IDLE) {
            self.state = STATE_DEAD;
        }
        else {
            self.emit('error', 'SMTP connection failed: ' + err);
            self.pool.destroy(self);
        }
    });

    this.socket.on('timeout', function () {
        if (self.state == STATE_IDLE) {
            self.state = STATE_DEAD;
        }
        else {
            self.emit('error', 'SMTP connection timed out');
            self.pool.destroy(self);
        }
    });

    this.socket.on('close', function (had_error) {
        if (self.state == STATE_IDLE) {
            self.state = STATE_DEAD;
        }
        else {
            self.pool.destroy(self);
        }
    });
}

util.inherits(SMTPClient, events.EventEmitter);

SMTPClient.prototype.send_command = function (command, data) {
    var line = (command == 'dot') ? '.' : command + (data ? (' ' + data) : '');
    this.emit('client_protocol', line);
    this.command = command.toLowerCase();
    this.response = [];
    this.socket.write(line + "\r\n");
};

SMTPClient.prototype.start_data = function (data) {
    this.command = 'mailbody';
    if (data instanceof Function) {
        this.send_data = data;
    }
    else if (data instanceof Array) {
        var data_marker = 0;
        this.send_data = function () {
            while (data_marker < data.length) {
                var line = data[data_marker];
                data_marker++;
                if (!this.send_data_line(line)) {
                    return false;
                }
            }
            return true;
        };
    }
    else {
        this.send_data = function () {
            this.socket.write(data);
            return true;
        };
    }
    this.continue_data();
};

SMTPClient.prototype.continue_data = function () {
    if (!this.send_data()) {
        return;
    }
    this.send_command('dot');
};

SMTPClient.prototype.send_data_line = function (line) {
    line = line.replace(/^\./, '..').replace(/\r?\n/g, '\r\n');
    console.log('BODY: ' + line);
    return this.socket.write(line);
};

SMTPClient.prototype.release = function () {
    this.state = STATE_RELEASED;
    this.removeAllListeners();

    this.on('bad_code', function (code, msg) {
        this.pool.destroy(this);
    });

    this.on('rset', function () {
        this.state = STATE_IDLE;
        this.removeAllListeners();
        this.pool.release(this);
    });

    this.send_command('RSET');
};

// Separate pools are kept for each set of server attributes.
exports.get_pool = function (server, port, host, timeout, enable_tls, max) {
    var port = port || 25;
    var host = host || 'localhost';
    var timeout = (timeout == undefined) ? 300 : timeout;
    var enable_tls = /(true|yes|1)/i.exec(enable_tls) != null;
    var name = port + ':' + host + ':' + timeout + ':' + enable_tls;
    if (!server.notes.pool) {
        server.notes.pool = {};
    }
    if (!server.notes.pool[name]) {
        var pool = generic_pool.Pool({
            name: name,
            create: function (callback) {
                var smtp_client = new SMTPClient(port, host, timeout, enable_tls);
                callback(null, smtp_client);
            },
            destroy: function(smtp_client) {
                if (smtp_client.state != STATE_DEAD) {
                    smtp_client.socket.destroy();
                }
            },
            max: max || 1000,
            idleTimeoutMillis: timeout * 1000,
            log: function (str, level) {
                level = (level == 'verbose') ? 'debug' : level;
                logger['log' + level]('[smtp_client_pool] ' + str);
            }
        });

        var acquire = pool.acquire;
        pool.acquire = function (callback, priority) {
            var callback_wrapper = function (err, smtp_client) {
                if (smtp_client.state == STATE_DEAD) {
                    pool.acquire(callback, priority);
                    return;
                }
                smtp_client.pool = pool;
                smtp_client.state = STATE_ACTIVE;
                callback(err, smtp_client);
            };
            acquire.call(pool, callback_wrapper, priority);
        };
        server.notes.pool[name] = pool;
    }
    return server.notes.pool[name];
};

// Get a smtp_client for the given attributes.
exports.get_client = function (server, callback, port, host, timeout, enable_tls, max) {
    var pool = exports.get_pool(server, port, host, timeout, enable_tls, max);
    pool.acquire(callback);
};

// Get a smtp_client for the given attributes and set it up the common
// config and listeners for plugins. Currently this is what smtp_proxy and
// smtp_forward have in common.
exports.get_client_plugin = function (plugin, connection, config, callback) {
    var pool = exports.get_pool(connection.server, config.main.port,
        config.main.host, config.main.timeout, config.main.enable_tls,
        config.main.max);
    pool.acquire(function (err, smtp_client) {
        connection.logdebug(plugin, 'Got smtp_client (' + connection.uuid + ' ' + connection.transaction + ' ' + smtp_client.listeners('helo').length + ')');
        smtp_client.call_next = function (retval, msg) {
            if (this.next) {
                this.next(retval, msg);
                delete this.next;
            }
        };

        smtp_client.on('client_protocol', function (line) {
            connection.logprotocol(plugin, 'C: ' + line);
        });

        smtp_client.on('server_protocol', function (line) {
            connection.logprotocol(plugin, 'S: ' + line);
        });

        var helo = function (command) {
            if (smtp_client.xclient) {
                smtp_client.send_command(command, connection.hello_host);
            }
            else {
                smtp_client.send_command(command, plugin.config.get('me'));
            }
        };
        smtp_client.on('greeting', helo);
        smtp_client.on('xclient', helo);

        smtp_client.on('capabilities', function () {
            for (var line in smtp_client.response) {
                if (smtp_client.response[line].match(/^XCLIENT/)) {
                    if(!smtp_client.xclient) {
                        smtp_client.send_command('XCLIENT',
                            'ADDR=' + connection.remote_ip);
                        return;
                    }
                }
                if (smtp_client.response[line].match(/^STARTTLS/)) {
                    var key = plugin.config.get('tls_key.pem', 'data').join("\n");
                    var cert = plugin.config.get('tls_cert.pem', 'data').join("\n");
                    if (key && cert && enable_tls) {
                        smtp_client.socket.on('secure', function () {
                            smtp_client.emit('greeting', 'EHLO');
                        });
                        smtp_client.send_command('STARTTLS');
                        return;
                    }
                }
            }
        });

        smtp_client.on('helo', function () {
            connection.logdebug(plugin, 'Sending mail to in smtp_client (' + connection.uuid + ' ' + connection.transaction + ' ' + smtp_client.listeners('helo').length + ')');
            smtp_client.send_command('MAIL',
                'FROM:' + connection.transaction.mail_from);
        });

        smtp_client.on('dot', function () {
            smtp_client.call_next(constants.ok, smtp_client.response + ' (' + connection.transaction.uuid + ')');
            smtp_client.release();
        });

        smtp_client.on('error', function (msg) {
            connection.logerror(plugin, msg);
            smtp_client.call_next();
        });

        if (smtp_client.connected) {
            if (smtp_client.xclient) {
                smtp_client.send_command('XCLIENT',
                    'ADDR=' + connection.remote_ip);
            }
            else {
                smtp_client.emit('helo');
            }
        }

        callback(err, smtp_client);
    });
};
<|endoftext|>


<commit_before>/*jshint esnext:true*/
var fs = require("fs"),
    cards = require("./Cards"),
    Grid = require("./Grid"),
    Decks = require("./Decks.js"),
    Hand = require("./Hand.js");

/**
 * Represents a game
 * @param {Room} room     The parent Room
 * @param {[String]} cardSets List of card sets to use
 */
function Game(room,cardSets){
  this.room = room;
  this.hands = [];
  this.grid = new Grid(this);
  this.decks = new Decks(this);
  this.cardList = [];
  cardSets.forEach(this.loadCards.bind(this));
  this.setupDecks();

  //---- DEMO ----
  this.grid.addCard([0,0],this.cardList[0]);
  for(var i=0;i<this.decks.ponyCards.length;i++){
    if (this.decks.ponyCards[i].id === 0) break;
  }
  this.decks.ponyCards.splice(i,1);
  this.activePlayer = 0;
  //---- END DEMO ----
}

Game.prototype.newClient = function(client){
  var newHand = new Hand(client,this);
  newHand.drawCards(4,3);
  client.curHand = newHand;
  this.hands.push(newHand);
};

Game.prototype.isActivePlayer = function(client){
  return this.hands[this.activePlayer].client == client;
};

/**
 * Loads a card set from the given file and adds them to the usable card List
 * @param  {String}   file    File location to load the card list from
 */
Game.prototype.loadCards = function(file){
  var that = this;
  JSON.parse(fs.readFileSync(file)).forEach(function(rawCard){
    var card = cards.Card.fromObject(rawCard);
    card.id = that.cardList.length;
    if("special" in rawCard){ //XXX Special hack
      card.special = rawCard.special;
      console.log(JSON.stringify(card));
    }
    that.cardList.push(card);
  });
};

Game.prototype.setupDecks = function(){
  for(var i=0;i<this.cardList.length;i++){
    this.decks.addCard(i);
  }
  this.decks.shuffleShips();
  this.decks.shuffleGoals();
  this.decks.shufflePonies();
};

/**
 * Event handler to be called when a player plays a cards
 * Calculates all the results of the play then returns what needs to be done
 * @param  {Array}    Cards   List of Card id's and positions that where played
 * @param  {string}   Effect  The name of the effect that has been triggered by the play
 * @param  {[object]} Params  List of paramaters for the triggered effect, varies basied on effect
 * @param  {Client}   Client  The client who made the play
 * @return {Array}            List of Card id's and positions that should be reported back to the client to update their grid
 */
Game.prototype.onPlay = function(cards,params,client){

  //XXX Should be tidied up, im thinking an assert statment, that might be helpful
  var cc = this.hands[this.activePlayer].client;
  if(cc != client){
    client.send({type:"error",msg:"Not your turn, it is "+cc.name+" turn"});
    return;
  }

  if(params.length > 0 && this.cardList[params[0]].effect == "replace"){
    this.grid.replaceCard(params[1],params.shift());
    return [{id:params.shift(),position:null},cards[0]];
  } else {
    cards.forEach(c => this.grid.addCard(c.position,c.id));
    return cards.concat(this.resolveEffect(params,client));
  }
};

Game.prototype.resolveEffect = function(params,client){
  if(params.length === 0){
    console.warn("Empty effect paramaters - this is only normal if no effect triggered");
    return [];
  }
  var effect = this.cardList[params.shift()].effect;
  if(effect in this.effects){
    return this.effects[effect].call(this,params,client);
  } else {
    console.warn("No handler for effect",effect);
    return [];
  }
};

Game.prototype.effects = {
  swap:function(params,client){
    var swappedCards = this.grid.swapCards([params[0],params[1]]);
    return [].concat(
      swappedCards.map(c=>({id:c.id,position:null})), //Mark cards to remove
      swappedCards.map(c=>({id:c.id,position:c.position})) //Readd cards
    );
  },
  draw:function(params,client){
    var type = params.shift(),drawnCards,
        nPonies = type=="pony"? 1:0;
    client.curHand.drawCards(nPonies,1-nPonies);
    return [];
  },
  copy:Game.prototype.resolveEffect
};

/*Game hooks, checked after room */
Game.prototype.hooks = {};

Game.prototype.hooks.playCards = function(data,client){
  data.cards = this.onPlay(data.cards,data.params,client);
  data.client = client;
  data.type = "playCards";
  this.room.broadcast(data);
};

Game.prototype.hooks.reSyncGrid = function(data,client){
  client.send(this.room.packet("gridState"));
};

Game.prototype.hooks.endTurn = function(data,client){
  if (!this.isActivePlayer(client)){
    client.send({type:"error",msg:"Not your turn, it is "+cc.name+" turn"});
    return;
  }
  var cHand = client.curHand,
    handSizeNow = cHand.ponies.length + cHand.ships.length,
    handSizeAfter = handSizeNow + data.ponies + data.ships;
  if( handSizeAfter != 7){ //MAGIC Number
    client.send({type:"error",msg:"Attempt to draw wrong number of cards"});
    return;
  }
  client.curHand.drawCards(data.ponies, data.ships);
  this.activePlayer = (this.activePlayer+1)%this.hands.length;
  //TODO Add turnStart message
};

/*Game Packets - Called from Room.packet()*/
Game.prototype.packets = {};
Game.prototype.packets.cardList = function(){
  return {cardList:this.cardList};
};
Game.prototype.packets.gridState = function(){
  var grid=this.grid;
  return {grid:[].concat(
    Object.keys(grid.ponies).map(function(n){var c=grid.ponies[n];return {id:c.id,position:c.position};}),
    Object.keys(grid.ships).map(function(n){var c=grid.ships[n];return {id:c.id,position:c.position};})
  )};
};

module.exports = Game;
<commit_msg>Removed an old logging command<commit_after>/*jshint esnext:true*/
var fs = require("fs"),
    cards = require("./Cards"),
    Grid = require("./Grid"),
    Decks = require("./Decks.js"),
    Hand = require("./Hand.js");

/**
 * Represents a game
 * @param {Room} room     The parent Room
 * @param {[String]} cardSets List of card sets to use
 */
function Game(room,cardSets){
  this.room = room;
  this.hands = [];
  this.grid = new Grid(this);
  this.decks = new Decks(this);
  this.cardList = [];
  cardSets.forEach(this.loadCards.bind(this));
  this.setupDecks();

  //---- DEMO ----
  this.grid.addCard([0,0],this.cardList[0]);
  for(var i=0;i<this.decks.ponyCards.length;i++){
    if (this.decks.ponyCards[i].id === 0) break;
  }
  this.decks.ponyCards.splice(i,1);
  this.activePlayer = 0;
  //---- END DEMO ----
}

Game.prototype.newClient = function(client){
  var newHand = new Hand(client,this);
  newHand.drawCards(4,3);
  client.curHand = newHand;
  this.hands.push(newHand);
};

Game.prototype.isActivePlayer = function(client){
  return this.hands[this.activePlayer].client == client;
};

/**
 * Loads a card set from the given file and adds them to the usable card List
 * @param  {String}   file    File location to load the card list from
 */
Game.prototype.loadCards = function(file){
  var that = this;
  JSON.parse(fs.readFileSync(file)).forEach(function(rawCard){
    var card = cards.Card.fromObject(rawCard);
    card.id = that.cardList.length;
    if("special" in rawCard){ //XXX Special hack
      card.special = rawCard.special;
    }
    that.cardList.push(card);
  });
};

Game.prototype.setupDecks = function(){
  for(var i=0;i<this.cardList.length;i++){
    this.decks.addCard(i);
  }
  this.decks.shuffleShips();
  this.decks.shuffleGoals();
  this.decks.shufflePonies();
};

/**
 * Event handler to be called when a player plays a cards
 * Calculates all the results of the play then returns what needs to be done
 * @param  {Array}    Cards   List of Card id's and positions that where played
 * @param  {string}   Effect  The name of the effect that has been triggered by the play
 * @param  {[object]} Params  List of paramaters for the triggered effect, varies basied on effect
 * @param  {Client}   Client  The client who made the play
 * @return {Array}            List of Card id's and positions that should be reported back to the client to update their grid
 */
Game.prototype.onPlay = function(cards,params,client){

  //XXX Should be tidied up, im thinking an assert statment, that might be helpful
  var cc = this.hands[this.activePlayer].client;
  if(cc != client){
    client.send({type:"error",msg:"Not your turn, it is "+cc.name+" turn"});
    return;
  }

  if(params.length > 0 && this.cardList[params[0]].effect == "replace"){
    this.grid.replaceCard(params[1],params.shift());
    return [{id:params.shift(),position:null},cards[0]];
  } else {
    cards.forEach(c => this.grid.addCard(c.position,c.id));
    return cards.concat(this.resolveEffect(params,client));
  }
};

Game.prototype.resolveEffect = function(params,client){
  if(params.length === 0){
    console.warn("Empty effect paramaters - this is only normal if no effect triggered");
    return [];
  }
  var effect = this.cardList[params.shift()].effect;
  if(effect in this.effects){
    return this.effects[effect].call(this,params,client);
  } else {
    console.warn("No handler for effect",effect);
    return [];
  }
};

Game.prototype.effects = {
  swap:function(params,client){
    var swappedCards = this.grid.swapCards([params[0],params[1]]);
    return [].concat(
      swappedCards.map(c=>({id:c.id,position:null})), //Mark cards to remove
      swappedCards.map(c=>({id:c.id,position:c.position})) //Readd cards
    );
  },
  draw:function(params,client){
    var type = params.shift(),drawnCards,
        nPonies = type=="pony"? 1:0;
    client.curHand.drawCards(nPonies,1-nPonies);
    return [];
  },
  copy:Game.prototype.resolveEffect
};

/*Game hooks, checked after room */
Game.prototype.hooks = {};

Game.prototype.hooks.playCards = function(data,client){
  data.cards = this.onPlay(data.cards,data.params,client);
  data.client = client;
  data.type = "playCards";
  this.room.broadcast(data);
};

Game.prototype.hooks.reSyncGrid = function(data,client){
  client.send(this.room.packet("gridState"));
};

Game.prototype.hooks.endTurn = function(data,client){
  if (!this.isActivePlayer(client)){
    client.send({type:"error",msg:"Not your turn, it is "+cc.name+" turn"});
    return;
  }
  var cHand = client.curHand,
    handSizeNow = cHand.ponies.length + cHand.ships.length,
    handSizeAfter = handSizeNow + data.ponies + data.ships;
  if( handSizeAfter != 7){ //MAGIC Number
    client.send({type:"error",msg:"Attempt to draw wrong number of cards"});
    return;
  }
  client.curHand.drawCards(data.ponies, data.ships);
  this.activePlayer = (this.activePlayer+1)%this.hands.length;
  //TODO Add turnStart message
};

/*Game Packets - Called from Room.packet()*/
Game.prototype.packets = {};
Game.prototype.packets.cardList = function(){
  return {cardList:this.cardList};
};
Game.prototype.packets.gridState = function(){
  var grid=this.grid;
  return {grid:[].concat(
    Object.keys(grid.ponies).map(function(n){var c=grid.ponies[n];return {id:c.id,position:c.position};}),
    Object.keys(grid.ships).map(function(n){var c=grid.ships[n];return {id:c.id,position:c.position};})
  )};
};

module.exports = Game;
<|endoftext|>


<commit_before>var Tile = require('./tile');

// this is what a deck should look like
  // [ {id: a0, orientation: 0}, {id: a1, orientation: 0}, ... ]

// takes a `spec` argument
// the spec is an object, it contains letter keys (i.e. a, b, c)
  // and its values are arrays that contain integers representing the number of
  // each card in the deck.
// if that is confusing just look at the `cards` object below and it might make sense...
var Deck = function(spec){
  this.deck = [];
  for (var key in spec){
    for (var i = 0; i < spec[key].length; i++) {
      this.deck.push(new Tile ( key + spec[key][i] ));
    }
  }
};

// classic fisher-yates shuffle
// operates on this.deck
Deck.prototype.shuffle = function() {
  if (this.deck.length === 0) {
    console.log('you dun goofed, your deck is empty');
  }
  var currentIndex = this.deck.length, temporaryValue, randomIndex;
  while (0 !== currentIndex){
    randomIndex = Math.floor( Math.random () * currentIndex );
    currentIndex -= 1;
    temporaryValue = this.deck[currentIndex];
    this.deck[currentIndex] = this.deck[randomIndex];
    this.deck[randomIndex] = temporaryValue;
  }

  // if group approves _ inclusion, replace all that with
  // _.shuffle(this.deck);
};

// returns the card from the top of the deck
Deck.prototype.pop = function() {
  return this.deck.pop();
};

module.exports = Deck;<commit_msg>refactor deck to shuffle itself upon instantiation refactor deck to use new style of deckSpec refactor comments about deck/deckSpec<commit_after>var Tile = require('./tile');
// var spec = require('./deckSpec');

// this is what a deck should look like
  // [ {id: a0, orientation: 0}, {id: a1, orientation: 0}, ... ]

// takes a `spec` argument
// the spec is an object, it contains letter keys (i.e. a, b, c)
  // and its values are integers representing the number of
  // each of that card in the deck.
// if that is confusing just look at the `cards` object below and it might make sense...
var Deck = function(spec){
  this.deck = [];
  for (var key in spec){
    for (var i = 0; i < spec[key]; i++) {
      this.deck.push(new Tile ( key + i ));
    }
  }
  Deck.prototype.shuffle.call(this);
};

// classic fisher-yates shuffle
// operates on this.deck
Deck.prototype.shuffle = function() {
  if (this.deck.length === 0) {
    console.log('you dun goofed, your deck is empty');
  }
  var currentIndex = this.deck.length, temporaryValue, randomIndex;
  while (0 !== currentIndex){
    randomIndex = Math.floor( Math.random () * currentIndex );
    currentIndex -= 1;
    temporaryValue = this.deck[currentIndex];
    this.deck[currentIndex] = this.deck[randomIndex];
    this.deck[randomIndex] = temporaryValue;
  }

  // if group approves _ inclusion, replace all that with
  // _.shuffle(this.deck);
};

// removes and returns the card from the top of the deck
Deck.prototype.pop = function() {
  return this.deck.pop();
};

// returns the card at the top of the deck without removing it
Deck.prototype.peek = function() {
  return this.deck[ this.deck.length - 1 ];
};

module.exports = Deck;<|endoftext|>


<commit_before>'use strict';

const express = require('express');

const app = express();

app.get('/', (req, res) => {
    res.render('./../app/index.ejs');
});
app.use(express.static(__dirname + '/../tmp'));
app.listen(7777);
<commit_msg>Create End point for items list<commit_after>'use strict';

const express = require('express');
const bodyParser = require('body-parser');

const app = express();

app.get('/', (req, res) => {
    res.render('./../app/index.ejs');
});
app.use(express.static(__dirname + '/../tmp'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
    extended: false
}));

app.listen(7777);
require('./routes/items')(app);
<|endoftext|>


<commit_before>import { Meteor } from 'meteor/meteor';
import { AppLogs, UserData, Bounties} from '/imports/api/indexDB.js';
import { generateBounties, createtypes, fetchHashrate } from '/imports/api/utilities'

import '/imports/startup/server'

//import * as jobs from './API_requests/github.js';

SyncedCron.add({
  name: 'Tabulate ELO values',
  schedule: function(parser) {
    return parser.text('every 10 minutes');
  },
  job: function() {
    Meteor.call('tabulateElo', (err, data) => {})
  }
});

// FastRender.route('/', function(){
// SubsCache.subscribe('approvedcurrencies');
// });

Meteor.startup(() => {
//jobs.initiate_later();
SyncedCron.start();
Meteor.call('convertAlgorithm', (err, data) => {})
//jobs.print();
  // code to run on server at startup
});<commit_msg>Problem: forget password email not working<commit_after>import '/imports/startup/server'

SyncedCron.add({
  name: 'Tabulate ELO values',
  schedule: function (parser) {
    return parser.text('every 10 minutes');
  },
  job: function () {
    Meteor.call('tabulateElo', (err, data) => { })
  }
})

// FastRender.route('/', function(){
// SubsCache.subscribe('approvedcurrencies');
// });

Meteor.startup(() => {
  MAIL_URL = process.env.MAIL_URL
  SyncedCron.start()
  Meteor.call('convertAlgorithm', (err, data) => { })
})<|endoftext|>


<commit_before>Meteor.startup(() => {

  Meteor.isElectron = (Meteor.server.method_handlers['electrify.get.socket.port']() !== null);

  buildIntelligence();

  Meteor.methods({
    'openVossistanWindow': function(isDevelopment) {
      var port = isDevelopment ? 3000 : Meteor.server.method_handlers['electrify.get.socket.port']();
      commands.execute({command: {
        application: 'browser',
        parameters: ['http://localhost:' + port]
      }}, false);
    },
    'inbound': function(text, language, textId) {

      _ = function(txt, opts) {
        return TAPi18n.__(txt, opts, language);
      }
      moment.locale(language);

      var analysis = textRequest(text, language);

      if (!!analysis) {

        if (!!actions[analysis.intention]) {

          var action = actions[analysis.intention](analysis);

          if (!action) return false;

          if (!!action.command) {
            if (action.command.application === 'mongo') {
              Meteor.users.update({
                _id: Meteor.userId()
              }, {$set: action.command.parameters});
              delete action.command;
            } else {
              if (commands.execute(action, false)) {
                delete action.command;
              }
            }
          }

          var data = {};
          Object.assign(data, action, analysis);

          chat.update({_id: textId}, {
            $set: {data:data}
          });

          return action;
        }
      } else {
        chat.update({_id: textId}, {
          $set: {data: {} }
        });
      }

      return analysis;

    }
  });

});
<commit_msg>electron app opens correct port<commit_after>Meteor.startup(() => {

  Meteor.isElectron = (Meteor.server.method_handlers['electrify.get.socket.port']() !== null);

  buildIntelligence();

  Meteor.methods({
    'openVossistanWindow': function(isDevelopment) {
      var port = 0;
      if (isDevelopment) { port = 3000; } else {
        var _port = Number(Meteor.server.method_handlers['electrify.get.socket.port']());
        port = ++_port;
      }
      commands.execute({command: {
        application: 'browser',
        parameters: ['http://localhost:' + port]
      }}, false);
    },
    'inbound': function(text, language, textId) {

      _ = function(txt, opts) {
        return TAPi18n.__(txt, opts, language);
      }
      moment.locale(language);

      var analysis = textRequest(text, language);

      if (!!analysis) {

        if (!!actions[analysis.intention]) {

          var action = actions[analysis.intention](analysis);

          if (!action) return false;

          if (!!action.command) {
            if (action.command.application === 'mongo') {
              Meteor.users.update({
                _id: Meteor.userId()
              }, {$set: action.command.parameters});
              delete action.command;
            } else {
              if (commands.execute(action, false)) {
                delete action.command;
              }
            }
          }

          var data = {};
          Object.assign(data, action, analysis);

          chat.update({_id: textId}, {
            $set: {data:data}
          });

          return action;
        }
      } else {
        chat.update({_id: textId}, {
          $set: {data: {} }
        });
      }

      return analysis;

    }
  });

});
<|endoftext|>