<commit_before>// Copyright (c) 2012-2014 Heapsource.com and Contributors - http://www.heapsource.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
var winston = require('winston');
var util = require('util');
var chalk = require('chalk');

//Allow this file to get an exclusive copy of underscore so it can change the template settings without affecting others
delete require.cache[require.resolve('lodash')];
var _ = require('lodash');
delete require.cache[require.resolve('lodash')];

/**
 * A default list of properties in the request object that are allowed to be logged.
 * These properties will be safely included in the meta of the log.
 * 'body' is not included in this list because it can contains passwords and stuff that are sensitive for logging.
 * TODO: Include 'body' and get the defaultRequestFilter to filter the inner properties like 'password' or 'password_confirmation', etc. Pull requests anyone?
 * @type {Array}
 */
var requestWhitelist = ['url', 'headers', 'method', 'httpVersion', 'originalUrl', 'query'];

/**
 * A default list of properties in the request body that are allowed to be logged.
 * This will normally be empty here, since it should be done at the route level.
 * @type {Array}
 */
var bodyWhitelist = [];

/**
 * A default list of properties in the request body that are not allowed to be logged.
 * @type {Array}
 */
var bodyBlacklist = [];

/**
 * A default list of properties in the response object that are allowed to be logged.
 * These properties will be safely included in the meta of the log.
 * @type {Array}
 */
var responseWhitelist = ['statusCode'];

/**
 * A list of request routes that will be skipped instead of being logged. This would be useful if routes for health checks or pings would otherwise pollute
 * your log files.
 * @type {Array}
 */
var ignoredRoutes = [];

/**
 * A default function to filter the properties of the req object.
 * @param req
 * @param propName
 * @return {*}
 */
var defaultRequestFilter = function (req, propName) {
    return _.result(req, propName);
};

/**
 * A default function to filter the properties of the res object.
 * @param res
 * @param propName
 * @return {*}
 */
var defaultResponseFilter = function (res, propName) {
    return _.result(res, propName);
};

/**
 * A default function to decide whether skip logging of particular request. Doesn't skip anything (i.e. log all requests).
 * @return always false
 */
var defaultSkip = function() {
  return false;
};

function filterObject(originalObj, whiteList, initialFilter) {
    var obj = {};
    var fieldsSet = false;

    [].concat(whiteList).forEach(function (propName) {
        var value = initialFilter(originalObj, propName);

        if(typeof (value) !== 'undefined') {
            _.set(obj, propName, value);
            fieldsSet = true;
        };
    });

    return fieldsSet ? obj : undefined;
}

//
// ### function errorLogger(options)
// #### @options {Object} options to initialize the middleware.
//

function errorLogger(options) {

    ensureValidOptions(options);

    options.requestFilter = options.requestFilter || defaultRequestFilter;
    options.winstonInstance = options.winstonInstance || (new winston.Logger ({ transports: options.transports }));

    return function (err, req, res, next) {

        // Let winston gather all the error data.
        var exceptionMeta = winston.exception.getAllInfo(err);
        exceptionMeta.req = filterObject(req, requestWhitelist, options.requestFilter);

        // This is fire and forget, we don't want logging to hold up the request so don't wait for the callback
        options.winstonInstance.log('error', 'middlewareError', exceptionMeta);

        next(err);
    };
}

//
// ### function logger(options)
// #### @options {Object} options to initialize the middleware.
//

function logger(options) {

    ensureValidOptions(options);
    ensureValidLoggerOptions(options);

    options.requestFilter = options.requestFilter || defaultRequestFilter;
    options.responseFilter = options.responseFilter || defaultResponseFilter;
    options.winstonInstance = options.winstonInstance || (new winston.Logger ({ transports: options.transports }));
    options.level = options.level || "info";
    options.statusLevels = options.statusLevels || false;
    options.msg = options.msg || "HTTP {{req.method}} {{req.url}}";
    options.colorStatus = options.colorStatus || false;
    options.expressFormat = options.expressFormat || false;
    options.ignoreRoute = options.ignoreRoute || function () { return false; };
    options.skip = options.skip || defaultSkip;

    // Using mustache style templating
    var template = _.template(options.msg, null, {
      interpolate: /\{\{(.+?)\}\}/g
    });

    return function (req, res, next) {
        var currentUrl = req.originalUrl || req.url;
        if (currentUrl && _.contains(ignoredRoutes, currentUrl)) return next();

        req._startTime = (new Date);

        req._routeWhitelists = {
            req: [],
            res: [],
            body: []
        };

        req._routeBlacklists = {
            body: []
        };

        // Manage to get information from the response too, just like Connect.logger does:
        var end = res.end;
        res.end = function(chunk, encoding) {
            res.responseTime = (new Date) - req._startTime;

            res.end = end;
            res.end(chunk, encoding);

            req.url = req.originalUrl || req.url;

            if (options.statusLevels) {
              if (res.statusCode >= 100) { options.level = "info"; }
              if (res.statusCode >= 400) { options.level = "warn"; }
              if (res.statusCode >= 500) { options.level = "error"; }
            };

            if (options.colorStatus || options.expressFormat) {
              // Palette from https://github.com/expressjs/morgan/blob/master/index.js#L205
              var statusColor = 'green';
              if (res.statusCode >= 500) statusColor = 'red';
              else if (res.statusCode >= 400) statusColor = 'yellow';
              else if (res.statusCode >= 300) statusColor = 'cyan';
              var coloredStatusCode = chalk[statusColor](res.statusCode);
            }

            var meta = {};

            if(options.meta !== false) {
              var bodyWhitelist, blacklist;

              requestWhitelist = requestWhitelist.concat(req._routeWhitelists.req || []);
              responseWhitelist = responseWhitelist.concat(req._routeWhitelists.res || []);

              meta.req = filterObject(req, requestWhitelist, options.requestFilter);
              meta.res = filterObject(res, responseWhitelist, options.responseFilter);

              if (_.contains(responseWhitelist, 'body')) {
                if (chunk) {
                  var isJson = (res._headers && res._headers['content-type']
                    && res._headers['content-type'].indexOf('json') >= 0);

                  meta.res.body =  isJson ? JSON.parse(chunk) : chunk.toString();
                }
              }

              bodyWhitelist = req._routeWhitelists.body || [];
              blacklist = _.union(bodyBlacklist, (req._routeBlacklists.body || []));

              var filteredBody = null;

              if ( req.body !== undefined ) {
                  if (blacklist.length > 0 && bodyWhitelist.length === 0) {
                    var whitelist = _.difference(_.keys(req.body), blacklist);
                    filteredBody = filterObject(req.body, whitelist, options.requestFilter);
                  } else {
                    filteredBody = filterObject(req.body, bodyWhitelist, options.requestFilter);
                  }
              }

              if (filteredBody) meta.req.body = filteredBody;

              meta.responseTime = res.responseTime;
            }

            if(options.expressFormat) {
              var msg = chalk.grey(req.method + " " + req.url || req.url)
                + " " + chalk[statusColor](res.statusCode)
                + " " + chalk.grey(res.responseTime+"ms");
            } else {
              var msg = template({req: req, res: res});
            }
            // This is fire and forget, we don't want logging to hold up the request so don't wait for the callback
            if (!options.skip(req, res) && !options.ignoreRoute(req, res)) {
              options.winstonInstance.log(options.level, msg, meta);
            }
        };

        next();
    };
}

function ensureValidOptions(options) {
    if(!options) throw new Error("options are required by express-winston middleware");
    if(!((options.transports && (options.transports.length > 0)) || options.winstonInstance))
        throw new Error("transports or a winstonInstance are required by express-winston middleware");
}

function ensureValidLoggerOptions(options) {
    if (options.ignoreRoute && !_.isFunction(options.ignoreRoute)) {
        throw new Error("`ignoreRoute` express-winston option should be a function");
    }
}

module.exports.errorLogger = errorLogger;
module.exports.logger = logger;
module.exports.requestWhitelist = requestWhitelist;
module.exports.bodyWhitelist = bodyWhitelist;
module.exports.bodyBlacklist = bodyBlacklist;
module.exports.responseWhitelist = responseWhitelist;
module.exports.defaultRequestFilter = defaultRequestFilter;
module.exports.defaultResponseFilter = defaultResponseFilter;
module.exports.defaultSkip = defaultSkip;
module.exports.ignoredRoutes = ignoredRoutes;
<commit_msg>add filtered response object to error message (keeps logging items consistent)<commit_after>// Copyright (c) 2012-2014 Heapsource.com and Contributors - http://www.heapsource.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
var winston = require('winston');
var util = require('util');
var chalk = require('chalk');

//Allow this file to get an exclusive copy of underscore so it can change the template settings without affecting others
delete require.cache[require.resolve('lodash')];
var _ = require('lodash');
delete require.cache[require.resolve('lodash')];

/**
 * A default list of properties in the request object that are allowed to be logged.
 * These properties will be safely included in the meta of the log.
 * 'body' is not included in this list because it can contains passwords and stuff that are sensitive for logging.
 * TODO: Include 'body' and get the defaultRequestFilter to filter the inner properties like 'password' or 'password_confirmation', etc. Pull requests anyone?
 * @type {Array}
 */
var requestWhitelist = ['url', 'headers', 'method', 'httpVersion', 'originalUrl', 'query'];

/**
 * A default list of properties in the request body that are allowed to be logged.
 * This will normally be empty here, since it should be done at the route level.
 * @type {Array}
 */
var bodyWhitelist = [];

/**
 * A default list of properties in the request body that are not allowed to be logged.
 * @type {Array}
 */
var bodyBlacklist = [];

/**
 * A default list of properties in the response object that are allowed to be logged.
 * These properties will be safely included in the meta of the log.
 * @type {Array}
 */
var responseWhitelist = ['statusCode'];

/**
 * A list of request routes that will be skipped instead of being logged. This would be useful if routes for health checks or pings would otherwise pollute
 * your log files.
 * @type {Array}
 */
var ignoredRoutes = [];

/**
 * A default function to filter the properties of the req object.
 * @param req
 * @param propName
 * @return {*}
 */
var defaultRequestFilter = function (req, propName) {
    return _.result(req, propName);
};

/**
 * A default function to filter the properties of the res object.
 * @param res
 * @param propName
 * @return {*}
 */
var defaultResponseFilter = function (res, propName) {
    return _.result(res, propName);
};

/**
 * A default function to decide whether skip logging of particular request. Doesn't skip anything (i.e. log all requests).
 * @return always false
 */
var defaultSkip = function() {
  return false;
};

function filterObject(originalObj, whiteList, initialFilter) {
    var obj = {};
    var fieldsSet = false;

    [].concat(whiteList).forEach(function (propName) {
        var value = initialFilter(originalObj, propName);

        if(typeof (value) !== 'undefined') {
            _.set(obj, propName, value);
            fieldsSet = true;
        };
    });

    return fieldsSet ? obj : undefined;
}

//
// ### function errorLogger(options)
// #### @options {Object} options to initialize the middleware.
//

function errorLogger(options) {

    ensureValidOptions(options);

    options.requestFilter = options.requestFilter || defaultRequestFilter;
    options.responseFilter = options.responseFilter || defaultResponseFilter;
    options.winstonInstance = options.winstonInstance || (new winston.Logger ({ transports: options.transports }));

    return function (err, req, res, next) {

        // Let winston gather all the error data.
        var exceptionMeta = winston.exception.getAllInfo(err);
        exceptionMeta.req = filterObject(req, requestWhitelist, options.requestFilter);
        var end = res.end;
        res.end = function(chunk, encoding) {
            res.end = end;
            res.end(chunk, encoding);

            exceptionMeta.res = filterObject(res, responseWhitelist, options.responseFilter);
            // This is fire and forget, we don't want logging to hold up the request so don't wait for the callback
            options.winstonInstance.log('error', 'middlewareError', exceptionMeta);
        }

        next(err);
    };
}

