<commit_before>var

sessionStorageSupported = require('webstorage-supported')();
var log = require('./client/log')('plan:store');
var session = require('session');
var store = require('store');

/**
 * Expose `storePlan`
 */

module.exports = storePlan;

/**
 * Store a plan
 */

function storePlan(plan) {
  log('--> storing plan');
  if (!sessionStorageSupported)
    return;

  // convert to "JSON", remove routes & patterns
  var json = {};
  for (var key in plan.attrs) {
    if (key === 'journey' || key === 'options' || key === 'scorer') continue;
    json[key] = plan.attrs[key];
  }

  // if we've created a commuter object, save to the commuter
  var commuter = session.commuter();
  if (commuter) {
    json._commuter = commuter._id();
    commuter.opts(json);
    //commuter.save();
  }

  // save in local storage
  try {
    store('plan', json);
    log('<-- stored plan');
  } catch (e) {
    log.error('<-- failed to store plan %e', e);
  }

  return json;
}

/**
 * Clear storage
 */

module.exports.clear = function() {
  if (sessionStorageSupported)
    store('plan', null);
};
<commit_msg>Solution for merge conflict<commit_after>var
sessionStorageSupported = require('webstorage-supported')();
var log = require('./client/log')('plan:store');
var session = require('session');
var store = require('store');

/**
 * Expose `storePlan`
 */

module.exports = storePlan;

/**
 * Store a plan
 */

function storePlan(plan) {
  log('--> storing plan');
  if (!sessionStorageSupported)
    return;

  // convert to "JSON", remove routes & patterns
  var json = {};
  for (var key in plan.attrs) {
    if (key === 'journey' || key === 'options' || key === 'scorer') continue;
    json[key] = plan.attrs[key];
  }

  // if we've created a commuter object, save to the commuter
  var commuter = session.commuter();
  if (commuter) {
    json._commuter = commuter._id();
    commuter.opts(json);
    //commuter.save();
  }

  // save in local storage
  try {
    store('plan', json);
    log('<-- stored plan');
  } catch (e) {
    log.error('<-- failed to store plan %e', e);
  }

  return json;
}

/**
 * Clear storage
 */

