<commit_before>/*
  Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
  Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*jslint vars:false*/
/*jshint indent:4*/
/*global exports:true, define:true, window:true*/
(function (factory) {
    'use strict';

    // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
    // and plain browser loading,
    if (typeof define === 'function' && define.amd) {
        define(['exports'], factory);
    } else if (typeof exports !== 'undefined') {
        factory(exports);
    } else {
        factory((window.estraverse = {}));
    }
}(function (exports) {
    'use strict';

    var Syntax,
        isArray,
        VisitorOption,
        VisitorKeys,
        wrappers;

    Syntax = {
        AssignmentExpression: 'AssignmentExpression',
        ArrayExpression: 'ArrayExpression',
        BlockStatement: 'BlockStatement',
        BinaryExpression: 'BinaryExpression',
        BreakStatement: 'BreakStatement',
        CallExpression: 'CallExpression',
        CatchClause: 'CatchClause',
        ConditionalExpression: 'ConditionalExpression',
        ContinueStatement: 'ContinueStatement',
        DebuggerStatement: 'DebuggerStatement',
        DirectiveStatement: 'DirectiveStatement',
        DoWhileStatement: 'DoWhileStatement',
        EmptyStatement: 'EmptyStatement',
        ExpressionStatement: 'ExpressionStatement',
        ForStatement: 'ForStatement',
        ForInStatement: 'ForInStatement',
        FunctionDeclaration: 'FunctionDeclaration',
        FunctionExpression: 'FunctionExpression',
        Identifier: 'Identifier',
        IfStatement: 'IfStatement',
        Literal: 'Literal',
        LabeledStatement: 'LabeledStatement',
        LogicalExpression: 'LogicalExpression',
        MemberExpression: 'MemberExpression',
        NewExpression: 'NewExpression',
        ObjectExpression: 'ObjectExpression',
        Program: 'Program',
        Property: 'Property',
        ReturnStatement: 'ReturnStatement',
        SequenceExpression: 'SequenceExpression',
        SwitchStatement: 'SwitchStatement',
        SwitchCase: 'SwitchCase',
        ThisExpression: 'ThisExpression',
        ThrowStatement: 'ThrowStatement',
        TryStatement: 'TryStatement',
        UnaryExpression: 'UnaryExpression',
        UpdateExpression: 'UpdateExpression',
        VariableDeclaration: 'VariableDeclaration',
        VariableDeclarator: 'VariableDeclarator',
        WhileStatement: 'WhileStatement',
        WithStatement: 'WithStatement'
    };

    isArray = Array.isArray;
    if (!isArray) {
        isArray = function isArray(array) {
            return Object.prototype.toString.call(array) === '[object Array]';
        };
    }

    VisitorKeys = {
        AssignmentExpression: ['left', 'right'],
        ArrayExpression: ['elements'],
        BlockStatement: ['body'],
        BinaryExpression: ['left', 'right'],
        BreakStatement: ['label'],
        CallExpression: ['callee', 'arguments'],
        CatchClause: ['param', 'body'],
        ConditionalExpression: ['test', 'consequent', 'alternate'],
        ContinueStatement: ['label'],
        DebuggerStatement: [],
        DirectiveStatement: [],
        DoWhileStatement: ['body', 'test'],
        EmptyStatement: [],
        ExpressionStatement: ['expression'],
        ForStatement: ['init', 'test', 'update', 'body'],
        ForInStatement: ['left', 'right', 'body'],
        FunctionDeclaration: ['id', 'params', 'body'],
        FunctionExpression: ['id', 'params', 'body'],
        Identifier: [],
        IfStatement: ['test', 'consequent', 'alternate'],
        Literal: [],
        LabeledStatement: ['label', 'body'],
        LogicalExpression: ['left', 'right'],
        MemberExpression: ['object', 'property'],
        NewExpression: ['callee', 'arguments'],
        ObjectExpression: ['properties'],
        Program: ['body'],
        Property: ['key', 'value'],
        ReturnStatement: ['argument'],
        SequenceExpression: ['expressions'],
        SwitchStatement: ['discriminant', 'cases'],
        SwitchCase: ['test', 'consequent'],
        ThisExpression: [],
        ThrowStatement: ['argument'],
        TryStatement: ['block', 'handlers', 'finalizer'],
        UnaryExpression: ['argument'],
        UpdateExpression: ['argument'],
        VariableDeclaration: ['declarations'],
        VariableDeclarator: ['id', 'init'],
        WhileStatement: ['test', 'body'],
        WithStatement: ['object', 'body']
    };

    VisitorOption = {
        Break: 1,
        Skip: 2
    };

    wrappers = {
        PropertyWrapper: 'Property'
    };

    function Reference(parent, key) {
        this.parent = parent;
        this.key = key;
    }

    Reference.prototype.replace = function replace(node) {
        this.parent[this.key] = node;
    };

    function Element(node, path, wrap, ref) {
        this.node = node;
        this.path = path;
        this.wrap = wrap;
        this.ref = ref;
    }

    function Controller(root, visitor) {
        this.visitor = visitor;
        this.root = root;
        this.__worklist = [];
        this.__leavelist = [];
        this.__current = null;
        this.__state = null;
    }

    // API:
    // return property path from root to current node
    Controller.prototype.path = function path() {
        var i, iz, result, element;

        // first node is sentinel
        result = [];
        for (i = 1, iz = this.__leavelist.length; i < iz; ++i) {
            element = this.__leavelist[i];
            result.push(element.path);
        }
        result.push(this.__current.path);

        return '$' + result.join('.');
    };

    // API:
    // return array of parent elements
    Controller.prototype.parents = function parents() {
        var i, iz, result;

        // first node is sentinel
        result = [];
        for (i = 1, iz = this.__leavelist.length; i < iz; ++i) {
            result.push(this.__leavelist[i].node);
        }

        return result;
    };

    // API:
    // return current node
    Controller.prototype.current = function current() {
        return this.__current.node;
    };

    Controller.prototype.__execute = function __execute(callback, element) {
        var previous, result;
        previous  = this.__current;
        this.__current = element;
        this.__state = null;
        result = callback.call(this, element.node, this.__leavelist[this.__leavelist.length - 1].node);
        this.__current = previous;
        return result;
    };

    Controller.prototype.notify = function notify(flag) {
        this.__state = flag;
    };

    Controller.prototype.skip = function () {
        this.notify(VisitorOption.Skip);
    };

    Controller.prototype['break'] = function () {
        this.notify(VisitorOption.Break);
    };

    function traverse(root, visitor) {
        var worklist,
            leavelist,
            element,
            node,
            nodeType,
            ret,
            key,
            current,
            current2,
            candidates,
            candidate,
            sentinel,
            controller;

        sentinel = {};
        controller = new Controller(root, visitor);

        // reference
        worklist = controller.__worklist;
        leavelist = controller.__leavelist;

        // initialize
        worklist.push(new Element(root, '', null, null));
        leavelist.push(new Element(null, '', null, null));

        while (worklist.length) {
            element = worklist.pop();

            if (element === sentinel) {
                element = leavelist.pop();

                ret = (visitor.leave) ? controller.__execute(visitor.leave, element) : null;

                if (controller.__state === VisitorOption.Break || ret === VisitorOption.Break) {
                    return;
                }
                continue;
            }

            if (element.node) {

                ret = (visitor.enter) ? controller.__execute(visitor.enter, element) : null;

                if (controller.__state === VisitorOption.Break || ret === VisitorOption.Break) {
                    return;
                }

                worklist.push(sentinel);
                leavelist.push(element);

                if (controller.__state === VisitorOption.Skip || ret === VisitorOption.Skip) {
                    continue;
                }

                node = element.node;
                nodeType = element.wrap || node.type;
                candidates = VisitorKeys[nodeType];

                current = candidates.length;
                while ((current -= 1) >= 0) {
                    key = candidates[current];
                    candidate = node[key];
                    if (!candidate) {
                        continue;
                    }

                    if (!isArray(candidate)) {
                        worklist.push(new Element(candidate, key, null, null));
                        continue;
                    }

                    current2 = candidate.length;
                    while ((current2 -= 1) >= 0) {
                        if (!candidate[current2]) {
                            continue;
                        }
                        if (nodeType === Syntax.ObjectExpression && 'properties' === candidates[current] && null == candidates[current].type) {
                            element = new Element(candidate[current2], key + '[' + current2 + ']', 'Property', null);
                        } else {
                            element = new Element(candidate[current2], key + '[' + current2 + ']', null, null);
                        }
                        worklist.push(element);
                    }
                }
            }
        }
    }

    function replace(root, visitor) {
        var worklist,
            leavelist,
            node,
            nodeType,
            target,
            element,
            current,
            current2,
            candidates,
            candidate,
            sentinel,
            controller,
            outer,
            key;

        sentinel = {};
        controller = new Controller(root, visitor);

        // reference
        worklist = controller.__worklist;
        leavelist = controller.__leavelist;

        // initialize
        outer = {
            root: root
        };
        element = new Element(root, '', null, new Reference(outer, 'root'));
        worklist.push(element);
        leavelist.push(element);

        while (worklist.length) {
            element = worklist.pop();

            if (element === sentinel) {
                element = leavelist.pop();

                if (visitor.leave) {
                    target = controller.__execute(visitor.leave, element);

                    // node may be replaced with null,
                    // so distinguish between undefined and null in this place
                    if (target !== undefined) {
                        // replace
                        element.ref.replace(target);
                    }
                }

                if (controller.__state === VisitorOption.Break) {
                    return outer.root;
                }
                continue;
            }

            if (visitor.enter) {
                target = controller.__execute(visitor.enter, element);

                // node may be replaced with null,
                // so distinguish between undefined and null in this place
                if (target !== undefined) {
                    // replace
                    element.ref.replace(target);
                    element.node = target;
                }
            }

            if (controller.__state === VisitorOption.Break) {
                return outer.root;
            }

            // node may be null
            node = element.node;
            if (!node) {
                continue;
            }

            worklist.push(sentinel);
            leavelist.push(element);

            if (controller.__state === VisitorOption.Skip) {
                continue;
            }

            nodeType = element.wrap || node.type;
            candidates = VisitorKeys[nodeType];

            current = candidates.length;
            while ((current -= 1) >= 0) {
                key = candidates[current];
                candidate = node[key];
                if (!candidate) {
                    continue;
                }

                if (!isArray(candidate)) {
                    worklist.push(new Element(candidate, key, null, new Reference(node, key)));
                    continue;
                }

                current2 = candidate.length;
                while ((current2 -= 1) >= 0) {
                    if (!candidate[current2]) {
                        continue;
                    }
                    if (nodeType === Syntax.ObjectExpression && 'properties' === candidates[current] && null == candidates[current].type) {
                        element = new Element(candidate[current2], key + '[' + current2 + ']', 'Property', new Reference(candidate, current2));
                    } else {
                        element = new Element(candidate[current2], key + '[' + current2 + ']', null, new Reference(candidate, current2));
                    }
                    worklist.push(element);
                }
            }
        }

        return outer.root;
    }

    exports.version = '1.0.1-dev';
    exports.Syntax = Syntax;
    exports.traverse = traverse;
    exports.replace = replace;
    exports.VisitorKeys = VisitorKeys;
    exports.VisitorOption = VisitorOption;
    exports.Controller = Controller;
}));
/* vim: set sw=4 ts=4 et tw=80 : */
<commit_msg>Remove wrappers<commit_after>/*
  Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
  Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*jslint vars:false*/