//
// ### function logger(options)
// #### @options {Object} options to initialize the middleware.
//

function logger(options) {

    ensureValidOptions(options);
    ensureValidLoggerOptions(options);

    options.requestFilter = options.requestFilter || defaultRequestFilter;
    options.responseFilter = options.responseFilter || defaultResponseFilter;
    options.winstonInstance = options.winstonInstance || (new winston.Logger ({ transports: options.transports }));
    options.level = options.level || "info";
    options.statusLevels = options.statusLevels || false;
    options.msg = options.msg || "HTTP {{req.method}} {{req.url}}";
    options.colorStatus = options.colorStatus || false;
    options.expressFormat = options.expressFormat || false;
    options.ignoreRoute = options.ignoreRoute || function () { return false; };
    options.skip = options.skip || defaultSkip;

    // Using mustache style templating
    var template = _.template(options.msg, null, {
      interpolate: /\{\{(.+?)\}\}/g
    });

    return function (req, res, next) {
        var currentUrl = req.originalUrl || req.url;
        if (currentUrl && _.contains(ignoredRoutes, currentUrl)) return next();

        req._startTime = (new Date);

        req._routeWhitelists = {
            req: [],
            res: [],
            body: []
        };

        req._routeBlacklists = {
            body: []
        };

        // Manage to get information from the response too, just like Connect.logger does:
        var end = res.end;
        res.end = function(chunk, encoding) {
            res.responseTime = (new Date) - req._startTime;

            res.end = end;
            res.end(chunk, encoding);

            req.url = req.originalUrl || req.url;

            if (options.statusLevels) {
              if (res.statusCode >= 100) { options.level = "info"; }
              if (res.statusCode >= 400) { options.level = "warn"; }
              if (res.statusCode >= 500) { options.level = "error"; }
            };

            if (options.colorStatus || options.expressFormat) {
              // Palette from https://github.com/expressjs/morgan/blob/master/index.js#L205
              var statusColor = 'green';
              if (res.statusCode >= 500) statusColor = 'red';
              else if (res.statusCode >= 400) statusColor = 'yellow';
              else if (res.statusCode >= 300) statusColor = 'cyan';
              var coloredStatusCode = chalk[statusColor](res.statusCode);
            }

            var meta = {};

            if(options.meta !== false) {
              var bodyWhitelist, blacklist;

              requestWhitelist = requestWhitelist.concat(req._routeWhitelists.req || []);
              responseWhitelist = responseWhitelist.concat(req._routeWhitelists.res || []);

              meta.req = filterObject(req, requestWhitelist, options.requestFilter);
              meta.res = filterObject(res, responseWhitelist, options.responseFilter);

              if (_.contains(responseWhitelist, 'body')) {
                if (chunk) {
                  var isJson = (res._headers && res._headers['content-type']
                    && res._headers['content-type'].indexOf('json') >= 0);

                  meta.res.body =  isJson ? JSON.parse(chunk) : chunk.toString();
                }
              }

              bodyWhitelist = req._routeWhitelists.body || [];
              blacklist = _.union(bodyBlacklist, (req._routeBlacklists.body || []));

              var filteredBody = null;

              if ( req.body !== undefined ) {
                  if (blacklist.length > 0 && bodyWhitelist.length === 0) {
                    var whitelist = _.difference(_.keys(req.body), blacklist);
                    filteredBody = filterObject(req.body, whitelist, options.requestFilter);
                  } else {
                    filteredBody = filterObject(req.body, bodyWhitelist, options.requestFilter);
                  }
              }

              if (filteredBody) meta.req.body = filteredBody;

              meta.responseTime = res.responseTime;
            }

            if(options.expressFormat) {
              var msg = chalk.grey(req.method + " " + req.url || req.url)
                + " " + chalk[statusColor](res.statusCode)
                + " " + chalk.grey(res.responseTime+"ms");
            } else {
              var msg = template({req: req, res: res});
            }
            // This is fire and forget, we don't want logging to hold up the request so don't wait for the callback
            if (!options.skip(req, res) && !options.ignoreRoute(req, res)) {
              options.winstonInstance.log(options.level, msg, meta);
            }
        };

        next();
    };
}

function ensureValidOptions(options) {
    if(!options) throw new Error("options are required by express-winston middleware");
    if(!((options.transports && (options.transports.length > 0)) || options.winstonInstance))
        throw new Error("transports or a winstonInstance are required by express-winston middleware");
}

function ensureValidLoggerOptions(options) {
    if (options.ignoreRoute && !_.isFunction(options.ignoreRoute)) {
        throw new Error("`ignoreRoute` express-winston option should be a function");
    }
}

module.exports.errorLogger = errorLogger;
module.exports.logger = logger;
module.exports.requestWhitelist = requestWhitelist;
module.exports.bodyWhitelist = bodyWhitelist;
module.exports.bodyBlacklist = bodyBlacklist;
module.exports.responseWhitelist = responseWhitelist;
module.exports.defaultRequestFilter = defaultRequestFilter;
module.exports.defaultResponseFilter = defaultResponseFilter;
module.exports.defaultSkip = defaultSkip;
module.exports.ignoredRoutes = ignoredRoutes;
<|endoftext|>


<commit_before>/*
* Name : index.js
* Module : Back-end::Lib
* Location : /lib/
*
* History :
*
* Version         Date           Programmer
* =================================================
* 0.0.1          2014-03-01     Gianluca Donato
* -------------------------------------------------
* Codifica modulo.
* =================================================
*/
'use strict';

var express = require('express');
var mongoose = require('mongoose');
var usermodel = require('./model/UserModel');
var middleware = require("./controller/middleware");
var MongoStore = require('connect-mongo')(express);
var createSuperAdmins = require("./utils/CreateSuperAdmins");

var initDB = function(app) {
	var config = app.config;
	app.db = {};

	// Connette a DB utenti
	app.db.user = mongoose.createConnection("mongodb://" + config.userDB.url);
	app.db.user.on("error", function(err) {
		console.error(err);
		console.error("Check if your mongodb Users database is running at " + config.userDB.url);
	});
	app.db.user.on('open', function (ref) {
		console.log('Users database connected.');
	});
	usermodel.init(app);

	// Connette a DB dati
	app.db.data = mongoose.createConnection("mongodb://" + config.dataDB.url);
	app.db.data.on("error", function(err) {
		console.error(err);
		console.error("Check if your mongodb Data database is running at " + config.dataDB.url);
	});
	app.db.data.on('open', function (ref) {
		console.log('Data database connected.');
	});
};

var initApp = function(app)  {
	var config = app.config;

	if (config.env === "development") {
		app.use(express.logger());
	}

	app.use(express.json());
	app.use(express.urlencoded());
	app.use(express.methodOverride());
	app.use(express.cookieParser("y0ur $3cret h3re"));
	app.use(express.session({
		secret: "y0ur $3cret h3re",
		store: new MongoStore({
			url: "mongodb://" + config.userDB.url,
			maxAge: 2 * 7 * 24 * 3600 * 1000
		})
	}));

	if (config.webServer && config.webServer.static) {
		app.use(express.static(config.webServer.static));
	}

	middleware.init(app);
};

var initSuperAdmins = function(app) {
	createSuperAdmins(
		app.config.superAdmins,
		app.db.user.model("users")
	);
};

var start = function(config)  {
	var app = express();
	app.config = config;
	initDB(app);
	initSuperAdmins(app);
	initApp(app);

	process.on('uncaughtException', function(err) {
		console.error("/!\\ Caught exception:", err);
	});

	console.log("Starting app.listen...");
	app.listen(config.webServer.port);
};

exports.initDB = initDB;
exports.initApp = initApp;
exports.start = start;
<commit_msg>Export DSLEngine when require package<commit_after>/**
 * @author Andrea Mantovani
 * @license MIT
 */

'use strict'

module.exports = require("./src/dslEngine.js");<|endoftext|>


<commit_before>'use strict';

const app = require('app');
const BrowserWindow = require('browser-window');
const Menu = require('menu');

// report crashes to the Electron project
require('crash-reporter').start();

// adds debug features like hotkeys for triggering dev tools and reload
require('electron-debug')();

function createMainWindow () {
	const win = new BrowserWindow({
		width: 800,
		height: 600,
		resizable: true,
		center: true,
		show: false,
		'skip-taskbar': true
	});

	win.loadUrl(`http://devdocs.io/`);
	win.on('closed', onClosed);

	return win;
}

function toggleWindow() {
	mainWindow[mainWindow.isVisible() ? 'hide' : 'show']();
}

function onClosed() {
	// deref the window
	// for multiple windows store them in an array
	mainWindow = null;
}

// prevent window being GC'd
let mainWindow;

app.on('window-all-closed', function () {
	if (process.platform !== 'darwin') {
		app.quit();
	}
});

app.on('activate-with-no-open-windows', function () {
	if (!mainWindow) {
		mainWindow = createMainWindow();
	}
});

app.on('ready', function () {
	var template = [{
		label: 'Devdocs',
    submenu: [{
		  label: 'Hide Electron',
		  accelerator: 'Esc',
		  selector: 'hide:'
		}]
	}];

	var menu = Menu.buildFromTemplate(template);
  Menu.setApplicationMenu(menu);

	mainWindow = createMainWindow();

	// Register shortcut
	var globalShortcut = require('global-shortcut');
	globalShortcut.register('CommandOrControl+/', toggleWindow);
});

app.on('will-quit', function () {
	globalShortcut.unregisterAll();
})
<commit_msg>Change the way of display browser<commit_after>'use strict';

const app = require('app');
const BrowserWindow = require('browser-window');
const Menu = require('menu');

// report crashes to the Electron project
require('crash-reporter').start();

// adds debug features like hotkeys for triggering dev tools and reload
require('electron-debug')();

function createMainWindow () {
	const win = new BrowserWindow({
		width: 800,
		height: 600,
		resizable: true,
		center: true,
		show: false,
		'skip-taskbar': true
	});

	win.loadUrl(`http://devdocs.io/`);
	win.on('closed', onClosed);

	return win;
}

function toggleWindow() {
	mainWindow[mainWindow.isVisible() ? 'minimize' : 'restore']();
}

function onClosed() {
	// deref the window
	// for multiple windows store them in an array
	mainWindow = null;
}

// prevent window being GC'd
let mainWindow;

app.on('window-all-closed', function () {
	if (process.platform !== 'darwin') {
		app.quit();
	}
});

app.on('activate-with-no-open-windows', function () {
	if (!mainWindow) {
		mainWindow = createMainWindow();
	}
});

app.on('ready', function () {
	var template = [{
		label: 'Devdocs',
    submenu: [{
		  label: 'Hide Electron',
		  accelerator: 'Esc',
		  selector: 'hide:'
		}]
	}];

	var menu = Menu.buildFromTemplate(template);
  Menu.setApplicationMenu(menu);

	mainWindow = createMainWindow();

	// Register shortcut
	var globalShortcut = require('global-shortcut');
	globalShortcut.register('CommandOrControl+?', toggleWindow);
});

app.on('will-quit', function () {
	globalShortcut.unregisterAll();
})
<|endoftext|>


<commit_before>'use strict';

var TweetStream = require('node-tweet-stream'),
    http = require('http'),
    express = require('express'),
    socketIO = require('socket.io'),
    config = require('./config.json');

var app = express(),
    server = http.Server(app),
    io = socketIO(server),
    twitter = new TweetStream(config);

// What keywords to track
[
    'JavaSript',
    'node.js',
    'nodejs',
    'python'
].forEach(function(keyword) {
    twitter.track(keyword);
});

