<commit_before>//----------------------------------------------------------------------------
//  Copyright (C) 2011  The IPython Development Team
//
//  Distributed under the terms of the BSD License.  The full license is in
//  the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------

//============================================================================
// Keyboard management
//============================================================================

var IPython = (function (IPython) {
    "use strict";

    var browser = utils.browser[0];
    var platform = utils.platform;

    // Main keyboard manager for the notebook
    var keycodes = keyboard.keycodes;

    var KeyboardManager = function (options) {
        // Constructor
        //
        // Parameters:
        //  options: dictionary
        //      Dictionary of keyword arguments.
        //          events: $(Events) instance
        //          pager: Pager instance
        this.mode = 'command';
        this.enabled = true;
        this.pager = options.pager;
        this.quick_help = undefined;
        this.notebook = undefined;
        this.bind_events();
        this.command_shortcuts = new keyboard.ShortcutManager(undefined, options.events);
        this.command_shortcuts.add_shortcuts(this.get_default_common_shortcuts());
        this.command_shortcuts.add_shortcuts(this.get_default_command_shortcuts());
        this.edit_shortcuts = new keyboard.ShortcutManager(undefined, options.events);
        this.edit_shortcuts.add_shortcuts(this.get_default_common_shortcuts());
        this.edit_shortcuts.add_shortcuts(this.get_default_edit_shortcuts());
    };

    KeyboardManager.prototype.get_default_common_shortcuts = function() {
        var that = this;
        var shortcuts = {
        'shift' : {
            help    : '',
            help_index : '',
            handler : function (event) {
                // ignore shift keydown
                return true;
            }
        },
        'shift-enter' : {
            help    : 'run cell, select below',
            help_index : 'ba',
            handler : function (event) {
                    that.notebook.execute_cell_and_select_below();
                return false;
            }
        },
        'ctrl-enter' : {
            help    : 'run cell',
            help_index : 'bb',
            handler : function (event) {
                    that.notebook.execute_cell();
                return false;
            }
        },
        'alt-enter' : {
            help    : 'run cell, insert below',
            help_index : 'bc',
            handler : function (event) {
                    that.notebook.execute_cell_and_insert_below();
                return false;
            }
        }
    };

    if (platform === 'MacOS') {
            shortcuts['cmd-s'] =
            {
                help    : 'save notebook',
                help_index : 'fb',
                handler : function (event) {
                        that.notebook.save_checkpoint();
                    event.preventDefault();
                    return false;
                }
            };
    } else {
            shortcuts['ctrl-s'] =
            {
                help    : 'save notebook',
                help_index : 'fb',
                handler : function (event) {
                        that.notebook.save_checkpoint();
                    event.preventDefault();
                    return false;
                }
            };
    }
        return shortcuts;
    };

    KeyboardManager.prototype.get_default_edit_shortcuts = function() {
        var that = this;
        return {
        'esc' : {
            help    : 'command mode',
            help_index : 'aa',
            handler : function (event) {
                    that.notebook.command_mode();
                return false;
            }
        },
        'ctrl-m' : {
            help    : 'command mode',
            help_index : 'ab',
            handler : function (event) {
                    that.notebook.command_mode();
                return false;
            }
        },
        'up' : {
            help    : '',
            help_index : '',
            handler : function (event) {
                    var index = that.notebook.get_selected_index();
                    var cell = that.notebook.get_cell(index);
                if (cell && cell.at_top() && index !== 0) {
                    event.preventDefault();
                        that.notebook.command_mode();
                        that.notebook.select_prev();
                        that.notebook.edit_mode();
                        var cm = that.notebook.get_selected_cell().code_mirror;
                    cm.setCursor(cm.lastLine(), 0);
                    return false;
                } else if (cell) {
                    var cm = cell.code_mirror;
                    cm.execCommand('goLineUp');
                    return false;
                }
            }
        },
        'down' : {
            help    : '',
            help_index : '',
            handler : function (event) {
                    var index = that.notebook.get_selected_index();
                    var cell = that.notebook.get_cell(index);
                    if (cell.at_bottom() && index !== (that.notebook.ncells()-1)) {
                    event.preventDefault();
                        that.notebook.command_mode();
                        that.notebook.select_next();
                        that.notebook.edit_mode();
                        var cm = that.notebook.get_selected_cell().code_mirror;
                    cm.setCursor(0, 0);
                    return false;
                } else {
                    var cm = cell.code_mirror;
                    cm.execCommand('goLineDown');
                    return false;
                }
            }
        },
        'ctrl-shift--' : {
            help    : 'split cell',
            help_index : 'ea',
            handler : function (event) {
                    that.notebook.split_cell();
                return false;
            }
        },
        'ctrl-shift-subtract' : {
            help    : '',
            help_index : 'eb',
            handler : function (event) {
                    that.notebook.split_cell();
                return false;
            }
        },
    };
    };

    KeyboardManager.prototype.get_default_command_shortcuts = function() {
        var that = this;
        return {
        'space': {
            help: "Scroll down to next H1 cell",
            handler: function(event) {
                return that.notebook.scrollmanager.scroll(1);
            },
        },
        'shift-space': {
            help: "Scroll up to previous H1 cell",
            handler: function(event) {
                return that.notebook.scrollmanager.scroll(-1);
            },
        },
        'enter' : {
            help    : 'edit mode',
            help_index : 'aa',
            handler : function (event) {
                    that.notebook.edit_mode();
                return false;
            }
        },
        'up' : {
            help    : 'select previous cell',
            help_index : 'da',
            handler : function (event) {
                    var index = that.notebook.get_selected_index();
                if (index !== 0 && index !== null) {
                        that.notebook.select_prev();
                        that.notebook.focus_cell();
                }
                return false;
            }
        },
        'down' : {
            help    : 'select next cell',
            help_index : 'db',
            handler : function (event) {
                    var index = that.notebook.get_selected_index();
                    if (index !== (that.notebook.ncells()-1) && index !== null) {
                        that.notebook.select_next();
                        that.notebook.focus_cell();
                }
                return false;
            }
        },
        'k' : {
            help    : 'select previous cell',
            help_index : 'dc',
            handler : function (event) {
                    var index = that.notebook.get_selected_index();
                if (index !== 0 && index !== null) {
                        that.notebook.select_prev();
                        that.notebook.focus_cell();
                }
                return false;
            }
        },
        'j' : {
            help    : 'select next cell',
            help_index : 'dd',
            handler : function (event) {
                    var index = that.notebook.get_selected_index();
                    if (index !== (that.notebook.ncells()-1) && index !== null) {
                        that.notebook.select_next();
                        that.notebook.focus_cell();
                }
                return false;
            }
        },
        'x' : {
            help    : 'cut cell',
            help_index : 'ee',
            handler : function (event) {
                    that.notebook.cut_cell();
                return false;
            }
        },
        'c' : {
            help    : 'copy cell',
            help_index : 'ef',
            handler : function (event) {
                    that.notebook.copy_cell();
                return false;
            }
        },
        'shift-v' : {
            help    : 'paste cell above',
            help_index : 'eg',
            handler : function (event) {
                    that.notebook.paste_cell_above();
                return false;
            }
        },
        'v' : {
            help    : 'paste cell below',
            help_index : 'eh',
            handler : function (event) {
                    that.notebook.paste_cell_below();
                return false;
            }
        },
        'd' : {
            help    : 'delete cell (press twice)',
            help_index : 'ej',
            count: 2,
            handler : function (event) {
                    that.notebook.delete_cell();
                return false;
            }
        },
        'a' : {
            help    : 'insert cell above',
            help_index : 'ec',
            handler : function (event) {
                    that.notebook.insert_cell_above();
                    that.notebook.select_prev();
                    that.notebook.focus_cell();
                return false;
            }
        },
        'b' : {
            help    : 'insert cell below',
            help_index : 'ed',
            handler : function (event) {
                    that.notebook.insert_cell_below();
                    that.notebook.select_next();
                    that.notebook.focus_cell();
                return false;
            }
        },
        'y' : {
            help    : 'to code',
            help_index : 'ca',
            handler : function (event) {
                    that.notebook.to_code();
                return false;
            }
        },
        'm' : {
            help    : 'to markdown',
            help_index : 'cb',
            handler : function (event) {
                    that.notebook.to_markdown();
                return false;
            }
        },
        'r' : {
            help    : 'to raw',
            help_index : 'cc',
            handler : function (event) {
                    that.notebook.to_raw();
                return false;
            }
        },
        '1' : {
            help    : 'to heading 1',
            help_index : 'cd',
            handler : function (event) {
                    that.notebook.to_heading(undefined, 1);
                return false;
            }
        },
        '2' : {
            help    : 'to heading 2',
            help_index : 'ce',
            handler : function (event) {
                    that.notebook.to_heading(undefined, 2);
                return false;
            }
        },
        '3' : {
            help    : 'to heading 3',
            help_index : 'cf',
            handler : function (event) {
                    that.notebook.to_heading(undefined, 3);
                return false;
            }
        },
        '4' : {
            help    : 'to heading 4',
            help_index : 'cg',
            handler : function (event) {
                    that.notebook.to_heading(undefined, 4);
                return false;
            }
        },
        '5' : {
            help    : 'to heading 5',
            help_index : 'ch',
            handler : function (event) {
                    that.notebook.to_heading(undefined, 5);
                return false;
            }
        },
        '6' : {
            help    : 'to heading 6',
            help_index : 'ci',
            handler : function (event) {
                    that.notebook.to_heading(undefined, 6);
                return false;
            }
        },
        'o' : {
            help    : 'toggle output',
            help_index : 'gb',
            handler : function (event) {
                    that.notebook.toggle_output();
                return false;
            }
        },
        'shift-o' : {
            help    : 'toggle output scrolling',
            help_index : 'gc',
            handler : function (event) {
                    that.notebook.toggle_output_scroll();
                return false;
            }
        },
        's' : {
            help    : 'save notebook',
            help_index : 'fa',
            handler : function (event) {
                    that.notebook.save_checkpoint();
                return false;
            }
        },
        'ctrl-j' : {
            help    : 'move cell down',
            help_index : 'eb',
            handler : function (event) {
                    that.notebook.move_cell_down();
                return false;
            }
        },
        'ctrl-k' : {
            help    : 'move cell up',
            help_index : 'ea',
            handler : function (event) {
                    that.notebook.move_cell_up();
                return false;
            }
        },
        'l' : {
            help    : 'toggle line numbers',
            help_index : 'ga',
            handler : function (event) {
                    that.notebook.cell_toggle_line_numbers();
                return false;
            }
        },
        'i' : {
            help    : 'interrupt kernel (press twice)',
            help_index : 'ha',
            count: 2,
            handler : function (event) {
                    that.notebook.kernel.interrupt();
                return false;
            }
        },
        '0' : {
            help    : 'restart kernel (press twice)',
            help_index : 'hb',
            count: 2,
            handler : function (event) {
                    that.notebook.restart_kernel();
                return false;
            }
        },
        'h' : {
            help    : 'keyboard shortcuts',
            help_index : 'ge',
            handler : function (event) {
                    that.quick_help.show_keyboard_shortcuts();
                return false;
            }
        },
        'z' : {
            help    : 'undo last delete',
            help_index : 'ei',
            handler : function (event) {
                    that.notebook.undelete_cell();
                return false;
            }
        },
        'shift-m' : {
            help    : 'merge cell below',
            help_index : 'ek',
            handler : function (event) {
                    that.notebook.merge_cell_below();
                return false;
            }
        },
        'q' : {
            help    : 'close pager',
            help_index : 'gd',
            handler : function (event) {
                    that.pager.collapse();
                return false;
            }
        },
    };
    };

    KeyboardManager.prototype.bind_events = function () {
        var that = this;
        $(document).keydown(function (event) {
            return that.handle_keydown(event);
        });
    };

    KeyboardManager.prototype.handle_keydown = function (event) {
        var notebook = this.notebook;

        if (event.which === keycodes.esc) {
            // Intercept escape at highest level to avoid closing
            // websocket connection with firefox
            event.preventDefault();
        }

        if (!this.enabled) {
            if (event.which === keycodes.esc) {
                // ESC
                notebook.command_mode();
                return false;
            }
            return true;
        }

        if (this.mode === 'edit') {
            return this.edit_shortcuts.call_handler(event);
        } else if (this.mode === 'command') {
            return this.command_shortcuts.call_handler(event);
        }
        return true;
    };

    KeyboardManager.prototype.edit_mode = function () {
        this.last_mode = this.mode;
        this.mode = 'edit';
    };

    KeyboardManager.prototype.command_mode = function () {
        this.last_mode = this.mode;
        this.mode = 'command';
    };

    KeyboardManager.prototype.enable = function () {
        this.enabled = true;
    };

    KeyboardManager.prototype.disable = function () {
        this.enabled = false;
    };

    KeyboardManager.prototype.register_events = function (e) {
        var that = this;
        var handle_focus = function () {
            that.disable();
        };
        var handle_blur = function () {
            that.enable();
        };
        e.on('focusin', handle_focus);
        e.on('focusout', handle_blur);
        // TODO: Very strange. The focusout event does not seem fire for the
        // bootstrap textboxes on FF25&26...  This works around that by
        // registering focus and blur events recursively on all inputs within
        // registered element.
        e.find('input').blur(handle_blur);
        e.on('DOMNodeInserted', function (event) {
            var target = $(event.target);
            if (target.is('input')) {
                target.blur(handle_blur);
            } else {
                target.find('input').blur(handle_blur);
            }
          });
        // There are times (raw_input) where we remove the element from the DOM before
        // focusout is called. In this case we bind to the remove event of jQueryUI,
        // which gets triggered upon removal, iff it is focused at the time.
        // is_focused must be used to check for the case where an element within
        // the element being removed is focused.
        e.on('remove', function () {
            if (utils.is_focused(e[0])) {
                that.enable();
            }
        });
    };

    // For backwards compatability.
    IPython.KeyboardManager = KeyboardManager;

    return {'KeyboardManager': KeyboardManager};
});
<commit_msg>Fixed bug<commit_after>// Copyright (c) IPython Development Team.
// Distributed under the terms of the Modified BSD License.

