<commit_before>const CronJob = require('cron').CronJob;
const request = require('request');
const LOG = require('./log');
const moment = require('moment');
const Response = require('../models/response');
const Monitor = require('../models/monitor');
const Email = require('../lib/email');
const async = require('async');

var Cron = {};

const emailTimeStampFormat = "dddd, MMMM Do YYYY, h:mm:ss a";

var q = async.queue(function (task, callback) {
    // console.log('hello ' + task.name);

    var error = task.error;
    var monitor = task.monitor;
    var response = task.response;
    var body = task.body;
    var start = task.start;
    var end = task.end;

    if (!response) {
        response = {}; //make sure it exists
    }

    var duration = moment.duration(end.diff(start));
    var timeDiff = duration.asMilliseconds();

    var isUp = (!error && response.statusCode == 200);
    if (!isUp && monitor.up) {//ITS DOWN!

        if (!monitor.emailSent) {
            Email.isDown(monitor, response, end.format(emailTimeStampFormat));
            monitor.emailSent = true;
            // monitor.save() //TODO will save it later
            //     .then(()=> {
            //         // LOG.success('updated monitor up percentage', monitor.upPercent);
            //     })
            //     .catch((err)=> {
            //         LOG.error('failed to save monitor up percentage', err);
            //         return callback(err);
            //     })
        }
    }

    if (isUp && !monitor.up) { //ITS BACK UP!
        Email.isUp(monitor, response, end.format(emailTimeStampFormat));
        monitor.emailSent = false;
        // monitor.save() //TODO will save it later
        //     .then(()=> {
        //         // LOG.success('updated monitor up percentage', monitor.upPercent);
        //     })
        //     .catch((err)=> {
        //         LOG.error('failed to save monitor up percentage', err);
        //         return callback(err);
        //     })
    }

    new Response({
        time: isUp ? timeDiff : null, //9999 aka didnt return
        monitorID: monitor.id,
        up: isUp,
        statusCode: response.statusCode || null,
        error: error ? error.toString() : null
    }).save().then(()=> {
        // LOG.success('saved response');
        Response.filter({monitorID: monitor.id}).run()
            .then((responses)=> {
                var up = responses.filter((r)=> {
                    return r.up;
                }).length;
                monitor.upPercent = Math.floor((up / responses.length) * 100);
                monitor.up = isUp;

                //calculate average response time (optimal)
                var respt = 0;
                responses.map((resp)=> {
                    respt += resp.time;
                });
                monitor.avgResponseTime = Math.floor(respt / responses.length);

                monitor.save()
                    .then(()=> {
                        // LOG.success('updated monitor up percentage', monitor.upPercent);
                        return callback();
                    })
                    .catch((err)=> {
                        LOG.error('failed to save monitor up percentage', err);
                        return callback(err);
                    })
            })
            .catch((err)=> {
                LOG.error('failed to update monitor', monitor.name, 'up percent, because', err);
                return callback(err);
            })
    });
}, 1);

Cron.add = (monitor)=> {

    LOG.log(monitor.name, 'added to monitor list');

    new CronJob('*/5 * * * *', function () { //5 mins, add job
            LOG.log('Checking site', monitor.name);

            var start = moment(); //pre request time
            request(monitor.url, function (error, response, body) { //do we need body?
                var end = moment(); //post request time
                q.push([{error, monitor, response, body, start, end}], function (err) {
                    if (err) {
                        LOG.error(err);
                    } else {
                        console.log('finished processing item');
                    }

                });
            })

        }, function () {
            //TODO reschedule
            Cron.add(monitor);
            LOG.error('CRON', monitor.name, 'ENDED', 'RESCHEDULED IT');
        },
        true /* Start the job right now */
    );

};

Cron.startAll = () => {
    Monitor.run().then((monitors)=> {
        LOG.log('Starting', monitors.length, 'monitor(s)');
        monitors.map((monitor)=> {
            Cron.add(monitor);
        })
    })
};

module.exports = Cron;<commit_msg>debug<commit_after>const CronJob = require('cron').CronJob;
const request = require('request');
const LOG = require('./log');
const moment = require('moment');
const Response = require('../models/response');
const Monitor = require('../models/monitor');
const Email = require('../lib/email');
const async = require('async');

var Cron = {};

const emailTimeStampFormat = "dddd, MMMM Do YYYY, h:mm:ss a";

var q = async.queue(function (task, callback) {
    // console.log('hello ' + task.name);

    var error = task.error;
    var monitor = task.monitor;
    var response = task.response;
    var body = task.body;
    var start = task.start;
    var end = task.end;

    LOG.log(monitor.name, 'being processed in queue');

    if (!response) {
        response = {}; //make sure it exists
    }

    var duration = moment.duration(end.diff(start));
    var timeDiff = duration.asMilliseconds();

    var isUp = (!error && response.statusCode == 200);
    if (!isUp && monitor.up) {//ITS DOWN!

        if (!monitor.emailSent) {
            Email.isDown(monitor, response, end.format(emailTimeStampFormat));
            monitor.emailSent = true;
            // monitor.save() //TODO will save it later
            //     .then(()=> {
            //         // LOG.success('updated monitor up percentage', monitor.upPercent);
            //     })
            //     .catch((err)=> {
            //         LOG.error('failed to save monitor up percentage', err);
            //         return callback(err);
            //     })
        }
    }

    if (isUp && !monitor.up) { //ITS BACK UP!
        Email.isUp(monitor, response, end.format(emailTimeStampFormat));
        monitor.emailSent = false;
        // monitor.save() //TODO will save it later
        //     .then(()=> {
        //         // LOG.success('updated monitor up percentage', monitor.upPercent);
        //     })
        //     .catch((err)=> {
        //         LOG.error('failed to save monitor up percentage', err);
        //         return callback(err);
        //     })
    }

    new Response({
        time: isUp ? timeDiff : null, //9999 aka didnt return
        monitorID: monitor.id,
        up: isUp,
        statusCode: response.statusCode || null,
        error: error ? error.toString() : null
    }).save().then(()=> {
        // LOG.success('saved response');
        Response.filter({monitorID: monitor.id}).run()
            .then((responses)=> {
                var up = responses.filter((r)=> {
                    return r.up;
                }).length;
                monitor.upPercent = Math.floor((up / responses.length) * 100);
                monitor.up = isUp;

                //calculate average response time (optimal)
                var respt = 0;
                responses.map((resp)=> {
                    respt += resp.time;
                });
                monitor.avgResponseTime = Math.floor(respt / responses.length);

                monitor.save()
                    .then(()=> {
                        // LOG.success('updated monitor up percentage', monitor.upPercent);
                        return callback();
                    })
                    .catch((err)=> {
                        LOG.error('failed to save monitor up percentage', err);
                        return callback(err);
                    })
            })
            .catch((err)=> {
                LOG.error('failed to update monitor', monitor.name, 'up percent, because', err);
                return callback(err);
            })
    });
}, 1);

Cron.add = (monitor)=> {

    LOG.log(monitor.name, 'added to monitor list');

    new CronJob('*/5 * * * *', function () { //5 mins, add job
            var start = moment(); //pre request time
            request(monitor.url, function (error, response, body) { //do we need body?
                LOG.log('Got response from', monitor.name);
                var end = moment(); //post request time
                q.push([{error, monitor, response, body, start, end}], function (err) {
                    if (err) {
                        LOG.error(err);
                    } else {
                        console.log('finished processing item');
                    }

                });
            })

        }, function () {
            //TODO reschedule
            Cron.add(monitor);
            LOG.error('CRON', monitor.name, 'ENDED', 'RESCHEDULED IT');
        },
        true /* Start the job right now */
    );

};

Cron.startAll = () => {
    Monitor.run().then((monitors)=> {
        LOG.log('Starting', monitors.length, 'monitor(s)');
        monitors.map((monitor)=> {
            Cron.add(monitor);
        })
    })
};

module.exports = Cron;<|endoftext|>


<commit_before>const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Main = imports.ui.main;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const St = imports.gi.St;

const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Util = Me.imports.util;

function LOG(message) {
	// log("[pixel-saver]: " + message);
}

function WARN(message) {
	log("[pixel-saver]: " + message);
}

/**
 * Buttons
 */
const DCONF_META_PATH = 'org.gnome.desktop.wm.preferences';

let actors = [], boxes = [];
function createButtons() {
	// Ensure we do not create buttons twice.
	destroyButtons();

	actors = [
		new St.Bin({ style_class: 'box-bin'}),
		new St.Bin({ style_class: 'box-bin'})
	];

	boxes = [
		new St.BoxLayout({ style_class: 'button-box' }),
		new St.BoxLayout({ style_class: 'button-box' })
	];

	actors.forEach(function(actor, i) {
		actor.add_actor(boxes[i]);
	});

	let order = new Gio.Settings({schema_id: DCONF_META_PATH}).get_string('button-layout');
	LOG('Buttons layout : ' + order);

	let orders = order.replace(/ /g, '').split(':');

	orders[0] = orders[0].split(',');

	// Check if it's actually exists, if not then create it
	if(typeof orders[1] == 'undefined') orders[1] = '';
	orders[1] = orders[1].split(',');

	const callbacks = {
		minimize : minimize,
		maximize : maximize,
		close    : close
	};

	for (let bi = 0; bi < boxes.length; ++bi) {
		let order = orders[bi],
			box = boxes[bi];

		for (let i = 0; i < order.length; ++i) {
			if (!order[i]) {
				continue;
			}

			if (!callbacks[order[i]]) {
				// Skip if the button's name is not right...
				WARN("\'%s\' is not a valid button.".format(order[i]));
				continue;
			}

			let button = new St.Button({
				style_class: order[i]  + ' window-button',
				track_hover: true
			});

			button.connect('button-release-event', leftclick(callbacks[order[i]]));
			box.add(button);
		}
	}

	Mainloop.idle_add(function () {
		// 1 for activity button and -1 for the menu
		if (boxes[0].get_children().length) {
			Main.panel._leftBox.insert_child_at_index(actors[0], 1);
		}

		if (boxes[1].get_children().length) {
			Main.panel._rightBox.insert_child_at_index(actors[1], Main.panel._rightBox.get_children().length - 1);
		}

		updateVisibility();
		return false;
	});
}

function destroyButtons() {
	actors.forEach(function(actor, i) {
		actor.destroy();
		boxes[i].destroy();
	});

	actors = [];
	boxes = [];
}

/**
 * Buttons actions
 */
function leftclick(callback) {
	return function(actor, event) {
		if (event.get_button() !== 1) {
			return null;
		}

		return callback(actor, event);
	}
}

function minimize() {
	let win = Util.getWindow();
	if (!win || win.minimized) {
		WARN('impossible to minimize');
		return;
	}

	win.minimize();
}