/*jshint indent:4*/
/*global exports:true, define:true, window:true*/
(function (factory) {
    'use strict';

    // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
    // and plain browser loading,
    if (typeof define === 'function' && define.amd) {
        define(['exports'], factory);
    } else if (typeof exports !== 'undefined') {
        factory(exports);
    } else {
        factory((window.estraverse = {}));
    }
}(function (exports) {
    'use strict';

    var Syntax,
        isArray,
        VisitorOption,
        VisitorKeys;

    Syntax = {
        AssignmentExpression: 'AssignmentExpression',
        ArrayExpression: 'ArrayExpression',
        BlockStatement: 'BlockStatement',
        BinaryExpression: 'BinaryExpression',
        BreakStatement: 'BreakStatement',
        CallExpression: 'CallExpression',
        CatchClause: 'CatchClause',
        ConditionalExpression: 'ConditionalExpression',
        ContinueStatement: 'ContinueStatement',
        DebuggerStatement: 'DebuggerStatement',
        DirectiveStatement: 'DirectiveStatement',
        DoWhileStatement: 'DoWhileStatement',
        EmptyStatement: 'EmptyStatement',
        ExpressionStatement: 'ExpressionStatement',
        ForStatement: 'ForStatement',
        ForInStatement: 'ForInStatement',
        FunctionDeclaration: 'FunctionDeclaration',
        FunctionExpression: 'FunctionExpression',
        Identifier: 'Identifier',
        IfStatement: 'IfStatement',
        Literal: 'Literal',
        LabeledStatement: 'LabeledStatement',
        LogicalExpression: 'LogicalExpression',
        MemberExpression: 'MemberExpression',
        NewExpression: 'NewExpression',
        ObjectExpression: 'ObjectExpression',
        Program: 'Program',
        Property: 'Property',
        ReturnStatement: 'ReturnStatement',
        SequenceExpression: 'SequenceExpression',
        SwitchStatement: 'SwitchStatement',
        SwitchCase: 'SwitchCase',
        ThisExpression: 'ThisExpression',
        ThrowStatement: 'ThrowStatement',
        TryStatement: 'TryStatement',
        UnaryExpression: 'UnaryExpression',
        UpdateExpression: 'UpdateExpression',
        VariableDeclaration: 'VariableDeclaration',
        VariableDeclarator: 'VariableDeclarator',
        WhileStatement: 'WhileStatement',
        WithStatement: 'WithStatement'
    };

    isArray = Array.isArray;
    if (!isArray) {
        isArray = function isArray(array) {
            return Object.prototype.toString.call(array) === '[object Array]';
        };
    }

    VisitorKeys = {
        AssignmentExpression: ['left', 'right'],
        ArrayExpression: ['elements'],
        BlockStatement: ['body'],
        BinaryExpression: ['left', 'right'],
        BreakStatement: ['label'],
        CallExpression: ['callee', 'arguments'],
        CatchClause: ['param', 'body'],
        ConditionalExpression: ['test', 'consequent', 'alternate'],
        ContinueStatement: ['label'],
        DebuggerStatement: [],
        DirectiveStatement: [],
        DoWhileStatement: ['body', 'test'],
        EmptyStatement: [],
        ExpressionStatement: ['expression'],
        ForStatement: ['init', 'test', 'update', 'body'],
        ForInStatement: ['left', 'right', 'body'],
        FunctionDeclaration: ['id', 'params', 'body'],
        FunctionExpression: ['id', 'params', 'body'],
        Identifier: [],
        IfStatement: ['test', 'consequent', 'alternate'],
        Literal: [],
        LabeledStatement: ['label', 'body'],
        LogicalExpression: ['left', 'right'],
        MemberExpression: ['object', 'property'],
        NewExpression: ['callee', 'arguments'],
        ObjectExpression: ['properties'],
        Program: ['body'],
        Property: ['key', 'value'],
        ReturnStatement: ['argument'],
        SequenceExpression: ['expressions'],
        SwitchStatement: ['discriminant', 'cases'],
        SwitchCase: ['test', 'consequent'],
        ThisExpression: [],
        ThrowStatement: ['argument'],
        TryStatement: ['block', 'handlers', 'finalizer'],
        UnaryExpression: ['argument'],
        UpdateExpression: ['argument'],
        VariableDeclaration: ['declarations'],
        VariableDeclarator: ['id', 'init'],
        WhileStatement: ['test', 'body'],
        WithStatement: ['object', 'body']
    };

    VisitorOption = {
        Break: 1,
        Skip: 2
    };

    function Reference(parent, key) {
        this.parent = parent;
        this.key = key;
    }

    Reference.prototype.replace = function replace(node) {
        this.parent[this.key] = node;
    };

    function Element(node, path, wrap, ref) {
        this.node = node;
        this.path = path;
        this.wrap = wrap;
        this.ref = ref;
    }

    function Controller(root, visitor) {
        this.visitor = visitor;
        this.root = root;
        this.__worklist = [];
        this.__leavelist = [];
        this.__current = null;
        this.__state = null;
    }

    // API:
    // return property path from root to current node
    Controller.prototype.path = function path() {
        var i, iz, result, element;

        // first node is sentinel
        result = [];
        for (i = 1, iz = this.__leavelist.length; i < iz; ++i) {
            element = this.__leavelist[i];
            result.push(element.path);
        }
        result.push(this.__current.path);

        return '$' + result.join('.');
    };

    // API:
    // return array of parent elements
    Controller.prototype.parents = function parents() {
        var i, iz, result;

        // first node is sentinel
        result = [];
        for (i = 1, iz = this.__leavelist.length; i < iz; ++i) {
            result.push(this.__leavelist[i].node);
        }

        return result;
    };

    // API:
    // return current node
    Controller.prototype.current = function current() {
        return this.__current.node;
    };

    Controller.prototype.__execute = function __execute(callback, element) {
        var previous, result;
        previous  = this.__current;
        this.__current = element;
        this.__state = null;
        result = callback.call(this, element.node, this.__leavelist[this.__leavelist.length - 1].node);
        this.__current = previous;
        return result;
    };

    Controller.prototype.notify = function notify(flag) {
        this.__state = flag;
    };

    Controller.prototype.skip = function () {
        this.notify(VisitorOption.Skip);
    };

    Controller.prototype['break'] = function () {
        this.notify(VisitorOption.Break);
    };

    function traverse(root, visitor) {
        var worklist,
            leavelist,
            element,
            node,
            nodeType,
            ret,
            key,
            current,
            current2,
            candidates,
            candidate,
            sentinel,
            controller;

        sentinel = {};
        controller = new Controller(root, visitor);

        // reference
        worklist = controller.__worklist;
        leavelist = controller.__leavelist;

        // initialize
        worklist.push(new Element(root, '', null, null));
        leavelist.push(new Element(null, '', null, null));

        while (worklist.length) {
            element = worklist.pop();

            if (element === sentinel) {
                element = leavelist.pop();

                ret = (visitor.leave) ? controller.__execute(visitor.leave, element) : null;

                if (controller.__state === VisitorOption.Break || ret === VisitorOption.Break) {
                    return;
                }
                continue;
            }

            if (element.node) {

                ret = (visitor.enter) ? controller.__execute(visitor.enter, element) : null;

                if (controller.__state === VisitorOption.Break || ret === VisitorOption.Break) {
                    return;
                }

                worklist.push(sentinel);
                leavelist.push(element);

                if (controller.__state === VisitorOption.Skip || ret === VisitorOption.Skip) {
                    continue;
                }

                node = element.node;
                nodeType = element.wrap || node.type;
                candidates = VisitorKeys[nodeType];

                current = candidates.length;
                while ((current -= 1) >= 0) {
                    key = candidates[current];
                    candidate = node[key];
                    if (!candidate) {
                        continue;
                    }

                    if (!isArray(candidate)) {
                        worklist.push(new Element(candidate, key, null, null));
                        continue;
                    }

                    current2 = candidate.length;
                    while ((current2 -= 1) >= 0) {
                        if (!candidate[current2]) {
                            continue;
                        }
                        if (nodeType === Syntax.ObjectExpression && 'properties' === candidates[current] && null == candidates[current].type) {
                            element = new Element(candidate[current2], key + '[' + current2 + ']', 'Property', null);
                        } else {
                            element = new Element(candidate[current2], key + '[' + current2 + ']', null, null);
                        }
                        worklist.push(element);
                    }
                }
            }
        }
    }

    function replace(root, visitor) {
        var worklist,
            leavelist,
            node,
            nodeType,
            target,
            element,
            current,
            current2,
            candidates,
            candidate,
            sentinel,
            controller,
            outer,
            key;

        sentinel = {};
        controller = new Controller(root, visitor);

        // reference
        worklist = controller.__worklist;
        leavelist = controller.__leavelist;

        // initialize
        outer = {
            root: root
        };
        element = new Element(root, '', null, new Reference(outer, 'root'));
        worklist.push(element);
        leavelist.push(element);

        while (worklist.length) {
            element = worklist.pop();

            if (element === sentinel) {
                element = leavelist.pop();

                if (visitor.leave) {
                    target = controller.__execute(visitor.leave, element);

                    // node may be replaced with null,
                    // so distinguish between undefined and null in this place
                    if (target !== undefined) {
                        // replace
                        element.ref.replace(target);
                    }
                }

                if (controller.__state === VisitorOption.Break) {
                    return outer.root;
                }
                continue;
            }

            if (visitor.enter) {
                target = controller.__execute(visitor.enter, element);

                // node may be replaced with null,
                // so distinguish between undefined and null in this place
                if (target !== undefined) {
                    // replace
                    element.ref.replace(target);
                    element.node = target;
                }
            }

            if (controller.__state === VisitorOption.Break) {
                return outer.root;
            }

            // node may be null
            node = element.node;
            if (!node) {
                continue;
            }

            worklist.push(sentinel);
            leavelist.push(element);

            if (controller.__state === VisitorOption.Skip) {
                continue;
            }

            nodeType = element.wrap || node.type;
            candidates = VisitorKeys[nodeType];

            current = candidates.length;
            while ((current -= 1) >= 0) {
                key = candidates[current];
                candidate = node[key];
                if (!candidate) {
                    continue;
                }

                if (!isArray(candidate)) {
                    worklist.push(new Element(candidate, key, null, new Reference(node, key)));
                    continue;
                }

                current2 = candidate.length;
                while ((current2 -= 1) >= 0) {
                    if (!candidate[current2]) {
                        continue;
                    }
                    if (nodeType === Syntax.ObjectExpression && 'properties' === candidates[current] && null == candidates[current].type) {
                        element = new Element(candidate[current2], key + '[' + current2 + ']', 'Property', new Reference(candidate, current2));
                    } else {
                        element = new Element(candidate[current2], key + '[' + current2 + ']', null, new Reference(candidate, current2));
                    }
                    worklist.push(element);
                }
            }
        }

        return outer.root;
    }

    exports.version = '1.0.1-dev';
    exports.Syntax = Syntax;
    exports.traverse = traverse;
    exports.replace = replace;
    exports.VisitorKeys = VisitorKeys;
    exports.VisitorOption = VisitorOption;
    exports.Controller = Controller;
}));
/* vim: set sw=4 ts=4 et tw=80 : */
<|endoftext|>


