<commit_before>// NOTE: Other rules will be disabled by Prettier

module.exports = {
  extends: ["prettier/react"],

  rules: {
    "react/jsx-boolean-value": "error",
    "react/jsx-curly-brace-presence": "error",
    "react/jsx-filename-extension": ["error", { extensions: [".js", ".jsx"] }],
    "react/jsx-fragments": ["error", "syntax"],
    "react/jsx-handler-names": "error",
    "react/jsx-max-depth": ["error", { max: 5 }],
    "react/jsx-no-bind": [
      "error",
      {
        allowArrowFunctions: true,
        allowBind: false,
        ignoreRefs: true,
      },
    ],
    "react/jsx-no-literals": ["error", { noStrings: true }],
    "react/jsx-pascal-case": [
      "error",
      {
        allowAllCaps: true,
      },
    ],
    "react/jsx-sort-default-props": "off",
    "react/jsx-sort-props": "off",
  },
};
<commit_msg>feat(react): disable `jsx-boolean-value` rule (#362)<commit_after>// NOTE: Other rules will be disabled by Prettier

module.exports = {
  extends: ["prettier/react"],

  rules: {
    "react/jsx-boolean-value": "off",
    "react/jsx-curly-brace-presence": "error",
    "react/jsx-filename-extension": ["error", { extensions: [".js", ".jsx"] }],
    "react/jsx-fragments": ["error", "syntax"],
    "react/jsx-handler-names": "error",
    "react/jsx-max-depth": ["error", { max: 5 }],
    "react/jsx-no-bind": [
      "error",
      {
        allowArrowFunctions: true,
        allowBind: false,
        ignoreRefs: true,
      },
    ],
    "react/jsx-no-literals": ["error", { noStrings: true }],
    "react/jsx-pascal-case": [
      "error",
      {
        allowAllCaps: true,
      },
    ],
    "react/jsx-sort-default-props": "off",
    "react/jsx-sort-props": "off",
  },
};
<|endoftext|>


<commit_before>game.Laser = me.Renderable.extend({
    init: function (x, y) {
        this._super(me.Renderable, "init", [x, y, game.Laser.width, game.Laser.height]);
        this.z = 5;
    },

    draw: function (renderer) {
        var color = renderer.getColor();
        renderer.setColor('#5EFF7E');
        renderer.fillRect(this.pos.x, this.pos.y, this.width, this.height);
        renderer.setColor(color);
    },

    update: function (time) {
        this._super(me.Renderable, "update", [time]);
        this.pos.y -= 750 * me.timer.getDelta() / 1000;
        if (this.pos.y + this.height <= 0) {
            me.game.world.removeChild(this);
        }
    }
});

game.Laser.width = 5;
game.Laser.height = 28;<commit_msg>updated the laser to use body velocity<commit_after>game.Laser = me.Renderable.extend({
    init: function (x, y) {
        this._super(me.Renderable, "init", [x, y, game.Laser.width, game.Laser.height]);
        this.z = 5;
        this.body = new me.Body(this, ([
            new me.Polygon(0, 0, [
                new me.Vector2d(0, 0),
                new me.Vector2d(this.width, 0),
                new me.Vector2d(this.width, this.height),
                new me.Vector2d(0, this.height)
            ])
        ]));
        this.body.updateBounds();
        this.body.setVelocity(0, 20);
    },

    draw: function (renderer) {
        var color = renderer.getColor();
        renderer.setColor('#5EFF7E');
        renderer.fillRect(this.pos.x, this.pos.y, this.width, this.height);
        renderer.setColor(color);
    },

    update: function (time) {
        this._super(me.Renderable, "update", [time]);
        this.body.vel.y -= this.body.accel.y * me.timer.tick;
        if (this.pos.y + this.height <= 0) {
            me.game.world.removeChild(this);
        }

        this.body.update();

        return true;
    }
});

game.Laser.width = 5;
game.Laser.height = 28;<|endoftext|>


<commit_before>var seq = require('seq');
var once = require('once');

var createDatabase = require('../../lib/util/createDatabase');
var DBFactory = require('../../lib/database/Factory');

function createPlainDatabase(configuration, callback) {
    createDatabase(configuration, callback);
}

function create2Users5TransactionsDatabase(configuration, callback) {
    createDatabase(configuration, function(error) {
        if (error) return callback(error);

        DBFactory.create(configuration, function (error, db) {
            if (error) return callback(error);

            var end = once(function end (error) {
                db.close();

                callback(error);
            });

            //CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name text, createDate DATETIME DEFAULT current_timestamp)
            //CREATE TABLE transactions (id INTEGER PRIMARY KEY AUTOINCREMENT, userId INTEGER, createDate DATETIME DEFAULT current_timestamp, value NUMERIC)

            seq()
                .par(function () {
                    db.query('INSERT INTO users (id, name, createDate) VALUES (1, "foo", "2014-01-01 00:23:42")', [], this);
                })
                .par(function () {
                    db.query('INSERT INTO users (id, name, createDate) VALUES (2, "bar", "2014-01-01 00:42:23")', [], this);
                })
                .par(function () {
                    db.query('INSERT INTO transactions (userId, value, createDate) VALUES (1, 1, "2014-01-01 00:23:42")', [], this);
                })
                .par(function () {
                    db.query('INSERT INTO transactions (userId, value, createDate) VALUES (1, 1, "2014-01-01 00:23:43")', [], this);
                })
                .par(function () {
                    db.query('INSERT INTO transactions (userId, value, createDate) VALUES (1, 1, "2014-01-01 00:23:44")', [], this);
                })
                .par(function () {
                    db.query('INSERT INTO transactions (userId, value, createDate) VALUES (2, 1, "2014-01-01 00:23:45")', [], this);
                })
                .par(function () {
                    db.query('INSERT INTO transactions (userId, value, createDate) VALUES (2, 1, "2014-01-01 00:23:46")', [], this);
                })
                .seq(end.bind(null, null))
                .catch(end);
        });
    });
}

module.exports = {
    createPlainDatabase: createPlainDatabase,
    create2Users5TransactionsDatabase: create2Users5TransactionsDatabase
};<commit_msg>enforces unique keys on test transactions<commit_after>var seq = require('seq');
var once = require('once');

var createDatabase = require('../../lib/util/createDatabase');
var DBFactory = require('../../lib/database/Factory');

function createPlainDatabase(configuration, callback) {
    createDatabase(configuration, callback);
}

function create2Users5TransactionsDatabase(configuration, callback) {
    createDatabase(configuration, function(error) {
        if (error) return callback(error);

        DBFactory.create(configuration, function (error, db) {
            if (error) return callback(error);

            var end = once(function end (error) {
                db.close();

                callback(error);
            });

            //CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name text, createDate DATETIME DEFAULT current_timestamp)
            //CREATE TABLE transactions (id INTEGER PRIMARY KEY AUTOINCREMENT, userId INTEGER, createDate DATETIME DEFAULT current_timestamp, value NUMERIC)

            seq()
                .par(function () {
                    db.query('INSERT INTO users (id, name, createDate) VALUES (1, "foo", "2014-01-01 00:23:42")', [], this);
                })
                .par(function () {
                    db.query('INSERT INTO users (id, name, createDate) VALUES (2, "bar", "2014-01-01 00:42:23")', [], this);
                })
                .par(function () {
                    db.query('INSERT INTO transactions (id, userId, value, createDate) VALUES (1, 1, 1, "2014-01-01 00:23:42")', [], this);
                })
                .par(function () {
                    db.query('INSERT INTO transactions (id, userId, value, createDate) VALUES (2, 1, 1, "2014-01-01 00:23:43")', [], this);
                })
                .par(function () {
                    db.query('INSERT INTO transactions (id, userId, value, createDate) VALUES (3, 1, 1, "2014-01-01 00:23:44")', [], this);
                })
                .par(function () {
                    db.query('INSERT INTO transactions (id, userId, value, createDate) VALUES (4, 2, 1, "2014-01-01 00:23:45")', [], this);
                })
                .par(function () {
                    db.query('INSERT INTO transactions (id, userId, value, createDate) VALUES (5, 2, 1, "2014-01-01 00:23:46")', [], this);
                })
                .seq(end.bind(null, null))
                .catch(end);
        });
    });
}

module.exports = {
    createPlainDatabase: createPlainDatabase,
    create2Users5TransactionsDatabase: create2Users5TransactionsDatabase
};<|endoftext|>


<commit_before>export class SrfSearch {

    constructor($inputField, $submitButton, $menu, options = {maxSuggestionCount: 7}) {
        this.$inputField = $inputField;
        // inputField and submitButton are distinct html elements for accessibility
        this.$submitButton = $submitButton;
        this.$menu = $menu;
        this.options = options;

        this.typeaheadUrl = this.$inputField.data("typeahead-url");
        this.typeaheadData = null;
        this.suggestionUrl = '';

        this.registerListeners();
    }

    registerListeners() {
        this.$inputField.on("focus", (e) => {
            this.initTypeahead();
        });

        this.$inputField.on("keyup", (e) => {
            this.enhanceAccessibility();
            this.onKeyUp(e);
        });

        this.$inputField.on("keydown", (e) => {
            this.onKeyDown(e);
        });

        this.$inputField.on("blur", (e) => {
            setTimeout(() => {
                this.hideMenu()
            }, 150);
        });

        this.$menu.on("mouseenter", 'li', (e) => {
            this.onMenuMouseenter(e);
        });

        this.$menu.on("touchstart", 'li', (e) => {
            this.onMenuMouseenter(e);
        });
    }

    onKeyUp(e) {
        switch (e.keyCode) {
            case 40: // down arrow
            case 38: // up arrow
                break;
            case 9: // tab
                this.hideMenu();
                break;

            case 27: // escape
                this.hideMenu();
                break;

            default:
                this.lookup();
        }
    }

    onKeyDown(e) {
        // if no suggestion is selected fall back to default browser behavior for form submission
        if (e.keyCode === 13) {
            if (this.suggestionUrl != '') {
                e.stopPropagation();
                e.preventDefault();
                location.href = this.suggestionUrl;
            }
        }
        if (e.keyCode === 40 || e.keyCode === 38) {
            let direction = e.keyCode === 40 ? 'down' : 'up';
            this.moveInMenu(direction);
        }
    }

    onMenuMouseenter(e) {
        this.$menu.find('.active').removeClass('active');
        $(e.currentTarget).addClass('active');
    }

    hideMenu() {
        this.$menu.hide();
        this.$inputField.attr("aria-expanded", false);
        this.$inputField.attr("aria-activedescendant", "");
        this.suggestionUrl = '';
    }

    clearInput() {
        this.$inputField.val("");
        this.$submitButton.attr("tabindex", -1).attr("aria-hidden", true);
        this.suggestionUrl = '';
    }

    moveInMenu(direction) {
        if (direction === 'down') {
            this.nextSuggestion();
        }
        else if (direction === 'up') {
            this.prevSuggestion();
        }
    }

    addScreenreaderSupport($old, $new) {
        $old.attr("id", "");
        $new.attr("aria-selected", true);
        this.$inputField.attr("aria-activedescendant", "selectedSuggestion");
        $new.attr("id", "selectedSuggestion");
    }

    prevSuggestion() {
        let $active = this.$menu.find('.active').removeClass('active');
        let $prev = $active.prev();
        if ($prev.length === 0) {
            $prev = this.$menu.find('li').last();
        }
        this.suggestionUrl = $prev.find("a").attr('href');
        $prev.addClass('active');
        this.addScreenreaderSupport($active, $prev);
    }

    nextSuggestion() {
        let $active = this.$menu.find('.active').removeClass('active');
        let $next = $active.next();
        if ($next.length === 0) {
            $next = $(this.$menu.find('li').first());
        }
        this.suggestionUrl = $next.find("a").attr('href');
        $next.addClass('active');
        this.addScreenreaderSupport($active, $next);
    }

    enhanceAccessibility() {
        // a search button only makes sense on desktop - when it's actually working
        if (!(('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0))) {
            // this works mobile as well unlike <enter>-keys an d the likes
            if (this.$inputField.val().length > 2 && this.$submitButton.attr("tabindex") == -1) {
                this.$submitButton.attr("tabindex", 0).attr("aria-hidden", false);
            } else if (this.$inputField.val().length == 0 && this.$submitButton.attr("tabindex") == 0) {
                this.$submitButton.attr("tabindex", -1).attr("aria-hidden", true);
            }
        }
    }

    initTypeahead() {
        if (this.typeaheadData === null) {
            $.getJSON(this.typeaheadUrl, (data) => {
                this.typeaheadData = data;
            })
        }
    }

    lookup() {
        let results = [];
        let query = this.$inputField.val().toString().toLowerCase();
        if (this.typeaheadData === null) {
            return true;
        }
        this.typeaheadData.forEach((item) => {
            let matchIndex = item.name.toString().toLowerCase().indexOf(query);
            if (matchIndex >= 0) {
                results.push({name: item.name, url: item.url, matchIndex: matchIndex});
            }
        });
        if (results.length > 0) {
            results = results.slice(0, this.options.maxSuggestionCount);
            this.$inputField.attr("aria-expanded", true);
            this.renderResults(results, query);
        }
        else {
            this.hideMenu();
        }
    }

    renderResults(results, query) {
        let html = '';

        results.forEach((result) => {
            let name = this.highlightQuery(query, result.name);
            html += `<li role="option" aria-selected="false" class="typeahead-suggestion" tabindex="-1"> <a href="${result.url}">${name}</a> </li>`;
        })
        this.$menu.html(html).show();
    }

    highlightQuery(query, name) {
        query = query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
        return name.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
            return '' + match + ''
        })
    }
}

<commit_msg>implement min search length req.; also fixes bug that menu is not closed when search field is cleared<commit_after>export class SrfSearch {

    constructor($inputField, $submitButton, $menu, options = {maxSuggestionCount: 7, minSearchLength: 2}) {
        this.$inputField = $inputField;
        // inputField and submitButton are distinct html elements for accessibility
        this.$submitButton = $submitButton;
        this.$menu = $menu;
        this.options = options;

        this.typeaheadUrl = this.$inputField.data("typeahead-url");
        this.typeaheadData = null;
        this.suggestionUrl = '';

        this.registerListeners();
    }

    registerListeners() {
        this.$inputField.on("focus", (e) => {
            this.initTypeahead();
        });

        this.$inputField.on("keyup", (e) => {
            this.enhanceAccessibility();
            this.onKeyUp(e);
        });

        this.$inputField.on("keydown", (e) => {
            this.onKeyDown(e);
        });

        this.$inputField.on("blur", (e) => {
            setTimeout(() => {
                this.hideMenu()
            }, 150);
        });

        this.$menu.on("mouseenter", 'li', (e) => {
            this.onMenuMouseenter(e);
        });

        this.$menu.on("touchstart", 'li', (e) => {
            this.onMenuMouseenter(e);
        });
    }

    onKeyUp(e) {
        switch (e.keyCode) {
            case 40: // down arrow
            case 38: // up arrow
                break;
            case 9: // tab
                this.hideMenu();
                break;

            case 27: // escape
                this.hideMenu();
                break;

            default:
                this.lookup();
        }
    }

    onKeyDown(e) {
        // if no suggestion is selected fall back to default browser behavior for form submission
        if (e.keyCode === 13) {
            if (this.suggestionUrl != '') {
                e.stopPropagation();
                e.preventDefault();
                location.href = this.suggestionUrl;
            }
        }
        if (e.keyCode === 40 || e.keyCode === 38) {
            let direction = e.keyCode === 40 ? 'down' : 'up';
            this.moveInMenu(direction);
        }
    }

    onMenuMouseenter(e) {
        this.$menu.find('.active').removeClass('active');
        $(e.currentTarget).addClass('active');
    }

    hideMenu() {
        this.$menu.hide();
        this.$inputField.attr("aria-expanded", false);
        this.$inputField.attr("aria-activedescendant", "");
        this.suggestionUrl = '';
    }

    clearInput() {
        this.$inputField.val("");
        this.$submitButton.attr("tabindex", -1).attr("aria-hidden", true);
        this.suggestionUrl = '';
    }

    moveInMenu(direction) {
        if (direction === 'down') {
            this.nextSuggestion();
        }
        else if (direction === 'up') {
            this.prevSuggestion();
        }
    }

    addScreenreaderSupport($old, $new) {
        $old.attr("id", "");
        $new.attr("aria-selected", true);
        this.$inputField.attr("aria-activedescendant", "selectedSuggestion");
        $new.attr("id", "selectedSuggestion");
    }

    prevSuggestion() {
        let $active = this.$menu.find('.active').removeClass('active');
        let $prev = $active.prev();
        if ($prev.length === 0) {
            $prev = this.$menu.find('li').last();
        }
        this.suggestionUrl = $prev.find("a").attr('href');
        $prev.addClass('active');
        this.addScreenreaderSupport($active, $prev);
    }

    nextSuggestion() {
        let $active = this.$menu.find('.active').removeClass('active');
        let $next = $active.next();
        if ($next.length === 0) {
            $next = $(this.$menu.find('li').first());
        }
        this.suggestionUrl = $next.find("a").attr('href');
        $next.addClass('active');
        this.addScreenreaderSupport($active, $next);
    }

    enhanceAccessibility() {
        // a search button only makes sense on desktop - when it's actually working
        if (!(('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0))) {
            // this works mobile as well unlike <enter>-keys an d the likes
            if (this.$inputField.val().length > 2 && this.$submitButton.attr("tabindex") == -1) {
                this.$submitButton.attr("tabindex", 0).attr("aria-hidden", false);
            } else if (this.$inputField.val().length == 0 && this.$submitButton.attr("tabindex") == 0) {
                this.$submitButton.attr("tabindex", -1).attr("aria-hidden", true);
            }
        }
    }

    initTypeahead() {
        if (this.typeaheadData === null) {
            $.getJSON(this.typeaheadUrl, (data) => {
                this.typeaheadData = data;
            })
        }
    }

    lookup() {
        let results = [];
        let query = this.$inputField.val().toString().toLowerCase();
        if (this.typeaheadData === null) {
            return true;
        }
        if(query.length < this.options.minSearchLength) {
            this.hideMenu();
            return true;
        }

        this.typeaheadData.forEach((item) => {
            let matchIndex = item.name.toString().toLowerCase().indexOf(query);
            if (matchIndex >= 0) {
                results.push({name: item.name, url: item.url, matchIndex: matchIndex});
            }
        });
        if (results.length > 0) {
            results = results.slice(0, this.options.maxSuggestionCount);
            this.$inputField.attr("aria-expanded", true);
            this.renderResults(results, query);
        }
        else {
            this.hideMenu();
        }
    }

    renderResults(results, query) {
        let html = '';

        results.forEach((result) => {
            let name = this.highlightQuery(query, result.name);
            html += `<li role="option" aria-selected="false" class="typeahead-suggestion" tabindex="-1"> <a href="${result.url}">${name}</a> </li>`;
        })
        this.$menu.html(html).show();
    }

    highlightQuery(query, name) {
        query = query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
        return name.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
            return '' + match + ''
        })
    }
}

<|endoftext|>


<commit_before>/* SauceNao query Handler
 *
 *
 * Contributed by Capuccino
 */

const got = require('got');
const urlRegex = str => /(http(s)?:\/\/)?(www\.)?[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi.test(str);

/**
 * Query Handler for SauceNao-related requests.
 */

class SauceHandler {
    /**
     * @param {Object} options Object for overriding the query system for API. valid parameters are outputType (the type of output you want) and numRes (number of responses you want returned)
     * @param {String} apiKey the API key for interacting with sauceNao
     * @see {link} https://saucenao.com/user.php?page=search-api
     */
    constructor(options = {}, apiKey) {
        this.apiKey = apiKey;
        this.options = {
            outputType: this.options.outputType || 2,
            numRes: this.options.numRes || 5
        };
        if (!this.apiKey || apiKey === typeof string) {
            throw new TypeError('No API Key or invalid key was provided');
        }
    }
    /**
     * Gets the source and outputs it in your preffered output type
     * @param {String} path filepath for the image you want to get the source from (Not Implemented yet).
     * @param {String} link web address for the source, must be a valid HTTP/HTTPS address.
     * @returns {Promise} and JSON output.
     * @example client.getSauce(path/link).then(res => { console.log(res) });
     */
    getSauce(path, link) {
        return new Promise((resolve, reject) => {
            if (!path === typeof path) {
                throw new TypeError('path is not string');
            } else if (path) {
                /** @todo Finalize this. We need to input file as a stream then convert to MIMEType */
                throw new Error('This is not implemented yet!');
                /* got(`http://saucenao.com/search.php?output_type=${this.options.outputType}&numres=${this.options.numRes}&api_key=${this.apiKey}`, {}).then(res => {
                 });*/
            } else if (link) {
                if (!urlRegex) {
                    throw new Error('Link is not valid HTTP/HTTPS Address.');
                } else {
                    /** @todo I need a regex for making the following URL in the URL parameter */
                    got(`http://saucenao.com/search.php?output_type=${this.options.outputType}&numres=${this.options.numRes}&api_key=${this.apiKey}&url=${encodeURIComponent(link)}`).then(res => {
                        resolve(res.body);
                    }).catch(reject);
                }
            }
        });
    }
}

module.exports = SauceHandler;<commit_msg>I forgot to nullthis nyahahah<commit_after>/* SauceNao query Handler
 *
 *
 * Contributed by Capuccino
 */

const got = require('got');
const urlRegex = str => /(http(s)?:\/\/)?(www\.)?[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi.test(str);

/**
 * Query Handler for SauceNao-related requests.
 */

class SauceHandler {
    /**
     * @param {Object} options Object for overriding the query system for API. valid parameters are outputType (the type of output you want) and numRes (number of responses you want returned)
     * @param {String} apiKey the API key for interacting with sauceNao
     * @see {link} https://saucenao.com/user.php?page=search-api
     */
    constructor(options = {}, apiKey) {
        this.apiKey = apiKey;
        this.options = {
            outputType: this.options.outputType || 2,
            numRes: this.options.numRes || 5
        };
        if (!this.apiKey || !apiKey === typeof string) {
            throw new TypeError('No API Key or invalid key was provided');
        }
    }
    /**
     * Gets the source and outputs it in your preffered output type
     * @param {String} path filepath for the image you want to get the source from (Not Implemented yet).
     * @param {String} link web address for the source, must be a valid HTTP/HTTPS address.
     * @returns {Promise} and JSON output.
     * @example client.getSauce(path/link).then(res => { console.log(res) });
     */
    getSauce(path, link) {
        return new Promise((resolve, reject) => {
            if (!path === typeof path) {
                throw new TypeError('path is not string');
            } else if (path) {
                /** @todo Finalize this. We need to input file as a stream then convert to MIMEType */
                throw new Error('This is not implemented yet!');
                /* got(`http://saucenao.com/search.php?output_type=${this.options.outputType}&numres=${this.options.numRes}&api_key=${this.apiKey}`, {}).then(res => {
                 });*/
            } else if (link) {
                if (!urlRegex) {
                    throw new Error('Link is not valid HTTP/HTTPS Address.');
                } else {
                    /** @todo I need a regex for making the following URL in the URL parameter */
                    got(`http://saucenao.com/search.php?output_type=${this.options.outputType}&numres=${this.options.numRes}&api_key=${this.apiKey}&url=${encodeURIComponent(link)}`).then(res => {
                        resolve(res.body);
                    }).catch(reject);
                }
            }
        });
    }
}

module.exports = SauceHandler;<|endoftext|>


<commit_before>define(function (require) {
    var $ = require('jquery');
    var _ = require('underscore');
    var Backbone = require('util/backbone-helper');
    var Hbs = require('handlebars');
    var Mn = require('backbone.marionette');
    var Q = require('q');
    var Radio = require('backbone.radio');
    var pageChannel = Radio.channel('page');
    var courseChannel = Radio.channel('course');
    var template = require('text!ctemplates/addNewCategoryView.hbs');
    var alertTemplate = require('text!ctemplates/alert-block.hbs');

    var Course = require('course/model/course');

    var NewCategoryView = Mn.ItemView.extend({
        tagName: 'div',
        className: 'new-category modal-dialog  modal-lg',
        template: Hbs.compile(template),
        ui: {
            //'newCategoryButton' : '.newCategoryButton',
            'save': '.save',
            'cancel': '.cancel',
            'name': '.name',
            'weight': '.weight',
            'category': '.parent-category',
            error: '.error'
        },
        /**
         * Hides the dialog on initial load
         */

        events: {
            'click @ui.save': 'saveNewCategory',
            'click @ui.cancel': 'closeNewCategory'
        },
        traverseCat: function (indent, o) {

            for (i in o) {
                if (o[i] &&
                    typeof o[i].tree === 'function'
                    && typeof(o[i].tree()) == "object") {
                    this.categoryList.push({
                        name: indent + " " + o[i].get('name'),
                        cid: o[i].cid
                    });
                    this.traverseCat(indent + "---", o[i].tree());
                }
            }

        },

        initialize: function () {
            this.model = courseChannel.request('current:course');
            this.alertTemplate = Hbs.compile(alertTemplate);
        },
        onShow: function () {
            var categories = this.model.categories;
            var categoryTree = categories.tree();
            this.categoryList = [];
            var self = this;

            self.traverseCat("", categoryTree);

            var optionString;
            this.categoryList.forEach(function (c) {
                optionString = '<option value="' + c.cid + '" >' + c.name + '</option>';
                $('#new-category-parent-category').append(optionString);
            });
        },
        saveNewCategory: function () {
            var ui = this.ui;
            self = this;
            var newCategory = {};

            newCategory.course = this.model.get('colloquialUrl');
            if (ui.name.val().length === 0){
                self.ui.error.html(self.alertTemplate({
                    message: "Category name can not be empty"
                }));
                return;
            }
            else
                newCategory.name = ui.name.val();

            if (ui.weight.val().length === 0){
                self.ui.error.html(self.alertTemplate({
                    message: "Category weight can not be empty"
                }));
                return;
            }
            else
                newCategory.weight = ui.weight.val();

            if (ui.category.val() == null){
                self.ui.error.html(self.alertTemplate({
                    message: "Course Abbreviation can not be empty"
                }));
                return;
            }
            else
                newCategory.parentCategory = ui.category.val();

            if (isNaN(ui.weight.val()) || ui.weight.val() < 0 || ui.weight.val() > 1) {
                self.ui.error.html(self.alertTemplate({
                    message: "Category weight must be a number between 0 and 1"
                }));
                return;
            }

            console.log(newCategory);

            //var category = new Category(newCategory);
            //category.save()
            this.model.categories.push(newCategory);
            this.model.categories.save()

            //TODO Input value checking above!!
            //TODO Please save this to DB

            //$('.cancel').click()
        }
    })

    return NewCategoryView;
});

//
//module.exports = function generateMockCategory(name, parentPath) {
//    var path = parentPath + pathSeparator + name;
//
//    var result = new Object();
//
//    result.name = name
//    result.weight = 1
//    result.assignments = new Array()
//    result.path = path
//
//    return result;
//
//}<commit_msg>Add new category?<commit_after>define(function (require) {
    var $ = require('jquery');
    var _ = require('underscore');
    var Backbone = require('util/backbone-helper');
    var Hbs = require('handlebars');
    var Mn = require('backbone.marionette');
    var Q = require('q');
    var Radio = require('backbone.radio');
    var pageChannel = Radio.channel('page');
    var courseChannel = Radio.channel('course');
    var template = require('text!ctemplates/addNewCategoryView.hbs');
    var alertTemplate = require('text!ctemplates/alert-block.hbs');

    var Course = require('course/model/course');

    var NewCategoryView = Mn.ItemView.extend({
        tagName: 'div',
        className: 'new-category modal-dialog  modal-lg',
        template: Hbs.compile(template),
        ui: {
            //'newCategoryButton' : '.newCategoryButton',
            'save': '.save',
            'cancel': '.cancel',
            'name': '.name',
            'weight': '.weight',
            'category': '.parent-category',
            error: '.error'
        },
        /**
         * Hides the dialog on initial load
         */

        events: {
            'click @ui.save': 'saveNewCategory',
            'click @ui.cancel': 'closeNewCategory'
        },
        traverseCat: function (indent, o) {

            for (i in o) {
                if (o[i] &&
                    typeof o[i].tree === 'function'
                    && typeof(o[i].tree()) == "object") {
                    this.categoryList.push({
                        name: indent + " " + o[i].get('name'),
                        cid: o[i].cid,
                        path: o[i].get('path')
                    });
                    this.traverseCat(indent + "---", o[i].tree());
                }
            }

        },

        initialize: function () {
            this.model = courseChannel.request('current:course');
            this.course = courseChannel.request('current:course');
            this.listenTo(this.model.categories, 'add remove update reset sort sync', this.onShow.bind(this));
            this.alertTemplate = Hbs.compile(alertTemplate);
        },
        onShow: function () {
            var categories = this.model.categories;
            var categoryTree = categories.tree();
            this.categoryList = [];
            var self = this;

            self.traverseCat("", categoryTree);

            var optionString;
            this.categoryList.forEach(function (c) {
                optionString = '<option value="' + c.path + '" >' + c.name + '</option>';
                $('#new-category-parent-category').append(optionString);
            });
        },
        saveNewCategory: function () {
            var ui = this.ui;
            self = this;
            var newCategory = {};

            //newCategory.course = this.model.get('colloquialUrl');
            if (ui.name.val().length === 0){
                self.ui.error.html(self.alertTemplate({
                    message: "Category name can not be empty"
                }));
                return;
            }
            else
                newCategory.name = ui.name.val();

            if (ui.weight.val().length === 0){
                self.ui.error.html(self.alertTemplate({
                    message: "Category weight can not be empty"
                }));
                return;
            }
            else
                newCategory.weight = ui.weight.val();

            if (ui.category.val() == null){
                self.ui.error.html(self.alertTemplate({
                    message: "Must Choose a Category"
                }));
                return;
            }
            else
                newCategory.path = ui.category.val();

            if (isNaN(ui.weight.val()) || ui.weight.val() < 0 || ui.weight.val() > 1) {
                self.ui.error.html(self.alertTemplate({
                    message: "Category weight must be a number between 0 and 1"
                }));
                return;
            }

            var newPath = newCategory.name;
            newPath = newPath.replace(/\s+/g, '');
            newCategory.path = newCategory.path + "#" + newPath ;
            newCategory.assignments = new Array();

            console.log(newCategory);

            //var category = new Category(newCategory);
            //category.save()
            this.model.categories.push(newCategory);

            var modalRegion = pageChannel.request('modalRegion');
            this.model.save().then(modalRegion.hideModal())
            //this.model.save()
            //window.location.reload();

            //TODO Input value checking above!!
            //TODO Please save this to DB

            //$('.cancel').click()
        }
    })

    return NewCategoryView;
});

//
//module.exports = function generateMockCategory(name, parentPath) {
//    var path = parentPath + pathSeparator + name;
//
//    var result = new Object();
//
//    result.name = name
//    result.weight = 1
//    result.assignments = new Array()
//    result.path = path
//
//    return result;
//
//}<|endoftext|>


<commit_before>module('lively.ide.codeeditor.TextOverlay').requires('lively.DOMAbstraction').toRun(function() {

(function setupCSS() {
    var css = ".text-overlay {\n"
            + "    z-index: 999;\n"
            + "    font-family: Monaco, monospace;\n"
            + "    font-size: 11px;\n"
            + "    position: absolute;\n"
            + "    color: white;\n"
            + "    background: darkviolet;\n"
            + "    padding: 1px;\n"
            + "    border-radius: 4px;\n"
            + "    box-shadow: 0px 0px 5px 3px rgb(160, 100, 210);\n"
         // + "    text-shadow: 0px 0px 5px rgba(0,0,200, 0.7);\n"
         // + "    text-shadow: 0px 0px 5px blue;\n"
         // + "    text-shadow: 0px 0px 5px white;\n"
            + "    white-space: pre;\n"
            + "}\n"
            + ".text-overlay.hidden {\n"
            + "    display: none;\n"
            + "}"
    XHTMLNS.addCSSDef(css, 'lively.ide.CodeEditorTextOverlay');
})();

Object.subclass("lively.ide.CodeEditorTextOverlay.Overlay",
"properties", {
    baseClassName: "text-overlay",
    overlays: null,
    id: null
},
"initializing", {
    initialize: function()  {
        this.overlays = [];
        this.$redraw = this.redraw.bind(this);
        this.$onDocumentChange = this.onDocumentChange.bind(this)
    },
    attach: function(session) {
        var isInstalled = this.id && this.id in session.$frontMarkers;
        if (isInstalled) this.detach(session);
        session.addDynamicMarker(this, true);
        session.on('change', this.$onDocumentChange);
        var overlays = this.overlays.clone();
        this.redraw(session);
    },
    detach: function(session) {
        var id = this.id;
        session.removeMarker(id);
        session.removeEventListener('change', this.$onDocumentChange);
        delete this.id;
    }
},
"updating", {
    onChange: function(evt, session) {
        this.redraw(session);
        lively.bindings.signal(this, 'changed');
    },
    onDocumentChange: function(evt, session) {
        this.onChange(evt,session);
    },
    update: function(html, markerLayer, session, config) {
        var startRow = config.firstRowScreen,
            endRow = config.lastRow,
            overlays = this.overlays || [],
            classNames = [this.baseClassName];
        overlays.forEach(function(overlay) {
            if (overlay.start.row < startRow || overlay.start.row > endRow) return;
            var x = config.padding + (config.characterWidth * overlay.start.column),
                y = config.lineHeight * (overlay.start.row-config.firstRowScreen),
                classes = classNames.concat(overlay.classNames).join(" ");
            html.pushAll([
                "",
                overlay.text,
                ""])
        });
    },
    redraw: function(session) {
        session._signal('changeFrontMarker');
    }
},
"accessing", {
    add: function(overlay, session) {
        if (!overlay.classNames) overlay.classNames = [];
        this.overlays.push(overlay);
        if (session.$textOverlay !== this) this.attach(session);
        this.onChange({type: 'overlayAdded', data: overlay}, session);
    },
    remove: function(overlay, session) {
        this.overlays.remove(overlay);
        this.onChange({type: 'overlayRemoved', data: overlay}, session);
    },
    removeAllOverlays: function(session) {
        this.overlays.clone().forEach(function(overlay) {
            this.remove(overlay, session); }, this);
    },
    getElements: function(editor) {
        return Array.from(editor.renderer.container.getElementsByClassName(this.baseClassName));
    }
});

(function extendCodeEditor() {
require('lively.ide.CodeEditor').toRun(function() {

    lively.morphic.CodeEditor.addMethods(
    'text overlay', {
        setupOverlaySupport: function(ed) {
            var session = ed.session;
            var $overlay = session.$textOverlay;
            if ($overlay) $overlay.detach(session)
            session.$textOverlay = new lively.ide.CodeEditorTextOverlay.Overlay()
            session.$textOverlay.attach(session);
            return session.$textOverlay;
        },

        withOverlaySupport: function(func) {
            this.withAceDo(function(ed) {
                func.call(this, ed.session.$textOverlay || this.setupOverlaySupport(ed), ed);
            });
        },

        addTextOverlay: function(overlay) {
            if (!this.getTextOverlaysEnabled()) return;
            this.withOverlaySupport(function($overlay, ed) {
                $overlay.add(overlay, ed.session); });
        },

        redrawTextOverlays: function() {
            this.withOverlaySupport(function(overlay, ed) {
                overlay.redraw(ed.session);
            });
        },
        removeTextOverlay: function() {
            this.withOverlaySupport(function($overlay, ed) {
                $overlay.detach(ed.session);
                delete ed.session.$textOverlay;
            });
        },

        hideTextOverlays: function() {
            this.jQuery().find('.text-overlay').addClass('hidden');
        },

        unhideTextOverlays: function() {
            this.jQuery().find('.text-overlay').removeClass('hidden');
        },

        setTextOverlaysEnabled: function(bool) {
            if (bool) this.textString += ''; // force redraw
            else this.removeTextOverlay();
            return this._TextOverlaysEnabled = bool;
        },
        getTextOverlaysEnabled: function() {
            return this._TextOverlaysEnabled === undefined || this._TextOverlaysEnabled;
        }
    });
});
})();

}) // end of module<commit_msg>codeeditor: fixing text-verlays when lines are wrapped<commit_after>module('lively.ide.codeeditor.TextOverlay').requires('lively.DOMAbstraction').toRun(function() {

(function setupCSS() {
    var css = ".text-overlay {\n"
            + "    z-index: 999;\n"
            + "    font-family: Monaco, monospace;\n"
            + "    font-size: 11px;\n"
            + "    position: absolute;\n"
            + "    color: white;\n"
            + "    background: darkviolet;\n"
            + "    padding: 1px;\n"
            + "    border-radius: 4px;\n"
            + "    box-shadow: 0px 0px 5px 3px rgb(160, 100, 210);\n"
         // + "    text-shadow: 0px 0px 5px rgba(0,0,200, 0.7);\n"
         // + "    text-shadow: 0px 0px 5px blue;\n"
         // + "    text-shadow: 0px 0px 5px white;\n"
            + "    white-space: pre;\n"
            + "}\n"
            + ".text-overlay.hidden {\n"
            + "    display: none;\n"
            + "}"
    XHTMLNS.addCSSDef(css, 'lively.ide.CodeEditorTextOverlay');
})();

Object.subclass("lively.ide.CodeEditorTextOverlay.Overlay",
"properties", {
    baseClassName: "text-overlay",
    overlays: null,
    id: null
},
"initializing", {
    initialize: function()  {
        this.overlays = [];
        this.$redraw = this.redraw.bind(this);
        this.$onDocumentChange = this.onDocumentChange.bind(this)
    },
    attach: function(session) {
        var isInstalled = this.id && this.id in session.$frontMarkers;
        if (isInstalled) this.detach(session);
        session.addDynamicMarker(this, true);
        session.on('change', this.$onDocumentChange);
        var overlays = this.overlays.clone();
        this.redraw(session);
    },
    detach: function(session) {
        var id = this.id;
        session.removeMarker(id);
        session.removeEventListener('change', this.$onDocumentChange);
        delete this.id;
    }
},
"updating", {
    onChange: function(evt, session) {
        this.redraw(session);
        lively.bindings.signal(this, 'changed');
    },
    onDocumentChange: function(evt, session) {
        this.onChange(evt,session);
    },
    update: function(html, markerLayer, session, config) {
        var startRow = config.firstRowScreen,
            endRow = config.lastRow,
            overlays = this.overlays || [],
            classNames = [this.baseClassName];

        overlays.forEach(function(overlay) {
            if (overlay.start.row < startRow || overlay.start.row > endRow) return;
            var screenPos = session.documentToScreenPosition(overlay.start.row, overlay.start.column),
                x = config.padding + (config.characterWidth * screenPos.column),
                y = config.lineHeight * (screenPos.row-config.firstRowScreen),
                classes = classNames.concat(overlay.classNames).join(" ");
            html.pushAll([
                "",
                overlay.text,
                ""])
        });
    },
    redraw: function(session) {
        session._signal('changeFrontMarker');
    }
},
"accessing", {
    add: function(overlay, session) {
        if (!overlay.classNames) overlay.classNames = [];
        this.overlays.push(overlay);
        if (session.$textOverlay !== this) this.attach(session);
        this.onChange({type: 'overlayAdded', data: overlay}, session);
    },
    remove: function(overlay, session) {
        this.overlays.remove(overlay);
        this.onChange({type: 'overlayRemoved', data: overlay}, session);
    },
    removeAllOverlays: function(session) {
        this.overlays.clone().forEach(function(overlay) {
            this.remove(overlay, session); }, this);
    },
    getElements: function(editor) {
        return Array.from(editor.renderer.container.getElementsByClassName(this.baseClassName));
    }
});

(function extendCodeEditor() {
require('lively.ide.CodeEditor').toRun(function() {

    lively.morphic.CodeEditor.addMethods(
    'text overlay', {
        setupOverlaySupport: function(ed) {
            var session = ed.session;
            var $overlay = session.$textOverlay;
            if ($overlay) $overlay.detach(session)
            session.$textOverlay = new lively.ide.CodeEditorTextOverlay.Overlay()
            session.$textOverlay.attach(session);
            return session.$textOverlay;
        },

        withOverlaySupport: function(func) {
            this.withAceDo(function(ed) {
                func.call(this, ed.session.$textOverlay || this.setupOverlaySupport(ed), ed);
            });
        },

        addTextOverlay: function(overlay) {
            if (!this.getTextOverlaysEnabled()) return;
            this.withOverlaySupport(function($overlay, ed) {
                $overlay.add(overlay, ed.session); });
        },

        redrawTextOverlays: function() {
            this.withOverlaySupport(function(overlay, ed) {
                overlay.redraw(ed.session);
            });
        },
        removeTextOverlay: function() {
            this.withOverlaySupport(function($overlay, ed) {
                $overlay.detach(ed.session);
                delete ed.session.$textOverlay;
            });
        },

        hideTextOverlays: function() {
            this.jQuery().find('.text-overlay').addClass('hidden');
        },

        unhideTextOverlays: function() {
            this.jQuery().find('.text-overlay').removeClass('hidden');
        },

        setTextOverlaysEnabled: function(bool) {
            if (bool) this.textString += ''; // force redraw
            else this.removeTextOverlay();
            return this._TextOverlaysEnabled = bool;
        },
        getTextOverlaysEnabled: function() {
            return this._TextOverlaysEnabled === undefined || this._TextOverlaysEnabled;
        }
    });
});
})();

}) // end of module
<|endoftext|>