function maximize() {
	let win = Util.getWindow();
	if (!win) {
		WARN('impossible to maximize');
		return;
	}

	const MAXIMIZED = Meta.MaximizeFlags.BOTH;
	if (win.get_maximized() === MAXIMIZED) {
		win.unmaximize(MAXIMIZED);
	} else {
		WARN('window shoud already be maximized');
		win.maximize(MAXIMIZED);
	}

	win.activate(global.get_current_time());
}

function close() {
	let win = Util.getWindow();
	if (!win) {
		WARN('impossible to close');
		return;
	}

	win.delete(global.get_current_time());
}

/**
 * Theming
 */
let activeCSS = false;
function loadTheme() {
	let theme = Gtk.Settings.get_default().gtk_theme_name,
		cssPath = GLib.build_filenamev([extensionPath, 'themes', theme, 'style.css']);

	LOG('Load theme ' + theme);
	if (!GLib.file_test(cssPath, GLib.FileTest.EXISTS)) {
		cssPath = GLib.build_filenamev([extensionPath, 'themes/default/style.css']);
	}

	if (cssPath === activeCSS) {
		return;
	}

	unloadTheme();

	// Load the new style
	let cssFile = Gio.file_new_for_path(cssPath);
	St.ThemeContext.get_for_stage(global.stage).get_theme().load_stylesheet(cssFile);

	// Force style update.
	actors.forEach(function(actor) {
		actor.grab_key_focus();
	});

	activeCSS = cssPath;
}

function unloadTheme() {
	if (activeCSS) {
		LOG('Unload ' + activeCSS);

		let cssFile = Gio.file_new_for_path(activeCSS);
		St.ThemeContext.get_for_stage(global.stage).get_theme().unload_stylesheet(cssFile);
		activeCSS = false;
	}
}

/**
 * callbacks
 */
function updateVisibility() {
	// If we have a window to control, then we show the buttons.
	let visible = !Main.overview.visible;
	if (visible) {
		visible = false;
		let win = Util.getWindow();
		if (win) {
			visible = win.decorated;
		}
	}

	actors.forEach(function(actor, i) {
		if (!boxes[i].get_children().length) {
			return;
		}

		if (visible) {
			actor.show();
		} else {
			actor.hide();
		}
	});

	return false;
}

/**
 * Subextension hooks
 */
let extensionPath;
function init(extensionMeta) {
	extensionPath = extensionMeta.path;
}

let wmCallbackIDs = [];
let overviewCallbackIDs = [];
let themeCallbackID = 0;

function enable() {
	loadTheme();
	createButtons();

	overviewCallbackIDs.push(Main.overview.connect('showing', updateVisibility));
	overviewCallbackIDs.push(Main.overview.connect('hidden', updateVisibility));

	let wm = global.window_manager;
	wmCallbackIDs.push(wm.connect('switch-workspace', updateVisibility));
	wmCallbackIDs.push(wm.connect('map', updateVisibility));
	wmCallbackIDs.push(wm.connect('minimize', updateVisibility));
	wmCallbackIDs.push(wm.connect('unminimize', updateVisibility));

	wmCallbackIDs = wmCallbackIDs.concat(Util.onSizeChange(updateVisibility));

	themeCallbackID = Gtk.Settings.get_default().connect('notify::gtk-theme-name', loadTheme);
}

function disable() {
	wmCallbackIDs.forEach(function(id) {
		global.window_manager.disconnect(id);
	});

	overviewCallbackIDs.forEach(function(id) {
		Main.overview.disconnect(id);
	});

	wmCallbackIDs = [];
	overviewCallbackIDs = [];

	if (themeCallbackID !== 0) {
		Gtk.Settings.get_default().disconnect(0);
		themeCallbackID = 0;
	}

	destroyButtons();
	unloadTheme();
}

<commit_msg>Handles empty button-layout value<commit_after>const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Main = imports.ui.main;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const St = imports.gi.St;

const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Util = Me.imports.util;

function LOG(message) {
	// log("[pixel-saver]: " + message);
}

function WARN(message) {
	log("[pixel-saver]: " + message);
}

/**
 * Buttons
 */
const DCONF_META_PATH = 'org.gnome.desktop.wm.preferences';

let actors = [], boxes = [];
function createButtons() {
	// Ensure we do not create buttons twice.
	destroyButtons();

	actors = [
		new St.Bin({ style_class: 'box-bin'}),
		new St.Bin({ style_class: 'box-bin'})
	];

	boxes = [
		new St.BoxLayout({ style_class: 'button-box' }),
		new St.BoxLayout({ style_class: 'button-box' })
	];

	actors.forEach(function(actor, i) {
		actor.add_actor(boxes[i]);
	});

	let order = new Gio.Settings({schema_id: DCONF_META_PATH}).get_string('button-layout');
	LOG('Buttons layout : ' + order);

	if (order.indexOf(':') == -1) {
		LOG('Button layout empty')
		return
	}

	let orders = order.replace(/ /g, '').split(':');

	orders[0] = orders[0].split(',');

	// Check if it's actually exists, if not then create it
	if(typeof orders[1] == 'undefined') orders[1] = '';
	orders[1] = orders[1].split(',');

	const callbacks = {
		minimize : minimize,
		maximize : maximize,
		close    : close
	};

	for (let bi = 0; bi < boxes.length; ++bi) {
		let order = orders[bi],
			box = boxes[bi];

		for (let i = 0; i < order.length; ++i) {
			if (!order[i]) {
				continue;
			}

			if (!callbacks[order[i]]) {
				// Skip if the button's name is not right...
				WARN("\'%s\' is not a valid button.".format(order[i]));
				continue;
			}

			let button = new St.Button({
				style_class: order[i]  + ' window-button',
				track_hover: true
			});

			button.connect('button-release-event', leftclick(callbacks[order[i]]));
			box.add(button);
		}
	}

	Mainloop.idle_add(function () {
		// 1 for activity button and -1 for the menu
		if (boxes[0].get_children().length) {
			Main.panel._leftBox.insert_child_at_index(actors[0], 1);
		}

		if (boxes[1].get_children().length) {
			Main.panel._rightBox.insert_child_at_index(actors[1], Main.panel._rightBox.get_children().length - 1);
		}

		updateVisibility();
		return false;
	});
}

function destroyButtons() {
	actors.forEach(function(actor, i) {
		actor.destroy();
		boxes[i].destroy();
	});

	actors = [];
	boxes = [];
}

/**
 * Buttons actions
 */
function leftclick(callback) {
	return function(actor, event) {
		if (event.get_button() !== 1) {
			return null;
		}

		return callback(actor, event);
	}
}

function minimize() {
	let win = Util.getWindow();
	if (!win || win.minimized) {
		WARN('impossible to minimize');
		return;
	}

	win.minimize();
}

function maximize() {
	let win = Util.getWindow();
	if (!win) {
		WARN('impossible to maximize');
		return;
	}

	const MAXIMIZED = Meta.MaximizeFlags.BOTH;
	if (win.get_maximized() === MAXIMIZED) {
		win.unmaximize(MAXIMIZED);
	} else {
		WARN('window shoud already be maximized');
		win.maximize(MAXIMIZED);
	}

	win.activate(global.get_current_time());
}

function close() {
	let win = Util.getWindow();
	if (!win) {
		WARN('impossible to close');
		return;
	}

	win.delete(global.get_current_time());
}

/**
 * Theming
 */
let activeCSS = false;
function loadTheme() {
	let theme = Gtk.Settings.get_default().gtk_theme_name,
		cssPath = GLib.build_filenamev([extensionPath, 'themes', theme, 'style.css']);

	LOG('Load theme ' + theme);
	if (!GLib.file_test(cssPath, GLib.FileTest.EXISTS)) {
		cssPath = GLib.build_filenamev([extensionPath, 'themes/default/style.css']);
	}

	if (cssPath === activeCSS) {
		return;
	}

	unloadTheme();

	// Load the new style
	let cssFile = Gio.file_new_for_path(cssPath);
	St.ThemeContext.get_for_stage(global.stage).get_theme().load_stylesheet(cssFile);

	// Force style update.
	actors.forEach(function(actor) {
		actor.grab_key_focus();
	});

	activeCSS = cssPath;
}

function unloadTheme() {
	if (activeCSS) {
		LOG('Unload ' + activeCSS);

		let cssFile = Gio.file_new_for_path(activeCSS);
		St.ThemeContext.get_for_stage(global.stage).get_theme().unload_stylesheet(cssFile);
		activeCSS = false;
	}
}

/**
 * callbacks
 */
function updateVisibility() {
	// If we have a window to control, then we show the buttons.
	let visible = !Main.overview.visible;
	if (visible) {
		visible = false;
		let win = Util.getWindow();
		if (win) {
			visible = win.decorated;
		}
	}

	actors.forEach(function(actor, i) {
		if (!boxes[i].get_children().length) {
			return;
		}

		if (visible) {
			actor.show();
		} else {
			actor.hide();
		}
	});

	return false;
}

/**
 * Subextension hooks
 */
let extensionPath;
function init(extensionMeta) {
	extensionPath = extensionMeta.path;
}

let wmCallbackIDs = [];
let overviewCallbackIDs = [];
let themeCallbackID = 0;

function enable() {
	loadTheme();
	createButtons();

	overviewCallbackIDs.push(Main.overview.connect('showing', updateVisibility));
	overviewCallbackIDs.push(Main.overview.connect('hidden', updateVisibility));

	let wm = global.window_manager;
	wmCallbackIDs.push(wm.connect('switch-workspace', updateVisibility));
	wmCallbackIDs.push(wm.connect('map', updateVisibility));
	wmCallbackIDs.push(wm.connect('minimize', updateVisibility));
	wmCallbackIDs.push(wm.connect('unminimize', updateVisibility));

	wmCallbackIDs = wmCallbackIDs.concat(Util.onSizeChange(updateVisibility));

	themeCallbackID = Gtk.Settings.get_default().connect('notify::gtk-theme-name', loadTheme);
}

function disable() {
	wmCallbackIDs.forEach(function(id) {
		global.window_manager.disconnect(id);
	});

	overviewCallbackIDs.forEach(function(id) {
		Main.overview.disconnect(id);
	});

	wmCallbackIDs = [];
	overviewCallbackIDs = [];

	if (themeCallbackID !== 0) {
		Gtk.Settings.get_default().disconnect(0);
		themeCallbackID = 0;
	}

	destroyButtons();
	unloadTheme();
}

<|endoftext|>


<commit_before>var watchID;
var accelerometerOptions = { frequency: 2000 };  // Update every 2 seconds
accelerometerOptions.frequency = 3000; //changed my mind - now 3 seconds