var IPython = (function (IPython) {
    "use strict";

    var browser = utils.browser[0];
    var platform = utils.platform;

    // Main keyboard manager for the notebook
    var keycodes = keyboard.keycodes;

    var KeyboardManager = function (options) {
        // Constructor
        //
        // Parameters:
        //  options: dictionary
        //      Dictionary of keyword arguments.
        //          events: $(Events) instance
        //          pager: Pager instance
        this.mode = 'command';
        this.enabled = true;
        this.pager = options.pager;
        this.quick_help = undefined;
        this.notebook = undefined;
        this.bind_events();
        this.command_shortcuts = new keyboard.ShortcutManager(undefined, options.events);
        this.command_shortcuts.add_shortcuts(this.get_default_common_shortcuts());
        this.command_shortcuts.add_shortcuts(this.get_default_command_shortcuts());
        this.edit_shortcuts = new keyboard.ShortcutManager(undefined, options.events);
        this.edit_shortcuts.add_shortcuts(this.get_default_common_shortcuts());
        this.edit_shortcuts.add_shortcuts(this.get_default_edit_shortcuts());
    };

    KeyboardManager.prototype.get_default_common_shortcuts = function() {
        var that = this;
        var shortcuts = {
        'shift' : {
            help    : '',
            help_index : '',
            handler : function (event) {
                // ignore shift keydown
                return true;
            }
        },
        'shift-enter' : {
            help    : 'run cell, select below',
            help_index : 'ba',
            handler : function (event) {
                    that.notebook.execute_cell_and_select_below();
                return false;
            }
        },
        'ctrl-enter' : {
            help    : 'run cell',
            help_index : 'bb',
            handler : function (event) {
                    that.notebook.execute_cell();
                return false;
            }
        },
        'alt-enter' : {
            help    : 'run cell, insert below',
            help_index : 'bc',
            handler : function (event) {
                    that.notebook.execute_cell_and_insert_below();
                return false;
            }
        }
    };

    if (platform === 'MacOS') {
            shortcuts['cmd-s'] =
            {
                help    : 'save notebook',
                help_index : 'fb',
                handler : function (event) {
                        that.notebook.save_checkpoint();
                    event.preventDefault();
                    return false;
                }
            };
    } else {
            shortcuts['ctrl-s'] =
            {
                help    : 'save notebook',
                help_index : 'fb',
                handler : function (event) {
                        that.notebook.save_checkpoint();
                    event.preventDefault();
                    return false;
                }
            };
    }
        return shortcuts;
    };

    KeyboardManager.prototype.get_default_edit_shortcuts = function() {
        var that = this;
        return {
        'esc' : {
            help    : 'command mode',
            help_index : 'aa',
            handler : function (event) {
                    that.notebook.command_mode();
                return false;
            }
        },
        'ctrl-m' : {
            help    : 'command mode',
            help_index : 'ab',
            handler : function (event) {
                    that.notebook.command_mode();
                return false;
            }
        },
        'up' : {
            help    : '',
            help_index : '',
            handler : function (event) {
                    var index = that.notebook.get_selected_index();
                    var cell = that.notebook.get_cell(index);
                if (cell && cell.at_top() && index !== 0) {
                    event.preventDefault();
                        that.notebook.command_mode();
                        that.notebook.select_prev();
                        that.notebook.edit_mode();
                        var cm = that.notebook.get_selected_cell().code_mirror;
                    cm.setCursor(cm.lastLine(), 0);
                    return false;
                } else if (cell) {
                    var cm = cell.code_mirror;
                    cm.execCommand('goLineUp');
                    return false;
                }
            }
        },
        'down' : {
            help    : '',
            help_index : '',
            handler : function (event) {
                    var index = that.notebook.get_selected_index();
                    var cell = that.notebook.get_cell(index);
                    if (cell.at_bottom() && index !== (that.notebook.ncells()-1)) {
                    event.preventDefault();
                        that.notebook.command_mode();
                        that.notebook.select_next();
                        that.notebook.edit_mode();
                        var cm = that.notebook.get_selected_cell().code_mirror;
                    cm.setCursor(0, 0);
                    return false;
                } else {
                    var cm = cell.code_mirror;
                    cm.execCommand('goLineDown');
                    return false;
                }
            }
        },
        'ctrl-shift--' : {
            help    : 'split cell',
            help_index : 'ea',
            handler : function (event) {
                    that.notebook.split_cell();
                return false;
            }
        },
        'ctrl-shift-subtract' : {
            help    : '',
            help_index : 'eb',
            handler : function (event) {
                    that.notebook.split_cell();
                return false;
            }
        },
    };
    };

    KeyboardManager.prototype.get_default_command_shortcuts = function() {
        var that = this;
        return {
        'space': {
            help: "Scroll down to next H1 cell",
            handler: function(event) {
                return that.notebook.scrollmanager.scroll(1);
            },
        },
        'shift-space': {
            help: "Scroll up to previous H1 cell",
            handler: function(event) {
                return that.notebook.scrollmanager.scroll(-1);
            },
        },
        'enter' : {
            help    : 'edit mode',
            help_index : 'aa',
            handler : function (event) {
                    that.notebook.edit_mode();
                return false;
            }
        },
        'up' : {
            help    : 'select previous cell',
            help_index : 'da',
            handler : function (event) {
                    var index = that.notebook.get_selected_index();
                if (index !== 0 && index !== null) {
                        that.notebook.select_prev();
                        that.notebook.focus_cell();
                }
                return false;
            }
        },
        'down' : {
            help    : 'select next cell',
            help_index : 'db',
            handler : function (event) {
                    var index = that.notebook.get_selected_index();
                    if (index !== (that.notebook.ncells()-1) && index !== null) {
                        that.notebook.select_next();
                        that.notebook.focus_cell();
                }
                return false;
            }
        },
        'k' : {
            help    : 'select previous cell',
            help_index : 'dc',
            handler : function (event) {
                    var index = that.notebook.get_selected_index();
                if (index !== 0 && index !== null) {
                        that.notebook.select_prev();
                        that.notebook.focus_cell();
                }
                return false;
            }
        },
        'j' : {
            help    : 'select next cell',
            help_index : 'dd',
            handler : function (event) {
                    var index = that.notebook.get_selected_index();
                    if (index !== (that.notebook.ncells()-1) && index !== null) {
                        that.notebook.select_next();
                        that.notebook.focus_cell();
                }
                return false;
            }
        },
        'x' : {
            help    : 'cut cell',
            help_index : 'ee',
            handler : function (event) {
                    that.notebook.cut_cell();
                return false;
            }
        },
        'c' : {
            help    : 'copy cell',
            help_index : 'ef',
            handler : function (event) {
                    that.notebook.copy_cell();
                return false;
            }
        },
        'shift-v' : {
            help    : 'paste cell above',
            help_index : 'eg',
            handler : function (event) {
                    that.notebook.paste_cell_above();
                return false;
            }
        },
        'v' : {
            help    : 'paste cell below',
            help_index : 'eh',
            handler : function (event) {
                    that.notebook.paste_cell_below();
                return false;
            }
        },
        'd' : {
            help    : 'delete cell (press twice)',
            help_index : 'ej',
            count: 2,
            handler : function (event) {
                    that.notebook.delete_cell();
                return false;
            }
        },
        'a' : {
            help    : 'insert cell above',
            help_index : 'ec',
            handler : function (event) {
                    that.notebook.insert_cell_above();
                    that.notebook.select_prev();
                    that.notebook.focus_cell();
                return false;
            }
        },
        'b' : {
            help    : 'insert cell below',
            help_index : 'ed',
            handler : function (event) {
                    that.notebook.insert_cell_below();
                    that.notebook.select_next();
                    that.notebook.focus_cell();
                return false;
            }
        },
        'y' : {
            help    : 'to code',
            help_index : 'ca',
            handler : function (event) {
                    that.notebook.to_code();
                return false;
            }
        },
        'm' : {
            help    : 'to markdown',
            help_index : 'cb',
            handler : function (event) {
                    that.notebook.to_markdown();
                return false;
            }
        },
        'r' : {
            help    : 'to raw',
            help_index : 'cc',
            handler : function (event) {
                    that.notebook.to_raw();
                return false;
            }
        },
        '1' : {
            help    : 'to heading 1',
            help_index : 'cd',
            handler : function (event) {
                    that.notebook.to_heading(undefined, 1);
                return false;
            }
        },
        '2' : {
            help    : 'to heading 2',
            help_index : 'ce',
            handler : function (event) {
                    that.notebook.to_heading(undefined, 2);
                return false;
            }
        },
        '3' : {
            help    : 'to heading 3',
            help_index : 'cf',
            handler : function (event) {
                    that.notebook.to_heading(undefined, 3);
                return false;
            }
        },
        '4' : {
            help    : 'to heading 4',
            help_index : 'cg',
            handler : function (event) {
                    that.notebook.to_heading(undefined, 4);
                return false;
            }
        },
        '5' : {
            help    : 'to heading 5',
            help_index : 'ch',
            handler : function (event) {
                    that.notebook.to_heading(undefined, 5);
                return false;
            }
        },
        '6' : {
            help    : 'to heading 6',
            help_index : 'ci',
            handler : function (event) {
                    that.notebook.to_heading(undefined, 6);
                return false;
            }
        },
        'o' : {
            help    : 'toggle output',
            help_index : 'gb',
            handler : function (event) {
                    that.notebook.toggle_output();
                return false;
            }
        },
        'shift-o' : {
            help    : 'toggle output scrolling',
            help_index : 'gc',
            handler : function (event) {
                    that.notebook.toggle_output_scroll();
                return false;
            }
        },
        's' : {
            help    : 'save notebook',
            help_index : 'fa',
            handler : function (event) {
                    that.notebook.save_checkpoint();
                return false;
            }
        },
        'ctrl-j' : {
            help    : 'move cell down',
            help_index : 'eb',
            handler : function (event) {
                    that.notebook.move_cell_down();
                return false;
            }
        },
        'ctrl-k' : {
            help    : 'move cell up',
            help_index : 'ea',
            handler : function (event) {
                    that.notebook.move_cell_up();
                return false;
            }
        },
        'l' : {
            help    : 'toggle line numbers',
            help_index : 'ga',
            handler : function (event) {
                    that.notebook.cell_toggle_line_numbers();
                return false;
            }
        },
        'i' : {
            help    : 'interrupt kernel (press twice)',
            help_index : 'ha',
            count: 2,
            handler : function (event) {
                    that.notebook.kernel.interrupt();
                return false;
            }
        },
        '0' : {
            help    : 'restart kernel (press twice)',
            help_index : 'hb',
            count: 2,
            handler : function (event) {
                    that.notebook.restart_kernel();
                return false;
            }
        },
        'h' : {
            help    : 'keyboard shortcuts',
            help_index : 'ge',
            handler : function (event) {
                    that.quick_help.show_keyboard_shortcuts();
                return false;
            }
        },
        'z' : {
            help    : 'undo last delete',
            help_index : 'ei',
            handler : function (event) {
                    that.notebook.undelete_cell();
                return false;
            }
        },
        'shift-m' : {
            help    : 'merge cell below',
            help_index : 'ek',
            handler : function (event) {
                    that.notebook.merge_cell_below();
                return false;
            }
        },
        'q' : {
            help    : 'close pager',
            help_index : 'gd',
            handler : function (event) {
                    that.pager.collapse();
                return false;
            }
        },
    };
    };

    KeyboardManager.prototype.bind_events = function () {
        var that = this;
        $(document).keydown(function (event) {
            return that.handle_keydown(event);
        });
    };

    KeyboardManager.prototype.handle_keydown = function (event) {
        var notebook = this.notebook;

        if (event.which === keycodes.esc) {
            // Intercept escape at highest level to avoid closing
            // websocket connection with firefox
            event.preventDefault();
        }

        if (!this.enabled) {
            if (event.which === keycodes.esc) {
                // ESC
                notebook.command_mode();
                return false;
            }
            return true;
        }

        if (this.mode === 'edit') {
            return this.edit_shortcuts.call_handler(event);
        } else if (this.mode === 'command') {
            return this.command_shortcuts.call_handler(event);
        }
        return true;
    };

    KeyboardManager.prototype.edit_mode = function () {
        this.last_mode = this.mode;
        this.mode = 'edit';
    };

    KeyboardManager.prototype.command_mode = function () {
        this.last_mode = this.mode;
        this.mode = 'command';
    };

    KeyboardManager.prototype.enable = function () {
        this.enabled = true;
    };

    KeyboardManager.prototype.disable = function () {
        this.enabled = false;
    };

    KeyboardManager.prototype.register_events = function (e) {
        var that = this;
        var handle_focus = function () {
            that.disable();
        };
        var handle_blur = function () {
            that.enable();
        };
        e.on('focusin', handle_focus);
        e.on('focusout', handle_blur);
        // TODO: Very strange. The focusout event does not seem fire for the
        // bootstrap textboxes on FF25&26...  This works around that by
        // registering focus and blur events recursively on all inputs within
        // registered element.
        e.find('input').blur(handle_blur);
        e.on('DOMNodeInserted', function (event) {
            var target = $(event.target);
            if (target.is('input')) {
                target.blur(handle_blur);
            } else {
                target.find('input').blur(handle_blur);
            }
          });
        // There are times (raw_input) where we remove the element from the DOM before
        // focusout is called. In this case we bind to the remove event of jQueryUI,
        // which gets triggered upon removal, iff it is focused at the time.
        // is_focused must be used to check for the case where an element within
        // the element being removed is focused.
        e.on('remove', function () {
            if (utils.is_focused(e[0])) {
                that.enable();
            }
        });
    };

    // For backwards compatability.
    IPython.KeyboardManager = KeyboardManager;

    return {'KeyboardManager': KeyboardManager};
});
<|endoftext|>