module.exports.clear = function() {
  if (sessionStorageSupported)
    store('plan', null);
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

var optparse = require('optparse');
var operations = require('./operations.js');

/* Define command-line options */

var switches = [
    ['-h', '--help', 'Shows help sections'],
    ['--show-trace', 'Causes Nix to print out a stack trace in case of Nix expression evaluation errors'],
    ['-K', '--keep-failed', 'Specifies that in case of a build failure, the temporary directory should not be deleted'],
    ['-o', '--out-link FILE', 'Change the name of the symlink to the output path created from result to outlink'],
    ['-A', '--attr NAME', 'Selects an instance of the top-level packages object'],
    ['--no-out-link', 'Do not create a symlink to the output path'],
    ['--eval-only', 'Causes the tool to only generate a Nix expression without evaluating it']
];

var parser = new optparse.OptionParser(switches);

/* Set some variables and their default values */

var help = false;
var showTrace = false;
var keepFailed = false;
var outLink = null;
var attr = null;
var noOutLink = false;
var evalOnly = false;
var executable = "";
var filename = null;

/* Define process rules for option parameters */

parser.on('help', function(arg, value) {
    help = true;
});

parser.on('show-trace', function(arg, value) {
    showTrace = true;
});

parser.on('keep-failed', function(arg, value) {
    keepFailed = true;
});

parser.on('out-link', function(arg, value) {
    outLink = value;
});

parser.on('attr', function(arg, value) {
    attr = value;
});

parser.on('no-out-link', function(arg, value) {
    noOutLink = true;
});

parser.on('eval-only', function(arg, value) {
    evalOnly = true;
});

/* Define process rules for non-option parameters */

parser.on(1, function(opt) {
    executable = opt;
});

parser.on(2, function(opt) {
    filename = opt;
});

/* Do the actual command-line parsing */

parser.parse(process.argv);

/* Display the help, if it has been requested */

if(help) {
    function displayTab(len, maxlen) {
        for(var i = 0; i < maxlen - len; i++) {
            process.stdout.write(" ");
        }
    }

    process.stdout.write("Usage:\n\n");
    process.stdout.write(executable + " [options] -A package pkgs.js\n\n");
    process.stdout.write("Options:\n\n");

    var maxlen = 20;

    for(var i = 0; i < switches.length; i++) {

        var currentSwitch = switches[i];

        if(currentSwitch.length == 3) {
            process.stdout.write(currentSwitch[0] + ", "+currentSwitch[1]);
            displayTab(currentSwitch[0].length + 2 + currentSwitch[1].length, maxlen);
            process.stdout.write(currentSwitch[2]);
        } else {
            process.stdout.write(currentSwitch[0]);
            displayTab(currentSwitch[0].length, maxlen);
            process.stdout.write(currentSwitch[1]);
        }

        process.stdout.write("\n");
    }

    process.exit(0);
}

/* Verify the input parameters */

if(filename === null) {
    process.stderr.write("No packages JavaScript module is specified!\n");
    process.exit(1);
}

if(attr === null) {
    process.stderr.write("No package has been selected!\n");
    process.exit(1);
}

/* Perform the desired operation */

if(evalOnly) {
    operations.evaluateModule({
        filename : filename,
        attr : attr
    });
} else {
    operations.nixBuild({
        filename : filename,
        attr : attr,
        showTrace : showTrace,
        keepFailed : keepFailed,
        outLink : outLink,
        noOutLink : noOutLink
    });
}
<commit_msg>Fixed typo<commit_after>#!/usr/bin/env node

var optparse = require('optparse');
var operations = require('./operations.js');

/* Define command-line options */

var switches = [
    ['-h', '--help', 'Shows help sections'],
    ['--show-trace', 'Causes Nix to print out a stack trace in case of Nix expression evaluation errors'],
    ['-K', '--keep-failed', 'Specifies that in case of a build failure, the temporary directory should not be deleted'],
    ['-o', '--out-link FILE', 'Change the name of the symlink to the output path created from result to outlink'],
    ['-A', '--attr NAME', 'Selects an instance of the top-level packages object'],
    ['--no-out-link', 'Do not create a symlink to the output path'],
    ['--eval-only', 'Causes the tool to only generate a Nix expression without evaluating it']
];

var parser = new optparse.OptionParser(switches);

/* Set some variables and their default values */

var help = false;
var showTrace = false;
var keepFailed = false;
var outLink = null;
var attr = null;
var noOutLink = false;
var evalOnly = false;
var executable = "";
var filename = null;

/* Define process rules for option parameters */

parser.on('help', function(arg, value) {
    help = true;
});

parser.on('show-trace', function(arg, value) {
    showTrace = true;
});

parser.on('keep-failed', function(arg, value) {
    keepFailed = true;
});

parser.on('out-link', function(arg, value) {
    outLink = value;
});

parser.on('attr', function(arg, value) {
    attr = value;
});

parser.on('no-out-link', function(arg, value) {
    noOutLink = true;
});

parser.on('eval-only', function(arg, value) {
    evalOnly = true;
});

/* Define process rules for non-option parameters */

parser.on(1, function(opt) {
    executable = opt;
});

parser.on(2, function(opt) {
    filename = opt;
});

/* Do the actual command-line parsing */

parser.parse(process.argv);

/* Display the help, if it has been requested */

if(help) {
    function displayTab(len, maxlen) {
        for(var i = 0; i < maxlen - len; i++) {
            process.stdout.write(" ");
        }
    }

    process.stdout.write("Usage:\n\n");
    process.stdout.write(executable + " [options] -A package pkgs.js\n\n");
    process.stdout.write("Options:\n\n");

    var maxlen = 20;

    for(var i = 0; i < switches.length; i++) {

        var currentSwitch = switches[i];

        if(currentSwitch.length == 3) {
            process.stdout.write(currentSwitch[0] + ", "+currentSwitch[1]);
            displayTab(currentSwitch[0].length + 2 + currentSwitch[1].length, maxlen);
            process.stdout.write(currentSwitch[2]);
        } else {
            process.stdout.write(currentSwitch[0]);
            displayTab(currentSwitch[0].length, maxlen);
            process.stdout.write(currentSwitch[1]);
        }

        process.stdout.write("\n");
    }

    process.exit(0);
}

/* Verify the input parameters */

if(filename === null) {
    process.stderr.write("No packages CommonJS module is specified!\n");
    process.exit(1);
}

if(attr === null) {
    process.stderr.write("No package has been selected!\n");
    process.exit(1);
}

/* Perform the desired operation */

if(evalOnly) {
    operations.evaluateModule({
        filename : filename,
        attr : attr
    });
} else {
    operations.nixBuild({
        filename : filename,
        attr : attr,
        showTrace : showTrace,
        keepFailed : keepFailed,
        outLink : outLink,
        noOutLink : noOutLink
    });
}
<|endoftext|>


<commit_before>/**
 * Created by joel on 8/20/16.
 */

import {send} from './connect';
import {editor, editor_element} from './editor';
import {state, defaults} from './utils';
import CodeMirror from 'codemirror';
const mac = CodeMirror.keyMap["default"] == CodeMirror.keyMap.macDefault;
const ctrl = mac ? "Cmd-" : "Ctrl-";

const print_open = "#|";
const print_close = "|#";

const icon_elements = [];
const icon_collection = document.getElementsByClassName('icon');
for (let i = 0; icon_collection[i]; i++) icon_elements.push(icon_collection[i]);
const icons = {
    settings: {
        'monokai': document.getElementById('icon-settings-white'),
        'default': document.getElementById('icon-settings-black')
    },
    close: {
        'monokai': document.getElementById('icon-close-white'),
        'default': document.getElementById('icon-close-black')
    }
};
const hint = document.getElementById('hint');
const labels = [
    {
        element: document.getElementById('eval-expression'),
        emacs: 'Ctrl-X Ctrl-E',
        sublime: ctrl + 'Enter'
    },
    {
        element: document.getElementById('eval-document'),
        emacs: 'Ctrl-X Ctrl-A',
        sublime: ctrl + 'Shift-Enter'
    },
    {
        element: document.getElementById('view'),
        emacs: 'Tab',
        sublime: 'Tab'
    },
    {
        element: document.getElementById('autocomplete'),
        emacs: 'Meta-/',
        sublime: 'Alt-/'
    },
    {
        element: document.getElementById('open'),
        emacs: 'Ctrl-X F',
        sublime: ctrl + 'O'
    },
    {
        element: document.getElementById('save'),
        emacs: 'Ctrl-X S',
        sublime: ctrl + 'S'
    },
    {
        element: document.getElementById('interrupt'),
        emacs: 'Ctrl-C',
        sublime: ctrl + 'B'
    },
    {
        element: document.getElementById('help'),
        emacs: 'Meta-H',
        sublime: ctrl + 'Shift-H'
    }
];

labels.forEach(({element}) => element.parentNode.onclick = e => editor.execCommand(element.id));

function set_theme(theme) {
    state.theme = theme;
    icon_elements.forEach(element => element.style.visibility = 'hidden');
    icons[state.visibility][theme].style.visibility = 'visible';
    editor.setOption('theme', theme);
}

function set_visibility(visibility) {
    state.visibility = visibility;
    if (visibility === 'settings') {
        hint.style.display = 'none';
        editor_element.style.right = 0;
    }
    else if (visibility === 'close') {
        hint.style.display = 'block';
        editor_element.style.right = 320;
    }
    icon_elements.forEach(element => element.style.visibility = 'hidden');
    icons[visibility][state.theme].style.visibility = 'visible';
}

function help() {
    const visibility = (state.visibility === 'close' ? 'settings' : 'close');
    set_visibility(visibility);
    editor.focus();
}

function set_keyMap(keyMap) {
    labels.forEach(label => label.element.textContent = label[keyMap]);
    editor.setOption('keyMap', keyMap);
}

document.getElementById('icons').onclick = help;
document.getElementById('keyMap-emacs').onclick = e => set_keyMap('emacs');
document.getElementById('keyMap-sublime').onclick = e => set_keyMap('sublime');
document.getElementById('theme-light').onclick = e => set_theme('default');
document.getElementById('theme-dark').onclick = e => set_theme('monokai');
set_visibility(defaults.visibility);
set_keyMap(defaults.keyMap);
set_theme(defaults.theme);

editor.focus();

const filename = document.getElementById('filename');
const login = document.getElementById('login');
function set_filename(changed) {
    const {user, file} = state;
    if (user) {
        login.href = '/logout';
        login.textContent = 'Logout';
    } else {
        login.href = '/login';
        login.textContent = 'Login';
    }
    const title = (user || 'Lambda') + (file ? ': ' + file : '') + (changed ? ' ∙' : '');
    filename.textContent = title;
    document.title = title;
    history.replaceState({}, title, location.host + (user ? '/users/' + user : '') + (file ? '/files/' + file : ''));
}

set_filename();

let clean = true;
let dialog = false;

const dialogText = 'Unsaved changes will be lost!';
window.onbeforeunload = function(e) {
    if (clean || !state.file) return null;
    e.returnValue = dialogText;
    return dialogText;
};

editor.on('change', function(cm, change) {
    if (state.file && !cm.isClean() && clean) {
        set_filename(true);
        clean = false;
    }
});

function move(file) {
    editor.clearHistory();
    // const path = location.pathname.split('/');
    // if (path && path.pop() && path.pop() === 'files') history.pushState({}, file, file);
    // else history.pushState({}, file, 'files/' + file);
    // history.replaceState({}, file, file);
    state.file = file;
    send('load', {file});
    if (dialog) dialog();
    dialog = false;
}

function make(file) {
    const button = document.createElement('button');
    button.textContent = file;
    button.addEventListener('click', e => move(file));
    open_files.appendChild(button);
}

function open(files) {
    open_files.innerHTML = '';
    files.forEach(make);
    if (files.length === 0) open_files.textContent = 'No files found';
    input.focus();
}

function load(data) {
    editor.setValue(data || '');
    editor.markClean();
    set_filename();
    clean = true;
    editor.focus();
}

const save_notification = document.createElement('span');
function save(data) {
    if (data) save_notification.textContent = 'Saved successfully';
    else save_notification.textContent = 'Save failed';
    editor.openNotification(save_notification, {duration: 3000});
}
const open_dialog = document.createElement('div');
open_dialog.className = 'prompt';
const open_prompt = document.createElement('div');
const open_label = document.createElement('span');
const open_files = document.createElement('span');
open_label.textContent = 'Open file: ';
open_prompt.appendChild(open_label);
open_prompt.appendChild(open_files);

const new_prompt = document.createElement('div');
const new_label = document.createElement('span');
const input = document.createElement('input');
new_label.textContent = 'New file: ';
input.type = 'text';
input.placeholder = 'Enter filename';
input.addEventListener('keydown', e => e.keyCode === 13 && move(input.value));
new_prompt.appendChild(new_label);
new_prompt.appendChild(input);

open_dialog.appendChild(new_prompt);
open_dialog.appendChild(open_prompt);
function cm_open(cm) {
    if (dialog) dialog();
    send('open', true);
    dialog = cm.openNotification(open_dialog, {duration: 0});
}

const save_prompt = document.createElement('span');
save_prompt.textContent = 'Save file: /files/';
const save_input = document.createElement('input');
save_input.type = 'text';
save_prompt.appendChild(save_input);

const test = text =>
    (text.substring(0, print_open.length) !== print_open ||
    (text.substring(text.length - print_close.length, text.length) !== print_close));

function send_save() {
    if (save_input.value) {
        const name = save_input.value;
        const text = editor.getValue();
        state.file = name;
        set_filename(name);
        clean = true;
        editor.markClean();
        send('save', {name, text});
    }
}

function onInput(event, value) {
    save_input.value = value.split('/').join('');
}

function cm_save(cm) {
    if (!cm.isClean()) {
        if (state.file) save_input.value = state.file;
        cm.openDialog(save_prompt, send_save, {onInput});
    }
}

document.addEventListener('keydown', function(e) {
    if (e.keyCode === 27) {
        if (dialog) {
            dialog();
            dialog = false;
        } else if (state.error) {
            editor.execCommand('interrupt');
        }
    } else if (e.keyCode === 9) {
        if (state.error) {
            const {length, inputs, index} = state.error;
            const i = (index + length + (e.shiftKey ? -1 : 1)) % length;
            inputs[i].input.focus();
            inputs[state.error.index].row.classList.remove('focus');
            inputs[i].row.classList.add('focus');
            state.error.index = i;
            e.preventDefault();
        }
    }
});
export {cm_open, cm_save, open, save, load, help, set_visibility, test}
<commit_msg>ok this is ridiculous<commit_after>/**
 * Created by joel on 8/20/16.
 */

import {send} from './connect';
import {editor, editor_element} from './editor';
import {state, defaults} from './utils';
import CodeMirror from 'codemirror';
const mac = CodeMirror.keyMap["default"] == CodeMirror.keyMap.macDefault;
const ctrl = mac ? "Cmd-" : "Ctrl-";

const print_open = "#|";
const print_close = "|#";

const icon_elements = [];
const icon_collection = document.getElementsByClassName('icon');
for (let i = 0; icon_collection[i]; i++) icon_elements.push(icon_collection[i]);
const icons = {
    settings: {
        'monokai': document.getElementById('icon-settings-white'),
        'default': document.getElementById('icon-settings-black')
    },
    close: {
        'monokai': document.getElementById('icon-close-white'),
        'default': document.getElementById('icon-close-black')
    }
};
const hint = document.getElementById('hint');
const labels = [
    {
        element: document.getElementById('eval-expression'),
        emacs: 'Ctrl-X Ctrl-E',
        sublime: ctrl + 'Enter'
    },
    {
        element: document.getElementById('eval-document'),
        emacs: 'Ctrl-X Ctrl-A',
        sublime: ctrl + 'Shift-Enter'
    },
    {
        element: document.getElementById('view'),
        emacs: 'Tab',
        sublime: 'Tab'
    },
    {
        element: document.getElementById('autocomplete'),
        emacs: 'Meta-/',
        sublime: 'Alt-/'
    },
    {
        element: document.getElementById('open'),
        emacs: 'Ctrl-X F',
        sublime: ctrl + 'O'
    },
    {
        element: document.getElementById('save'),
        emacs: 'Ctrl-X S',
        sublime: ctrl + 'S'
    },
    {
        element: document.getElementById('interrupt'),
        emacs: 'Ctrl-C',
        sublime: ctrl + 'B'
    },
    {
        element: document.getElementById('help'),
        emacs: 'Meta-H',
        sublime: ctrl + 'Shift-H'
    }
];

labels.forEach(({element}) => element.parentNode.onclick = e => editor.execCommand(element.id));

function set_theme(theme) {
    state.theme = theme;
    icon_elements.forEach(element => element.style.visibility = 'hidden');
    icons[state.visibility][theme].style.visibility = 'visible';
    editor.setOption('theme', theme);
}

function set_visibility(visibility) {
    state.visibility = visibility;
    if (visibility === 'settings') {
        hint.style.display = 'none';
        editor_element.style.right = 0;
    }
    else if (visibility === 'close') {
        hint.style.display = 'block';
        editor_element.style.right = 320;
    }
    icon_elements.forEach(element => element.style.visibility = 'hidden');
    icons[visibility][state.theme].style.visibility = 'visible';
}

function help() {
    const visibility = (state.visibility === 'close' ? 'settings' : 'close');
    set_visibility(visibility);
    editor.focus();
}

function set_keyMap(keyMap) {
    labels.forEach(label => label.element.textContent = label[keyMap]);
    editor.setOption('keyMap', keyMap);
}

document.getElementById('icons').onclick = help;
document.getElementById('keyMap-emacs').onclick = e => set_keyMap('emacs');
document.getElementById('keyMap-sublime').onclick = e => set_keyMap('sublime');
document.getElementById('theme-light').onclick = e => set_theme('default');
document.getElementById('theme-dark').onclick = e => set_theme('monokai');
set_visibility(defaults.visibility);
set_keyMap(defaults.keyMap);
set_theme(defaults.theme);

editor.focus();

const filename = document.getElementById('filename');
const login = document.getElementById('login');
function set_filename(changed) {
    const {user, file} = state;
    if (user) {
        login.href = '/logout';
        login.textContent = 'Logout';
    } else {
        login.href = '/login';
        login.textContent = 'Login';
    }
    const title = (user || 'Lambda') + (file ? ': ' + file : '') + (changed ? ' ∙' : '');
    filename.textContent = title;
    document.title = title;
    history.replaceState({}, title, (user ? '/users/' + user : '') + (file ? '/files/' + file : ''));
}

set_filename();

let clean = true;
let dialog = false;

const dialogText = 'Unsaved changes will be lost!';
window.onbeforeunload = function(e) {
    if (clean || !state.file) return null;
    e.returnValue = dialogText;
    return dialogText;
};

editor.on('change', function(cm, change) {
    if (state.file && !cm.isClean() && clean) {
        set_filename(true);
        clean = false;
    }
});

function move(file) {
    editor.clearHistory();
    // const path = location.pathname.split('/');
    // if (path && path.pop() && path.pop() === 'files') history.pushState({}, file, file);
    // else history.pushState({}, file, 'files/' + file);
    // history.replaceState({}, file, file);
    state.file = file;
    send('load', {file});
    if (dialog) dialog();
    dialog = false;
}

function make(file) {
    const button = document.createElement('button');
    button.textContent = file;
    button.addEventListener('click', e => move(file));
    open_files.appendChild(button);
}

function open(files) {
    open_files.innerHTML = '';
    files.forEach(make);
    if (files.length === 0) open_files.textContent = 'No files found';
    input.focus();
}

function load(data) {
    editor.setValue(data || '');
    editor.markClean();
    set_filename();
    clean = true;
    editor.focus();
}

const save_notification = document.createElement('span');
function save(data) {
    if (data) save_notification.textContent = 'Saved successfully';
    else save_notification.textContent = 'Save failed';
    editor.openNotification(save_notification, {duration: 3000});
}
const open_dialog = document.createElement('div');
open_dialog.className = 'prompt';
const open_prompt = document.createElement('div');
const open_label = document.createElement('span');
const open_files = document.createElement('span');
open_label.textContent = 'Open file: ';
open_prompt.appendChild(open_label);
open_prompt.appendChild(open_files);

const new_prompt = document.createElement('div');
const new_label = document.createElement('span');
const input = document.createElement('input');
new_label.textContent = 'New file: ';
input.type = 'text';
input.placeholder = 'Enter filename';
input.addEventListener('keydown', e => e.keyCode === 13 && move(input.value));
new_prompt.appendChild(new_label);
new_prompt.appendChild(input);

open_dialog.appendChild(new_prompt);
open_dialog.appendChild(open_prompt);
function cm_open(cm) {
    if (dialog) dialog();
    send('open', true);
    dialog = cm.openNotification(open_dialog, {duration: 0});
}

const save_prompt = document.createElement('span');
save_prompt.textContent = 'Save file: /files/';
const save_input = document.createElement('input');
save_input.type = 'text';
save_prompt.appendChild(save_input);

const test = text =>
    (text.substring(0, print_open.length) !== print_open ||
    (text.substring(text.length - print_close.length, text.length) !== print_close));

function send_save() {
    if (save_input.value) {
        const name = save_input.value;
        const text = editor.getValue();
        state.file = name;
        set_filename(name);
        clean = true;
        editor.markClean();
        send('save', {name, text});
    }
}

function onInput(event, value) {
    save_input.value = value.split('/').join('');
}

function cm_save(cm) {
    if (!cm.isClean()) {
        if (state.file) save_input.value = state.file;
        cm.openDialog(save_prompt, send_save, {onInput});
    }
}

document.addEventListener('keydown', function(e) {
    if (e.keyCode === 27) {
        if (dialog) {
            dialog();
            dialog = false;
        } else if (state.error) {
            editor.execCommand('interrupt');
        }
    } else if (e.keyCode === 9) {
        if (state.error) {
            const {length, inputs, index} = state.error;
            const i = (index + length + (e.shiftKey ? -1 : 1)) % length;
            inputs[i].input.focus();
            inputs[state.error.index].row.classList.remove('focus');
            inputs[i].row.classList.add('focus');
            state.error.index = i;
            e.preventDefault();
        }
    }
});
export {cm_open, cm_save, open, save, load, help, set_visibility, test}
<|endoftext|>


<commit_before>/*    Copyright 2016 Firewalla LLC
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
'use strict';
let log = require("../net2/logger.js")(__filename);

let Firewalla = require('../net2/Firewalla.js');

let Promise = require('bluebird');
let cp = require('child_process');

const cpp = require('child-process-promise');
const fs = require("fs");
const platform = require('../platform/PlatformLoader.js').getPlatform();

let instance = null;
class DeviceMgmtTool {
  constructor() {
    if (!instance) {
      instance = this;
    }
    return instance;
  }

  _getOverlayUpperDirectory() {
    return Firewalla.getOverlayUpperDirPartition() + "/overlay";
  }

  _getOverlayUpperWorkDirectory() {
    return Firewalla.getOverlayUpperDirPartition() + "/overlay-workdir";
  }

  async deleteGroup(eptcloud, gid) {
    log.info("Delete group " + gid);
    await eptcloud.deleteGroup(gid)
    log.info("Group " + gid + " is deleted.");
  }

  async resetGold() {
    log.info("Resetting Gold...")
    try {
      await cpp.exec("sudo pkill -x -SIGUSR1 firereset");
      await cpp.exec("sudo pkill -x -SIGUSR1 firereset");
      await cpp.exec("sudo pkill -x -SIGUSR1 firereset");
    } catch(err) {
      log.error("Got error when resetting gold, err:", err);
    }
  }

  async resetGoldAndShutdown() {
    log.info("Resetting Gold and Shutdown...")
    try {
      await cpp.exec("sudo pkill -x -SIGUSR2 firereset");
      await cpp.exec("sudo pkill -x -SIGUSR2 firereset");
      await cpp.exec("sudo pkill -x -SIGUSR2 firereset");
    } catch(err) {
      log.error("Got error when resetting gold and shutdown, err:", err);
    }
  }

  switchCleanSupportFlag(op=true) {
    const onOff = op ? "ON" : "OFF";
    log.info(`Switch ${onOff} clean support flag`);
    const CLEAN_SUPPORT_FLAG_FILE = '/dev/shm/clean_support.touch'
    try {
      if ( op ) {
        fs.closeSync(fs.openSync(CLEAN_SUPPORT_FLAG_FILE,'w'));
      } else {
        fs.unlinkSync(CLEAN_SUPPORT_FLAG_FILE);
      }
    } catch (err) {
      log.error(`failed to switch ${onOff} clean support flag(${CLEAN_SUPPORT_FLAG_FILE}):`,err);
    }
  }

  resetDevice(config) {
    log.info("Resetting device to factory defaults...");

    this.switchCleanSupportFlag(config && config.clean_support);

    if(platform.getName() === 'gold') {
      if(config && config.shutdown) {
        return this.resetGoldAndShutdown();
      } else {
        return this.resetGold();
      }
    }

    if(Firewalla.isOverlayFS()) {
      log.info("OverlayFS is enabled");
      return new Promise((resolve, reject) => {
        let cmd = ((config && config.shutdown) ? "FIREWALLA_POST_RESET_OP=shutdown " : "") + Firewalla.getFirewallaHome() + "/scripts/"+platform.getSystemResetAllOverlayfsScriptName();
        log.info("cmd: ",cmd);
        cp.exec(cmd, (err) => {
          if(err) {
            log.error("Failed to rename overlay upper work directory to backup:", err);
          }
          log.info("Resetting with cmd ",cmd);
          resolve();
        });
      });
    } else {
      log.info("Regular filesystem without OverlayFS");
      let cmd = ((config && config.shutdown) ? "FIREWALLA_POST_RESET_OP=shutdown " : "") + Firewalla.getFirewallaHome() + "/scripts/system-reset-all";
      return new Promise((resolve, reject) => {
        cp.exec(cmd, (err, stdout, stderr) => {
          if(err) {
            reject(err);
            return;
          }
          resolve();
        });
      });
    }
  }
}

module.exports = new DeviceMgmtTool();
<commit_msg>remove hard code gold<commit_after>/*    Copyright 2016 Firewalla LLC
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
'use strict';
let log = require("../net2/logger.js")(__filename);

let Firewalla = require('../net2/Firewalla.js');

let Promise = require('bluebird');
let cp = require('child_process');

const cpp = require('child-process-promise');
const fs = require("fs");
const platform = require('../platform/PlatformLoader.js').getPlatform();

let instance = null;
class DeviceMgmtTool {
  constructor() {
    if (!instance) {
      instance = this;
    }
    return instance;
  }

  _getOverlayUpperDirectory() {
    return Firewalla.getOverlayUpperDirPartition() + "/overlay";
  }

  _getOverlayUpperWorkDirectory() {
    return Firewalla.getOverlayUpperDirPartition() + "/overlay-workdir";
  }

  async deleteGroup(eptcloud, gid) {
    log.info("Delete group " + gid);
    await eptcloud.deleteGroup(gid)
    log.info("Group " + gid + " is deleted.");
  }

  async bluetoothReset() {
    log.info("Resetting Gold...")
    try {
      await cpp.exec("sudo pkill -x -SIGUSR1 firereset");
      await cpp.exec("sudo pkill -x -SIGUSR1 firereset");
      await cpp.exec("sudo pkill -x -SIGUSR1 firereset");
    } catch(err) {
      log.error("Got error when resetting gold, err:", err);
    }
  }

  async bluetoothResetAndShutdown() {
    log.info("Resetting Gold and Shutdown...")
    try {
      await cpp.exec("sudo pkill -x -SIGUSR2 firereset");
      await cpp.exec("sudo pkill -x -SIGUSR2 firereset");
      await cpp.exec("sudo pkill -x -SIGUSR2 firereset");
    } catch(err) {
      log.error("Got error when resetting gold and shutdown, err:", err);
    }
  }

  switchCleanSupportFlag(op=true) {
    const onOff = op ? "ON" : "OFF";
    log.info(`Switch ${onOff} clean support flag`);
    const CLEAN_SUPPORT_FLAG_FILE = '/dev/shm/clean_support.touch'
    try {
      if ( op ) {
        fs.closeSync(fs.openSync(CLEAN_SUPPORT_FLAG_FILE,'w'));
      } else {
        fs.unlinkSync(CLEAN_SUPPORT_FLAG_FILE);
      }
    } catch (err) {
      log.error(`failed to switch ${onOff} clean support flag(${CLEAN_SUPPORT_FLAG_FILE}):`,err);
    }
  }

  resetDevice(config) {
    log.info("Resetting device to factory defaults...");

    this.switchCleanSupportFlag(config && config.clean_support);

    if(platform.isFireRouterManaged()) {
      if(config && config.shutdown) {
        return this.bluetoothResetAndShutdown();
      } else {
        return this.bluetoothReset();
      }
    }

    if(Firewalla.isOverlayFS()) {
      log.info("OverlayFS is enabled");
      return new Promise((resolve, reject) => {
        let cmd = ((config && config.shutdown) ? "FIREWALLA_POST_RESET_OP=shutdown " : "") + Firewalla.getFirewallaHome() + "/scripts/"+platform.getSystemResetAllOverlayfsScriptName();
        log.info("cmd: ",cmd);
        cp.exec(cmd, (err) => {
          if(err) {
            log.error("Failed to rename overlay upper work directory to backup:", err);
          }
          log.info("Resetting with cmd ",cmd);
          resolve();
        });
      });
    } else {
      log.info("Regular filesystem without OverlayFS");
      let cmd = ((config && config.shutdown) ? "FIREWALLA_POST_RESET_OP=shutdown " : "") + Firewalla.getFirewallaHome() + "/scripts/system-reset-all";
      return new Promise((resolve, reject) => {
        cp.exec(cmd, (err, stdout, stderr) => {
          if(err) {
            reject(err);
            return;
          }
          resolve();
        });
      });
    }
  }
}

module.exports = new DeviceMgmtTool();
<|endoftext|>


<commit_before>#!/usr/bin/env node

var path          = require('path'),
	fs            = require('fs'),
	sourceDir     = path.join(path.dirname(fs.realpathSync(__filename)), '../../standalone/'),
	jsDir         = path.join(path.dirname(fs.realpathSync(__filename)), '../../..'),
	child_process = require('child_process');

function runDocco() {

	fs.mkdir("../../docs", function() {
		fs.readdir("temp", function( err, files ) {

			// Prepend temp to each file
			files = files.map(function( file ) {
				return "temp/" + file;
			});

			console.log( "Generating docco annotated source..." );
			child_process.exec("docco " + files.join(" "), function() {
				fs.readdir("docs", function( err, files ) {
					files.forEach(function( file ) {
						console.log( "\t" + file );
						fs.renameSync( "docs/" + file, "../../docs/" + file );
					});
					console.log("Cleaning up...");
					fs.readdir("temp", function( e, files ) {
						files.forEach(function( file ) {
							fs.unlinkSync("temp/" + file );
						});
						fs.rmdir("temp");
					});
					fs.rmdir("docs");
					console.log("Done!");
				});
			});

		});

	});

}

function stripComments() {
	fs.readdir(sourceDir, function( err, files ) {

		var count = 0;

		// Only annotate full srcs
		files = files.filter(function( file ) {
			return file.indexOf(".min.") < 0;
		});

		// Create the temp directory for stripped code
		fs.mkdir("temp", function() {

			// Generate source for all standalones
			console.log( "Stripping multiline comments from:" );
			files.forEach(function( file ) {
				fs.readFile( sourceDir + file, "utf-8", function( err, code ) {
					console.log( "\t" + file );
					code = code.replace( /\/\*(?:.*)(?:\n\s+\*.*)*/gim, "");
					fs.writeFile("temp/" + file, code, "utf-8", function() {
						if ( ++count == files.length ) {
							runDocco();
						}
					});
				});
			});
		});
	});
}

