<commit_before>/**
 * @class Oskari.mapframework.bundle.mapmodule.plugin.PanButtons
 * Adds on-screen pan buttons on the map. In the middle of the pan buttons is a state reset button.
 * See http://www.oskari.org/trac/wiki/DocumentationBundleMapModulePluginPanButtons
 */
Oskari.clazz.define('Oskari.mapping.mapmodule.plugin.BasicMapModulePlugin',

/**
 * @method create called automatically on construction
 * @static
 */
function(config) {
    this._ctl = null;
    this._el = null;
    this._clazz = null;
    this._element = null;
    this._enabled = true;
    this._index = null;
    this._visible = true;
    this._startPluginHook.unshift('_startPluginBasicImpl');
}, {
    /**
     * @method startPlugin
     * mapmodule.Plugin protocol method.
     * Sets sandbox and registers self to sandbox. Constructs the plugin UI and displays it.
     * @param {Oskari.mapframework.sandbox.Sandbox} sandbox
     */
    _startPluginBasicImpl : function (sandbox) {
        /*
        this._element = this._createControlElement();
        this._ctl = this.createControlAdapter(this._element);
        this.getMapModule().addMapControl(this._pluginName,this._ctl);

        me._create();
        // There's a possibility these were set before the plugin was started.
        me.setEnabled(me._enabled);
        me.setVisible(me._visible);
        var element = me.getElement();
        if (element) {
            element.attr("data-clazz", me.getClazz());
        }*/
        console.log('it works!');
    },

    /**
     * @method stopPlugin
     * mapmodule.Plugin protocol method.
     * Unregisters self from sandbox and removes plugins UI from screen.
     *
     * @param {Oskari.mapframework.sandbox.Sandbox} sandbox
     */
    _stopPluginImpl : function (sandbox) {
        this.getMapModule().removeMapControl(this._pluginName,this._ctl);
        this._ctl = null;

        this._destroyControlElement();

        if (me._element) {
            me._element.remove();
            me._element = null;
        }
    },

    /**
     * @method getClazz
     * @return {String} Plugin class
     */
    getClazz: function () {
        // Throw a fit if clazz is not set, it'd probably break things.
        if (this._clazz === null || this._clazz === undefined) {
            throw "No clazz provided for " + this.getName() + "!";
        }
        return this._clazz;
    },

    /**
     * @method getElement
     * @return {jQuery} Plugin jQuery element or null/undefined if no element has been set
     */
    getElement: function () {
        // element should be created in startPlugin and only destroyed in stopPlugin
        // i.e. don't start & stop the plugin to refresh it.
        return this._element;
    },

    /**
     * @method getIndex Returs the plugin's preferred position in the container
     * @return {Number} Plugin's preferred position in container
     */
    getIndex: function () {
        // i.e. position
        return this._index;
    },

    /**
     * @method getConfig Gets the plugin's config
     * @return {Object}  Plugin's configuration (a clone, use setConfig if you want to change the plugin's config)
     */
    getConfig: function () {
        // use this when saving published map so we won't have to keep a separate copy in the publisher
        var ret = {};
        if (this._config) {
            // return a clone so people won't muck about with the config...
            return jQuery.extend(true, ret, this._config);
        }
        return ret;
    },

    /**
     * @method setConfig       Sets the plugin's config
     * @param  {Object} config Config
     */
    setConfig: function (config) {
        this._config = config;
        // take new conf to use
        this._refresh();
    },

    /**
     * @method _refresh Called after a configuration change. Implement if needed.
     */
    _refresh: function () {},

    /**
     * @method getLocation Gets the plugin's location from its config
     * @return {String}    Plugin's location
     */
    getLocation: function () {
        var ret = null;
        if (this._config.location) {
            ret = this._config.location.classes;
        }
        return ret;
    },

    /**
     * @method setLocation      Set the plugin's location
     * @param {String} location Location
     */
    setLocation: function (location) {
        var me = this;
        if (!me._config) {
            me._config = {};
        }
        if (!me._config.location) {
            me._config.location = {};
        }
        me._config.location.classes = location;
        if (me.getElement()) {
            me.getMapModule().setMapControl(me.getElement(), location, me.getIndex());
        }
    },

    /**
     * @method setColorScheme      Set the plugin's color scheme. Implement if needed. This will be deprecated if/when we move this to a map-level property
     * @param {Object} colorScheme Magical object with some colors and classes and whatnot...
     */
    _setColorScheme: function (colorScheme) {},

    /**
     * @method setFont      Set the plugin's font. Implement if needed. This will be deprecated if/when we move this to a map-level property
     * @param {String} font Font ID
     */
    _setFont: function (font) {},

    /**
     * @method setStyle Set the plugin's style. Implement if needed. This will be deprecated if/when we move this to a map-level property
     * @param {Object} style Magical object with some widths and whatnot...
     */
    _setStyle: function (style) {},

    /**
     * @method hasUI
     * This plugin has an UI so always returns true
     * @return {Boolean} true
     */
    hasUI : function() {
        return true;
    },

    /* IMPL */

    _createControlElement : function() {},
    _destroyControlElement : function() {},
    createControlAdapter : function(el) {
        /* this._el.get()[0] */

    },
    /**
     * @method _toggleControls Enable/disable plugin controls. Used in map layout edit mode.
     * @param {Boolean} enable Whether the controls should be enabled or disabled.
     */
    _toggleUIControls: function (enable) {
        // implement if needed... don't trust this._enabled, set the state even if enable === this._enabled
    },

    /**
     * @method setEnabled      Enable/Disable plugin controls.
     * @param {Boolean} enable Whether the controls should be enabled or disabled.
     */
    setEnabled: function (enabled) {
        // toggle controls
        this._toggleUIControls(enabled);
        this._enabled = enabled;
    },

    /**
     * @method getEnabled Are the plugin's controls enabled
     * @return {Boolean}  True if plugin's tools are enabled
     */
    getEnabled: function () {
        return this._enabled;
    },

    /**
     * @method setVisible
     * Set the plugin UI's visibility
     * @param {Boolean} visible Whether the UI should be visible or hidden
     */
    setVisible: function (visible) {
        // toggle element
        if (this._element) {
            this._element.toggle(visible);
        }
        this._visible = visible;
    },

    /**
     * @method getVisible Is the plugin's UI visible
     * @return {Boolean}  True if plugin is visible
     */
    getVisible: function () {
        return this._visible;
    }
}, {
    /**
     * @property {String[]} protocol
     * @static
     */
    'protocol' : ["Oskari.mapframework.module.Module", "Oskari.mapframework.ui.module.common.mapmodule.Plugin"],
    "extend" : ["Oskari.mapping.mapmodule.plugin.AbstractMapModulePlugin"]
});
<commit_msg>[AH-957] Modified map-module to extend src/mapping/mapmodule/AbstractMapModule.js. Reorganized files in src to be modified later.<commit_after>/**
 * @class Oskari.mapframework.bundle.mapmodule.plugin.PanButtons
 * Adds on-screen pan buttons on the map. In the middle of the pan buttons is a state reset button.
 * See http://www.oskari.org/trac/wiki/DocumentationBundleMapModulePluginPanButtons
 */
Oskari.clazz.define('Oskari.mapping.mapmodule.plugin.BasicMapModulePlugin',

/**
 * @method create called automatically on construction
 * @static
 */
function(config) {
    this._ctl = null;
    this._el = null;
    this._clazz = null;
    this._element = null;
    this._enabled = true;
    this._index = null;
    this._visible = true;
}, {
    /**
     * @method startPlugin
     * mapmodule.Plugin protocol method.
     * Sets sandbox and registers self to sandbox. Constructs the plugin UI and displays it.
     * @param {Oskari.mapframework.sandbox.Sandbox} sandbox
     */
    _startPluginBasicImpl : function (sandbox) {
        this._element = this._createControlElement();
        this._ctl = this.createControlAdapter(this._element);
        this.getMapModule().addMapControl(this._pluginName,this._ctl);

        me._create();
        // There's a possibility these were set before the plugin was started.
        me.setEnabled(me._enabled);
        me.setVisible(me._visible);
        var element = me.getElement();
        if (element) {
            element.attr("data-clazz", me.getClazz());
        }
    },

    /**
     * @method stopPlugin
     * mapmodule.Plugin protocol method.
     * Unregisters self from sandbox and removes plugins UI from screen.
     *
     * @param {Oskari.mapframework.sandbox.Sandbox} sandbox
     */
    _stopPluginImpl : function (sandbox) {
        this.getMapModule().removeMapControl(this._pluginName,this._ctl);
        this._ctl = null;

        this._destroyControlElement();

        if (me._element) {
            me._element.remove();
            me._element = null;
        }
    },

    /**
     * @method getClazz
     * @return {String} Plugin class
     */
    getClazz: function () {
        // Throw a fit if clazz is not set, it'd probably break things.
        if (this._clazz === null || this._clazz === undefined) {
            throw "No clazz provided for " + this.getName() + "!";
        }
        return this._clazz;
    },

    /**
     * @method getElement
     * @return {jQuery} Plugin jQuery element or null/undefined if no element has been set
     */
    getElement: function () {
        // element should be created in startPlugin and only destroyed in stopPlugin
        // i.e. don't start & stop the plugin to refresh it.
        return this._element;
    },

    /**
     * @method getIndex Returs the plugin's preferred position in the container
     * @return {Number} Plugin's preferred position in container
     */
    getIndex: function () {
        // i.e. position
        return this._index;
    },

    /**
     * @method getConfig Gets the plugin's config
     * @return {Object}  Plugin's configuration (a clone, use setConfig if you want to change the plugin's config)
     */
    getConfig: function () {
        // use this when saving published map so we won't have to keep a separate copy in the publisher
        var ret = {};
        if (this._config) {
            // return a clone so people won't muck about with the config...
            return jQuery.extend(true, ret, this._config);
        }
        return ret;
    },

    /**
     * @method setConfig       Sets the plugin's config
     * @param  {Object} config Config
     */
    setConfig: function (config) {
        this._config = config;
        // take new conf to use
        this._refresh();
    },

    /**
     * @method _refresh Called after a configuration change. Implement if needed.
     */
    _refresh: function () {},

    /**
     * @method getLocation Gets the plugin's location from its config
     * @return {String}    Plugin's location
     */
    getLocation: function () {
        var ret = null;
        if (this._config.location) {
            ret = this._config.location.classes;
        }
        return ret;
    },

    /**
     * @method setLocation      Set the plugin's location
     * @param {String} location Location
     */
    setLocation: function (location) {
        var me = this;
        if (!me._config) {
            me._config = {};
        }
        if (!me._config.location) {
            me._config.location = {};
        }
        me._config.location.classes = location;
        if (me.getElement()) {
            me.getMapModule().setMapControl(me.getElement(), location, me.getIndex());
        }
    },

    /**
     * @method setColorScheme      Set the plugin's color scheme. Implement if needed. This will be deprecated if/when we move this to a map-level property
     * @param {Object} colorScheme Magical object with some colors and classes and whatnot...
     */
    _setColorScheme: function (colorScheme) {},

    /**
     * @method setFont      Set the plugin's font. Implement if needed. This will be deprecated if/when we move this to a map-level property
     * @param {String} font Font ID
     */
    _setFont: function (font) {},

    /**
     * @method setStyle Set the plugin's style. Implement if needed. This will be deprecated if/when we move this to a map-level property
     * @param {Object} style Magical object with some widths and whatnot...
     */
    _setStyle: function (style) {},

    /**
     * @method hasUI
     * This plugin has an UI so always returns true
     * @return {Boolean} true
     */
    hasUI : function() {
        return true;
    },

    /* IMPL */

    _createControlElement : function() {},
    _destroyControlElement : function() {},
    createControlAdapter : function(el) {
        /* this._el.get()[0] */

    },
    /**
     * @method _toggleControls Enable/disable plugin controls. Used in map layout edit mode.
     * @param {Boolean} enable Whether the controls should be enabled or disabled.
     */
    _toggleUIControls: function (enable) {
        // implement if needed... don't trust this._enabled, set the state even if enable === this._enabled
    },

    /**
     * @method setEnabled      Enable/Disable plugin controls.
     * @param {Boolean} enable Whether the controls should be enabled or disabled.
     */
    setEnabled: function (enabled) {
        // toggle controls
        this._toggleUIControls(enabled);
        this._enabled = enabled;
    },

    /**
     * @method getEnabled Are the plugin's controls enabled
     * @return {Boolean}  True if plugin's tools are enabled
     */
    getEnabled: function () {
        return this._enabled;
    },

    /**
     * @method setVisible
     * Set the plugin UI's visibility
     * @param {Boolean} visible Whether the UI should be visible or hidden
     */
    setVisible: function (visible) {
        // toggle element
        if (this._element) {
            this._element.toggle(visible);
        }
        this._visible = visible;
    },

    /**
     * @method getVisible Is the plugin's UI visible
     * @return {Boolean}  True if plugin is visible
     */
    getVisible: function () {
        return this._visible;
    }
}, {
    /**
     * @property {String[]} protocol
     * @static
     */
    'protocol' : ["Oskari.mapframework.module.Module", "Oskari.mapframework.ui.module.common.mapmodule.Plugin"],
    "extend" : ["Oskari.mapping.mapmodule.plugin.AbstractMapModulePlugin"]
});
<|endoftext|>