//when the page is created...
$(document).on("pagecreate", "#page1", function () {

	//setup listener for the toggle switch
	$("#flipswitch").on("change", function() {

		if( $(this).val() == "on" ) startSensor();
		else if ( $(this).val() == "off" ) stopSensor();

	});

	//setup listener for the slider
	$("#slider").on("slidestop", function() {

		//the value from the slider is text - it needs to be turned into an integer
		var freq = parseInt($(this).val());

		updateFreq(freq);

	});

});

function startSensor() {
	watchID = navigator.accelerometer.watchAcceleration( accelerometerSuccess, accelerometerError, accelerometerOptions);
}

function stopSensor() {
	navigator.accelerometer.clearWatch(watchID);

	$('#sensorX').val("0");
	$('#sensorY').val("0");
	$('#sensorZ').val("9.81");
	$('#timestamp').val("");
}

function accelerometerSuccess(acceleration) {

	$('#sensorX').val(acceleration.x);
	$('#sensorY').val(acceleration.y);
	$('#sensorZ').val(acceleration.z);
	$('#timestamp').val(acceleration.timestamp);

}

function accelerometerError() {
   alert('Error');
}

function updateFreq(freq) {

	//do something to update freq. here.
}

<commit_msg>update<commit_after>var watchID;
var accelerometerOptions = { frequency: 2000 };  // Update every 2 seconds
accelerometerOptions.frequency = 3000; //changed my mind - now 3 seconds

//when the page is created...
$(document).on("pagecreate", "#page1", function () {

	//setup listener for the toggle switch
	$("#flipswitch").on("change", function() {

		if( $(this).val() == "on" ) startSensor();
		else if ( $(this).val() == "off" ) stopSensor();

	});

	//setup listener for the slider
	$("#slider").on("slidestop", function() {

		//the value from the slider is text - it needs to be turned into an integer
		var freq = parseInt($(this).val());

		updateFreq(freq);

	});

});

function startSensor() {
	watchID = navigator.accelerometer.watchAcceleration( accelerometerSuccess, accelerometerError, accelerometerOptions);
}

function stopSensor() {
	navigator.accelerometer.clearWatch(watchID);

	$('#sensorX').val("0");
	$('#sensorY').val("0");
	$('#sensorZ').val("9.81");
	$('#timestamp').val("");
}

function accelerometerSuccess(acceleration) {

	$('#sensorX').val(acceleration.x);
	$('#sensorY').val(acceleration.y);
	$('#sensorZ').val(acceleration.z);
	$('#timestamp').val(acceleration.timestamp);

}

function accelerometerError() {
   alert('Error');
}

function updateFreq(elephant) {

	accelerometerOptions.frequency = elephant;
	startSensor();
    stopSensor();
	//do something to update freq. here.
}

<|endoftext|>


<commit_before>var util = require('util');
var fs = require('fs');
var http = require('http');
var path = require('path');
var child_process = require('child_process');
var AWS = require('aws-sdk');
var awsConfig = new AWS.Config({});

var GOLANG_CONSTANTS = require('./golang-constants.json');

//TODO: See if https://forums.aws.amazon.com/message.jspa?messageID=633802
// has been updated with new information
process.env.PATH = process.env.PATH + ':/var/task';

// These two names will be dynamically reassigned during archive creation
var SPARTA_BINARY_NAME = 'Sparta.lambda.amd64';
var SPARTA_SERVICE_NAME = 'SpartaService';
// End dynamic reassignment

// This is where the binary will be extracted
var SPARTA_BINARY_PATH = path.join('/tmp', SPARTA_BINARY_NAME);
var MAXIMUM_RESPAWN_COUNT = 5;

// Handlers that are referenced as part of stack creation, via CustomResource
// references.
var PROXIED_MODULES = ['s3', 'sns', 'apigateway', 's3Site'];

// Handle to the active golang process.
var golangProcess = null;
var failCount = 0;

var METRIC_NAMES = {
  CREATED : 'ProcessCreated',
  REUSED: 'ProcessReused',
  TERMINATED: 'ProcessTerminated'
};

function makeRequest(path, event, context) {
  var requestBody = {
    event: event,
    context: context
  };

  var stringified = JSON.stringify(requestBody);

  var contentLength = Buffer.byteLength(stringified, 'utf-8');
  var options = {
    host: 'localhost',
    port: 9999,
    path: path,
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Content-Length': contentLength
    }
  };

  var req = http.request(options, function(res) {
    res.setEncoding('utf8');
    var body = '';
    res.on('data', function(chunk) {
      body += chunk;
    });
    res.on('end', function() {
      // Bridge the NodeJS and golang worlds by including the golang
      // HTTP status text in the error response if appropriate.  This enables
      // the API Gateway integration response to use standard golang StatusText regexp
      // matches to manage HTTP status codes.
      var responseData = {};
      responseData.code = res.statusCode;
      responseData.status = GOLANG_CONSTANTS.HTTP_STATUS_TEXT[res.statusCode.toString()];
      responseData.headers = res.headers;
      responseData.error = (res.statusCode >= 400) ? body : undefined;
      responseData.results = responseData.error ? undefined : body;
      try {
        // TODO: Check content-type before parse attempt
        if (responseData.results)
        {
          responseData.results = JSON.parse(responseData.results);
        }
      } catch (e) {
        // NOP
      }
      var err = responseData.error ? new Error(JSON.stringify(responseData)) : null;
      var resp = err ? null : responseData;
      context.done(err, resp);
    });
  });
  req.on('error', function(e) {
    context.done(e, null);
  });
  req.write(stringified);
  req.end();
}

var log = function(obj_or_string)
{
  if (_.isString(obj_or_string)) {
    try {
      // If it's empty, just skip it...
      if (_.isEmpty(obj_or_string)) {
        return;
      }
      obj_or_string = JSON.parse(obj_or_string);
    } catch (e) {
      // NOP
    }
  }
  if (_.isString(obj_or_string)) {
    obj_or_string = {msg: obj_or_string};
  }
  if (obj_or_string.stack)
  {
    console.error();
  }
  else
  {
    var xformed = {};
    Object.keys(obj_or_string).forEach(function (eachKey) {
      xformed[eachKey.toUpperCase()] = obj_or_string[eachKey];
    });
    console.log(JSON.stringify(xformed));
  }
};

var postMetricCounter = function(metricName, userCallback) {
  var namespace = util.format('Sparta/%s', SPARTA_SERVICE_NAME);

  var params = {
    MetricData: [
      {
        MetricName: metricName,
        Unit: 'Count',
        Value: 1
      },
    ],
    Namespace: namespace
  };
  var cloudwatch = new AWS.CloudWatch(awsConfig);
  var onResult = function(/*e, result */) {
    if (userCallback) {
      userCallback();
    }
  };
  cloudwatch.putMetricData(params, onResult);
};

// Move the file to /tmp to temporarily work around
// https://forums.aws.amazon.com/message.jspa?messageID=583910
var ensureGoLangBinary = function(callback)
{
    try
    {
      fs.statSync(SPARTA_BINARY_PATH);
      setImmediate(callback, null);
    }
    catch (e)
    {
      var command = util.format('cp ./%s %s; chmod +x %s',
                                SPARTA_BINARY_NAME,
                                SPARTA_BINARY_PATH,
                                SPARTA_BINARY_PATH);
      child_process.exec(command, function (err, stdout) {
        if (err)
        {
          console.error(err);
          process.exit(1);
        }
        else
        {
          log(stdout.toString('utf-8'));
          // Post the
        }
        callback(err, stdout);
      });
    }
};

var createForwarder = function(path) {
  var forwardToGolangProcess = function(event, context, metricName)
  {
    if (!golangProcess) {
      ensureGoLangBinary(function() {
        golangProcess = child_process.spawn(SPARTA_BINARY_PATH, ['execute', '--signal', process.pid], {});

        golangProcess.stdout.on('data', function(buf) {
          buf.toString('utf-8').split('\n').forEach(function (eachLine) {
            log(eachLine);
          });
        });
        golangProcess.stderr.on('data', function(buf) {
          buf.toString('utf-8').split('\n').forEach(function (eachLine) {
            log(eachLine);
          });
        });

        var terminationHandler = function(eventName) {
          return function(value) {
            var onPosted = function() {
              console.error(util.format('Sparta %s: %s\n', eventName.toUpperCase(), JSON.stringify(value)));
              failCount += 1;
              if (failCount > MAXIMUM_RESPAWN_COUNT) {
                process.exit(1);
              }
              golangProcess = null;
              forwardToGolangProcess(null, null, METRIC_NAMES.TERMINATED);
            };
            postMetricCounter(METRIC_NAMES.TERMINATED, onPosted);
          };
        };
        golangProcess.on('error', terminationHandler('error'));
        golangProcess.on('exit', terminationHandler('exit'));
        process.on('exit', function() {
          if (golangProcess) {
            golangProcess.kill();
          }
        });
        var golangProcessReadyHandler = function() {
          process.removeListener('SIGUSR2', golangProcessReadyHandler);
          forwardToGolangProcess(event, context, METRIC_NAMES.CREATED);
        };
        process.on('SIGUSR2', golangProcessReadyHandler);
      });
    }
    else if (event && context)
    {
      postMetricCounter(metricName || METRIC_NAMES.REUSED);
      makeRequest(path, event, context);
    }
  };
  return forwardToGolangProcess;
};

var sendResponse = function(event, context, e, results)
{
  try {
    var response = require('cfn-response');
    var data = {
      ERROR: e ? e.toString() : undefined,
      RESULTS: results || undefined
    };
    response.send(event, context, e ? response.FAILED : response.SUCCESS, data);
  }
  catch (eResponse) {
    log('ERROR sending response: ' + eResponse.toString());
  }
};

// CustomResource Configuration exports
PROXIED_MODULES.forEach(function (eachConfig) {
  var exportName = util.format('%sConfiguration', eachConfig);
  exports[exportName] = function(event, context)
  {
    try {
      // If the stack is in update mode, don't delegate
      var proxyTasks = [];
      proxyTasks.push(function (taskCB) {
        var params = {
          StackName: event.StackId
        };
        var awsConfig = new AWS.Config({});
        awsConfig.logger = console;
        var cloudFormation = new AWS.CloudFormation(awsConfig);
        cloudFormation.describeStacks(params, taskCB);
      });

      // Only delegate to the stack if the update is in progress.
      var onStackDescription = function(e, stackDescriptionResponse) {
        if (e)
        {
          sendResponse(event, context, e, null);
        }
        else {
          var stackDescription = stackDescriptionResponse.Stacks ? stackDescriptionResponse.Stacks[0] : {};
          var stackStatus = stackDescription.StackStatus || "";
          if (stackStatus !== "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS")
          {
            try {
              // log({
              //   requestType: event.RequestType,
              //   handler: eachConfig,
              //   event: event
              // });
              var svc = require(util.format('./%s', eachConfig));
              svc.handler(event, context);
            } catch (e) {
              sendResponse(event, context, e, null);
            }
          } else {
            log('Bypassing configurator execution due to status: ' + stackStatus);
            sendResponse(event, context, e, "NOP");
          }
        }
      };
      // Get the current stack status
      var params = {
        StackName: event.StackId
      };
      var cloudFormation = new AWS.CloudFormation(awsConfig);
      cloudFormation.describeStacks(params, onStackDescription);
    } catch (e) {
      console.error('Failed to load configurator:' + e.toString());
      sendResponse(event, context, e, null);
    }
  };
});