console.log("generating unminified sources...");
child_process.exec("js can/util/docco/makestandalone.js", {
	cwd : jsDir
}, function( err, stdout, stderr ) {
	console.log("test", stdout, stderr, jsDir);
	stripComments();
});

<commit_msg>Small docco script tweak.<commit_after>#!/usr/bin/env node

var path          = require('path'),
	fs            = require('fs'),
	sourceDir     = path.join(path.dirname(fs.realpathSync(__filename)), '../../standalone/'),
	jsDir         = path.join(path.dirname(fs.realpathSync(__filename)), '../../..'),
	child_process = require('child_process');

function runDocco() {

	fs.mkdir("../../docs", function() {
		fs.readdir("temp", function( err, files ) {

			// Prepend temp to each file
			files = files.map(function( file ) {
				return "temp/" + file;
			});

			console.log( "Generating docco annotated source..." );
			child_process.exec("docco " + files.join(" "), function() {
				fs.readdir("docs", function( err, files ) {
					files.forEach(function( file ) {
						console.log( "\t" + file );
						fs.renameSync( "docs/" + file, "../../docs/" + file );
					});
					console.log("Cleaning up...");
					fs.readdir("temp", function( e, files ) {
						files.forEach(function( file ) {
							fs.unlinkSync("temp/" + file );
						});
						fs.rmdir("temp");
					});
					fs.rmdir("docs");
					console.log("Done!");
				});
			});

		});

	});

}