twitter.on('tweet', function(tweet) {
    if (tweet.lang !== 'en') {
        return;
    }

    io.emit('tweet', {
        'user': {
            'name': tweet.user.name,
            'screenName': tweet.user.screen_name,
            'backgroundColor': tweet.user.profile_background_color,
            'profileImage': tweet.user.profile_image_url
        },
        'text': tweet.text,
        'createdAt': tweet.created_at
    });
});

app.use(express.static(__dirname + '/public'));

app.get('/', function(req, res) {
    res.sendFile(__dirname + '/public/index.html');
});

http.listen(3000, console.log('listening on *:3000'));
<commit_msg>Wait for server to start before informing user about server status<commit_after>'use strict';

var TweetStream = require('node-tweet-stream'),
    http = require('http'),
    express = require('express'),
    socketIO = require('socket.io'),
    config = require('./config.json');

var app = express(),
    server = http.Server(app),
    io = socketIO(server),
    twitter = new TweetStream(config);

// What keywords to track
[
    'JavaSript',
    'node.js',
    'nodejs',
    'python'
].forEach(function(keyword) {
    twitter.track(keyword);
});

twitter.on('tweet', function(tweet) {
    if (tweet.lang !== 'en') {
        return;
    }

    io.emit('tweet', {
        'user': {
            'name': tweet.user.name,
            'screenName': tweet.user.screen_name,
            'backgroundColor': tweet.user.profile_background_color,
            'profileImage': tweet.user.profile_image_url
        },
        'text': tweet.text,
        'createdAt': tweet.created_at
    });
});

app.use(express.static(__dirname + '/public'));

app.get('/', function(req, res) {
    res.sendFile(__dirname + '/public/index.html');
});

server.listen(3000, function() {
    console.log('listening on *:3000');
});
<|endoftext|>


<commit_before>// Module by angleman, MIT
// Get Redshift / postgres schema for a table

function Module(client) {
	self = this

	function query(tablename, fields, callback) {
		fields = (typeof fields == 'string') ? fields : fields.join(',')
		client.query('SELECT ' + fields + ' FROM information_schema.columns WHERE table_name ="' + tablename + '"', callback)
	}

	self.get = function(tablename, callback) {
		query(tablename, 'column_name, data_type, character_maximum_length', callback)
	}

	self.getColumns = function(tablename, callback) {
		query(tablename, 'column_name', callback)
	}
	return this
}

module.exports = Module<commit_msg>fillout features<commit_after>// Module by angleman, MIT
// Get Redshift / postgres schema for a table

function Module(client) {
	self = this

	function query(tablename, fields, callback) {
		fields = (typeof fields == 'string') ? fields : fields.join(',')
		qry    = 'SELECT ' + fields + " FROM information_schema.columns WHERE table_name='" + tablename + "'"
		client.query(qry, callback)
	}

	self.get = function(tablename, callback) {
		function extractColumns(err, result) {
			if (result && result.rows) {
				rows = result.rows
				result = []
				for (i = 0; i < rows.length; i++) {
					row = rows[i]
					type = row['data_type']
					switch (type) {
					case 'character varying': type = 'varchar'; break
					case 'character':         type = 'char';    break
					case 'double precision':  type = 'float';   break
					default:
						type = row['data_type'].split(' ')[0]
					}
					json = '{"'+row['column_name'] + '": "' + type + '"}'
					row  = JSON.parse(json)
					result.push(row)
				}
			}
			callback(err, result)
		}
		query(tablename, 'column_name, data_type, character_maximum_length', extractColumns)
	}

	self.getCreateTypes = function(tablename, callback) {
		function extractColumns(err, result) {
			if (result && result.rows) {
				rows = result.rows
				result = []
				for (i = 0; i < rows.length; i++) {
					row = rows[i]
					type = row['data_type']
					switch (type) {
					case 'character varying': type = 'varchar(' + row['character_maximum_length'] + ')'; break
					case 'character':         type = 'char(' + row['character_maximum_length'] + ')';    break
					case 'double precision':  type = 'float';   break
					default:
						type = row['data_type'].split(' ')[0]
					}
					json = '{"'+row['column_name'] + '": "' + type + '"}'
					row  = JSON.parse(json)
					result.push(row)
				}
			}
			callback(err, result)
		}
		query(tablename, 'column_name, data_type, character_maximum_length', extractColumns)
	}

	self.getColumns = function(tablename, callback) {
		function extractColumns(err, result) {
			if (result && result.rows) {
				rows = result.rows
				result = []
				for (i = 0; i < rows.length; i++) {
					row = rows[i]
					result.push(row['column_name'])
				}
			}
			callback(err, result)
		}
		query(tablename, 'column_name', extractColumns)
	}

	return this
}

module.exports = Module<|endoftext|>


<commit_before>function WindowPage() {
	var inst = window.Page;
	if (inst) {
		// because using instanceof requires reference to the same WindowPage
		if (inst.name == "WindowPage") return inst;
	}
	this.name = "WindowPage";

	var QueryString = require('query-string');

	this.parse = function(str) {
		var obj = new URL(str || "", document.location.toString());
		obj.query = QueryString.parse(obj.search);
		return obj;
	}.bind(this);
	this.format = function(obj) {
		var search = QueryString.stringify(obj.query);
		var nobj = obj;
		if (!(obj instanceof window.URL)) {
			nobj = this.parse(obj.path);
			if (!obj.path) {
				if (obj.pathname) nobj.pathname = obj.pathname;
				if (obj.search && obj.search != "?") nobj.search = obj.search;
				if (obj.hash && obj.hash != "#") nobj.hash = obj.hash;
			}
			if (obj.port && obj.port != 80) nobj.port = obj.port;
			if (obj.hostname) nobj.hostname = obj.hostname;
			if (obj.protocol) nobj.protocol = obj.protocol;
		}
		if (search) nobj.search = search;
		else if (obj.query) delete nobj.search;
		return nobj.toString();
	};

	this.reset();

	this.historyListener = this.historyListener.bind(this);
	window.addEventListener('popstate', this.historyListener);

	this.route = this.chainThenable.bind(this, "route");
	this.build = this.chainThenable.bind(this, "build");
	this.handle = this.chainThenable.bind(this, "handle");

	this.importDocument = this.importDocument.bind(this);

	this.waitUiReady = this.waitUiReady.bind(this);

	var page = 	this.parse("");
	page.stage = this.stage();
	if (page.stage == "build") page.imported = true;
	this.run(page);
}

WindowPage.prototype.run = function(page) {
	var pageUrl = this.format(page);
	var self = this;
	return this.waitReady().then(function() {
		if (!page.imported) {
			return self.runChain('route', page);
		}
	}).then(function() {
		if (!page.imported && page.document) {
			self.reset();
			page.updating = false;
			return self.importDocument(page.document).then(function() {
				page.imported = true;
			});
		}
	}).then(function() {
		if (page.stage != "build") {
			// always run except if the document has just been opened in a build stage
			return self.runChain('build', page);
		}
	}).then(function() {
		return self.waitUiReady(page).then(function() {
			return self.runChain('handle', page);
		});
	}).then(function() {
		self.url = self.format(page);
		page.updating = true;
	});
};

WindowPage.prototype.reset = function() {
	this.chains = {
		route: {thenables: []},
		build: {thenables: []},
		handle: {thenables: []}
	};
};

WindowPage.prototype.runChain = function(stage, page) {
	page.stage = stage;
	this.stage(stage);
	var chain = this.chains[stage];
	chain.promise = this.allFn(page, chain.thenables);
	return chain.promise.then(function() {
		return page;
	});
};

WindowPage.prototype.chainThenable = function(stage, fn) {
	var chain = this.chains[stage];
	chain.thenables.push(fn);
	if (chain.promise && this.stage() == stage) {
		chain.promise = this.oneFn(chain.promise, fn);
	}
	return this;
};

WindowPage.prototype.catcher = function(phase, err, fn) {
	console.error("Uncaught error during", phase, err, fn);
};

WindowPage.prototype.oneFn = function(p, fn) {
	var catcher = this.catcher.bind(this);
	return p.then(function(page) {
		return Promise.resolve(page).then(fn).catch(function(err) {
			return catcher(page.stage, err, fn);
		}).then(function() {
			return page;
		});
	});
};

WindowPage.prototype.allFn = function(page, list) {
	var p = Promise.resolve(page);
	var self = this;
	list.forEach(function(fn) {
		p = self.oneFn(p, fn);
	});
	return p;
};

WindowPage.prototype.stage = function(name) {
	var root = document.documentElement;
	if (name === null) root.removeAttribute("stage");
	else if (name) root.setAttribute("stage", name);
	else name = root.getAttribute("stage");
	return name;
};

WindowPage.prototype.waitUiReady = function(page) {
	if (document.visibilityState == "prerender") {
		var solve, p = new Promise(function(resolve) { solve = resolve; });
		function vizListener() {
			document.removeEventListener('visibilitychange', vizListener, false);
			solve();
		}
		document.addEventListener('visibilitychange', vizListener, false);
		return p.then(waitImports);
	} else {
		return waitImports();
	}
	function waitImports() {
		var imports = Array.from(document.querySelectorAll('link[rel="import"]'));
		var polyfill = window.HTMLImports;
		var whenReady = (function() {
			var promise;
			return function() {
				if (!promise) promise = new Promise(function(resolve) {
					polyfill.whenReady(function() {
						setTimeout(resolve);
					});
				});
				return promise;
			};
		})();

		return Promise.all(imports.map(function(link) {
			if (link.import && link.import.readyState == "complete") {
				// no need to wait, wether native or polyfill
				return Promise.resolve();
			}
			if (polyfill) {
				// link.onload cannot be trusted
				return whenReady();
			}

			return new Promise(function(resolve, reject) {
				function loadListener() {
					link.removeEventListener('load', loadListener);
					resolve();
				}
				function errorListener() {
					link.removeEventListener('error', errorListener);
					resolve();
				}
				link.addEventListener('load', loadListener);
				link.addEventListener('error', errorListener);
			});
		})).then(function() {
			return page;
		});
	}
};

WindowPage.prototype.waitReady = function() {
	if (this.docReady) return Promise.resolve();
	var solve;
	var p = new Promise(function(resolve) {
		solve = resolve;
	});
	// https://github.com/jquery/jquery/issues/2100
	if (document.readyState == "complete" ||
		(document.readyState != "loading" && !document.documentElement.doScroll)) {
		this.docReady = true;
		setTimeout(solve);
		return p;
	}
	var self = this;
	function listener() {
		document.removeEventListener('DOMContentLoaded', listener);
		window.removeEventListener('load', listener);
		if (self.docReady) return;
		self.docReady = true;
		solve();
	}
	document.addEventListener('DOMContentLoaded', listener);
	window.addEventListener('load', listener);
	return p;
};

WindowPage.prototype.importDocument = function(doc) {
	var scripts = Array.from(doc.querySelectorAll('script')).map(function(node) {
		if (node.type && node.type != "text/javascript") return Promise.resolve({});
		// make sure script is not loaded when inserted into document
		node.type = "text/plain";
		// fetch script content ourselves
		if (node.src) return GET(node.src).then(function(txt) {
			return {src: node.src, txt: txt, node: node};
		}).catch(function(err) {
			console.error("Error loading", node.src, err);
			return {};
		});
		else return Promise.resolve({
			src: "inline", txt: node.textContent, node: node
		});
	});

	var imports = Array.from(doc.querySelectorAll('link[rel="import"]'));
	var cursor;
	imports.forEach(function(link) {
		if (!cursor) {
			cursor = doc.createTextNode("");
			link.parentNode.insertBefore(cursor, link);
		}
		link.remove();
	});

	var root = document.documentElement;
	if (doc.attributes) for (var i=0; i < doc.attributes.length; i++) {
		root.setAttribute(doc.attributes[i].name, doc.attributes[i].value);
	}
	root.replaceChild(document.adoptNode(doc.head), document.head);
	root.replaceChild(document.adoptNode(doc.body), document.body);

	// execute all scripts in their original order as soon as they loaded
	return scripts.reduce(function(sequence, scriptPromise) {
		return sequence.then(function() {
			return scriptPromise;
		}).then(function(obj) {
			if (!obj.txt) return;
			var script = document.createElement("script");
			script.textContent = obj.txt;
			document.head.appendChild(script).remove();
			obj.node.type = "text/javascript";
		});
	}, Promise.resolve()).then(function() {
		imports.forEach(function(link) {
			cursor.parentNode.insertBefore(link, cursor);
		});
	});
};