<commit_before>'use babel'

let [workspaceElement, editor, editorElement, pack] = [];
let path = require('path');

function sharedSetup() {

  atom.project.setPaths([path.join(__dirname, 'fixtures')]);
  workspaceElement = atom.views.getView(atom.workspace)

  waitsForPromise(() => {

    return atom.packages.activatePackage('atom-ternjs').then((pkg) => {

      pack = pkg.mainModule;
    });
  });

  waitsForPromise(() => {

    return atom.workspace.open('test.js');
  });

  runs(() => {

    editor = atom.workspace.getActiveTextEditor();
    editorElement = atom.views.getView(editor);
  });
}

describe('atom-ternjs', () => {

  beforeEach(() => {

    sharedSetup(true);
  });

  describe('activate()', () => {

    it('activates atom-ternjs and initializes the autocomplete-plus provider', () => {

      expect(pack.provider).toBeDefined();
    });

    it('activates atom-ternjs and initializes the manager', () => {

      expect(pack.manager).toBeDefined();
    });
  });

  describe('deactivate()', () => {

    beforeEach(() => {

      editor.setCursorBufferPosition([4, 15]);
      atom.packages.deactivatePackage('atom-ternjs');
    });

    it('deactivates atom-ternjs', () => {

      expect(pack.manager).toBeUndefined();
      expect(pack.provider).toBeUndefined();
    });

    it('destroys all views', () => {

      expect(workspaceElement.querySelectorAll('atom-ternjs-reference').length).toBe(0);
      expect(workspaceElement.querySelectorAll('atom-ternjs-rename').length).toBe(0);
      expect(workspaceElement.querySelectorAll('atom-ternjs-config').length).toBe(0);
      expect(workspaceElement.querySelectorAll('atom-ternjs-documentation').length).toBe(0);
      expect(workspaceElement.querySelectorAll('atom-ternjs-type').length).toBe(0);
      expect(editorElement.querySelectorAll('atom-text-editor .scroll-view .atom-ternjs-definition-marker').length).toBe(0);
    });
  });
});

