<commit_before>var mongoWebShell = (function () {
  // TODO: Provide a way for the embeder to specify path. <meta> tag? js obj
  // declared on the window obj?
  var CSS_PATH, MWS_BASE_RES_URL, MWS_HOST;
  CSS_PATH = "mongo-web-shell.css";
  MWS_HOST = 'http://localhost:5000';
  MWS_BASE_RES_URL = MWS_HOST + '/mws';

  function injectStylesheet() {
    var linkElement = document.createElement('link');
    linkElement.href = CSS_PATH;
    linkElement.rel = 'stylesheet';
    linkElement.type = 'text/css';
    // TODO: Prepend? This would make the stylesheet overridable.
    $('head').append(linkElement);
  }

  function injectShellHTML(element) {
    // TODO: Use client-side templating instead.
    // TODO: Why is there a border class? Can it be done with CSS border (or be
    // renamed to be more descriptive)?
    // TODO: .mshell not defined in CSS; change it.
    var html = '
' +
                 '
' +
                   '

' +
                   '<form>' +
                     '<input type="text" class="mws-input">' +
                   '</form>' +
                 '
' +
               '
';
    element.innerHTML = html;
  }

  function handleShellInput(data) {
    console.log('Received text:', data);
    // TODO: Merge #25: Parse <input> content; remove console.log. Make AJAX
    // request based on parsed input. On success/error, return output to
    // console, at class mws-in-shell-response.
  }

  function attachShellInputHandler(shellElement) {
    $(shellElement).find('form').submit(function (e) {
      var $input;
      e.preventDefault();
      $input = $(e.target).find('.mws-input');
      handleShellInput($input.val());
      $input.val('');
    });
  }

  return {
    /**
     * Injects a mongo web shell into the DOM wherever an element of class
     * 'mongo-web-shell' can be found. Additionally sets up the resources
     * required by the web shell, including the mws REST resource and the mws
     * CSS stylesheets.
     */
    injectShells: function () {
      injectStylesheet();
      $('.mongo-web-shell').each(function (index, shellElement) {
        injectShellHTML(shellElement);
        // TODO: Disable shell input by default (during creation).
        $.post(MWS_BASE_RES_URL, null, function (data, textStatus, jqXHR) {
          attachShellInputHandler(shellElement);
          // TODO: Enable shell input after disabling above.
          // TODO: Inject returned mws resource id into appropriate elements;
          // maybe <form> so it's easy to get from handleShellInput?
        }, 'json').fail(function (jqXHR, textStatus, errorThrown) {
          // TODO: Display error message in the mongo web shell. Remove log.
          console.log('AJAX request failed:', textStatus, errorThrown);
        });
      });
    }
  };
}());

$(document).ready(mongoWebShell.injectShells);
<commit_msg>Verify resource id returned from web service.<commit_after>var mongoWebShell = (function () {
  // TODO: Provide a way for the embeder to specify path. <meta> tag? js obj
  // declared on the window obj?
  var CSS_PATH, MWS_BASE_RES_URL, MWS_HOST;
  CSS_PATH = "mongo-web-shell.css";
  MWS_HOST = 'http://localhost:5000';
  MWS_BASE_RES_URL = MWS_HOST + '/mws';

  function injectStylesheet() {
    var linkElement = document.createElement('link');
    linkElement.href = CSS_PATH;
    linkElement.rel = 'stylesheet';
    linkElement.type = 'text/css';
    // TODO: Prepend? This would make the stylesheet overridable.
    $('head').append(linkElement);
  }

  function injectShellHTML(element) {
    // TODO: Use client-side templating instead.
    // TODO: Why is there a border class? Can it be done with CSS border (or be
    // renamed to be more descriptive)?
    // TODO: .mshell not defined in CSS; change it.
    var html = '
' +
                 '
' +
                   '

' +
                   '<form>' +
                     '<input type="text" class="mws-input">' +
                   '</form>' +
                 '
' +
               '
';
    element.innerHTML = html;
  }

  function handleShellInput(data, mwsResourceID) {
    console.log('Received text:', data, mwsResourceID);
    // TODO: Merge #25: Parse <input> content; remove console.log. Make AJAX
    // request based on parsed input. On success/error, return output to
    // console, at class mws-in-shell-response.
  }

  function attachShellInputHandler(shellElement, mwsResourceID) {
    $(shellElement).find('form').submit(function (e) {
      var $input;
      e.preventDefault();
      $input = $(e.target).find('.mws-input');
      handleShellInput($input.val(), mwsResourceID);
      $input.val('');
    });
  }

  return {
    /**
     * Injects a mongo web shell into the DOM wherever an element of class
     * 'mongo-web-shell' can be found. Additionally sets up the resources
     * required by the web shell, including the mws REST resource and the mws
     * CSS stylesheets.
     */
    injectShells: function () {
      injectStylesheet();
      $('.mongo-web-shell').each(function (index, shellElement) {
        injectShellHTML(shellElement);
        // TODO: Disable shell input by default (during creation).
        $.post(MWS_BASE_RES_URL, null, function (data, textStatus, jqXHR) {
          if (!data.res_id) {
            // TODO: Print error in shell. Improve error below.
            console.log('No res_id received!', data);
            return;
          }
          attachShellInputHandler(shellElement, data.res_id);
          // TODO: Enable shell input after disabling above.
        }, 'json').fail(function (jqXHR, textStatus, errorThrown) {
          // TODO: Display error message in the mongo web shell. Remove log.
          console.log('AJAX request failed:', textStatus, errorThrown);
        });
      });
    }
  };
}());