function stripComments() {
	fs.readdir(sourceDir, function( err, files ) {

		var count = 0;

		// Only annotate full srcs
		files = files.filter(function( file ) {
			return file.indexOf(".min.") < 0;
		});

		// Create the temp directory for stripped code
		fs.mkdir("temp", function() {

			// Generate source for all standalones
			console.log( "Stripping multiline comments from:" );
			files.forEach(function( file ) {
				fs.readFile( sourceDir + file, "utf-8", function( err, code ) {
					console.log( "\t" + file );
					code = code.replace( /\/\*(?:.*)(?:\n\s+\*.*)*/gim, "");
					fs.writeFile("temp/" + file, code, "utf-8", function() {
						if ( ++count == files.length ) {
							runDocco();
						}
					});
				});
			});
		});
	});
}

console.log("generating unminified sources...");
child_process.exec("js can/util/docco/makestandalone.js", {
	cwd : jsDir
}, function( err, stdout, stderr ) {
	console.log( stdout );
	stripComments();
});

<|endoftext|>


<commit_before>define([
  'backbone',
  'jquery',
  'underscore',
  'text!templates/room.html',
  'module/adapter',
  'module/room',
  'module/chat',
  'module/socket',
  'module/dataChannel'
], function (Backbone, $, _, roomTpl, adapter, room, initChat, socket, initDataChannel) {

    var servers = {
        iceServers: [
            {url: "stun:stun.l.google.com:19302"},
            {url: "turn:agornostal%40cogniance.com@numb.viagenie.ca:3478", credential: 'webrtc'}
        ]
    };

    var RoomView = Backbone.View.extend({

        el: 'body',
        template: _.template(roomTpl),

        initialize: function(roomId){
            this.room = roomId;
        },

        render: function () {
            this.el.innerHTML = this.template({room: this.room});
            this.joinRoom(this.room);

            $('.hangup').click(function(){
                document.location.href = '/';
            });
        },

        joinRoom: function(roomId){
            var that = this;
            room.join(roomId, function(isCaller){
                console.log('isCaller -', isCaller);
                try{
                    that.establishConnection(isCaller);
                } catch(e) {
                    console.error(e);
                }
            }, function(e){
                alert(e);
                document.location.href = '/';
            });

            room.onLeave(function(){
                console.log('User left the room');
                $('#remote-view video').remove();
                $('#user-left').fadeIn(function(){
                    var $div = $(this);
                    setTimeout(function(){ $div.fadeOut(); }, 3e3);
                });
            });
        },

        establishConnection: function(isCaller){
            var pc = new adapter.RTCPeerConnection(servers, {optional: [{RtpDataChannels: true}]});

            var chat = initChat();
            var dataChannel = initDataChannel(pc, {
                onOpen: chat.activate,
                onClose: chat.deactivate,
                onMessage: chat.onReceiveMsg
            });
            if( dataChannel ){
                chat.onSendMsg = dataChannel.send.bind(dataChannel);
            }

            // send ice candidates to the other peer
            pc.onicecandidate = function (evt) {
                if(evt.candidate){
                    console.debug('send candidate', evt.candidate);
                    socket.emit('candidate', {candidate: evt.candidate});
                }
            };

            // once remote stream arrives, show it in the remote video element
            pc.onaddstream = function (evt) {
                var video = document.createElement("video");
                video.controls = true;
                adapter.attachMediaStream(video, evt.stream);
                document.getElementById('remote-view').appendChild(video);
            };
            adapter.getUserMedia({video: true, audio: true}, function(localMediaStream){
                var video = document.createElement("video");
                video.controls = true;
                adapter.attachMediaStream(video, localMediaStream);
                document.getElementById('local-view').appendChild(video);

                var gotDescription = function(description){
                    // send our description to server
                    pc.setLocalDescription(description);
                    console.debug('send local description', description);
                    socket.emit('description', {description: description});
                };

                pc.addStream(localMediaStream);

                // notify server that we need a remote description
                socket.emit('need_description');

                // we get a remote description
                socket.on('description', function(data){
                    console.debug('received description', data);
                    pc.setRemoteDescription( new adapter.RTCSessionDescription(data.description), function(){
                        // crateAnswer from within callback of setRemoteDescription to avoid race condition
                        if( !isCaller ){
                            // NOTE: createAnswer has to be called after callee receives a remote description
                            console.debug('Create answer');
                            pc.createAnswer(gotDescription, function(e){
                                console.error('Error - createAnswer:', e);
                            });
                        }
                    }, function(e){
                        console.error('Error - setRemoteDescription: ' + e);
                    });

                    // we got candidates
                    socket.on('candidate', function(data){
                        console.debug('received candidate', data);
                        pc.addIceCandidate( new adapter.RTCIceCandidate(data.candidate) );
                    });

                    // once we have it, we can set candidates
                    // notify server that we need candidates
                    socket.emit('need_candidates');
                });

                if (isCaller) {
                    console.debug('Create offer');
                    pc.createOffer(function(offer){
                        if (adapter.webrtcDetectedBrowser === "firefox") {
                            offer.sdp = ensureCryptoLine(offer.sdp);
                        }
                        gotDescription(offer);
                    }, function(e){
                        console.error('Error - createOffer:', e);
                    });
                }

            }, function(e){
                console.error('Error - getUserMedia:', e);
            });
        }
    });

    return RoomView;
});
<commit_msg>Revert "that doesn't help"<commit_after>define([
  'backbone',
  'jquery',
  'underscore',
  'text!templates/room.html',
  'module/adapter',
  'module/room',
  'module/chat',
  'module/socket',
  'module/dataChannel'
], function (Backbone, $, _, roomTpl, adapter, room, initChat, socket, initDataChannel) {

    var servers = {
        iceServers: [
            {url: "stun:stun.l.google.com:19302"},
            {url: "turn:agornostal%40cogniance.com@numb.viagenie.ca:3478", credential: 'webrtc'}
        ]
    };

    var RoomView = Backbone.View.extend({

        el: 'body',
        template: _.template(roomTpl),

        initialize: function(roomId){
            this.room = roomId;
        },

        render: function () {
            this.el.innerHTML = this.template({room: this.room});
            this.joinRoom(this.room);

            $('.hangup').click(function(){
                document.location.href = '/';
            });
        },

        joinRoom: function(roomId){
            var that = this;
            room.join(roomId, function(isCaller){
                console.log('isCaller -', isCaller);
                try{
                    that.establishConnection(isCaller);
                } catch(e) {
                    console.error(e);
                }
            }, function(e){
                alert(e);
                document.location.href = '/';
            });

            room.onLeave(function(){
                console.log('User left the room');
                $('#remote-view video').remove();
                $('#user-left').fadeIn(function(){
                    var $div = $(this);
                    setTimeout(function(){ $div.fadeOut(); }, 3e3);
                });
            });
        },

        establishConnection: function(isCaller){
            var pc = new adapter.RTCPeerConnection(servers, {optional: [{RtpDataChannels: true}]});

            var chat = initChat();
            var dataChannel = initDataChannel(pc, {
                onOpen: chat.activate,
                onClose: chat.deactivate,
                onMessage: chat.onReceiveMsg
            });
            if( dataChannel ){
                chat.onSendMsg = dataChannel.send.bind(dataChannel);
            }

            // send ice candidates to the other peer
            pc.onicecandidate = function (evt) {
                if(evt.candidate){
                    console.debug('send candidate', evt.candidate);
                    socket.emit('candidate', {candidate: evt.candidate});
                }
            };

            // Add an a=crypto line for SDP emitted by Firefox.
            // This is backwards compatibility for Firefox->Chrome calls because
            // Chrome will not accept a=crypto-less offers and Firefox only
            // does DTLS-SRTP.
            var ensureCryptoLine = function(sdp) {
                console.debug('Add an a=crypto line');

                var sdpLinesIn = sdp.split('\r\n');
                var sdpLinesOut = [];

                // Search for m line.
                for (var i = 0; i < sdpLinesIn.length; i++) {
                    sdpLinesOut.push(sdpLinesIn[i]);
                    if (sdpLinesIn[i].search('m=') !== -1) {
                        sdpLinesOut.push(
                            "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:BAADBAADBAADBAADBAADBAADBAADBAADBAADBAAD");
                    }
                }

                sdp = sdpLinesOut.join('\r\n');
                return sdp;
            };

            // once remote stream arrives, show it in the remote video element
            pc.onaddstream = function (evt) {
                var video = document.createElement("video");
                video.controls = true;
                adapter.attachMediaStream(video, evt.stream);
                document.getElementById('remote-view').appendChild(video);
            };
            adapter.getUserMedia({video: true, audio: true}, function(localMediaStream){
                var video = document.createElement("video");
                video.controls = true;
                adapter.attachMediaStream(video, localMediaStream);
                document.getElementById('local-view').appendChild(video);

                var gotDescription = function(description){
                    // send our description to server
                    pc.setLocalDescription(description);
                    console.debug('send local description', description);
                    socket.emit('description', {description: description});
                };

                pc.addStream(localMediaStream);

                // notify server that we need a remote description
                socket.emit('need_description');

                // we get a remote description
                socket.on('description', function(data){
                    console.debug('received description', data);
                    pc.setRemoteDescription( new adapter.RTCSessionDescription(data.description), function(){
                        // crateAnswer from within callback of setRemoteDescription to avoid race condition
                        if( !isCaller ){
                            // NOTE: createAnswer has to be called after callee receives a remote description
                            console.debug('Create answer');
                            pc.createAnswer(gotDescription, function(e){
                                console.error('Error - createAnswer:', e);
                            });
                        }
                    }, function(e){
                        console.error('Error - setRemoteDescription: ' + e);
                    });

                    // we got candidates
                    socket.on('candidate', function(data){
                        console.debug('received candidate', data);
                        pc.addIceCandidate( new adapter.RTCIceCandidate(data.candidate) );
                    });

                    // once we have it, we can set candidates
                    // notify server that we need candidates
                    socket.emit('need_candidates');
                });

                if (isCaller) {
                    console.debug('Create offer');
                    pc.createOffer(function(offer){
                        if (adapter.webrtcDetectedBrowser === "firefox") {
                            offer.sdp = ensureCryptoLine(offer.sdp);
                        }
                        gotDescription(offer);
                    }, function(e){
                        console.error('Error - createOffer:', e);
                    });
                }

            }, function(e){
                console.error('Error - getUserMedia:', e);
            });
        }
    });

    return RoomView;
});
<|endoftext|>