describe('atom-ternjs', () => {

  beforeEach(() => {

    sharedSetup(false);
  });

  describe('activate()', () => {

  });
});
<commit_msg>fix specs (WIP)<commit_after>'use babel'

let [workspaceElement, editor, editorElement, pack] = [];
let path = require('path');

function sharedSetup() {

  atom.project.setPaths([path.join(__dirname, 'fixtures')]);
  workspaceElement = atom.views.getView(atom.workspace);

  waitsForPromise(() => {

    return new Promise((resolve, reject) => {

      atom.workspace.open('test.js')
      .then(() => {

        pack = atom.packages.enablePackage('atom-ternjs');

        resolve();
      });
    });
  });

  runs(() => {

    editor = atom.workspace.getActiveTextEditor();
    editorElement = atom.views.getView(editor);
  });
}

describe('atom-ternjs', () => {

  beforeEach(() => {

    sharedSetup(true);
  });

  describe('activate()', () => {

    it('activates the atom-ternjs-manager', () => {

      expect(pack.config).toBeDefined();
    });
  });

  describe('deactivate()', () => {

    beforeEach(() => {

      editor.setCursorBufferPosition([4, 15]);
      atom.packages.deactivatePackage('atom-ternjs');
    });

    it('destroys all views', () => {

      expect(workspaceElement.querySelectorAll('atom-ternjs-reference').length).toBe(0);
      expect(workspaceElement.querySelectorAll('atom-ternjs-rename').length).toBe(0);
      expect(workspaceElement.querySelectorAll('.atom-ternjs-config').length).toBe(0);
      expect(workspaceElement.querySelectorAll('atom-ternjs-documentation').length).toBe(0);
      expect(workspaceElement.querySelectorAll('atom-ternjs-type').length).toBe(0);
      expect(editorElement.querySelectorAll('atom-text-editor .atom-ternjs-definition-marker').length).toBe(0);
    });
  });
});