<commit_before>(function (global, $, _) {
	'use strict';
	// Style Guide
	// All jQuery objects are prefixed with `$`
	global.Utils = _.extend( (window.Utils || {}), {

		// make sure that all styles are added with inline css rather than tags.
		styleWithCss: function() {
			if (!document.queryCommandState('styleWithCSS')) {
				document.execCommand('styleWithCSS', null, true) // make sure that
				// contenteditable regions use styles not html markup.
			}
		},

	});

	var defaultButtons = ['bold', 'italic', 'strikethrough', 'underline'],// 'insertunorderedlist', 'insertorderedlist', 'outdent', 'indent', 'justifyleft', 'justifycenter', 'justifyright', 'justifyfull', 'undo', 'redo'],
	fontList = [],
	buttonGroups = {
		text: {
			bold: {icon: 'bold', desc: 'Bold (Ctrl/Cmd+B)'},
			italic: {icon: 'italic', desc: ''},
			strikethrough: {icon: 'strikethrough', desc: 'Strikethrough'},
			underline: {icon: 'underline' , desc: 'Underline (Ctrl/Cmd+U)'}
		},
		lists: {

		},
		align: {},
		custom: {
			atag: { icon: 'caret', },
			ptag: { icon: 'caret', }
		},
		font:{icon: 'font', fonts: fontList},
		color: {icon: 'circle'} // use custom bootstrap data.
	},
	pDefaults = {
		style: {
			"font-size": "13px",
			"font-family": "Verdana, arial, sans-serif",
			"font-weight": "normal",
			"font-style": "normal",
			"line-height": "17px",
			"text-align": "center",
			"margin": "0px auto 10px",
			"padding": "10px",
			"color": "#000",
		}
	},
	aDefaults = {
		style: {
			"font-weight": "bold",
			"text-decoration": "none",
			"color": "#000"
		},
		url: "",
		clickref: "Link",
		onclickOverride: null,
	};

	$.fn.vePersonality = function (options) {

		var $editor = this,
		$textButtons,
		toolbarHtml = '
 THIS IS AWESOME
',
		textEditHtml = function () {
			var htmlString = '<button class="btn" data-edit="<% command %>" title="" data-original-title="<%= desc %>"><i class="fa fa-<%= icon %>">',
			outputString = ''
			_.forEach(buttonGroups.text, function(val, key){
				var data = {command: key, desc: val.desc, icon: val.icon}
				outputString += _.template(htmlString, data)
			});
			return outputString;
		},

		createButtonGroup = function(html) {
			var btnGroup = $('
').html(html);
			return btnGroup
		},

		changePosition = function(pos, $toolbar) {
			$toolbar.animate({'top': pos.y, 'left': pos.x}, { queue: false });
		},

		updateToolbar = function( e ) {
			e.stopPropagation();
			var $toolbar = $(options.toolbarSelector);
			if(!$toolbar.length) {
				$toolbar = $(toolbarHtml).css({zIndex: 100000, position: 'absolute'});
				document.body.appendChild($toolbar[0])
				// TODO store data (current selector, atag and ptag data on $editor)
			}

			// Bind bodyclick events
			$('body').off('mousedown.toolbar').on('mousedown.toolbar', function(e) {
				var target = e.target || e.srcElement; // for IE
				if($(target).not(options.toolbarSelector +', ' + options.toolbarSelector + ' *')){
					$toolbar.remove();
					$(this).off('mousedown.toolbar');
				}

				// Turn off the bindings on the model.

			});

			var $textButtons = createButtonGroup(textEditHtml());
			$toolbar.append($textButtons);
			var newPosition = {x: e.pageX - 15, y: e.pageY - 80};
			changePosition(newPosition, $toolbar);

		},

		options = $.extend({}, $.fn.vePersonality.defaults, options);
		$editor.attr('contenteditable', true)
		.on('mousedown.editor', function( e ){
			updateToolbar( e );

		}).data({atag: options.atag, ptag: options.ptag});

		return this;
	};
	$.fn.vePersonality.defaults = {
		toolbarSelector: '[data-role=editor-toolbar]',
		atag: aDefaults,
		ptag: pDefaults,
		buttons: defaultButtons,

	};
}(this, window.jQuery, window._));
<commit_msg>changes added<commit_after>(function (global, $, _) {
	'use strict';
	// Style Guide
	// All jQuery objects are prefixed with `$`
  // make sure that all styles are added with inline css rather than tags.

	var defaultButtons = ['bold', 'italic', 'strikethrough', 'underline'],// 'insertunorderedlist', 'insertorderedlist', 'outdent', 'indent', 'justifyleft', 'justifycenter', 'justifyright', 'justifyfull', 'undo', 'redo'],
	fontList = [],
	buttonGroups = {
		text: {
			bold: {icon: 'bold', desc: 'Bold (Ctrl/Cmd+B)'},
			italic: {icon: 'italic', desc: ''},
			strikethrough: {icon: 'strikethrough', desc: 'Strikethrough'},
			underline: {icon: 'underline' , desc: 'Underline (Ctrl/Cmd+U)'}
		},
		lists: {

		},
		align: {},
		custom: {
			atag: { icon: 'caret', },
			ptag: { icon: 'caret', }
		},
		font:{icon: 'font', fonts: fontList},
		color: {icon: 'circle'} // use custom bootstrap data.
	},
	pDefaults = {
		style: {
			"font-size": "13px",
			"font-family": "Verdana, arial, sans-serif",
			"font-weight": "normal",
			"font-style": "normal",
			"line-height": "17px",
			"text-align": "center",
			"margin": "0px auto 10px",
			"padding": "10px",
			"color": "#000",
		}
	},
	aDefaults = {
		style: {
			"font-weight": "bold",
			"text-decoration": "none",
			"color": "#000"
		},
		url: "",
		clickref: "Link",
		onclickOverride: null,
	};

	$.fn.vePersonality = function (userOptions) {

		var $editor = this,
				options,
        selectedRange,
        toolbarBtnSelector = 'button[data-edit]',
        $textButtons,
        toolbarHtml = '

',

        styleWithCss = function() {
          if (!document.queryCommandState('styleWithCSS')) {
            document.execCommand('styleWithCSS', null, true); // make sure that
            // contenteditable regions use styles not html markup.
          }
        },

        execCommand = function (commandWithArgs, valueArg) {
          var commandArr = commandWithArgs.split(' '),
          command = commandArr.shift(),
          args = commandArr.join(' ') + (valueArg || '');
          document.execCommand(command, 0, args);
          restyleToolbar();
        },

        getCurrentRange = function () {
          var sel = window.getSelection();
          if (sel.getRangeAt && sel.rangeCount) {
            return sel.getRangeAt(0);
          }
        },
        saveSelection = function () {
          selectedRange = getCurrentRange();
        },
        restoreSelection = function () {
          var selection = window.getSelection();
          if (selectedRange) {
            try {
              selection.removeAllRanges();
            } catch (ex) {
              document.body.createTextRange().select();
              document.selection.empty();
            }

            selection.addRange(selectedRange);
          }
        },

        atagHtml = function(styles) {
          var atagString = '<div class="btn-group'
        }

        ptagHtml = function(styles) {
          var ptagString = '
<button type="button" class="btn btn-default">Dropup</button><button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">Toggle Dropdown</button>

';
          var styleString = '

<input type="text" value="<%= styleName %>" class="form-control" placeholder="Style Name">

<input type="text" value="<%= styleValue %>" class="form-control" placeholder="Style Value">
';

  				var outputStyleString = '';

        },

        textEditHtml = function () {
          var htmlString = '<button class="btn btn-default" data-edit="<%= command %>" title="" data-original-title="<%= desc %>"><i class="fa fa-<%= icon %>">',

          var outputString = '';
          _.forEach(buttonGroups.text, function(val, key){
            var data = {command: key, desc: val.desc, icon: val.icon};
            outputString += _.template(htmlString, data);
          });
          return outputString;
        },

        createButtonGroup = function(html) {
          var btnGroup = $('
').html(html);
          return btnGroup;
        },

        changePosition = function(pos, $toolbar) {
          $toolbar.animate({'top': pos.y, 'left': pos.x}, { queue: false });
        },

				restyleToolbar = function() {
          $(options.toolbarSelector).find(toolbarBtnSelector).each(function () {
          var command = $(this).data('edit');
          if (document.queryCommandState(command)) {
            $(this).addClass('btn-primary').removeClass('btn-default');
          } else {
            $(this).removeClass('btn-primary').addClass('btn-default');
          }
        });
        },
        updateToolbar = function( e , updatePosition) {
          e.stopPropagation();
          var $toolbar = $(options.toolbarSelector);
          if(!$toolbar.length) {

            // Create the toolbar that is slightly above the editor touch point.
            $toolbar = $(toolbarHtml).css({zIndex: 100000, position: 'absolute'});
            var $textButtons = createButtonGroup(textEditHtml());
            // set up text buttons.
            $toolbar.append($textButtons);
            document.body.appendChild($toolbar[0]);
            // TODO store data (current selector, atag and ptag data on $editor)
          }

          // Bind bodyclick events
          $('body').off('mousedown.toolbar').on('mousedown.toolbar', function(e) {
            var target = e.target || e.srcElement; // for IE
            if($(target).not(options.toolbarSelector +', ' + options.toolbarSelector + ' *').length){
              $toolbar.remove();
              $(this).off('mousedown.toolbar');
            }

            // Turn off the bindings on the model.

          });

          bindToolbar($toolbar)

					if (updatePosition) {
            var newPosition = {x: e.pageX - 15, y: e.pageY - 100};
            changePosition(newPosition, $toolbar);
          }
        },

        bindToolbar = function (toolbar, options) {
          toolbar.find(toolbarBtnSelector).click(function () {
            restoreSelection();
            $editor.focus();
            execCommand($(this).data('edit'));
            saveSelection();
          });
          toolbar.find('[data-toggle=dropdown]').click(restoreSelection);
        },

        options = $.extend({}, $.fn.vePersonality.defaults, userOptions);

        styleWithCss(); // Set the styles to be done CSS.
        $editor.attr('contenteditable', true)
        .on('mouseup keyup mouseout', function (e) {
          saveSelection();
          updateToolbar(e, false);
        }).on('paste',function(e) { // paste defaults to plain text
          e.preventDefault();
          var text = (e.originalEvent || e).clipboardData.getData('text/plain') || prompt('Paste something..');
          document.execCommand('insertText', false, text);
        })
        .on('mousedown.editor', function( e ){
          saveSelection();
          updateToolbar( e, true );
        }).data({atag: options.atag, ptag: options.ptag});

		return this;
	};
	$.fn.vePersonality.defaults = {
		toolbarSelector: '[data-role=editor-toolbar]',
		atag: aDefaults,
		ptag: pDefaults,
		buttons: defaultButtons,

	};
}(this, window.jQuery, window._));
<|endoftext|>


<commit_before>'use strict';

var async     = require('async');
var fs        = require('fs');
var net       = require('net');
var net_utils = require('./net_utils');

exports.register = function (done) {
    var plugin = this;

    plugin.load_geoip_ini();

    var loadIt = function (fName, iterDone) {
        plugin[fName](iterDone);
    };
    var finalCb = function () {
        // calls done() only when testing
        if (done && typeof(done) === 'function') done();
    };
    async.some(['load_maxmind', 'load_geoip_lite'], loadIt, finalCb);
};

exports.load_geoip_ini = function () {
    var plugin = this;
    plugin.cfg = plugin.config.get('connect.geoip.ini', {
            booleans: [
                '+main.show_city',
                '+main.show_region',
                '-main.calc_distance',
            ],
        },
        plugin.load_geoip_ini
    );
};

exports.load_maxmind = function (loadDone) {
    var plugin = this;

    try {
        plugin.maxmind = require('maxmind');
    }
    catch (e) {
        plugin.logerror(e);
        plugin.logerror("unable to load maxmind, try\n\n\t'npm install -g maxmind'\n\n");
        return loadDone(false);
    }

    var dbs = ['GeoIPCity', 'GeoIP', 'GeoIPv6',  'GeoIPASNum', 'GeoISP',
               'GeoIPNetSpeedCell',  'GeoIPOrg', 'GeoLiteCityV6'];
    var dbsFound = [];

    var fsDone = function (err) {
        if (err) { plugin.logerror(err); }
        plugin.maxmind.dbsLoaded = dbsFound.length;
        if (dbsFound.length === 0) {
            plugin.logerror('no GeoIP Dbs!');
            return loadDone(false);
        }
        plugin.maxmind.init(dbsFound, {indexCache: true, checkForUpdates: true});
        plugin.register_hook('connect',     'lookup_maxmind');
        plugin.register_hook('data_post',   'add_geoip_headers');
        loadDone(true);
    };

    var dbdir = plugin.cfg.main.dbdir || '/usr/local/share/GeoIP/';
    var fsIter = function (file, iterDone) {
        var path = dbdir + file + '.dat';

        fs.exists(path, function (exists) {
            if (!exists) return iterDone();
            dbsFound.push(path);
            iterDone();
        });
    };

    async.each(dbs, fsIter, fsDone);
};

exports.load_geoip_lite = function (done) {
    var plugin = this;

    try {
        plugin.geoip = require('geoip-lite');
    }
    catch (e) {
        plugin.logerror(e);
        plugin.logerror("unable to load geoip-lite, try\n\n" +
                "\t'npm install -g geoip-lite'\n\n");
        return done(false);
    }

    if (!plugin.geoip) {
        // geoip-lite dropped node 0.8 support, it may not have loaded
        console.logerror('unable to load geoip-lite');
        return done(false);
    }

    plugin.register_hook('connect',     'lookup_geoip');
    plugin.register_hook('data_post',   'add_geoip_headers');

    return done(true);
};

exports.lookup_maxmind = function (next, connection) {
    var plugin = this;

    if (!plugin.maxmind) { return next(); }
    if (!plugin.maxmind.dbsLoaded) { return next(); }

    var ip = connection.remote_ip;
    var show = [];
    var loc = plugin.get_geoip_maxmind(ip);
    if (loc) {
        connection.results.add(plugin, {continent: loc.continentCode});
        connection.results.add(plugin, {country: loc.countryCode || loc.code});
        show.push(loc.continentCode);
        show.push(loc.countryCode);
        if (loc.city) {
            connection.results.add(plugin, {region: loc.region});
            connection.results.add(plugin, {city: loc.city});
            connection.results.add(plugin, {ll: [loc.latitude, loc.longitude]});
            if (plugin.cfg.main.show_region) { show.push(loc.region); }
            if (plugin.cfg.main.show_city  ) { show.push(loc.city); }
        }
    }

    var asn = plugin.maxmind.getAsn(ip);
    if (asn) {
        var match = asn.match(/^(?:AS)([0-9]+)\s+(.*)$/);
        connection.results.add(plugin, {asn: match[1]});
        connection.results.add(plugin, {asn_org: match[2]});
    }

    if (!loc || !plugin.cfg.main.calc_distance) {
        connection.results.add(plugin, {human: show.join(', '), emit:true});
        return next();
    }

    plugin.calculate_distance(connection, [loc.latitude, loc.longitude], function (err, distance) {
        if (err) { connection.results.add(plugin, {err: err}); }
        if (distance) { show.push(distance+'km'); }
        connection.results.add(plugin, {human: show.join(', '), emit:true});
        return next();
    });
};

exports.lookup_geoip = function (next, connection) {
    var plugin = this;

    // geoip.lookup results look like this:
    // range: [ 3479299040, 3479299071 ],
    //    country: 'US',
    //    region: 'CA',
    //    city: 'San Francisco',
    //    ll: [37.7484, -122.4156]

    if (!plugin.geoip) {
        connection.logerror(plugin, "oops, geoip-lite not loaded");
        return next();
    }

    var r = plugin.get_geoip_lite(connection.remote_ip);
    if (!r) { return next(); }

    connection.results.add(plugin, r);

    var show = [ r.country ];
    if (r.region   && plugin.cfg.main.show_region) { show.push(r.region); }
    if (r.city     && plugin.cfg.main.show_city  ) { show.push(r.city); }

    if (!plugin.cfg.main.calc_distance) {
        connection.results.add(plugin, {human: show.join(', '), emit:true});
        return next();
    }

    plugin.calculate_distance(connection, r.ll, function (err, distance) {
        show.push(r.distance+'km');
        connection.results.add(plugin, {human: show.join(', '), emit:true});
        return next();
    });
};

exports.get_geoip = function (ip) {
    var plugin = this;

    var result = plugin.get_geoip_maxmind(ip);
    if (result) return result;

    return plugin.get_geoip_lite(ip);
};

exports.get_geoip_maxmind = function (ip) {
    var plugin = this;
    if (!ip) return;
    if (!plugin.maxmind) return;
    if (net_utils.is_rfc1918(ip)) return;

    var ipv6 = net.isIPv6(ip);

    var result;
    try { result = ipv6 ? plugin.maxmind.getLocationV6(ip) : plugin.maxmind.getLocation(ip); }
    catch (e) { plugin.logerror(e); }
    if (!result) {
        try { result = ipv6 ? plugin.maxmind.getCountryV6(ip) : plugin.maxmind.getCountry(ip); }
        catch (e) { plugin.logerror(e); }
    }
    return result;
};

exports.get_geoip_lite = function (ip) {
    var plugin = this;
    if (!ip) return;
    if (!plugin.geoip) return;
    if (net_utils.is_rfc1918(ip)) return;

    var result = plugin.geoip.lookup(ip);
    if (result && result.ll) {
        result.latitude = result.ll[0];
        result.longitude = result.ll[1];
    }

    return result;
};

exports.add_geoip_headers = function (next, connection) {
    var plugin = this;
    var txn = connection.transaction;
    if (!txn) { return; }
    txn.remove_header('X-Haraka-GeoIP');
    txn.remove_header('X-Haraka-GeoIP-Received');
    var geoip = connection.results.get('connect.geoip');
    if (geoip) {             txn.add_header('X-Haraka-GeoIP',   geoip.human  );
        if (geoip.asn)     { txn.add_header('X-Haraka-ASN',     geoip.asn    ); }
        if (geoip.asn_org) { txn.add_header('X-Haraka-ASN-Org', geoip.asn_org); }
    }

    var received = [];

    var rh = plugin.received_headers(connection);
    if ( rh) { received.push(rh); }
    if (!rh) { plugin.user_agent(connection); } // No received headers.

    var oh = plugin.originating_headers(connection);
    if (oh) { received.push(oh); }

    // Add any received results to a trace header
    if (received.length) {
        txn.add_header('X-Haraka-GeoIP-Received', received.join(' '));
    }
    return next();
};

exports.get_local_geo = function (ip, connection) {
    var plugin = this;
    if (plugin.local_geoip) return;  // cached

    if (!plugin.local_ip) { plugin.local_ip = ip; }
    if (!plugin.local_ip) { plugin.local_ip = plugin.cfg.main.public_ip; }
    if (!plugin.local_ip) {
        connection.logerror(plugin, "can't calculate distance, set public_ip in smtp.ini");
        return;
    }

    if (!plugin.local_geoip) {
         plugin.local_geoip = plugin.get_geoip(plugin.local_ip);
    }

    if (!plugin.local_geoip) {
        connection.logerror(plugin, "no GeoIP results for local_ip!");
    }
};

exports.calculate_distance = function (connection, rll, done) {
    var plugin = this;

    var cb = function (err, l_ip) {
        if (err) {
            connection.results.add(plugin, {err: err});
            connection.logerror(plugin, err);
        }

        plugin.get_local_geo(l_ip, connection);
        if (!plugin.local_ip || !plugin.local_geoip) { return done(); }

        var gl = plugin.local_geoip;
        var gcd = plugin.haversine(gl.latitude, gl.longitude, rll[0], rll[1]);
        connection.results.add(plugin, {distance: gcd});

        if (plugin.cfg.main.too_far && (parseFloat(plugin.cfg.main.too_far) < parseFloat(gcd))) {
            connection.results.add(plugin, {too_far: true});
        }
        done(err, gcd);
    };

    if (plugin.local_ip) return cb(null, plugin.local_ip);
    net_utils.get_public_ip(cb);
};

exports.haversine = function (lat1, lon1, lat2, lon2) {
    // calculate the great circle distance using the haversine formula
    // found here: http://www.movable-type.co.uk/scripts/latlong.html
    var EARTH_RADIUS = 6371; // km
    function toRadians(v) { return v * Math.PI / 180; }
    var deltaLat = toRadians(lat2 - lat1);
    var deltaLon = toRadians(lon2 - lon1);
            lat1 = toRadians(lat1);
            lat2 = toRadians(lat2);

    var a = Math.sin(deltaLat/2) * Math.sin(deltaLat/2) +
            Math.sin(deltaLon/2) * Math.sin(deltaLon/2) * Math.cos(lat1) * Math.cos(lat2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    return (EARTH_RADIUS * c).toFixed(0);
};

exports.received_headers = function (connection) {
    var plugin = this;
    var txn = connection.transaction;
    var received = txn.header.get_all('received');
    if (!received.length) return;

    var results = [];

    // Try and parse each received header
    for (var i=0; i < received.length; i++) {
        var match = /\[(\d+\.\d+\.\d+\.\d+)\]/.exec(received[i]);
        if (!match) continue;
        if (net_utils.is_rfc1918(match[1])) continue;  // exclude private IP

        var gi = plugin.get_geoip(match[1]);
        connection.loginfo(plugin, 'received=' + match[1] + ' country=' + ((gi) ? gi.country : 'UNKNOWN'));
        results.push(match[1] + ':' + ((gi) ? gi.country : 'UNKNOWN'));
    }
    return results;
};

exports.originating_headers = function (connection) {
    var plugin = this;
    var txn = connection.transaction;

    // Try and parse any originating IP headers
    var orig = txn.header.get('x-originating-ip') ||
               txn.header.get('x-ip') ||
               txn.header.get('x-remote-ip');

    if (!orig) return;

    var match = /(\d+\.\d+\.\d+\.\d+)/.exec(orig);
    if (!match) return;
    var found_ip = match[1];
    if (!net.isIPv4(found_ip)) return;
    if (net_utils.is_rfc1918(found_ip)) return;

    var gi = plugin.geoip.lookup(found_ip);
    connection.loginfo(plugin, 'originating=' + found_ip + ' country=' + ((gi) ? gi.country : 'UNKNOWN'));
    return found_ip + ':' + ((gi) ? gi.country : 'UNKNOWN');
};
<commit_msg>switch from async.some to async.eachSeries<commit_after>'use strict';

var async     = require('async');
var fs        = require('fs');
var net       = require('net');
var net_utils = require('./net_utils');

exports.register = function (done) {
    var plugin = this;

    plugin.load_geoip_ini();
    plugin.hasProvider=false;

    var loadProvider = function (fName, iterDone) {
        plugin[fName](iterDone);
    };
    var finalCb = function () {
        // calls done() only when testing
        if (done && typeof(done) === 'function') done();
    };
    async.eachSeries(['load_maxmind', 'load_geoip_lite'], loadProvider, finalCb);
};

exports.load_geoip_ini = function () {
    var plugin = this;
    plugin.cfg = plugin.config.get('connect.geoip.ini', {
            booleans: [
                '+main.show_city',
                '+main.show_region',
                '-main.calc_distance',
            ],
        },
        plugin.load_geoip_ini
    );
};

exports.load_maxmind = function (loadDone) {
    var plugin = this;
    if (plugin.hasProvider) return loadDone();

    try {
        plugin.maxmind = require('maxmind');
    }
    catch (e) {
        plugin.logerror(e);
        plugin.logerror("unable to load maxmind, try\n\n\t'npm install -g maxmind'\n\n");
        return loadDone();
    }

    var dbs = ['GeoIPCity', 'GeoIP', 'GeoIPv6',  'GeoIPASNum', 'GeoISP',
               'GeoIPNetSpeedCell',  'GeoIPOrg', 'GeoLiteCityV6'];
    var dbsFound = [];

    var fsDone = function (err) {
        if (err) { plugin.logerror(err); }
        plugin.maxmind.dbsLoaded = dbsFound.length;
        if (dbsFound.length === 0) {
            plugin.logerror('maxmind loaded but no GeoIP DBs found!');
            return loadDone();
        }
        plugin.hasProvider=true;
        plugin.loginfo('geoip provider maxmind with ' + dbsFound.length + ' DBs');
        plugin.maxmind.init(dbsFound, {indexCache: true, checkForUpdates: true});
        plugin.register_hook('connect',     'lookup_maxmind');
        plugin.register_hook('data_post',   'add_geoip_headers');
        loadDone();
    };

    var dbdir = plugin.cfg.main.dbdir || '/usr/local/share/GeoIP/';
    var fsIter = function (file, iterDone) {
        var path = dbdir + file + '.dat';

        fs.exists(path, function (exists) {
            if (!exists) return iterDone();
            dbsFound.push(path);
            iterDone();
        });
    };

    async.each(dbs, fsIter, fsDone);
};

exports.load_geoip_lite = function (done) {
    var plugin = this;
    if (plugin.hasProvider) return done();

    try {
        plugin.geoip = require('geoip-lite');
    }
    catch (e) {
        plugin.logerror("unable to load geoip-lite, try\n\n" +
                "\t'npm install -g geoip-lite'\n\n");
        return done();
    }

    if (!plugin.geoip) {
        // geoip-lite dropped node 0.8 support, it may not have loaded
        plugin.logerror('unable to load geoip-lite');
        return done();
    }

    plugin.loginfo('geoip provider geoip-lite');
    plugin.register_hook('connect',     'lookup_geoip');
    plugin.register_hook('data_post',   'add_geoip_headers');

    return done();
};

exports.lookup_maxmind = function (next, connection) {
    var plugin = this;

    if (!plugin.maxmind) { return next(); }
    if (!plugin.maxmind.dbsLoaded) { return next(); }

    var ip = connection.remote_ip;
    var show = [];
    var loc = plugin.get_geoip_maxmind(ip);
    if (loc) {
        connection.results.add(plugin, {continent: loc.continentCode});
        connection.results.add(plugin, {country: loc.countryCode || loc.code});
        show.push(loc.continentCode);
        show.push(loc.countryCode);
        if (loc.city) {
            connection.results.add(plugin, {region: loc.region});
            connection.results.add(plugin, {city: loc.city});
            connection.results.add(plugin, {ll: [loc.latitude, loc.longitude]});
            if (plugin.cfg.main.show_region) { show.push(loc.region); }
            if (plugin.cfg.main.show_city  ) { show.push(loc.city); }
        }
    }

    var asn = plugin.maxmind.getAsn(ip);
    if (asn) {
        var match = asn.match(/^(?:AS)([0-9]+)\s+(.*)$/);
        connection.results.add(plugin, {asn: match[1]});
        connection.results.add(plugin, {asn_org: match[2]});
    }

    if (!loc || !plugin.cfg.main.calc_distance) {
        connection.results.add(plugin, {human: show.join(', '), emit:true});
        return next();
    }

    plugin.calculate_distance(connection, [loc.latitude, loc.longitude], function (err, distance) {
        if (err) { connection.results.add(plugin, {err: err}); }
        if (distance) { show.push(distance+'km'); }
        connection.results.add(plugin, {human: show.join(', '), emit:true});
        return next();
    });
};

exports.lookup_geoip = function (next, connection) {
    var plugin = this;

    // geoip.lookup results look like this:
    // range: [ 3479299040, 3479299071 ],
    //    country: 'US',
    //    region: 'CA',
    //    city: 'San Francisco',
    //    ll: [37.7484, -122.4156]

    if (!plugin.geoip) {
        connection.logerror(plugin, "oops, geoip-lite not loaded");
        return next();
    }

    var r = plugin.get_geoip_lite(connection.remote_ip);
    if (!r) { return next(); }

    connection.results.add(plugin, r);

    var show = [ r.country ];
    if (r.region   && plugin.cfg.main.show_region) { show.push(r.region); }
    if (r.city     && plugin.cfg.main.show_city  ) { show.push(r.city); }

    if (!plugin.cfg.main.calc_distance) {
        connection.results.add(plugin, {human: show.join(', '), emit:true});
        return next();
    }

    plugin.calculate_distance(connection, r.ll, function (err, distance) {
        show.push(r.distance+'km');
        connection.results.add(plugin, {human: show.join(', '), emit:true});
        return next();
    });
};

exports.get_geoip = function (ip) {
    var plugin = this;

    var result = plugin.get_geoip_maxmind(ip);
    if (result) return result;

    return plugin.get_geoip_lite(ip);
};

exports.get_geoip_maxmind = function (ip) {
    var plugin = this;
    if (!ip) return;
    if (!plugin.maxmind) return;
    if (net_utils.is_rfc1918(ip)) return;

    var ipv6 = net.isIPv6(ip);

    var result;
    try { result = ipv6 ? plugin.maxmind.getLocationV6(ip) : plugin.maxmind.getLocation(ip); }
    catch (e) { plugin.logerror(e); }
    if (!result) {
        try { result = ipv6 ? plugin.maxmind.getCountryV6(ip) : plugin.maxmind.getCountry(ip); }
        catch (e) { plugin.logerror(e); }
    }
    return result;
};

exports.get_geoip_lite = function (ip) {
    var plugin = this;
    if (!ip) return;
    if (!plugin.geoip) return;
    if (net_utils.is_rfc1918(ip)) return;

    var result = plugin.geoip.lookup(ip);
    if (result && result.ll) {
        result.latitude = result.ll[0];
        result.longitude = result.ll[1];
    }

    return result;
};

exports.add_geoip_headers = function (next, connection) {
    var plugin = this;
    var txn = connection.transaction;
    if (!txn) { return; }
    txn.remove_header('X-Haraka-GeoIP');
    txn.remove_header('X-Haraka-GeoIP-Received');
    var geoip = connection.results.get('connect.geoip');
    if (geoip) {             txn.add_header('X-Haraka-GeoIP',   geoip.human  );
        if (geoip.asn)     { txn.add_header('X-Haraka-ASN',     geoip.asn    ); }
        if (geoip.asn_org) { txn.add_header('X-Haraka-ASN-Org', geoip.asn_org); }
    }

    var received = [];

    var rh = plugin.received_headers(connection);
    if ( rh) { received.push(rh); }
    if (!rh) { plugin.user_agent(connection); } // No received headers.

    var oh = plugin.originating_headers(connection);
    if (oh) { received.push(oh); }

    // Add any received results to a trace header
    if (received.length) {
        txn.add_header('X-Haraka-GeoIP-Received', received.join(' '));
    }
    return next();
};

exports.get_local_geo = function (ip, connection) {
    var plugin = this;
    if (plugin.local_geoip) return;  // cached

    if (!plugin.local_ip) { plugin.local_ip = ip; }
    if (!plugin.local_ip) { plugin.local_ip = plugin.cfg.main.public_ip; }
    if (!plugin.local_ip) {
        connection.logerror(plugin, "can't calculate distance, set public_ip in smtp.ini");
        return;
    }

    if (!plugin.local_geoip) {
         plugin.local_geoip = plugin.get_geoip(plugin.local_ip);
    }

    if (!plugin.local_geoip) {
        connection.logerror(plugin, "no GeoIP results for local_ip!");
    }
};

exports.calculate_distance = function (connection, rll, done) {
    var plugin = this;

    var cb = function (err, l_ip) {
        if (err) {
            connection.results.add(plugin, {err: err});
            connection.logerror(plugin, err);
        }

        plugin.get_local_geo(l_ip, connection);
        if (!plugin.local_ip || !plugin.local_geoip) { return done(); }

        var gl = plugin.local_geoip;
        var gcd = plugin.haversine(gl.latitude, gl.longitude, rll[0], rll[1]);
        connection.results.add(plugin, {distance: gcd});

        if (plugin.cfg.main.too_far && (parseFloat(plugin.cfg.main.too_far) < parseFloat(gcd))) {
            connection.results.add(plugin, {too_far: true});
        }
        done(err, gcd);
    };

    if (plugin.local_ip) return cb(null, plugin.local_ip);
    net_utils.get_public_ip(cb);
};

exports.haversine = function (lat1, lon1, lat2, lon2) {
    // calculate the great circle distance using the haversine formula
    // found here: http://www.movable-type.co.uk/scripts/latlong.html
    var EARTH_RADIUS = 6371; // km
    function toRadians(v) { return v * Math.PI / 180; }
    var deltaLat = toRadians(lat2 - lat1);
    var deltaLon = toRadians(lon2 - lon1);
            lat1 = toRadians(lat1);
            lat2 = toRadians(lat2);

    var a = Math.sin(deltaLat/2) * Math.sin(deltaLat/2) +
            Math.sin(deltaLon/2) * Math.sin(deltaLon/2) * Math.cos(lat1) * Math.cos(lat2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    return (EARTH_RADIUS * c).toFixed(0);
};

exports.received_headers = function (connection) {
    var plugin = this;
    var txn = connection.transaction;
    var received = txn.header.get_all('received');
    if (!received.length) return;

    var results = [];

    // Try and parse each received header
    for (var i=0; i < received.length; i++) {
        var match = /\[(\d+\.\d+\.\d+\.\d+)\]/.exec(received[i]);
        if (!match) continue;
        if (net_utils.is_rfc1918(match[1])) continue;  // exclude private IP

        var gi = plugin.get_geoip(match[1]);
        connection.loginfo(plugin, 'received=' + match[1] + ' country=' + ((gi) ? gi.country : 'UNKNOWN'));
        results.push(match[1] + ':' + ((gi) ? gi.country : 'UNKNOWN'));
    }
    return results;
};

exports.originating_headers = function (connection) {
    var plugin = this;
    var txn = connection.transaction;

    // Try and parse any originating IP headers
    var orig = txn.header.get('x-originating-ip') ||
               txn.header.get('x-ip') ||
               txn.header.get('x-remote-ip');

    if (!orig) return;

    var match = /(\d+\.\d+\.\d+\.\d+)/.exec(orig);
    if (!match) return;
    var found_ip = match[1];
    if (!net.isIPv4(found_ip)) return;
    if (net_utils.is_rfc1918(found_ip)) return;

    var gi = plugin.geoip.lookup(found_ip);
    connection.loginfo(plugin, 'originating=' + found_ip + ' country=' + ((gi) ? gi.country : 'UNKNOWN'));
    return found_ip + ':' + ((gi) ? gi.country : 'UNKNOWN');
};
<|endoftext|>


<commit_before>const $ = require('jquery');
const Board = require('./board.js')
const Snake = require('./snake.js')

let canvas = document.getElementById("canvas");
let ctx = canvas.getContext('2d');

let board = new Board(canvas, ctx);
let snake = new Snake();

function animate() {
  requestAnimationFrame(function gameLoop() {
    keyDownListener();
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    snake.draw();
    // snake.moveDown;
    if (snake.wallDetection === true) {
    } else {
      requestAnimationFrame(gameLoop);
    }
  }
)};

function keyDownListener() {
  $(document).keydown(function(e) {
    if (e.keyCode === 37) {
      console.log("Left")
      snake.moveLeft;
    } else if (e.keyCode == 38) {
      console.log("Up")
      snake.moveUp;
    } else if (e.keyCode == 39) {
      console.log("Right")
      snake.moveRight;
    } else if (e.keyCode = 40) {
      console.log("Down")
      snake.moveDown;
    }
  })
}

animate();
<commit_msg>We are now working with a moving dingus and need to work out the logic of having a continually moving snake, event emitters and getting the snake to not pause on a redirect<commit_after>const $ = require('jquery');
const Board = require('./board.js')
const Snake = require('./snake.js')

let canvas = document.getElementById("canvas");
let ctx = canvas.getContext('2d');

let board = new Board(canvas, ctx);
let snake = new Snake();

keyDownListener();

function animate() {
  requestAnimationFrame(function gameLoop() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    snake.draw(); // will draw everything
    // snake.move(event.direction)
    if (snake.wallDetection === true) {

    } else {
      requestAnimationFrame(gameLoop);
    }
  }
)};

function keyDownListener() {
  $(document).keydown(function(e) {
    if (e.keyCode === 37) {
      // e.snakeDirectionChange(left)
      snake.moveLeft;
    } else if (e.keyCode === 38) {
      snake.moveUp;
    } else if (e.keyCode === 39) {
      snake.moveRight;
    } else if (e.keyCode === 40) {
      snake.moveDown;
    }
  })
}

animate();
<|endoftext|>


<commit_before>module.exports = function(config) {
  config.set({

    // base path, that will be used to resolve files and exclude
    basePath: 'src/js/test',

    // frameworks to use
    frameworks: ['mocha', 'browserify'],

    // preprocessors
    preprocessors: {
      '**/*.js': [ 'browserify', 'coverage' ]
    },

    // list of files / patterns to load in the browser
    files: [
      // vendor files
      // "bower_components/jquery/dist/jquery.js",

      // src files
      // "main.js",

      // test files
      "**/*.test.js"
    ],

    // list of files to exclude
    exclude: [],

    // test results reporter to use
    reporters: ['mocha', 'coverage'],

    coverageReporter: {
      reporters: [
        {
          type: 'text-summary'
        },
        {
          type: 'html',
          dir: '../../../coverage'
        }
      ]
    },

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // Start these browsers, currently available:
    // - Chrome
    // - ChromeCanary
    // - Firefox
    // - Opera (has to be installed with `npm install karma-opera-launcher`)
    // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`)
    // - PhantomJS
    // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`)
    browsers: [
      // 'Chrome'
      'PhantomJS'
    ],

    // If browser does not capture in given timeout [ms], kill it
    captureTimeout: 60000,

    // Continuous Integration mode
    // if true, it capture browsers, run tests and exit
    singleRun: false
  });
};
<commit_msg>Added opt for mocha reporter to show diff for failed tests<commit_after>module.exports = function(config) {
  config.set({

    // base path, that will be used to resolve files and exclude
    basePath: 'src/js/test',

    // frameworks to use
    frameworks: ['mocha', 'browserify'],

    // preprocessors
    preprocessors: {
      '**/*.js': [ 'browserify', 'coverage' ]
    },

    // list of files / patterns to load in the browser
    files: [
      // vendor files
      // "bower_components/jquery/dist/jquery.js",

      // src files
      // "main.js",

      // test files
      "**/*.test.js"
    ],

    // list of files to exclude
    exclude: [],

    // test results reporter to use
    reporters: ['mocha', 'coverage'],

    mochaReporter: {
      showDiff: true
    },

    coverageReporter: {
      reporters: [
        {
          type: 'text-summary'
        },
        {
          type: 'html',
          dir: '../../../coverage'
        }
      ]
    },

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // Start these browsers, currently available:
    // - Chrome
    // - ChromeCanary
    // - Firefox
    // - Opera (has to be installed with `npm install karma-opera-launcher`)
    // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`)
    // - PhantomJS
    // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`)
    browsers: [
      // 'Chrome'
      'PhantomJS'
    ],

    // If browser does not capture in given timeout [ms], kill it
    captureTimeout: 60000,

    // Continuous Integration mode
    // if true, it capture browsers, run tests and exit
    singleRun: false
  });
};
<|endoftext|>


<commit_before>var UTILS = (function () {

    return {
        /**
         * Check if a given value is a plain Object
         *
         * @param  {*}       o Any value to be checked
         * @return {Boolean}   true if it's an Object
         */
        isObject: function (o) {
            var toString = Object.prototype.toString;
            return (toString.call(o) === toString.call({}));
        }

    };
}());

// Place any jQuery/helper plugins in here.
<commit_msg>Updated UTILS library<commit_after>/**
 * JS Library v2
 */

var UTILS = (function () {

	return {
		/**
		 * Check if a given value is a plain Object
		 *
		 * @param  {*}       o Any value to be checked
		 * @return {Boolean}   true if it's an Object
		 */
		isObject: function (o) {
			var toString = Object.prototype.toString;
			return (toString.call(o) === toString.call({}));
		},

		/**
		 * AJAX helper function (similar to jQuery, but far from it!)
		 *
		 * @param {string} url     URL for the ajax request
		 * @param {Object} options AJAX settings
		 */
		ajax: function (url, options) {
			var xhr = new XMLHttpRequest(),
				method = 'GET',
				options = UTILS.isObject(options) ? options : {};

			// Check if "method" was supplied
			if (options.method) {
				method = options.method;
			}

			// Setup the request
			xhr.open(method.toUpperCase(), url);

			xhr.onreadystatechange = function () {
				var status;

				// If request finished
				if (xhr.readyState === 4) {
					status = xhr.status;

					// If response is OK or fetched from cache
					if ((status >= 200 && status < 300) || status === 304) {
						var res = xhr.responseText,
							contentType = xhr.getResponseHeader('Content-Type');

						// If server sent a content type header, handle formats
						if (contentType) {
							// Handle JSON format
							if (contentType === 'text/json' ||
								contentType === 'application/json') {

								// JSON throws an exception on invalid JSON
								try {
									res = JSON.parse(res);
								} catch (err) {
									// Trigger "fail" callback if set
									if (options.fail) {
										options.fail.call(xhr, err);
										return;
									}
								}
							// Handle XML format
							} else if (contentType === 'text/xml' ||
								contentType === 'application/xml') {
								// responseXML returns a document object
								res = xhr.responseXML;

								// if XML was invalid, trigger fail callback
								if (res === null && options.fail) {
									options.fail.call(xhr, 'Bad XML file');
									return;
								}
							}
						}

						// Trigger done callback with the proper response
						if (options.done) {
							options.done.call(xhr, res);
						}
					}

				}
			};

			// Fire the request
			xhr.send(null);
		}
	};
}());<|endoftext|>


<commit_before>'use strict';

module.exports = {
	db: 'mongodb://localhost/sts-integratedsystem',
	assets: {
		lib: {
			css: [
                'public/lib/bootstrap/dist/css/bootstrap.css',
                'public/lib/bootstrap-material-design/dist/css/roboto.min.css',
                'public/lib/bootstrap-material-design/dist/css/material.min.css',
                'public/lib/bootstrap-material-design/dist/css/ripples.min.css'
			],
			js: [
				'public/lib/angular/angular.min.js',
				'public/lib/angular-resource/angular-resource.js',
				'public/lib/angular-cookies/angular-cookies.js',
				'public/lib/angular-animate/angular-animate.js',
				'public/lib/angular-touch/angular-touch.js',
				'public/lib/angular-sanitize/angular-sanitize.js',
				'public/lib/angular-ui-router/release/angular-ui-router.min.js',
				'public/lib/angular-ui-utils/ui-utils.min.js',
				'public/lib/angular-bootstrap/ui-bootstrap-tpls.min.js',
                'public/lib/bootstrap-material-design/dist/js/ripples.min.js',
                'public/lib/bootstrap-material-design/dist/js/material.min.js',
                'public/lib/ng-file-upload/ng-file-upload.min.js',
                'public/lib/ng-file-upload/ng-file-upload-shim.min.js'
			]
		},
		css: 'public/dist/application.min.css',
		js: 'public/dist/application.min.js'
	},
	facebook: {
		clientID: process.env.FACEBOOK_ID || 'APP_ID',
		clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET',
		callbackURL: '/auth/facebook/callback'
	},
	twitter: {
		clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY',
		clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET',
		callbackURL: '/auth/twitter/callback'
	},
	google: {
		clientID: process.env.GOOGLE_ID || 'APP_ID',
		clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET',
		callbackURL: '/auth/google/callback'
	},
	linkedin: {
		clientID: process.env.LINKEDIN_ID || 'APP_ID',
		clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET',
		callbackURL: '/auth/linkedin/callback'
	},
	github: {
		clientID: process.env.GITHUB_ID || 'APP_ID',
		clientSecret: process.env.GITHUB_SECRET || 'APP_SECRET',
		callbackURL: '/auth/github/callback'
	},
	mailer: {
		from: process.env.MAILER_FROM || 'MAILER_FROM',
		options: {
			service: process.env.MAILER_SERVICE_PROVIDER || 'MAILER_SERVICE_PROVIDER',
			auth: {
				user: process.env.MAILER_EMAIL_ID || 'MAILER_EMAIL_ID',
				pass: process.env.MAILER_PASSWORD || 'MAILER_PASSWORD'
			}
		}
	}
};
<commit_msg>Progress push<commit_after>'use strict';

module.exports = {
	db: 'mongodb://localhost/sts-integratedsystem',
	assets: {
		lib: {
			css: [
                'public/lib/bootstrap/dist/css/bootstrap.css',
                'public/lib/bootstrap-material-design/dist/css/roboto.min.css',
                'public/lib/bootstrap-material-design/dist/css/material.min.css',
                'public/lib/bootstrap-material-design/dist/css/ripples.min.css'
			],
			js: [
                'public/lib/jquery/dist/jquery.min.js',
                'public/lib/angular/angular.min.js',
				'public/lib/angular-resource/angular-resource.js',
				'public/lib/angular-cookies/angular-cookies.js',
				'public/lib/angular-animate/angular-animate.js',
				'public/lib/angular-touch/angular-touch.js',
				'public/lib/angular-sanitize/angular-sanitize.js',
				'public/lib/angular-ui-router/release/angular-ui-router.min.js',
				'public/lib/angular-ui-utils/ui-utils.min.js',
				'public/lib/angular-bootstrap/ui-bootstrap-tpls.min.js',
                'public/lib/bootstrap-material-design/dist/js/ripples.min.js',
                'public/lib/bootstrap-material-design/dist/js/material.min.js',
                'public/lib/ng-file-upload/ng-file-upload.min.js',
                'public/lib/ng-file-upload/ng-file-upload-shim.min.js'
			]
		},
		css: 'public/dist/application.min.css',
		js: 'public/dist/application.min.js'
	},
	facebook: {
		clientID: process.env.FACEBOOK_ID || 'APP_ID',
		clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET',
		callbackURL: '/auth/facebook/callback'
	},
	twitter: {
		clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY',
		clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET',
		callbackURL: '/auth/twitter/callback'
	},
	google: {
		clientID: process.env.GOOGLE_ID || 'APP_ID',
		clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET',
		callbackURL: '/auth/google/callback'
	},
	linkedin: {
		clientID: process.env.LINKEDIN_ID || 'APP_ID',
		clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET',
		callbackURL: '/auth/linkedin/callback'
	},
	github: {
		clientID: process.env.GITHUB_ID || 'APP_ID',
		clientSecret: process.env.GITHUB_SECRET || 'APP_SECRET',
		callbackURL: '/auth/github/callback'
	},
	mailer: {
		from: process.env.MAILER_FROM || 'MAILER_FROM',
		options: {
			service: process.env.MAILER_SERVICE_PROVIDER || 'MAILER_SERVICE_PROVIDER',
			auth: {
				user: process.env.MAILER_EMAIL_ID || 'MAILER_EMAIL_ID',
				pass: process.env.MAILER_PASSWORD || 'MAILER_PASSWORD'
			}
		}
	}
};
<|endoftext|>


<commit_before>/**
 * Mocks indexing Db adapter
 */
var _ = require('lodash');
var Db = require('backbone-db');
var debug = require('../utils/debug')('serverbone:utils:db:mock');
var async = require('async');

var IndexingTestDb = function TestDb() {
  var db = Db.apply(this, arguments);
  this.storage = db.storage;
  this.records = db.records;
};

_.extend(IndexingTestDb.prototype, Db.prototype, {
  addToIndex: function(collection, model, options, cb) {
    var self = this;
    debug.log('add ' + model.id + ' to ' + options.indexKey);
    this.store().getItem(options.indexKey, function(err, items) {
      if (err) return cb(err);
      if (!items) {
        items = [];
      } else {
        items = JSON.parse(items);
      }
      // item was already existing
      if (items.indexOf(model.id) > -1) {
        return cb();
      }
      items.push(model.id);
      self.store().setItem(
        options.indexKey,
        JSON.stringify(items),
        function(err, res) {
          cb(err, model.toJSON(), res);
        });
    });
  },

  readFromIndex: function(collection, options, cb) {
    this.store().getItem(options.indexKey, function(err, ids) {
      ids = _.isString(ids) ? JSON.parse(ids) : ids;
      var models = [];
      _.each(ids, function(id) {
        models.push({
          id: id
        });
      });
      collection.set(models, options);
      return cb(err, models);
    });
  },

  readFromIndexes: function(collection, options, cb) {
    var indexesToRead = options.indexKeys;
    var fns = _.map(indexesToRead, function(key) {
      var store = this.store();
      return function getItem(cb) {
        store.getItem(key, function(err, ids) {
          cb(err, ids);
        });
      };
    }, this);

    async.parallel(fns, function(err, results) {
      if (err) return cb(err);
      // join results
      var models = [];
      _.each(results, function(ids) {
        ids = _.isString(ids) ? JSON.parse(ids) : ids;
        _.each(ids, function(id) {
          models.push({
            id: id
          });
        });
      });
      collection.set(models, options);
      return cb(err, models);
    });
  },

  removeFromIndex: function(collection, models, options, cb) {
    var self = this;
    var ids = _.pluck(models, models[0].idAttribute);
    debug.log('removing ' + ids + ' from ' + options.indexKey);
    this.store().getItem(options.indexKey, function(err, items) {
      items = _.isString(items) ? JSON.parse(items) : items;
      items = _.reject(items, function(id) {
        return ids.indexOf(id) > -1;
      });
      self.store().setItem(
        options.indexKey,
        JSON.stringify(items),
        function(err, res) {
          cb(err, models, res);
        }
      );
    });
  },

  // removes everything from index
  removeIndex: function(collection, options, cb) {
    this.store().setItem(
      options.indexKey,
      JSON.stringify([]),
      function(err, res) {
        cb(err, [], res);
      }
    );
  },

  existsInIndex: function(collection, model, options, cb) {
    this.store().getItem(options.indexKey, function(err, ids) {
      ids = ids ? JSON.parse(ids) : [];
      cb(err, ids.indexOf(model.id) > -1);
    });
  },

  indexCount: function(collection, options, cb) {
    this.store().getItem(options.indexKey, function(err, ids) {
      ids = ids ? JSON.parse(ids) : [];
      cb(err, ids.length);
    });
  },

  // mock adapter only supports exact match
  findKeys: function(collection, options, cb) {
    var ids = [];
    var keys = _.isFunction(collection.url) ? collection.url() : collection.url;
    keys += options.keys;
    debug.log('findKeys', keys);
    this.store().getItem(keys, function(err, data) {
      if (data) ids.push(keys);
      cb(null, ids);
    });
  }
});

IndexingTestDb.sync = IndexingTestDb.prototype.sync;

module.exports = IndexingTestDb;<commit_msg>handle offset & limit in indexing db mock<commit_after>/**
 * Mocks indexing Db adapter
 */
var _ = require('lodash');
var Db = require('backbone-db');
var debug = require('../utils/debug')('serverbone:utils:db:mock');
var async = require('async');

var IndexingTestDb = function TestDb() {
  var db = Db.apply(this, arguments);
  this.storage = db.storage;
  this.records = db.records;
};

_.extend(IndexingTestDb.prototype, Db.prototype, {
  addToIndex: function(collection, model, options, cb) {
    var self = this;
    debug.log('add ' + model.id + ' to ' + options.indexKey);
    this.store().getItem(options.indexKey, function(err, items) {
      if (err) return cb(err);
      if (!items) {
        items = [];
      } else {
        items = JSON.parse(items);
      }
      // item was already existing
      if (items.indexOf(model.id) > -1) {
        return cb();
      }
      items.push(model.id);
      self.store().setItem(
        options.indexKey,
        JSON.stringify(items),
        function(err, res) {
          cb(err, model.toJSON(), res);
        });
    });
  },

  readFromIndex: function(collection, options, cb) {
    this.store().getItem(options.indexKey, function(err, ids) {
      ids = _.isString(ids) ? JSON.parse(ids) : ids;
      if (options.limit) {
        ids = ids.splice(options.offset || 0, options.limit);
      }
      var models = [];
      _.each(ids, function(id) {
        models.push({
          id: id
        });
      });
      collection.set(models, options);
      return cb(err, models);
    });
  },

  readFromIndexes: function(collection, options, cb) {
    var indexesToRead = options.indexKeys;
    var fns = _.map(indexesToRead, function(key) {
      var store = this.store();
      return function getItem(cb) {
        store.getItem(key, function(err, ids) {
          cb(err, ids);
        });
      };
    }, this);

    async.parallel(fns, function(err, results) {
      if (err) return cb(err);
      // join results
      var models = [];
      _.each(results, function(ids) {
        ids = _.isString(ids) ? JSON.parse(ids) : ids;
        _.each(ids, function(id) {
          models.push({
            id: id
          });
        });
      });
      collection.set(models, options);
      return cb(err, models);
    });
  },

  removeFromIndex: function(collection, models, options, cb) {
    var self = this;
    var ids = _.pluck(models, models[0].idAttribute);
    debug.log('removing ' + ids + ' from ' + options.indexKey);
    this.store().getItem(options.indexKey, function(err, items) {
      items = _.isString(items) ? JSON.parse(items) : items;
      items = _.reject(items, function(id) {
        return ids.indexOf(id) > -1;
      });
      self.store().setItem(
        options.indexKey,
        JSON.stringify(items),
        function(err, res) {
          cb(err, models, res);
        }
      );
    });
  },

  // removes everything from index
  removeIndex: function(collection, options, cb) {
    this.store().setItem(
      options.indexKey,
      JSON.stringify([]),
      function(err, res) {
        cb(err, [], res);
      }
    );
  },

  existsInIndex: function(collection, model, options, cb) {
    this.store().getItem(options.indexKey, function(err, ids) {
      ids = ids ? JSON.parse(ids) : [];
      cb(err, ids.indexOf(model.id) > -1);
    });
  },

  indexCount: function(collection, options, cb) {
    this.store().getItem(options.indexKey, function(err, ids) {
      ids = ids ? JSON.parse(ids) : [];
      cb(err, ids.length);
    });
  },

  // mock adapter only supports exact match
  findKeys: function(collection, options, cb) {
    var ids = [];
    var keys = _.isFunction(collection.url) ? collection.url() : collection.url;
    keys += options.keys;
    debug.log('findKeys', keys);
    this.store().getItem(keys, function(err, data) {
      if (data) ids.push(keys);
      cb(null, ids);
    });
  }
});

IndexingTestDb.sync = IndexingTestDb.prototype.sync;

module.exports = IndexingTestDb;<|endoftext|>


<commit_before><commit_msg>fix bug<commit_after><|endoftext|>


<commit_before>var _config = {
	fixture: null,
	Test: [],
	stats: {
		all: 0,
		bad: 0
	},
	queue: [],
	blocking: true,
	timeout: null,
	expected: null,
	currentModule: null,
	asyncTimeout: 2 // seconds for async timeout
};

var isLocal = !!(window.location.protocol == 'file:');

$(function() {
	$('#userAgent').html(navigator.userAgent);
	runTest();
});

function synchronize(callback) {
	_config.queue[_config.queue.length] = callback;
	if(!_config.blocking) {
		process();
	}
}

function process() {
	while(_config.queue.length && !_config.blocking) {
		var call = _config.queue[0];
		_config.queue = _config.queue.slice(1);
		call();
	}
}

function stop(allowFailure) {
	_config.blocking = true;
	var handler = allowFailure ? start : function() {
		ok( false, "Test timed out" );
		start();
	};
	// Disabled, caused too many random errors
	//_config.timeout = setTimeout(handler, _config.asyncTimeout * 1000);
}
function start() {
	// A slight delay, to avoid any current callbacks
	setTimeout(function(){
		if(_config.timeout)
			clearTimeout(_config.timeout);
		_config.blocking = false;
		process();
	}, 13);
}

function dontrun(name) {
	var filter = location.search.slice(1);
	return filter && !new RegExp(filter).test(encodeURIComponent(name));
}

function runTest() {
	_config.blocking = false;
	var time = new Date();
	_config.fixture = document.getElementById('main').innerHTML;
	synchronize(function() {
		time = new Date() - time;
		$("
").html(['
Tests completed in ',
			time, ' milliseconds.
',
			_config.stats.bad, ' tests of ', _config.stats.all, ' failed.
']
			.join(''))
			.appendTo("body");
		$("#banner").addClass(_config.stats.bad ? "fail" : "pass");
	});
}

function test(name, callback, nowait) {
	if(_config.currentModule)
		name = _config.currentModule + " module: " + name;

	if (dontrun(name))
		return;

	synchronize(function() {
		_config.Test = [];
		try {
			callback();
		} catch(e) {
			if( typeof console != "undefined" && console.error && console.warn ) {
				console.error("Test " + name + " died, exception and test follows");
				console.error(e);
				console.warn(callback.toString());
			}
			_config.Test.push( [ false, "Died on test #" + (_config.Test.length+1) + ": " + e ] );
		}
	});
	synchronize(function() {
		reset();

		// don't output pause tests
		if(nowait) return;

		if(_config.expected && _config.expected != _config.Test.length) {
			_config.Test.push( [ false, "Expected " + _config.expected + " assertions, but " + _config.Test.length + " were run" ] );
		}
		_config.expected = null;

		var good = 0, bad = 0;
		var ol = document.createElement("ol");
		ol.style.display = "none";
		var li = "", state = "pass";
		for ( var i = 0; i < _config.Test.length; i++ ) {
			var li = document.createElement("li");
			li.className = _config.Test[i][0] ? "pass" : "fail";
			li.innerHTML = _config.Test[i][1];
			ol.appendChild( li );

			_config.stats.all++;
			if ( !_config.Test[i][0] ) {
				state = "fail";
				bad++;
				_config.stats.bad++;
			} else good++;
		}

		var li = document.createElement("li");
		li.className = state;

		var b = document.createElement("strong");
		b.innerHTML = name + " (" + bad + ", " + good + ", " + _config.Test.length + ")";
		b.onclick = function(){
			var n = this.nextSibling;
			if ( jQuery.css( n, "display" ) == "none" )
				n.style.display = "block";
			else
				n.style.display = "none";
		};
		$(b).dblclick(function(event) {
			var target = jQuery(event.target).filter("strong").clone();
			if ( target.length ) {
				target.children().remove();
				location.href = location.href.match(/^(.+?)(\?.*)?$/)[1] + "?" + encodeURIComponent($.trim(target.text()));
			}
		});
		li.appendChild( b );
		li.appendChild( ol );

		document.getElementById("tests").appendChild( li );
	});
}

// call on start of module test to prepend name to all tests
function module(moduleName) {
	_config.currentModule = moduleName;
}

/**
 * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
 */
function expect(asserts) {
	_config.expected = asserts;
}

/**
 * Resets the test setup. Useful for tests that modify the DOM.
 */
function reset() {
	$("#main").html( _config.fixture );
}

/**
 * Asserts true.
 * @example ok( $("a").size() > 5, "There must be at least 5 anchors" );
 */
function ok(a, msg) {
	_config.Test.push( [ !!a, msg ] );
}

/**
 * Asserts that two arrays are the same
 */
function isSet(a, b, msg) {
	var ret = true;
	if ( a && b && a.length != undefined && a.length == b.length ) {
		for ( var i = 0; i < a.length; i++ )
			if ( a[i] != b[i] )
				ret = false;
	} else
		ret = false;
	if ( !ret )
		_config.Test.push( [ ret, msg + " expected: " + serialArray(b) + " result: " + serialArray(a) ] );
	else
		_config.Test.push( [ ret, msg ] );
}

/**
 * Asserts that two objects are equivalent
 */
function isObj(a, b, msg) {
	var ret = true;

	if ( a && b ) {
		for ( var i in a )
			if ( a[i] != b[i] )
				ret = false;

		for ( i in b )
			if ( a[i] != b[i] )
				ret = false;
	} else
		ret = false;

    _config.Test.push( [ ret, msg ] );
}

function serialArray( a ) {
	var r = [];

	if ( a && a.length )
        for ( var i = 0; i < a.length; i++ ) {
            var str = a[i].nodeName;
            if ( str ) {
                str = str.toLowerCase();
                if ( a[i].id )
                    str += "#" + a[i].id;
            } else
                str = a[i];
            r.push( str );
        }

	return "[ " + r.join(", ") + " ]"
}

/**
 * Returns an array of elements with the given IDs, eg.
 * @example q("main", "foo", "bar")
 * @result [
, , <input id="bar">]
 */
function q() {
	var r = [];
	for ( var i = 0; i < arguments.length; i++ )
		r.push( document.getElementById( arguments[i] ) );
	return r;
}

/**
 * Asserts that a select matches the given IDs
 * @example t("Check for something", "//[a]", ["foo", "baar"]);
 * @result returns true if "//[a]" return two elements with the IDs 'foo' and 'baar'
 */
function t(a,b,c) {
	var f = jQuery(b);
	var s = "";
	for ( var i = 0; i < f.length; i++ )
		s += (s && ",") + '"' + f[i].id + '"';
	isSet(f, q.apply(q,c), a + " (" + b + ")");
}

/**
 * Add random number to url to stop IE from caching
 *
 * @example url("data/test.html")
 * @result "data/test.html?10538358428943"
 *
 * @example url("data/test.php?foo=bar")
 * @result "data/test.php?foo=bar&10538358345554"
 */
function url(value) {
	return value + (/\?/.test(value) ? "&" : "?") + new Date().getTime() + "" + parseInt(Math.random()*100000);
}

/**
 * Checks that the first two arguments are equal, with an optional message.
 * Prints out both expected and actual values on failure.
 *
 * Prefered to ok( expected == actual, message )
 *
 * @example equals( "Expected 2 characters.", v.formatMessage("Expected {0} characters.", 2) );
 *
 * @param Object actual
 * @param Object expected
 * @param String message (optional)
 */
function equals(actual, expected, message) {
	var result = expected == actual;
	message = message || (result ? "okay" : "failed");
	_config.Test.push( [ result, result ? message + ": " + expected : message + " expected: " + expected + " actual: " + actual ] );
}

/**
 * Trigger an event on an element.
 *
 * @example triggerEvent( document.body, "click" );
 *
 * @param DOMElement elem
 * @param String type
 */
function triggerEvent( elem, type, event ) {
	if ( jQuery.browser.mozilla || jQuery.browser.opera ) {
		event = document.createEvent("MouseEvents");
		event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
			0, 0, 0, 0, 0, false, false, false, false, 0, null);
		elem.dispatchEvent( event );
	} else if ( jQuery.browser.msie ) {
		elem.fireEvent("on"+type);
	}
}
<commit_msg>- Adding the enhancements to the test runner, to accept multiple(and negative) filters from the GET variables, as specified in the ticket #2738.<commit_after>var _config = {
	fixture: null,
	Test: [],
	stats: {
		all: 0,
		bad: 0
	},
	queue: [],
	blocking: true,
	timeout: null,
	expected: null,
	currentModule: null,
	asyncTimeout: 2 // seconds for async timeout
};

_config.filters = location.search.length > 1 && //restrict modules/tests by get parameters
		$.map( location.search.slice(1).split('&'), decodeURIComponent );

var isLocal = !!(window.location.protocol == 'file:');

$(function() {
	$('#userAgent').html(navigator.userAgent);
	runTest();
});

function synchronize(callback) {
	_config.queue[_config.queue.length] = callback;
	if(!_config.blocking) {
		process();
	}
}

function process() {
	while(_config.queue.length && !_config.blocking) {
		var call = _config.queue[0];
		_config.queue = _config.queue.slice(1);
		call();
	}
}

function stop(allowFailure) {
	_config.blocking = true;
	var handler = allowFailure ? start : function() {
		ok( false, "Test timed out" );
		start();
	};
	// Disabled, caused too many random errors
	//_config.timeout = setTimeout(handler, _config.asyncTimeout * 1000);
}
function start() {
	// A slight delay, to avoid any current callbacks
	setTimeout(function(){
		if(_config.timeout)
			clearTimeout(_config.timeout);
		_config.blocking = false;
		process();
	}, 13);
}

function validTest( name ) {
	var filters = _config.filters;
	if( !filters )
		return true;

	var i = filters.length,
		run = false;
	while( i-- ){
		var filter = filters[i],
			not = filter.charAt(0) == '!';
		if( not )
			filter = filter.slice(1);
		if( name.indexOf(filter) != -1 )
			return !not;
		if( not )
			run = true;
	}
	return run;
}

function runTest() {
	_config.blocking = false;
	var time = new Date();
	_config.fixture = document.getElementById('main').innerHTML;
	synchronize(function() {
		time = new Date() - time;
		$("
").html(['
Tests completed in ',
			time, ' milliseconds.
',
			_config.stats.bad, ' tests of ', _config.stats.all, ' failed.
']
			.join(''))
			.appendTo("body");
		$("#banner").addClass(_config.stats.bad ? "fail" : "pass");
	});
}

function test(name, callback, nowait) {
	if(_config.currentModule)
		name = _config.currentModule + " module: " + name;

	if ( !validTest(name) )
		return;

	synchronize(function() {
		_config.Test = [];
		try {
			callback();
		} catch(e) {
			if( typeof console != "undefined" && console.error && console.warn ) {
				console.error("Test " + name + " died, exception and test follows");
				console.error(e);
				console.warn(callback.toString());
			}
			_config.Test.push( [ false, "Died on test #" + (_config.Test.length+1) + ": " + e ] );
		}
	});
	synchronize(function() {
		reset();

		// don't output pause tests
		if(nowait) return;

		if(_config.expected && _config.expected != _config.Test.length) {
			_config.Test.push( [ false, "Expected " + _config.expected + " assertions, but " + _config.Test.length + " were run" ] );
		}
		_config.expected = null;

		var good = 0, bad = 0;
		var ol = document.createElement("ol");
		ol.style.display = "none";
		var li = "", state = "pass";
		for ( var i = 0; i < _config.Test.length; i++ ) {
			var li = document.createElement("li");
			li.className = _config.Test[i][0] ? "pass" : "fail";
			li.innerHTML = _config.Test[i][1];
			ol.appendChild( li );

			_config.stats.all++;
			if ( !_config.Test[i][0] ) {
				state = "fail";
				bad++;
				_config.stats.bad++;
			} else good++;
		}

		var li = document.createElement("li");
		li.className = state;

		var b = document.createElement("strong");
		b.innerHTML = name + " (" + bad + ", " + good + ", " + _config.Test.length + ")";
		b.onclick = function(){
			var n = this.nextSibling;
			if ( jQuery.css( n, "display" ) == "none" )
				n.style.display = "block";
			else
				n.style.display = "none";
		};
		$(b).dblclick(function(event) {
			var target = jQuery(event.target).filter("strong").clone();
			if ( target.length ) {
				target.children().remove();
				location.href = location.href.match(/^(.+?)(\?.*)?$/)[1] + "?" + encodeURIComponent($.trim(target.text()));
			}
		});
		li.appendChild( b );
		li.appendChild( ol );

		document.getElementById("tests").appendChild( li );
	});
}

// call on start of module test to prepend name to all tests
function module(moduleName) {
	_config.currentModule = moduleName;
}

/**
 * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
 */
function expect(asserts) {
	_config.expected = asserts;
}

/**
 * Resets the test setup. Useful for tests that modify the DOM.
 */
function reset() {
	$("#main").html( _config.fixture );
}

/**
 * Asserts true.
 * @example ok( $("a").size() > 5, "There must be at least 5 anchors" );
 */
function ok(a, msg) {
	_config.Test.push( [ !!a, msg ] );
}

/**
 * Asserts that two arrays are the same
 */
function isSet(a, b, msg) {
	var ret = true;
	if ( a && b && a.length != undefined && a.length == b.length ) {
		for ( var i = 0; i < a.length; i++ )
			if ( a[i] != b[i] )
				ret = false;
	} else
		ret = false;
	if ( !ret )
		_config.Test.push( [ ret, msg + " expected: " + serialArray(b) + " result: " + serialArray(a) ] );
	else
		_config.Test.push( [ ret, msg ] );
}

/**
 * Asserts that two objects are equivalent
 */
function isObj(a, b, msg) {
	var ret = true;

	if ( a && b ) {
		for ( var i in a )
			if ( a[i] != b[i] )
				ret = false;

		for ( i in b )
			if ( a[i] != b[i] )
				ret = false;
	} else
		ret = false;

    _config.Test.push( [ ret, msg ] );
}

function serialArray( a ) {
	var r = [];

	if ( a && a.length )
        for ( var i = 0; i < a.length; i++ ) {
            var str = a[i].nodeName;
            if ( str ) {
                str = str.toLowerCase();
                if ( a[i].id )
                    str += "#" + a[i].id;
            } else
                str = a[i];
            r.push( str );
        }

	return "[ " + r.join(", ") + " ]";
}

/**
 * Returns an array of elements with the given IDs, eg.
 * @example q("main", "foo", "bar")
 * @result [
, , <input id="bar">]
 */
function q() {
	var r = [];
	for ( var i = 0; i < arguments.length; i++ )
		r.push( document.getElementById( arguments[i] ) );
	return r;
}

/**
 * Asserts that a select matches the given IDs
 * @example t("Check for something", "//[a]", ["foo", "baar"]);
 * @result returns true if "//[a]" return two elements with the IDs 'foo' and 'baar'
 */
function t(a,b,c) {
	var f = jQuery(b);
	var s = "";
	for ( var i = 0; i < f.length; i++ )
		s += (s && ",") + '"' + f[i].id + '"';
	isSet(f, q.apply(q,c), a + " (" + b + ")");
}

/**
 * Add random number to url to stop IE from caching
 *
 * @example url("data/test.html")
 * @result "data/test.html?10538358428943"
 *
 * @example url("data/test.php?foo=bar")
 * @result "data/test.php?foo=bar&10538358345554"
 */
function url(value) {
	return value + (/\?/.test(value) ? "&" : "?") + new Date().getTime() + "" + parseInt(Math.random()*100000);
}

/**
 * Checks that the first two arguments are equal, with an optional message.
 * Prints out both expected and actual values on failure.
 *
 * Prefered to ok( expected == actual, message )
 *
 * @example equals( "Expected 2 characters.", v.formatMessage("Expected {0} characters.", 2) );
 *
 * @param Object actual
 * @param Object expected
 * @param String message (optional)
 */
function equals(actual, expected, message) {
	var result = expected == actual;
	message = message || (result ? "okay" : "failed");
	_config.Test.push( [ result, result ? message + ": " + expected : message + " expected: " + expected + " actual: " + actual ] );
}

/**
 * Trigger an event on an element.
 *
 * @example triggerEvent( document.body, "click" );
 *
 * @param DOMElement elem
 * @param String type
 */
function triggerEvent( elem, type, event ) {
	if ( jQuery.browser.mozilla || jQuery.browser.opera ) {
		event = document.createEvent("MouseEvents");
		event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
			0, 0, 0, 0, 0, false, false, false, false, 0, null);
		elem.dispatchEvent( event );
	} else if ( jQuery.browser.msie ) {
		elem.fireEvent("on"+type);
	}
}
<|endoftext|>