<commit_before>const { Monitor, CommandMessage, Stopwatch, util: { regExpEsc, newError } } = require('klasa');

module.exports = class extends Monitor {

	async run(msg) {
		// Ignore other users if selfbot
		if (!this.client.user.bot && msg.author.id !== this.client.user.id) return;
		if (this.client.user.bot && msg.guild && !msg.guild.me) await msg.guild.members.fetch(this.client.user);
		if (msg.guild && !msg.channel.permissionsFor(msg.guild.me).has('SEND_MESSAGES')) return;
		const { command, prefix, prefixLength } = this.parseCommand(msg);
		if (!command) return;
		const validCommand = this.client.commands.get(command);
		if (!validCommand) return;
		const timer = new Stopwatch();
		if (this.client.config.typing) msg.channel.startTyping();
		this.client.inhibitors.run(msg, validCommand)
			.then(() => this.runCommand(this.makeProxy(msg, new CommandMessage(msg, validCommand, prefix, prefixLength)), timer))
			.catch((response) => {
				if (this.client.config.typing) msg.channel.stopTyping();
				this.client.emit('commandInhibited', msg, validCommand, response);
			});
	}

	parseCommand(msg) {
		const prefix = this.getPrefix(msg);
		if (!prefix) return { command: false };
		const prefixLength = prefix.exec(msg.content)[0].length;
		return {
			command: msg.content.slice(prefixLength).trim().split(' ')[0].toLowerCase(),
			prefix,
			prefixLength
		};
	}

	getPrefix(msg) {
		if (this.client.config.prefixMention.test(msg.content)) return this.client.config.prefixMention;
		const prefix = msg.guildSettings.prefix || this.client.config.prefix;
		if (prefix instanceof Array) {
			for (let i = prefix.length - 1; i >= 0; i--) {
				if (msg.content.startsWith(prefix[i])) return new RegExp(`^${regExpEsc(prefix[i])}`);
			}
		} else if (prefix && msg.content.startsWith(prefix)) {
			return new RegExp(`^${regExpEsc(prefix)}`);
		}
		return false;
	}

	makeProxy(msg, cmdMsg) {
		return new Proxy(msg, {
			get: function handler(target, param) {
				return param in msg ? msg[param] : cmdMsg[param];
			}
		});
	}

	runCommand(msg, timer) {
		msg.validateArgs()
			.then(async (params) => {
				await msg.cmd.run(msg, params)
					.then(mes => {
						this.client.emit('commandRun', msg, msg.cmd, params, mes);
						return this.client.finalizers.run(msg, mes, timer);
					})
					.catch(error => this.client.emit('commandError', msg, msg.cmd, msg.params, error));
				if (this.client.config.typing) msg.channel.stopTyping();
			})
			.catch((error) => {
				if (this.client.config.typing) msg.channel.stopTyping();
				if (error.code === 1 && this.client.config.cmdPrompt) {
					return this.awaitMessage(msg, timer, error.message)
						.catch(err => {
							if (err) this.client.emit('commandError', msg, msg.cmd, msg.params, err);
						});
				}
				return this.client.emit('commandError', msg, msg.cmd, msg.params, error);
			});
	}

	async awaitMessage(msg, timer, error) {
		const message = await msg.channel.send(msg.language.get('MONITOR_COMMAND_HANDLER_REPROMPT', `<@!${msg.author.id}>`, error))
			.catch((err) => { throw newError(err); });

		const param = await msg.channel.awaitMessages(response => response.author.id === msg.author.id && response.id !== message.id, { max: 1, time: 30000, errors: ['time'] })
			.catch(() => {
				message.delete();
				throw undefined;
			});

		if (param.first().content.toLowerCase() === 'abort') throw msg.language.get('MONITOR_COMMAND_HANDLER_ABORTED');
		msg.args[msg.args.lastIndexOf(null)] = param.first().content;
		msg.reprompted = true;

		message.delete();
		if (this.client.config.typing) msg.channel.startTyping();
		return this.runCommand(msg, timer);
	}

	init() {
		this.ignoreSelf = this.client.user.bot;
	}

};
<commit_msg>Fix for commands that return a virtual "never". (#76)<commit_after>const { Monitor, CommandMessage, Stopwatch, util: { regExpEsc, newError } } = require('klasa');

module.exports = class extends Monitor {

	async run(msg) {
		// Ignore other users if selfbot
		if (!this.client.user.bot && msg.author.id !== this.client.user.id) return;
		if (this.client.user.bot && msg.guild && !msg.guild.me) await msg.guild.members.fetch(this.client.user);
		if (msg.guild && !msg.channel.permissionsFor(msg.guild.me).has('SEND_MESSAGES')) return;
		const { command, prefix, prefixLength } = this.parseCommand(msg);
		if (!command) return;
		const validCommand = this.client.commands.get(command);
		if (!validCommand) return;
		const timer = new Stopwatch();
		if (this.client.config.typing) msg.channel.startTyping();

		this.client.inhibitors.run(msg, validCommand)
			.then(() => this.runCommand(this.makeProxy(msg, new CommandMessage(msg, validCommand, prefix, prefixLength)), timer))
			.catch((response) => {
				if (this.client.config.typing) msg.channel.stopTyping();
				this.client.emit('commandInhibited', msg, validCommand, response);
			});
	}

	parseCommand(msg) {
		const prefix = this.getPrefix(msg);
		if (!prefix) return { command: false };
		const prefixLength = prefix.exec(msg.content)[0].length;
		return {
			command: msg.content.slice(prefixLength).trim().split(' ')[0].toLowerCase(),
			prefix,
			prefixLength
		};
	}

	getPrefix(msg) {
		if (this.client.config.prefixMention.test(msg.content)) return this.client.config.prefixMention;
		const prefix = msg.guildSettings.prefix || this.client.config.prefix;
		if (prefix instanceof Array) {
			for (let i = prefix.length - 1; i >= 0; i--) {
				if (msg.content.startsWith(prefix[i])) return new RegExp(`^${regExpEsc(prefix[i])}`);
			}
		} else if (prefix && msg.content.startsWith(prefix)) {
			return new RegExp(`^${regExpEsc(prefix)}`);
		}
		return false;
	}

	makeProxy(msg, cmdMsg) {
		return new Proxy(msg, {
			get: function handler(target, param) {
				return param in msg ? msg[param] : cmdMsg[param];
			}
		});
	}

	async runCommand(msg, timer) {
		try {
			await msg.validateArgs();
		} catch (error) {
			if (this.client.config.typing) msg.channel.stopTyping();
			if (error.code === 1 && this.client.config.cmdPrompt) {
				return this.awaitMessage(msg, timer, error.message)
					.catch(err => this.client.emit('commandError', msg, msg.cmd, msg.params, err));
			}
			return this.client.emit('commandError', msg, msg.cmd, msg.params, error);
		}

		const commandRun = msg.cmd.run(msg, msg.params);

		if (this.client.config.typing) msg.channel.stopTyping();
		timer.stop();

		return commandRun
			.then(mes => {
				this.client.finalizers.run(msg, mes, timer);
				this.client.emit('commandRun', msg, msg.cmd, msg.params, mes);
			})
			.catch(error => this.client.emit('commandError', msg, msg.cmd, msg.params, error));
	}

	async awaitMessage(msg, timer, error) {
		const message = await msg.channel.send(msg.language.get('MONITOR_COMMAND_HANDLER_REPROMPT', `<@!${msg.author.id}>`, error))
			.catch((err) => { throw newError(err); });

		const param = await msg.channel.awaitMessages(response => response.author.id === msg.author.id && response.id !== message.id, { max: 1, time: 30000, errors: ['time'] })
			.catch(() => {
				message.delete();
				throw undefined;
			});

		if (param.first().content.toLowerCase() === 'abort') throw msg.language.get('MONITOR_COMMAND_HANDLER_ABORTED');
		msg.args[msg.args.lastIndexOf(null)] = param.first().content;
		msg.reprompted = true;

		message.delete();
		if (this.client.config.typing) msg.channel.startTyping();
		return this.runCommand(msg, timer);
	}

	init() {
		this.ignoreSelf = this.client.user.bot;
	}

};
<|endoftext|>


<commit_before>/**
 * Flat-shaded ocean primitive.
 *
 * Based on a Codrops tutorial:
 * http://tympanus.net/codrops/2016/04/26/the-aviator-animating-basic-3d-scene-threejs/
 */
module.exports.Primitive = {
  defaultComponents: {
    ocean: {},
    rotation: {x: -90, y: 0, z: 0}
  },
  mappings: {
    width: 'ocean.width',
    depth: 'ocean.depth',
    density: 'ocean.density',
    color: 'ocean.color',
    opacity: 'ocean.opacity'
  }
};

module.exports.Component = {
  schema: {
    // Dimensions of the ocean area.
    width: {default: 10, min: 0},
    depth: {default: 10, min: 0},

    // Density of waves.
    density: {default: 10},

    // Wave amplitude and variance.
    amplitude: {default: 0.1},
    amplitudeVariance: {default: 0.3},

    // Wave speed and variance.
    speed: {default: 1},
    speedVariance: {default: 2},

    // Material.
    color: {default: 0x7AD2F7},
    opacity: {default: 0.8}
  },

  /**
   * Use play() instead of init(), because component mappings – unavailable as dependencies – are
   * not guaranteed to have parsed when this component is initialized.
   */
  play: function () {
    var el = this.el,
        data = this.data,
        material = el.components.material;

    var geometry = new THREE.PlaneGeometry(data.width, data.depth, data.density, data.density);
    geometry.mergeVertices();
    this.waves = [];
    for (var v, i = 0, l = geometry.vertices.length; i < l; i++) {
      v = geometry.vertices[i];
      this.waves.push({
        z: v.z,
        ang: Math.random() * Math.PI * 2,
        amp: data.amplitude + Math.random() * data.amplitudeVariance,
        speed: (data.speed + Math.random() * data.speedVariance) / 1000 // radians / frame
      });
    }

    if (!material) {
      material = {};
      material.material = new THREE.MeshPhongMaterial({
        color: data.color,
        transparent: data.opacity < 1,
        opacity: data.opacity,
        shading: THREE.FlatShading,
      });
    }

    this.mesh = new THREE.Mesh(geometry, material.material);
    el.setObject3D('mesh', this.mesh);
  },

  remove: function () {
    this.el.removeObject3D('mesh');
  },

  tick: function (t, dt) {
    if (!dt) return;

    var verts = this.mesh.geometry.vertices;
    for (var v, vprops, i = 0; (v = verts[i]); i++){
      vprops = this.waves[i];
      v.z = vprops.z + Math.sin(vprops.ang) * vprops.amp;
      vprops.ang += vprops.speed * dt;
    }
    this.mesh.geometry.verticesNeedUpdate = true;
  }
};
<commit_msg>Fix color property in 'ocean' component.<commit_after>/**
 * Flat-shaded ocean primitive.
 *
 * Based on a Codrops tutorial:
 * http://tympanus.net/codrops/2016/04/26/the-aviator-animating-basic-3d-scene-threejs/
 */
module.exports.Primitive = {
  defaultComponents: {
    ocean: {},
    rotation: {x: -90, y: 0, z: 0}
  },
  mappings: {
    width: 'ocean.width',
    depth: 'ocean.depth',
    density: 'ocean.density',
    color: 'ocean.color',
    opacity: 'ocean.opacity'
  }
};

module.exports.Component = {
  schema: {
    // Dimensions of the ocean area.
    width: {default: 10, min: 0},
    depth: {default: 10, min: 0},

    // Density of waves.
    density: {default: 10},

    // Wave amplitude and variance.
    amplitude: {default: 0.1},
    amplitudeVariance: {default: 0.3},

    // Wave speed and variance.
    speed: {default: 1},
    speedVariance: {default: 2},

    // Material.
    color: {default: '#7AD2F7', type: 'color'},
    opacity: {default: 0.8}
  },

  /**
   * Use play() instead of init(), because component mappings – unavailable as dependencies – are
   * not guaranteed to have parsed when this component is initialized.
   */
  play: function () {
    var el = this.el,
        data = this.data,
        material = el.components.material;

    var geometry = new THREE.PlaneGeometry(data.width, data.depth, data.density, data.density);
    geometry.mergeVertices();
    this.waves = [];
    for (var v, i = 0, l = geometry.vertices.length; i < l; i++) {
      v = geometry.vertices[i];
      this.waves.push({
        z: v.z,
        ang: Math.random() * Math.PI * 2,
        amp: data.amplitude + Math.random() * data.amplitudeVariance,
        speed: (data.speed + Math.random() * data.speedVariance) / 1000 // radians / frame
      });
    }

    if (!material) {
      material = {};
      material.material = new THREE.MeshPhongMaterial({
        color: data.color,
        transparent: data.opacity < 1,
        opacity: data.opacity,
        shading: THREE.FlatShading,
      });
    }

    this.mesh = new THREE.Mesh(geometry, material.material);
    el.setObject3D('mesh', this.mesh);
  },

  remove: function () {
    this.el.removeObject3D('mesh');
  },

  tick: function (t, dt) {
    if (!dt) return;

    var verts = this.mesh.geometry.vertices;
    for (var v, vprops, i = 0; (v = verts[i]); i++){
      vprops = this.waves[i];
      v.z = vprops.z + Math.sin(vprops.ang) * vprops.amp;
      vprops.ang += vprops.speed * dt;
    }
    this.mesh.geometry.verticesNeedUpdate = true;
  }
};
<|endoftext|>


<commit_before>import { Component, FontAwesomeIcon } from 'substance'

export default class ProjectTab extends Component {

  getInitialState() {
    return {
      edit: false,
      menu: false
    }
  }

  render($$) {
    let el = $$('div').addClass('sc-project-tab')
    let entry = this.props.entry
    let docTypeEl = $$('div').addClass('se-doc-type')
    if (entry.type === 'application/jats4m') {
      docTypeEl.append($$(FontAwesomeIcon, {icon: 'fa-align-left'}))
    } else if (entry.type === 'application/sheetml') {
      docTypeEl.append($$(FontAwesomeIcon, {icon: 'fa-table'}))
    }
    el.append(docTypeEl)

    if (this.state.edit) {
      // Render input for document name editing
      el.addClass('sm-edit sm-active').append(
        $$('input').addClass('se-input').attr({value: entry.name})
          .ref('documentName')
          .on('blur', this._updateDocumentName)
          .on('keydown', this._onKeyDown)
      )
    } else {
      el.append(' '+(entry.name || entry.id))
        .on('click', this._openDocument)
        .on('dblclick', this._editDocumentName)
        .on('contextmenu', this._toggleMenu)

      if (this.props.active) {
        el.addClass('sm-active')
      }

      if (this.state.menu) {
        el.append(
          $$('ul').addClass('se-menu').append(
            $$('li').append('Remove')
              .on('click', this._removeDocument)
          )
        )
      }
    }

    // el.append(
    //   $$('div').addClass('se-toggle-menu').append(
    //     $$(FontAwesomeIcon, {icon: 'fa-caret-up'})
    //   ).on('click', this._toggleMenu.bind(this, entry.id))
    // )

    return el
  }

  _onKeyDown(e) {
    if (e.key === 'Enter') {
      // ATTENTION: It is important to trigger a blur event here, to ensure
      // that there is only one event source for updating the document name.
      this.refs.documentName.el.blur()
    }
  }

  _openDocument() {
    if (!this.props.active) {
      this.send('openDocument', this.props.entry.id)
    }
  }

  _editDocumentName() {
    this.extendState({edit: true})
    this.refs.documentName.el.focus()
  }

  _updateDocumentName() {
    const name = this.refs.documentName.val()
    this.extendState({ edit: false })
    this.send('updateDocumentName', this.props.entry.id, name)
  }

  _removeDocument() {
    this.send('removeDocument', this.props.entry.id)
  }

  _toggleMenu(e) {
    e.preventDefault()
    e.stopPropagation()
    this.extendState({ menu: !this.state.menu })
  }

}
<commit_msg>Handle escape key to cancel document name editing.<commit_after>import { Component, FontAwesomeIcon } from 'substance'

export default class ProjectTab extends Component {

  getInitialState() {
    return {
      edit: false,
      menu: false
    }
  }

  render($$) {
    let el = $$('div').addClass('sc-project-tab')
    let entry = this.props.entry
    let docTypeEl = $$('div').addClass('se-doc-type')
    if (entry.type === 'application/jats4m') {
      docTypeEl.append($$(FontAwesomeIcon, {icon: 'fa-align-left'}))
    } else if (entry.type === 'application/sheetml') {
      docTypeEl.append($$(FontAwesomeIcon, {icon: 'fa-table'}))
    }
    el.append(docTypeEl)

    if (this.state.edit) {
      // Render input for document name editing
      el.addClass('sm-edit sm-active').append(
        $$('input').addClass('se-input').attr({value: entry.name})
          .ref('documentName')
          .on('blur', this._updateDocumentName)
          .on('keydown', this._onKeyDown)
      )
    } else {
      el.append(' '+(entry.name || entry.id))
        .on('click', this._openDocument)
        .on('dblclick', this._editDocumentName)
        .on('contextmenu', this._toggleMenu)

      if (this.props.active) {
        el.addClass('sm-active')
      }

      if (this.state.menu) {
        el.append(
          $$('ul').addClass('se-menu').append(
            $$('li').append('Remove')
              .on('click', this._removeDocument)
          )
        )
      }
    }

    // el.append(
    //   $$('div').addClass('se-toggle-menu').append(
    //     $$(FontAwesomeIcon, {icon: 'fa-caret-up'})
    //   ).on('click', this._toggleMenu.bind(this, entry.id))
    // )

    return el
  }

  _onKeyDown(e) {
    if (e.key === 'Enter' || e.key === 'Escape') {
      if (e.key === 'Escape') {
        this._resetDocumentName()
      }
      // ATTENTION: It is important to trigger a blur event here, to ensure
      // that there is only one event source for updating the document name.
      this.refs.documentName.el.blur()
    }
  }

  /*
    Reset document name to original value
  */
  _resetDocumentName() {
    this.refs.documentName.val(this.props.entry.name)
  }

  _openDocument() {
    if (!this.props.active) {
      this.send('openDocument', this.props.entry.id)
    }
  }

  _editDocumentName() {
    this.extendState({ edit: true })
    this.refs.documentName.el.focus()
  }

  _updateDocumentName() {
    const name = this.refs.documentName.val()
    this.extendState({ edit: false })
    this.send('updateDocumentName', this.props.entry.id, name)
  }

  _removeDocument() {
    this.send('removeDocument', this.props.entry.id)
  }

  _toggleMenu(e) {
    e.preventDefault()
    e.stopPropagation()
    this.extendState({ menu: !this.state.menu })
  }

}
<|endoftext|>


<commit_before>// Based on BluefruitLE by Don Coleman (https://github.com/don/cordova-plugin-ble-central/tree/master/examples/bluefruitle)

/* global mainPage, deviceList, refreshButton, statusText */
/* global detailPage, resultDiv, messageInput, sendButton, disconnectButton */
/* global ble  */
/* jshint browser: true , devel: true*/
'use strict';

// ASCII only
function bytesToString(buffer) {
    return String.fromCharCode.apply(null, new Uint8Array(buffer));
}

// ASCII only
function stringToBytes(string) {
    var array = new Uint8Array(string.length);
    for (var i = 0, l = string.length; i < l; i++) {
        array[i] = string.charCodeAt(i);
    }
    return array.buffer;
}

// this is Nordic's UART service
var bluefruit = {
    serviceUUID: '6e400001-b5a3-f393-e0a9-e50e24dcca9e',
    txCharacteristic: '6e400002-b5a3-f393-e0a9-e50e24dcca9e', // transmit is from the phone's perspective
    rxCharacteristic: '6e400003-b5a3-f393-e0a9-e50e24dcca9e'  // receive is from the phone's perspective
};

var app = {
    initialize: function() {
        this.bindEvents();
        detailPage.hidden = true;
    },
    bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
        refreshButton.addEventListener('touchstart', this.refreshDeviceList, false);
        sendButton.addEventListener('click', this.sendData, false);
        disconnectButton.addEventListener('touchstart', this.disconnect, false);
        deviceList.addEventListener('touchstart', this.connect, false); // assume not scrolling
    },
    onDeviceReady: function() {
        app.showStatusText("Ready");
        app.refreshDeviceList();
    },
    refreshDeviceList: function() {
        app.showStatusText("Starting scan");
        deviceList.innerHTML = ''; // empties the list
        if (cordova.platformId === 'android') { // Android filtering is broken
            ble.scan([], 5, app.onDiscoverDevice, app.onError);
        } else {
            ble.scan([bluefruit.serviceUUID], 5, app.onDiscoverDevice, app.onError);
        }
        console.log('Start scan call end');
    },
    onDiscoverDevice: function(device) {
        var listItem = document.createElement('li'),
            html = '' + device.name + '
' +
                'RSSI: ' + device.rssi + ' | ' +
                device.id;

        listItem.dataset.deviceId = device.id;
        listItem.innerHTML = html;
        deviceList.appendChild(listItem);
    },
    connect: function(e) {
        app.showStatusText('Attemping to connect '+ e.target.dataset.deviceId);
        var deviceId = e.target.dataset.deviceId,
            onConnect = function(peripheral) {
                app.showStatusText('Connected '+ e.target.dataset.deviceId);
                app.determineWriteType(peripheral);

                // subscribe for incoming data
                ble.startNotification(deviceId, bluefruit.serviceUUID, bluefruit.rxCharacteristic, app.onData, app.onError);
                sendButton.dataset.deviceId = deviceId;
                disconnectButton.dataset.deviceId = deviceId;
                resultDiv.innerHTML = "";
                app.showDetailPage();
            };

        ble.connect(deviceId, onConnect, app.onConnectError);
    },
    determineWriteType: function(peripheral) {
        // Adafruit nRF8001 breakout uses WriteWithoutResponse for the TX characteristic
        // Newer Bluefruit devices use Write Request for the TX characteristic

        var characteristic = peripheral.characteristics.filter(function(element) {
            if (element.characteristic.toLowerCase() === bluefruit.txCharacteristic) {
                return element;
            }
        })[0];

        if (characteristic.properties.indexOf('WriteWithoutResponse') > -1) {
            app.writeWithoutResponse = true;
        } else {
            app.writeWithoutResponse = false;
        }

    },
    onData: function(data) { // data received from Arduino
        console.log(data);
        resultDiv.innerHTML = resultDiv.innerHTML + "Received: " + bytesToString(data) + "
";
        resultDiv.scrollTop = resultDiv.scrollHeight;
    },
    sendData: function(event) { // send data to Arduino

        var success = function() {
            console.log("success");
            resultDiv.innerHTML = resultDiv.innerHTML + "Sent: " + messageInput.value + "
";
            resultDiv.scrollTop = resultDiv.scrollHeight;
        };

        var failure = function() {
            alert("Failed writing data to the bluefruit le");
        };

        var data = stringToBytes(messageInput.value);
        var deviceId = event.target.dataset.deviceId;

        if (app.writeWithoutResponse) {
            ble.writeWithoutResponse(
                deviceId,
                bluefruit.serviceUUID,
                bluefruit.txCharacteristic,
                data, success, failure
            );
        } else {
            ble.write(
                deviceId,
                bluefruit.serviceUUID,
                bluefruit.txCharacteristic,
                data, success, failure
            );
        }

    },
    disconnect: function(event) {
        app.showStatusText('Disconnecting '+ event.target.dataset.deviceId);
        var deviceId = event.target.dataset.deviceId;
        ble.disconnect(deviceId, app.showMainPage, app.onError);
        app.showStatusText('Disconnect call ended '+ event.target.dataset.deviceId);
    },
    showMainPage: function() {
        mainPage.hidden = false;
        detailPage.hidden = true;
    },
    showDetailPage: function() {
        mainPage.hidden = true;
        detailPage.hidden = false;
    },
    onConnectError: function(reason) {
        console.log('Error connecting'+ reason);
        alert("ERROR Connecting: " + reason); // real apps should use notification.alert
    },

    onError: function(reason) {
        console.log('Error '+ reason);
        alert("ERROR: " + reason); // real apps should use notification.alert
    },

    showStatusText: function(info) {
        console.log(info);
        document.getElementById("statusText").innerHTML = info;
    }
};
<commit_msg>minor changes for testing connect and disconnect<commit_after>// Based on BluefruitLE by Don Coleman (https://github.com/don/cordova-plugin-ble-central/tree/master/examples/bluefruitle)