describe('atom-ternjs', () => {

  beforeEach(() => {

    sharedSetup(false);
  });

  describe('activate()', () => {

  });
});
<|endoftext|>


<commit_before>'use babel'

'use strict'

import { defaultRoute, user, api, savePostAPI, listPostsAPI, getPostAPI, getPostView, updatePostAPI, deletePostAPI, loginPage, signupPage, logout } from './routes'

const express = require('express')
const config = require('./config')
const engine = require('consolidate')
const root = require('./util')
const passport = require('passport')
const flash = require('connect-flash')
const Logger = require('./logger').Logger
const bodyParser = require('body-parser')
const methodOverride = require('method-override')
const session = require('express-session')
const cookieParser = require('cookie-parser')
const favicon = require('serve-favicon')

const pring = express()
const routerAPI = express.Router()

require('./middleware/auth/passport')(passport)

function isLoggedin (req, res, next) {
  if (req.isAuthenticated()) return next()
  res.redirect('/')
}

pring.use(bodyParser.urlencoded({ extended: true }))
pring.use(bodyParser.json())
pring.use(cookieParser())
pring.use(methodOverride())
pring.use(favicon(__dirname + '/public/favicon.ico'))

pring.use(session({
  secret: 'pagedekisasimplestaticgenerator',
  resave: true,
  saveUninitialized: true
}))