// Log the outputs
var envSettings = {
    AWS_SDK : AWS.VERSION,
    NODE_JS: process.version,
    OS: {
      PLATFORM: os.platform(),
      RELEASE: os.release(),
      TYPE: os.type(),
      UPTIME: os.uptime()
    }
};
log(envSettings);

exports.main = createForwarder('/');
// Additional golang handlers to be dynamically appended below
<commit_msg>Only wrap response data in error case<commit_after>var util = require('util');
var fs = require('fs');
var http = require('http');
var path = require('path');
var os = require('os');
var child_process = require('child_process');
var _ = require('underscore');

var AWS = require('aws-sdk');
var awsConfig = new AWS.Config({});

var GOLANG_CONSTANTS = require('./golang-constants.json');

//TODO: See if https://forums.aws.amazon.com/message.jspa?messageID=633802
// has been updated with new information
process.env.PATH = process.env.PATH + ':/var/task';

// These two names will be dynamically reassigned during archive creation
var SPARTA_BINARY_NAME = 'Sparta.lambda.amd64';
var SPARTA_SERVICE_NAME = 'SpartaService';
// End dynamic reassignment

// This is where the binary will be extracted
var SPARTA_BINARY_PATH = path.join('/tmp', SPARTA_BINARY_NAME);
var MAXIMUM_RESPAWN_COUNT = 5;

// Handlers that are referenced as part of stack creation, via CustomResource
// references.
var PROXIED_MODULES = ['s3', 'sns', 'apigateway', 's3Site'];

// Handle to the active golang process.
var golangProcess = null;
var failCount = 0;

var METRIC_NAMES = {
  CREATED : 'ProcessCreated',
  REUSED: 'ProcessReused',
  TERMINATED: 'ProcessTerminated'
};

function makeRequest(path, event, context) {
  var requestBody = {
    event: event,
    context: context
  };
  // If there is a request.event.body element, try and parse it to make
  // interacting with API Gateway a bit simpler.  The .body property
  // corresponds to the data shape set by the *.vtl templates
  if (requestBody && requestBody.event && requestBody.event.body) {
    try
    {
      requestBody.event.body = JSON.parse(requestBody.event.body);
    }
    catch (e)
    {

    }
  }
  var stringified = JSON.stringify(requestBody);
  var contentLength = Buffer.byteLength(stringified, 'utf-8');
  var options = {
    host: 'localhost',
    port: 9999,
    path: path,
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Content-Length': contentLength
    }
  };

  var req = http.request(options, function(res) {
    res.setEncoding('utf8');
    var body = '';
    res.on('data', function(chunk) {
      body += chunk;
    });
    res.on('end', function() {
      // Bridge the NodeJS and golang worlds by including the golang
      // HTTP status text in the error response if appropriate.  This enables
      // the API Gateway integration response to use standard golang StatusText regexp
      // matches to manage HTTP status codes.

      // TODO - need alternative mapping templates for non application/json content-types
      var responseData = {};
      var handlerError = (res.statusCode >= 400) ? new Error(body) : undefined;
      if (handlerError) {
        responseData.code = res.statusCode;
        responseData.status = GOLANG_CONSTANTS.HTTP_STATUS_TEXT[res.statusCode.toString()];
        responseData.headers = res.headers;
        responseData.error = handlerError.toString();
      }
      else {
        try {
          // TODO: Check content-type before parse attempt
          responseData = JSON.parse(body);
        } catch (e) {
          console.log('Request body isn not JSON: ' + e.toString());
          responseData = body;
        }
      }
      var err = handlerError ? new Error(JSON.stringify(responseData)) : null;
      var resp = handlerError ? null : responseData;
      context.done(err, resp);
    });
  });
  req.on('error', function(e) {
    context.done(e, null);
  });
  req.write(stringified);
  req.end();
}

var log = function(obj_or_string)
{
  if (_.isString(obj_or_string)) {
    try {
      // If it's empty, just skip it...
      if (_.isEmpty(obj_or_string)) {
        return;
      }
      obj_or_string = JSON.parse(obj_or_string);
    } catch (e) {
      // NOP
    }
  }
  if (_.isString(obj_or_string)) {
    obj_or_string = {msg: obj_or_string};
  }
  if (obj_or_string.stack)
  {
    console.error();
  }
  else
  {
    var xformed = {};
    Object.keys(obj_or_string).forEach(function (eachKey) {
      xformed[eachKey.toUpperCase()] = obj_or_string[eachKey];
    });
    console.log(JSON.stringify(xformed));
  }
};

var postMetricCounter = function(metricName, userCallback) {
  var namespace = util.format('Sparta/%s', SPARTA_SERVICE_NAME);

  var params = {
    MetricData: [
      {
        MetricName: metricName,
        Unit: 'Count',
        Value: 1
      },
    ],
    Namespace: namespace
  };
  var cloudwatch = new AWS.CloudWatch(awsConfig);
  var onResult = function(/*e, result */) {
    if (userCallback) {
      userCallback();
    }
  };
  cloudwatch.putMetricData(params, onResult);
};

// Move the file to /tmp to temporarily work around
// https://forums.aws.amazon.com/message.jspa?messageID=583910
var ensureGoLangBinary = function(callback)
{
    try
    {
      fs.statSync(SPARTA_BINARY_PATH);
      setImmediate(callback, null);
    }
    catch (e)
    {
      var command = util.format('cp ./%s %s; chmod +x %s',
                                SPARTA_BINARY_NAME,
                                SPARTA_BINARY_PATH,
                                SPARTA_BINARY_PATH);
      child_process.exec(command, function (err, stdout) {
        if (err)
        {
          console.error(err);
          process.exit(1);
        }
        else
        {
          log(stdout.toString('utf-8'));
          // Post the
        }
        callback(err, stdout);
      });
    }
};

var createForwarder = function(path) {
  var forwardToGolangProcess = function(event, context, metricName)
  {
    if (!golangProcess) {
      ensureGoLangBinary(function() {
        golangProcess = child_process.spawn(SPARTA_BINARY_PATH, ['execute', '--signal', process.pid], {});

        golangProcess.stdout.on('data', function(buf) {
          buf.toString('utf-8').split('\n').forEach(function (eachLine) {
            log(eachLine);
          });
        });
        golangProcess.stderr.on('data', function(buf) {
          buf.toString('utf-8').split('\n').forEach(function (eachLine) {
            log(eachLine);
          });
        });

        var terminationHandler = function(eventName) {
          return function(value) {
            var onPosted = function() {
              console.error(util.format('Sparta %s: %s\n', eventName.toUpperCase(), JSON.stringify(value)));
              failCount += 1;
              if (failCount > MAXIMUM_RESPAWN_COUNT) {
                process.exit(1);
              }
              golangProcess = null;
              forwardToGolangProcess(null, null, METRIC_NAMES.TERMINATED);
            };
            postMetricCounter(METRIC_NAMES.TERMINATED, onPosted);
          };
        };
        golangProcess.on('error', terminationHandler('error'));
        golangProcess.on('exit', terminationHandler('exit'));
        process.on('exit', function() {
          if (golangProcess) {
            golangProcess.kill();
          }
        });
        var golangProcessReadyHandler = function() {
          process.removeListener('SIGUSR2', golangProcessReadyHandler);
          forwardToGolangProcess(event, context, METRIC_NAMES.CREATED);
        };
        process.on('SIGUSR2', golangProcessReadyHandler);
      });
    }
    else if (event && context)
    {
      postMetricCounter(metricName || METRIC_NAMES.REUSED);
      makeRequest(path, event, context);
    }
  };
  return forwardToGolangProcess;
};

var sendResponse = function(event, context, e, results)
{
  try {
    var response = require('cfn-response');
    var data = {
      ERROR: e ? e.toString() : undefined,
      RESULTS: results || undefined
    };
    response.send(event, context, e ? response.FAILED : response.SUCCESS, data);
  }
  catch (eResponse) {
    log('ERROR sending response: ' + eResponse.toString());
  }
};

// CustomResource Configuration exports
PROXIED_MODULES.forEach(function (eachConfig) {
  var exportName = util.format('%sConfiguration', eachConfig);
  exports[exportName] = function(event, context)
  {
    try {
      // If the stack is in update mode, don't delegate
      var proxyTasks = [];
      proxyTasks.push(function (taskCB) {
        var params = {
          StackName: event.StackId
        };
        var awsConfig = new AWS.Config({});
        awsConfig.logger = console;
        var cloudFormation = new AWS.CloudFormation(awsConfig);
        cloudFormation.describeStacks(params, taskCB);
      });

      // Only delegate to the stack if the update is in progress.
      var onStackDescription = function(e, stackDescriptionResponse) {
        if (e)
        {
          sendResponse(event, context, e, null);
        }
        else {
          var stackDescription = stackDescriptionResponse.Stacks ? stackDescriptionResponse.Stacks[0] : {};
          var stackStatus = stackDescription.StackStatus || "";
          if (stackStatus !== "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS")
          {
            try {
              // log({
              //   requestType: event.RequestType,
              //   handler: eachConfig,
              //   event: event
              // });
              var svc = require(util.format('./%s', eachConfig));
              svc.handler(event, context);
            } catch (e) {
              sendResponse(event, context, e, null);
            }
          } else {
            log('Bypassing configurator execution due to status: ' + stackStatus);
            sendResponse(event, context, e, "NOP");
          }
        }
      };
      // Get the current stack status
      var params = {
        StackName: event.StackId
      };
      var cloudFormation = new AWS.CloudFormation(awsConfig);
      cloudFormation.describeStacks(params, onStackDescription);
    } catch (e) {
      console.error('Failed to load configurator:' + e.toString());
      sendResponse(event, context, e, null);
    }
  };
});

// Log the outputs
var envSettings = {
    AWS_SDK : AWS.VERSION,
    NODE_JS: process.version,
    OS: {
      PLATFORM: os.platform(),
      RELEASE: os.release(),
      TYPE: os.type(),
      UPTIME: os.uptime()
    }
};
log(envSettings);