$(document).ready(mongoWebShell.injectShells);
<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 20% buffer, to reduce the likelihood of going in to the future
      t_offset = commit_time * -1.2;
      faketime(t_offset);
    }
    try {
      child_process.execFileSync('git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var counter = 0
    process.stdout.write("Queueing up the first commit...\r");
    var timeout;
    if (process.env.FAKETIME) {
      faketime(t_offset);
      timeout = 20;
    } else {
      timeout = randomIntFromInterval(0, max_sleep) * 1000
    }
    setTimeout(commit, timeout, t_offset, outFD, outFile, data, counter, length);<commit_msg>Someone poisoned the waterhole!<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 20% buffer, to reduce the likelihood of going in to the future
      t_offset = commit_time * -1.2;
      faketime(t_offset);
    }
    try {
      child_process.execFileSync('git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var counter = 0
    process.stdout.write("Queueing up the first commit...\r");
    var timeout;
    if (process.env.FAKETIME) {
      faketime(t_offset);
      timeout = 20;
    } else {
      timeout = randomIntFromInterval(0, max_sleep) * 1000
    }
    setTimeout(commit, timeout, t_offset, outFD, outFile, data, counter, length);
<|endoftext|>


<commit_before>/*
 * gpub
 * https://github.com/goliatone/gpub
 *
 * Copyright (c) 2013 goliatone
 * Licensed under the MIT license.
 */
/*global define:true*/
/* jshint strict: false */
define('gpub', function($) {

    var defaults = {
        methodMapping:{
            publish:'publish',
            subscribe:'subscribe',
            unsubscribe:'unsubscribe'
        }
    };

    /**
     * [ description]
     * @param  {[type]} config [description]
     * @return {[type]}        [description]
     */
    var Gpub = function(config){
        this.options = _defaults((config || {}), defaults);

        this._callbacks = {};
    };

    //TODO: do we need to do deep extend?
    var _defaults = function(src, defaults) {
        for (var prop in defaults){
            if(prop in src) continue;
            src[prop] = defaults[prop];
        }
        return src;
    };

    var _publish = function(list, args, options){
        var event, i, l;
        //Invoke callbacks. We need length on each iter
        //cose it could change, unsubscribe.
        // args = _slice.call(arguments, 1);
        //var o;
        for(i = 0, l = list.length; i < l; i++){
            event = list[i];
            if(!event) continue;

            //We want to have a dif. options object
            //for each callback;
            options.event  = event;
            options.target = event.target;//shortcut to access target.
            // o = $.extend({},options);

            if(!event.callback.apply(event.scope, args)) break;
            // if(!event.callback.apply(event.scope, a)) break;
        }
    };

    var _slice = [].slice;

    /**
     * [ description]
     * @param  {[type]} $   [description]
     * @param  {[type]} src [description]
     * @param  {[type]} map [description]
     * @return {[type]}     [description]
     */
    Gpub.prototype.simple = function($, src, map){
        var o = $({});
        src = src || {};
        map = map || this.options.methodMapping;
        src[map['publish']] = function() { o.trigger.apply(o, arguments);};
        src[map['subscribe']] = function() { o.on.apply(o, arguments);};
        src[map['unsubscribe']] = function() { o.off.apply(o, arguments);};
    };

    /**
     * PubSub mixin.
     * TODO: Handle scope!!! <= DONE
     * TODO: Handle options! <= WE NEED TO CLONE THEM!
     *
     * Use:
     * Module.include(PubSub);
     * If we need more complex stuff:
     *
     */
    Gpub.prototype.subscribe = function(topic, callback, scope, options){
        //Create _callbacks, unless we have it
        var topics = this._callbacks[topic] || (this._callbacks[topic] = []);

        //Create an array for the given topic key, unless we have it,
        //then append the callback to the array
        // topic.push(callback);
        var event = {};
        event.topic = topic;
        event.callback = callback;
        event.scope = scope || this;
        event.target = this;
        // event.options = options || {};//_merge((options || {}),{target:this});

        topics.push(event);

        return this;
    };

    /**
     * [ description]
     * @param  {[type]} topic [description]
     * @return {[type]}       [description]
     */
    Gpub.prototype.subscribers = function(topic){

        return this._callbacks.hasOwnProperty(topic) && this._callbacks[topic].length > 0;
    };

    /**
     * TODO: Add 'all' support.
     *
     * @param  {[type]} topic   [description]
     * @param  {[type]} options [description]
     * @return {[type]}         [description]
     */
    Gpub.prototype.publish = function(topic, options){
        //Turn args obj into real array
        var args = _slice.call(arguments, 1);

        //get the first arg, topic name
        options = options || {};

        //include the options into the arguments, making sure that we
        //send it along if we just created it here.
        args.push(options);

        var list, calls, all;
        //return if no callback
        if(!(calls = this._callbacks)) return this;
        //get listeners, if none and no global handlers, return.
        if(!(list = calls[topic]) && !calls['all']) return this;
        //if global handlers, append to list.
        //if((all = calls['all'])) list = (list || []).concat(all);

        if((all = calls['all'])) _publish.call(this, all, _slice.call(arguments, 0), options);
        // if((all = calls['all'])) _publish.call(this, all, [topic].concat(args));
        if(list) _publish.call(this,list, args, options);

        return this;
    };

    /**
     * [ description]
     * @param  {[type]}   topic    [description]
     * @param  {Function} callback [description]
     * @return {[type]}            [description]
     */
    Gpub.prototype.unsubscribe = function(topic, callback/*, scope*/){

        var list, calls, i, l;

        if(!(calls = this._callbacks)) return this;

        if(!(list  = calls[topic])) return this;

        for(i = 0, l = list.length; i < l; i++){
            if(list[i].callback === callback) list.splice(i,1);
        }

        return this;
    };

    return Gpub;
});<commit_msg>Updated method map.<commit_after>/*
 * gpub
 * https://github.com/goliatone/gpub
 *
 * Copyright (c) 2013 goliatone
 * Licensed under the MIT license.
 */
/*global define:true*/
/* jshint strict: false */
define('gpub', function($) {

    var defaults = {
        methodMapping:{
            emit:'publish',
            on:'subscribe',
            off:'unsubscribe',
            emits:'subscribers'
        },
    };

    /**
     * [ description]
     * @param  {[type]} config [description]
     * @return {[type]}        [description]
     */
    var Gpub = function(config){
        this.options = _defaults((config || {}), defaults);
        this._callbacks = {};
    };

    //TODO: do we need to do deep extend?
    var _defaults = function(src, defaults) {
        for (var prop in defaults){
            if(prop in src) continue;
            src[prop] = defaults[prop];
        }
        return src;
    };

    var _publish = function(list, args, options){
        var event, i, l;
        //Invoke callbacks. We need length on each iter
        //cose it could change, off.
        // args = _slice.call(arguments, 1);
        //var o;
        for(i = 0, l = list.length; i < l; i++){
            event = list[i];
            if(!event) continue;

            //We want to have a dif. options object
            //for each callback;
            options.event  = event;
            options.target = event.target;//shortcut to access target.
            // o = $.extend({},options);

            if(!event.callback.apply(event.scope, args)) break;
            // if(!event.callback.apply(event.scope, a)) break;
        }
    };

    var _slice = [].slice;

    /**
     * PubSub mixin.
     * TODO: Handle scope!!! <= DONE
     * TODO: Handle options! <= WE NEED TO CLONE THEM!
     *
     * Use:
     * Module.include(PubSub);
     * If we need more complex stuff:
     *
     */
    Gpub.prototype.on = function(topic, callback, scope, options){
        //Create _callbacks, unless we have it
        var topics = this._callbacks[topic] || (this._callbacks[topic] = []);

        //Create an array for the given topic key, unless we have it,
        //then append the callback to the array
        // topic.push(callback);
        var event = {};
        event.topic = topic;
        event.callback = callback;
        event.scope = scope || this;
        event.target = this;
        // event.options = options || {};//_merge((options || {}),{target:this});

        topics.push(event);

        return this;
    };

    /**
     * [ description]
     * @param  {[type]} topic [description]
     * @return {[type]}       [description]
     */
    Gpub.prototype.emits = function(topic){

        return this._callbacks.hasOwnProperty(topic) && this._callbacks[topic].length > 0;
    };

    /**
     * TODO: Add 'all' support.
     *
     * @param  {[type]} topic   [description]
     * @param  {[type]} options [description]
     * @return {[type]}         [description]
     */
    Gpub.prototype.emit = function(topic, options){
        //Turn args obj into real array
        var args = _slice.call(arguments, 1);

        //get the first arg, topic name
        options = options || {};

        //include the options into the arguments, making sure that we
        //send it along if we just created it here.
        args.push(options);

        var list, calls, all;
        //return if no callback
        if(!(calls = this._callbacks)) return this;
        //get listeners, if none and no global handlers, return.
        if(!(list = calls[topic]) && !calls['all']) return this;
        //if global handlers, append to list.
        //if((all = calls['all'])) list = (list || []).concat(all);

        if((all = calls['all'])) _publish.call(this, all, _slice.call(arguments, 0), options);
        // if((all = calls['all'])) _publish.call(this, all, [topic].concat(args));
        if(list) _publish.call(this,list, args, options);

        return this;
    };

    /**
     * [ description]
     * @param  {[type]}   topic    [description]
     * @param  {Function} callback [description]
     * @return {[type]}            [description]
     */
    Gpub.prototype.off = function(topic, callback/*, scope*/){

        var list, calls, i, l;

        if(!(calls = this._callbacks)) return this;

        if(!(list  = calls[topic])) return this;

        for(i = 0, l = list.length; i < l; i++){
            if(list[i].callback === callback) list.splice(i,1);
        }

        return this;
    };

    Gpub.observable = function(src, options){

    };

    Gpub.delegable = function(src, events){
        var event,
            e;
        if(typeof event === 'string') events = events.split(' ');

        events.forEach(function(event){
            src['on'+event] = (function(handler){
                this.on(event, handler);
            }).bind(src);
        });
    };

    Gpub.bindable = function(src, get, set, bind){
        if(!('on' in src) || !('emit' in src)) this.observable(src);

        var _set = src[set], _get = src[get];

        var method = function(key, value){
            var old = _get.call(this, key),
                out = _set.call(this, key, value),
                evt = {odl:old, value:value};

            if (this.emits('change')) this.emit('change', evt);
            if (this.emits('change:' + key)) this.emit('change:'+key, evt);
            return out;
        };

        if(bind) method.bind(src);

        src[set] = method;
    };

    Gpub.prototype.publish     = Gpub.prototype.emit;
    Gpub.prototype.subscribe   = Gpub.prototype.on;
    Gpub.prototype.unsubscribe = Gpub.prototype.off;
    Gpub.prototype.subscribers = Gpub.prototype.emits;

    return Gpub;
});<|endoftext|>


<commit_before>/**
 * @file 表单验证
 * @author xiaowu <fe.xiaowu@gmail.com>
 * @module validate/form
 */

define(function (require) {
    'use strict';

    var Zui = require('zui');
    var $ = required('zepto');

    var Form = Zui.extend({
        constructor: function () {
            Form.super.constructor.call(this);
        }
    });

    /**
     * 默认规则数据
     *
     * @type {Object}
     */
    Form.rulesData = {
        required: {
            check: function () {

            },
            message: ''
        },

        email: {
            check: /1/,
            message: ''
        },

        minlength: {
            check: 1
        },

        maxlength: {
            check: function (value, rule) {

            }
        }
    };

    /**
     * 验证
     *
     * @param  {string} key   规则名称
     * @param  {string} value 要验证的值
     *
     * @return {boolean}       是否通过
     */
    Form.checkRule = function (key, value) {
        var data = Form.rulesData[key];

        // 如果没有规则数据
        if (!data || !value) {
            return false;
        }

        // 如果规则是字符串则必须相等
        if ('string' === typeof data.check) {
            return value === data.check;
        }

        // 如果是数字
        else if ('number' === typeof data.check) {
            return Number(data.check) === value;
        }

        // 如果是正则
        else if (data.check instanceof RegExp) {
            return data.check.test(value);
        }

        // 如果是方法
        else if ('function' === typeof data.check) {
            return data.check(value);
        }

        return false;
    };

    /**
     * 添加规则
     *
     * @param {string|Object} key  规则名或者数据
     * @param {string|RegExt|Function} check 验证数据
     */
    Form.addRule = function (key, check, message) {
        if ('string' !== typeof key || !check) {
            return Form;
        }

        Form.rulesData[key] = {
            check: check,
            message: message
        };

        return Form;
    };

    /**
     * 删除规则
     *
     * @param  {string} key 规则名称
     */
    Form.removeRule = function (key) {
        delete Form.rulesData[key];
    };

    /**
     * 默认参数
     *
     * @type {Object}
     */
    Form.defaults = {
        elem: null,
        event: 'submit',
        ignoreElem: null,
        rules: {
            username: {
                required: true,
                minlength: 6,
                maxlength: 10
            }
        }
    };

    return Form;
});
<commit_msg>update: 更新内置规则<commit_after>/**
 * @file 表单验证
 * @author xiaowu <fe.xiaowu@gmail.com>
 * @module validate/form
 */

define(function (require) {
    'use strict';

    var Zui = require('zui');
    var $ = required('zepto');

    var Form = Zui.extend({
        constructor: function () {
            Form.super.constructor.call(this);
        }
    });

    /**
     * 默认规则数据
     *
     * @type {Object}
     */
    Form.rulesData = {
        required: {
            check: function (value) {
                return !!value;
            },
            message: '必须'
        },

        email: {
            check: /1/,
            message: ''
        },

        minlength: {
            check: function (value, rule) {
                return String(value).length >= rule;
            },
            check: 1
        },

        maxlength: {
            check: function (value, rule) {
                return String(value).length <= rule;
            }
        }
    };

    /**
     * 验证
     *
     * @param  {string} key   规则名称
     * @param  {string} value 要验证的值
     *
     * @return {boolean}       是否通过
     */
    Form.checkRule = function (key, value) {
        var data = Form.rulesData[key];

        // 如果没有规则数据
        if (!data || !value) {
            return false;
        }

        // 如果规则是字符串则必须相等
        if ('string' === typeof data.check) {
            return value === data.check;
        }

        // 如果是数字
        else if ('number' === typeof data.check) {
            return Number(data.check) === value;
        }

        // 如果是正则
        else if (data.check instanceof RegExp) {
            return data.check.test(value);
        }

        // 如果是方法
        else if ('function' === typeof data.check) {
            return data.check(value);
        }

        return false;
    };

    /**
     * 添加规则
     *
     * @param {string|Object} key  规则名或者数据
     * @param {string|RegExt|Function} check 验证数据
     */
    Form.addRule = function (key, check, message) {
        if ('string' !== typeof key || !check) {
            return Form;
        }

        Form.rulesData[key] = {
            check: check,
            message: message
        };

        return Form;
    };

    /**
     * 删除规则
     *
     * @param  {string} key 规则名称
     */
    Form.removeRule = function (key) {
        delete Form.rulesData[key];
    };

    /**
     * 默认参数
     *
     * @type {Object}
     */
    Form.defaults = {
        elem: null,
        event: 'submit',
        ignoreElem: null,
        rules: {
            username: {
                required: true,
                minlength: 6,
                maxlength: 10
            }
        }
    };

    return Form;
});
<|endoftext|>


<commit_before>import _ from 'lodash'
import Role from './models/role'

const ids = {}
const names = {}
let roles = []
let isLoaded = false

function load(cb) {
  Role.find({}, function(err, documents) {
    if (err) {
      return cb(err)
    }

    roles = roles.concat(documents)
    roles.forEach(function(role) {
      ids[role.id] = role
      names[role.name] = role
    })

    isLoaded = true

    cb()
  })
}

function getByName(role) {
  if (!isLoaded) {
    throw new Error('Roles not loaded')
  }

  return names[role.toUpperCase()]
}

function getById(role) {
  if (!isLoaded) {
    throw new Error('Roles not loaded')
  }

  return ids[role]
}

/**
 * Normalize role input as string
 * @param {String} role
 * @returns {Object} The normalized role
 */
function normalizeString(role) {
  // Evaluate as ID
  if (getById(role)) {
    return getById(role)
  }
  // Evaluate as name
  if (getByName(role)) {
    return getByName(role)
  }

  // Return guest
  return getByName('guest')
}

/**
 * Normalize role input as object
 * @param {String} role
 * @returns {Role} The normalized role
 */
function normalizeObject(role) {
  // Evaluate as native MongoDB ObjectID
  if (role.toString && getById(role.toString())) {
    return getById(role.toString())
  }

  // Evaluate as object with id.toString()
  if (role.id && getById(role.id)) {
    return getById(role.id)
  }

  // Evaluate as object with id
  if (role.id && getById(role.id)) {
    return getById(role.id)
  }

  // Evaluate as object with name
  if (role.name && getByName(role.name)) {
    return getByName(role.name)
  }

  // Return guest
  return getByName('guest')
}

/**
 * Normalize input values and returns the specified role
 * @param {String|Object} role
 * @returns {Role} The normalized role
 */
function normalize(role) {
  if (!role) {
    throw 'Invalid role: ' + role
  }

  if (!roles) {
    throw 'Roles middleware is not ready'
  }

  if (_.isString(role)) {
    return normalizeString(role)
  }

  if (_.isObject(role)) {
    return normalizeObject(role)
  }

  // Return guest
  return getByName('guest')
}

/**
 * Get role by ID, name or the role object itself.
 * Use this method to normalize access to roles.
 * @param {String|Object} role
 * @returns {Role}
 */
function get(role) {
  role = normalize(role)

  if (!role) {
    throw new Error('Role does not exist')
  }

  return role
}

/**
 * Add role
 * @param {String} name
 * @param {String} [parent]
 * @returns {Role}
 */
function add(name, parent) {
  let role = new Role({
    name: name,
    parent: parent ? get(parent) : null
  })

  names[role] = role

  return role
}

/**
 * Is role already registered
 * @param {String|Object} role
 * @returns {Boolean}
 */
function has(role) {
  return get(role) ? true : false
}

export default Object.freeze({
  add,
  has,
  get,
  load
})
<commit_msg>fix: handle normalize failures by failing silenty(not optimal)<commit_after>import _ from 'lodash'
import Role from './models/role'

const ids = {}
const names = {}
let roles = []
let isLoaded = false

function load(cb) {
  Role.find({}, function(err, documents) {
    if (err) {
      return cb(err)
    }

    roles = roles.concat(documents)
    roles.forEach(function(role) {
      ids[role.id] = role
      names[role.name] = role
    })

    isLoaded = true

    cb()
  })
}

function getByName(role) {
  if (!isLoaded) {
    throw new Error('Roles not loaded')
  }

  return names[role.toUpperCase()]
}

function getById(role) {
  if (!isLoaded) {
    throw new Error('Roles not loaded')
  }

  return ids[role]
}

/**
 * Normalize role input as string
 * @param {String} role
 * @returns {Object} The normalized role
 */
function normalizeString(role) {
  // Evaluate as ID
  if (getById(role)) {
    return getById(role)
  }
  // Evaluate as name
  if (getByName(role)) {
    return getByName(role)
  }

  // Return guest
  return getByName('guest')
}

/**
 * Normalize role input as object
 * @param {String} role
 * @returns {Role} The normalized role
 */
function normalizeObject(role) {
  // Evaluate as native MongoDB ObjectID
  if (role.toString && getById(role.toString())) {
    return getById(role.toString())
  }

  // Evaluate as object with id.toString()
  if (role.id && getById(role.id)) {
    return getById(role.id)
  }

  // Evaluate as object with id
  if (role.id && getById(role.id)) {
    return getById(role.id)
  }

  // Evaluate as object with name
  if (role.name && getByName(role.name)) {
    return getByName(role.name)
  }

  // Return guest
  return getByName('guest')
}

/**
 * Normalize input values and returns the specified role
 * @param {String|Object} role
 * @returns {Role} The normalized role
 */
function normalize(role) {
  if (!role) {
    throw 'Invalid role: ' + role
  }

  if (!roles) {
    throw 'Roles middleware is not ready'
  }

  if (_.isString(role)) {
    return normalizeString(role)
  }

  if (_.isObject(role)) {
    return normalizeObject(role)
  }

  // Return guest
  return getByName('guest')
}

/**
 * Get role by ID, name or the role object itself.
 * Use this method to normalize access to roles.
 * @param {String|Object} role
 * @returns {Role}
 */
function get(role) {
  try {
    return normalize(role)
  } catch (err) {
    // FIXME this should not fail silenty
    return getByName('guest')
  }

  return getByName('guest')
}

/**
 * Add role
 * @param {String} name
 * @param {String} [parent]
 * @returns {Role}
 */
function add(name, parent) {
  let role = new Role({
    name: name,
    parent: parent ? get(parent) : null
  })

  names[role] = role

  return role
}

/**
 * Is role already registered
 * @param {String|Object} role
 * @returns {Boolean}
 */
function has(role) {
  return get(role) ? true : false
}

export default Object.freeze({
  add,
  has,
  get,
  load
})
<|endoftext|>


<commit_before>/**
 * Toolbar Core Module
 * @class Core.Module.Toolbar
 * @author Jerome Vial, Bruno Santos
 */
define(function(require, exports, module) {

  //var appIconConfig = require('config/icon/app');
  var fontIconConfig = require('config/icon/font');
  var mdiIconConfig = require('config/icon/mdi');
  var langControlsConfigEn = require('config/sys/lang/control/en');
  var langControlsConfigFr = require('config/sys/lang/control/fr');
  var settings = require('Core/Module/Settings/Settings');

  var _log = __debug('core-module-toolbar').defineLevel();

  var Toolbar = new Class({

    /**
     * initialize toolbar
     * @param {Object} obj
     */
    _initToolbar: function(obj) {
      _log.debug('_initToolbar', obj);

      this.langControl = {
        en: langControlsConfigEn,
        fr: langControlsConfigFr
      };

      this.toolbar = {};
      this.control = {};

      if (!obj.list) {
        _log.warn('missing list field');
        return;
      }

      this._initToolbarReady(obj);

      for (var i = 0; obj.list.length > i; i++) {
        var name = obj.list[i];
        var bar = obj[name];

        if (!bar) {
          continue;
        }

        //continue if container is not defined
        if (!bar.container) {
          continue;
        }

        //init container if doesn't exist
        if (!this.container[bar.container]) {
          this.container['_init' + bar.container.capitalize()]();
        }

        var element = this._initToolbarEl(name, bar);

        this._initToolbarComp(bar, element);
      }

      this.container.fireEvent('resize');
    },

    /**
     * init toolbar element
     * @param  {string} name
     * @param  {Object} bar
     * @return {DOMElement}
     */
    _initToolbarEl: function(name, bar) {
      var element = this.toolbar[name] = new Element('div', {
        'class': 'ui-toolbar'
      }).addEvents({

      }).inject(this.container[bar.container]);

      if (bar.klss) {
        element.addClass(bar.klss);
      }

      element.addClass('toolbar-' + name);

      return element;
    },

    /**
     * init toolbar eeady
     * @return {void}
     */
    _initToolbarReady: function(obj) {
      var self = this;
      this.ready = 0;
      this.isReady = 0;

      Object.map(obj, function(map) {
        if (map.list) {
          self.ready = self.ready + map.list.length;
        }
      });

      this.addEvent('isReady', function(isReady) {
        //_log.debug('isready', isReady);
        if (isReady >= this.ready) {
          //_log.debug('toolbarReady');
          self.fireEvent('toolbarReady', isReady);
        }
      });
    },

    /**
     * init toolbar comp
     * @param {Object} bar
     * @param {DOMElement} element
     */
    _initToolbarComp: function(bar, element) {
      _log.debug('_initToolbarComp', bar, element);

      bar.list = bar.list || [];

      for (var i = 0; i < bar.list.length; i++) {
        var name = bar.list[i];
        var def = bar[name] || {};
        this._instanciateComp(name, def, element);
      }
    },

    /**
     * [_instanciateComp description]
     * @param  {string} name    [description]
     * @param  {Object} def     [description]
     * @param  {HTMLElement} element [description]
     * @return {void}
     */
    _instanciateComp: function(name, def, element) {
      _log.debug('_instanciateComp', name, def, element);

      var self = this;
      var clss = def.clss || 'UI/Control/Button';

      //process name and klss for components with ::
      var temp = name.split(/\:\:/);
      name = temp[0];
      temp.splice(0, 1);
      var klss = temp.join(' ');

      if (!name) {
        _log.warn('missing name');
        return;
      }

      //handle separator
      if (name === 'separator') {
        clss = 'UI/Control/Separator';
      }

      var icon = def.icon || name;
      var opts = {
        name: name,
        icon: fontIconConfig[icon] || 'mdi-action-help',
        type: 'action',
        klss: klss
      };

      if (def.opts) {
        opts = def.opts;
        opts.text = Locale.get('control.' + name, name) || name;
        opts.icon = mdiIconConfig[icon] || fontIconConfig[icon] || 'mdi-action-help';
      }

      var lang = 'en';
      if (settings && settings.getLang) {
        lang = settings.getLang() || 'en';
      }

      if (!this.langControl[lang]) {
        lang = 'en';
      }

      var text = '';
      if (def.text) {
        text = this.langControl[lang][name] || def.text;
      }

      if (clss === 'UI/Control/Button' || clss === 'UI/Control/ButtonMenu') {
        opts.text = this.langControl[lang][name] || Locale.get('control.' + name, name) || text || name;
      }

      var isAllow = this._isAllow(name);

      if (isAllow) {
        _log.debug('require module', name, clss, opts);
        this._requireModule(clss, function(Clss) {
          self._initToolbarControl(Clss, name, clss, opts, element);
        });

        self.isReady++;
        self.fireEvent('isReady', self.isReady);
      }
    },

    /**
     * check role for control
     * @return {boolean}
     */
    _isAllow: function(name) {
      var isAllow = true;
      var role = null;

      if (!this.sandbox) {
        _log.warn('no sandbox');
      } else {
        var user = this.sandbox.getCurrentUser();
        if (user && user.role) {
          role = user.role;
        }
      }

      this.options.control = this.options.control || {};

      if (!this.options.control[role] || this.options.control[role].disallowed) {
        return isAllow;
      }

      if (this.options.control[role].disallowed.indexOf(name) !== -1) {
        isAllow = false;
      }

      return isAllow;
    },

    /**
     * _initToolbarControl
     */
    _initToolbarControl: function(Clss, name, clss, opts, element) {
      //_log.debug('Clss', typeOf(Clss));

      var self = this;

      if (!Clss) {
        _log.warn('not found, should require?', name, opts);
        return;
      }

      this.control[name] = new Clss(opts).inject(element);

      // init more toolbar menu
      if (name === 'more') {
        this._initMore();
        return;
      }

      self.control[name].addEvents({
        /**
         * @ignore
         */
        change: function(value) {
          //var name =  this.options.name;
          //_log.debug('change', this);
          if (this.isEnable()) {
            self.fireEvent(name, value);
          }
        }
      });

      if (clss === 'UI/Control/Button') {
        self.control[name].addEvents({
          /**
           * @ignore
           */
          press: function() {
            _log.debug('press', name);
            self.fireEvent('control::pressed');
            //var name =  this.options.name;
            //_log.debug('press', name, this.isEnable());
            if (this.isEnable()) {
              self.fireEvent('control::' + name, this);
              self.fireEvent(name, [self]);
            }
          }
        });
      }

      if (clss === 'UI/Control/Upload') {
        self.control[name].addEvents({
          /**
           * @ignore
           */
          uploadFile: function(files) {
            _log.debug('uploadFile', files);
            if (this.isEnable()) {
              //self.fireEvent('control::'+name, this);
              self.fireEvent(name, [files]);
            }
          }
        });
      }

      if (clss === 'UI/Control/Field') {
        self.control[name].addEvents({
          /**
           * @ignore
           */
          change: function() {
            //_log.debug('change', name, this.isEnable());
            self.fireEvent('control::pressed');
            //var name =  this.options.name;
            //_log.debug('press', name, this.isEnable());
            if (this.isEnable()) {
              self.fireEvent('control::' + name, this);
              self.fireEvent(name, [self]);
            }
          }
        });
      }

      if (clss === 'UI/Control/ButtonMenu') {
        self.control[name].addEvents({
          /**
           * @ignore
           */
          press: function(name) {
            self.fireEvent('control::pressed');
            //var name =  this.options.name;
            _log.debug('ButtonMenu press', name, this.isEnable());
            if (this.isEnable()) {
              self.fireEvent('control::' + name, this);
              self.fireEvent(name, [self]);
            }
          }
        });
      }
    },

    /**
     * [_initMore description]
     * @return {void}
     */
    _initMore: function() {
      _log.debug('_initMore', this.toolbar.more);

      if (!this.control || !this.toolbar) {
        _log.warn('missing control or toolbar');
        return null;
      }

      var timer = null;

      var toolbar = this.toolbar.more;
      var control = this.control.more;

      if (!control || !toolbar) {
        _log.warn('missing control or toolbar', control, toolbar);
        return;
      }

      control.addEvent('press', function(ev) {
        _log.debug('-- press', ev);
        //var coord = control.getCoordinates();
        toolbar.setStyles({
          display: 'inline-block'
        });

        return true;
      });

      this.addEvent('control::pressed', function() {
        toolbar.setStyle('display', 'none');
      });

      toolbar.addEvents({
        /**
         * @ignore
         */
        mouseleave: function() {
          clearTimeout(timer);
          timer = setTimeout(function() {
            toolbar.setStyle('display', 'none');
          }, 500);
        },
        /**
         * @ignore
         */
        mouseenter: function() {
          clearTimeout(timer);
        },
        /**
         * @ignore
         */
        click: function() {
          toolbar.setStyle('display', 'none');
        }
      });
    },

    /**
     * [_requireView description]
     * @return {void}
     */
    _requireModule: function(module, cb) {
      _log.debug('_requireModule', module);
      if (typeOf(module) === 'class') {
        cb(module);
        return;
      }

      require([module], function(Class) {
        cb(Class);
      }, function(err) {
        _log.error(module, err);
        cb();
      });
    }

  });

  module.exports = Toolbar;

});
<commit_msg>remove sandbox from toolbar + fix isAllow method<commit_after>/**
 * Toolbar Core Module
 * @class Core.Module.Toolbar
 * @author Jerome Vial, Bruno Santos
 */
define(function(require, exports, module) {

  //var appIconConfig = require('config/icon/app');
  var fontIconConfig = require('config/icon/font');
  var mdiIconConfig = require('config/icon/mdi');
  var langControlsConfigEn = require('config/sys/lang/control/en');
  var langControlsConfigFr = require('config/sys/lang/control/fr');
  var settings = require('Core/Module/Settings/Settings');

  var _log = __debug('core-module-toolbar').defineLevel();

  var Toolbar = new Class({

    options: {
      toolbar: {
        role: 'admin'
      }
    },

    /**
     * initialize toolbar
     * @param {Object} obj
     */
    _initToolbar: function(obj) {
      _log.debug('_initToolbar', obj);

      this.langControl = {
        en: langControlsConfigEn,
        fr: langControlsConfigFr
      };

      this.toolbar = {};
      this.control = {};

      if (!obj.list) {
        _log.warn('missing list field');
        return;
      }

      this._initToolbarReady(obj);

      for (var i = 0; obj.list.length > i; i++) {
        var name = obj.list[i];
        var bar = obj[name];

        if (!bar) {
          continue;
        }

        //continue if container is not defined
        if (!bar.container) {
          continue;
        }

        //init container if doesn't exist
        if (!this.container[bar.container]) {
          this.container['_init' + bar.container.capitalize()]();
        }

        var element = this._initToolbarEl(name, bar);

        this._initToolbarComp(bar, element);
      }

      this.container.fireEvent('resize');
    },

    /**
     * init toolbar element
     * @param  {string} name
     * @param  {Object} bar
     * @return {DOMElement}
     */
    _initToolbarEl: function(name, bar) {
      var element = this.toolbar[name] = new Element('div', {
        'class': 'ui-toolbar'
      }).addEvents({

      }).inject(this.container[bar.container]);

      if (bar.klss) {
        element.addClass(bar.klss);
      }

      element.addClass('toolbar-' + name);

      return element;
    },

    /**
     * init toolbar eeady
     * @return {void}
     */
    _initToolbarReady: function(obj) {
      var self = this;
      this.ready = 0;
      this.isReady = 0;

      Object.map(obj, function(map) {
        if (map.list) {
          self.ready = self.ready + map.list.length;
        }
      });

      this.addEvent('isReady', function(isReady) {
        //_log.debug('isready', isReady);
        if (isReady >= this.ready) {
          //_log.debug('toolbarReady');
          self.fireEvent('toolbarReady', isReady);
        }
      });
    },

    /**
     * init toolbar comp
     * @param {Object} bar
     * @param {DOMElement} element
     */
    _initToolbarComp: function(bar, element) {
      _log.debug('_initToolbarComp', bar, element);

      bar.list = bar.list || [];

      for (var i = 0; i < bar.list.length; i++) {
        var name = bar.list[i];
        var def = bar[name] || {};
        this._instanciateComp(name, def, element);
      }
    },

    /**
     * [_instanciateComp description]
     * @param  {string} name    [description]
     * @param  {Object} def     [description]
     * @param  {HTMLElement} element [description]
     * @return {void}
     */
    _instanciateComp: function(name, def, element) {
      _log.debug('_instanciateComp', name, def, element);

      var self = this;
      var clss = def.clss || 'UI/Control/Button';

      //process name and klss for components with ::
      var temp = name.split(/\:\:/);
      name = temp[0];
      temp.splice(0, 1);
      var klss = temp.join(' ');

      if (!name) {
        _log.warn('missing name');
        return;
      }

      //handle separator
      if (name === 'separator') {
        clss = 'UI/Control/Separator';
      }

      var icon = def.icon || name;
      var opts = {
        name: name,
        icon: fontIconConfig[icon] || 'mdi-action-help',
        type: 'action',
        klss: klss
      };

      if (def.opts) {
        opts = def.opts;
        opts.text = Locale.get('control.' + name, name) || name;
        opts.icon = mdiIconConfig[icon] || fontIconConfig[icon] || 'mdi-action-help';
      }

      var lang = 'en';
      if (settings && settings.getLang) {
        lang = settings.getLang() || 'en';
      }

      if (!this.langControl[lang]) {
        lang = 'en';
      }

      var text = '';
      if (def.text) {
        text = this.langControl[lang][name] || def.text;
      }

      if (clss === 'UI/Control/Button' || clss === 'UI/Control/ButtonMenu') {
        opts.text = this.langControl[lang][name] || Locale.get('control.' + name, name) || text || name;
      }

      var isAllow = this._isAllow(name);

      if (isAllow) {
        _log.debug('require module', name, clss, opts);
        this._requireModule(clss, function(Clss) {
          self._initToolbarControl(Clss, name, clss, opts, element);
        });

        self.isReady++;
        self.fireEvent('isReady', self.isReady);
      }
    },

    /**
     * check role for control
     * @return {boolean}
     */
    _isAllow: function(name) {
      var isAllow = true;
      var role = this.options.toolbar.role;

      this.options.control = this.options.control || {};

      var ctrRole = this.options.control[role];

      if (!ctrRole || !ctrRole.disallowed) {
        return isAllow;
      }

      if (ctrRole.disallowed.indexOf(name) !== -1) {
        isAllow = false;
      }

      return isAllow;
    },

    /**
     * _initToolbarControl
     */
    _initToolbarControl: function(Clss, name, clss, opts, element) {
      //_log.debug('Clss', typeOf(Clss));

      var self = this;

      if (!Clss) {
        _log.warn('not found, should require?', name, opts);
        return;
      }

      this.control[name] = new Clss(opts).inject(element);

      // init more toolbar menu
      if (name === 'more') {
        this._initMore();
        return;
      }

      self.control[name].addEvents({
        /**
         * @ignore
         */
        change: function(value) {
          //var name =  this.options.name;
          //_log.debug('change', this);
          if (this.isEnable()) {
            self.fireEvent(name, value);
          }
        }
      });

      if (clss === 'UI/Control/Button') {
        self.control[name].addEvents({
          /**
           * @ignore
           */
          press: function() {
            _log.debug('press', name);
            self.fireEvent('control::pressed');
            //var name =  this.options.name;
            //_log.debug('press', name, this.isEnable());
            if (this.isEnable()) {
              self.fireEvent('control::' + name, this);
              self.fireEvent(name, [self]);
            }
          }
        });
      }

      if (clss === 'UI/Control/Upload') {
        self.control[name].addEvents({
          /**
           * @ignore
           */
          uploadFile: function(files) {
            _log.debug('uploadFile', files);
            if (this.isEnable()) {
              //self.fireEvent('control::'+name, this);
              self.fireEvent(name, [files]);
            }
          }
        });
      }

      if (clss === 'UI/Control/Field') {
        self.control[name].addEvents({
          /**
           * @ignore
           */
          change: function() {
            //_log.debug('change', name, this.isEnable());
            self.fireEvent('control::pressed');
            //var name =  this.options.name;
            //_log.debug('press', name, this.isEnable());
            if (this.isEnable()) {
              self.fireEvent('control::' + name, this);
              self.fireEvent(name, [self]);
            }
          }
        });
      }

      if (clss === 'UI/Control/ButtonMenu') {
        self.control[name].addEvents({
          /**
           * @ignore
           */
          press: function(name) {
            self.fireEvent('control::pressed');
            //var name =  this.options.name;
            _log.debug('ButtonMenu press', name, this.isEnable());
            if (this.isEnable()) {
              self.fireEvent('control::' + name, this);
              self.fireEvent(name, [self]);
            }
          }
        });
      }
    },

    /**
     * [_initMore description]
     * @return {void}
     */
    _initMore: function() {
      _log.debug('_initMore', this.toolbar.more);

      if (!this.control || !this.toolbar) {
        _log.warn('missing control or toolbar');
        return null;
      }

      var timer = null;

      var toolbar = this.toolbar.more;
      var control = this.control.more;

      if (!control || !toolbar) {
        _log.warn('missing control or toolbar', control, toolbar);
        return;
      }

      control.addEvent('press', function(ev) {
        _log.debug('-- press', ev);
        //var coord = control.getCoordinates();
        toolbar.setStyles({
          display: 'inline-block'
        });

        return true;
      });

      this.addEvent('control::pressed', function() {
        toolbar.setStyle('display', 'none');
      });

      toolbar.addEvents({
        /**
         * @ignore
         */
        mouseleave: function() {
          clearTimeout(timer);
          timer = setTimeout(function() {
            toolbar.setStyle('display', 'none');
          }, 500);
        },
        /**
         * @ignore
         */
        mouseenter: function() {
          clearTimeout(timer);
        },
        /**
         * @ignore
         */
        click: function() {
          toolbar.setStyle('display', 'none');
        }
      });
    },

    /**
     * [_requireView description]
     * @return {void}
     */
    _requireModule: function(module, cb) {
      _log.debug('_requireModule', module);
      if (typeOf(module) === 'class') {
        cb(module);
        return;
      }

      require([module], function(Class) {
        cb(Class);
      }, function(err) {
        _log.error(module, err);
        cb();
      });
    }

  });

  module.exports = Toolbar;

});
<|endoftext|>


<commit_before>module.exports = {
  'rules': {
    // enforce spacing inside array brackets
    'array-bracket-spacing': [2, 'never'],
    // enforce one true brace style
    'brace-style': [2, '1tbs', { 'allowSingleLine': true }],
    // require camel case names
    'camelcase': [2, { 'properties': 'never' }],
    // enforce spacing before and after comma
    'comma-spacing': [2, { 'before': false, 'after': true }],
    // enforce one true comma style
    'comma-style': [2, 'last'],
    // disallow padding inside computed properties
    'computed-property-spacing': [2, 'never'],
    // enforces consistent naming when capturing the current execution context
    'consistent-this': 0,
    // enforce newline at the end of file, with no multiple empty lines
    'eol-last': 2,
    // require function expressions to have a name
    'func-names': 1,
    // enforces use of function declarations or expressions
    'func-style': 0,
    // this option enforces minimum and maximum identifier lengths
    // (variable names, property names etc.)
    'id-length': 0,
    // this option sets a specific tab width for your code
    // https://github.com/eslint/eslint/blob/master/docs/rules/indent.md
    'indent': [2, 2, { 'SwitchCase': 1, 'VariableDeclarator': 1 }],
    // specify whether double or single quotes should be used in JSX attributes
    // http://eslint.org/docs/rules/jsx-quotes
    'jsx-quotes': [2, 'prefer-double'],
    // enforces spacing between keys and values in object literal properties
    'key-spacing': [2, { 'beforeColon': false, 'afterColon': true }],
    // require a space before & after certain keywords
    'keyword-spacing': [2, {
      'before': true,
      'after': true,
      'overrides': {
        'return': { 'after': true },
        'throw': { 'after': true },
        'case': { 'after': true }
      }
    }],
    // enforces empty lines around comments
    'lines-around-comment': 0,
    // disallow mixed 'LF' and 'CRLF' as linebreaks
    'linebreak-style': 0,
    // specify the maximum length of a line in your program
    // https://github.com/eslint/eslint/blob/master/docs/rules/max-len.md
    'max-len': [2, 100, 2, {
      'ignoreUrls': true,
      'ignoreComments': false
    }],
    // specify the maximum depth callbacks can be nested
    'max-nested-callbacks': 0,
    // require a capital letter for constructors
    'new-cap': [2, { 'newIsCap': true }],
    // disallow the omission of parentheses when invoking a constructor with no arguments
    'new-parens': 0,
    // allow/disallow an empty newline after var statement
    'newline-after-var': 0,
    // enforces new line after each method call in the chain to make it more readable and easy to maintain
    // http://eslint.org/docs/rules/newline-per-chained-call
    'newline-per-chained-call': [2, { "ignoreChainWithDepth": 3 }],
    // disallow use of the Array constructor
    'no-array-constructor': 0,
    // disallow use of the continue statement
    'no-continue': 0,
    // disallow comments inline after code
    'no-inline-comments': 0,
    // disallow if as the only statement in an else block
    'no-lonely-if': 0,
    // disallow mixed spaces and tabs for indentation
    'no-mixed-spaces-and-tabs': 2,
    // disallow multiple empty lines and only one newline at the end
    'no-multiple-empty-lines': [2, { 'max': 2, 'maxEOF': 1 }],
    // disallow nested ternary expressions
    'no-nested-ternary': 2,
    // disallow use of the Object constructor
    'no-new-object': 2,
    // disallow space between function identifier and application
    'no-spaced-func': 2,
    // disallow the use of ternary operators
    'no-ternary': 0,
    // disallow trailing whitespace at the end of lines
    'no-trailing-spaces': 2,
    // disallow dangling underscores in identifiers
    'no-underscore-dangle': 0,
    // disallow the use of Boolean literals in conditional expressions
    // also, prefer `a || b` over `a ? a : b`
    // http://eslint.org/docs/rules/no-unneeded-ternary
    'no-unneeded-ternary': [2, { 'defaultAssignment': false }],
    // disallow whitespace before properties
    // http://eslint.org/docs/rules/no-whitespace-before-property
    'no-whitespace-before-property': 2,
    // require padding inside curly braces
    'object-curly-spacing': [2, 'always'],
    // allow just one var statement per function
    'one-var': [2, 'never'],
    // require assignment operator shorthand where possible or prohibit it entirely
    'operator-assignment': 0,
    // enforce operators to be placed before or after line breaks
    'operator-linebreak': 0,
    // enforce padding within blocks
    'padded-blocks': [2, 'never'],
    // require quotes around object literal property names
    // http://eslint.org/docs/rules/quote-props.html
    'quote-props': [2, 'as-needed', { 'keywords': false, 'unnecessary': true, 'numbers': false }],
    // specify whether double or single quotes should be used
    'quotes': [2, 'single', 'avoid-escape'],
    // require identifiers to match the provided regular expression
    'id-match': 0,
    // enforce spacing before and after semicolons
    'semi-spacing': [2, { 'before': false, 'after': true }],
    // require or disallow use of semicolons instead of ASI
    'semi': [2, 'always'],
    // sort variables within the same declaration block
    'sort-vars': 0,
    // require or disallow space before blocks
    'space-before-blocks': 2,
    // require or disallow space before function opening parenthesis
    // https://github.com/eslint/eslint/blob/master/docs/rules/space-before-function-paren.md
    'space-before-function-paren': [2, { 'anonymous': 'always', 'named': 'never' }],
    // require or disallow spaces inside parentheses
    'space-in-parens': [2, 'never'],
    // require spaces around operators
    'space-infix-ops': 2,
    // Require or disallow spaces before/after unary operators
    'space-unary-ops': 0,
    // require or disallow a space immediately following the // or /* in a comment
    'spaced-comment': [2, 'always', {
      'exceptions': ['-', '+'],
      'markers': ['=', '!']           // space here to support sprockets directives
    }],
    // require regex literals to be wrapped in parentheses
    'wrap-regex': 0
  }
};
<commit_msg>[eslint-v2] add one-var-declaration-per-line<commit_after>module.exports = {
  'rules': {
    // enforce spacing inside array brackets
    'array-bracket-spacing': [2, 'never'],
    // enforce one true brace style
    'brace-style': [2, '1tbs', { 'allowSingleLine': true }],
    // require camel case names
    'camelcase': [2, { 'properties': 'never' }],
    // enforce spacing before and after comma
    'comma-spacing': [2, { 'before': false, 'after': true }],
    // enforce one true comma style
    'comma-style': [2, 'last'],
    // disallow padding inside computed properties
    'computed-property-spacing': [2, 'never'],
    // enforces consistent naming when capturing the current execution context
    'consistent-this': 0,
    // enforce newline at the end of file, with no multiple empty lines
    'eol-last': 2,
    // require function expressions to have a name
    'func-names': 1,
    // enforces use of function declarations or expressions
    'func-style': 0,
    // this option enforces minimum and maximum identifier lengths
    // (variable names, property names etc.)
    'id-length': 0,
    // this option sets a specific tab width for your code
    // https://github.com/eslint/eslint/blob/master/docs/rules/indent.md
    'indent': [2, 2, { 'SwitchCase': 1, 'VariableDeclarator': 1 }],
    // specify whether double or single quotes should be used in JSX attributes
    // http://eslint.org/docs/rules/jsx-quotes
    'jsx-quotes': [2, 'prefer-double'],
    // enforces spacing between keys and values in object literal properties
    'key-spacing': [2, { 'beforeColon': false, 'afterColon': true }],
    // require a space before & after certain keywords
    'keyword-spacing': [2, {
      'before': true,
      'after': true,
      'overrides': {
        'return': { 'after': true },
        'throw': { 'after': true },
        'case': { 'after': true }
      }
    }],
    // enforces empty lines around comments
    'lines-around-comment': 0,
    // disallow mixed 'LF' and 'CRLF' as linebreaks
    'linebreak-style': 0,
    // specify the maximum length of a line in your program
    // https://github.com/eslint/eslint/blob/master/docs/rules/max-len.md
    'max-len': [2, 100, 2, {
      'ignoreUrls': true,
      'ignoreComments': false
    }],
    // specify the maximum depth callbacks can be nested
    'max-nested-callbacks': 0,
    // require a capital letter for constructors
    'new-cap': [2, { 'newIsCap': true }],
    // disallow the omission of parentheses when invoking a constructor with no arguments
    'new-parens': 0,
    // allow/disallow an empty newline after var statement
    'newline-after-var': 0,
    // enforces new line after each method call in the chain to make it more readable and easy to maintain
    // http://eslint.org/docs/rules/newline-per-chained-call
    'newline-per-chained-call': [2, { "ignoreChainWithDepth": 3 }],
    // disallow use of the Array constructor
    'no-array-constructor': 0,
    // disallow use of the continue statement
    'no-continue': 0,
    // disallow comments inline after code
    'no-inline-comments': 0,
    // disallow if as the only statement in an else block
    'no-lonely-if': 0,
    // disallow mixed spaces and tabs for indentation
    'no-mixed-spaces-and-tabs': 2,
    // disallow multiple empty lines and only one newline at the end
    'no-multiple-empty-lines': [2, { 'max': 2, 'maxEOF': 1 }],
    // disallow nested ternary expressions
    'no-nested-ternary': 2,
    // disallow use of the Object constructor
    'no-new-object': 2,
    // disallow space between function identifier and application
    'no-spaced-func': 2,
    // disallow the use of ternary operators
    'no-ternary': 0,
    // disallow trailing whitespace at the end of lines
    'no-trailing-spaces': 2,
    // disallow dangling underscores in identifiers
    'no-underscore-dangle': 0,
    // disallow the use of Boolean literals in conditional expressions
    // also, prefer `a || b` over `a ? a : b`
    // http://eslint.org/docs/rules/no-unneeded-ternary
    'no-unneeded-ternary': [2, { 'defaultAssignment': false }],
    // disallow whitespace before properties
    // http://eslint.org/docs/rules/no-whitespace-before-property
    'no-whitespace-before-property': 2,
    // require padding inside curly braces
    'object-curly-spacing': [2, 'always'],
    // allow just one var statement per function
    'one-var': [2, 'never'],
    // require a newline around variable declaration
    // http://eslint.org/docs/rules/one-var-declaration-per-line
    'one-var-declaration-per-line': [2, 'always'],
    // require assignment operator shorthand where possible or prohibit it entirely
    'operator-assignment': 0,
    // enforce operators to be placed before or after line breaks
    'operator-linebreak': 0,
    // enforce padding within blocks
    'padded-blocks': [2, 'never'],
    // require quotes around object literal property names
    // http://eslint.org/docs/rules/quote-props.html
    'quote-props': [2, 'as-needed', { 'keywords': false, 'unnecessary': true, 'numbers': false }],
    // specify whether double or single quotes should be used
    'quotes': [2, 'single', 'avoid-escape'],
    // require identifiers to match the provided regular expression
    'id-match': 0,
    // enforce spacing before and after semicolons
    'semi-spacing': [2, { 'before': false, 'after': true }],
    // require or disallow use of semicolons instead of ASI
    'semi': [2, 'always'],
    // sort variables within the same declaration block
    'sort-vars': 0,
    // require or disallow space before blocks
    'space-before-blocks': 2,
    // require or disallow space before function opening parenthesis
    // https://github.com/eslint/eslint/blob/master/docs/rules/space-before-function-paren.md
    'space-before-function-paren': [2, { 'anonymous': 'always', 'named': 'never' }],
    // require or disallow spaces inside parentheses
    'space-in-parens': [2, 'never'],
    // require spaces around operators
    'space-infix-ops': 2,
    // Require or disallow spaces before/after unary operators
    'space-unary-ops': 0,
    // require or disallow a space immediately following the // or /* in a comment
    'spaced-comment': [2, 'always', {
      'exceptions': ['-', '+'],
      'markers': ['=', '!']           // space here to support sprockets directives
    }],
    // require regex literals to be wrapped in parentheses
    'wrap-regex': 0
  }
};
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////
// Although a lot of the surrounding code may be sound,
// this file is SUPER-PROTOTYPE-Y-ONLY!
///////////////////////////////////////////////////////

dc.ui.Visualizer = dc.View.extend({

  id : 'visualizer',

  callbacks : [
    ['#viz_circle',     'click',    'renderCircular'],
    ['#viz_line',       'click',    'renderLinear']
  ],

  constructor : function(options) {
    _.bindAll('open', 'renderVisualization', 'highlightDatum', 'highlightOff', this);
    this.base(options);
    dc.app.navigation.register('visualize', this.open);
    $(window).resize(function() {
      if (dc.app.navigation.currentTab == 'visualize') this.renderVisualization();
    });
  },

  open : function() {
    this._kindFilter = null;
    this.setMode('linear', 'format');
    this._numMetadata = 10;
    this.gatherMetadata();
    _.defer(this.renderVisualization);
  },

  visualize : function(kind) {
    this._kindFilter = kind;
    this.gatherMetadata();
    this.renderVisualization();
  },

  gatherMetadata : function() {
    this.topDocuments = _(Documents.models()).sortBy(function(doc){ return doc.id; });
    var seenKinds = {};
    var filter = this._kindFilter;
    this.topMetadata = _(Metadata.models()).chain()
      .sortBy(function(meta){ return meta.instanceCount + meta.totalRelevance(); })
      .reverse()
      .select(function(meta){
        var kind = meta.get('kind');
        if (filter) {
          return (kind == filter);
        } else {
          if (_(['country', 'province_or_state', 'category']).include(kind)) return false;
          if (seenKinds[kind]) return false;
          return seenKinds[kind] = true;
        }
      })
      .slice(0, this._numMetadata)
      .sortBy(function(meta){ return meta.get('instances')[0].document_id; })
      .value();
  },

  renderCircular : function() {
    this.setMode('circular', 'format');
    this._numMetadata = 7;
    this.gatherMetadata();
    this.renderVisualization();
  },

  renderLinear : function() {
    this.setMode('linear', 'format');
    this._numMetadata = 10;
    this.gatherMetadata();
    this.renderVisualization();
  },

  highlightDatum : function(e) {
    var ids = e.data.documentIds();
    _.each(this.docViews, function(view) {
      if (_(ids).include(view.model.id)) {
        $(view.el).addClass('bolded');
      } else {
        $(view.el).addClass('muted').animate({opacity : 0.5}, {duration : 'fast', queue : false});
      }
    });
  },

  highlightOff : function() {
    $('.document_tile', this.el).removeClass('muted').removeClass('bolded').animate({opacity : 1}, {duration : 'fast', queue : false});
  },

  renderVisualization : function() {
    if (this.topMetadata.length == 0) return;
    var me = this;
    var el = $(this.el);
    el.html('');
    this.docViews = [];
    var linear = this.modes.format == 'linear';

    var title = (this._kindFilter ? Metadata.KIND_MAP[this._kindFilter] : 'Most Relevant') + ':';
    el.append($.el('div', {id : 'visualization_title'}, title));

    var links = $.el('div', {id : 'viz_types'}, 'linear | circular');
    var links = el.append(links);
    this.setCallbacks();

    el.append($.el('div', {id :'viz_inner_wrapper'}, $.el('div', {id :'viz_inner'})));
    el = $('#viz_inner');
    if (linear) {
      var maxHeight = _.max([this.topDocuments.length * 100, this.topMetadata.length * 75]);
      el.css({height : maxHeight});
    } else {
      el.css({height : $(this.el).height()});
    }

    var canvas = $.el('canvas', {id : 'visualizer_canvas', width : el.width(), height : el.height()});
    el.append(canvas);
    var ctx = canvas.getContext('2d');
    ctx.strokeStyle = "#abafe5";
    ctx.lineCap = "round";

    var scale = 0.92 - (150 / el.width());
    var originX = el.width() / 2, originY = el.height() / 2;
    var width = originX * scale, height = originY * scale;
    var piece = Math.PI * 2 / Documents.size();

    _.each(this.topDocuments, function(doc, i) {
      var tile = new dc.ui.DocumentTile(doc, 'viz').render();
      me.docViews.push(tile);
      el.append(tile.el);
      var position = piece * i;
      $(tile.el).css({
        left: Math.cos(position) * width + originX - 110,
        top: Math.sin(position) * height + originY - 40
      });
    });

    scale = 0.4 - (100 / el.width());
    width = originX * scale; height = originY * scale;
    piece = Math.PI * 2 / this.topMetadata.length;

    _.each(this.topMetadata, function(meta, i) {
      var metaEl = $($.el('div', {'class' : 'datum'}, meta.get('value')));
      el.append(metaEl[0]);
      metaEl.bind('mouseenter', meta, me.highlightDatum);
      metaEl.bind('mouseleave', meta, me.highlightOff);
      var position = piece * i;
      var w2 = metaEl.width() / 2, h2 = metaEl.height() / 2;
      if (linear) {
        metaEl.css({left: 'auto', top: i * 75 + 25, right : 25});
      } else {
        metaEl.css({
          left: Math.cos(position) * width + originX - w2,
          top: Math.sin(position) * height + originY - h2,
          right: 'auto'
        });
      }
      var pos = metaEl.position();

      _.each(meta.get('instances'), function(instance) {
        var del = $('#document_viz_' + instance.document_id);
        var dpos = del.position();
        var docx = dpos.left + del.width() / 4, docy = dpos.top + del.height() / 2;
        ctx.globalAlpha = instance.relevance * 0.9 + 0.1;
        ctx.lineWidth = instance.relevance * 20 + 1;
        ctx.beginPath();
        ctx.moveTo(pos.left + w2, pos.top + h2);
        if (linear) {
          ctx.bezierCurveTo(pos.left + w2 - originX,
                            pos.top + h2,
                            docx + originX, docy,
                            docx, docy);
        } else {
          ctx.bezierCurveTo(Math.cos(position) * width * 2.5 + originX - w2,
                            Math.sin(position) * height * 2.5 + originY - h2,
                            docx, docy,
                            docx, docy);
        }
        ctx.stroke();
      });
    });
  }

});<commit_msg>breaking out the vizualization resizing into its own guarded function<commit_after>////////////////////////////////////////////////////////
// Although a lot of the surrounding code may be sound,
// this file is SUPER-PROTOTYPE-Y-ONLY!
///////////////////////////////////////////////////////

dc.ui.Visualizer = dc.View.extend({

  id : 'visualizer',

  callbacks : [
    ['#viz_circle',     'click',    'renderCircular'],
    ['#viz_line',       'click',    'renderLinear']
  ],

  constructor : function(options) {
    _.bindAll('open', 'renderVisualization', 'highlightDatum', 'highlightOff', 'onResize', this);
    this.base(options);
    this.topDocuments = [];
    this.topMetadata = [];
    dc.app.navigation.register('visualize', this.open);
    $(window).resize(this.onResize);
  },

  open : function() {
    this._kindFilter = null;
    this.setMode('linear', 'format');
    this._numMetadata = 10;
    this.gatherMetadata();
    _.defer(this.renderVisualization);
  },

  visualize : function(kind) {
    this._kindFilter = kind;
    this.gatherMetadata();
    this.renderVisualization();
  },

  gatherMetadata : function() {
    this.topDocuments = _(Documents.models()).sortBy(function(doc){ return doc.id; });
    var seenKinds = {};
    var filter = this._kindFilter;
    this.topMetadata = _(Metadata.models()).chain()
      .sortBy(function(meta){ return meta.instanceCount + meta.totalRelevance(); })
      .reverse()
      .select(function(meta){
        var kind = meta.get('kind');
        if (filter) {
          return (kind == filter);
        } else {
          if (_(['country', 'province_or_state', 'category']).include(kind)) return false;
          if (seenKinds[kind]) return false;
          return seenKinds[kind] = true;
        }
      })
      .slice(0, this._numMetadata)
      .sortBy(function(meta){ return meta.get('instances')[0].document_id; })
      .value();
  },

  renderCircular : function() {
    this.setMode('circular', 'format');
    this._numMetadata = 7;
    this.gatherMetadata();
    this.renderVisualization();
  },

  renderLinear : function() {
    this.setMode('linear', 'format');
    this._numMetadata = 10;
    this.gatherMetadata();
    this.renderVisualization();
  },

  empty : function() {
    return _.empty(this.topMetadata);
  },

  highlightDatum : function(e) {
    var ids = e.data.documentIds();
    _.each(this.docViews, function(view) {
      if (_(ids).include(view.model.id)) {
        $(view.el).addClass('bolded');
      } else {
        $(view.el).addClass('muted').animate({opacity : 0.5}, {duration : 'fast', queue : false});
      }
    });
  },

  highlightOff : function() {
    $('.document_tile', this.el).removeClass('muted').removeClass('bolded').animate({opacity : 1}, {duration : 'fast', queue : false});
  },

  onResize : function() {
    if (dc.app.navigation.currentTab == 'visualize' && !this.empty()) this.renderVisualization();
  },

  renderVisualization : function() {
    if (this.empty()) return;
    var me = this;
    var el = $(this.el);
    el.html('');
    this.docViews = [];
    var linear = this.modes.format == 'linear';

    var title = (this._kindFilter ? Metadata.KIND_MAP[this._kindFilter] : 'Most Relevant') + ':';
    el.append($.el('div', {id : 'visualization_title'}, title));

    var links = $.el('div', {id : 'viz_types'}, 'linear | circular');
    var links = el.append(links);
    this.setCallbacks();

    el.append($.el('div', {id :'viz_inner_wrapper'}, $.el('div', {id :'viz_inner'})));
    el = $('#viz_inner');
    if (linear) {
      var maxHeight = _.max([this.topDocuments.length * 100, this.topMetadata.length * 75]);
      el.css({height : maxHeight});
    } else {
      el.css({height : $(this.el).height()});
    }

    var canvas = $.el('canvas', {id : 'visualizer_canvas', width : el.width(), height : el.height()});
    el.append(canvas);
    var ctx = canvas.getContext('2d');
    ctx.strokeStyle = "#abafe5";
    ctx.lineCap = "round";

    var scale = 0.92 - (150 / el.width());
    var originX = el.width() / 2, originY = el.height() / 2;
    var width = originX * scale, height = originY * scale;
    var piece = Math.PI * 2 / Documents.size();

    _.each(this.topDocuments, function(doc, i) {
      var tile = new dc.ui.DocumentTile(doc, 'viz').render();
      me.docViews.push(tile);
      el.append(tile.el);
      var position = piece * i;
      $(tile.el).css({
        left: Math.cos(position) * width + originX - 110,
        top: Math.sin(position) * height + originY - 40
      });
    });

    scale = 0.4 - (100 / el.width());
    width = originX * scale; height = originY * scale;
    piece = Math.PI * 2 / this.topMetadata.length;

    _.each(this.topMetadata, function(meta, i) {
      var metaEl = $($.el('div', {'class' : 'datum'}, meta.get('value')));
      el.append(metaEl[0]);
      metaEl.bind('mouseenter', meta, me.highlightDatum);
      metaEl.bind('mouseleave', meta, me.highlightOff);
      var position = piece * i;
      var w2 = metaEl.width() / 2, h2 = metaEl.height() / 2;
      if (linear) {
        metaEl.css({left: 'auto', top: i * 75 + 25, right : 25});
      } else {
        metaEl.css({
          left: Math.cos(position) * width + originX - w2,
          top: Math.sin(position) * height + originY - h2,
          right: 'auto'
        });
      }
      var pos = metaEl.position();

      _.each(meta.get('instances'), function(instance) {
        var del = $('#document_viz_' + instance.document_id);
        var dpos = del.position();
        var docx = dpos.left + del.width() / 4, docy = dpos.top + del.height() / 2;
        ctx.globalAlpha = instance.relevance * 0.9 + 0.1;
        ctx.lineWidth = instance.relevance * 20 + 1;
        ctx.beginPath();
        ctx.moveTo(pos.left + w2, pos.top + h2);
        if (linear) {
          ctx.bezierCurveTo(pos.left + w2 - originX,
                            pos.top + h2,
                            docx + originX, docy,
                            docx, docy);
        } else {
          ctx.bezierCurveTo(Math.cos(position) * width * 2.5 + originX - w2,
                            Math.sin(position) * height * 2.5 + originY - h2,
                            docx, docy,
                            docx, docy);
        }
        ctx.stroke();
      });
    });
  }

});<|endoftext|>


<commit_before>// http://pinout.xyz/pinout/wiringpi_gpio_pinout

var wpi = require('wiring-pi');
wpi.setup('wpi');

var started = false;
var clock = null;

var teamAplus = 15;
var teamAminus = 6;

var teamBplus = 25;
var teamBminus = 14;

wpi.pinMode(teamAplus, wpi.INPUT);
wpi.pullUpDnControl(teamAplus, wpi.PUD_UP);
wpi.wiringPiISR(teamAplus, wpi.INT_EDGE_FALLING, function() {
	setTimeout(score(pin), 250);
});
wpi.pinMode(teamAminus, wpi.INPUT);
wpi.pullUpDnControl(teamAminus, wpi.PUD_UP);
wpi.wiringPiISR(teamAminus, wpi.INT_EDGE_FALLING, function() {
	setTimeout(score(pin), 250);
});

wpi.pinMode(teamBplus, wpi.INPUT);
wpi.pullUpDnControl(teamBplus, wpi.PUD_UP);
wpi.wiringPiISR(teamBplus, wpi.INT_EDGE_FALLING, function() {
	setTimeout(score(pin), 250);
});
wpi.pinMode(teamBminus, wpi.INPUT);
wpi.pullUpDnControl(teamBminus, wpi.PUD_UP);
wpi.wiringPiISR(teamBminus, wpi.INT_EDGE_FALLING, function() {
	setTimeout(score(pin), 250);
});

function score(pin) {
	if (pin === teamAplus) {
		console.log('team A ++' + pin)
	} else if (pin === teamAminus) {
		console.log('team A -- ' + pin)
	} else if (pin === teamBplus) {
		console.log('team B ++ ' + pin)
	} else if (pin === teamBminus) {
		console.log('team B -- ' + pin)
	}
}<commit_msg>all four buttons<commit_after>// http://pinout.xyz/pinout/wiringpi_gpio_pinout

var wpi = require('wiring-pi');
wpi.setup('wpi');

var started = false;
var clock = null;

var teamAplus = 15;
var teamAminus = 6;

var teamBplus = 25;
var teamBminus = 14;

wpi.pinMode(teamAplus, wpi.INPUT);
wpi.pullUpDnControl(teamAplus, wpi.PUD_UP);
wpi.wiringPiISR(teamAplus, wpi.INT_EDGE_FALLING, function() {
	setTimeout(score(teamAplus), 250);
});
wpi.pinMode(teamAminus, wpi.INPUT);
wpi.pullUpDnControl(teamAminus, wpi.PUD_UP);
wpi.wiringPiISR(teamAminus, wpi.INT_EDGE_FALLING, function() {
	setTimeout(score(teamAminus), 250);
});

wpi.pinMode(teamBplus, wpi.INPUT);
wpi.pullUpDnControl(teamBplus, wpi.PUD_UP);
wpi.wiringPiISR(teamBplus, wpi.INT_EDGE_FALLING, function() {
	setTimeout(score(teamBplus), 250);
});
wpi.pinMode(teamBminus, wpi.INPUT);
wpi.pullUpDnControl(teamBminus, wpi.PUD_UP);
wpi.wiringPiISR(teamBminus, wpi.INT_EDGE_FALLING, function() {
	setTimeout(score(teamBminus), 250);
});

function score(pin) {
	if (pin === teamAplus) {
		console.log('team A ++' + pin)
	} else if (pin === teamAminus) {
		console.log('team A -- ' + pin)
	} else if (pin === teamBplus) {
		console.log('team B ++ ' + pin)
	} else if (pin === teamBminus) {
		console.log('team B -- ' + pin)
	}
}<|endoftext|>


<commit_before>/**
 * Populate DB with sample data on server start
 * to disable, edit config/environment/index.js, and set `seedDB: false`
 */

'use strict';

// Set default node environment to development
process.env.NODE_ENV = process.env.NODE_ENV || 'development';

var config = require('./environment');
var models = require('../models');

models.sequelize.sync().then(function () {
    console.log('running seedsql.js ...')

    // remove user 'test' and the associated queries/notifications
    models.User.destroy({
    	where:{username: 'test'}
    })
    // create user test
    .then(function () {
    	models.User.create({username: 'test'})
        // create each query
    	.then(function(user) {
            console.log('adding queries to user test');
            queries.forEach(function(query) {
                models.Query.create(serialize(query))
                // update foreign key UserUserName for this query to 'test'
                .then(function(queryInstance) {
                    queryInstance.setUser(user);
                });
            });
    	});
    }).catch(function(error) {
        console.log(error);
    });
});

var queries =
[
	{
		name: 'Query #1',
		digState: {
			searchTerms: 'bob smith',
			filters: {"aggFilters":{"city_agg":{"LittleRock":true,"FortSmith":true}},"textFilters":{"phonenumber":{"live":"","submitted":""}},"dateFilters":{"dateCreated":{"beginDate":null,"endDate":null}}},
			selectedSort: {"title":"Best Match","order":"rank"},
			includeMissing: {'aggregations': {}, 'allIncludeMissing': false}
		},
		elasticUIState: {
			queryState:{"query_string":{"fields":["_all"],"query":"bob smith"}}},
			filterState:{"bool":{"should":[{"terms":{"hasFeatureCollection\\uff0eplace_postalAddress_feature\\uff0efeatureObject\\uff0eaddressLocality":["LittleRock"]}},{"terms":{"hasFeatureCollection\\uff0eplace_postalAddress_feature\\uff0efeatureObject\\uff0eaddressLocality":["FortSmith"]}}]}
		},
		frequency: 'never',
		lastRunDate: new Date()
	},
	{
		name: 'Query #2',
		digState: {
			searchTerms: 'jane doe',
			filters: {"textFilters":{"phonenumber":{"live":"","submitted":""}},"dateFilters":{"dateCreated":{"beginDate":"2013-02-02T05:00:00.000Z","endDate":"2015-02-03T05:00:00.000Z"}}},
			selectedSort: {"title":"Best Match","order":"rank"},
			includeMissing: {'aggregations': {}, 'allIncludeMissing': false}
		},
		elasticUIState: {
			queryState: {"query_string":{"query":"jane doe","fields":["_all"]}},
			filterState:{"bool":{"must":[{"range":{"dateCreated":{"from":"2013-02-02"}}},{"range":{"dateCreated":{"to":"2015-02-03"}}}]}}
		},
		frequency: 'hourly',
		lastRunDate: new Date()
	},
	{
		name: 'Query #3',
		digState: {
			searchTerms: 'another users query',
			filters: {"textFilters":{"phonenumber":{"live":"","submitted":""}},"dateFilters":{"dateCreated":{"beginDate":null,"endDate":null}}},
			selectedSort: {"title":"Best Match","order":"rank"},
			includeMissing: {'aggregations': {}, 'allIncludeMissing': false}
		},
		elasticUIState: {
			queryState: {"query_string":{"fields":["_all"],"query":"another users query"}}
		},
		frequency: 'daily',
		lastRunDate: new Date(),
        notificationHasRun: false
	}
];

var serialize = function (query) {
    query.digState = JSON.stringify(query.digState);
    query.elasticUIState = JSON.stringify(query.elasticUIState);
    return query;
}
<commit_msg>refactor seedsql. remove some indentation<commit_after>/**
 * Populate DB with sample data on server start
 * to disable, edit config/environment/index.js, and set `seedDB: false`
 */

'use strict';

// Set default node environment to development
process.env.NODE_ENV = process.env.NODE_ENV || 'development';

var config = require('./environment');
var models = require('../models');

console.log('running seedsql.js ...')
models.sequelize.sync()
// remove user 'test' and the associated queries/notifications
.then(function () {

    return models.User.destroy({ where:{username: 'test'}})
})
// create user test
.then(function () {
    return models.User.create({username: 'test'})
})
// create each query
.then(function(user) {
    console.log('adding queries to user test');
    queries.forEach(function(query) {
        models.Query.create(serialize(query))
        // update foreign key UserUserName for this query to 'test'
        .then(function(queryInstance) {
            queryInstance.setUser(user);
        });
    });
})
.catch(function(error) {
    console.log(error);
});

var queries =
[
	{
		name: 'Query #1',
		digState: {
			searchTerms: 'bob smith',
			filters: {"aggFilters":{"city_agg":{"LittleRock":true,"FortSmith":true}},"textFilters":{"phonenumber":{"live":"","submitted":""}},"dateFilters":{"dateCreated":{"beginDate":null,"endDate":null}}},
			selectedSort: {"title":"Best Match","order":"rank"},
			includeMissing: {'aggregations': {}, 'allIncludeMissing': false}
		},
		elasticUIState: {
			queryState:{"query_string":{"fields":["_all"],"query":"bob smith"}}},
			filterState:{"bool":{"should":[{"terms":{"hasFeatureCollection\\uff0eplace_postalAddress_feature\\uff0efeatureObject\\uff0eaddressLocality":["LittleRock"]}},{"terms":{"hasFeatureCollection\\uff0eplace_postalAddress_feature\\uff0efeatureObject\\uff0eaddressLocality":["FortSmith"]}}]}
		},
		frequency: 'never',
		lastRunDate: new Date()
	},
	{
		name: 'Query #2',
		digState: {
			searchTerms: 'jane doe',
			filters: {"textFilters":{"phonenumber":{"live":"","submitted":""}},"dateFilters":{"dateCreated":{"beginDate":"2013-02-02T05:00:00.000Z","endDate":"2015-02-03T05:00:00.000Z"}}},
			selectedSort: {"title":"Best Match","order":"rank"},
			includeMissing: {'aggregations': {}, 'allIncludeMissing': false}
		},
		elasticUIState: {
			queryState: {"query_string":{"query":"jane doe","fields":["_all"]}},
			filterState:{"bool":{"must":[{"range":{"dateCreated":{"from":"2013-02-02"}}},{"range":{"dateCreated":{"to":"2015-02-03"}}}]}}
		},
		frequency: 'hourly',
		lastRunDate: new Date()
	},
	{
		name: 'Query #3',
		digState: {
			searchTerms: 'another users query',
			filters: {"textFilters":{"phonenumber":{"live":"","submitted":""}},"dateFilters":{"dateCreated":{"beginDate":null,"endDate":null}}},
			selectedSort: {"title":"Best Match","order":"rank"},
			includeMissing: {'aggregations': {}, 'allIncludeMissing': false}
		},
		elasticUIState: {
			queryState: {"query_string":{"fields":["_all"],"query":"another users query"}}
		},
		frequency: 'daily',
		lastRunDate: new Date(),
        notificationHasRun: false
	}
];

var serialize = function (query) {
    query.digState = JSON.stringify(query.digState);
    query.elasticUIState = JSON.stringify(query.elasticUIState);
    return query;
}
<|endoftext|>


<commit_before>/**
 * ActivationBanner component.
 *
 * Site Kit by Google, Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * WordPress dependencies
 */
import { useState } from '@wordpress/element';

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import ReminderBanner from './ReminderBanner';
import SetupBanner from './SetupBanner';
import SuccessBanner from './SuccessBanner';
import {
	ACTIVATION_STEP_REMINDER,
	ACTIVATION_STEP_SETUP,
	ACTIVATION_STEP_SUCCESS,
} from '../../../constants';
import { CORE_MODULES } from '../../../../../googlesitekit/modules/datastore/constants';
const { useSelect } = Data;

export default function ActivationBanner() {
	const [ step, setStep ] = useState( ACTIVATION_STEP_REMINDER );

	const uaConnected = useSelect( ( select ) =>
		select( CORE_MODULES ).isModuleConnected( 'analytics' )
	);

	const ga4Connected = useSelect( ( select ) =>
		select( CORE_MODULES ).isModuleConnected( 'analytics-4' )
	);

	const handleSubmit = () => {
		if ( step === ACTIVATION_STEP_REMINDER ) {
			setStep( ACTIVATION_STEP_SETUP );
		}

		if ( step === ACTIVATION_STEP_SETUP ) {
			setStep( ACTIVATION_STEP_SUCCESS );
		}

		return { dismissOnCTAClick: false };
	};

	if ( ! uaConnected || ga4Connected ) {
		return null;
	}

	switch ( step ) {
		case ACTIVATION_STEP_REMINDER:
			return <ReminderBanner onSubmitSuccess={ handleSubmit } />;
		case ACTIVATION_STEP_SETUP:
			return <SetupBanner onSubmitSuccess={ handleSubmit } />;
		case ACTIVATION_STEP_SUCCESS:
			return <SuccessBanner />;
		default:
			return null;
	}
}
<commit_msg>Return the user to the same step after oauth flow.<commit_after>/**
 * ActivationBanner component.
 *
 * Site Kit by Google, Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * WordPress dependencies
 */
import { useState, useCallback, useEffect } from '@wordpress/element';

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import ReminderBanner from './ReminderBanner';
import SetupBanner from './SetupBanner';
import SuccessBanner from './SuccessBanner';
import {
	ACTIVATION_STEP_REMINDER,
	ACTIVATION_STEP_SETUP,
	ACTIVATION_STEP_SUCCESS,
	GA4_ACTIVATION_BANNER_STATE,
} from '../../../constants';
import { CORE_MODULES } from '../../../../../googlesitekit/modules/datastore/constants';
import { CORE_USER } from '../../../../../googlesitekit/datastore/user/constants';
import { EDIT_SCOPE } from '../../../../analytics/datastore/constants';
import { CORE_FORMS } from '../../../../../googlesitekit/datastore/forms/constants';
const { useSelect, useDispatch, useRegistry } = Data;

export default function ActivationBanner() {
	const [ step, setStep ] = useState( ACTIVATION_STEP_REMINDER );

	const registry = useRegistry();

	const uaConnected = useSelect( ( select ) =>
		select( CORE_MODULES ).isModuleConnected( 'analytics' )
	);
	const ga4Connected = useSelect( ( select ) =>
		select( CORE_MODULES ).isModuleConnected( 'analytics-4' )
	);
	const hasEditScope = useSelect( ( select ) =>
		select( CORE_USER ).hasScope( EDIT_SCOPE )
	);
	const returnToSetupStep = useSelect( ( select ) =>
		select( CORE_FORMS ).getValue(
			GA4_ACTIVATION_BANNER_STATE,
			'returnToSetupStep'
		)
	);

	const { setValues } = useDispatch( CORE_FORMS );

	useEffect( () => {
		if ( hasEditScope && returnToSetupStep ) {
			setStep( ACTIVATION_STEP_SETUP );
			setValues( GA4_ACTIVATION_BANNER_STATE, {
				returnToSetupStep: false,
			} );
		}
	}, [ hasEditScope, registry, returnToSetupStep, setValues ] );

	const handleSubmit = useCallback( () => {
		if ( step === ACTIVATION_STEP_REMINDER ) {
			setStep( ACTIVATION_STEP_SETUP );
		}

		if ( ! returnToSetupStep && step === ACTIVATION_STEP_SETUP ) {
			setStep( ACTIVATION_STEP_SUCCESS );
		}

		return { dismissOnCTAClick: false };
	}, [ returnToSetupStep, step ] );

	if ( ! uaConnected || ga4Connected ) {
		return null;
	}

	switch ( step ) {
		case ACTIVATION_STEP_REMINDER:
			return <ReminderBanner onSubmitSuccess={ handleSubmit } />;
		case ACTIVATION_STEP_SETUP:
			return <SetupBanner onSubmitSuccess={ handleSubmit } />;
		case ACTIVATION_STEP_SUCCESS:
			return <SuccessBanner />;
		default:
			return null;
	}
}
<|endoftext|>