pring.use(passport.initialize())
pring.use(passport.session())
pring.use(flash())
pring.use(express.static(`${root.path()}/public`))
pring.set('views', `${root.path()}/views`)
pring.engine('html', engine.handlebars)
pring.set('view engine', 'html')

config.get('passport:authentication') ? pring.get('/', defaultRoute) : pring.get('/', user)

routerAPI.route('/').get(api)
routerAPI.route('/posts')
  .post(savePostAPI)
  .get(listPostsAPI)
routerAPI.route('/posts/:id')
  .get(getPostAPI)
  .put(updatePostAPI)
  .delete(deletePostAPI)

pring.use('/api', routerAPI)

pring.get('/posts/:id', getPostView)

pring.post('/login', passport.authenticate('local-login', {
  successRedirect: '/user',
  failureRedirect: '/login',
  failureFlash: true
}))
pring.get('/login', loginPage)

pring.post('/signup', passport.authenticate('local-signup', {
  successRedirect: '/user',
  failureRedirect: '/signup',
  failureFlash: true
}))
pring.get('/signup', signupPage)

pring.get('/logout', logout)
pring.get('/user', isLoggedin, user)

pring.listen(config.get('express:port'), () => Logger.info(`Blogel is running on port ${config.get('express:port')}`))

process.on('unhandledRejection', (err) => Logger.error(err.stack))

module.exports = { express, pring }
<commit_msg>Use favico<commit_after>'use babel'

'use strict'

import { defaultRoute, user, api, savePostAPI, listPostsAPI, getPostAPI, getPostView, updatePostAPI, deletePostAPI, loginPage, signupPage, logout } from './routes'

const express = require('express')
const config = require('./config')
const engine = require('consolidate')
const root = require('./util')
const passport = require('passport')
const flash = require('connect-flash')
const Logger = require('./logger').Logger
const bodyParser = require('body-parser')
const methodOverride = require('method-override')
const session = require('express-session')
const cookieParser = require('cookie-parser')
const favicon = require('express-favicon')

const pring = express()
const routerAPI = express.Router()

require('./middleware/auth/passport')(passport)

function isLoggedin (req, res, next) {
  if (req.isAuthenticated()) return next()
  res.redirect('/')
}

pring.use(bodyParser.urlencoded({ extended: true }))
pring.use(bodyParser.json())
pring.use(cookieParser())
pring.use(methodOverride())
pring.use(favicon(`${root.path()}/public/favicon.ico`))

pring.use(session({
  secret: 'pagedekisasimplestaticgenerator',
  resave: true,
  saveUninitialized: true
}))

pring.use(passport.initialize())
pring.use(passport.session())
pring.use(flash())
pring.use(express.static(`${root.path()}/public`))
pring.set('views', `${root.path()}/views`)
pring.engine('html', engine.handlebars)
pring.set('view engine', 'html')

config.get('passport:authentication') ? pring.get('/', defaultRoute) : pring.get('/', user)

routerAPI.route('/').get(api)
routerAPI.route('/posts')
  .post(savePostAPI)
  .get(listPostsAPI)
routerAPI.route('/posts/:id')
  .get(getPostAPI)
  .put(updatePostAPI)
  .delete(deletePostAPI)

pring.use('/api', routerAPI)

pring.get('/posts/:id', getPostView)

pring.post('/login', passport.authenticate('local-login', {
  successRedirect: '/user',
  failureRedirect: '/login',
  failureFlash: true
}))
pring.get('/login', loginPage)

pring.post('/signup', passport.authenticate('local-signup', {
  successRedirect: '/user',
  failureRedirect: '/signup',
  failureFlash: true
}))
pring.get('/signup', signupPage)

pring.get('/logout', logout)
pring.get('/user', isLoggedin, user)

pring.listen(config.get('express:port'), () => Logger.info(`Blogel is running on port ${config.get('express:port')}`))

process.on('unhandledRejection', (err) => Logger.error(err.stack))

module.exports = { express, pring }
<|endoftext|>


<commit_before>import URIConf from '../src/uriconf';
import pathname from '../src/addons/pathname';
import uri from '../src/uri';
import path from '../src/path';
import createMemoryHistory from 'history/createMemoryHistory';

describe('URIConf', () => {

  let history;

  beforeEach(() => {
    history = createMemoryHistory();
    pathname.reset();
  });

  describe('constructor', () => {
    // these tests rely on the fact that the pathname generator
    // is a default addon
    it('registers uris', () => {
      const uris = [
        uri('Home', path('', { end: true })),
        uri('About', path('about')),
        uri('Contact', path('contact'))
      ];
      const conf = URIConf(history, uris);
      const names = [ 'Home', 'About', 'Contact' ];
      names.forEach(n => {
        expect(pathname.get(n)).toBeDefined();
      });
    });

    it('registers nested uris', () => {
      const uris = [
        uri('Home', path('', { end: true })),
        uri('About', path('about')),
        uri('Contact', path('contact'), [
          uri('Email', path('email')),
          uri('Phone', path('phone'))
        ])
      ];

      const conf = URIConf(history, uris);
      const names = [ 'Email', 'Phone' ];
      names.forEach(n => {
        expect(pathname.get(n)).toBeDefined();
      });
    });

    it('works when initialURIs isn\'t an array', () => {
      const uris = uri('Contact', path('contact'), [
        uri('Email', path('email')),
        uri('Phone', path('phone'))
      ]);

      const conf = URIConf(history, uris);
      const names = [ 'Contact', 'Email', 'Phone' ];
      names.forEach(n => {
        expect(pathname.get(n)).toBeDefined();
      });
    });

    it('makes addons available through return object', () => {
      const uris = [
        uri('Home', path('', { end: true }))
      ];
      const fakeAddon = {
        name: 'fake',
        register: () => {},
        reset: () => {},
        get: () => {}
      };
      const conf = URIConf(history, uris, [ fakeAddon ]);
      expect(conf.addons.fake).toBeDefined();
    });

    it('includes pathname addon by default', () => {
      const uris = [
        uri('Home', path('', { end: true }))
      ];
      const conf = URIConf(history, uris);
      expect(conf.addons.pathname).toBeDefined();
    })
  });

  describe('refresh', () => {
    const err = console.error;

    beforeEach(() => {
      console.error = jest.fn();
    });

    afterEach(() => {
      console.error = err;
    });

    it('resets and replaces registered uris', () => {
      const uris = [
        uri('Home', path('', { end: true })),
        uri('About', path('about')),
        uri('Contact', path('contact'))
      ];
      const conf = URIConf(history, uris);

      const spanishURIs = [
        uri('Casa', path('', { end: true })),
        uri('Acerca De', path('acerca-de')),
        uri('Contacto', path('contacto'))
      ];
      conf.refresh(spanishURIs);

      const englishNames = [ 'Home', 'About', 'Contact' ];
      englishNames.forEach(n => {
        expect(pathname.get(n)).toBeUndefined();
      });

      const spanishNames = [ 'Casa', 'Acerca De', 'Contacto' ];
      spanishNames.forEach(n => {
        expect(pathname.get(n)).toBeDefined();
      });
    })
  });

  describe('emit', () => {
    it('notifies subscribers of matching routes when location changes', () => {
      const uris = [
        uri('Home', path('', { end: true })),
        uri('About', path('about')),
        uri('Contact', path('contact'), [
          uri('How', path(':method'))
        ])
      ];

      const conf = URIConf(history, uris);
      conf.subscribe(info => {
        expect(info['Contact']).toBeDefined();
        expect(info['How']).toBeDefined();
        expect(info['How'].params.method).toBe('mail');
      });
      history.push('/contact/mail');
    });

    it('notifies subscribers after promises have resolved', (done) => {
      let promiseResolved = false;
      const uris = [
        uri('Home', path('', { end: true })),
        uri('About', path('about')),
        uri('Contact', path('contact'), [
          uri('How', path(':method'), undefined, {
            load: () => {
              return new Promise((resolve) => {
                setTimeout(() => {
                  promiseResolved = true;
                  resolve(true);
                }, 500);
              })
            }
          })
        ])
      ];
      const conf = URIConf(history, uris);
      conf.subscribe(info => {
        expect(promiseResolved).toBe(true);
        done();
      });
      history.push('/contact/phone');
    });

    it('only emits most recent update if another one occurs before emitting', (done) => {
      let promiseResolved = false;
      const uris = [
        uri('Home', path('', { end: true })),
        uri('About', path('about')),
        uri('Contact', path('contact'), [
          uri('How', path(':method'), undefined, {
            preload: () => {
              return new Promise((resolve) => {
                setTimeout(() => {
                  promiseResolved = true;
                  resolve(true);
                }, 500);
              })
            }
          })
        ])
      ];
      const conf = URIConf(history, uris);
      conf.subscribe(info => {
        expect(info['How'].params.method).toBe('mail');
        done();
      });
      history.push('/contact/phone');
      history.push('/contact/mail');
    });

    it('will only match the first uri (per level) that matches', () => {
      const uris = [
        uri('Exact', path('exact')),
        uri('Catch All', path(':anything'))
      ];

      const conf = URIConf(history, uris);
      conf.subscribe(info => {
        expect(info['Exact']).toBeDefined();
        expect(info['Catch All']).toBeUndefined();
      });
      history.push('exact');
    });
  });
});
<commit_msg>Nested one uri match test<commit_after>import URIConf from '../src/uriconf';
import pathname from '../src/addons/pathname';
import uri from '../src/uri';
import path from '../src/path';
import createMemoryHistory from 'history/createMemoryHistory';