/* global mainPage, deviceList, refreshButton, statusText */
/* global detailPage, resultDiv, messageInput, sendButton, disconnectButton */
/* global ble  */
/* jshint browser: true , devel: true*/
'use strict';

// ASCII only
function bytesToString(buffer) {
    return String.fromCharCode.apply(null, new Uint8Array(buffer));
}

// ASCII only
function stringToBytes(string) {
    var array = new Uint8Array(string.length);
    for (var i = 0, l = string.length; i < l; i++) {
        array[i] = string.charCodeAt(i);
    }
    return array.buffer;
}

// this is Nordic's UART service
var bluefruit = {
    serviceUUID: '6e400001-b5a3-f393-e0a9-e50e24dcca9e',
    txCharacteristic: '6e400002-b5a3-f393-e0a9-e50e24dcca9e', // transmit is from the phone's perspective
    rxCharacteristic: '6e400003-b5a3-f393-e0a9-e50e24dcca9e'  // receive is from the phone's perspective
};

var app = {
    initialize: function() {
        this.bindEvents();
        detailPage.hidden = true;
    },
    bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
        refreshButton.addEventListener('touchstart', this.refreshDeviceList, false);
        sendButton.addEventListener('click', this.sendData, false);
        disconnectButton.addEventListener('touchstart', this.disconnect, false);
        deviceList.addEventListener('touchstart', this.connect, false); // assume not scrolling
    },
    onDeviceReady: function() {
        app.showStatusText("Ready");
        app.refreshDeviceList();
    },
    refreshDeviceList: function() {
        app.showStatusText("Starting scan");
        deviceList.innerHTML = ''; // empties the list
        if (cordova.platformId === 'android') { // Android filtering is broken
            ble.scan([], 5, app.onDiscoverDevice, app.onError);
        } else {
            ble.scan([bluefruit.serviceUUID], 5, app.onDiscoverDevice, app.onError);
        }
        console.log('Start scan call end');
    },
    onDiscoverDevice: function(device) {
        var listItem = document.createElement('li'),
            html = '' + device.name + '
' +
                'RSSI: ' + device.rssi + ' | ' +
                device.id;

        listItem.dataset.deviceId = device.id;
        listItem.innerHTML = html;
        deviceList.appendChild(listItem);

        if (device.name == "BADGE") {
            app.showStatusText('Found: '+ device.id);
            app.connectToDevice(device.id);
        }
    },
    connectToDevice: function(deviceId) {
        app.showStatusText('Attemping to connect '+ deviceId);
        var onConnect = function(peripheral) {
                app.showStatusText('Connected '+ deviceId);
                //app.determineWriteType(peripheral);

                // subscribe for incoming data
                //ble.startNotification(deviceId, bluefruit.serviceUUID, bluefruit.rxCharacteristic, app.onData, app.onError);
                //sendButton.dataset.deviceId = deviceId;
                //disconnectButton.dataset.deviceId = deviceId;
                //resultDiv.innerHTML = "";
                //app.showDetailPage();
                //app.disconnectFromDevice(deviceID);
            };

        ble.connect(deviceId, onConnect, app.onConnectError);
    },
    disconnectFromDevice: function(deviceId) {
        app.showStatusText('Disconnecting '+ deviceId);
        ble.disconnect(deviceId, app.onDisconnect, app.onError);
        app.showStatusText('Disconnect call ended '+ deviceId);
    },
    onDisconnect: function(o) {
        console.log('Disconnected '+ o);
        app.showStatusText('Disconnected '+ o);
    },

    connect: function(e) {
        app.showStatusText('Attemping to connect '+ e.target.dataset.deviceId);
        var deviceId = e.target.dataset.deviceId,
            onConnect = function(peripheral) {
                app.showStatusText('Connected '+ e.target.dataset.deviceId);
                app.determineWriteType(peripheral);

                // subscribe for incoming data
                ble.startNotification(deviceId, bluefruit.serviceUUID, bluefruit.rxCharacteristic, app.onData, app.onError);
                sendButton.dataset.deviceId = deviceId;
                disconnectButton.dataset.deviceId = deviceId;
                resultDiv.innerHTML = "";
                app.showDetailPage();
            };

        ble.connect(deviceId, onConnect, app.onConnectError);
    },
    determineWriteType: function(peripheral) {
        // Adafruit nRF8001 breakout uses WriteWithoutResponse for the TX characteristic
        // Newer Bluefruit devices use Write Request for the TX characteristic

        var characteristic = peripheral.characteristics.filter(function(element) {
            if (element.characteristic.toLowerCase() === bluefruit.txCharacteristic) {
                return element;
            }
        })[0];

        if (characteristic.properties.indexOf('WriteWithoutResponse') > -1) {
            app.writeWithoutResponse = true;
        } else {
            app.writeWithoutResponse = false;
        }

    },
    onData: function(data) { // data received from Arduino
        console.log(data);
        resultDiv.innerHTML = resultDiv.innerHTML + "Received: " + bytesToString(data) + "
";
        resultDiv.scrollTop = resultDiv.scrollHeight;
    },
    sendData: function(event) { // send data to Arduino

        var success = function() {
            console.log("success");
            resultDiv.innerHTML = resultDiv.innerHTML + "Sent: " + messageInput.value + "
";
            resultDiv.scrollTop = resultDiv.scrollHeight;
        };

        var failure = function() {
            alert("Failed writing data to the bluefruit le");
        };

        var data = stringToBytes(messageInput.value);
        var deviceId = event.target.dataset.deviceId;

        if (app.writeWithoutResponse) {
            ble.writeWithoutResponse(
                deviceId,
                bluefruit.serviceUUID,
                bluefruit.txCharacteristic,
                data, success, failure
            );
        } else {
            ble.write(
                deviceId,
                bluefruit.serviceUUID,
                bluefruit.txCharacteristic,
                data, success, failure
            );
        }

    },
    disconnect: function(event) {
        app.showStatusText('Disconnecting '+ event.target.dataset.deviceId);
        var deviceId = event.target.dataset.deviceId;
        ble.disconnect(deviceId, app.showMainPage, app.onError);
        app.showStatusText('Disconnect call ended '+ event.target.dataset.deviceId);
    },
    showMainPage: function() {
        mainPage.hidden = false;
        detailPage.hidden = true;
    },
    showDetailPage: function() {
        mainPage.hidden = true;
        detailPage.hidden = false;
    },
    onConnectError: function(reason) {
        console.log('Error connecting'+ reason);
        app.showStatusText('could not connect because'+ reason);
        //alert("ERROR Connecting: " + reason); // real apps should use notification.alert
    },

    onError: function(reason) {
        console.log('Error '+ reason);
        //alert("ERROR: " + reason); // real apps should use notification.alert
    },

    showStatusText: function(info) {
        console.log(info);
        document.getElementById("statusText").innerHTML = info;
    }
};
<|endoftext|>