<commit_before>(function () {
  var utils = require('utilities')
    , assert = require('assert')
    , request = require('request')
    , path = require('path')
    , fs = require('fs')
    , cmd = require('../../lib/cmd').Cmd
    , geddyCli = path.join(__dirname,'../','../','bin','cli')+'.js'
    , tmpDir = path.join(__dirname, '../', 'tmp')
    , staticId = utils.string.uuid(10)
    , engines = {
        ejs: null
      , jade: '-j'
      , swig: '-s'
      , handlebars: '-H'
      , mustache: '-m'
      }
    /*
    * Runs `geddy gen app` with the specified template engine
    */
    , scaffoldApp = function (engine, flag, cb) {
        var spawn = require('child_process').spawn
          , testDir = tmpDir
          , cmd = geddyCli
          , opts = ['gen', 'app', engine + 'App']
          , srcModules = path.join(__dirname, '..', '..', 'node_modules')
          , appDir = path.join(testDir, engine + 'App')
          , proc;

        if(flag) {
          opts.push(flag);
        }

        proc = spawn(cmd, opts, {cwd:testDir});

        proc.stderr.setEncoding('utf8');

        proc.stderr.on('data', function (data) {
          console.error(data);
          if (/^execvp\(\)/.test(data)) {
            assert.ok(false, 'Failed to generate scaffolding for ' + engine);
          }
        });

        proc.on('close', function (code) {
          // Create a copy of node_modules so the generated apps don't need to
          // do an `npm install`
          utils.file.cpR(srcModules, appDir, {silent: true});
          cb();
        });
      }
    /*
    * Runs `geddy gen scaffold zoobies foo:string bar:number`
    * with the specified template engine
    */
    , scaffoldResource = function (engine, flag, cb) {
        var spawn = require('child_process').spawn
          , testAppDir = path.join(tmpDir, engine + 'App')
          , cmd = geddyCli
          , opts = ['gen', 'scaffold']
          , proc;

        if(flag) {
          opts.push(flag);
        }

        opts = opts.concat(['zoobies', 'foo:string', 'bar:number']);

        proc = spawn(cmd, opts, {cwd:testAppDir});

        proc.stderr.setEncoding('utf8');

        proc.stderr.on('data', function (data) {
          console.error(data);
          if (/^execvp\(\)/.test(data)) {
            assert.ok(false, 'Failed to generate scaffolding for ' + engine);
          }
        });

        proc.on('close', function (code) {
          cb();
        });
      }
    /*
    * Starts a geddy server
    */
    , startServer = function (engine, port, cb) {
        var spawn = require('child_process').spawn
          , testAppDir = path.join(tmpDir, engine + 'App')
          , cmd = geddyCli
          , opts = ['--port', port]
          , server
          , notified = false
          , failed = false;

        server = spawn(cmd, opts, {cwd:testAppDir});

        server.stderr.setEncoding('utf8');

        server.stderr.on('data', function (data) {
          console.log(data);
        });

        console.log("Starting " + engine + " app on port " + port);

        server.stdout.on('data', function (data) {
          var ready = data.toString().match(/Server worker running in [a-z]+? on port [0-9]+? with a PID of: [0-9]+?/)?true:false;

          if(!notified && ready) {
            notified = true;
            cb(server);
          }
        });
      }
  /*
  * Kills a geddy server
  */
  , killServer = function (server, cb) {
      server.on('close', function (code) {
        cb();
      });

      server.kill("SIGHUP");
    }
  , tests = {}
  , servers = []
  , port = 8090
  , portCopy = port
  , base = 'http://127.0.0.1:'
  , baseUrl
  , reqOpts = {
      timeout: 1000
    };

  /*
  * CRUD Tests
  */
  for(var engine in engines) {
    (function (baseUrl) {

      tests["test " + engine + " shows site index"] = function(next) {
        //Request index
        request(baseUrl, reqOpts, function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when requesting ' + baseUrl);
          assert.notStrictEqual(body.match(/Hello, World!/), null, 'Hello world text is missing')
          next();
        });
      };

      tests["test " + engine + " site index with malformed query string"] = function(next) {
        //Request index
        request(baseUrl + '?test=t%\'2B', reqOpts, function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 400, 'Error '+res.statusCode+' when requesting ' + baseUrl);
          next();
        });
      };

      tests["test " + engine + " index when empty"] = function(next) {
        //Request index
        request(baseUrl + '/zoobies', reqOpts, function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when requesting /zoobies: ' + body);
          assert.notStrictEqual(body.match(/
\s*<\/div>/gi), null, 'There should be an empty zoobies list')
          next();
        });
      };

      tests["test " + engine + " create entry"] = function(next) {
        //Request index
        request({
          method: 'POST'
        , uri: baseUrl + '/zoobies'
        , form: {
            foo: 'zerb'
          , bar: '2112'
          , id: staticId  // Just use a static ID to keep tests cleaner
          }
        , timeout: 1000
        , followAllRedirects: true
        }
        , function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when creating zoobies');
          assert.strictEqual(body.indexOf('' + staticId + '')>=0, true, 'The zooby should have the expected ID')
          next();
        });
      };

      tests["test " + engine + " show initial values"] = function(next) {
        //Request index
        request({
          method: 'GET'
        , uri: baseUrl + '/zoobies/' + staticId
        , timeout: 1000
        }
        , function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when showing zoobies');
          assert.strictEqual(body.indexOf('zerb') >= 0 , true , 'Foo was persisted correctly')
          assert.strictEqual(body.indexOf('2112') >= 0 , true , 'Bar was persisted correctly')
          next();
        });
      };

      tests["test " + engine + " show initial values in JSON"] = function(next) {
        //Request index
        request({
          method: 'GET'
        , uri: baseUrl + '/zoobies/' + staticId + '.json'
        , timeout: 1000
        }
        , function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when showing zoobies');

          body = JSON.parse(body);

          assert.deepEqual(body, {
            "createdAt": body.createdAt
          , "foo": "zerb"
          , "bar": 2112
          , "id": body.id
          });
          next();
        });
      };

      tests["test " + engine + " update form persists values"] = function(next) {
        //Request index
        request({
          method: 'GET'
        , uri: baseUrl + '/zoobies/' + staticId + '/edit'
        , timeout: 1000
        }
        , function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when updating zooby');

          // FIXME: Is there a less stupid way of asserting this?

          assert.strictEqual(
            body.indexOf('input type="text" class="span6" name="foo" value="zerb"') >= 0  // ms
          ||body.indexOf('input class="span6" name="foo" type="text" value="zerb"') >= 0  // ejs
          , true , 'Foo was persisted correctly')

          assert.strictEqual(
            body.indexOf('input type="number" class="span2" name="bar" value="2112"') >= 0 // ms
          ||body.indexOf('input class="span2" name="bar" type="number" value="2112"') >= 0  // ejs
          , true , 'Bar was persisted correctly')

          next();
        });
      };

      tests["test " + engine + " update values"] = function(next) {
        //Request index
        request({
          method: 'PUT'
        , uri: baseUrl + '/zoobies/' + staticId
        , form: {
            foo: 'overture'
          , bar: '1984'
          }
        , timeout: 1000
        , followAllRedirects: true
        }
        , function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when updating zooby');
          assert.strictEqual(body.indexOf('' + staticId + '')>=0, true, 'The zooby should have the expected ID')
          next();
        });
      };

      tests["test " + engine + " show updated values"] = function(next) {
        //Request index
        request({
          method: 'GET'
        , uri: baseUrl + '/zoobies/' + staticId
        , timeout: 1000
        }
        , function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when showing zoobies');
          assert.strictEqual(body.indexOf('overture') >= 0 , true , 'Foo was updated correctly')
          assert.strictEqual(body.indexOf('1984') >= 0 , true , 'Bar was updated correctly')
          next();
        });
      };

      tests["test " + engine + " delete entry"] = function(next) {
        //Request index
        request({
          method: 'DELETE'
        , uri: baseUrl + '/zoobies/' + staticId
        , timeout: 1000
        , followAllRedirects: true
        }
        , function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when deleting zooby');
          assert.strictEqual(body.match(/id="zooby-[a-z0-9\-]+"/gi), null, 'There should be no zoobies in the list')
          next();
        });
      };

      tests["test " + engine + " 404"] = function(next) {
        //Request index
        request({
          method: 'GET'
        , uri: baseUrl + '/zoobies/' + staticId
        , timeout: 1000
        }
        , function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 404, 'Should get error 404 viewing nonexistant zooby');
          next();
        });
      };

    }(base + portCopy));

    // Increment Port Number
    portCopy++;
  }

  /*
  * The before action will generate the scaffolded apps
  */
  tests.before = function (next) {
    var generators = []
      , chain
      , portCopy = port;

    // Generate a new app for each engine
    for(var engine in engines) {
      (function (serverPort) {
        generators.push({
          func: scaffoldApp
        , args: [engine, engines[engine]]
        , callback: null
        });
        generators.push({
          func: scaffoldResource
        , args: [engine, engines[engine]]
        , callback: null
        });
        generators.push({
          func: startServer
        , args: [engine, serverPort]
        , callback: function (server) {
            servers.push(server);
          }
        });
      }(portCopy));

      // Increment port number
      portCopy++;
    }

    chain = new utils.async.AsyncChain(generators);

    chain.last = next;

    chain.run();
  };

  /*
  * The after action cleans the temporary directory
  */
  tests.after = function (next) {
    //Kill all the servers
    var killers = [];
    for(var key in servers) {
      killers.push({
        func: killServer
      , args: [servers[key]]
      , callback: null
      });
    }

    chain = new utils.async.AsyncChain(killers);

    chain.last = function () {
      //utils.file.rmRf(tmpDir, {silent:true});
      next();
    };

    chain.run();
  };

  module.exports = tests;
}());
<commit_msg>Update JSON test to check for model type in response<commit_after>(function () {
  var utils = require('utilities')
    , assert = require('assert')
    , request = require('request')
    , path = require('path')
    , fs = require('fs')
    , cmd = require('../../lib/cmd').Cmd
    , geddyCli = path.join(__dirname,'../','../','bin','cli')+'.js'
    , tmpDir = path.join(__dirname, '../', 'tmp')
    , staticId = utils.string.uuid(10)
    , engines = {
        ejs: null
      , jade: '-j'
      , swig: '-s'
      , handlebars: '-H'
      , mustache: '-m'
      }
    /*
    * Runs `geddy gen app` with the specified template engine
    */
    , scaffoldApp = function (engine, flag, cb) {
        var spawn = require('child_process').spawn
          , testDir = tmpDir
          , cmd = geddyCli
          , opts = ['gen', 'app', engine + 'App']
          , srcModules = path.join(__dirname, '..', '..', 'node_modules')
          , appDir = path.join(testDir, engine + 'App')
          , proc;

        if(flag) {
          opts.push(flag);
        }

        proc = spawn(cmd, opts, {cwd:testDir});

        proc.stderr.setEncoding('utf8');

        proc.stderr.on('data', function (data) {
          console.error(data);
          if (/^execvp\(\)/.test(data)) {
            assert.ok(false, 'Failed to generate scaffolding for ' + engine);
          }
        });

        proc.on('close', function (code) {
          // Create a copy of node_modules so the generated apps don't need to
          // do an `npm install`
          utils.file.cpR(srcModules, appDir, {silent: true});
          cb();
        });
      }
    /*
    * Runs `geddy gen scaffold zoobies foo:string bar:number`
    * with the specified template engine
    */
    , scaffoldResource = function (engine, flag, cb) {
        var spawn = require('child_process').spawn
          , testAppDir = path.join(tmpDir, engine + 'App')
          , cmd = geddyCli
          , opts = ['gen', 'scaffold']
          , proc;

        if(flag) {
          opts.push(flag);
        }

        opts = opts.concat(['zoobies', 'foo:string', 'bar:number']);

        proc = spawn(cmd, opts, {cwd:testAppDir});

        proc.stderr.setEncoding('utf8');

        proc.stderr.on('data', function (data) {
          console.error(data);
          if (/^execvp\(\)/.test(data)) {
            assert.ok(false, 'Failed to generate scaffolding for ' + engine);
          }
        });

        proc.on('close', function (code) {
          cb();
        });
      }
    /*
    * Starts a geddy server
    */
    , startServer = function (engine, port, cb) {
        var spawn = require('child_process').spawn
          , testAppDir = path.join(tmpDir, engine + 'App')
          , cmd = geddyCli
          , opts = ['--port', port]
          , server
          , notified = false
          , failed = false;

        server = spawn(cmd, opts, {cwd:testAppDir});

        server.stderr.setEncoding('utf8');

        server.stderr.on('data', function (data) {
          console.log(data);
        });

        console.log("Starting " + engine + " app on port " + port);

        server.stdout.on('data', function (data) {
          var ready = data.toString().match(/Server worker running in [a-z]+? on port [0-9]+? with a PID of: [0-9]+?/)?true:false;

          if(!notified && ready) {
            notified = true;
            cb(server);
          }
        });
      }
  /*
  * Kills a geddy server
  */
  , killServer = function (server, cb) {
      server.on('close', function (code) {
        cb();
      });

      server.kill("SIGHUP");
    }
  , tests = {}
  , servers = []
  , port = 8090
  , portCopy = port
  , base = 'http://127.0.0.1:'
  , baseUrl
  , reqOpts = {
      timeout: 1000
    };

  /*
  * CRUD Tests
  */
  for(var engine in engines) {
    (function (baseUrl) {

      tests["test " + engine + " shows site index"] = function(next) {
        //Request index
        request(baseUrl, reqOpts, function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when requesting ' + baseUrl);
          assert.notStrictEqual(body.match(/Hello, World!/), null, 'Hello world text is missing')
          next();
        });
      };

      tests["test " + engine + " site index with malformed query string"] = function(next) {
        //Request index
        request(baseUrl + '?test=t%\'2B', reqOpts, function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 400, 'Error '+res.statusCode+' when requesting ' + baseUrl);
          next();
        });
      };

      tests["test " + engine + " index when empty"] = function(next) {
        //Request index
        request(baseUrl + '/zoobies', reqOpts, function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when requesting /zoobies: ' + body);
          assert.notStrictEqual(body.match(/
\s*<\/div>/gi), null, 'There should be an empty zoobies list')
          next();
        });
      };

      tests["test " + engine + " create entry"] = function(next) {
        //Request index
        request({
          method: 'POST'
        , uri: baseUrl + '/zoobies'
        , form: {
            foo: 'zerb'
          , bar: '2112'
          , id: staticId  // Just use a static ID to keep tests cleaner
          }
        , timeout: 1000
        , followAllRedirects: true
        }
        , function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when creating zoobies');
          assert.strictEqual(body.indexOf('' + staticId + '')>=0, true, 'The zooby should have the expected ID')
          next();
        });
      };

      tests["test " + engine + " show initial values"] = function(next) {
        //Request index
        request({
          method: 'GET'
        , uri: baseUrl + '/zoobies/' + staticId
        , timeout: 1000
        }
        , function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when showing zoobies');
          assert.strictEqual(body.indexOf('zerb') >= 0 , true , 'Foo was persisted correctly')
          assert.strictEqual(body.indexOf('2112') >= 0 , true , 'Bar was persisted correctly')
          next();
        });
      };

      tests["test " + engine + " show initial values in JSON"] = function(next) {
        //Request index
        request({
          method: 'GET'
        , uri: baseUrl + '/zoobies/' + staticId + '.json'
        , timeout: 1000
        }
        , function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when showing zoobies');

          body = JSON.parse(body);

          assert.deepEqual(body, {
            "createdAt": body.createdAt
          , "foo": "zerb"
          , "bar": 2112
          , "id": body.id
          , "type": "Zooby"
          });
          next();
        });
      };

      tests["test " + engine + " update form persists values"] = function(next) {
        //Request index
        request({
          method: 'GET'
        , uri: baseUrl + '/zoobies/' + staticId + '/edit'
        , timeout: 1000
        }
        , function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when updating zooby');

          // FIXME: Is there a less stupid way of asserting this?

          assert.strictEqual(
            body.indexOf('input type="text" class="span6" name="foo" value="zerb"') >= 0  // ms
          ||body.indexOf('input class="span6" name="foo" type="text" value="zerb"') >= 0  // ejs
          , true , 'Foo was persisted correctly')

          assert.strictEqual(
            body.indexOf('input type="number" class="span2" name="bar" value="2112"') >= 0 // ms
          ||body.indexOf('input class="span2" name="bar" type="number" value="2112"') >= 0  // ejs
          , true , 'Bar was persisted correctly')

          next();
        });
      };

      tests["test " + engine + " update values"] = function(next) {
        //Request index
        request({
          method: 'PUT'
        , uri: baseUrl + '/zoobies/' + staticId
        , form: {
            foo: 'overture'
          , bar: '1984'
          }
        , timeout: 1000
        , followAllRedirects: true
        }
        , function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when updating zooby');
          assert.strictEqual(body.indexOf('' + staticId + '')>=0, true, 'The zooby should have the expected ID')
          next();
        });
      };

      tests["test " + engine + " show updated values"] = function(next) {
        //Request index
        request({
          method: 'GET'
        , uri: baseUrl + '/zoobies/' + staticId
        , timeout: 1000
        }
        , function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when showing zoobies');
          assert.strictEqual(body.indexOf('overture') >= 0 , true , 'Foo was updated correctly')
          assert.strictEqual(body.indexOf('1984') >= 0 , true , 'Bar was updated correctly')
          next();
        });
      };

      tests["test " + engine + " delete entry"] = function(next) {
        //Request index
        request({
          method: 'DELETE'
        , uri: baseUrl + '/zoobies/' + staticId
        , timeout: 1000
        , followAllRedirects: true
        }
        , function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when deleting zooby');
          assert.strictEqual(body.match(/id="zooby-[a-z0-9\-]+"/gi), null, 'There should be no zoobies in the list')
          next();
        });
      };

      tests["test " + engine + " 404"] = function(next) {
        //Request index
        request({
          method: 'GET'
        , uri: baseUrl + '/zoobies/' + staticId
        , timeout: 1000
        }
        , function(err, res, body) {
          assert.strictEqual(err, null, err);
          assert.strictEqual(res.statusCode, 404, 'Should get error 404 viewing nonexistant zooby');
          next();
        });
      };

    }(base + portCopy));

    // Increment Port Number
    portCopy++;
  }

  /*
  * The before action will generate the scaffolded apps
  */
  tests.before = function (next) {
    var generators = []
      , chain
      , portCopy = port;

    // Generate a new app for each engine
    for(var engine in engines) {
      (function (serverPort) {
        generators.push({
          func: scaffoldApp
        , args: [engine, engines[engine]]
        , callback: null
        });
        generators.push({
          func: scaffoldResource
        , args: [engine, engines[engine]]
        , callback: null
        });
        generators.push({
          func: startServer
        , args: [engine, serverPort]
        , callback: function (server) {
            servers.push(server);
          }
        });
      }(portCopy));

      // Increment port number
      portCopy++;
    }

    chain = new utils.async.AsyncChain(generators);

    chain.last = next;

    chain.run();
  };

  /*
  * The after action cleans the temporary directory
  */
  tests.after = function (next) {
    //Kill all the servers
    var killers = [];
    for(var key in servers) {
      killers.push({
        func: killServer
      , args: [servers[key]]
      , callback: null
      });
    }

    chain = new utils.async.AsyncChain(killers);

    chain.last = function () {
      //utils.file.rmRf(tmpDir, {silent:true});
      next();
    };

    chain.run();
  };

  module.exports = tests;
}());
<|endoftext|>