<commit_before>const SlackBots = require('slackbots');
const util = require('util');
const EventEmitter = require('events');

function SlackBot (config) {
    EventEmitter.call(this);
    var SlackBot = this;

    this.bot = new SlackBots({
        token: config.token,
        name: config.name
    });

    this.type = 'slack';

    /*
    this.bot.on('start', function() {
        SlackBot.emit('online');
    });*/

    this.sendMessage = function (message) {
        /*
        var params = {
            "icon_emoji": message.icon_emoji
        };
        SlackBot.bot.postMessageToUser(config.login, message.text, params).always(function(data) {

        });*/
    };

    /*
    this.bot.on('message', function (message) {
        if (message.username != config.name && message.type == 'message') {
            //SlackBot.emit('message', message);
        }
    });*/
}

util.inherits(SlackBot, EventEmitter);

module.exports = SlackBot;
<commit_msg>remove code<commit_after>const SlackBots = require('slackbots');
const util = require('util');
const EventEmitter = require('events');

function SlackBot (config) {
    EventEmitter.call(this);
    var SlackBot = this;

    this.bot = new SlackBots({
        token: config.token,
        name: config.name
    });

    this.type = 'slack';

    this.bot.on('start', function() {
    //    SlackBot.emit('online');
    });

    this.sendMessage = function (message) {
        /*
        var params = {
            "icon_emoji": message.icon_emoji
        };
        SlackBot.bot.postMessageToUser(config.login, message.text, params).always(function(data) {

        });*/
    };

    /*
    this.bot.on('message', function (message) {
        if (message.username != config.name && message.type == 'message') {
            //SlackBot.emit('message', message);
        }
    });*/
}

util.inherits(SlackBot, EventEmitter);

module.exports = SlackBot;
<|endoftext|>


<commit_before>'use strict';
describe('$store', function() {
  describe('configure', function() {
    var storeProvider;

    beforeEach(function() {
      angular.module('test.store', function() {})
        .config(function($storeProvider) {
          storeProvider = $storeProvider;
        });

      module('local.storage', 'test.store');

      inject(function() {});
    });

    it('should default cookieFallback to true', function() {
      storeProvider.configure().cookieFallback.should.be.true;
    });

    it('should properly set cookiefallback to false', function() {
      storeProvider.configure({cookieFallback: false}).cookieFallback.should.be.false;
    });

    it('should default useSessionStorage to false', function() {
      storeProvider.configure().useSessionStorage.should.be.false;
    });

    it('should properly set useSessionStorage to true', function() {
      storeProvider.configure({useSessionStorage: true}).useSessionStorage.should.be.true;
    });
  });

  describe('$get', function() {
    beforeEach(module('local.storage'));

    it('should have a list of functions', inject(function($store) {
      var functions = ['set', 'get', 'remove', 'bind', 'unbind', 'has', 'clear'];
      for (var i in functions) {
        $store[functions[i]].should.be.a.Function;
      }
    }));

    describe('set', function() {
      it('should remove a key if set is called with an empty value', inject(function($store) {
        sinon.spy($store, 'remove');
        var result = $store.set('foo');
        $store.remove.calledOnce.should.be.true;
        (result === undefined).should.be.true;
      }));

      it('should transform the value into json and set the key', inject(function($store) {
        sinon.spy($store.getStorage(), 'setItem');
        sinon.spy(angular, 'toJson');
        var result = $store.set('foo', {bar: 'a'});
        $store.getStorage().setItem.calledOnce.should.be.true;
        angular.toJson.calledOnce.should.be.true;
        result.should.eql({bar: 'a'});
      }));

      it('should store info in the cookie store if the environment is not supported', inject(function($store, $cookieStore) {
        sinon.spy($cookieStore, 'put');
        $store.setSupported(false);
        var result = $store.set('foo', 'bar');
        $cookieStore.put.calledOnce.should.be.true;
        result.should.equal('bar');
      }));

      it('should store info in the memStorage if the environment is not supported and cookie fallback is disabled', function() {
        module('local.storage', ['$storeProvider', function($storeProvider) {
          $storeProvider.configure({cookieFallback: false});
        }]);
        inject(function($store) {
          $store.setSupported(false);
          var result = $store.set('foo', 'bar');
          $store.getMemStore()['foo'].should.equal('bar');
          result.should.equal('bar');
        });
      });
    });

    describe('get', function() {
      beforeEach(module('local.storage'));

      it('should return the value from the store', inject(function($store) {
        $store.set('foo', 'bar');
        $store.get('foo').should.equal('bar');
      }));

      it('should return the value from the cookie store if the environment is not supported', inject(function($store) {
        $store.setSupported(false);
        $store.set('foo', 'bar');
        $store.get('foo').should.equal('bar');
      }));

      it('should return the value from the memStorage if the environment is not supported and cookie fallback is disabled', function() {
        module('local.storage', ['$storeProvider', function($storeProvider) {
          $storeProvider.configure({cookieFallback: false});
        }]);
        inject(function($store) {
          $store.setSupported(false);
          var result = $store.set('foo', 'bar');
          $store.getMemStore()['foo'].should.equal('bar');
          $store.get('foo').should.equal('bar');
        });
      });
    });

    describe('remove', function() {
      beforeEach(module('local.storage'));

      it('should remove the value from the store', inject(function($store) {
        sinon.spy($store.getStorage(), 'removeItem');
        $store.remove('foo');
        $store.getStorage().removeItem.calledOnce.should.be.true;
      }));

      it('should remove the value from the cookie store if the environment is not supported', inject(function($store, $cookieStore) {
        $store.setSupported(false);
        sinon.spy($cookieStore, 'remove');
        $store.remove('foo');
        $cookieStore.remove.calledOnce.should.be.true;
      }));

      it('should remove the value from the memStorage if the environment is not supported and cookie fallback is disabled', function() {
        module('local.storage', ['$storeProvider', function($storeProvider) {
          $storeProvider.configure({cookieFallback: false});
        }]);
        inject(function($store) {
          $store.setSupported(false);
          var result = $store.set('foo', 'bar');
          $store.getMemStore()['foo'].should.equal('bar');
          $store.remove('foo');
          ($store.getMemStore()['foo'] === undefined).should.be.true;
        });
      });
    });

    describe('bind', function() {
      beforeEach(module('local.storage'));

      it('should add a watch to a scope', inject(function($store, $rootScope, $parse) {
        var scope = $rootScope.$new();
        sinon.spy(scope, '$watch');
        $store.bind(scope, 'foo');
        scope.$watch.calledOnce.should.be.true;
      }));

      it('should set the value to fallback if a fallback is given and key does not already exist', inject(function($store, $rootScope) {
        var scope = $rootScope.$new();
        $store.remove('foo');
        $store.bind(scope, 'foo', 'bar');
        $store.get('foo').should.equal('bar');
      }));
    });

    describe('unbind', function() {
      beforeEach(module('local.storage'));

      it('should empty the watcher', inject(function($store, $rootScope) {
        var scope = $rootScope.$new();
        sinon.spy(scope, '$watch');
        $store.bind(scope, 'foo');
        $store.unbind(scope, 'foo');

        // We wanted the first call because the zeroth is the bind call
        var watchCall = scope.$watch.getCall(1);
        watchCall.args[1].toString().should.eql((function(){}).toString());
      }));

      it('should remove the key', inject(function($store, $rootScope) {
        var scope = $rootScope.$new();
        $store.bind(scope, 'foo', 'bar');
        $store.get('foo').should.equal('bar');
        $store.unbind(scope, 'foo');
        ($store.get('foo') === null).should.be.true;
      }));
    });
  });
});<commit_msg>Has tests<commit_after>'use strict';
describe('$store', function() {
  describe('configure', function() {
    var storeProvider;

    beforeEach(function() {
      angular.module('test.store', function() {})
        .config(function($storeProvider) {
          storeProvider = $storeProvider;
        });

      module('local.storage', 'test.store');

      inject(function() {});
    });

    it('should default cookieFallback to true', function() {
      storeProvider.configure().cookieFallback.should.be.true;
    });

    it('should properly set cookiefallback to false', function() {
      storeProvider.configure({cookieFallback: false}).cookieFallback.should.be.false;
    });

    it('should default useSessionStorage to false', function() {
      storeProvider.configure().useSessionStorage.should.be.false;
    });

    it('should properly set useSessionStorage to true', function() {
      storeProvider.configure({useSessionStorage: true}).useSessionStorage.should.be.true;
    });
  });

  describe('$get', function() {
    beforeEach(module('local.storage'));

    it('should have a list of functions', inject(function($store) {
      var functions = ['set', 'get', 'remove', 'bind', 'unbind', 'has', 'clear'];
      for (var i in functions) {
        $store[functions[i]].should.be.a.Function;
      }
    }));

    describe('set', function() {
      it('should remove a key if set is called with an empty value', inject(function($store) {
        sinon.spy($store, 'remove');
        var result = $store.set('foo');
        $store.remove.calledOnce.should.be.true;
        (result === undefined).should.be.true;
      }));

      it('should transform the value into json and set the key', inject(function($store) {
        sinon.spy($store.getStorage(), 'setItem');
        sinon.spy(angular, 'toJson');
        var result = $store.set('foo', {bar: 'a'});
        $store.getStorage().setItem.calledOnce.should.be.true;
        angular.toJson.calledOnce.should.be.true;
        result.should.eql({bar: 'a'});
      }));

      it('should store info in the cookie store if the environment is not supported', inject(function($store, $cookieStore) {
        sinon.spy($cookieStore, 'put');
        $store.setSupported(false);
        var result = $store.set('foo', 'bar');
        $cookieStore.put.calledOnce.should.be.true;
        result.should.equal('bar');
      }));

      it('should store info in the memStorage if the environment is not supported and cookie fallback is disabled', function() {
        module('local.storage', ['$storeProvider', function($storeProvider) {
          $storeProvider.configure({cookieFallback: false});
        }]);
        inject(function($store) {
          $store.setSupported(false);
          var result = $store.set('foo', 'bar');
          $store.getMemStore()['foo'].should.equal('bar');
          result.should.equal('bar');
        });
      });
    });

    describe('get', function() {
      beforeEach(module('local.storage'));

      it('should return the value from the store', inject(function($store) {
        $store.set('foo', 'bar');
        $store.get('foo').should.equal('bar');
      }));

      it('should return the value from the cookie store if the environment is not supported', inject(function($store) {
        $store.setSupported(false);
        $store.set('foo', 'bar');
        $store.get('foo').should.equal('bar');
      }));

      it('should return the value from the memStorage if the environment is not supported and cookie fallback is disabled', function() {
        module('local.storage', ['$storeProvider', function($storeProvider) {
          $storeProvider.configure({cookieFallback: false});
        }]);
        inject(function($store) {
          $store.setSupported(false);
          var result = $store.set('foo', 'bar');
          $store.getMemStore()['foo'].should.equal('bar');
          $store.get('foo').should.equal('bar');
        });
      });
    });

    describe('remove', function() {
      beforeEach(module('local.storage'));

      it('should remove the value from the store', inject(function($store) {
        sinon.spy($store.getStorage(), 'removeItem');
        $store.remove('foo');
        $store.getStorage().removeItem.calledOnce.should.be.true;
      }));

      it('should remove the value from the cookie store if the environment is not supported', inject(function($store, $cookieStore) {
        $store.setSupported(false);
        sinon.spy($cookieStore, 'remove');
        $store.remove('foo');
        $cookieStore.remove.calledOnce.should.be.true;
      }));

      it('should remove the value from the memStorage if the environment is not supported and cookie fallback is disabled', function() {
        module('local.storage', ['$storeProvider', function($storeProvider) {
          $storeProvider.configure({cookieFallback: false});
        }]);
        inject(function($store) {
          $store.setSupported(false);
          var result = $store.set('foo', 'bar');
          $store.getMemStore()['foo'].should.equal('bar');
          $store.remove('foo');
          ($store.getMemStore()['foo'] === undefined).should.be.true;
        });
      });
    });

    describe('bind', function() {
      beforeEach(module('local.storage'));

      it('should add a watch to a scope', inject(function($store, $rootScope, $parse) {
        var scope = $rootScope.$new();
        sinon.spy(scope, '$watch');
        $store.bind(scope, 'foo');
        scope.$watch.calledOnce.should.be.true;
      }));

      it('should set the value to fallback if a fallback is given and key does not already exist', inject(function($store, $rootScope) {
        var scope = $rootScope.$new();
        $store.remove('foo');
        $store.bind(scope, 'foo', 'bar');
        $store.get('foo').should.equal('bar');
      }));
    });

    describe('unbind', function() {
      beforeEach(module('local.storage'));

      it('should empty the watcher', inject(function($store, $rootScope) {
        var scope = $rootScope.$new();
        sinon.spy(scope, '$watch');
        $store.bind(scope, 'foo');
        $store.unbind(scope, 'foo');

        // We wanted the first call because the zeroth is the bind call
        var watchCall = scope.$watch.getCall(1);
        watchCall.args[1].toString().should.eql((function(){}).toString());
      }));

      it('should remove the key', inject(function($store, $rootScope) {
        var scope = $rootScope.$new();
        $store.bind(scope, 'foo', 'bar');
        $store.get('foo').should.equal('bar');
        $store.unbind(scope, 'foo');
        ($store.get('foo') === null).should.be.true;
      }));
    });

    describe('has', function() {
      beforeEach(module('local.storage'));

      it('should return false if the key is not in the store', inject(function($store) {
        $store.remove('foo');
        $store.has('foo').should.be.false;
      }));

      it('should return true if the key in the store', inject(function($store) {
        $store.set('foo', 'bar');
        $store.has('foo').should.be.true;
      }));
    })
  });
});<|endoftext|>