WindowPage.prototype.push = function(page) {
	return this.historyMethod('push', page);
};

WindowPage.prototype.replace = function(page) {
	return this.historyMethod('replace', page);
};

WindowPage.prototype.historyMethod = function(method, page) {
	var supported = !!window.history;
	if (supported) {
		if (!this.wroteState && method == "push") {
			var state = this.toState(page);
			state.href = document.location.toString();
			window.history.replaceState(state, document.title, state.href);
			this.wroteState = true;
		}
	}
	return this.run(page).then(function() {
		if (supported) {
			window.history[method + 'State'](this.toState(page), document.title, this.format(page));
		}
	}.bind(this));
};

WindowPage.prototype.toState = function(page) {
	return {
		html: page.document && page.document.documentElement.outerHTML,
		data: page.data,
		href: page.href
	};
};

WindowPage.prototype.fromState = function(state) {
	if (!state || !state.href) return;
	var page = this.parse(state.href);
	if (state.data) page.data = state.data;
	if (state.html) {
		var doc = document.implementation.createHTMLDocument("");
		doc.open();
		doc.write(state.html);
		doc.close();
		page.document = doc;
	} else {
		page.imported = true;
		page.updating = true;
	}
	return page;
};

WindowPage.prototype.historyListener = function(e) {
	var page = this.fromState(e.state);
	if (!page) return;
	this.run(page);
};

window.Page = new WindowPage();

<commit_msg>Page.format: just return what's been asked<commit_after>function WindowPage() {
	var inst = window.Page;
	if (inst) {
		// because using instanceof requires reference to the same WindowPage
		if (inst.name == "WindowPage") return inst;
	}
	this.name = "WindowPage";

	var QueryString = require('query-string');

	this.parse = function(str) {
		var obj = new URL(str || "", document.location.toString());
		obj.query = QueryString.parse(obj.search);
		return obj;
	}.bind(this);
	this.format = function(obj) {
		var search = QueryString.stringify(obj.query);
		var nobj = obj;
		if (!(obj instanceof window.URL)) {
			nobj = this.parse(obj.path);
			if (!obj.path) {
				if (obj.pathname) nobj.pathname = obj.pathname;
				if (obj.search && obj.search != "?") nobj.search = obj.search;
				if (obj.hash && obj.hash != "#") nobj.hash = obj.hash;
			}
			if (obj.port && obj.port != 80) nobj.port = obj.port;
			if (obj.hostname) nobj.hostname = obj.hostname;
			if (obj.protocol) nobj.protocol = obj.protocol;
		}
		if (search) nobj.search = search;
		else if (obj.query) delete nobj.search;
		if (!obj.hostname && !obj.protocol && !obj.port) {
			if (!obj.pathname) return nobj.search;
			else return nobj.pathname + nobj.search;
		} else {
			return nobj.toString();
		}
	};

	this.reset();

	this.historyListener = this.historyListener.bind(this);
	window.addEventListener('popstate', this.historyListener);

	this.route = this.chainThenable.bind(this, "route");
	this.build = this.chainThenable.bind(this, "build");
	this.handle = this.chainThenable.bind(this, "handle");

	this.importDocument = this.importDocument.bind(this);

	this.waitUiReady = this.waitUiReady.bind(this);

	var page = 	this.parse("");
	page.stage = this.stage();
	if (page.stage == "build") page.imported = true;
	this.run(page);
}

WindowPage.prototype.run = function(page) {
	var pageUrl = this.format(page);
	var self = this;
	return this.waitReady().then(function() {
		if (!page.imported) {
			return self.runChain('route', page);
		}
	}).then(function() {
		if (!page.imported && page.document) {
			self.reset();
			page.updating = false;
			return self.importDocument(page.document).then(function() {
				page.imported = true;
			});
		}
	}).then(function() {
		if (page.stage != "build") {
			// always run except if the document has just been opened in a build stage
			return self.runChain('build', page);
		}
	}).then(function() {
		return self.waitUiReady(page).then(function() {
			return self.runChain('handle', page);
		});
	}).then(function() {
		self.url = self.format(page);
		page.updating = true;
	});
};

WindowPage.prototype.reset = function() {
	this.chains = {
		route: {thenables: []},
		build: {thenables: []},
		handle: {thenables: []}
	};
};

WindowPage.prototype.runChain = function(stage, page) {
	page.stage = stage;
	this.stage(stage);
	var chain = this.chains[stage];
	chain.promise = this.allFn(page, chain.thenables);
	return chain.promise.then(function() {
		return page;
	});
};

WindowPage.prototype.chainThenable = function(stage, fn) {
	var chain = this.chains[stage];
	chain.thenables.push(fn);
	if (chain.promise && this.stage() == stage) {
		chain.promise = this.oneFn(chain.promise, fn);
	}
	return this;
};

WindowPage.prototype.catcher = function(phase, err, fn) {
	console.error("Uncaught error during", phase, err, fn);
};

WindowPage.prototype.oneFn = function(p, fn) {
	var catcher = this.catcher.bind(this);
	return p.then(function(page) {
		return Promise.resolve(page).then(fn).catch(function(err) {
			return catcher(page.stage, err, fn);
		}).then(function() {
			return page;
		});
	});
};

WindowPage.prototype.allFn = function(page, list) {
	var p = Promise.resolve(page);
	var self = this;
	list.forEach(function(fn) {
		p = self.oneFn(p, fn);
	});
	return p;
};

WindowPage.prototype.stage = function(name) {
	var root = document.documentElement;
	if (name === null) root.removeAttribute("stage");
	else if (name) root.setAttribute("stage", name);
	else name = root.getAttribute("stage");
	return name;
};

WindowPage.prototype.waitUiReady = function(page) {
	if (document.visibilityState == "prerender") {
		var solve, p = new Promise(function(resolve) { solve = resolve; });
		function vizListener() {
			document.removeEventListener('visibilitychange', vizListener, false);
			solve();
		}
		document.addEventListener('visibilitychange', vizListener, false);
		return p.then(waitImports);
	} else {
		return waitImports();
	}
	function waitImports() {
		var imports = Array.from(document.querySelectorAll('link[rel="import"]'));
		var polyfill = window.HTMLImports;
		var whenReady = (function() {
			var promise;
			return function() {
				if (!promise) promise = new Promise(function(resolve) {
					polyfill.whenReady(function() {
						setTimeout(resolve);
					});
				});
				return promise;
			};
		})();

		return Promise.all(imports.map(function(link) {
			if (link.import && link.import.readyState == "complete") {
				// no need to wait, wether native or polyfill
				return Promise.resolve();
			}
			if (polyfill) {
				// link.onload cannot be trusted
				return whenReady();
			}

			return new Promise(function(resolve, reject) {
				function loadListener() {
					link.removeEventListener('load', loadListener);
					resolve();
				}
				function errorListener() {
					link.removeEventListener('error', errorListener);
					resolve();
				}
				link.addEventListener('load', loadListener);
				link.addEventListener('error', errorListener);
			});
		})).then(function() {
			return page;
		});
	}
};

WindowPage.prototype.waitReady = function() {
	if (this.docReady) return Promise.resolve();
	var solve;
	var p = new Promise(function(resolve) {
		solve = resolve;
	});
	// https://github.com/jquery/jquery/issues/2100
	if (document.readyState == "complete" ||
		(document.readyState != "loading" && !document.documentElement.doScroll)) {
		this.docReady = true;
		setTimeout(solve);
		return p;
	}
	var self = this;
	function listener() {
		document.removeEventListener('DOMContentLoaded', listener);
		window.removeEventListener('load', listener);
		if (self.docReady) return;
		self.docReady = true;
		solve();
	}
	document.addEventListener('DOMContentLoaded', listener);
	window.addEventListener('load', listener);
	return p;
};

WindowPage.prototype.importDocument = function(doc) {
	var scripts = Array.from(doc.querySelectorAll('script')).map(function(node) {
		if (node.type && node.type != "text/javascript") return Promise.resolve({});
		// make sure script is not loaded when inserted into document
		node.type = "text/plain";
		// fetch script content ourselves
		if (node.src) return GET(node.src).then(function(txt) {
			return {src: node.src, txt: txt, node: node};
		}).catch(function(err) {
			console.error("Error loading", node.src, err);
			return {};
		});
		else return Promise.resolve({
			src: "inline", txt: node.textContent, node: node
		});
	});

	var imports = Array.from(doc.querySelectorAll('link[rel="import"]'));
	var cursor;
	imports.forEach(function(link) {
		if (!cursor) {
			cursor = doc.createTextNode("");
			link.parentNode.insertBefore(cursor, link);
		}
		link.remove();
	});

	var root = document.documentElement;
	if (doc.attributes) for (var i=0; i < doc.attributes.length; i++) {
		root.setAttribute(doc.attributes[i].name, doc.attributes[i].value);
	}
	root.replaceChild(document.adoptNode(doc.head), document.head);
	root.replaceChild(document.adoptNode(doc.body), document.body);

	// execute all scripts in their original order as soon as they loaded
	return scripts.reduce(function(sequence, scriptPromise) {
		return sequence.then(function() {
			return scriptPromise;
		}).then(function(obj) {
			if (!obj.txt) return;
			var script = document.createElement("script");
			script.textContent = obj.txt;
			document.head.appendChild(script).remove();
			obj.node.type = "text/javascript";
		});
	}, Promise.resolve()).then(function() {
		imports.forEach(function(link) {
			cursor.parentNode.insertBefore(link, cursor);
		});
	});
};

WindowPage.prototype.push = function(page) {
	return this.historyMethod('push', page);
};

WindowPage.prototype.replace = function(page) {
	return this.historyMethod('replace', page);
};

WindowPage.prototype.historyMethod = function(method, page) {
	var supported = !!window.history;
	if (supported) {
		if (!this.wroteState && method == "push") {
			var state = this.toState(page);
			state.href = document.location.toString();
			window.history.replaceState(state, document.title, state.href);
			this.wroteState = true;
		}
	}
	return this.run(page).then(function() {
		if (supported) {
			window.history[method + 'State'](this.toState(page), document.title, this.format(page));
		}
	}.bind(this));
};

WindowPage.prototype.toState = function(page) {
	return {
		html: page.document && page.document.documentElement.outerHTML,
		data: page.data,
		href: page.href
	};
};

WindowPage.prototype.fromState = function(state) {
	if (!state || !state.href) return;
	var page = this.parse(state.href);
	if (state.data) page.data = state.data;
	if (state.html) {
		var doc = document.implementation.createHTMLDocument("");
		doc.open();
		doc.write(state.html);
		doc.close();
		page.document = doc;
	} else {
		page.imported = true;
		page.updating = true;
	}
	return page;
};

WindowPage.prototype.historyListener = function(e) {
	var page = this.fromState(e.state);
	if (!page) return;
	this.run(page);
};

window.Page = new WindowPage();

<|endoftext|>


<commit_before>var rest = require('restler');