describe('URIConf', () => {

  let history;

  beforeEach(() => {
    history = createMemoryHistory();
    pathname.reset();
  });

  describe('constructor', () => {
    // these tests rely on the fact that the pathname generator
    // is a default addon
    it('registers uris', () => {
      const uris = [
        uri('Home', path('', { end: true })),
        uri('About', path('about')),
        uri('Contact', path('contact'))
      ];
      const conf = URIConf(history, uris);
      const names = [ 'Home', 'About', 'Contact' ];
      names.forEach(n => {
        expect(pathname.get(n)).toBeDefined();
      });
    });

    it('registers nested uris', () => {
      const uris = [
        uri('Home', path('', { end: true })),
        uri('About', path('about')),
        uri('Contact', path('contact'), [
          uri('Email', path('email')),
          uri('Phone', path('phone'))
        ])
      ];

      const conf = URIConf(history, uris);
      const names = [ 'Email', 'Phone' ];
      names.forEach(n => {
        expect(pathname.get(n)).toBeDefined();
      });
    });

    it('works when initialURIs isn\'t an array', () => {
      const uris = uri('Contact', path('contact'), [
        uri('Email', path('email')),
        uri('Phone', path('phone'))
      ]);

      const conf = URIConf(history, uris);
      const names = [ 'Contact', 'Email', 'Phone' ];
      names.forEach(n => {
        expect(pathname.get(n)).toBeDefined();
      });
    });

    it('makes addons available through return object', () => {
      const uris = [
        uri('Home', path('', { end: true }))
      ];
      const fakeAddon = {
        name: 'fake',
        register: () => {},
        reset: () => {},
        get: () => {}
      };
      const conf = URIConf(history, uris, [ fakeAddon ]);
      expect(conf.addons.fake).toBeDefined();
    });

    it('includes pathname addon by default', () => {
      const uris = [
        uri('Home', path('', { end: true }))
      ];
      const conf = URIConf(history, uris);
      expect(conf.addons.pathname).toBeDefined();
    })
  });

  describe('refresh', () => {
    const err = console.error;

    beforeEach(() => {
      console.error = jest.fn();
    });

    afterEach(() => {
      console.error = err;
    });

    it('resets and replaces registered uris', () => {
      const uris = [
        uri('Home', path('', { end: true })),
        uri('About', path('about')),
        uri('Contact', path('contact'))
      ];
      const conf = URIConf(history, uris);

      const spanishURIs = [
        uri('Casa', path('', { end: true })),
        uri('Acerca De', path('acerca-de')),
        uri('Contacto', path('contacto'))
      ];
      conf.refresh(spanishURIs);

      const englishNames = [ 'Home', 'About', 'Contact' ];
      englishNames.forEach(n => {
        expect(pathname.get(n)).toBeUndefined();
      });

      const spanishNames = [ 'Casa', 'Acerca De', 'Contacto' ];
      spanishNames.forEach(n => {
        expect(pathname.get(n)).toBeDefined();
      });
    })
  });

  describe('emit', () => {
    it('notifies subscribers of matching routes when location changes', () => {
      const uris = [
        uri('Home', path('', { end: true })),
        uri('About', path('about')),
        uri('Contact', path('contact'), [
          uri('How', path(':method'))
        ])
      ];

      const conf = URIConf(history, uris);
      conf.subscribe(info => {
        expect(info['Contact']).toBeDefined();
        expect(info['How']).toBeDefined();
        expect(info['How'].params.method).toBe('mail');
      });
      history.push('/contact/mail');
    });

    it('notifies subscribers after promises have resolved', (done) => {
      let promiseResolved = false;
      const uris = [
        uri('Home', path('', { end: true })),
        uri('About', path('about')),
        uri('Contact', path('contact'), [
          uri('How', path(':method'), undefined, {
            load: () => {
              return new Promise((resolve) => {
                setTimeout(() => {
                  promiseResolved = true;
                  resolve(true);
                }, 500);
              })
            }
          })
        ])
      ];
      const conf = URIConf(history, uris);
      conf.subscribe(info => {
        expect(promiseResolved).toBe(true);
        done();
      });
      history.push('/contact/phone');
    });

    it('only emits most recent update if another one occurs before emitting', (done) => {
      let promiseResolved = false;
      const uris = [
        uri('Home', path('', { end: true })),
        uri('About', path('about')),
        uri('Contact', path('contact'), [
          uri('How', path(':method'), undefined, {
            preload: () => {
              return new Promise((resolve) => {
                setTimeout(() => {
                  promiseResolved = true;
                  resolve(true);
                }, 500);
              })
            }
          })
        ])
      ];
      const conf = URIConf(history, uris);
      conf.subscribe(info => {
        expect(info['How'].params.method).toBe('mail');
        done();
      });
      history.push('/contact/phone');
      history.push('/contact/mail');
    });

    it('will only match the first uri (per level) that matches', () => {
      const uris = [
        uri('Exact', path('exact')),
        uri('Catch All', path(':anything'))
      ];

      const conf = URIConf(history, uris);
      conf.subscribe(info => {
        expect(info['Exact']).toBeDefined();
        expect(info['Catch All']).toBeUndefined();
      });
      history.push('exact');
    });

    it('only matches one uri for nested levels', () => {
      const uris = [
        uri('Parent', path('parent'), [
          uri('Exact', path('exact')),
          uri('Catch All', path(':anything'))
        ])
      ];

      const conf = URIConf(history, uris);
      conf.subscribe(info => {
        expect(info['Exact']).toBeDefined();
        expect(info['Catch All']).toBeUndefined();
      });
      history.push('parent/exact');
    })
  });
});
<|endoftext|>


<commit_before>import { takeLatest, put, call } from 'redux-saga/effects';

import {
  REQUEST_FEED_NOTIFICATIONS_SUCCESS,
  REQUEST_FEED_NOTIFICATIONS,
  REQUEST_FEED_NOTIFICATIONS_FAILURE,
} from 'actions/feedActions';
import moreNotificationsCall from 'api/feedApiCall';

export function* getFeedNotificationsFlow(action) {
  const receivedNotificationTypes = {
    deck_created: 'DECK_CREATED',
    deck_updated: 'DECK_UPDATED',
  };

  try {
    const responseListOfNotifications = yield call(
      moreNotificationsCall,
      action.meta,
    );
    if (!responseListOfNotifications) {
      throw new Error('Received undefined list.');
    }
    const listOfNotifications = responseListOfNotifications.map(
      responseNotification => ({
        timestamp: responseNotification.attributes.createdAt,
        type: receivedNotificationTypes[
          responseNotification.attributes.eventType.toLowerCase()
        ],
        targetDeck: responseNotification.attributes.deckName,
        concernedUser: responseNotification.attributes.userName,
      }),
    );

    yield put({
      type: REQUEST_FEED_NOTIFICATIONS_SUCCESS,
      payload: {
        listOfNotifications,
      },
    });
  } catch (error) {
    yield put({
      type: REQUEST_FEED_NOTIFICATIONS_FAILURE,
      payload: {
        message: error.message,
      },
    });
  }
}

function* feedUpdateWatcher() {
  yield takeLatest(REQUEST_FEED_NOTIFICATIONS, getFeedNotificationsFlow);
}

export default feedUpdateWatcher;
<commit_msg>Store the notification id when fetching notifications<commit_after>import { takeLatest, put, call } from 'redux-saga/effects';

import {
  REQUEST_FEED_NOTIFICATIONS_SUCCESS,
  REQUEST_FEED_NOTIFICATIONS,
  REQUEST_FEED_NOTIFICATIONS_FAILURE,
} from 'actions/feedActions';
import moreNotificationsCall from 'api/feedApiCall';

export function* getFeedNotificationsFlow(action) {
  const receivedNotificationTypes = {
    deck_created: 'DECK_CREATED',
    deck_updated: 'DECK_UPDATED',
  };

  try {
    const responseListOfNotifications = yield call(
      moreNotificationsCall,
      action.meta,
    );
    if (!responseListOfNotifications) {
      throw new Error('Received undefined list.');
    }
    const listOfNotifications = responseListOfNotifications.map(
      responseNotification => ({
        id: responseNotification.id,
        timestamp: responseNotification.attributes.createdAt,
        type:
          receivedNotificationTypes[
            responseNotification.attributes.eventType.toLowerCase()
          ],
        targetDeck: responseNotification.attributes.deckName,
        concernedUser: responseNotification.attributes.userName,
      }),
    );

    yield put({
      type: REQUEST_FEED_NOTIFICATIONS_SUCCESS,
      payload: {
        listOfNotifications,
      },
    });
  } catch (error) {
    yield put({
      type: REQUEST_FEED_NOTIFICATIONS_FAILURE,
      payload: {
        message: error.message,
      },
    });
  }
}

function* feedUpdateWatcher() {
  yield takeLatest(REQUEST_FEED_NOTIFICATIONS, getFeedNotificationsFlow);
}

export default feedUpdateWatcher;
<|endoftext|>