exports.main = createForwarder('/');
// Additional golang handlers to be dynamically appended below
<|endoftext|>


<commit_before><commit_msg>Update character.js<commit_after><|endoftext|>


<commit_before>/*

    We currently always use
        - jQuery (or equivalent)
        - underscore (or equivalent),
        - UTIL (wrapper around some useful utility methods, tooltips, logging, etc)

    Alternatives like zepto or lo-dash can be passsed as arguments to the IIFE

*/
(function (global, $, _, undefined) { 'use strict';

    var m = {}; // modules

    var setupEnvironment = function () {
        m.Environment.initialize();
    };

    var registerListeners = function () {
        m.UI.listeners();
        m.TheModel.listeners();
    };

    var registerGlobals = function () {
        m.Environment.globals();
    };

    var registerTips = function () {
        /* UTIL is a utility object that provides, among other things, an abstraction layer
           over the tooltip system for a page -- in this case, tipsy.
           Register the tips we need, and the framework activates the tip system below
        */
        UTIL.registerTip(['.classname','Tiptext'], {gravity: 'w', fade: false, opacity: 1 });
        UTIL.registerTip(['.another-selector','Other tiptext']);
    };

    var last = function () {
        m.UI.last();
        // other "late" things go here
    };

    m = {

        Environment : {

            /* General environmental functions */
            initialize : function () {
                m.Environment.setup();
            },

            /* overall setup, bootstrapping, logging access, checking credentials, modes */
            setup : function () {
                UTIL.setlogging(false);
                m.Environment.doSomething();
            },

            globals : function () {
                global.func_published_as_global = function (a) {
                    var b = do_something_with_a(a);
                    return b;
                };

                global.another_func = function (a) {
                    return ~~a;
                };

                global.UTIL = (function () {

                    var _state = {
                        logging : false;
                    };

                    var f = {

                        setlogging = function (on_off) {
                            _state.logging = !!on_off;
                        },

                        registerTip = function (arg1, arg2) {
                            // set tipsy tip with
                            //      arg1[0] as selector
                            //      arg1[1] as text
                            //      arg2 as config object
                        }

                    };

                    return f;

                }());
            },

            doSomething : function (el) {
                /* if we need to attach/export functions to global scope, do so like this */
                global.a_global_function = function (x) {
                    do_something_with(x);
                };

                return true;
            }

        },

        UI : {

            listeners : function () {
                /* General UI-level listeners go here */
                $('.some-button-area').on('click', '.do-something', m.UI.do_a_thing);
            },

            setup : function () {
                /* things to do early, before nearly everything else has run */
            },

            last : function () {
                /* things to do, trigger, or bind late, after nearly everything else has run */
                registerTips();
                UTIL.activateTips();
            },

            do_a_thing : function (e) {
                e.preventDefault();
                do_something_here();
            }

        },

        /*
        * Lightweight models
        */

        TheModel : {

            listeners : function () {
                $('body').on('click', '.do-something', m.TheModel.something_handler);
                $('.some-class').on('click', m.TheModel.some_class_handler);
            },

            something_handler : function (e) {
                e.preventDefault();
                do_something();
            },

            some_class_handler : function (e) {
                e.preventDefault();
                do_something_else();
            }

        },

        AnotherModel : {

        }

    }; // m

    setupEnvironment();
    registerGlobals();
    registerListeners();
    last();

}(
    window,
    jQuery || $,
    _
    /* undefined */
));
<commit_msg>Proper DOMready waiting; naming<commit_after>/*

    We currently always use
        - jQuery (or equivalent)
        - underscore (or equivalent),
        - UTIL (wrapper around some useful utility methods, tooltips, logging, etc)

    Alternatives like zepto or lo-dash can be passsed as arguments to the IIFE

*/
(function (global, $, _, undefined) { 'use strict';

    var m = {}; // modules

    var setupEnvironment = function () {
        m.Environment.initialize();
    };

    var registerListeners = function () {
        m.UI.listeners();
        m.TheModel.listeners();
    };

    var registerGlobals = function () {
        m.Environment.globals();
    };

    var registerTips = function () {
        /* UTIL is a utility object that provides, among other things, an abstraction layer
           over the tooltip system for a page -- in this case, tipsy.
           Register the tips we need, and the framework activates the tip system below
        */
        UTIL.registerTip(['.classname','Tiptext'], {gravity: 'w', fade: false, opacity: 1 });
        UTIL.registerTip(['.another-selector','Other tiptext']);
    };

    var late = function () {
        m.UI.late();
        // other "late" things go here
    };

    m = {

        Environment : {

            /* General environmental functions */
            initialize : function () {
                m.Environment.setup();
            },

            /* overall setup, bootstrapping, logging access, checking credentials, modes */
            setup : function () {
                UTIL.setlogging(false);
                m.Environment.doSomething();
            },

            globals : function () { // export globals, optionally grouped by categories like "Environment"
                global.func_published_as_global = function (a) {
                    var b = do_something_with_a(a);
                    return b;
                };

                global.another_func = function (a) {
                    return ~~a;
                };

                global.UTIL = (function () {

                    var _state = {
                        logging : false;
                    };

                    var f = {

                        setlogging = function (on_off) {
                            _state.logging = !!on_off;
                        },

                        registerTip = function (arg1, arg2) {
                            // set tipsy tip with
                            //      arg1[0] as selector
                            //      arg1[1] as text
                            //      arg2 as config object
                        }

                    };

                    return f;

                }());
            },

            doSomething : function (el) {
                /* can attach functions to global scope using this pattern as well */
                global.a_global_function = function (x) {
                    do_something_with(x);
                };

                return true;
            }

        },

        UI : {

            listeners : function () {
                /* General UI-level listeners go here */
                $('.some-button-area').on('click', '.do-something', m.UI.do_a_thing);
            },

            setup : function () {
                /* things to do early, before nearly everything else has run */
            },

            late : function () {
                /* things to do, trigger, or bind late, after nearly everything else has run */
                registerTips();
                UTIL.activateTips();
            },

            do_a_thing : function (e) {
                e.preventDefault();
                do_something_here();
            }

        },

        /*
        * Lightweight models
        */

        TheModel : {

            listeners : function () {
                $('body').on('click', '.do-something', m.TheModel.something_handler);
                $('.some-class').on('click', m.TheModel.some_class_handler);
            },

            something_handler : function (e) {
                e.preventDefault();
                do_something();
            },

            some_class_handler : function (e) {
                e.preventDefault();
                do_something_else();
            }

        },

        AnotherModel : {

        }

    }; // m

    $(function () { // wait for domready

        setupEnvironment();
        registerGlobals();
        registerListeners();
        late();

    });

}(
    window,
    jQuery || $,
    _
    /* undefined */
));
<|endoftext|>


<commit_before>
module.exports = {
  variants: {
    items: {
      // keepNames: true,
      resize: {
        mini : '300x200',
        preview: '800x600'
      },
      crop: {
        thumb: '200x200'
      },
      resizeAndCrop: {
        large: {
          resize: '1000x1000',
          crop: '900x900'
        }
      }
    },

    gallery: {
      crop: {
        thumb: '100x100'
      }
    }
  },

  storage: {
    Local: {
      path: '/tmp',
      mode: 0777
    },
    Rackspace: {
      username: 'USERNAME',
      apiKey: 'API_KEY',
      // authUrl: "https://lon.auth.api.rackspacecloud.com",
      container: 'CONTAINER'
    },
    S3: {
      key: 'KEY',
      secret: 'SECRET',
      bucket: 'BUCKET'
      // set `secure: false` if you want to use buckets with characters like .
    }
  },

  debug: true
}
<commit_msg>udpate example config<commit_after>
module.exports = {
  variants: {
    items: {
      // keepNames: true,
      resize: {
        mini : '300x200',
        preview: '800x600'
      },
      crop: {
        thumb: '200x200'
      },
      resizeAndCrop: {
        large: {
          resize: '1000x1000',
          crop: '900x900'
        }
      }
    },

    gallery: {
      crop: {
        thumb: '100x100'
      }
    }
  },

  storage: {
    Local: {
      path: '/tmp',
      mode: 0777
    },
    Rackspace: {
      username: 'USERNAME',
      apiKey: 'API_KEY',
      // authUrl: "https://lon.auth.api.rackspacecloud.com",
      container: 'CONTAINER'
    },
    S3: {
      key: 'KEY',
      secret: 'SECRET',
      bucket: 'BUCKET',
      cdn: 'http://CDN_URL', // (optional)
      storageClass: 'REDUCED_REDUNDANCY' // (optional)
      // set `secure: false` if you want to use buckets with characters like '.' (dot)
    }
  },

  debug: true
}
<|endoftext|>


<commit_before>/*!
 * @license MIT
 * Client side js to use wechat-jssdk, also works with other server side service.
 * https://github.com/JasonBoy/wechat-jssdk
 */

'use strict';

const document = window.document;
const location = window.location;

//default wechat script url
let defaultScriptUrl = location.protocol + '//res.wx.qq.com/open/js/jweixin-1.2.0.js';

//default apis with share-on-moment and share-on-chat
const defaultApiList = ['onMenuShareTimeline', 'onMenuShareAppMessage'];

class WechatJSSDK {
  /**
   * Initialize the WechatJSSDK instance
   * @constructor
   * @param {object} wechatConfig, should contain like:
   *   {
   *      appId: 'xxxx',
   *      timestamp: '',
   *      nonceStr: '',
   *      signature: '',
   *      jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage', ...],
   *      success: function(){}, //sign success callback
   *      error: function(){}, //sign error callback
   *      customUrl: 'http://res.wx.qq.com/open/js/jweixin-1.0.0.js' // set custom weixin script url
   *   }
   * @returns {WechatJSSDK}
   */
  constructor (wechatConfig) {
    //using new WechatJSSDK(config);
    if (this instanceof WechatJSSDK) {
      this.config = wechatConfig || {};
      if (this.config.customUrl) {
        defaultScriptUrl = this.config.customUrl;
        delete this.config.customUrl;
      }
      let apiList = this.config.jsApiList;
      //add more apis if passed in
      if (!apiList || apiList.length <= 0) {
        this.config.jsApiList = defaultApiList;
      } else {
        let i = 0;
        const length = defaultApiList.length;
        for (; i < length; i++) {
          const defaultItem = defaultApiList[i];
          if (apiList.indexOf(defaultItem) < 0) {
            apiList.push(defaultItem);
          }
        }
      }
      this.debug = !!this.config.debug;
      this.loadScript();
      return this;
    }
    return new WechatJSSDK(wechatConfig);
  }