module.exports = {
  'gif': function(input, cb) {
    var self = this;
    var query = encodeURIComponent(input.parsed);
    var options = { rejectUnauthorized: false };
    var baseUrl = 'https://ticketap.com/rightgif'
    var url = baseUrl + '?text='+query
    rest.get(url, options).on('complete', function(data) {
      var img;
      if(data.gifs && data.gifs.length > 0) {
        img = self.chooseRandom(data.gifs).url;
      } else {
        img = data.url;
      }
      cb(null, 'word!  ' + img);
    });
  },
  'chooseRandom': function(gifs) {
    return gifs[Math.floor(Math.random() * gifs.length)];
  }
}<commit_msg>removed else statement that is impossible to get to using a test... :/<commit_after>var rest = require('restler');

module.exports = {
  'gif': function(input, cb) {
    var self = this;
    var query = encodeURIComponent(input.parsed);
    var options = { rejectUnauthorized: false };
    var baseUrl = 'https://ticketap.com/rightgif'
    var url = baseUrl + '?text='+query
    rest.get(url, options).on('complete', function(data) {
      var img = self.chooseRandom(data.gifs).url;
      cb(null, 'word!  ' + img);
    });
  },
  'chooseRandom': function(gifs) {
    return gifs[Math.floor(Math.random() * gifs.length)];
  }
}<|endoftext|>


<commit_before>module.exports = {
  extends: require.resolve('eslint-config-airbnb'),
  parser: 'babel-eslint',
  env: {
    browser: true,
    node: true,
    mocha: true,
  },
  ecmaFeatures: {
    experimentalObjectRestSpread: true,
  },
  plugins: [
    'jsx-a11y',
    'flowtype',
  ],
  rules: {
    'comma-dangle': ['error', 'always-multiline'],
    // write semicolons only if necessary, not always
    semi: [2, 'never'],
    // better readability for nested function calls
    'space-in-parens': 0,
    // to allow rest destructing with unused vars
    'no-unused-vars': ['warn', { vars: 'local', args: 'after-used' }],
    // better readability for props
    'react/jsx-curly-spacing': 0,
    // no error because of wrapper components
    'react/prop-types': 1,
    // render above everything-else
    'react/sort-comp': [1, {
      order: [
        'static-methods',
        'lifecycle',
        'render',
        'everything-else',
      ],
    }],

    'flowtype/define-flow-type': 1,
    'flowtype/require-parameter-type': 1,
    'flowtype/space-after-type-colon': [1, "always"],
    'flowtype/space-before-type-colon': [1, "never"],
    "flowtype/use-flow-type": 1,
  },
  'settings': {
    'flowtype': {
      'onlyFilesWithFlowAnnotation': true
    }
  }
}
<commit_msg>some rule adjustments<commit_after>module.exports = {
  extends: require.resolve('eslint-config-airbnb'),
  parser: 'babel-eslint',
  env: {
    browser: true,
    node: true,
    mocha: true,
  },
  ecmaFeatures: {
    experimentalObjectRestSpread: true,
  },
  plugins: [
    'jsx-a11y',
    'flowtype',
  ],
  rules: {
    'comma-dangle': ['error', 'always-multiline'],
    // write semicolons only if necessary, not always
    semi: [2, 'never'],
    // better readability for nested function calls
    'space-in-parens': 0,
    // to allow rest destructing with unused vars
    'no-unused-vars': ['warn', { vars: 'local', args: 'after-used' }],
    // to allow defining internal helper functions after the exported objects
    'no-use-before-define': 0,
    // better readability for props
    'react/jsx-curly-spacing': 0,
    // no error because of wrapper components
    'react/prop-types': 1,
    // allow reassigning a variable in the test of a while or do...while loop
    'no-cond-assign': ['error', 'except-parens'],
    // render above everything-else
    'react/sort-comp': [1, {
      order: [
        'static-methods',
        'lifecycle',
        'render',
        'everything-else',
      ],
    }],

    'flowtype/define-flow-type': 1,
    'flowtype/require-parameter-type': 1,
    'flowtype/space-after-type-colon': [1, "always"],
    'flowtype/space-before-type-colon': [1, "never"],
    "flowtype/use-flow-type": 1,
  },
  'settings': {
    'flowtype': {
      'onlyFilesWithFlowAnnotation': true
    }
  }
}
<|endoftext|>


<commit_before>'use strict';

var toPosInt = require('es5-ext/number/to-pos-integer')
  , firstKey = require('es5-ext/object/first-key')
  , d        = require('d')
  , Message  = require('./_message')

  , isArray = Array.isArray, defineProperties = Object.defineProperties;

module.exports = function (locale) {
	var self, resolve;
	self = function (keyS/*, keyP, n, inserts*/) {
		var inserts, template, keyP, key, n;
		keyS = String(keyS);
		if (arguments.length > 2) { //plural
			inserts = arguments[3];
			keyP = String(arguments[1]);
			key = 'n\0' + keyS + '\0' + keyP;
			n = toPosInt(arguments[2]);
			template = resolve.call(this, key, n);
			if (template === key) template = (n > 1) ? keyP : keyS;
		} else {
			inserts = arguments[1];
			template = resolve.call(this, keyS);
		}
		if (!inserts) return template;
		return new Message(template, inserts);
	};
	resolve = function (key, n) {
		var locale = self.locale, context, template, isMulti;
		if (!locale) return key;
		if ((locale = locale[key]) == null) return key;
		if (typeof locale === 'string') return locale;
		isMulti = (n != null);
		if (isMulti && (typeof locale === 'function')) return locale(n);
		if (!isMulti || !isArray(locale)) {
			context = ((this == null) || (this === self)) ? 'default' : this;
			if (locale[context] != null) {
				template = locale[context];
			} else if (locale.default != null) {
				template = locale.default;
			} else {
				context = firstKey(locale);
				if (context == null) return key;
				template = locale[context];
			}
		} else {
			template = locale;
		}
		if (!isMulti) return String(template);
		if (typeof template === 'function') return template(n);
		if (isArray(template)) {
			if (n) --n;
			while (n && (template[n] == null)) --n;
			if (template[n] != null) return template[n];
			return key;
		}
		return String(template);
	};

	return defineProperties(self, {
		locale: d(locale),
		_: d(self)
	});
};
<commit_msg>-- style<commit_after>'use strict';

var toPosInt = require('es5-ext/number/to-pos-integer')
  , firstKey = require('es5-ext/object/first-key')
  , d        = require('d')
  , Message  = require('./_message')

  , isArray = Array.isArray, defineProperties = Object.defineProperties;

module.exports = function (locale) {
	var self, resolve;
	self = function (keyS/*, keyP, n, inserts*/) {
		var inserts, template, keyP, key, n;
		keyS = String(keyS);
		if (arguments.length > 2) { // Plural
			inserts = arguments[3];
			keyP = String(arguments[1]);
			key = 'n\0' + keyS + '\0' + keyP;
			n = toPosInt(arguments[2]);
			template = resolve.call(this, key, n);
			if (template === key) template = (n > 1) ? keyP : keyS;
		} else {
			inserts = arguments[1];
			template = resolve.call(this, keyS);
		}
		if (!inserts) return template;
		return new Message(template, inserts);
	};
	resolve = function (key, n) {
		var locale = self.locale, context, template, isMulti;
		if (!locale) return key;
		if ((locale = locale[key]) == null) return key;
		if (typeof locale === 'string') return locale;
		isMulti = (n != null);
		if (isMulti && (typeof locale === 'function')) return locale(n);
		if (!isMulti || !isArray(locale)) {
			context = ((this == null) || (this === self)) ? 'default' : this;
			if (locale[context] != null) {
				template = locale[context];
			} else if (locale.default != null) {
				template = locale.default;
			} else {
				context = firstKey(locale);
				if (context == null) return key;
				template = locale[context];
			}
		} else {
			template = locale;
		}
		if (!isMulti) return String(template);
		if (typeof template === 'function') return template(n);
		if (isArray(template)) {
			if (n) --n;
			while (n && (template[n] == null)) --n;
			if (template[n] != null) return template[n];
			return key;
		}
		return String(template);
	};

	return defineProperties(self, {
		locale: d(locale),
		_: d(self)
	});
};
<|endoftext|>


<commit_before>var tessel = require('tessel');
var hardware = tessel.port('d');

var uart = hardware.UART({baudrate: 19200});
var g3 = hardware.gpio(3)
          .output()
          .high();
var sleepTime = 2000;
var txCount = 0;
var rxCount = 0;

//////////////////////////////////////////////////////////////////////////////

function decode(array)
{
  var decoded = '';
  for (var i = 0; i < array.length; i++)
  {
    if (array[i] < 14)
      decoded += '\n'
    else
      decoded += String.fromCharCode(array[i]);
  }
  return decoded;
}

function printRecieved(r)
{
  message = decode(r)
  if (message == '\n\nUNDER-VOLTAGE WARNNING\n\n')
    return
  console.log(rxCount, '\tRecieved:\n\t', message, '\n');
  rxCount++;
}

function send(cmd, verbose)
{
  verbose = verbose || 0;
  uart.write(cmd);
  if (verbose)
  {
    console.log(txCount, '\tSent:\n\t', cmd);
    txCount++;
  }
}

function SMS(number, message)
{
  number = String(number) || '15555555555';
  message = message || 'text from a Tessel';

  setTimeout(function(){
    send('AT\r\n');
    setTimeout(function(){
      send('AT+CMGF=1\r\n');
      setTimeout(function(){
        send('AT+CMGS="' + number + '"\r\n');
        setTimeout(function(){
          send(message + '\r\n');
          setTimeout(function(){
            send([0x1A]);
            }, 2000);
          }, 750);
        }, 500);
      }, 500);
    }, 500);
}

function heyListen(reps)
{
  reps = reps || 3;
  for (var i = 0; i < reps; i++)
  {
    setTimeout(function(){
      send('AT');
    }, 200 * i);
  }
}

////////////////////////////////////////////////////////////////////////////////

uart.on('data', function(bytes) {
  tessel.sleep(1);
  printRecieved(bytes);
});

// tessel.sleep(10000);
console.log('gogogo!');

heyListen();

//    for history's sake

// THIS BLOCK WORKED
// var characters = 'AT\r\n'
// send(characters);
// tessel.sleep(sleepTime);

// characters = 'AT+CMGF=1\r\n'
// send(characters);
// tessel.sleep(sleepTime);

// characters = 'AT+CMGS="15555555555"\r\n'
// send(characters);
// tessel.sleep(sleepTime);

// characters = 'text from a Tessel\r\n'
// send(characters);
// tessel.sleep(sleepTime);

// characters = [0x1A]
// send(characters);

<commit_msg>we can read sms...and communicate live<commit_after>var tessel = require('tessel');
var hardware = tessel.port('d');

var uart = hardware.UART({baudrate: 19200});
var g3 = hardware.gpio(3)
          .output()
          .high();
var sleepTime = 2000;
var txCount = 0;
var rxCount = 0;

//////////////////////////////////////////////////////////////////////////////

function decode(array)
{
  var decoded = '';
  for (var i = 0; i < array.length; i++)
  {
    if (array[i] < 14)
      decoded += '\n'
    else
      decoded += String.fromCharCode(array[i]);
  }
  return decoded;
}

function printRecieved(r)
{
  message = decode(r)
  // if (message == '\n\nUNDER-VOLTAGE WARNNING\n\n')
  //   return
  console.log(rxCount, '\tRecieved:\n\t', message, '\n');
  rxCount++;
}

function send(cmd, verbose)
{
  verbose = verbose || 0;
  uart.write(cmd);
  if (verbose)
  {
    console.log(txCount, '\tSent:\n\t', cmd);
    txCount++;
  }
}

function SMS(number, message)
{
  number = String(number) || '15555555555';
  message = message || 'text from a Tessel';

  setTimeout(function(){
    send('AT\r\n');
    setTimeout(function(){
      send('AT+CMGF=1\r\n');
      setTimeout(function(){
        send('AT+CMGS="' + number + '"\r\n');
        setTimeout(function(){
          send(message + '\r\n');
          setTimeout(function(){
            send([0x1A]);
            }, 2000);
          }, 750);
        }, 500);
      }, 500);
    }, 500);
}