<commit_before>// https get module
// Todo: api -> url

const https = require('https');
//const keys = require('../keys.js');

let parameters = {};

function init(params) {
	parameters = params; // move params to module's global scope
}

function getDataFromAPI(APIpath, localCallback) {
	let options = {
		host: 'api.laji.fi',
		path: (APIpath + "&access_token=" +  process.env.LAJI_TOKEN)
	}

	console.log(options.path);

	https.get(options, function handleAPIResponseStream(apiResponse) {
		if (404 == apiResponse.statusCode) { // Stop processing on 404
			handleAPIError(404);
		}
		else {
			let body = '';

		    apiResponse.on('data', function(chunk) {
		        body += chunk;
		    });

		    apiResponse.on('end', function() {
		   		let data;
				try {
					data = JSON.parse(body);
				} catch(e) {
					console.log('Malformed request: ' + body);
				}
	//	   		console.log("body: " + body); // debug
		   		localCallback(null, data); // First argument is error
		    });
		}
	})
	.on('error', handleAPIError);
}

function handleAPIError(error) {
	parameters.response.writeHead(504);
	if (404 == error) {
		parameters.response.end('api.laji.fi endpoint not found (404)');
		console.log("api.laji.fi returns 404: " + error);
	}
	else {
		parameters.response.end('api.laji.fi is not responding (504)');
		console.log("Error reading api.laji.fi (check server internet connection): " + error);
	}
}