  /**
   * Sign the signature now
   * @param {object} [newSignConfig], debug mode, appId, jsApiList cannot be changed!!!
   *        , should only provide new signature specific config
   * @returns {WechatJSSDK} sdk instance
   */
  signSignature (newSignConfig) {
    const selfConfig = this.config;
    const config = newSignConfig || selfConfig;
    const signConfig = {
      debug: this.debug,
      appId: selfConfig.appId,
      timestamp: config.timestamp || selfConfig.timestamp,
      nonceStr: config.nonceStr || selfConfig.nonceStr,
      signature: config.signature || selfConfig.signature,
      jsApiList: selfConfig.jsApiList.slice(0, selfConfig.jsApiList.length)
    };
    const debug = this.debug;
    if (!window.wx) {
      this.log('wechat js not defined', 'warn');
      return this;
    }
    const wx = window.wx;
    this.wx = wx;
    wx.config(signConfig);
    wx.ready(() => {
      this.log('wx.ready() done!', 'log', true);
      config.success && config.success.call(this, undefined, wx);
    });

    wx.error((err) => {
      this.log('sign error: ' + JSON.stringify(err), 'error', true);
      config.error && config.error.call(this, err, wx);
    });

    return this;
  };

  /**
   * Load wechat js script and sign the signature
   * @returns {WechatJSSDK}
   */
  loadScript () {
    const ele = document.createElement('script');
    ele.type = 'text\/javascript';
    ele.async = true;
    ele.onload = () => {
      this.log('Wechat script loaded successfully!');
      //init the wechat config
      this.signSignature();
    };
    ele.onerror = (err) => {
      this.log('Failed to load wechat script!', 'error');
      this.log(JSON.stringify(err), 'error', true);
    };
    const linkEle = document.getElementsByTagName('script')[0];
    linkEle.parentNode.insertBefore(ele, linkEle);
    ele.src = defaultScriptUrl;
    return this;
  };

  /**
   * Quick way to set custom moment share configs
   * @param {object} info
   * @returns {WechatJSSDK}
   */
  shareOnMoment (info) {
    if (!info) return this;
    return this.callWechatApi('onMenuShareTimeline', info);
  };

  /**
   * Quick way to set custom chat share configs
   * @param {object} info
   * @returns {WechatJSSDK}
   */
  shareOnChat (info) {
    if (!info) return this;
    return this.callWechatApi('onMenuShareAppMessage', info);
  };

  /**
   * Call any wechat api
   * @param {string} apiName
   * @param {object} config specific api config
   * @returns {WechatJSSDK}
   */
  callWechatApi (apiName, config) {
    const debug = this.debug;
    if (!apiName) {
      debug && alert('wechat api not specified!');
      return this;
    }
    if (this.config.jsApiList.indexOf(apiName) < 0) {
      debug && alert('the wechat api [' + apiName + '] you call was not registered, \npls add the api into your [jsApiList] config');
      return this;
    }
    const wx = this.wx || window.wx;
    const customAPI = wx[apiName];
    if (!customAPI || 'function' !== typeof customAPI) {
      debug && alert('no such api [' + apiName + '] found!');
      return this;
    }
    try {
      customAPI(config);
    } catch(e) {
      this.log('call wechat api failed: ', 'error');
      this.log(JSON.stringify(e), 'error');
    }
    return this;
  };

  /**
   * simple wechat-jssdk logger
   * @param {String} msg
   * @param {String} level log method in 'console' object
   * @param alert add additional alert invoke
   */
  log(msg, level, alert) {
    if(!this.debug) return;
    const logger = console[level] || console.log;
    const message = '[wechat-jssdk]-' + msg;
    logger(message);
    if(alert) alert(message);
  }
}

module.exports = WechatJSSDK;

<commit_msg>alert name dupe fix<commit_after>/*!
 * @license MIT
 * Client side js to use wechat-jssdk, also works with other server side service.
 * https://github.com/JasonBoy/wechat-jssdk
 */

'use strict';

const document = window.document;
const location = window.location;

//default wechat script url
let defaultScriptUrl = location.protocol + '//res.wx.qq.com/open/js/jweixin-1.2.0.js';

//default apis with share-on-moment and share-on-chat
const defaultApiList = ['onMenuShareTimeline', 'onMenuShareAppMessage'];

class WechatJSSDK {
  /**
   * Initialize the WechatJSSDK instance
   * @constructor
   * @param {object} wechatConfig, should contain like:
   *   {
   *      appId: 'xxxx',
   *      timestamp: '',
   *      nonceStr: '',
   *      signature: '',
   *      jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage', ...],
   *      success: function(){}, //sign success callback
   *      error: function(){}, //sign error callback
   *      customUrl: 'http://res.wx.qq.com/open/js/jweixin-1.0.0.js' // set custom weixin script url
   *   }
   * @returns {WechatJSSDK}
   */
  constructor (wechatConfig) {
    //using new WechatJSSDK(config);
    if (this instanceof WechatJSSDK) {
      this.config = wechatConfig || {};
      if (this.config.customUrl) {
        defaultScriptUrl = this.config.customUrl;
        delete this.config.customUrl;
      }
      let apiList = this.config.jsApiList;
      //add more apis if passed in
      if (!apiList || apiList.length <= 0) {
        this.config.jsApiList = defaultApiList;
      } else {
        let i = 0;
        const length = defaultApiList.length;
        for (; i < length; i++) {
          const defaultItem = defaultApiList[i];
          if (apiList.indexOf(defaultItem) < 0) {
            apiList.push(defaultItem);
          }
        }
      }
      this.debug = !!this.config.debug;
      this.loadScript();
      return this;
    }
    return new WechatJSSDK(wechatConfig);
  }

  /**
   * Sign the signature now
   * @param {object} [newSignConfig], debug mode, appId, jsApiList cannot be changed!!!
   *        , should only provide new signature specific config
   * @returns {WechatJSSDK} sdk instance
   */
  signSignature (newSignConfig) {
    const selfConfig = this.config;
    const config = newSignConfig || selfConfig;
    const signConfig = {
      debug: this.debug,
      appId: selfConfig.appId,
      timestamp: config.timestamp || selfConfig.timestamp,
      nonceStr: config.nonceStr || selfConfig.nonceStr,
      signature: config.signature || selfConfig.signature,
      jsApiList: selfConfig.jsApiList.slice(0, selfConfig.jsApiList.length)
    };
    const debug = this.debug;
    if (!window.wx) {
      this.log('wechat js not defined', 'warn');
      return this;
    }
    const wx = window.wx;
    this.wx = wx;
    wx.config(signConfig);
    wx.ready(() => {
      this.log('wx.ready() done!', 'log', true);
      config.success && config.success.call(this, undefined, wx);
    });

    wx.error((err) => {
      this.log('sign error: ' + JSON.stringify(err), 'error', true);
      config.error && config.error.call(this, err, wx);
    });

    return this;
  };

  /**
   * Load wechat js script and sign the signature
   * @returns {WechatJSSDK}
   */
  loadScript () {
    const ele = document.createElement('script');
    ele.type = 'text\/javascript';
    ele.async = true;
    ele.onload = () => {
      this.log('Wechat script loaded successfully!');
      //init the wechat config
      this.signSignature();
    };
    ele.onerror = (err) => {
      this.log('Failed to load wechat script!', 'error');
      this.log(JSON.stringify(err), 'error', true);
    };
    const linkEle = document.getElementsByTagName('script')[0];
    linkEle.parentNode.insertBefore(ele, linkEle);
    ele.src = defaultScriptUrl;
    return this;
  };

  /**
   * Quick way to set custom moment share configs
   * @param {object} info
   * @returns {WechatJSSDK}
   */
  shareOnMoment (info) {
    if (!info) return this;
    return this.callWechatApi('onMenuShareTimeline', info);
  };

  /**
   * Quick way to set custom chat share configs
   * @param {object} info
   * @returns {WechatJSSDK}
   */
  shareOnChat (info) {
    if (!info) return this;
    return this.callWechatApi('onMenuShareAppMessage', info);
  };

  /**
   * Call any wechat api
   * @param {string} apiName
   * @param {object} config specific api config
   * @returns {WechatJSSDK}
   */
  callWechatApi (apiName, config) {
    const debug = this.debug;
    if (!apiName) {
      debug && alert('wechat api not specified!');
      return this;
    }
    if (this.config.jsApiList.indexOf(apiName) < 0) {
      debug && alert('the wechat api [' + apiName + '] you call was not registered, \npls add the api into your [jsApiList] config');
      return this;
    }
    const wx = this.wx || window.wx;
    const customAPI = wx[apiName];
    if (!customAPI || 'function' !== typeof customAPI) {
      debug && alert('no such api [' + apiName + '] found!');
      return this;
    }
    try {
      customAPI(config);
    } catch(e) {
      this.log('call wechat api failed: ', 'error');
      this.log(JSON.stringify(e), 'error');
    }
    return this;
  };

  /**
   * simple wechat-jssdk logger
   * @param {String} msg
   * @param {String} level log method in 'console' object
   * @param {boolean} alertMsg add additional alert invoke
   */
  log(msg, level, alertMsg) {
    if(!this.debug) return;
    const logger = console[level] || console.log;
    const message = '[wechat-jssdk]-' + msg;
    logger(message);
    if(alertMsg) window.alert(message);
  }
}

module.exports = WechatJSSDK;

<|endoftext|>


<commit_before>var net = require('net');
var FileSystem = require('fs');
var FileSystemHelper = require('./filesystem_helper');
var Logger = require('./logger');
var Util = require('./util');

var logger = new Logger();

var getBooleanValue = function(value, defaultValue) {
  if (typeof value === 'undefined') {
    return defaultValue;
  }

  // Handle Boolean Values:
  if (value == true || value == false) {
    return value;
  }

  // Handle String Values
  if (typeof value === 'string') {
    var isTrueString = value.toLowerCase() == 'true';
    var isFalseString = value.toLowerCase() == 'false';

    return isTrueString && !isFalseString;
  }

  return defaultValue
};

/**
 * Provides default values and verifies that requied values are set.
 */
var DefaultOptions = function() {}

DefaultOptions.prototype.options = {
  accessLogFile: null,
  cacheDir: null,
  cacheHeader: [],
  ignoreContentType: '',
  ignoreJsonBodyPath: [],
  logLevel: 'info',
  overrideCacheDir: null,
  passthrough: false,
  port: process.env.MOCKINGJAYS_PORT || 9000,
  readOnly: false,
  refresh: false,
  responseHeaderBlacklist: [],
  serverBaseUrl: null,
  transitionConfig: {},
  whiteLabel: false
}

DefaultOptions.prototype.defaultExtras = {
  attemptToCreateCacheDir: true
}