function heyListen(reps)
{
  reps = reps || 3;
  for (var i = 0; i < reps; i++)
  {
    setTimeout(function(){
      send('AT', 1);
    }, 200 * (i + 1));
  }
}

function getNotificationSetting()
{
  send('AT+CGEREP?\r\n');
}

function setNotifications(mode, clearBuffer)
{
  /*
  mode
    0   buffer them
    1   discard
    2   buffer when you're in the middle of something, send when you're done

  clearBuffer
    0   keep the buffer
    1   flush
  */
  mode = mode || 0;                 //  off
  clearBuffer = clearBuffer || 0;   //  don't clear

  message = 'AT+CGEREP'
}

////////////////////////////////////////////////////////////////////////////////

process.on('message', function (data) {
  // console.log(data.substring(1, data.length-1));
  send(data.substring(1, data.length - 1) + "\r\n");
});

console.log('waiting for messages...');

uart.on('data', function(bytes) {
  printRecieved(bytes);
});

console.log('gogogo!');
tessel.sleep(50);
g3.low();
tessel.sleep(1200);
g3.high();
tessel.sleep(3000);

heyListen();

tessel.sleep(100);

// setInterval(function(){
//   send('AT+CMGR=1,1\r\n');
// }, 4000);

// setInterval(function(){
//   send('AT+CMGR=2,1\r\n');
// }, 5000);

// setInterval(function(){
//   send('AT+CMGR=3,1\r\n');
// }, 6000);

// setInterval(function(){
//   send('AT+CMGR=4,1\r\n');
// }, 7000);

// SMS(phone#,'messagetext');

//    for history's sake

// THIS BLOCK WORKED
// var characters = 'AT\r\n'
// send(characters);
// tessel.sleep(sleepTime);

// characters = 'AT+CMGF=1\r\n'
// send(characters);
// tessel.sleep(sleepTime);

// characters = 'AT+CMGS="15555555555"\r\n'
// send(characters);
// tessel.sleep(sleepTime);

// characters = 'text from a Tessel\r\n'
// send(characters);
// tessel.sleep(sleepTime);

// characters = [0x1A]
// send(characters);

<|endoftext|>


<commit_before>/*global jQuery */
/*!
* FitText.js 1.2
*
* Copyright 2011, Dave Rupert http://daverupert.com
* Released under the WTFPL license
* http://sam.zoy.org/wtfpl/
*
* Date: Thu May 05 14:23:00 2011 -0600
*/

(function( $ ){

  $.fn.fitText = function( kompressor, options ) {

    // Setup options
    var compressor = kompressor || 1,
        settings = $.extend({
          'minFontSize' : Number.NEGATIVE_INFINITY,
          'maxFontSize' : Number.POSITIVE_INFINITY
        }, options);

    return this.each(function(){

      // Store the object
      var $this = $(this);

      // Resizer() resizes items based on the object width divided by the compressor * 10
      var resizer = function () {
        $this.css('font-size', Math.max(Math.min($this.width() / (compressor*10), parseFloat(settings.maxFontSize)), parseFloat(settings.minFontSize)));
      };

      // Call once to set.
      resizer();

      // Call on resize. Opera debounces their resize by default.
      $(window).on('resize.fittext orientationchange.fittext', resizer);

    });

  };

})( jQuery );
/* end FitText.js */

/**
 * main js
 */

(function(window) {
  var labelDateFormatter = d3.time.format('%A %B %e, at %I:%M %p');
  var weights = [
    {when: "2015-03-29T01:14:00.000Z", weight: 8 + 11 / 16},
    {when: "2015-03-30T05:15:00.000Z", weight: 8 +  3 / 16},
    {when: "2015-03-31T16:00:00.000Z", weight: 7 + 12 / 16},
    {when: "2015-04-03T19:40:00.000Z", weight: 8 +  3 / 16},
    {when: "2015-04-07T15:48:00.000Z", weight: 8 +  5 / 16},
    {when: "2015-04-10T20:00:00.000Z", weight: 8          }
  ];
  var start = new Date(weights[0].when).valueOf();
  var hasImpact = false;

  weights = weights.reduce(function(weights, d) {
    var days = weights.length?
      (new Date(d.when).valueOf() - start) / 1000 / 60 / 60 / 24 : 0;
    return weights.concat([{when: days, weight: d.weight}])
  }, []);

  function chartWeight() {
    var $weight = $('#weight').empty();
    var margin = {top: 20, right: 20, bottom: 30, left: 70};
    var width = $weight.width() - margin.left - margin.right;
    var height = 250 - margin.top - margin.bottom - 15;

    function add10Percent(extent) {
      var magnitude = extent[1] - extent[0];
      var tenPercent = magnitude * 0.1;
      return [extent[0] - magnitude * .1, extent[1] + magnitude * .1];
    }

    var x = d3.scale.linear()
      .domain(add10Percent(d3.extent(weights, function(d) { return d.when })))
      .range([0, width]);

    var y = d3.scale.linear()
      .domain(add10Percent(d3.extent(weights, function(d) { return d.weight })))
      .range([height, 0]);

    var xAxis = d3.svg.axis()
      .scale(x)
      .ticks(8)
      .orient('bottom');

    var yAxis = d3.svg.axis()
      .scale(y)
      .ticks(4)
      .orient('left');

    var line = d3.svg.line()
      .interpolate('monotone')
      .x(function(d) { return x(d.when); })
      .y(function(d) { return y(d.weight); });

    var svg = d3.select($weight[0]).append("svg")
      .attr('width', width + margin.left + margin.right)
      .attr('height', height + margin.top + margin.bottom)
      .append('g')
        .attr('transform', 'translate(' + margin.left + ',' + margin.top +')');

    svg.append('g')
      .attr('class', 'x axis')
      .attr('transform', 'translate(0,' + height + ')')
      .call(xAxis)
      .append('text')
        .attr('x', width)
        .attr('y', -5)
        .style('text-anchor', 'end')
        .text('Days on Earth');

    svg.append('g')
      .attr('class', 'y axis')
      .call(yAxis)
      .append('text')
        .attr('transform', 'rotate(-90)')
        .attr('dy', '-3em')
        .attr('x', '-3.5em')
        .style('text-anchor', 'end')
        .text('Pounds');

    var label = svg.append('text')
      .attr('y', height + margin.top - 64)
      .attr('class', 'label invisible');

    state({
      chart: {
        svg: svg,
        x: x,
        y: y,
        label: label,
        weights: weights,
        line: line
      },
      weightLineDrawn: false
    });
  }

  function chartIsFullyInView() {
    var s = state();

    if (!s.articleVisible || s.svgBottom == null)
      return false;

    if (s.chartIsFullyInView)
      return true;

    var viewportBottom = s.scroll + s.viewportHeight;

    return viewportBottom >= s.svgBottom;
  }

  function animateWeightLine() {
    var incrementDuration = 400;
    var s = state();
    var path = s.chart.svg.append('path')
      .datum(s.chart.weights)
      .attr('class', 'line')
      .attr('d', s.chart.line);
    var pathLen = path.node().getTotalLength();

    function setLabel(d) {
      var weight = 'Little man weighed ' + Math.floor(d.weight) + ' pounds ' +
        Math.floor(d.weight % 1 * 16) + ' ounces';
      var date = 'On ' + labelDateFormatter(new Date(d.when));

      unsetLabel();

      s.chart.label.text('').attr('class', 'label');

      s.chart.label.append('tspan').attr('x', 12).attr('dy', '1em').text(date);
      s.chart.label.append('tspan').attr('x', 12).attr('dy', '1.1em').text(weight);
    }

    function unsetLabel() {
      s.chart.label.attr('class', 'label invisible');
    }

    path
      .attr('stroke-dasharray', pathLen + ' ' + pathLen)
      .attr('stroke-dashoffset', pathLen)
      .transition()
        .duration(incrementDuration * (s.chart.weights.length - 1))
        .ease('linear')
        .attr('stroke-dashoffset', 0);

    s.chart.svg.selectAll('.measurement')
      .data(s.chart.weights)
      .enter()
        .append('circle')
        .attr('class', 'measurement')
        .attr('r', 0)
        .attr('cx', function(d) { return s.chart.x(d.when) })
        .attr('cy', function(d) { return s.chart.y(d.weight) })
        .on('mouseover', setLabel)
        .on('mouseout', unsetLabel)
        .transition()
          .delay(function(d, i) { return i * incrementDuration })
          .ease('elastic')
          .duration(500)
          .attr('r', 8);

    state({weightLineDrawn: true});
  }

  function showContent() {
    $('#loading').hide();
    $('#content').removeClass('invisible')
  }

  function setHeaderImageSize() {
    $('.dat-lil-guy-tho').height($('.what-it-is').height());
    state({headerImageIsSized: true});
  }

  function onStateChange(event, curState, prevState) {
    if (curState.heroImageLoaded && !prevState.heroImageLoaded)
      showContent();

    if ((curState.articleVisible && !prevState.articleVisible) ||
        curState.viewportWidth !== prevState.viewportWidth)
      chartWeight();

    if (curState.articleVisible !== prevState.articleVisible ||
        curState.svgBottom !== prevState.svgBottom ||
        curState.scroll !== prevState.scroll ||
        curState.viewportHeight !== prevState.viewportHeight)
      state({chartIsFullyInView: chartIsFullyInView()});

    if (curState.chart && curState.chart !== prevState.chart) {
      var $svgEl = $(curState.chart.svg[0][0].ownerSVGElement);
      var svgOffset = $svgEl.offset();
      state({svgBottom: $svgEl.height() + svgOffset.top});
    }

    if (curState.chartIsFullyInView && !curState.weightLineDrawn)
      animateWeightLine();

    if (!curState.headerImageIsSized && curState.heroImageLoaded)
      setHeaderImageSize();
  }

  var _state = {
    viewportHeight: window.innerHeight,
    scroll: $(window).scrollTop(),
    chartTop: $('#weight').offset().top,
    articleVisible: false,
    chartIsFullyInView: false,
    heroImageLoaded: false
  };
  var _prevState = {};
  var eventBus = $({});

  function state(newState) {
    if (arguments.length) {
      _prevState = _state;
      _state = $.extend({}, _state, newState);
      eventBus.trigger('statechange', [_state, _prevState]);
    } else {
      return _state;
    }
  }

  eventBus.on('statechange', onStateChange);

  if ($('#font-test-1').width() !== $('#font-test-2').width())
    hasImpact = true;

  $('[id^=font-test]').hide();

  $('[data-fittext]').each(function(i, el) {
    var prop = hasImpact? 'compressor-impact' : 'compressor';

    $(el).fitText($(el).data(prop));
  });

  $('[data-appear]').each(function(i, el) {
    setTimeout(function() {
      $(el).css('visibility', 'visible').trigger('appear');
    }, +$(el).data('appear') * 350);
  });

  var preload = new Image();
  preload.src = 'img/anderson-david.jpg';
  preload.onload = state.bind(null, {heroImageLoaded: true});

  $('body').on('appear', 'article', state.bind(null, {articleVisible: true}));
  $(window).on('orientationchange resize', function() {
    var h = window.innerHeight;
    var w = window.innerWidth;
    var newState = {headerImageIsSized: false};

    if (h != state().viewportHeight)
      newState.viewportHeight = h;

    if (w != state().viewportWidth)
      newState.viewportWidth = w;

    state(newState);
  });
  $('.parallax').on('scroll', function() {
    if (Math.abs(this.scrollTop - state().scroll) < 20)
      return;

    state({scroll: this.scrollTop});
  });

  onStateChange(null, _state, _prevState);
})(window);
<commit_msg>correct wording<commit_after>/*global jQuery */
/*!
* FitText.js 1.2
*
* Copyright 2011, Dave Rupert http://daverupert.com
* Released under the WTFPL license
* http://sam.zoy.org/wtfpl/
*
* Date: Thu May 05 14:23:00 2011 -0600
*/