<commit_before>;(function () {
  /**
   * List
   * @constructor
  */
  function _List () {
    var self = this
    this.vue = new App.Vue({
      el: '.list',
      data: {
        tabs: [
          {
            name: 'Torrents',
            id: 'torrents',
            state: false,
            columns: [
              'name',
              'size',
              'progress',
              'up',
              'down'
            ]
          },
          {
            name: 'Directories',
            id: 'directories',
            state: true,
            columns: [
              'name',
              'size',
              'date',
              'owner'
            ]
          }
        ],
        columns: [
          {
            name: 'Name',
            id: 'name',
            important: true,
            state: true,
            sort: 'asc'
          },
          {
            name: 'Size',
            id: 'size',
            important: true,
            state: true,
            sort: 'asc'
          },
          {
            name: 'Date',
            id: 'date',
            state: true,
            sort: 'asc'
          },
          {
            name: 'Owner',
            id: 'owner',
            state: true,
            sort: 'asc'
          },
          {
            name: 'Progress',
            id: 'progress',
            state: false,
            sort: 'asc'
          },
          {
            name: 'Up',
            id: 'up',
            state: false,
            sort: 'asc'
          },
          {
            name: 'Down',
            id: 'down',
            state: false,
            sort: 'asc'
          }
        ],
        lines: []
      }
    })

    $('.list').on('click', 'th', function () {
      var clickedColumn = $(this)
      var col = self.vue.$data.columns[$.indexOfO(self.vue.$data.columns, function (e) { return e.id === clickedColumn.attr('id') })]
      if (col.sort === 'asc') {
        col.sort = 'desc'
      } else {
        col.sort = 'asc'
      }
      self.sortLines(col.id, col.sort)
    })

    // scrollTop button
    $('.scrollTop').click(function () {
      $('body').animate({
        scrollTop: 0
      }, 1000)
    })
  }

  /**
   * Switch between all tables
   * @param {string} tabId - Id of the table
  */
  _List.prototype.switchTab = function (tabId) {
    $('.list tr').removeClass('selected')
    for (var t in this.vue.$data.tabs) {
      var tab = this.vue.$data.tabs[t]

      if (tab.id === tabId) {
        tab.state = true
        for (var c in this.vue.$data.columns) {
          var column = this.vue.$data.columns[c]

          if (tab.columns.indexOf(column.id) !== -1) {
            column.state = true
          }
        }
      } else {
        tab.state = false
        for (var c in this.vue.$data.columns) {
          var column = this.vue.$data.columns[c]

          if (tab.columns.indexOf(column.id) !== -1 && !column.important) {
            column.state = false
          }
        }
      }
    }
  }

  /**
   * Add lines to table
   * @param {object} line - Line to add
  */
  _List.prototype.addLine = function (line) {
    if ($.indexOfO(this.vue.$data.lines, function (e) { return e.name === line.name }) === -1) {
      this.vue.$data.lines.push(line)
    }
  }

  /**
   * Remove lines to table
   * @param {object} line - Line to remove
  */
  _List.prototype.removeLine = function (line) {
    for (var l in this.vue.$data.lines) {
      if (this.vue.$data.lines[l].name === line.name) {
        this.vue.$data.lines.splice(l, 1)
        return
      }
    }
  }

  /**
   * Clear all lines into the table
  */
  _List.prototype.clearLines = function () {
    this.vue.$data.lines = []
  }

  /**
   * Update all lines into the table
   * And remove absent lines
   * @param {array} lines - Array of lines to update
  */
  _List.prototype.updateLines = function (lines) {
    var self = this

    // updates lines
    $.each(lines, function (index, value) {
      var li = $.indexOfO(self.vue.$data.lines, function (e) { return e.name === value.name })
      if (li !== -1) {
        var line = self.vue.$data.lines[li]
        $.each(value, function (i, v) {
          line[i] = v
        })
      } else {
        self.addLine(value)
      }
    })

    // remove old lines
    var vueLines = self.vue.$data.lines.slice(0)
    for (var key in vueLines) {
      var line = vueLines[key]
      var li = $.indexOfO(lines, function (e) { return e.name === line.name })
      if (li === -1) {
        self.removeLine(line)
      }
    }
  }

  /**
   * Update one lines into the table
   * @param {object} line - The line to update
  */
  _List.prototype.updateLine = function (line) {
    var self = this

    var li = $.indexOfO(self.vue.$data.lines, function (e) { return e.name === line.name })
    if (li !== -1) {
      if (typeof line.newname !== 'undefined') {
        line.name = line.newname
      }
      var l = self.vue.$data.lines[li]
      $.each(line, function (i, v) {
        l[i] = v
      })
    }
  }

  /**
   * Sort the lines in the list
   * @param {string} by - Column to sort by
   * @param {string} direction - Asc, Desc
  */
  _List.prototype.sortLines = function (by, direction) {
    var dir = direction === 'asc' ? -1 : 1
    this.vue.$data.lines.sort(function (a, b) {
      if (a[by] < b[by]) {
        return dir
      } else if (a[by] > b[by]) {
        return -dir
      } else {
        return 0
      }
    })
  }

  _List.prototype.updateDragDrop = function () {
    var self = this
    $('.list .file #name').draggable({
      revert: true
    })

    $('.list .file #name[extension="dir"]').droppable({
      greedy: true,
      drop: function (data, element) {
        App.Loading.show('action')
        var folder = $(this).attr('data-file')
        var file = element.draggable.attr('data-file')
        var path = App.hash + '/'

        $.ajax({
          type: 'post',
          url: '/mv-d',
          timeout: 10000,
          data: {
            'file': file,
            'path': path,
            'folder': folder
          },
          dataType: 'json',
          success: function (file) {
            if (file.err) {
              $.notify.error({
                title: 'Error',
                text: file.err,
                duration: 10
              })
            } else {
              self.removeLine({
                name: file.file
              })
            }
          }
        }).done(function () {
          App.Loading.hide('action')
        }).fail(function (err) {
          App.Loading.hide('action')
          $.notify.error({
            title: 'Error in List.updateDragDrop()',
            text: err.statusText,
            duration: 5
          })
        })
      }
    })
  }
  App.List = new _List()
})()
<commit_msg>fix orderby date<commit_after>;(function () {
  /**
   * List
   * @constructor
  */
  function _List () {
    var self = this
    this.vue = new App.Vue({
      el: '.list',
      data: {
        tabs: [
          {
            name: 'Torrents',
            id: 'torrents',
            state: false,
            columns: [
              'name',
              'size',
              'progress',
              'up',
              'down'
            ]
          },
          {
            name: 'Directories',
            id: 'directories',
            state: true,
            columns: [
              'name',
              'size',
              'date',
              'owner'
            ]
          }
        ],
        columns: [
          {
            name: 'Name',
            id: 'name',
            important: true,
            state: true,
            sort: 'asc'
          },
          {
            name: 'Size',
            id: 'size',
            important: true,
            state: true,
            sort: 'asc'
          },
          {
            name: 'Date',
            id: 'date',
            state: true,
            sort: 'asc'
          },
          {
            name: 'Owner',
            id: 'owner',
            state: true,
            sort: 'asc'
          },
          {
            name: 'Progress',
            id: 'progress',
            state: false,
            sort: 'asc'
          },
          {
            name: 'Up',
            id: 'up',
            state: false,
            sort: 'asc'
          },
          {
            name: 'Down',
            id: 'down',
            state: false,
            sort: 'asc'
          }
        ],
        lines: []
      }
    })

    $('.list').on('click', 'th', function () {
      var clickedColumn = $(this)
      var col = self.vue.$data.columns[$.indexOfO(self.vue.$data.columns, function (e) { return e.id === clickedColumn.attr('id') })]
      if (col.sort === 'asc') {
        col.sort = 'desc'
      } else {
        col.sort = 'asc'
      }
      self.sortLines(col.id, col.sort)
    })

    // scrollTop button
    $('.scrollTop').click(function () {
      $('body').animate({
        scrollTop: 0
      }, 1000)
    })
  }

  /**
   * Switch between all tables
   * @param {string} tabId - Id of the table
  */
  _List.prototype.switchTab = function (tabId) {
    $('.list tr').removeClass('selected')
    for (var t in this.vue.$data.tabs) {
      var tab = this.vue.$data.tabs[t]

      if (tab.id === tabId) {
        tab.state = true
        for (var c in this.vue.$data.columns) {
          var column = this.vue.$data.columns[c]

          if (tab.columns.indexOf(column.id) !== -1) {
            column.state = true
          }
        }
      } else {
        tab.state = false
        for (var c in this.vue.$data.columns) {
          var column = this.vue.$data.columns[c]

          if (tab.columns.indexOf(column.id) !== -1 && !column.important) {
            column.state = false
          }
        }
      }
    }
  }

  /**
   * Add lines to table
   * @param {object} line - Line to add
  */
  _List.prototype.addLine = function (line) {
    if ($.indexOfO(this.vue.$data.lines, function (e) { return e.name === line.name }) === -1) {
      this.vue.$data.lines.push(line)
    }
  }

  /**
   * Remove lines to table
   * @param {object} line - Line to remove
  */
  _List.prototype.removeLine = function (line) {
    for (var l in this.vue.$data.lines) {
      if (this.vue.$data.lines[l].name === line.name) {
        this.vue.$data.lines.splice(l, 1)
        return
      }
    }
  }

  /**
   * Clear all lines into the table
  */
  _List.prototype.clearLines = function () {
    this.vue.$data.lines = []
  }

  /**
   * Update all lines into the table
   * And remove absent lines
   * @param {array} lines - Array of lines to update
  */
  _List.prototype.updateLines = function (lines) {
    var self = this

    // updates lines
    $.each(lines, function (index, value) {
      var li = $.indexOfO(self.vue.$data.lines, function (e) { return e.name === value.name })
      if (li !== -1) {
        var line = self.vue.$data.lines[li]
        $.each(value, function (i, v) {
          line[i] = v
        })
      } else {
        self.addLine(value)
      }
    })

    // remove old lines
    var vueLines = self.vue.$data.lines.slice(0)
    for (var key in vueLines) {
      var line = vueLines[key]
      var li = $.indexOfO(lines, function (e) { return e.name === line.name })
      if (li === -1) {
        self.removeLine(line)
      }
    }
  }

  /**
   * Update one lines into the table
   * @param {object} line - The line to update
  */
  _List.prototype.updateLine = function (line) {
    var self = this

    var li = $.indexOfO(self.vue.$data.lines, function (e) { return e.name === line.name })
    if (li !== -1) {
      if (typeof line.newname !== 'undefined') {
        line.name = line.newname
      }
      var l = self.vue.$data.lines[li]
      $.each(line, function (i, v) {
        l[i] = v
      })
    }
  }

  /**
   * Sort the lines in the list
   * @param {string} by - Column to sort by
   * @param {string} direction - Asc, Desc
  */
  _List.prototype.sortLines = function (by, direction) {
    var dir = direction === 'asc' ? -1 : 1
    switch(by){
      case 'date':
        this.vue.$data.lines.sort(function (a, b) {
          var tamp
          var sa = a[by].split('/')
          tamp = sa[0]
          sa[0] = sa[1]
          sa[1] = tamp
          var sb = b[by].split('/')
          tamp = sb[0]
          sb[0] = sb[1]
          sb[1] = tamp
          return dir * (new Date(sa.join('/')) - new Date(sb.join('/')))
        })
        break
      default:
        this.vue.$data.lines.sort(function (a, b) {
          if (a[by] < b[by]) {
            return dir
          } else if (a[by] > b[by]) {
            return -dir
          } else {
            return 0
          }
        })
        break
    }
  }

  _List.prototype.updateDragDrop = function () {
    var self = this
    $('.list .file #name').draggable({
      revert: true
    })

    $('.list .file #name[extension="dir"]').droppable({
      greedy: true,
      drop: function (data, element) {
        App.Loading.show('action')
        var folder = $(this).attr('data-file')
        var file = element.draggable.attr('data-file')
        var path = App.hash + '/'

        $.ajax({
          type: 'post',
          url: '/mv-d',
          timeout: 10000,
          data: {
            'file': file,
            'path': path,
            'folder': folder
          },
          dataType: 'json',
          success: function (file) {
            if (file.err) {
              $.notify.error({
                title: 'Error',
                text: file.err,
                duration: 10
              })
            } else {
              self.removeLine({
                name: file.file
              })
            }
          }
        }).done(function () {
          App.Loading.hide('action')
        }).fail(function (err) {
          App.Loading.hide('action')
          $.notify.error({
            title: 'Error in List.updateDragDrop()',
            text: err.statusText,
            duration: 5
          })
        })
      }
    })
  }
  App.List = new _List()
})()
<|endoftext|>