module.exports = {
	get: getDataFromAPI,
	init: init
}<commit_msg>Refactor & rewrite error messages<commit_after>// https get module
// Todo: api -> url

const https = require('https');
//const keys = require('../keys.js');

let parameters = {};

function init(params) {
	parameters = params; // move params to module's global scope
}

function getDataFromAPI(APIpath, localCallback) {
	let options = {
		host: 'api.laji.fi',
		path: (APIpath + "&access_token=" +  process.env.LAJI_TOKEN)
	}

	console.log(options.path);

	https.get(options, function handleAPIResponseStream(apiResponse) {
		if (200 != apiResponse.statusCode) { // Stop processing on error
			handleAPIError(apiResponse.statusCode);
		}
		else {
			let body = '';

		    apiResponse.on('data', function(chunk) {
		        body += chunk;
		    });

		    apiResponse.on('end', function() {
		   		let data;
				try {
					data = JSON.parse(body);
				} catch(e) {
					console.log('Malformed request: ' + body);
				}
	//	   		console.log("body: " + body); // debug
		   		localCallback(null, data); // First argument is error
		    });
		}
	})
	.on('error', handleAPIError);
}

function handleAPIError(error) {
	parameters.response.writeHead(504);
	if (Number.isInteger(error)) {
		let errorMessage = 'api.laji.fi error with status code ' + error;
		parameters.response.end(errorMessage);
		console.log(errorMessage);
	}
	else {
		parameters.response.end('api.laji.fi is not responding');
		console.log("api.laji.fi is not responding (check server internet connection), error message: " + error);
	}
}

module.exports = {
	get: getDataFromAPI,
	init: init
}<|endoftext|>


<commit_before> /*---------------------------------------------------------*/
   2: /* The routing strategy */
   3: (function (app, $) {
   4:     var st = {
   5:         strategies: {
   6:             mvc: {
   7:                 defaultController: 'home',
   8:                 defaultAction: 'index',
   9:                 controller: function controllerFromUrl() {
  10:                     // match urls in the form ../controllerName/actionName or ../controllerName
  11:                     var ctl = document.location.href.match(/http[s]?:\/\/[\w\:\.\-\d]+\/([\w\d\-]+)[\/|$]/i);
  12:                     return ctl ? ctl[1].toLowerCase() : this.defaultController;
  13:                 },
  14:                 action: function actionFromUrl() {
  15:                     // match urls in the form ../controllerName/actionName or ../controllerName
  16:                     var act = document.location.href.match(/http[s]?:\/\/[\w\:\.\-\d]+\/[\w\d\-]+\/([\w\d\-]+)/i);
  17:                     return act ? act[1].toLowerCase() : this.defaultAction;
  18:                 }
  19:             }
  20:         }
  21:     };
  22:
  23:     window.myApplication = $.extend(app, st);
  24: })(window.myApplication || {}, jQuery);
  25:
  26:
  27:
  28: /*--------------------------------------------*/
  29: /* The basic routing object */
  30:
  31: (function (app, $) {
  32:     var opts = {
  33:         routingStrategy: app.strategies.mvc
  34:     };
  35:
  36:     var theApp = {
  37:         activeController: undefined,
  38:         controllers: {},
  39:         run: function () {
  40:             this.initController();
  41:             this.initAction();
  42:         },
  43:         initController: function () {
  44:             var activeControllerName =  opts.routingStrategy.controller(); /*getCurrentControllerName*/
  45:             if (activeControllerName && this.controllers[activeControllerName]) {
  46:                 this.activeController = new this.controllers[activeControllerName]();
  47:                 this.activeController.init();
  48:             }
  49:         },
  50:         initAction: function () {
  51:             var activeActionName = opts.routingStrategy.action(); /*getCurrentActionName*/
  52:             if (activeActionName && this.activeController && this.activeController[activeActionName]) {
  53:                  this.activeController[activeActionName]();
  54:             }
  55:         }
  56:     };
  57:
  58:     /* pusblish the routing object */
  59:     window.myApplication = $.extend(app, theApp);
  60:
  61: })(window.myApplication || {}, jQuery);
  62:
  63:
  64: $(function () {
  65:     myApplication.run();
  66: });<commit_msg>removed the line numbers from the js file that were included by mistake<commit_after> /*---------------------------------------------------------*/
 /* The routing strategy */
 (function (app, $) {
     var st = {
         strategies: {
             mvc: {
                 defaultController: 'home',
                 defaultAction: 'index',
                 controller: function controllerFromUrl() {
                     // match urls in the form ../controllerName/actionName or ../controllerName
                     var ctl = document.location.href.match(/http[s]?:\/\/[\w\:\.\-\d]+\/([\w\d\-]+)[\/|$]/i);
                     return ctl ? ctl[1].toLowerCase() : this.defaultController;
                 },
                 action: function actionFromUrl() {
                     // match urls in the form ../controllerName/actionName or ../controllerName
                     var act = document.location.href.match(/http[s]?:\/\/[\w\:\.\-\d]+\/[\w\d\-]+\/([\w\d\-]+)/i);
                     return act ? act[1].toLowerCase() : this.defaultAction;
                 }
             }
         }
     };

     window.myApplication = $.extend(app, st);
 })(window.myApplication || {}, jQuery);

 /*--------------------------------------------*/
 /* The basic routing object */

 (function (app, $) {
     var opts = {
         routingStrategy: app.strategies.mvc
     };

     var theApp = {
         activeController: undefined,
         controllers: {},
         run: function () {
             this.initController();
             this.initAction();
         },
         initController: function () {
             var activeControllerName =  opts.routingStrategy.controller(); /*getCurrentControllerName*/
             if (activeControllerName && this.controllers[activeControllerName]) {
                 this.activeController = new this.controllers[activeControllerName]();
                 this.activeController.init();
             }
         },
         initAction: function () {
             var activeActionName = opts.routingStrategy.action(); /*getCurrentActionName*/
             if (activeActionName && this.activeController && this.activeController[activeActionName]) {
                  this.activeController[activeActionName]();
             }
         }
     };

     /* pusblish the routing object */
     window.myApplication = $.extend(app, theApp);

 })(window.myApplication || {}, jQuery);

 $(function () {
     myApplication.run();
 });<|endoftext|>