<commit_before>'use strict';

describe('Controllers Tests ', function () {
  var $scope, createController, DataAcquisitionProjectExportService, MockEntity;

  beforeEach(mockApiAccountCall);
  beforeEach(mockI18nCalls);
  beforeEach(function() {
    inject(function($controller, _$rootScope_, _DataAcquisitionProjectExportService_) {
      $scope = _$rootScope_.$new();
      DataAcquisitionProjectExportService = {
        exportToODT:function(){

        }
      };
      var locals = {
        '$scope' : $scope,
        'entity': MockEntity ,
        'DataAcquisitionProjectExportService': DataAcquisitionProjectExportService,
      };
      createController = function() {
        return $controller('DataAcquisitionProjectDetailController', locals);
      };
      spyOn(DataAcquisitionProjectExportService, 'exportToODT').and.callThrough();
    });
   });
   describe('DataAcquisitionProjectDetailController',function(){
     beforeEach(function(){
         createController();
     });
     it('$scope.isSaving should be false',function(){
       $scope.exportToODT();
       expect(DataAcquisitionProjectExportService.exportToODT).toHaveBeenCalled();
     });
   });
});
<commit_msg>#165 added javaScript tests<commit_after>'use strict';

describe('Controllers Tests ', function() {
    var $scope, createController, $translate,
        DataAcquisitionProjectExportService,
        ExcelParser, $q,
        surveys = [{
          id: 'fdzid',
          questionnaireId: 'fdzid',
          title: {
            en: 'en',
            de: 'de'
          },
          fieldPeriod: {
            start: 'yyyy-mm-dd',
            end: 'yyyy-mm-dd'
          }
        }],
        file = {
          0: {
            name: 'foo',
            size: 500001
          }
        },
        error = {
          data: {
            errors: [{
              message: 'test'
            }],
            status: 200
          },
          config: {
            data: {
              id: 'fdzid',
              errors: []
            }
          }
        };

    beforeEach(mockApiAccountCall);
    beforeEach(mockI18nCalls);
    beforeEach(function() {
        inject(function($controller, _$rootScope_, _$q_, _$translate_) {
            $scope = _$rootScope_.$new();
            $q = _$q_;
            $translate = _$translate_;
            DataAcquisitionProjectExportService = {
                exportToODT: function() {}
            };
            ExcelParser = {
                readFileAsync: function(file) {
                    return {
                        then: function(callback) {
                            return callback(surveys);
                        }
                    };
                }
            };

            var locals = {
                '$scope': $scope,
                'entity': {
                    id: 'fdzid'
                },
                'DataAcquisitionProjectExportService': DataAcquisitionProjectExportService,
                'ExcelParser': ExcelParser,
                '$translate': $translate
            };
            createController = function() {
                return $controller('DataAcquisitionProjectDetailController', locals);
            };
            spyOn(DataAcquisitionProjectExportService, 'exportToODT').and.callThrough();
            spyOn(ExcelParser, 'readFileAsync').and.callThrough();
        });
    });
    describe('DataAcquisitionProjectDetailController', function() {
        beforeEach(function() {
            createController();
        });
        it('$scope.isSaving should be false', function() {
            $scope.exportToODT();
            expect(DataAcquisitionProjectExportService.exportToODT).toHaveBeenCalled();
        });
        it('should call initUploadStatus with 1', function() {
            spyOn($scope, 'initUploadStatus');
            $scope.onSurveyUpload(file);
            expect($scope.initUploadStatus).toHaveBeenCalledWith(1);
        });
        it('should call $translate.instant', function() {
            spyOn($translate, 'instant');
            surveys[0].id = '';
            try {
                $scope.onSurveyUpload(file);
            } catch (e) {

            }
            expect($translate.instant).toHaveBeenCalled();
        });
        it('should set number of progress ', function(){
          $scope.uploadStatus.errors = 1;
          $scope.uploadStatus.successes = 1;
          expect($scope.uploadStatus.getProgress()).toEqual(2);
        });
        it('should return success ', function(){
          expect($scope.uploadStatus.getResult()).toEqual('success');
        });
        it('should return danger ', function(){
          $scope.uploadStatus.errors = 1;
          expect($scope.uploadStatus.getResult()).toEqual('danger');
        });
        it('should set progress state ', function(){
          expect($scope.uploadStatus.getProgressState()).toEqual('0/0');
        });
        it('should set number of success ', function(){
          $scope.uploadStatus.pushSuccess();
          expect($scope.uploadStatus.successes).toEqual(1);
        });
        it('should set number of success ', function(){
          $scope.uploadStatus.pushSuccess();
          expect($scope.uploadStatus.successes).toEqual(1);
        });
        it('should set error message and number of errors', function(){
          $scope.uploadStatus.pushError('error');
          expect($scope.uploadStatus.logMessages.length).toEqual(3);
          expect($scope.uploadStatus.errors).toEqual(1);
        });
        it('should set error message and number of errors', function(){
          $scope.uploadStatus.pushError(error);
          expect($scope.uploadStatus.logMessages.length).toEqual(4);
          expect($scope.uploadStatus.errors).toEqual(1);
        });
        it('should set error message and number of errors', function(){
          error.data = {
              status: 500
          };
          $scope.uploadStatus.pushError(error);
          expect($scope.uploadStatus.logMessages.length).toEqual(4);
          expect($scope.uploadStatus.errors).toEqual(1);
        });
    });
});
<|endoftext|>