DefaultOptions.prototype.merge = function(options, extraOptions) {
  var extras = extraOptions || this.defaultExtras;
  this._handleAccessLogFile(options);
  this._handlePortDefault(options);
  this._handleRefreshDefault(options);
  this._handleContentTypeDefault(options);
  this._handleBaseCacheDirectoryDefault(options);
  this._handleCacheDirectoryDefault(options, extras);
  this._handleBaseUrlDefault(options);
  this._handleCacheHeaders(options);
  this._handleResponseHeaders(options);
  this._handleLogLevel(options);
  this._handletransitionConfig(options);
  this._handlePassthrough(options);
  this._handleReadOnly(options);
  this._handleWhiteLabel(options);
  this._handleIgnoreJsonBodyPath(options);
  return options;
}

DefaultOptions.prototype._handleAccessLogFile = function (options) {
  var defaults = this.options;
  options.accessLogFile = options.accessLogFile || defaults.accessLogFile;
}

DefaultOptions.prototype._handleRefreshDefault = function (options) {
  options.refresh = getBooleanValue(options.refresh, this.options.refresh)
}

DefaultOptions.prototype._handleReadOnly = function (options) {
  options.readOnly = getBooleanValue(options.readOnly, this.options.readOnly)
}

DefaultOptions.prototype._handlePortDefault = function (options) {
  var defaults = this.options;
  options.port = options.port || defaults.port;
}

DefaultOptions.prototype._handleContentTypeDefault = function (options) {
  var defaults = this.options;
  var blacklist = (options.ignoreContentType || defaults.ignoreContentType)
    .split(',')
    .filter(function (type) {return type !== ''})
    .map(function (type) {return type.trim();})
    .map(function (type) {return type.replace(/\*/g, '.*')});
  options.ignoreContentType = blacklist;
}

DefaultOptions.prototype._handleBaseCacheDirectoryDefault  = function (options, extras) {
  var defaults = this.options;
  // Directory where the cache files can be read from:
  options.overrideCacheDir = options.overrideCacheDir || defaults.overrideCacheDir;

  if (!options.overrideCacheDir) {
    return; // No Base Cache Directory Provided
  }

  if (!FileSystemHelper.directoryExists(options.overrideCacheDir)) {
    logger.warn('Base Cache Directory Does not Exists.')
    logger.warn('Attempting to Create: ', options.overrideCacheDir);
    FileSystemHelper
      .createDirectory(options.overrideCacheDir)
      .catch(function() {
        throw Error("Please Use a Writable Location for the Base Cache Directory.");
      });
  }
}

DefaultOptions.prototype._handleCacheDirectoryDefault = function (options, extras) {
  var defaults = this.options;
  // Directory where the cache files can be read and written to:
  options.cacheDir = options.cacheDir || defaults.cacheDir;
  if (!options.cacheDir) {
    throw Error("cacheDir is required! It can not be empty.");
  }

  if (!FileSystemHelper.directoryExists(options.cacheDir) && extras.attemptToCreateCacheDir) {
    logger.warn('Cache Directory Does not Exists.')
    logger.warn('Attempting to Create: ', options.cacheDir);
    FileSystemHelper
      .createDirectory(options.cacheDir)
      .catch(function() {
        throw Error("Please Use a Writable Location for the Cache Directory.");
      });
  }
}

DefaultOptions.prototype._handleBaseUrlDefault = function (options) {
  var defaults = this.options;

  // The base URL of the server to proxy requests to.
  options.serverBaseUrl = options.serverBaseUrl || defaults.serverBaseUrl;
  if (!options.serverBaseUrl) {
    throw Error("serverBaseUrl is required! It can not be empty.");
  };
}

DefaultOptions.prototype._handleCacheHeaders = function (options) {
  var defaults = this.options;
  if (options.cacheHeader && typeof(options.cacheHeader) === 'string') {
    options.cacheHeader = options.cacheHeader.split(',').map(function(header) { return header.toLowerCase() });
  } else {
    options.cacheHeader = options.cacheHeader || defaults.cacheHeader;
  }
}

DefaultOptions.prototype._handleResponseHeaders = function (options) {
  var defaults = this.options;
  if (options.responseHeaderBlacklist && typeof(options.responseHeaderBlacklist) == 'string') {
    options.responseHeaderBlacklist = options.responseHeaderBlacklist.split(',');
  } else {
    options.responseHeaderBlacklist = options.responseHeaderBlacklist || defaults.responseHeaderBlacklist;
  }
}

DefaultOptions.prototype._handleLogLevel = function (options) {
  var defaults = this.options;
  if (!options.logLevel) {
    options.logLevel = defaults.logLevel;
  }
}

DefaultOptions.prototype._handletransitionConfig = function (options) {
  var defaults = this.options;
  if (!options.transitionConfig) {
    options.transitionConfig = defaults.transitionConfig;
  } else {
    if (typeof(options.transitionConfig) === 'string') {
      options.transitionConfig = Util.parseJSON(FileSystem.readFileSync(options.transitionConfig, {encoding: 'utf-8'}));
    }
  }
}

DefaultOptions.prototype._handlePassthrough = function (options) {
  options.passthrough = getBooleanValue(options.passthrough, this.options.passthrough)
}

DefaultOptions.prototype._handleWhiteLabel = function (options) {
  options.whiteLabel = getBooleanValue(options.whiteLabel, this.options.whiteLabel)
}

DefaultOptions.prototype._handleIgnoreJsonBodyPath = function (options) {
  var defaults = this.options;
  if (options.ignoreJsonBodyPath && typeof(options.ignoreJsonBodyPath) == 'string') {
    options.ignoreJsonBodyPath = options.ignoreJsonBodyPath.split(',');
  } else {
    options.ignoreJsonBodyPath = options.ignoreJsonBodyPath || defaults.ignoreJsonBodyPath;
  }
}

module.exports = DefaultOptions
<commit_msg>Alphabetize Methods for Default Options<commit_after>var net = require('net');
var FileSystem = require('fs');
var FileSystemHelper = require('./filesystem_helper');
var Logger = require('./logger');
var Util = require('./util');

var logger = new Logger();

var getBooleanValue = function(value, defaultValue) {
  if (typeof value === 'undefined') {
    return defaultValue;
  }

  // Handle Boolean Values:
  if (value == true || value == false) {
    return value;
  }

  // Handle String Values
  if (typeof value === 'string') {
    var isTrueString = value.toLowerCase() == 'true';
    var isFalseString = value.toLowerCase() == 'false';

    return isTrueString && !isFalseString;
  }

  return defaultValue
};

/**
 * Provides default values and verifies that requied values are set.
 */
var DefaultOptions = function() {}

DefaultOptions.prototype.options = {
  accessLogFile: null,
  cacheDir: null,
  cacheHeader: [],
  ignoreContentType: '',
  ignoreJsonBodyPath: [],
  logLevel: 'info',
  overrideCacheDir: null,
  passthrough: false,
  port: process.env.MOCKINGJAYS_PORT || 9000,
  readOnly: false,
  refresh: false,
  responseHeaderBlacklist: [],
  serverBaseUrl: null,
  transitionConfig: {},
  whiteLabel: false
}

DefaultOptions.prototype.defaultExtras = {
  attemptToCreateCacheDir: true
}

DefaultOptions.prototype.merge = function(options, extraOptions) {
  var extras = extraOptions || this.defaultExtras;
  this._handleAccessLogFile(options);
  this._handleBaseCacheDirectoryDefault(options);
  this._handleBaseUrlDefault(options);
  this._handleCacheDirectoryDefault(options, extras);
  this._handleCacheHeaders(options);
  this._handleContentTypeDefault(options);
  this._handleIgnoreJsonBodyPath(options);
  this._handleLogLevel(options);
  this._handlePassthrough(options);
  this._handlePortDefault(options);
  this._handleReadOnly(options);
  this._handleRefreshDefault(options);
  this._handleResponseHeaders(options);
  this._handleTransitionConfig(options);
  this._handleWhiteLabel(options);
  return options;
}

DefaultOptions.prototype._handleAccessLogFile = function (options) {
  var defaults = this.options;
  options.accessLogFile = options.accessLogFile || defaults.accessLogFile;
}

DefaultOptions.prototype._handleBaseCacheDirectoryDefault  = function (options, extras) {
  var defaults = this.options;
  // Directory where the cache files can be read from:
  options.overrideCacheDir = options.overrideCacheDir || defaults.overrideCacheDir;

  if (!options.overrideCacheDir) {
    return; // No Base Cache Directory Provided
  }

  if (!FileSystemHelper.directoryExists(options.overrideCacheDir)) {
    logger.warn('Base Cache Directory Does not Exists.')
    logger.warn('Attempting to Create: ', options.overrideCacheDir);
    FileSystemHelper
      .createDirectory(options.overrideCacheDir)
      .catch(function() {
        throw Error("Please Use a Writable Location for the Base Cache Directory.");
      });
  }
}

DefaultOptions.prototype._handleBaseUrlDefault = function (options) {
  var defaults = this.options;

  // The base URL of the server to proxy requests to.
  options.serverBaseUrl = options.serverBaseUrl || defaults.serverBaseUrl;
  if (!options.serverBaseUrl) {
    throw Error("serverBaseUrl is required! It can not be empty.");
  };
}

DefaultOptions.prototype._handleCacheHeaders = function (options) {
  var defaults = this.options;
  if (options.cacheHeader && typeof(options.cacheHeader) === 'string') {
    options.cacheHeader = options.cacheHeader.split(',').map(function(header) { return header.toLowerCase() });
  } else {
    options.cacheHeader = options.cacheHeader || defaults.cacheHeader;
  }
}

DefaultOptions.prototype._handleCacheDirectoryDefault = function (options, extras) {
  var defaults = this.options;
  // Directory where the cache files can be read and written to:
  options.cacheDir = options.cacheDir || defaults.cacheDir;
  if (!options.cacheDir) {
    throw Error("cacheDir is required! It can not be empty.");
  }

  if (!FileSystemHelper.directoryExists(options.cacheDir) && extras.attemptToCreateCacheDir) {
    logger.warn('Cache Directory Does not Exists.')
    logger.warn('Attempting to Create: ', options.cacheDir);
    FileSystemHelper
      .createDirectory(options.cacheDir)
      .catch(function() {
        throw Error("Please Use a Writable Location for the Cache Directory.");
      });
  }
}

DefaultOptions.prototype._handleContentTypeDefault = function (options) {
  var defaults = this.options;
  var blacklist = (options.ignoreContentType || defaults.ignoreContentType)
    .split(',')
    .filter(function (type) {return type !== ''})
    .map(function (type) {return type.trim();})
    .map(function (type) {return type.replace(/\*/g, '.*')});
  options.ignoreContentType = blacklist;
}