<commit_before>"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var Rule = (function (_super) {
    __extends(Rule, _super);
    function Rule() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    Rule.prototype.apply = function (sourceFile) {
        return this.applyWithFunction(sourceFile, walk, parseOptions(this.ruleArguments));
    };
    return Rule;
}(Lint.Rules.AbstractRule));
Rule.FAILURE_STRING = "Only ReadonlyArray allowed.";
exports.Rule = Rule;
var OPTION_IGNORE_LOCAL = "ignore-local";
var OPTION_IGNORE_PREFIX = "ignore-prefix";
function parseOptions(options) {
    var ignoreLocal = options.indexOf(OPTION_IGNORE_LOCAL) !== -1;
    var ignorePrefix;
    for (var _i = 0, options_1 = options; _i < options_1.length; _i++) {
        var o = options_1[_i];
        if (typeof o === "object" && o[OPTION_IGNORE_PREFIX] != null) {
            ignorePrefix = o[OPTION_IGNORE_PREFIX];
            break;
        }
    }
    return { ignoreLocal: ignoreLocal, ignorePrefix: ignorePrefix };
}
function walk(ctx) {
    return ts.forEachChild(ctx.sourceFile, cb);
    function cb(node) {
        // Skip checking in functions if ignore-local is set
        if (ctx.options.ignoreLocal && (node.kind === ts.SyntaxKind.FunctionDeclaration || node.kind === ts.SyntaxKind.ArrowFunction)) {
            // We still need to check the parameters!
            // SyntaxList node holds the parameters
            for (var _i = 0, _a = node.getChildren(ctx.sourceFile); _i < _a.length; _i++) {
                var child1 = _a[_i];
                if (child1.kind === ts.SyntaxKind.SyntaxList) {
                    for (var _b = 0, _c = child1.getChildren(ctx.sourceFile); _b < _c.length; _b++) {
                        var child2 = _c[_b];
                        if (child2.kind === ts.SyntaxKind.Parameter) {
                            for (var _d = 0, _e = child2.getChildren(ctx.sourceFile).filter(function (child) {
                                return child.kind === ts.SyntaxKind.ArrayLiteralExpression || child.kind === ts.SyntaxKind.TypeReference;
                            }); _d < _e.length; _d++) {
                                var child3 = _e[_d];
                                checkNode(child3, ctx);
                            }
                        }
                    }
                }
            }
            return;
        }
        // Check the node
        checkNode(node, ctx);
        // Use return becuase performance hints docs say it optimizes the function using tail-call recursion
        return ts.forEachChild(node, cb);
    }
}
function checkNode(node, ctx) {
    if (node.kind === ts.SyntaxKind.TypeReference && isInvalidArrayTypeReference(node, ctx)) {
        ctx.addFailureAtNode(node, Rule.FAILURE_STRING);
    }
    if (node.kind === ts.SyntaxKind.ArrayLiteralExpression && isInvalidArrayLiteralExpression(node, ctx)) {
        var variableDeclarationNode = node.parent;
        ctx.addFailureAt(variableDeclarationNode.name.getStart(ctx.sourceFile), variableDeclarationNode.name.getWidth(ctx.sourceFile), Rule.FAILURE_STRING);
    }
}
function isInvalidArrayTypeReference(node, ctx) {
    if (node.typeName.getText(ctx.sourceFile) === "Array") {
        if (ctx.options.ignorePrefix) {
            var variableDeclarationNode = node.parent;
            if (variableDeclarationNode.name.getText(ctx.sourceFile).substr(0, ctx.options.ignorePrefix.length) === ctx.options.ignorePrefix) {
                return false;
            }
        }
        return true;
    }
    return false;
}
function isInvalidArrayLiteralExpression(node, ctx) {
    // If the array literal is used in a variable declaration, the variable
    // must have a type spcecified, otherwise it will implicitly be of mutable Array type
    // It could also be a function parameter that has an array literal as default value
    if (node.parent && (node.parent.kind === ts.SyntaxKind.VariableDeclaration || node.parent.kind === ts.SyntaxKind.Parameter)) {
        var parent_1 = node.parent;
        if (!parent_1.type) {
            if (ctx.options.ignorePrefix &&
                parent_1.name.getText(ctx.sourceFile).substr(0, ctx.options.ignorePrefix.length) === ctx.options.ignorePrefix) {
                return false;
            }
            return true;
        }
    }
    return false;
}
<commit_msg>Built rule<commit_after>"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var Rule = (function (_super) {
    __extends(Rule, _super);
    function Rule() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    Rule.prototype.apply = function (sourceFile) {
        return this.applyWithFunction(sourceFile, walk, parseOptions(this.ruleArguments));
    };
    return Rule;
}(Lint.Rules.AbstractRule));
Rule.FAILURE_STRING = "Only ReadonlyArray allowed.";
exports.Rule = Rule;
var OPTION_IGNORE_LOCAL = "ignore-local";
var OPTION_IGNORE_PREFIX = "ignore-prefix";
function parseOptions(options) {
    var ignoreLocal = options.indexOf(OPTION_IGNORE_LOCAL) !== -1;
    var ignorePrefix;
    for (var _i = 0, options_1 = options; _i < options_1.length; _i++) {
        var o = options_1[_i];
        if (typeof o === "object" && o[OPTION_IGNORE_PREFIX] != null) {
            ignorePrefix = o[OPTION_IGNORE_PREFIX];
            break;
        }
    }
    return { ignoreLocal: ignoreLocal, ignorePrefix: ignorePrefix };
}
function walk(ctx) {
    return ts.forEachChild(ctx.sourceFile, cb);
    function cb(node) {
        // Skip checking in functions if ignore-local is set
        if (ctx.options.ignoreLocal && (node.kind === ts.SyntaxKind.FunctionDeclaration || node.kind === ts.SyntaxKind.ArrowFunction)) {
            // We still need to check the parameters which resides in the SyntaxList node
            for (var _i = 0, _a = node.getChildren(ctx.sourceFile); _i < _a.length; _i++) {
                var child1 = _a[_i];
                if (child1.kind === ts.SyntaxKind.SyntaxList) {
                    for (var _b = 0, _c = child1.getChildren(ctx.sourceFile); _b < _c.length; _b++) {
                        var child2 = _c[_b];
                        if (child2.kind === ts.SyntaxKind.Parameter) {
                            for (var _d = 0, _e = child2.getChildren(ctx.sourceFile).filter(function (child) {
                                return child.kind === ts.SyntaxKind.ArrayLiteralExpression || child.kind === ts.SyntaxKind.TypeReference;
                            }); _d < _e.length; _d++) {
                                var child3 = _e[_d];
                                checkNode(child3, ctx);
                            }
                        }
                    }
                }
            }
            return;
        }
        // Check the node
        checkNode(node, ctx);
        // Use return becuase performance hints docs say it optimizes the function using tail-call recursion
        return ts.forEachChild(node, cb);
    }
}
function checkNode(node, ctx) {
    if (node.kind === ts.SyntaxKind.TypeReference && isInvalidArrayTypeReference(node, ctx)) {
        ctx.addFailureAtNode(node, Rule.FAILURE_STRING);
    }
    if (node.kind === ts.SyntaxKind.ArrayLiteralExpression && isInvalidArrayLiteralExpression(node, ctx)) {
        var variableDeclarationNode = node.parent;
        ctx.addFailureAt(variableDeclarationNode.name.getStart(ctx.sourceFile), variableDeclarationNode.name.getWidth(ctx.sourceFile), Rule.FAILURE_STRING);
    }
}
function isInvalidArrayTypeReference(node, ctx) {
    if (node.typeName.getText(ctx.sourceFile) === "Array") {
        if (ctx.options.ignorePrefix) {
            var variableDeclarationNode = node.parent;
            if (variableDeclarationNode.name.getText(ctx.sourceFile).substr(0, ctx.options.ignorePrefix.length) === ctx.options.ignorePrefix) {
                return false;
            }
        }
        return true;
    }
    return false;
}
function isInvalidArrayLiteralExpression(node, ctx) {
    // If the array literal is used in a variable declaration, the variable
    // must have a type spcecified, otherwise it will implicitly be of mutable Array type
    // It could also be a function parameter that has an array literal as default value
    if (node.parent && (node.parent.kind === ts.SyntaxKind.VariableDeclaration || node.parent.kind === ts.SyntaxKind.Parameter)) {
        var parent_1 = node.parent;
        if (!parent_1.type) {
            if (ctx.options.ignorePrefix &&
                parent_1.name.getText(ctx.sourceFile).substr(0, ctx.options.ignorePrefix.length) === ctx.options.ignorePrefix) {
                return false;
            }
            return true;
        }
    }
    return false;
}
<|endoftext|>


<commit_before>var AppModule   = require('app_module');

module.exports = Route.inherits( AppModule );

function Route( params ) {
  this._init( params );
}

Route.prototype._init = function( params ) {
  this.super_._init( params );

  if ( typeof params.path != 'string' ) throw new Error( 'Route path should be string' );
  if ( !params.router ) throw new Error( 'Link to router is required for Route creation' );

  this.controller       = null;
  this.action           = null;
  this.connection_types = [];
  this._.router         = params.router;

  this._.path           = '';
  this._.path.get       = function(){
    var controller = this.controller || this.app.default_controller;
    // todo: контроллера может не быть
    var action     = this.action     || this.router.get_controller( controller ).default_action;
    return controller + '.' + action;
  }

  var self = this;
  this.rule_params = [];
  this.rule_re     = {};

  this._source_rule = params.rule;
  var re_text = this._source_rule.replace( /<(\w+):(.+?)>/g, function( all, $1, $2 ){
    self.rule_params.push( $1 );
    self.rule_re[ $1 ] = new RegExp( '^' + $2 + '$' );
    return '(' + $2 + ')';
  } );
  this.rule = new RegExp( '^\/' + re_text + '\/?$' );

  // valid : ' controller . action | post ', 'controller.action', 'controller|ws', ' controller', '', '|get'
  // pockets : 2 - controller, 4 - action, 6 - connection_type
  this._re = /^\s*((\w+)\s*(\.\s*(\w+)\s*)?)?(([|,]\s*(post|get|delete|http|ws)\s*)*)$/i;

  this._parse( params.path );
};

Route.prototype._parse = function ( route_path ) {
  var matches = this._re.exec( route_path );
  if ( !matches ) throw new Error( 'Route path `%s` has bad format'.format( route_path ) );

  this.controller       =   matches[2] || null;
  this.action           =   matches[4] || null;
  this.connection_types = ( matches[6] || '' ).split( /[\s|,]+/ ).filter( Boolean );
  if ( ~this.connection_types.indexOf( 'http' ) ) this.connection_types.push( 'post', 'get', 'delete' );
};

Route.prototype.is_allowed_con_type = function ( connection_type ) {
  return !this.connection_types.length || ~this.connection_types.indexOf( connection_type );
};

Route.prototype.has_params = function ( params ) {
  return this.rule_params.every( function( param ) {
    return param in params && this.rule_re[ param ].test( params[ param ] );
  }, this );
};

Route.prototype.get_rule = function ( params ) {
  return this._source_rule.replace( /<(\w+):(.+?)>/g, function( all, $1, $2 ){
    var param = params[ $1 ];
    delete params[ $1 ];
    return param;
  } );
};<commit_msg>user, profile & e.t.<commit_after>var AppModule   = require('app_module');

module.exports = Route.inherits( AppModule );

function Route( params ) {
  this._init( params );
}

Route.prototype._init = function( params ) {
  this.super_._init( params );

  if ( typeof params.path != 'string' ) throw new Error( 'Route path should be string' );
  if ( !params.router ) throw new Error( 'Link to router is required for Route creation' );

  this.controller       = null;
  this.action           = null;
  this.connection_types = [];
  this._.router         = params.router;

  this._.path           = '';
  this._.path.get       = function(){
    var controller = this.controller || this.app.default_controller;
    // todo: контроллера может не быть
    var action     = this.action     || this.router.get_controller( controller ).default_action;
    return controller + '.' + action;
  }

  var self = this;
  this.rule_params = [];
  this.rule_re     = {};

  this._source_rule = params.rule;
  var re_text = this._source_rule.replace( /<(\w+):(.+?)>/g, function( all, $1, $2 ){
    self.rule_params.push( $1 );
    self.rule_re[ $1 ] = new RegExp( '^' + $2 + '$' );
    return '(' + $2 + ')';
  } );
  this.rule = new RegExp( '^\/' + re_text + '\/?$' );

  // valid : ' controller . action | post ', 'controller.action', 'controller|ws', ' controller', '', '|get'
  // pockets : 2 - controller, 4 - action, 6 - connection_type
  this._re = /^\s*((\w+)\s*(\.\s*(\w+)\s*)?)?(([|,]\s*(post|get|delete|http|ws)\s*)*)$/i;

  this._parse( params.path );
};

Route.prototype._parse = function ( route_path ) {
  var matches = this._re.exec( route_path );
  if ( !matches ) throw new Error( 'Route path `%s` has bad format'.format( route_path ) );

  this.controller       =   matches[2] || null;
  this.action           =   matches[4] || null;
  this.connection_types = ( matches[6] || '' ).split( /[\s|,]+/ ).filter( Boolean );
  if ( ~this.connection_types.indexOf( 'http' ) ) this.connection_types.push( 'post', 'get', 'delete' );
};

Route.prototype.is_allowed_con_type = function ( connection_type ) {
  return !this.connection_types.length || ~this.connection_types.indexOf( connection_type );
};

Route.prototype.has_params = function ( params ) {
  params = params || {};

  return this.rule_params.every( function( param ) {
    return param in params && this.rule_re[ param ].test( params[ param ] );
  }, this );
};

Route.prototype.get_rule = function ( params ) {
  return this._source_rule.replace( /<(\w+):(.+?)>/g, function( all, $1, $2 ){
    var param = params[ $1 ];
    delete params[ $1 ];
    return param;
  } );
};<|endoftext|>