<commit_before>/**
 * List
 * @constructor
*/
function _List(){
  this.vue = new App.Vue({
    el: '.list',
    data: {
      tabs: [
        {
          name: 'Torrents',
          id: 'torrents',
          state: false,
          columns: [
            'name',
            'size',
            'progress',
            'up',
            'down'
          ]
        },
        {
          name: 'Directories',
          id: 'directories',
          state: true,
          columns: [
            'name',
            'size',
            'date',
            'owner'
          ]
        }
      ],
      columns: [
        {
          name: 'Name',
          id: 'name',
          important: true,
          state: ''
        },
        {
          name: 'Size',
          id: 'size',
          important: true,
          state: ''
        },
        {
          name: 'Date',
          id: 'date',
          state: ''
        },
        {
          name: 'Owner',
          id: 'owner',
          state: ''
        },
        {
          name: 'Progress',
          id: 'progress',
          state: 'hide'
        },
        {
          name: 'Up',
          id: 'up',
          state: 'hide'
        },
        {
          name: 'Down',
          id: 'down',
          state: 'hide'
        }
      ],
      lines: []
    }
  })
}

/**
 * Switch between all tables
 * @param {string} tabId - Id of the table
*/
_List.prototype.switchTab = function(tabId){
  var self = this
  for(var t in this.vue.$data.tabs){
    var tab = this.vue.$data.tabs[t]

    if(tab.id === tabId){
      tab.state = true
      for(var c in this.vue.$data.columns){
        var column = this.vue.$data.columns[c]

        if(tab.columns.indexOf(column.id) !== -1){
          column.state = ''
        }
      }
    } else {
      tab.state = false
      for(var c in this.vue.$data.columns){
        var column = this.vue.$data.columns[c]

        if(tab.columns.indexOf(column.id) !== -1 && !column.important){
          column.state = 'hide'
        }
      }
    }
  }
}