<commit_before>$(function () {
    var jsonFormatterId = "json-formatter";
    var jsonEditorId = "json-editor";
    var editorErrors = $("#alerts-editor");
    var formatterErrors = $("#alerts-formatter");
    var toFormatterButton = $("#to-formatter");
    var toEditorButton = $("#to-editor")
    var newJson = $("#new");
    var openFile = $("#open-file");
    var openUrl = $("#open-url");
    var saveFile = $("#save-file");
    var saveUrl = $("#save-url");
    var clearJson = $("#clear");
    var rawUrl = $("#raw-json");
    var modalRawJsonUrl = $("#rawJsonUrl");
    var modalJsonEditorUrl = $("#jsonEditorUrl");
    var jsonSharedModal = $("#jsonSharedModal");
    var fetchUrlModal = $('#fetchUrlModal');

    fetchUrlModal.find('form').submit(function(e){
        e.preventDefault();
    });

    var apiBase = "/api/jsonBlob";
    var blobId = window.location.pathname.substr(1);
    var sawShareModal = false;

    var defaultJson = {
        "name": "John Smith",
        "age": 32,
        "employed": true,
        "address": {
            "street": "701 First Ave.",
            "city": "Sunnyvale, CA 95125",
            "country": "United States"
        },
        "children": [
            {
                "name": "Richard",
                "age": 7
            },
            {
                "name": "Susan",
                "age": 4
            },
            {
                "name": "James",
                "age": 3
            }
        ]
    };

    var saved = true;
    var lastChangeByEditor = null;
    var editor = null;
    var formatter = null;

    // basic functions for the API
    var save = function(callback) {
        var request;
        if (!blobId) {
            request = {
                type: "POST",
                url: apiBase,
                headers: {'Content-Type': 'application/json', 'Accept':'application/json'},
                data: formatter.getText(),
                success: function(data, textStatus, jqXHR) {
                    saved = true;
                    var locationHeader = jqXHR.getResponseHeader("Location");
                    var parts = locationHeader.split("/");
                    blobId = parts[parts.length - 1];
                    rawUrl.removeClass("hidden").show("slow");
                    // TODO pushstate url with blob id
                    if (callback && typeof(callback) == 'function') {
                        callback(data, textStatus, jqXHR)
                    }
                },
                cache: false
            };
        } else {
            var blobApiUrl = [apiBase, blobId].join("/")
            request = {
                type: "PUT",
                url: blobApiUrl,
                headers: {'Content-Type': 'application/json', 'Accept':'application/json'},
                data: formatter.getText(),
                success: function(data, textStatus, jqXHR) {
                    saved = true;
                    // TODO pushstate url with blob id
                    if (callback && typeof(callback) == 'function') {
                        callback(data, textStatus, jqXHR)
                    }
                },
                cache: false
            };
        }
        if (request) {
            $.ajax(request);
        }
    };

    var reset = function() {
        saved = false;
        sawShareModal = false;
        var json = {};
        formatter.set(json);
        editor.set(json);
        blobId = ""
        rawUrl.addClass("hidden").show();
    }

    var formatterToEditor = function() {
        var error = false
        try {
            formatterErrors.empty();
            editor.set(formatter.get());
            if (blobId) {
                save();
            }
        } catch (err) {
            var msg = err.message.substr(0, err.message.indexOf("<a")) // remove json lint link
            formatterErrors.append('
<button type="button" class="close" data-dismiss="alert">×</button>' + msg + '
');
            formatterErrors.find(".alert").alert();
            error = true;
        }
        return error;
    };

    var editorToFormatter = function() {
        try {
            editorErrors.empty();
            formatter.set(editor.get());
            if (blobId) {
                save();
            }
        } catch (err) {
            editorErrors.append('
<button type="button" class="close" data-dismiss="alert">×</button>' + err.message + '
');
            editorErrors.find(".alert").alert();
        }
    };

    var init = function() {
        // setup the formatter
        formatter = new JSONFormatter(document.getElementById(jsonFormatterId), {
            change: function () {
                lastChanged = formatter;
                saved = false;
            }
        });

        // setup the editor
        editor = new JSONEditor(document.getElementById(jsonEditorId), {
            change: function () {
                lastChanged = editor;
                saved = false;
            }
        });

        if (!blobId) {
            formatter.set(defaultJson)
            editor.set(defaultJson)
        } else {
            var blobApiUrl = [apiBase, blobId].join("/")
            $.getJSON(blobApiUrl, function(data) {
                saved = true;
                formatter.set(data);
                editor.set(data);
                rawUrl.removeClass("hidden").show();
                sawShareModal = true;
                // TODO pushstate url with blob id
            });
        }
    }

    var saveToDisk = function() {
        var data = formatter.getText();
        var ts = (new Date()).getTime();
        saveFile.attr({
            "href" : "data:application/json;charset=utf-8," + encodeURIComponent(data),
            "download" : (blobId ? blobId : ts) + ".json"
        });
    }

    /* hook up the UI stuff */
    // raw JSON link
    rawUrl.click(function() {
        if (blobId) {
            var blobApiUrl = [apiBase, blobId].join("/")
            window.open(blobApiUrl, "jsonBlob_" + blobId);
        }
    });

    // create blob link
    saveUrl.click(function() {
        var callback = function() {
            if (!sawShareModal) {
                var location = document.location.origin;
                modalJsonEditorUrl.append(location + "/" + blobId);
                modalRawJsonUrl.append(location + apiBase + "/" + blobId);
                jsonSharedModal.modal();
                sawShareModal = true;
            }
        }
        if (!lastChangeByEditor) {
            if (!formatterToEditor()) {
                save(callback);
            }
        } else {
            editorToFormatter();
            save(callback);
        }

    });

    // download json file
    saveFile.click(function() {
        if (!lastChangeByEditor) {
            if (!formatterToEditor()) {
                saveToDisk();
            }
        } else {
            editorToFormatter();
            saveToDisk();
        }
    });

    // upload JSON
    openFile.click(function() {
        var modal = $('#uploadFileModal');
        $('#jsonFile').fileupload({
            dataType: 'json',
            add: function (e, data) {
                data.context = $('<button class="btn btn-primary" type="submit"/>').text('Upload')
                    .appendTo($("#jsonFile").parent())
                    .click(function () {
                        $(this).replaceWith($('
').text('Uploading...'));
                        data.submit();
                    });
            },
            done: function (e, data) {
                formatter.set(data.result);
                formatterToEditor();
                modal.modal('hide');
                saved = false;
            }
        });
        modal.modal();
    });

    $("#fetchJSONButton").click(function() {
        var url = $("#jsonUrl").val();
        $.ajax({
            type: "GET",
            url: url,
            dataType: 'json',
            cache: false,
            success: function(data) {
                formatter.set(data);
                formatterToEditor();
                fetchUrlModal.modal('hide');
                saved = false;
            },
            error: function() {
                $.ajax({
                    type: "POST",
                    url: '/file/fetch',
                    dataType: 'json',
                    data: {"url": url},
                    cache: false,
                    success: function(data) {
                        formatter.set(data);
                        formatterToEditor();
                        fetchUrlModal.modal('hide');
                        saved = false;
                    },
                    error: function() {
                        fetchUrlModal.modal('hide');
                        $("#fetchUrlErrorModal").find("pre").text(url);
                        $("#fetchUrlErrorModal").modal();
                    }
                });
            }
        });
    });

    // upload JSON
    openUrl.click(function() {
        fetchUrlModal.modal();
    });

    // clear the editor and formatter with either the clear button
    clearJson.click(function() {
       reset();
    });

    // clear the editor and formatter with either the new button
    newJson.click(function() {
        reset();
    });

    // format pane to editor pane
   toEditorButton.click(function() {
       formatterToEditor();
   });

    //editor pane to format pane
    toFormatterButton.click(function() {
        editorToFormatter();
    });

    var resize = function() {
        var height = $(window).height();
        height -=  $(".navbar-fixed-top").height();
        height -=  $(".navbar-fixed-bottom").height();
        height -=  $(".controls-row").height();
        height -= 20;
        $('.editor').height(height);
    }

    $(document).ready(function(){
        resize();
        init();
    });

    $(window).resize(function() {
        resize();
    });

    $(window).bind('beforeunload', function() {
        if (!saved) {
            return "You have unsaved work, it will be lost if you leave the page.";
        }
    });

});
<commit_msg>support push state<commit_after>$(function () {
    var jsonFormatterId = "json-formatter";
    var jsonEditorId = "json-editor";
    var editorErrors = $("#alerts-editor");
    var formatterErrors = $("#alerts-formatter");
    var toFormatterButton = $("#to-formatter");
    var toEditorButton = $("#to-editor")
    var newJson = $("#new");
    var openFile = $("#open-file");
    var openUrl = $("#open-url");
    var saveFile = $("#save-file");
    var saveUrl = $("#save-url");
    var clearJson = $("#clear");
    var rawUrl = $("#raw-json");
    var modalRawJsonUrl = $("#rawJsonUrl");
    var modalJsonEditorUrl = $("#jsonEditorUrl");
    var jsonSharedModal = $("#jsonSharedModal");
    var fetchUrlModal = $('#fetchUrlModal');

    fetchUrlModal.find('form').submit(function(e){
        e.preventDefault();
    });

    var apiBase = "/api/jsonBlob";
    var blobId = window.location.pathname.substr(1);
    var sawShareModal = false;

    var defaultJson = {
        "name": "John Smith",
        "age": 32,
        "employed": true,
        "address": {
            "street": "701 First Ave.",
            "city": "Sunnyvale, CA 95125",
            "country": "United States"
        },
        "children": [
            {
                "name": "Richard",
                "age": 7
            },
            {
                "name": "Susan",
                "age": 4
            },
            {
                "name": "James",
                "age": 3
            }
        ]
    };

    var saved = true;
    var lastChangeByEditor = null;
    var editor = null;
    var formatter = null;

    // basic functions for the API
    var save = function(callback) {
        var request;
        if (!blobId) {
            request = {
                type: "POST",
                url: apiBase,
                headers: {'Content-Type': 'application/json', 'Accept':'application/json'},
                data: formatter.getText(),
                success: function(data, textStatus, jqXHR) {
                    saved = true;
                    var locationHeader = jqXHR.getResponseHeader("Location");
                    var parts = locationHeader.split("/");
                    blobId = parts[parts.length - 1];
                    rawUrl.removeClass("hidden").show("slow");

                    history.pushState(null, "JSON Blob " + blobId, "/" + blobId);

                    if (callback && typeof(callback) == 'function') {
                        callback(data, textStatus, jqXHR)
                    }
                },
                cache: false
            };
        } else {
            var blobApiUrl = [apiBase, blobId].join("/")
            request = {
                type: "PUT",
                url: blobApiUrl,
                headers: {'Content-Type': 'application/json', 'Accept':'application/json'},
                data: formatter.getText(),
                success: function(data, textStatus, jqXHR) {
                    saved = true;
                    // TODO pushstate url with blob id
                    if (callback && typeof(callback) == 'function') {
                        callback(data, textStatus, jqXHR)
                    }
                },
                cache: false
            };
        }
        if (request) {
            $.ajax(request);
        }
    };

    var reset = function() {
        saved = false;
        sawShareModal = false;
        var json = {};
        formatter.set(json);
        editor.set(json);
        blobId = ""
        rawUrl.addClass("hidden").show();

        history.pushState(null, "JSON Blob", "/");
    }

    var formatterToEditor = function() {
        var error = false
        try {
            formatterErrors.empty();
            editor.set(formatter.get());
            if (blobId) {
                save();
            }
        } catch (err) {
            var msg = err.message.substr(0, err.message.indexOf("<a")) // remove json lint link
            formatterErrors.append('
<button type="button" class="close" data-dismiss="alert">×</button>' + msg + '
');
            formatterErrors.find(".alert").alert();
            error = true;
        }
        return error;
    };

    var editorToFormatter = function() {
        try {
            editorErrors.empty();
            formatter.set(editor.get());
            if (blobId) {
                save();
            }
        } catch (err) {
            editorErrors.append('
<button type="button" class="close" data-dismiss="alert">×</button>' + err.message + '
');
            editorErrors.find(".alert").alert();
        }
    };

    var init = function() {
        // setup the formatter
        formatter = new JSONFormatter(document.getElementById(jsonFormatterId), {
            change: function () {
                lastChanged = formatter;
                saved = false;
            }
        });

        // setup the editor
        editor = new JSONEditor(document.getElementById(jsonEditorId), {
            change: function () {
                lastChanged = editor;
                saved = false;
            }
        });

        if (!blobId) {
            formatter.set(defaultJson)
            editor.set(defaultJson)
        } else {
            var blobApiUrl = [apiBase, blobId].join("/")
            $.getJSON(blobApiUrl, function(data) {
                saved = true;
                formatter.set(data);
                editor.set(data);
                rawUrl.removeClass("hidden").show();
                sawShareModal = true;
                // TODO pushstate url with blob id
            });
        }
    }

    var saveToDisk = function() {
        var data = formatter.getText();
        var ts = (new Date()).getTime();
        saveFile.attr({
            "href" : "data:application/json;charset=utf-8," + encodeURIComponent(data),
            "download" : (blobId ? blobId : ts) + ".json"
        });
    }

    /* hook up the UI stuff */
    // raw JSON link
    rawUrl.click(function() {
        if (blobId) {
            var blobApiUrl = [apiBase, blobId].join("/")
            window.open(blobApiUrl, "jsonBlob_" + blobId);
        }
    });

    // create blob link
    saveUrl.click(function() {
        var callback = function() {
            if (!sawShareModal) {
                var location = document.location.origin;
                modalJsonEditorUrl.append(location + "/" + blobId);
                modalRawJsonUrl.append(location + apiBase + "/" + blobId);
                jsonSharedModal.modal();
                sawShareModal = true;
            }
        }
        if (!lastChangeByEditor) {
            if (!formatterToEditor()) {
                save(callback);
            }
        } else {
            editorToFormatter();
            save(callback);
        }

    });

    // download json file
    saveFile.click(function() {
        if (!lastChangeByEditor) {
            if (!formatterToEditor()) {
                saveToDisk();
            }
        } else {
            editorToFormatter();
            saveToDisk();
        }
    });

    // upload JSON
    openFile.click(function() {
        var modal = $('#uploadFileModal');
        $('#jsonFile').fileupload({
            dataType: 'json',
            add: function (e, data) {
                data.context = $('<button class="btn btn-primary" type="submit"/>').text('Upload')
                    .appendTo($("#jsonFile").parent())
                    .click(function () {
                        $(this).replaceWith($('
').text('Uploading...'));
                        data.submit();
                    });
            },
            done: function (e, data) {
                formatter.set(data.result);
                formatterToEditor();
                modal.modal('hide');
                saved = false;
            }
        });
        modal.modal();
    });

    $("#fetchJSONButton").click(function() {
        var url = $("#jsonUrl").val();
        $.ajax({
            type: "GET",
            url: url,
            dataType: 'json',
            cache: false,
            success: function(data) {
                formatter.set(data);
                formatterToEditor();
                fetchUrlModal.modal('hide');
                saved = false;
            },
            error: function() {
                $.ajax({
                    type: "POST",
                    url: '/file/fetch',
                    dataType: 'json',
                    data: {"url": url},
                    cache: false,
                    success: function(data) {
                        formatter.set(data);
                        formatterToEditor();
                        fetchUrlModal.modal('hide');
                        saved = false;
                    },
                    error: function() {
                        fetchUrlModal.modal('hide');
                        $("#fetchUrlErrorModal").find("pre").text(url);
                        $("#fetchUrlErrorModal").modal();
                    }
                });
            }
        });
    });

    // upload JSON
    openUrl.click(function() {
        fetchUrlModal.modal();
    });

    // clear the editor and formatter with either the clear button
    clearJson.click(function() {
       reset();
    });

    // clear the editor and formatter with either the new button
    newJson.click(function() {
        reset();
    });

    // format pane to editor pane
   toEditorButton.click(function() {
       formatterToEditor();
   });

    //editor pane to format pane
    toFormatterButton.click(function() {
        editorToFormatter();
    });

    var resize = function() {
        var height = $(window).height();
        height -=  $(".navbar-fixed-top").height();
        height -=  $(".navbar-fixed-bottom").height();
        height -=  $(".controls-row").height();
        height -= 20;
        $('.editor').height(height);
    }

    $(document).ready(function(){
        resize();
        init();
    });

    $(window).resize(function() {
        resize();
    });

    $(window).bind('beforeunload', function() {
        if (!saved) {
            return "You have unsaved work, it will be lost if you leave the page.";
        }
    });

});
<|endoftext|>


<commit_before>'use strict';
define([
    'underscore',
    'lib/utils',
    'views/base-view',
    'views/post',
    'tmpl!themeBase/posts-list'
], function(_, utils, BaseView, PostView) {

    return BaseView.extend({
        // Set el to the top level element from the template
        // instead of default behaviour of inserting a div element.
        el: false,

        // The selector of the view root element
        rootSel: '[data-gimme="posts.list"]',

        // Data attribute that identifies post view elements
        postRootDataAttr: 'data-gimme-postid',

        // The selector of a certain post view root element
        postRootSel: function(postId) {
            if (postId) {
                return '[' + this.postRootDataAttr + '="' + postId + '"]';
            } else {
                return '[' + this.postRootDataAttr + ']';
            }
        },

        flags: {
            autoRender: true
        },

        initialize: function() {
            utils.dispatcher.trigger('initialize.posts-view', this);
            _.bindAll(this, 'insertPostView', 'orderViews', '_postViewIndex',
                            '_insertPostViewAt', '_insertPostViewAtFirstPos');
            this.setTemplate('themeBase/posts-list');
            if (utils.isClient) {
                this.listenTo(this.collection, 'reset', this.setViewOnReset);
                this.listenTo(this.collection, 'add', this.addPost);
                this.listenTo(this.collection, 'remove', this.removePost);
                this.listenTo(this.collection, 'change:Order', this.reorderPost);
                this.listenTo(this.collection, 'change:DeletedOn', this.removePostFromCollection);
                this.listenTo(this.collection, 'change:IsPublished', this.removePostFromCollection);
            }
            this.collection.fetchPage({reset: true});
        },

        beforeRender: function(manage) {
            this.collection.forEach(this.insertPostView, this);
        },

        afterRender: function() {
            utils.dispatcher.trigger('after-render.posts-view', this);
            utils.dispatcher.trigger('add-all.posts-view', this);
        },

        setViewOnReset: function() {
            this.fakeViewRendering();
            var postEls = this.$el.children(this.postRootSel());

            // If there are no server side rendered posts, render whole view
            if (postEls.length === 0) {
                this.render();
                return;
            }

            // Otherwise construct nested views from DOM
            var self = this;
            postEls.each(function(index, pEl) {
                var postEl  = self.$(pEl),
                    postId  = postEl.attr(self.postRootDataAttr),
                    postCId = postEl.data('gimme-cid').toString(),
                    post    = self.collection.get(postId),
                    postView;

                // If the post is still in the collection and hasn't changed
                // construct the postView and add it to nested views
                if (post && postCId === post.get('CId')) {
                    postView = self.insertPostView(post, {el: self.postRootSel(postId)});
                    // fire events for the plugins if it was already rendered.
                    postView.alreadyRendered();
                } else {
                    // Else remove markup
                    postEl.remove();
                }
            });

            // Add new posts or posts that were removed because they had changed
            this.collection.forEach(this.addPostIfMissing, this);

            utils.dispatcher.trigger('add-all.posts-view', this);
        },

        addPostIfMissing: function(post) {
            var i = this._postViewIndex(post.id);
            if (i === -1) {
                this.addPost(post);
            }
        },

        removePostFromCollection: function(post) {
            if (!_.isUndefined(post.get('DeletedOn') ||
                post.get('isPublished') === 'false')) {
                this.collection.remove(post);
            }
        },

        addPost: function(post) {
            var postView = this.insertPostView(post);
            this.orderViews();
            postView.render();
            utils.dispatcher.trigger('add-all.posts-view', this);
        },

        removePost: function(post) {
            var self = this;
            this.removeView(function(nestedView) {
                if (nestedView.$el.is(self.postRootSel(post.id))) {
                    return nestedView;
                }
            });
        },

        reorderPost: function(post, newOrder) {
            // if some attribute other than Order (and CId) has changed
            // remove the view and render it again in the right position
            if (!this.onlyOrderHasChanged(post)) {
                this.removePost(post);
                this.addPost(post);
            } else {
                // Update order attribute in view
                this.views[''][this._postViewIndex(post.id)].order =
                                                            parseFloat(newOrder);

                // Reorder views array
                this.orderViews();

                // Detach view and insert it in new position
                var newIndex = this._postViewIndex(post.id),
                    postEl = this.$(this.postRootSel(post.id)).detach();

                this._insertPostViewAt(this.$el, postEl, newIndex);
            }
        },

        insert: function($root, $el) {
            // on 'reset' append all elements to the root element
            if ($root.is(':empty')) {
                $root.append($el);
            } else {
            // on 'add' insert the new post in the right position
                var i = this._postViewIndex($el.attr(this.postRootDataAttr));
                this._insertPostViewAt($root, $el, i);
            }
        },

        // Create a new post view and insert it at the end of the views array
        insertPostView: function(post, options) {
            var opts = _.extend({model: post}, options);
            var postView = new PostView(opts);
            this.insertView('', postView);
            return postView;
        },

        // Order the views array according to order param in views
        orderViews: function() {
            this.views[''] = _.sortBy(this.views[''], 'order').reverse();
        },

        onlyOrderHasChanged: function(post) {
            return (_.size(post.changedAttributes()) > 2 &&
                post.hasChanged('CId') && post.hasChanged('Order'));
        },

        // Returns the index of the post view on the views array or -1
        // if the view is not in it
        _postViewIndex: function(postId) {
            // If there are no views yet on this.views['']
            if (!this.views['']) {
                return -1;
            }

            var orderedIds = this.views[''].map(function(v) { return v.model.id; });
            return _.indexOf(orderedIds, postId);
        },

        // Insert post element in the parent list element at a given index
        _insertPostViewAt: function($parent, $el, i) {
            if (i === 0) {
                this._insertPostViewAtFirstPos($parent, $el);
            } else if (i > 0) {
                // For adding it to a position different that the first, find
                // prev post and add it after it
                var prevId = this.views[''][i - 1].model.id;
                $parent.children(this.postRootSel(prevId)).after($el);
            }
        },

        // Insert post element in the parent list element at first position
        _insertPostViewAtFirstPos: function($parent, $el) {
            // find the first post element and add it before it.
            var nextEl = $parent.children(this.postRootSel()).first();
            if (nextEl.length !== 0) {
                nextEl.before($el);
            } else {
                // If there is no first post search for pagination elements
                // and add it between them
                var pagEl = $parent.children('[data-gimme="posts.beforePage"]');
                if (pagEl.length !== 0) {
                    pagEl.after($el);
                } else {
                    // If there is no pagination element either, append to $parent
                    $parent.append($el);
                }
            }
        }
    });
});
<commit_msg>LB-1500 Fixed event triggering.<commit_after>'use strict';
define([
    'underscore',
    'lib/utils',
    'views/base-view',
    'views/post',
    'tmpl!themeBase/posts-list'
], function(_, utils, BaseView, PostView) {

    return BaseView.extend({
        // Set el to the top level element from the template
        // instead of default behaviour of inserting a div element.
        el: false,

        // The selector of the view root element
        rootSel: '[data-gimme="posts.list"]',

        // Data attribute that identifies post view elements
        postRootDataAttr: 'data-gimme-postid',

        // The selector of a certain post view root element
        postRootSel: function(postId) {
            if (postId) {
                return '[' + this.postRootDataAttr + '="' + postId + '"]';
            } else {
                return '[' + this.postRootDataAttr + ']';
            }
        },

        flags: {
            autoRender: true
        },

        initialize: function() {
            utils.dispatcher.trigger('initialize.posts-view', this);
            _.bindAll(this, 'insertPostView', 'orderViews', '_postViewIndex',
                            '_insertPostViewAt', '_insertPostViewAtFirstPos');
            this.setTemplate('themeBase/posts-list');
            if (utils.isClient) {
                this.listenTo(this.collection, 'reset', this.setViewOnReset);
                this.listenTo(this.collection, 'add', this.addPost);
                this.listenTo(this.collection, 'remove', this.removePost);
                this.listenTo(this.collection, 'change:Order', this.reorderPost);
                this.listenTo(this.collection, 'change:DeletedOn', this.removePostFromCollection);
                this.listenTo(this.collection, 'change:IsPublished', this.removePostFromCollection);
            }
            this.collection.fetchPage({reset: true});
        },

        beforeRender: function(manage) {
            this.collection.forEach(this.insertPostView, this);
        },

        afterRender: function() {
            utils.dispatcher.trigger('after-render.posts-view', this);
        },

        setViewOnReset: function() {
            this.fakeViewRendering();
            var postEls = this.$el.children(this.postRootSel());

            // If there are no server side rendered posts, render whole view
            if (postEls.length === 0) {
                this.render();
                return;
            }

            // Otherwise construct nested views from DOM
            var self = this;
            postEls.each(function(index, pEl) {
                var postEl  = self.$(pEl),
                    postId  = postEl.attr(self.postRootDataAttr),
                    postCId = postEl.data('gimme-cid').toString(),
                    post    = self.collection.get(postId),
                    postView;

                // If the post is still in the collection and hasn't changed
                // construct the postView and add it to nested views
                if (post && postCId === post.get('CId')) {
                    postView = self.insertPostView(post, {el: self.postRootSel(postId)});
                    // fire events for the plugins if it was already rendered.
                    postView.alreadyRendered();
                } else {
                    // Else remove markup
                    postEl.remove();
                }
            });

            // Add new posts or posts that were removed because they had changed
            this.collection.forEach(this.addPostIfMissing, this);

            utils.dispatcher.trigger('add-all.posts-view', this);
        },

        addPostIfMissing: function(post) {
            var i = this._postViewIndex(post.id);
            if (i === -1) {
                this.addPost(post);
            }
        },

        removePostFromCollection: function(post) {
            if (!_.isUndefined(post.get('DeletedOn') ||
                post.get('isPublished') === 'false')) {
                this.collection.remove(post);
            }
        },

        addPost: function(post) {
            var postView = this.insertPostView(post);
            this.orderViews();
            postView.render();
            utils.dispatcher.trigger('add-all.posts-view', this);
        },

        removePost: function(post) {
            var self = this;
            this.removeView(function(nestedView) {
                if (nestedView.$el.is(self.postRootSel(post.id))) {
                    return nestedView;
                }
            });
        },

        reorderPost: function(post, newOrder) {
            // if some attribute other than Order (and CId) has changed
            // remove the view and render it again in the right position
            if (!this.onlyOrderHasChanged(post)) {
                this.removePost(post);
                this.addPost(post);
            } else {
                // Update order attribute in view
                this.views[''][this._postViewIndex(post.id)].order =
                                                            parseFloat(newOrder);

                // Reorder views array
                this.orderViews();

                // Detach view and insert it in new position
                var newIndex = this._postViewIndex(post.id),
                    postEl = this.$(this.postRootSel(post.id)).detach();

                this._insertPostViewAt(this.$el, postEl, newIndex);
            }
        },

        insert: function($root, $el) {
            // on 'reset' append all elements to the root element
            if ($root.is(':empty')) {
                $root.append($el);
                utils.dispatcher.trigger('add-all.posts-view', this);
            } else {
            // on 'add' insert the new post in the right position
                var i = this._postViewIndex($el.attr(this.postRootDataAttr));
                this._insertPostViewAt($root, $el, i);
            }
        },

        // Create a new post view and insert it at the end of the views array
        insertPostView: function(post, options) {
            var opts = _.extend({model: post}, options);
            var postView = new PostView(opts);
            this.insertView('', postView);
            return postView;
        },

        // Order the views array according to order param in views
        orderViews: function() {
            this.views[''] = _.sortBy(this.views[''], 'order').reverse();
        },

        onlyOrderHasChanged: function(post) {
            return (_.size(post.changedAttributes()) > 2 &&
                post.hasChanged('CId') && post.hasChanged('Order'));
        },

        // Returns the index of the post view on the views array or -1
        // if the view is not in it
        _postViewIndex: function(postId) {
            // If there are no views yet on this.views['']
            if (!this.views['']) {
                return -1;
            }

            var orderedIds = this.views[''].map(function(v) { return v.model.id; });
            return _.indexOf(orderedIds, postId);
        },

        // Insert post element in the parent list element at a given index
        _insertPostViewAt: function($parent, $el, i) {
            if (i === 0) {
                this._insertPostViewAtFirstPos($parent, $el);
            } else if (i > 0) {
                // For adding it to a position different that the first, find
                // prev post and add it after it
                var prevId = this.views[''][i - 1].model.id;
                $parent.children(this.postRootSel(prevId)).after($el);
            }
        },

        // Insert post element in the parent list element at first position
        _insertPostViewAtFirstPos: function($parent, $el) {
            // find the first post element and add it before it.
            var nextEl = $parent.children(this.postRootSel()).first();
            if (nextEl.length !== 0) {
                nextEl.before($el);
            } else {
                // If there is no first post search for pagination elements
                // and add it between them
                var pagEl = $parent.children('[data-gimme="posts.beforePage"]');
                if (pagEl.length !== 0) {
                    pagEl.after($el);
                } else {
                    // If there is no pagination element either, append to $parent
                    $parent.append($el);
                }
            }
        }
    });
});
<|endoftext|>


<commit_before>'use strict'

const runtime = require('../../utils/Runtime');
const auth = require('../op/auth');
const regex = new RegExp( /^(hello|hi|sup|hello guys|whats up|what's up|hi guys)$/ );

//Different greetings based on rank

const greetings = {
    "mod": [
        "Welcome friend."
    ],

    "vip": [
        "Welcome fam."
    ],

    "donator": [
        "Welcome xaxaxaxa."
    ],

    "potato": [
        "Sup fagget",
        "What's up potato",
        "Please leave.",
        "Hey look, it's the potato!"
    ]
};

module.exports = [{
    name: 'greetings',
    types: ['message'],
    regex: regex,
    action: function( chat, stanza ) {
        console.log("USING THE LOCAL BOT");

        //get the info about the users
        let rawEvent = stanza.rawEvent;

        let userID = rawEvent.userID;
        console.log(userID);

        for ( let ranks in greetings ) {
            let keys = Object.keys(greetings);

            if ( auth.has(userID, ranks) ) {
                let randomNumber = Math.floor(Math.random() * greetings[ranks].length);

                chat.sendMessage(greetings[ranks][randomNumber], stanza);
                return;
            }
        }

        //Check if user is potato
        // if ( auth.has(userID, "potato") ) {
        //     chat.sendMessage(potatoGreetings[randomNumber], stanza);
        // }
    }
}];<commit_msg>Prevented greetings plugin from sending message if user is admin<commit_after>'use strict'

const runtime = require('../../utils/Runtime');
const auth = require('../op/auth');
const regex = new RegExp( /^(hello|hi|sup|hello guys|whats up|what's up|hi guys)$/ );

//Different greetings based on rank

const greetings = {
    "mod": [
        "Welcome friend."
    ],

    "vip": [
        "Welcome fam."
    ],

    "donator": [
        "Welcome xaxaxaxa."
    ],

    "potato": [
        "Sup fagget",
        "What's up potato",
        "Please leave.",
        "Hey look, it's the potato!"
    ]
};

module.exports = [{
    name: 'greetings',
    types: ['message'],
    regex: regex,
    action: function( chat, stanza ) {
        let userID = rawEvent.userID;

        if ( auth.has(userID, 'admin') ) {
            console.log("Admins has own greetings standard");
            return;
        }

        console.log("USING THE LOCAL BOT");

        //get the info about the users
        let rawEvent = stanza.rawEvent;

        console.log(userID);

        for ( let ranks in greetings ) {
            let keys = Object.keys(greetings);

            if ( auth.has(userID, ranks) ) {
                let randomNumber = Math.floor(Math.random() * greetings[ranks].length);

                chat.sendMessage(greetings[ranks][randomNumber], stanza);
                return;
            }
        }

        //Check if user is potato
        // if ( auth.has(userID, "potato") ) {
        //     chat.sendMessage(potatoGreetings[randomNumber], stanza);
        // }
    }
}];<|endoftext|>


<commit_before>var paper = require('browserifyable-paper');
/**
 * Converts a provided vector item into a drawn representation
 * Assumes a snap-to-center functionallity
 * Sets the pivot point to the base of the vector
 */
function PathDrawnItemFactory(hexDefinition) {
    this.hexDefinition = hexDefinition;

    this.vectorOnDrag = function (dx, dy) {
    };
}

/**
 * Returns a vector drawn item for the given object
 * Object should have color, sourceU, sourceV, destU, destV, shaftWidth
 */
PathDrawnItemFactory.prototype.getDrawnItem = function(item) {
    //Group together the head and shaft into one item
    var pathGroup = new paper.Group();
    pathGroup.pivot = new paper.Point(0, 0);

    var xyPoints = [];
    //Convert the item's array of u, v points into x, y
    for (var i = 0; i < item.points.length; i++) {
        var pixelCoordinates = this.hexDefinition.getPixelCoordinates(item.points[i][0], item.points[i][1])
        xyPoints.push([pixelCoordinates.x, pixelCoordinates.y]);
    }

    var backgroundPath = new paper.Path({
        segments: xyPoints,
        strokeColor: 'black',
        strokeWidth: item.width+2
    });
    pathGroup.addChild(backgroundPath);

    var path = new paper.Path({
        segments: xyPoints,
        strokeColor: item.color,
        strokeWidth: item.width
    });
    pathGroup.addChild(path);

    return pathGroup;
};
module.exports = PathDrawnItemFactory;<commit_msg>Run jshint before committing...<commit_after>var paper = require('browserifyable-paper');
/**
 * Converts a provided vector item into a drawn representation
 * Assumes a snap-to-center functionallity
 * Sets the pivot point to the base of the vector
 */
function PathDrawnItemFactory(hexDefinition) {
    this.hexDefinition = hexDefinition;

    this.vectorOnDrag = function (dx, dy) {
    };
}

/**
 * Returns a vector drawn item for the given object
 * Object should have color, sourceU, sourceV, destU, destV, shaftWidth
 */
PathDrawnItemFactory.prototype.getDrawnItem = function(item) {
    //Group together the head and shaft into one item
    var pathGroup = new paper.Group();
    pathGroup.pivot = new paper.Point(0, 0);

    var xyPoints = [];
    //Convert the item's array of u, v points into x, y
    for (var i = 0; i < item.points.length; i++) {
        var pixelCoordinates = this.hexDefinition.getPixelCoordinates(item.points[i][0], item.points[i][1]);
        xyPoints.push([pixelCoordinates.x, pixelCoordinates.y]);
    }

    var backgroundPath = new paper.Path({
        segments: xyPoints,
        strokeColor: 'black',
        strokeWidth: item.width+2
    });
    pathGroup.addChild(backgroundPath);

    var path = new paper.Path({
        segments: xyPoints,
        strokeColor: item.color,
        strokeWidth: item.width
    });
    pathGroup.addChild(path);

    return pathGroup;
};
module.exports = PathDrawnItemFactory;<|endoftext|>


<commit_before>var ytdl = require('ytdl-core');
var Request = require('request');
var Config = require('../../config.json');
var voice_connection = null;
var voice_handler = null;
var DEFAULT_VOLUME = 100;
var queue = [];
var now_playing_data = {};
var inform_np = true;
var paused = false;
var Commands = [];

Commands.join = {
  name: 'join',
  help: "Makes Shadow to join a voice channel.",
  fn: function (msg, suffix) {
    if (!msg.guild) return;
    text_channel = msg.guild.channels.find(chn => chn.name === 'general' && chn.type === "text");
    if(text_channel === null) throw "Couldn't find text channel '#" + 'general' + "' in server '" + server_name + "'";
    if (msg.member.voiceChannel) {
      msg.member.voiceChannel.join()
        .then(connection => {
          msg.reply('I have successfully connected to the channel!');
          voice_connection = connection;
        })
        .catch(console.log);
    } else {
      msg.reply('You need to join a voice channel first!');
    }
  }
}

Commands.leave = {
  name: 'leave',
  help: "Makes Shadow to .leave actual voice channel.",
  fn: function (msg, suffix) {
    if(voice_handler !== null) {
      msg.reply("Skipping...");
      voice_handler.end();
    } else {
      msg.reply("There is nothing being played.");
    }
  }
}

Commands.search = {
  name: 'search',
  help: "Searchs a song on youtube and adds it to the queue.",
  fn: function (msg, suffix) {
    search_video(msg, suffix);
  }
}

Commands.volume = {
  name: 'volume',
  help: "Sets volume or returns actual one if no suffix specified.",
  fn: function (msg, suffix, bot) {
    if(Number.isInteger(suffix)){
      DEFAULT_VOLUME = suffix;
      if(voice_handler !== undefined){
        voice_handler.setVolume(DEFAULT_VOLUME/100);
      }
    }
    msg.reply("Volume: " + DEFAULT_VOLUME + "%");
  }
}

Commands.pause = {
  name: 'pause',
  help: "Pauses the actual song.",
  fn: function (msg, suffix) {
    paused = true;
    voice_handler.pause();
  }
}

Commands.resume = {
  name: 'resume',
  help: "Resumes the actual song.",
  fn: function (msg, suffix) {
    paused = true;
    voice_handler.pause();
  }
}

Commands.skip = {
  name: 'skip',
  help: "Skips the actual song.",
  fn: function (msg, suffix) {
    if(voice_handler !== null) {
      msg.reply("Skipping...");
      voice_handler.end();
    } else {
      msg.reply("There is nothing being played.");
    }
  }
}

function search_video(message, query) {

  Request("https://www.googleapis.com/youtube/v3/search?part=id&type=video&q=" + encodeURIComponent(query) + "&key=" + Config.api_keys.youtube, (error, response, body) => {
    var json = JSON.parse(body);
    if("error" in json) {
      message.reply("An error has occurred: " + json.error.errors[0].message + " - " + json.error.errors[0].reason);
    } else if(json.items.length === 0) {
      message.reply("No videos found matching the search criteria.");
    } else {
      add_to_queue(json.items[0].id.videoId, message);
    }
  })
}

function add_to_queue(video, message, mute = false) {

  var video_id = get_video_id(video);

  ytdl.getInfo("https://www.youtube.com/watch?v=" + video_id, (error, info) => {
    if(error) {
      message.reply("The requested video (" + video_id + ") does not exist or cannot be played.");
      console.log("Error (" + video_id + "): " + error);
    } else {
      queue.push({title: info["title"], id: video_id, user: message.author.username});
      if (!mute) {
        message.reply('"' + info["title"] + '" has been added to the queue.');
      }
      if(!paused && !is_bot_playing() && queue.length === 1) {
        play_next_song();
      }
    }
  });
}

function get_video_id(string) {
  var regex = /(?:\?v=|&v=|youtu\.be\/)(.*?)(?:\?|&|$)/;
  var matches = string.match(regex);

  if(matches) {
    return matches[1];
  } else {
    return string;
  }
}

function play_next_song() {
  if(is_queue_empty()) {
    text_channel.sendMessage("The queue is empty!");
  }

  var video_id = queue[0]["id"];
  var title = queue[0]["title"];
  var user = queue[0]["user"];

  now_playing_data["title"] = title;
  now_playing_data["user"] = user;

  if(inform_np) {
    text_channel.send('Now playing: "' + title + '" (requested by ' + user + ')');
  }

  var audio_stream = ytdl("https://www.youtube.com/watch?v=" + video_id,{filter: 'audioonly'});
  voice_handler = voice_connection.playStream(audio_stream,{seek: 0, volume: (DEFAULT_VOLUME/100)});

  voice_handler.once("end", reason => {
    voice_handler = null;
    console.log("Alola");
    if(!paused && !is_queue_empty()) {
      play_next_song();
    }
  });

  queue.splice(0,1);
}

function is_bot_playing() {
  return voice_handler !== null;
}

function is_queue_empty() {
  return queue.length === 0;
}

exports.Commands = Commands<commit_msg>Fixed undefined problem<commit_after>var ytdl = require('ytdl-core');
var Request = require('request');
var Config = require('../../config.json');
var voice_connection = null;
var voice_handler = null;
var DEFAULT_VOLUME = 100;
var queue = [];
var now_playing_data = {};
var inform_np = true;
var paused = false;
var Commands = [];

Commands.join = {
  name: 'join',
  help: "Makes Shadow to join a voice channel.",
  fn: function (msg, suffix) {
    if (!msg.guild) return;
    text_channel = msg.guild.channels.find(chn => chn.name === 'general' && chn.type === "text");
    if(text_channel === null) throw "Couldn't find text channel '#" + 'general' + "' in server '" + server_name + "'";
    if (msg.member.voiceChannel) {
      msg.member.voiceChannel.join()
        .then(connection => {
          msg.reply('I have successfully connected to the channel!');
          voice_connection = connection;
        })
        .catch(console.log);
    } else {
      msg.reply('You need to join a voice channel first!');
    }
  }
}

Commands.leave = {
  name: 'leave',
  help: "Makes Shadow to .leave actual voice channel.",
  fn: function (msg, suffix) {
    if(voice_handler !== null) {
      msg.reply("Skipping...");
      voice_handler.end();
    } else {
      msg.reply("There is nothing being played.");
    }
  }
}

Commands.search = {
  name: 'search',
  help: "Searchs a song on youtube and adds it to the queue.",
  fn: function (msg, suffix) {
    search_video(msg, suffix);
  }
}

Commands.volume = {
  name: 'volume',
  help: "Sets volume or returns actual one if no suffix specified.",
  fn: function (msg, suffix, bot) {
    if(Number.isInteger(suffix)){
      DEFAULT_VOLUME = suffix;
      if(voice_handler !== "undefined"){
        voice_handler.setVolume(DEFAULT_VOLUME/100);
      }
    }
    msg.reply("Volume: " + DEFAULT_VOLUME + "%");
  }
}

Commands.pause = {
  name: 'pause',
  help: "Pauses the actual song.",
  fn: function (msg, suffix) {
    paused = true;
    voice_handler.pause();
  }
}

Commands.resume = {
  name: 'resume',
  help: "Resumes the actual song.",
  fn: function (msg, suffix) {
    paused = true;
    voice_handler.pause();
  }
}

Commands.skip = {
  name: 'skip',
  help: "Skips the actual song.",
  fn: function (msg, suffix) {
    if(voice_handler !== null) {
      msg.reply("Skipping...");
      voice_handler.end();
    } else {
      msg.reply("There is nothing being played.");
    }
  }
}

function search_video(message, query) {

  Request("https://www.googleapis.com/youtube/v3/search?part=id&type=video&q=" + encodeURIComponent(query) + "&key=" + Config.api_keys.youtube, (error, response, body) => {
    var json = JSON.parse(body);
    if("error" in json) {
      message.reply("An error has occurred: " + json.error.errors[0].message + " - " + json.error.errors[0].reason);
    } else if(json.items.length === 0) {
      message.reply("No videos found matching the search criteria.");
    } else {
      add_to_queue(json.items[0].id.videoId, message);
    }
  })
}

function add_to_queue(video, message, mute = false) {

  var video_id = get_video_id(video);

  ytdl.getInfo("https://www.youtube.com/watch?v=" + video_id, (error, info) => {
    if(error) {
      message.reply("The requested video (" + video_id + ") does not exist or cannot be played.");
      console.log("Error (" + video_id + "): " + error);
    } else {
      queue.push({title: info["title"], id: video_id, user: message.author.username});
      if (!mute) {
        message.reply('"' + info["title"] + '" has been added to the queue.');
      }
      if(!paused && !is_bot_playing() && queue.length === 1) {
        play_next_song();
      }
    }
  });
}

function get_video_id(string) {
  var regex = /(?:\?v=|&v=|youtu\.be\/)(.*?)(?:\?|&|$)/;
  var matches = string.match(regex);

  if(matches) {
    return matches[1];
  } else {
    return string;
  }
}

function play_next_song() {
  if(is_queue_empty()) {
    text_channel.sendMessage("The queue is empty!");
  }

  var video_id = queue[0]["id"];
  var title = queue[0]["title"];
  var user = queue[0]["user"];

  now_playing_data["title"] = title;
  now_playing_data["user"] = user;

  if(inform_np) {
    text_channel.send('Now playing: "' + title + '" (requested by ' + user + ')');
  }

  var audio_stream = ytdl("https://www.youtube.com/watch?v=" + video_id,{filter: 'audioonly'});
  voice_handler = voice_connection.playStream(audio_stream,{seek: 0, volume: (DEFAULT_VOLUME/100)});

  voice_handler.once("end", reason => {
    voice_handler = null;
    console.log("Alola");
    if(!paused && !is_queue_empty()) {
      play_next_song();
    }
  });

  queue.splice(0,1);
}

function is_bot_playing() {
  return voice_handler !== null;
}

function is_queue_empty() {
  return queue.length === 0;
}

exports.Commands = Commands<|endoftext|>