<commit_before>export class SrfSearch {

    constructor($inputField, $submitButton, $menu, options = {maxSuggestionCount: 7, minSearchLength: 2}) {
        this.$inputField = $inputField;
        // inputField and submitButton are distinct html elements for accessibility
        this.$submitButton = $submitButton;
        this.$menu = $menu;
        this.$closeIcon = $menu.parent().find('.close-search');
        this.options = options;

        this.typeaheadUrl = this.$inputField.data("typeahead-url");
        this.typeaheadData = null;
        this.suggestionUrl = '';

        // search field is hidden before document.ready (events firing before document.ready can get lost)
        this.$inputField.show();
        this.registerListeners();
    }

    registerListeners() {
        this.$inputField.on("focus", (e) => {
            this.initTypeahead();
        });

        this.$inputField.on("keyup", (e) => {
            this.enhanceAccessibility();
            this.onKeyUp(e);
        });

        this.$inputField.on("keydown", (e) => {
            this.onKeyDown(e);
        });

        this.$inputField.on("blur", (e) => {
            setTimeout(() => {
                this.hideMenu()
            }, 150);
        });

        this.$menu.on("mouseenter", 'li', (e) => {
            this.onMenuMouseenter(e);
        });

        this.$menu.on("touchstart", 'li', (e) => {
            this.onMenuMouseenter(e);
        });
    }

    onKeyUp(e) {
        switch (e.keyCode) {
            case 40: // down arrow
            case 38: // up arrow
                break;
            case 9: // tab
                this.hideMenu();
                break;

            case 27: // escape
                this.hideMenu();
                break;

            default:
                this.lookup();
        }
    }

    onKeyDown(e) {
        // if no suggestion is selected fall back to default browser behavior for form submission
        if (e.keyCode === 13) {
            if (this.suggestionUrl != '') {
                e.stopPropagation();
                e.preventDefault();
                location.href = this.suggestionUrl;
            }
        }
        if (e.keyCode === 40 || e.keyCode === 38) {
            let direction = e.keyCode === 40 ? 'down' : 'up';
            this.moveInMenu(direction);
        }
    }

    onMenuMouseenter(e) {
        // TODO: decide if we have to highlight a menu item if its hovered by mouse
        //this.$menu.find('.active').removeClass('active');
        //$(e.currentTarget).addClass('active');
    }

    hideMenu() {
        return;
        this.$menu.addClass('h-element--hide');
        this.suggestionUrl = '';
        this.hideCloseIcon();
    }

    clearInput() {
        this.$inputField.val("");
        this.$submitButton.attr("tabindex", -1).attr("aria-hidden", true);
        this.suggestionUrl = '';
    }

    moveInMenu(direction) {
        if (direction === 'down') {
            this.nextSuggestion();
        }
        else if (direction === 'up') {
            this.prevSuggestion();
        }
    }

    prevSuggestion() {
        let $active = this.$menu.find('.active').removeClass('active');
        let $prev = $active.prev();
        if ($prev.length === 0) {
            $prev = this.$menu.find('li').last();
        }
        this.suggestionUrl = $prev.find("a").attr('href');
        $prev.addClass('active');
    }

    nextSuggestion() {
        let $active = this.$menu.find('.active').removeClass('active');
        let $next = $active.next();
        if ($next.length === 0) {
            $next = $(this.$menu.find('li').first());
        }
        this.suggestionUrl = $next.find("a").attr('href');
        $next.addClass('active');
    }

    enhanceAccessibility() {
        // a search button only makes sense on desktop - when it's actually working
        if (!(('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0))) {
            // this works mobile as well unlike <enter>-keys an d the likes
            if (this.$inputField.val().length > 2 && this.$submitButton.attr("tabindex") == -1) {
                this.$submitButton.attr("tabindex", 0).attr("aria-hidden", false);
            } else if (this.$inputField.val().length == 0 && this.$submitButton.attr("tabindex") == 0) {
                this.$submitButton.attr("tabindex", -1).attr("aria-hidden", true);
            }
        }
    }

    initTypeahead() {
        if (this.typeaheadData === null) {
            $.getJSON(this.typeaheadUrl, (data) => {
                this.typeaheadData = data;
            })
        }
    }

    lookup() {
        let results = [];
        let query = this.$inputField.val().toString().toLowerCase();
        if (this.typeaheadData === null) {
            return true;
        }
        if(query.length < this.options.minSearchLength) {
            this.hideMenu();
            return true;
        }

        this.typeaheadData.forEach((item) => {
            let matchIndex = item.name.toString().toLowerCase().indexOf(query);
            if (matchIndex >= 0) {
                results.push({name: item.name, url: item.url, matchIndex: matchIndex});
            }
        });
        if (results.length > 0) {
            results = results.slice(0, this.options.maxSuggestionCount);
            this.renderResults(results, query);
            this.showCloseIcon();
        }
        else {
            this.hideMenu();
        }
    }

    renderResults(results, query) {
        let html = '';

        results.forEach((result) => {
            let name = this.highlightQuery(query, result.name);
            html += `<li role="option" class="typeahead-suggestion" tabindex="-1"> <a href="${result.url}">${name}</a> </li>`;
        })
        this.$menu.css('width', this.$inputField.outerWidth() + "px");
        this.$menu.html(html).removeClass('h-element--hide');

    }

    highlightQuery(query, name) {
        query = query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
        return name.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
            return '' + match + ''
        })
    }

    showCloseIcon() {
        let y = this.$inputField.position().top;
        let x = this.$inputField.outerWidth();
        this.$closeIcon.css({'top': y, 'left': x });
        this.$closeIcon.removeClass('h-element--hide');
    }

    hideCloseIcon() {
        this.$closeIcon.addClass('h-element--hide');
    }
}

<commit_msg>do not leave menu open SRFCMS-Footer-SRF-RTR_Typeahead-SRF-RTR_Header-RTR<commit_after>export class SrfSearch {

    constructor($inputField, $submitButton, $menu, options = {maxSuggestionCount: 7, minSearchLength: 2}) {
        this.$inputField = $inputField;
        // inputField and submitButton are distinct html elements for accessibility
        this.$submitButton = $submitButton;
        this.$menu = $menu;
        this.$closeIcon = $menu.parent().find('.close-search');
        this.options = options;

        this.typeaheadUrl = this.$inputField.data("typeahead-url");
        this.typeaheadData = null;
        this.suggestionUrl = '';

        // search field is hidden before document.ready (events firing before document.ready can get lost)
        this.$inputField.show();
        this.registerListeners();
    }

    registerListeners() {
        this.$inputField.on("focus", (e) => {
            this.initTypeahead();
        });

        this.$inputField.on("keyup", (e) => {
            this.enhanceAccessibility();
            this.onKeyUp(e);
        });

        this.$inputField.on("keydown", (e) => {
            this.onKeyDown(e);
        });

        this.$inputField.on("blur", (e) => {
            setTimeout(() => {
                this.hideMenu()
            }, 150);
        });

        this.$menu.on("mouseenter", 'li', (e) => {
            this.onMenuMouseenter(e);
        });

        this.$menu.on("touchstart", 'li', (e) => {
            this.onMenuMouseenter(e);
        });
    }

    onKeyUp(e) {
        switch (e.keyCode) {
            case 40: // down arrow
            case 38: // up arrow
                break;
            case 9: // tab
                this.hideMenu();
                break;

            case 27: // escape
                this.hideMenu();
                break;

            default:
                this.lookup();
        }
    }

    onKeyDown(e) {
        // if no suggestion is selected fall back to default browser behavior for form submission
        if (e.keyCode === 13) {
            if (this.suggestionUrl != '') {
                e.stopPropagation();
                e.preventDefault();
                location.href = this.suggestionUrl;
            }
        }
        if (e.keyCode === 40 || e.keyCode === 38) {
            let direction = e.keyCode === 40 ? 'down' : 'up';
            this.moveInMenu(direction);
        }
    }

    onMenuMouseenter(e) {
        // TODO: decide if we have to highlight a menu item if its hovered by mouse
        //this.$menu.find('.active').removeClass('active');
        //$(e.currentTarget).addClass('active');
    }

    hideMenu() {
        this.$menu.addClass('h-element--hide');
        this.suggestionUrl = '';
        this.hideCloseIcon();
    }

    clearInput() {
        this.$inputField.val("");
        this.$submitButton.attr("tabindex", -1).attr("aria-hidden", true);
        this.suggestionUrl = '';
    }

    moveInMenu(direction) {
        if (direction === 'down') {
            this.nextSuggestion();
        }
        else if (direction === 'up') {
            this.prevSuggestion();
        }
    }

    prevSuggestion() {
        let $active = this.$menu.find('.active').removeClass('active');
        let $prev = $active.prev();
        if ($prev.length === 0) {
            $prev = this.$menu.find('li').last();
        }
        this.suggestionUrl = $prev.find("a").attr('href');
        $prev.addClass('active');
    }

    nextSuggestion() {
        let $active = this.$menu.find('.active').removeClass('active');
        let $next = $active.next();
        if ($next.length === 0) {
            $next = $(this.$menu.find('li').first());
        }
        this.suggestionUrl = $next.find("a").attr('href');
        $next.addClass('active');
    }

    enhanceAccessibility() {
        // a search button only makes sense on desktop - when it's actually working
        if (!(('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0))) {
            // this works mobile as well unlike <enter>-keys an d the likes
            if (this.$inputField.val().length > 2 && this.$submitButton.attr("tabindex") == -1) {
                this.$submitButton.attr("tabindex", 0).attr("aria-hidden", false);
            } else if (this.$inputField.val().length == 0 && this.$submitButton.attr("tabindex") == 0) {
                this.$submitButton.attr("tabindex", -1).attr("aria-hidden", true);
            }
        }
    }

    initTypeahead() {
        if (this.typeaheadData === null) {
            $.getJSON(this.typeaheadUrl, (data) => {
                this.typeaheadData = data;
            })
        }
    }

    lookup() {
        let results = [];
        let query = this.$inputField.val().toString().toLowerCase();
        if (this.typeaheadData === null) {
            return true;
        }
        if(query.length < this.options.minSearchLength) {
            this.hideMenu();
            return true;
        }

        this.typeaheadData.forEach((item) => {
            let matchIndex = item.name.toString().toLowerCase().indexOf(query);
            if (matchIndex >= 0) {
                results.push({name: item.name, url: item.url, matchIndex: matchIndex});
            }
        });
        if (results.length > 0) {
            results = results.slice(0, this.options.maxSuggestionCount);
            this.renderResults(results, query);
            this.showCloseIcon();
        }
        else {
            this.hideMenu();
        }
    }

    renderResults(results, query) {
        let html = '';

        results.forEach((result) => {
            let name = this.highlightQuery(query, result.name);
            html += `<li role="option" class="typeahead-suggestion" tabindex="-1"> <a href="${result.url}">${name}</a> </li>`;
        })
        this.$menu.css('width', this.$inputField.outerWidth() + "px");
        this.$menu.html(html).removeClass('h-element--hide');

    }

    highlightQuery(query, name) {
        query = query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
        return name.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
            return '' + match + ''
        })
    }

    showCloseIcon() {
        let y = this.$inputField.position().top;
        let x = this.$inputField.outerWidth();
        this.$closeIcon.css({'top': y, 'left': x });
        this.$closeIcon.removeClass('h-element--hide');
    }

    hideCloseIcon() {
        this.$closeIcon.addClass('h-element--hide');
    }
}

<|endoftext|>