/**
 * Add lines to table
 * @param {object} line - Line to add
*/
_List.prototype.addLine = function(line){
  this.vue.$data.lines.push(line)
}
/**
 * Remove lines to table
 * @param {object} line - Line to remove
*/
_List.prototype.removeLine = function(line){
  for(var l in this.vue.$data.lines){
    if(this.vue.$data.lines[l].id === line.id){
      this.vue.$data.lines.splice(l, 1)
      return
    }
  }
}
/**
 * Clear all lines into the table
*/
_List.prototype.clearLines = function(){
  this.vue.$data.lines = []
}
App.List = new _List()
<commit_msg>update, remove multiple lines<commit_after>/**
 * List
 * @constructor
*/
function _List(){
  this.vue = new App.Vue({
    el: '.list',
    data: {
      tabs: [
        {
          name: 'Torrents',
          id: 'torrents',
          state: false,
          columns: [
            'name',
            'size',
            'progress',
            'up',
            'down'
          ]
        },
        {
          name: 'Directories',
          id: 'directories',
          state: true,
          columns: [
            'name',
            'size',
            'date',
            'owner'
          ]
        }
      ],
      columns: [
        {
          name: 'Name',
          id: 'name',
          important: true,
          state: ''
        },
        {
          name: 'Size',
          id: 'size',
          important: true,
          state: ''
        },
        {
          name: 'Date',
          id: 'date',
          state: ''
        },
        {
          name: 'Owner',
          id: 'owner',
          state: ''
        },
        {
          name: 'Progress',
          id: 'progress',
          state: 'hide'
        },
        {
          name: 'Up',
          id: 'up',
          state: 'hide'
        },
        {
          name: 'Down',
          id: 'down',
          state: 'hide'
        }
      ],
      lines: []
    }
  })
}

/**
 * Switch between all tables
 * @param {string} tabId - Id of the table
*/
_List.prototype.switchTab = function(tabId){
  var self = this
  for(var t in this.vue.$data.tabs){
    var tab = this.vue.$data.tabs[t]

    if(tab.id === tabId){
      tab.state = true
      for(var c in this.vue.$data.columns){
        var column = this.vue.$data.columns[c]

        if(tab.columns.indexOf(column.id) !== -1){
          column.state = ''
        }
      }
    } else {
      tab.state = false
      for(var c in this.vue.$data.columns){
        var column = this.vue.$data.columns[c]

        if(tab.columns.indexOf(column.id) !== -1 && !column.important){
          column.state = 'hide'
        }
      }
    }
  }
}