<commit_before>/**
 * @fileoverview: The webapp daemon control script invoked by
 * the Apache Commons Daemon jsvc tool.
 */

var system = require('system');
var Server = require('ringo/httpserver').Server;
var server, options;
var log = require('ringo/logging').getLogger(module.id);
var fileutils = require('ringo/fileutils');

export('init', 'start', 'stop', 'destroy', 'getServer');

// parse command line options
var parser = new (require('ringo/args').Parser);
parser.addOption("a", "app", "APP", "The exported property name of the JSGI app (default: 'app')");
parser.addOption("c", "config", "MODULE", "The module containing the JSGI app (default: 'config')");
parser.addOption("j", "jetty-config", "PATH", "The jetty xml configuration file (default. 'config/jetty.xml')");
parser.addOption("H", "host", "ADDRESS", "The IP address to bind to (default: 0.0.0.0)");
parser.addOption("m", "mountpoint", "PATH", "The URI path where to mount the application (default: /)");
parser.addOption("p", "port", "PORT", "The TCP port to listen on (default: 80)");
parser.addOption("s", "static-dir", "DIR", "A directory with static resources to serve");
parser.addOption("S", "static-mountpoint", "PATH", "The URI path where ot mount the static resources");
// parser.addOption("v", "virtual-host", "VHOST", "The virtual host name (default: undefined)");
parser.addOption("h", "help", null, "Print help message and exit");