DefaultOptions.prototype._handleIgnoreJsonBodyPath = function (options) {
  var defaults = this.options;
  if (options.ignoreJsonBodyPath && typeof(options.ignoreJsonBodyPath) == 'string') {
    options.ignoreJsonBodyPath = options.ignoreJsonBodyPath.split(',');
  } else {
    options.ignoreJsonBodyPath = options.ignoreJsonBodyPath || defaults.ignoreJsonBodyPath;
  }
}

DefaultOptions.prototype._handleLogLevel = function (options) {
  var defaults = this.options;
  if (!options.logLevel) {
    options.logLevel = defaults.logLevel;
  }
}

DefaultOptions.prototype._handlePassthrough = function (options) {
  options.passthrough = getBooleanValue(options.passthrough, this.options.passthrough)
}

DefaultOptions.prototype._handlePortDefault = function (options) {
  var defaults = this.options;
  options.port = options.port || defaults.port;
}

DefaultOptions.prototype._handleReadOnly = function (options) {
  options.readOnly = getBooleanValue(options.readOnly, this.options.readOnly)
}

DefaultOptions.prototype._handleRefreshDefault = function (options) {
  options.refresh = getBooleanValue(options.refresh, this.options.refresh)
}

DefaultOptions.prototype._handleResponseHeaders = function (options) {
  var defaults = this.options;
  if (options.responseHeaderBlacklist && typeof(options.responseHeaderBlacklist) == 'string') {
    options.responseHeaderBlacklist = options.responseHeaderBlacklist.split(',');
  } else {
    options.responseHeaderBlacklist = options.responseHeaderBlacklist || defaults.responseHeaderBlacklist;
  }
}

DefaultOptions.prototype._handleTransitionConfig = function (options) {
  var defaults = this.options;
  if (!options.transitionConfig) {
    options.transitionConfig = defaults.transitionConfig;
  } else {
    if (typeof(options.transitionConfig) === 'string') {
      options.transitionConfig = Util.parseJSON(FileSystem.readFileSync(options.transitionConfig, {encoding: 'utf-8'}));
    }
  }
}

DefaultOptions.prototype._handleWhiteLabel = function (options) {
  options.whiteLabel = getBooleanValue(options.whiteLabel, this.options.whiteLabel)
}

module.exports = DefaultOptions
<|endoftext|>


<commit_before>$(document).ready(function() {
	/*
		Global Variables
	*/
    var json;
    var selectedItems = [];

    /*
    	Updates selection and prices after choosing an item
    */
    function menuPrices(item) {
        var price = parseFloat(item.price);
        var total = getTotal();
        if (total + price > 8.75) {
            var warning = confirm("If you add this you will go over 8.75! OK to continue");
            if (warning) {
                selectedItems[selectedItems.length] = item;
            }
        } else if ((total + price) == 8.75) {
            alert("You've made $8.75! If you add anything else, you will use another meal or flex.");
            selectedItems[selectedItems.length] = item;
        } else {
            selectedItems[selectedItems.length] = item;
        }
        updateList(selectedItems);
        updateTotal();
    }

	/*
	Updates the "total" indicator HTML
	*/
    function updateTotal() {
        document.getElementById("js").innerHTML = currencyFormat(getTotal());
    }

    /*
    	Updates the "selection" indicator HTML
    */
    function updateList() {
        var updatedString = "";
        for (var index in selectedItems) {
            updatedString += selectedItems[index].name + ": " + currencyFormat(selectedItems[index].price) + ' <button class = "selectedItem" id = \"selectedItem' + index + '\">X</button>' + "
";
        }
        document.getElementById("list").innerHTML = updatedString;
    }

    /*
    	Makes the currency value from a float.
    */
    function currencyFormat(number) {
        number = number.toString();
        dollars = number.split('.')[0];
        cents = (number.split('.')[1] || '') + '00';
        dollars = dollars.split('').reverse().join('')
            .replace(/(\d{3}(?!$))/g, '$1,')
            .split('').reverse().join('');
        return '$' + dollars + '.' + cents.slice(0, 2);
    }
    /*
    	Makes an AJAX call to the server, getting JSON to populate the list with.
    */
    $.ajax({
        url: 'api.php', //the script to call to get data
        data: "", //you can insert url argumnets here to pass to api.php
        //for example "id=5&parent=6"
        dataType: 'json', //data format
        success: function(json) //on recieve of reply
        {
        	for (var index in json) {
        		json[index].price  = parseFloat(json[index].price);
        	}
            window.json = json;
            for (var i = 0; i < json.length; i++) {
                if (json[i].category == 'Drink') {
                    $("#drinks_list").append("
 " + json[i].name + ": $" + json[i].price + "
");
                } else if (json[i].category === 'Sandwich' || json[i].category === 'sandwiches') {
                    $("#sandwiches_list").append("
 " + json[i].name + ": $" + json[i].price + "
");
                } else if (json[i].category === 'Breakfast') {
                    $("#breakfast_list").append("
 " + json[i].name + ": $" + json[i].price + "
");
                }
            }
        }
    });

	/*
		Loads a preprepared JSON file for testing purposes.
	*/

    $.getJSON("prices.json", function(json) {
        window.json = json;
        for (var i = 0; i < json.length; i++) {
            if (json[i].category == 'drinks') {
                $("#drinks_list").append("
 " + json[i].name + "
");
            } else if (json[i].category === 'snacks' || json[i].category === 'sandwiches') {
                $("#sandwiches_list").append("
 " + json[i].name + "
");
            } else if (json[i].category === 'breakfast') {
                $("#breakfast_list").append("
 " + json[i].name + "
");
            }
        }
    });

    /*
    	Deletes an item from the list indicator.
    */
    function deleteItem(index) {
        var newPrice = 0;
        for (var i in json) {
        	console.log (selectedItems[index].name + " vs " +  json[i].name);
            if (selectedItems[index].name === json[i].name) {
            	console.log (selectedItems[index].name + " vs " +  json[i].name);
                newPrice = json[i].price;
            }
        }
        selectedItems.splice(index, 1);
        updateList(selectedItems);
        updateTotal();
    }

    /*
    	Listens for clicks on menu items
    */
    $(document).on('click', 'a', function() {
        var id = $(this).attr('id').slice(4);
        var item = window.json[id];
        menuPrices(item);
    });

    $(document).on('click', '.selectedItem', function() {
        var id = $(this).attr('id').slice(12);
        deleteItem(id);
    });

    /*
		GETTERS AND SETTERS
    */

    function getTotal() {
    	var total = 0;
        for (var index in selectedItems){
        	total += selectedItems[index].price;
        }
        return total;
    }
});
<commit_msg>Corrected confirm dialogue<commit_after>$(document).ready(function() {
	/*
		Global Variables
	*/
    var json;
    var selectedItems = [];

    /*
    	Updates selection and prices after choosing an item
    */
    function menuPrices(item) {
        var price = parseFloat(item.price);
        var total = getTotal();
        if (total + price > 8.75) {
            var warning = confirm("If you add this you will go over 8.75! Click 'OK' to continue");
            if (warning) {
                selectedItems[selectedItems.length] = item;
            }
        } else if ((total + price) == 8.75) {
            alert("You've made $8.75! If you add anything else, you will use another meal or flex.");
            selectedItems[selectedItems.length] = item;
        } else {
            selectedItems[selectedItems.length] = item;
        }
        updateList(selectedItems);
        updateTotal();
    }

	/*
	Updates the "total" indicator HTML
	*/
    function updateTotal() {
        document.getElementById("js").innerHTML = currencyFormat(getTotal());
    }

    /*
    	Updates the "selection" indicator HTML
    */
    function updateList() {
        var updatedString = "";
        for (var index in selectedItems) {
            updatedString += selectedItems[index].name + ": " + currencyFormat(selectedItems[index].price) + ' <button class = "selectedItem" id = \"selectedItem' + index + '\">X</button>' + "
";
        }
        document.getElementById("list").innerHTML = updatedString;
    }

    /*
    	Makes the currency value from a float.
    */
    function currencyFormat(number) {
        number = number.toString();
        dollars = number.split('.')[0];
        cents = (number.split('.')[1] || '') + '00';
        dollars = dollars.split('').reverse().join('')
            .replace(/(\d{3}(?!$))/g, '$1,')
            .split('').reverse().join('');
        return '$' + dollars + '.' + cents.slice(0, 2);
    }
    /*
    	Makes an AJAX call to the server, getting JSON to populate the list with.
    */
    $.ajax({
        url: 'api.php', //the script to call to get data
        data: "", //you can insert url argumnets here to pass to api.php
        //for example "id=5&parent=6"
        dataType: 'json', //data format
        success: function(json) //on recieve of reply
        {
        	for (var index in json) {
        		json[index].price  = parseFloat(json[index].price);
        	}
            window.json = json;
            for (var i = 0; i < json.length; i++) {
                if (json[i].category == 'Drink') {
                    $("#drinks_list").append("
 " + json[i].name + ": $" + json[i].price + "
");
                } else if (json[i].category === 'Sandwich' || json[i].category === 'sandwiches') {
                    $("#sandwiches_list").append("
 " + json[i].name + ": $" + json[i].price + "
");
                } else if (json[i].category === 'Breakfast') {
                    $("#breakfast_list").append("
 " + json[i].name + ": $" + json[i].price + "
");
                }
            }
        }
    });

	/*
		Loads a preprepared JSON file for testing purposes.
	*/

    $.getJSON("prices.json", function(json) {
        window.json = json;
        for (var i = 0; i < json.length; i++) {
            if (json[i].category == 'drinks') {
                $("#drinks_list").append("
 " + json[i].name + "
");
            } else if (json[i].category === 'snacks' || json[i].category === 'sandwiches') {
                $("#sandwiches_list").append("
 " + json[i].name + "
");
            } else if (json[i].category === 'breakfast') {
                $("#breakfast_list").append("
 " + json[i].name + "
");
            }
        }
    });

    /*
    	Deletes an item from the list indicator.
    */
    function deleteItem(index) {
        var newPrice = 0;
        for (var i in json) {
        	console.log (selectedItems[index].name + " vs " +  json[i].name);
            if (selectedItems[index].name === json[i].name) {
            	console.log (selectedItems[index].name + " vs " +  json[i].name);
                newPrice = json[i].price;
            }
        }
        selectedItems.splice(index, 1);
        updateList(selectedItems);
        updateTotal();
    }

    /*
    	Listens for clicks on menu items
    */
    $(document).on('click', 'a', function() {
        var id = $(this).attr('id').slice(4);
        var item = window.json[id];
        menuPrices(item);
    });

    $(document).on('click', '.selectedItem', function() {
        var id = $(this).attr('id').slice(12);
        deleteItem(id);
    });

    /*
		GETTERS AND SETTERS
    */

    function getTotal() {
    	var total = 0;
        for (var index in selectedItems){
        	total += selectedItems[index].price;
        }
        return total;
    }
});
<|endoftext|>