(function( $ ){

  $.fn.fitText = function( kompressor, options ) {

    // Setup options
    var compressor = kompressor || 1,
        settings = $.extend({
          'minFontSize' : Number.NEGATIVE_INFINITY,
          'maxFontSize' : Number.POSITIVE_INFINITY
        }, options);

    return this.each(function(){

      // Store the object
      var $this = $(this);

      // Resizer() resizes items based on the object width divided by the compressor * 10
      var resizer = function () {
        $this.css('font-size', Math.max(Math.min($this.width() / (compressor*10), parseFloat(settings.maxFontSize)), parseFloat(settings.minFontSize)));
      };

      // Call once to set.
      resizer();

      // Call on resize. Opera debounces their resize by default.
      $(window).on('resize.fittext orientationchange.fittext', resizer);

    });

  };

})( jQuery );
/* end FitText.js */

/**
 * main js
 */

(function(window) {
  var labelDateFormatter = d3.time.format('%A %B %e, at %I:%M %p');
  var weights = [
    {when: "2015-03-29T01:14:00.000Z", weight: 8 + 11 / 16},
    {when: "2015-03-30T05:15:00.000Z", weight: 8 +  3 / 16},
    {when: "2015-03-31T16:00:00.000Z", weight: 7 + 12 / 16},
    {when: "2015-04-03T19:40:00.000Z", weight: 8 +  3 / 16},
    {when: "2015-04-07T15:48:00.000Z", weight: 8 +  5 / 16},
    {when: "2015-04-10T20:00:00.000Z", weight: 8          }
  ];
  var start = new Date(weights[0].when).valueOf();
  var hasImpact = false;

  weights = weights.reduce(function(weights, d) {
    var days = weights.length?
      (new Date(d.when).valueOf() - start) / 1000 / 60 / 60 / 24 : 0;
    return weights.concat([{when: days, weight: d.weight}])
  }, []);

  function chartWeight() {
    var $weight = $('#weight').empty();
    var margin = {top: 20, right: 20, bottom: 30, left: 70};
    var width = $weight.width() - margin.left - margin.right;
    var height = 250 - margin.top - margin.bottom - 15;

    function add10Percent(extent) {
      var magnitude = extent[1] - extent[0];
      var tenPercent = magnitude * 0.1;
      return [extent[0] - magnitude * .1, extent[1] + magnitude * .1];
    }

    var x = d3.scale.linear()
      .domain(add10Percent(d3.extent(weights, function(d) { return d.when })))
      .range([0, width]);

    var y = d3.scale.linear()
      .domain(add10Percent(d3.extent(weights, function(d) { return d.weight })))
      .range([height, 0]);

    var xAxis = d3.svg.axis()
      .scale(x)
      .ticks(8)
      .orient('bottom');

    var yAxis = d3.svg.axis()
      .scale(y)
      .ticks(4)
      .orient('left');

    var line = d3.svg.line()
      .interpolate('monotone')
      .x(function(d) { return x(d.when); })
      .y(function(d) { return y(d.weight); });

    var svg = d3.select($weight[0]).append("svg")
      .attr('width', width + margin.left + margin.right)
      .attr('height', height + margin.top + margin.bottom)
      .append('g')
        .attr('transform', 'translate(' + margin.left + ',' + margin.top +')');

    svg.append('g')
      .attr('class', 'x axis')
      .attr('transform', 'translate(0,' + height + ')')
      .call(xAxis)
      .append('text')
        .attr('x', width)
        .attr('y', -5)
        .style('text-anchor', 'end')
        .text('Days since launch');

    svg.append('g')
      .attr('class', 'y axis')
      .call(yAxis)
      .append('text')
        .attr('transform', 'rotate(-90)')
        .attr('dy', '-3em')
        .attr('x', '-3.5em')
        .style('text-anchor', 'end')
        .text('Pounds');

    var label = svg.append('text')
      .attr('y', height + margin.top - 64)
      .attr('class', 'label invisible');

    state({
      chart: {
        svg: svg,
        x: x,
        y: y,
        label: label,
        weights: weights,
        line: line
      },
      weightLineDrawn: false
    });
  }

  function chartIsFullyInView() {
    var s = state();

    if (!s.articleVisible || s.svgBottom == null)
      return false;

    if (s.chartIsFullyInView)
      return true;

    var viewportBottom = s.scroll + s.viewportHeight;

    return viewportBottom >= s.svgBottom;
  }

  function animateWeightLine() {
    var incrementDuration = 400;
    var s = state();
    var path = s.chart.svg.append('path')
      .datum(s.chart.weights)
      .attr('class', 'line')
      .attr('d', s.chart.line);
    var pathLen = path.node().getTotalLength();

    function setLabel(d) {
      var weight = 'Little man weighed ' + Math.floor(d.weight) + ' pounds ' +
        Math.floor(d.weight % 1 * 16) + ' ounces';
      var date = 'On ' + labelDateFormatter(new Date(d.when));

      unsetLabel();

      s.chart.label.text('').attr('class', 'label');

      s.chart.label.append('tspan').attr('x', 12).attr('dy', '1em').text(date);
      s.chart.label.append('tspan').attr('x', 12).attr('dy', '1.1em').text(weight);
    }

    function unsetLabel() {
      s.chart.label.attr('class', 'label invisible');
    }

    path
      .attr('stroke-dasharray', pathLen + ' ' + pathLen)
      .attr('stroke-dashoffset', pathLen)
      .transition()
        .duration(incrementDuration * (s.chart.weights.length - 1))
        .ease('linear')
        .attr('stroke-dashoffset', 0);

    s.chart.svg.selectAll('.measurement')
      .data(s.chart.weights)
      .enter()
        .append('circle')
        .attr('class', 'measurement')
        .attr('r', 0)
        .attr('cx', function(d) { return s.chart.x(d.when) })
        .attr('cy', function(d) { return s.chart.y(d.weight) })
        .on('mouseover', setLabel)
        .on('mouseout', unsetLabel)
        .transition()
          .delay(function(d, i) { return i * incrementDuration })
          .ease('elastic')
          .duration(500)
          .attr('r', 8);

    state({weightLineDrawn: true});
  }

  function showContent() {
    $('#loading').hide();
    $('#content').removeClass('invisible')
  }

  function setHeaderImageSize() {
    $('.dat-lil-guy-tho').height($('.what-it-is').height());
    state({headerImageIsSized: true});
  }

  function onStateChange(event, curState, prevState) {
    if (curState.heroImageLoaded && !prevState.heroImageLoaded)
      showContent();

    if ((curState.articleVisible && !prevState.articleVisible) ||
        curState.viewportWidth !== prevState.viewportWidth)
      chartWeight();

    if (curState.articleVisible !== prevState.articleVisible ||
        curState.svgBottom !== prevState.svgBottom ||
        curState.scroll !== prevState.scroll ||
        curState.viewportHeight !== prevState.viewportHeight)
      state({chartIsFullyInView: chartIsFullyInView()});

    if (curState.chart && curState.chart !== prevState.chart) {
      var $svgEl = $(curState.chart.svg[0][0].ownerSVGElement);
      var svgOffset = $svgEl.offset();
      state({svgBottom: $svgEl.height() + svgOffset.top});
    }

    if (curState.chartIsFullyInView && !curState.weightLineDrawn)
      animateWeightLine();

    if (!curState.headerImageIsSized && curState.heroImageLoaded)
      setHeaderImageSize();
  }

  var _state = {
    viewportHeight: window.innerHeight,
    scroll: $(window).scrollTop(),
    chartTop: $('#weight').offset().top,
    articleVisible: false,
    chartIsFullyInView: false,
    heroImageLoaded: false
  };
  var _prevState = {};
  var eventBus = $({});

  function state(newState) {
    if (arguments.length) {
      _prevState = _state;
      _state = $.extend({}, _state, newState);
      eventBus.trigger('statechange', [_state, _prevState]);
    } else {
      return _state;
    }
  }

  eventBus.on('statechange', onStateChange);

  if ($('#font-test-1').width() !== $('#font-test-2').width())
    hasImpact = true;

  $('[id^=font-test]').hide();

  $('[data-fittext]').each(function(i, el) {
    var prop = hasImpact? 'compressor-impact' : 'compressor';

    $(el).fitText($(el).data(prop));
  });

  $('[data-appear]').each(function(i, el) {
    setTimeout(function() {
      $(el).css('visibility', 'visible').trigger('appear');
    }, +$(el).data('appear') * 350);
  });

  var preload = new Image();
  preload.src = 'img/anderson-david.jpg';
  preload.onload = state.bind(null, {heroImageLoaded: true});

  $('body').on('appear', 'article', state.bind(null, {articleVisible: true}));
  $(window).on('orientationchange resize', function() {
    var h = window.innerHeight;
    var w = window.innerWidth;
    var newState = {headerImageIsSized: false};

    if (h != state().viewportHeight)
      newState.viewportHeight = h;

    if (w != state().viewportWidth)
      newState.viewportWidth = w;

    state(newState);
  });
  $('.parallax').on('scroll', function() {
    if (Math.abs(this.scrollTop - state().scroll) < 20)
      return;

    state({scroll: this.scrollTop});
  });

  onStateChange(null, _state, _prevState);
})(window);
<|endoftext|>


<commit_before>var watch = require('recursive-watch')
var createReadStream = require('fd-read-stream')
var fs = require('fs')
var path = require('path')
var events = require('events')

module.exports = mirror