function init(defaults) {
    log.info("init");
    var options = defaults || {
        config: "config",
        app: "app",
        port: 80
    };
    var cmd = system.args.shift();
    parser.parse(Array.slice(system.args, 1), options);
    if (options.help) {
        print("Usage:");
        print("", cmd, "[OPTIONS]", "[PATH]");
        print("Options:");
        print(parser.help());
        require("ringo/shell").quit();
    }
    server = new Server(options);
}

function start() {
    log.info("start");
    var config = require(options.config);
    if (Array.isArray(config.static)) {
        config.static.forEach(function(spec) {
            var dir = fileutils.resolveId(options.config, spec[1]);
            server.addStaticResources(spec[0], null, dir);
        });
    }
    server.start();
}

function stop() {
    log.info("stop");
    server.stop();
}

function destroy() {
    log.info("destroy");
    server.destroy();
}

function getServer() {
    return server;
}<commit_msg>options is not local in daemon.init()<commit_after>/**
 * @fileoverview: The webapp daemon control script invoked by
 * the Apache Commons Daemon jsvc tool.
 */

var system = require('system');
var Server = require('ringo/httpserver').Server;
var server, options;
var log = require('ringo/logging').getLogger(module.id);
var fileutils = require('ringo/fileutils');

export('init', 'start', 'stop', 'destroy', 'getServer');