<commit_before>/**
 * @author mrdoob / http://mrdoob.com/
 */

function DaydreamController() {

	var state = {};

	function connect() {

		navigator.bluetooth.requestDevice( {
			filters: [ {
				name: 'Daydream controller'
			} ],
			optionalServices: [ '0000fe55-0000-1000-8000-00805f9b34fb' ]
		} )
		.then( function ( device ) {
			return device.gatt.connect();
		} )
		.then( function ( server ) {
			return server.getPrimaryService( '0000fe55-0000-1000-8000-00805f9b34fb' );
		} )
		.then( function ( service ) {
			return service.getCharacteristic( '00000001-1000-1000-8000-00805f9b34fb' );
		} )
		.then( function ( characteristic ) {
			characteristic.addEventListener( 'characteristicvaluechanged', handleData );
			characteristic.startNotifications();
		} )

	}

	function handleData( event ) {

		var data = event.target.value;

		// http://stackoverflow.com/questions/40730809/use-daydream-controller-on-hololens-or-outside-daydream/40753551#40753551

		state.isClickDown = (data.getUint8(18) & 0x1) > 0;
		state.isAppDown = (data.getUint8(18) & 0x4) > 0;
		state.isHomeDown = (data.getUint8(18) & 0x2) > 0;
		state.isVolPlusDown = (data.getUint8(18) & 0x10) > 0;
		state.isVolMinusDown = (data.getUint8(18) & 0x8) > 0;

		state.time = ((data.getUint8(0) & 0xFF) << 1 | (data.getUint8(1) & 0x80) >> 7);

		state.seq = (data.getUint8(1) & 0x7C) >> 2;

		state.xOri = (data.getUint8(1) & 0x03) << 11 | (data.getUint8(2) & 0xFF) << 3 | (data.getUint8(3) & 0x80) >> 5;
		state.xOri = (state.xOri << 19) >> 19;
		state.xOri *= (2 * Math.PI / 4095.0);

		state.yOri = (data.getUint8(3) & 0x1F) << 8 | (data.getUint8(4) & 0xFF);
		state.yOri = (state.yOri << 19) >> 19;
		state.yOri *= (2 * Math.PI / 4095.0);

		state.zOri = (data.getUint8(5) & 0xFF) << 5 | (data.getUint8(6) & 0xF8) >> 3;
		state.zOri = (state.zOri << 19) >> 19;
		state.zOri *= (2 * Math.PI / 4095.0);

		state.xAcc = (data.getUint8(6) & 0x07) << 10 | (data.getUint8(7) & 0xFF) << 2 | (data.getUint8(8) & 0xC0) >> 6;
		state.xAcc = (state.xAcc << 19) >> 19;
		state.xAcc *= (8 * 9.8 / 4095.0);

		state.yAcc = (data.getUint8(8) & 0x3F) << 7 | (data.getUint8(9) & 0xFE) >>> 1;
		state.yAcc = (state.yAcc << 19) >> 19;
		state.yAcc *= (8 * 9.8 / 4095.0);

		state.zAcc = (data.getUint8(9) & 0x01) << 12 | (data.getUint8(10) & 0xFF) << 4 | (data.getUint8(11) & 0xF0) >> 4;
		state.zAcc = (state.zAcc << 19) >> 19;
		state.zAcc *= (8 * 9.8 / 4095.0);

		state.xGyro = ((data.getUint8(11) & 0x0F) << 9 | (data.getUint8(12) & 0xFF) << 1 | (data.getUint8(13) & 0x80) >> 7);
		state.xGyro = (state.xGyro << 19) >> 19;
		state.xGyro *= (2048 / 180 * Math.PI / 4095.0);

		state.yGyro = ((data.getUint8(13) & 0x7F) << 6 | (data.getUint8(14) & 0xFC) >> 2);
		state.yGyro = (state.yGyro << 19) >> 19;
		state.yGyro *= (2048 / 180 * Math.PI / 4095.0);

		state.zGyro = ((data.getUint8(14) & 0x03) << 11 | (data.getUint8(15) & 0xFF) << 3 | (data.getUint8(16) & 0xE0) >> 5);
		state.zGyro = (state.zGyro << 19) >> 19;
		state.zGyro *= (2048 / 180 * Math.PI / 4095.0);

		state.xTouch = ((data.getUint8(16) & 0x1F) << 3 | (data.getUint8(17) & 0xE0) >> 5) / 255.0;
		state.yTouch = ((data.getUint8(17) & 0x1F) << 3 | (data.getUint8(18) & 0xE0) >> 5) / 255.0;

		onStateChangeCallback( state );

	}

	function onStateChangeCallback() {}

	//

	return {
		connect: connect,
		onStateChange: function ( callback ) {
			onStateChangeCallback = callback;
		}
	}

}
<commit_msg>Always return a promise in connect<commit_after>/**
 * @author mrdoob / http://mrdoob.com/
 */

function DaydreamController() {

	var state = {};

	function connect() {

		navigator.bluetooth.requestDevice( {
			filters: [ {
				name: 'Daydream controller'
			} ],
			optionalServices: [ '0000fe55-0000-1000-8000-00805f9b34fb' ]
		} )
		.then( function ( device ) {
			return device.gatt.connect();
		} )
		.then( function ( server ) {
			return server.getPrimaryService( '0000fe55-0000-1000-8000-00805f9b34fb' );
		} )
		.then( function ( service ) {
			return service.getCharacteristic( '00000001-1000-1000-8000-00805f9b34fb' );
		} )
		.then( function ( characteristic ) {
			characteristic.addEventListener( 'characteristicvaluechanged', handleData );
			return characteristic.startNotifications();
		} )

	}

	function handleData( event ) {

		var data = event.target.value;

		// http://stackoverflow.com/questions/40730809/use-daydream-controller-on-hololens-or-outside-daydream/40753551#40753551

		state.isClickDown = (data.getUint8(18) & 0x1) > 0;
		state.isAppDown = (data.getUint8(18) & 0x4) > 0;
		state.isHomeDown = (data.getUint8(18) & 0x2) > 0;
		state.isVolPlusDown = (data.getUint8(18) & 0x10) > 0;
		state.isVolMinusDown = (data.getUint8(18) & 0x8) > 0;

		state.time = ((data.getUint8(0) & 0xFF) << 1 | (data.getUint8(1) & 0x80) >> 7);

		state.seq = (data.getUint8(1) & 0x7C) >> 2;

		state.xOri = (data.getUint8(1) & 0x03) << 11 | (data.getUint8(2) & 0xFF) << 3 | (data.getUint8(3) & 0x80) >> 5;
		state.xOri = (state.xOri << 19) >> 19;
		state.xOri *= (2 * Math.PI / 4095.0);

		state.yOri = (data.getUint8(3) & 0x1F) << 8 | (data.getUint8(4) & 0xFF);
		state.yOri = (state.yOri << 19) >> 19;
		state.yOri *= (2 * Math.PI / 4095.0);

		state.zOri = (data.getUint8(5) & 0xFF) << 5 | (data.getUint8(6) & 0xF8) >> 3;
		state.zOri = (state.zOri << 19) >> 19;
		state.zOri *= (2 * Math.PI / 4095.0);

		state.xAcc = (data.getUint8(6) & 0x07) << 10 | (data.getUint8(7) & 0xFF) << 2 | (data.getUint8(8) & 0xC0) >> 6;
		state.xAcc = (state.xAcc << 19) >> 19;
		state.xAcc *= (8 * 9.8 / 4095.0);

		state.yAcc = (data.getUint8(8) & 0x3F) << 7 | (data.getUint8(9) & 0xFE) >>> 1;
		state.yAcc = (state.yAcc << 19) >> 19;
		state.yAcc *= (8 * 9.8 / 4095.0);

		state.zAcc = (data.getUint8(9) & 0x01) << 12 | (data.getUint8(10) & 0xFF) << 4 | (data.getUint8(11) & 0xF0) >> 4;
		state.zAcc = (state.zAcc << 19) >> 19;
		state.zAcc *= (8 * 9.8 / 4095.0);

		state.xGyro = ((data.getUint8(11) & 0x0F) << 9 | (data.getUint8(12) & 0xFF) << 1 | (data.getUint8(13) & 0x80) >> 7);
		state.xGyro = (state.xGyro << 19) >> 19;
		state.xGyro *= (2048 / 180 * Math.PI / 4095.0);

		state.yGyro = ((data.getUint8(13) & 0x7F) << 6 | (data.getUint8(14) & 0xFC) >> 2);
		state.yGyro = (state.yGyro << 19) >> 19;
		state.yGyro *= (2048 / 180 * Math.PI / 4095.0);

		state.zGyro = ((data.getUint8(14) & 0x03) << 11 | (data.getUint8(15) & 0xFF) << 3 | (data.getUint8(16) & 0xE0) >> 5);
		state.zGyro = (state.zGyro << 19) >> 19;
		state.zGyro *= (2048 / 180 * Math.PI / 4095.0);

		state.xTouch = ((data.getUint8(16) & 0x1F) << 3 | (data.getUint8(17) & 0xE0) >> 5) / 255.0;
		state.yTouch = ((data.getUint8(17) & 0x1F) << 3 | (data.getUint8(18) & 0xE0) >> 5) / 255.0;

		onStateChangeCallback( state );

	}

	function onStateChangeCallback() {}

	//

	return {
		connect: connect,
		onStateChange: function ( callback ) {
			onStateChangeCallback = callback;
		}
	}

}
<|endoftext|>


<commit_before><commit_msg>Remove the on_dom_loaded handler on DOMContentLoaded event.<commit_after><|endoftext|>


<commit_before><commit_msg>tweak<commit_after><|endoftext|>