function mirror (src, dst, opts, cb) {
  if (typeof opts === 'function') return mirror(src, dst, null, opts)
  if (!opts) opts = {}

  var progress = new events.EventEmitter()
  progress.destroy = destroy

  if (cb) {
    progress.on('error', cb)
    progress.on('end', cb)
  }

  src = parse(src)
  dst = parse(dst)

  var stopped = false
  var waiting = true
  var walking = [src.name]
  var pending = progress.pending = []
  var equals = opts.equals || defaultEquals
  var stopWatch = null

  if (opts.watch) stopWatch = watch(src.name, onwatch)
  walk()

  return progress

  function onwatch (name) {
    update(name, true)
  }

  function update (name, live) {
    var item = {name: name.slice(src.name.length) || path.sep, live: live}
    if (name === src.name) item = {name: '', live: live} // allow single file src (not '/')

    pending.push(item)
    progress.emit('pending', item)
    if (pending.length === 1) kick()
  }

  function stat (fs, name, cb) {
    if (opts.dereference) fs.stat(name, cb)
    else fs.lstat(name, cb)
  }

  function kick () {
    var name = pending[0].name
    var live = pending[0].live

    var a = {name: path.join(src.name, name), stat: null, live: live, fs: src.fs}
    var b = {name: path.join(dst.name, name), stat: null, live: live, fs: dst.fs}

    stat(a.fs, a.name, function (_, st) {
      if (st) a.stat = st
      stat(b.fs, b.name, function (_, st) {
        if (st) b.stat = st

        // skip, not in any folder
        if (!a.stat && !b.stat) {
          progress.emit('skip', a, b)
          return next()
        }

        // ignore
        if (opts.ignore && (opts.ignore(a.name, a.stat) || opts.ignore(b.name, b.stat))) {
          progress.emit('ignore', a, b)
          return next()
        }

        // del from b
        if (!a.stat && b.stat) return del(b, next)

        // copy to b
        if (a.stat && !b.stat) return put(a, b, next)

        // check if they are the same
        equals(a, b, function (err, same) {
          if (err) throw err
          if (same) {
            progress.emit('skip', a, b)
            return next()
          }
          put(a, b, next)
        })
      })
    })
  }

  function next (err) {
    if (stopped) return
    if (err) return progress.emit('error', err)
    if (stopped) return

    pending.shift()
    if (pending.length) return kick()

    if (!opts.watch && !walking.length && waiting) return progress.emit('end')
    walk()
  }

  function walk () {
    if (!walking.length || !waiting) return

    var name = walking.pop()
    waiting = false

    src.fs.lstat(name, function (err, st) {
      if (err && err.code === 'ENOENT') return walk()
      if (err) return progress.emit('error', err)

      if (!st.isDirectory()) {
        waiting = true
        update(name, false)
        return
      }

      src.fs.readdir(name, function (err, names) {
        if (err && err.code === 'ENOENT') return walk()
        if (err) return progress.emit('error', err)

        names = names.sort().reverse()
        for (var i = 0; i < names.length; i++) walking.push(path.join(name, names[i]))

        var dstName = path.join(dst.name, path.relative(src.name, name))
        dst.fs.readdir(dstName, function (err, dstNames) {
          if (err) return next()

          queueFilesToDelete(dstNames)
          next()
        })

        function next () {
          waiting = true
          update(name, false)
        }

        function queueFilesToDelete (dstNames) {
          // names = array of files in src
          // dstNames = array of files in dst
          // return items in dest but not in src (to delete)
          dstNames = dstNames.sort().reverse().filter(function (file) {
            return names.indexOf(file) === -1
          })

          // add files to pending to queue for deletion in dest
          // use `join(srcName, dstName)` since !src.stat = true, forces delete
          for (var j = 0; j < dstNames.length; j++) update(path.join(name, dstNames[j]), false)
        }
      })
    })
  }

  function del (b, cb) {
    progress.emit('del', b)
    if (opts.dryRun) return cb()
    if (!b.stat.isDirectory()) return b.fs.unlink(b.name, cb)
    rimraf(b, function () { // ignore errors for now
      cb()
    })
  }

  function rimraf (b, cb) { // this one is a bit hacky ...
    b.fs.readdir(b.name, function (_, list) {
      if (!list) list = []
      loop()

      function loop () {
        if (!list.length) {
          if (b.stat.isDirectory()) b.fs.rmdir(b.name, cb)
          else b.fs.unlink(b.name, cb)
          return
        }

        var name = path.join(b.name, list.shift())

        b.fs.lstat(name, function (err, st) {
          if (err) return cb()
          rimraf({name: name, stat: st, fs: b.fs}, loop)
        })
      }
    })
  }

  function put (a, b, cb) {
    progress.emit('put', a, b)
    if (opts.dryRun) {
      if (a.stat.isDirectory()) return cb() // Don't call put-end
      return onfinish()
    }
    if (a.stat.isDirectory()) return b.fs.mkdir(b.name, a.stat.mode, ignoreError(cb))

    if (a.live && a.fs.open) {
      // To work around the race condition that files might be written *in progress*
      // when live watching we use the fd retry 50ms option.
      a.fs.open(a.name, 'r', function (err, fd) {
        if (err) return cb(err)
        copy(createReadStream(fd, {retry: 50}))
      })
    } else {
      copy(a.fs.createReadStream(a.name))
    }

    function copy (rs) {
      var ws = b.fs.createWriteStream(b.name, {mode: a.stat.mode})

      rs.on('error', onerror)
      ws.on('error', onerror)
      ws.on('finish', onfinish)

      rs.pipe(ws)
      rs.on('data', ondata)

      function ondata (data) {
        progress.emit('put-data', data, a, b)
      }

      function onerror (err) {
        progress.emit('put-error', a, b)
        rs.destroy()
        ws.destroy()
        ws.removeListener('finish', cb)
        cb(err)
      }
    }

    function onfinish () {
      progress.emit('put-end', a, b)
      cb()
    }
  }

  function ignoreError (cb) {
    return function (err) {
      if (err && err.code !== 'EEXIST') return cb(err)
      cb(null)
    }
  }

  function destroy () {
    if (opts.watch) stopWatch()
    pending = []
    stopped = true
  }
}

function parse (name) {
  if (typeof name === 'string') return {name: path.resolve(name), fs: fs}
  name.name = path.resolve(name.name)
  if (!name.fs) name.fs = fs
  return name
}

function defaultEquals (a, b, cb) {
  if (!a.stat.isDirectory() && (a.stat.size !== b.stat.size)) return cb(null, false)
  if (a.stat.mtime.getTime() > b.stat.mtime.getTime()) return cb(null, false)
  cb(null, true)
}
<commit_msg>some fixes with live folder updates<commit_after>var watch = require('recursive-watch')
var createReadStream = require('fd-read-stream')
var fs = require('fs')
var path = require('path')
var events = require('events')

module.exports = mirror

function mirror (src, dst, opts, cb) {
  if (typeof opts === 'function') return mirror(src, dst, null, opts)
  if (!opts) opts = {}

  var progress = new events.EventEmitter()
  progress.destroy = destroy

  if (cb) {
    progress.on('error', cb)
    progress.on('end', cb)
  }

  src = parse(src)
  dst = parse(dst)

  var stopped = false
  var waiting = true
  var walking = [src.name]
  var pending = progress.pending = []
  var equals = opts.equals || defaultEquals
  var stopWatch = null

  if (opts.watch) stopWatch = watch(src.name, onwatch)
  walk()

  return progress

  function onwatch (name) {
    update(name, true)
  }

  function update (name, live) {
    var item = {name: name.slice(src.name.length) || path.sep, live: live}
    if (name === src.name) item = {name: '', live: live} // allow single file src (not '/')

    pending.push(item)
    progress.emit('pending', item)
    if (pending.length === 1) kick()
  }

  function stat (fs, name, cb) {
    if (opts.dereference) fs.stat(name, cb)
    else fs.lstat(name, cb)
  }

  function kick () {
    var name = pending[0].name
    var live = pending[0].live

    var a = {name: path.join(src.name, name), stat: null, live: live, fs: src.fs}
    var b = {name: path.join(dst.name, name), stat: null, live: live, fs: dst.fs}

    stat(a.fs, a.name, function (_, st) {
      if (st) a.stat = st
      stat(b.fs, b.name, function (_, st) {
        if (st) b.stat = st

        // skip, not in any folder
        if (!a.stat && !b.stat) {
          progress.emit('skip', a, b)
          return next()
        }

        if (live && a.stat && a.stat.isDirectory()) {
          walking.push(a.name) // will retrigger
          return next()
        }

        // ignore
        if (opts.ignore && (opts.ignore(a.name, a.stat) || opts.ignore(b.name, b.stat))) {
          if (live && b.stat && b.stat.isDirectory() && !a.stat) {
            return rimraf(b, opts.ignore, next)
          }
          progress.emit('ignore', a, b)
          return next()
        }

        // del from b
        if (!a.stat && b.stat) return del(b, next)

        // copy to b
        if (a.stat && !b.stat) return put(a, b, next)

        // check if they are the same
        equals(a, b, function (err, same) {
          if (err) throw err
          if (same) {
            progress.emit('skip', a, b)
            return next()
          }
          put(a, b, next)
        })
      })
    })
  }

  function next (err) {
    if (stopped) return
    if (err) return progress.emit('error', err)
    if (stopped) return

    pending.shift()
    if (pending.length) return kick()

    if (!opts.watch && !walking.length && waiting) return progress.emit('end')
    walk()
  }

  function walk () {
    if (!walking.length || !waiting) return

    var name = walking.pop()
    waiting = false

    src.fs.lstat(name, function (err, st) {
      if (err && err.code === 'ENOENT') return walk()
      if (err) return progress.emit('error', err)

      if (!st.isDirectory()) {
        waiting = true
        update(name, false)
        return
      }

      src.fs.readdir(name, function (err, names) {
        if (err && err.code === 'ENOENT') return walk()
        if (err) return progress.emit('error', err)

        names = names.sort().reverse()
        for (var i = 0; i < names.length; i++) walking.push(path.join(name, names[i]))

        var dstName = path.join(dst.name, path.relative(src.name, name))
        dst.fs.readdir(dstName, function (err, dstNames) {
          if (err) return next()

          queueFilesToDelete(dstNames)
          next()
        })

        function next () {
          waiting = true
          update(name, false)
        }

        function queueFilesToDelete (dstNames) {
          // names = array of files in src
          // dstNames = array of files in dst
          // return items in dest but not in src (to delete)
          dstNames = dstNames.sort().reverse().filter(function (file) {
            return names.indexOf(file) === -1
          })

          // add files to pending to queue for deletion in dest
          // use `join(srcName, dstName)` since !src.stat = true, forces delete
          for (var j = 0; j < dstNames.length; j++) update(path.join(name, dstNames[j]), false)
        }
      })
    })
  }

  function del (b, cb) {
    progress.emit('del', b)
    if (opts.dryRun) return cb()
    if (!b.stat.isDirectory()) return b.fs.unlink(b.name, cb)
    rimraf(b, null, function () { // ignore errors for now
      cb()
    })
  }

  function rimraf (b, ignore, cb) { // this one is a bit hacky ...
    b.fs.readdir(b.name, function (_, list) {
      if (!list) list = []
      loop()

      function loop () {
        if (!list.length) {
          if (ignore && ignore(b.name, b.stat)) return process.nextTick(cb)
          if (b.stat.isDirectory()) b.fs.rmdir(b.name, cb)
          else b.fs.unlink(b.name, cb)
          return
        }

        var name = path.join(b.name, list.shift())

        b.fs.lstat(name, function (err, st) {
          if (err) return cb()
          rimraf({name: name, stat: st, fs: b.fs}, ignore, loop)
        })
      }
    })
  }

  function put (a, b, cb) {
    progress.emit('put', a, b)
    if (opts.dryRun) {
      if (a.stat.isDirectory()) return cb() // Don't call put-end
      return onfinish()
    }
    if (a.stat.isDirectory()) return b.fs.mkdir(b.name, a.stat.mode, ignoreError(cb))

    if (a.live && a.fs.open) {
      // To work around the race condition that files might be written *in progress*
      // when live watching we use the fd retry 50ms option.
      a.fs.open(a.name, 'r', function (err, fd) {
        if (err) return cb(err)
        copy(createReadStream(fd, {retry: 50}))
      })
    } else {
      copy(a.fs.createReadStream(a.name))
    }

    function copy (rs) {
      var ws = b.fs.createWriteStream(b.name, {mode: a.stat.mode})

      rs.on('error', onerror)
      ws.on('error', onerror)
      ws.on('finish', onfinish)

      rs.pipe(ws)
      rs.on('data', ondata)

      function ondata (data) {
        progress.emit('put-data', data, a, b)
      }

      function onerror (err) {
        progress.emit('put-error', a, b)
        rs.destroy()
        ws.destroy()
        ws.removeListener('finish', cb)
        cb(err)
      }
    }

    function onfinish () {
      progress.emit('put-end', a, b)
      cb()
    }
  }

  function ignoreError (cb) {
    return function (err) {
      if (err && err.code !== 'EEXIST') return cb(err)
      cb(null)
    }
  }

  function destroy () {
    if (opts.watch) stopWatch()
    pending = []
    stopped = true
  }
}

function parse (name) {
  if (typeof name === 'string') return {name: path.resolve(name), fs: fs}
  name.name = path.resolve(name.name)
  if (!name.fs) name.fs = fs
  return name
}

function defaultEquals (a, b, cb) {
  if (!a.stat.isDirectory() && (a.stat.size !== b.stat.size)) return cb(null, false)
  if (a.stat.mtime.getTime() > b.stat.mtime.getTime()) return cb(null, false)
  cb(null, true)
}
<|endoftext|>