// parse command line options
var parser = new (require('ringo/args').Parser);
parser.addOption("a", "app", "APP", "The exported property name of the JSGI app (default: 'app')");
parser.addOption("c", "config", "MODULE", "The module containing the JSGI app (default: 'config')");
parser.addOption("j", "jetty-config", "PATH", "The jetty xml configuration file (default. 'config/jetty.xml')");
parser.addOption("H", "host", "ADDRESS", "The IP address to bind to (default: 0.0.0.0)");
parser.addOption("m", "mountpoint", "PATH", "The URI path where to mount the application (default: /)");
parser.addOption("p", "port", "PORT", "The TCP port to listen on (default: 80)");
parser.addOption("s", "static-dir", "DIR", "A directory with static resources to serve");
parser.addOption("S", "static-mountpoint", "PATH", "The URI path where ot mount the static resources");
// parser.addOption("v", "virtual-host", "VHOST", "The virtual host name (default: undefined)");
parser.addOption("h", "help", null, "Print help message and exit");

function init(defaults) {
    log.info("init");
    options = defaults || {
        config: "config",
        app: "app",
        port: 80
    };
    var cmd = system.args.shift();
    parser.parse(Array.slice(system.args, 1), options);
    if (options.help) {
        print("Usage:");
        print("", cmd, "[OPTIONS]", "[PATH]");
        print("Options:");
        print(parser.help());
        require("ringo/shell").quit();
    }
    server = new Server(options);
}

function start() {
    log.info("start");
    var config = require(options.config);
    if (Array.isArray(config.static)) {
        config.static.forEach(function(spec) {
            var dir = fileutils.resolveId(options.config, spec[1]);
            server.addStaticResources(spec[0], null, dir);
        });
    }
    server.start();
}

function stop() {
    log.info("stop");
    server.stop();
}

function destroy() {
    log.info("destroy");
    server.destroy();
}

function getServer() {
    return server;
}<|endoftext|>