/**
 * Add lines to table
 * @param {object} line - Line to add
*/
_List.prototype.addLine = function(line){
  this.vue.$data.lines.push(line)
}

/**
 * Remove lines to table
 * @param {object} line - Line to remove
*/
_List.prototype.removeLine = function(line){
  for(var l in this.vue.$data.lines){
    if(this.vue.$data.lines[l].name === line.name){
      this.vue.$data.lines.splice(l, 1)
      return
    }
  }
}

/**
 * Clear all lines into the table
*/
_List.prototype.clearLines = function(){
  this.vue.$data.lines = []
}

/**
 * Update all lines into the table
 * And remove absent lines
*/
_List.prototype.updateLines = function(lines){
   var self = this
  $.each(lines, function(index, value){

    var li = $.indexOfO(self.vue.$data.lines, function(e){ return e.name === value.name })
    if(li !== -1){
      var line = self.vue.$data.lines[li]
      $.each(value, function(i, v){
        line[i] = v
      })
    } else {
      self.addLine(value)
    }
  })

  var vueLines = self.vue.$data.lines.slice(0)
  for(var key in vueLines){
    console.log(key)
    var line = vueLines[key]
    var li = $.indexOfO(lines, function(e){ return e.name === line.name })
    if(li === -1){
      self.removeLine(line)
    }
  }
}

App.List = new _List()
<|endoftext|>


<commit_before>"use strict";
// Polyfills for commonly used Object functions
SmartPolyfill.register('Object.create', {
  Chrome: '1 - 4',
  Firefox: '1 - 3',
  IE: '1 - 8',
  Safari: '1 - 4'
}, function(o, props){
  function F() {}
  F.prototype = o;
  if (typeof(props) === "object")
    for (var prop in props)
      if (props.hasOwnProperty(prop))
        F[prop] = props[prop];
  return new F();
});
SmartPolyfill.register('Object.keys', {
  Chrome: '1 - 4',
  Firefox: '1 - 3',
  IE: '1 - 8',
  Opera: '1 - 11',
  Safari: '1 - 4'
}, function(o) {
  if (o !== Object(o))
    throw new TypeError('Object.keys called on a non-object');
  var r = [];
  for (r[r.length] in o);
  return r
});<commit_msg>:new: Add Opera to Object.create polyfill<commit_after>"use strict";
// Polyfills for commonly used Object functions
SmartPolyfill.register('Object.create', {
  Chrome: '1 - 4',
  Firefox: '1 - 3',
  IE: '1 - 8',
  Safari: '1 - 4',
  Opera: '1 - 10'
}, function(o, props){
  function F() {}
  F.prototype = o;
  if (typeof(props) === "object")
    for (var prop in props)
      if (props.hasOwnProperty(prop))
        F[prop] = props[prop];
  return new F();
});
SmartPolyfill.register('Object.keys', {
  Chrome: '1 - 4',
  Firefox: '1 - 3',
  IE: '1 - 8',
  Opera: '1 - 11',
  Safari: '1 - 4'
}, function(o) {
  if (o !== Object(o))
    throw new TypeError('Object.keys called on a non-object');
  var r = [];
  for (r[r.length] in o);
  return r
});<|endoftext|>


<commit_before>export default function() {
    return {
        canvasWidth: 800,
        canvasHeight: 700,
        screenWidth: 600,
        screenHeight: 600,
        coredorWidth: 19,
        roomDensity: 2000,
        roomColor: 'https://dl.dropboxusercontent.com/s/jm3h1hvw32l7ur5/floor2.png?dl=1',
        corredorColor: 'https://dl.dropboxusercontent.com/s/jm3h1hvw32l7ur5/floor2.png?dl=1',
        radius: 6,
        initialVel: 1.3,
        trapColor: 'https://photos-1.dropbox.com/t/2/AADRe1gxQV5q4y6ozskZTb1pj8I0JYtT6zIFmkt5rl8Gmw/12/596040564/png/32x32/1/_/1/2/blackHole.png/EKXCgecEGKcBIAIoAg/IjEa4oQGBWNjcf5NHLD3K-os1Cfd0Drbdu7hrDXy67E?size=1600x1200&size_mode=3'
    }
}<commit_msg>First commit again<commit_after>export default function() {
    return {
        canvasWidth: 800,
        canvasHeight: 700,
        screenWidth: 600,
        screenHeight: 600,
        coredorWidth: 19,
        roomDensity: 2000,
        roomColor: 'https://dl.dropboxusercontent.com/s/jm3h1hvw32l7ur5/floor2.png?dl=1',
        corredorColor: 'https://dl.dropboxusercontent.com/s/jm3h1hvw32l7ur5/floor2.png?dl=1',
        radius: 6,
        initialVel: 1.3,
        trapColor: 'https://dl.dropboxusercontent.com/s/opbei51tsw3toe3/blackHole.png?dl=1'
    }
}<|endoftext|>


<commit_before>const fs = require('fs');
const path = require('path');
const babelCompileDirectory = require('babel-d');

const matmanServer = require('./server');

const logger = require('./server/logger');
const matmanLog = logger.matmanLog();

module.exports = (opts) => {
  let configOpts;

  if (typeof opts === 'string' && fs.existsSync(opts)) {
    configOpts = require(opts);
  } else if (typeof opts === 'object') {
    configOpts = opts;
  }

  console.log(configOpts)

  if (!configOpts || !configOpts.ROOT_PATH) {
    console.error('Params error!', opts, configOpts);
    return;
  }

  // 设置默认值
  configOpts.SRC_PATH = configOpts.SRC_PATH || path.join(configOpts.ROOT_PATH, './src');
  configOpts.APP_PATH = configOpts.APP_PATH || path.join(configOpts.ROOT_PATH, './lib');
  configOpts.MOCKER_RELATIVE_PATH = configOpts.MOCKER_RELATIVE_PATH || './mocker';
  configOpts.LOG_PATH = configOpts.LOG_PATH || path.join(configOpts.ROOT_PATH, 'logs');
  configOpts.port = configOpts.port || 3000;

  // 确认 MOCKER_PATH 的值
  if (configOpts.SRC_PATH === configOpts.APP_PATH) {
    // 如果源文件目录和运行目录一致，就不进行babel编译了
    configOpts.MOCKER_PATH = path.join(configOpts.SRC_PATH, configOpts.MOCKER_RELATIVE_PATH);
  } else {
    // babel 编译
    babelCompileDirectory(configOpts.SRC_PATH, configOpts.APP_PATH);
    configOpts.MOCKER_PATH = path.join(configOpts.APP_PATH, configOpts.MOCKER_RELATIVE_PATH);
  }

  const routerMocker = matmanServer.routerMocker(configOpts);
  const server = matmanServer.create();
  const middlewares = matmanServer.mockServer();

  // Set default middlewares (logger, static, cors and no-cache)
  server.use(middlewares);

  // GET /admin，跳转到 /
  server.get('/admin', function (req, res) {
    res.redirect('/');
  });

  // GET /admin/*
  server.get('/admin/*', function (req, res) {
    // res.jsonp({ url2: req.url });
    res.sendFile(path.join(__dirname, '../www/static', 'index.html'));
  });

  server.use(logger.connectLogger(configOpts));

  // To handle POST, PUT and PATCH you need to use a body-parser
  // You can use the one used by JSON Server
  server.use(matmanServer.bodyParser);
  server.use((req, res, next) => {
    if (req.method === 'POST') {
      req.body.createdAt = Date.now()
    }
    // Continue to JSON Server router
    next();
  });

  // Use default router
  server.use(routerMocker);

  server.listen(configOpts.port || 3000, () => {
    console.log('matman server is running');
    matmanLog.info('matman server is running');
  });
};<commit_msg>fix: 修复默认编译的文件夹为 app，且打印配置参数到 log 文件中<commit_after>const fs = require('fs');
const path = require('path');
const babelCompileDirectory = require('babel-d');

const matmanServer = require('./server');

const logger = require('./server/logger');
const matmanLog = logger.matmanLog();

module.exports = (opts) => {
  let configOpts;

  if (typeof opts === 'string' && fs.existsSync(opts)) {
    configOpts = require(opts);
  } else if (typeof opts === 'object') {
    configOpts = opts;
  }

  if (!configOpts || !configOpts.ROOT_PATH) {
    console.error('Params error!', opts, configOpts);
    return;
  }

  // 设置默认值
  configOpts.SRC_PATH = configOpts.SRC_PATH || path.join(configOpts.ROOT_PATH, './src');
  configOpts.APP_PATH = configOpts.APP_PATH || path.join(configOpts.ROOT_PATH, './app');
  configOpts.MOCKER_RELATIVE_PATH = configOpts.MOCKER_RELATIVE_PATH || './mocker';
  configOpts.LOG_PATH = configOpts.LOG_PATH || path.join(configOpts.ROOT_PATH, 'logs');
  configOpts.port = configOpts.port || 3000;

  // 确认 MOCKER_PATH 的值
  if (configOpts.SRC_PATH === configOpts.APP_PATH) {
    // 如果源文件目录和运行目录一致，就不进行babel编译了
    configOpts.MOCKER_PATH = path.join(configOpts.SRC_PATH, configOpts.MOCKER_RELATIVE_PATH);
  } else {
    // babel 编译
    babelCompileDirectory(configOpts.SRC_PATH, configOpts.APP_PATH);
    configOpts.MOCKER_PATH = path.join(configOpts.APP_PATH, configOpts.MOCKER_RELATIVE_PATH);
  }

  matmanLog.info(configOpts);

  const routerMocker = matmanServer.routerMocker(configOpts);
  const server = matmanServer.create();
  const middlewares = matmanServer.mockServer();

  // Set default middlewares (logger, static, cors and no-cache)
  server.use(middlewares);

  // GET /admin，跳转到 /
  server.get('/admin', function (req, res) {
    res.redirect('/');
  });

  // GET /admin/*
  server.get('/admin/*', function (req, res) {
    // res.jsonp({ url2: req.url });
    res.sendFile(path.join(__dirname, '../www/static', 'index.html'));
  });

  server.use(logger.connectLogger(configOpts));

  // To handle POST, PUT and PATCH you need to use a body-parser
  // You can use the one used by JSON Server
  server.use(matmanServer.bodyParser);
  server.use((req, res, next) => {
    if (req.method === 'POST') {
      req.body.createdAt = Date.now()
    }
    // Continue to JSON Server router
    next();
  });

  // Use default router
  server.use(routerMocker);

  server.listen(configOpts.port || 3000, () => {
    console.log('matman server is running');
    matmanLog.info('matman server is running');
  });
};<|endoftext|>