<commit_before>'use strict';
(function (ns, _) {
  var filterLabel = Handlebars.compile('{{#if label}}{{label}}{{else}}{{value}}{{/if}}');

  /**
   * @class
   */
  ns.SmartTable = ns.BaseList.extend({
    $context: null,
    $ranger: null,
    autoFetch: true,
    events: {
      'click .archive-button': 'archiveButton_clickHandler',
      'click .delete-button': 'deleteButton_clickHandler',
      'click .refresh-button': 'refreshButton_clickHandler',
      'click .edit': 'edit_clickHandler',
      'click tbody .filter': 'tbodyFilter_clickHandler',
      'click thead .filter': 'theadFilter_clickHandler',
      'click .order': 'order_clickHandler',
      'change select.edit': 'select_changeHandler',
      'change .stars input': 'star_changeHandler',
      'change .status-button': 'statusButton_changeHandler'
    },
    initialize: function (options) {
      var data = this.$el.data()
        , autoFetch = 'autoFetch' in data ? data.autoFetch : this.autoFetch
        , typeahead = 'typeahead' in data ? data.typeahead : true;
      ns.BaseList.prototype.initialize.call(this, _.extend(options, {
        autoFetch: false,
        container: 'tbody',
        reset: true
      }));

      // 通过页面中介来实现翻页等功能
      this.model = this.model && this.model instanceof tp.model.TableMemento ? this.model : new tp.model.TableMemento(this.params, {tableId: this.el.id});
      this.model.on('change', this.model_changeHandler, this);
      this.model.on('invalid', this.model_invalidHandler, this);
      if (options.tags) {
        this.model.tags = options.tags.split(',');
      }
      if (this.model.has('start')) {
        if (this.collection.model && !_.isString(this.collection.model)) {
          _.extend(this.collection.model.prototype.defaults, this.model.pick('start', 'end'));
        }
      }
      this.renderHeader();

      // 启用搜索
      if ('search' in options) {
        this.search = new ns.table.Search({
          el: options.search,
          model: this.model,
          collection: this.collection
        });
      }

      // 翻页
      if ('pagesize' in options && options.pagesize > 0) {
        this.pagination = new ns.table.Pager(_.extend({}, options, {
          el: 'pagination' in options ? options.pagination : '.pager',
          model: this.model,
          collection: this.collection
        }));
      }

      // 调整每页数量
      if ('pagesizeController' in options) {
        this.pagesizeController = $(options.pagesizeController);
        this.pagesizeController.val(this.collection.pagesize);
        this.pagesizeController.on('change', _.bind(this.pagesize_changeHandler, this));
      }

      // 起止日期
      if ('ranger' in options) {
        if (!this.model.has('start')) {
          this.model.set(_.pick(options, 'start', 'end'), {silent: true});
        }
        if ('dateFormat' in options) {
          this.model.set('dateFormat', options.dateFormat, {silent: true});
        }
        this.$ranger.use(this.model);
      }

      // 删选器
      if ('filter' in options) {
        this.filter = new ns.table.Filter({
          el: options.filter,
          model: this.model,
          collection: this.collection
        });
      }

      // 导出按钮
      if ('exportButton' in options) {
        this.exportButton = new tp.component.ExportButton({
          model: this.model,
          el: options.exportButton
        });
      }

      // 桌面默认都固定表头
      if (document.body.clientWidth >= 768 && this.$el.closest('modal').length === 0 && typeahead) {
        this.header = new ns.table.FixedHeader({
          target: this
        });
      }

      if (autoFetch) {
        this.refresh(options);
      }
      this.options = options;
    },
    remove: function () {
      if (this.pagination) {
        this.pagination.remove();
      }
      if (this.pagesizeController) {
        this.pagesizeController.off('change');
      }
      if (this.ranger) {
        this.ranger.remove();
      }
      if (this.filter) {
        this.filter.remove();
      }
      if (this.header) {
        this.header.remove();
      }
      if (this.exportButton) {
        this.exportButton.remove();
      }
      this.model.off(null, null, this);
      this.collection.off(null, null, this);
      tp.model.ListCollection.destroyInstance(this.$el.data('collection-id'));
      ns.BaseList.prototype.remove.call(this);
    },
    render: function () {
      ns.BaseList.prototype.render.call(this);
      this.$context.trigger('table-rendered', this);
      this.trigger('table-rendered', this);
      // 排序
      if ('order' in this.model.changed || 'seq' in  this.model.changed) {
        var container = this.container;
        this.collection.each(function (model) {
          container.append(container.find('#' + model.id));
        });
      }
    },
    refresh: function (options) {
      options = options || {};
      options.data = _.extend(this.model.toJSON(), options.data);
      this.collection.fetch(options);
    },
    renderHeader: function () {
      // 排序
      var order = this.model.get('order')
        , seq = this.model.get('seq')
        , status = this.model.getTags()
        , labels = _.chain(status)
          .omit(function (value, key) {
            return key.match(/_label$/);
          })
          .map(function (value, key) {
            var attr = {key: key, value: value};
            if (status[key + '_label']) {
              attr['label'] = status[key + '_label'];
            }
            return filterLabel(attr);
          })
          .value();
      if (order) {
        this.$('.order').removeClass('active inverse');
        this.$('.order[href="#' + order + '"]').addClass('active').toggleClass('inverse', seq == 'desc');
      }
      this.$('.filters').append(labels.join(''));
    },
    saveModel: function (button, id, prop, value, options) {
      button.spinner();
      this.collection.get(id).save(prop, value, {
        patch: true,
        wait: true,
        context: this,
        success: function () {
          button.spinner(false);
          if (options && options.remove) {
            this.collection.remove(id, {fadeOut: true});
          }
        }
      });
    },
    archiveButton_clickHandler: function (event) {
      var button = $(event.currentTarget)
        , msg = button.data('msg') || '确定归档么？';
      if (!confirm(msg)) {
        return;
      }
      var id = button.closest('tr').attr('id');
      this.saveModel(button, id, button.attr('name'), button.val(), {remove: true});
    },
    collection_errorHandler: function (collection, response) {
      this.$('.waiting td').html(ns.Manager.createErrorMsg(response));
    },
    collection_syncHandler: function () {
      ns.BaseList.prototype.collection_syncHandler.call(this);
      this.model.waiting = false;
      if (this.options.amount) {
        var data = this.collection.getAmount(this.options.omits);
        this.$('.amount').remove();
        this.collection_addHandler(data, null, {immediately: true});
      }
    },
    deleteButton_clickHandler: function (event) {
      var button = $(event.currentTarget)
        , id = button.closest('tr').attr('id')
        , data = button.data()
        , msg = data.msg || '确定删除么？'
        , hasPopup = data.hasPopup
        , destroy = _.bind(function (popup) {
          var param = {};
          if (popup) {
            _.each(popup.$el.find('form').serializeArray(), function(element) {
              param[element.name] = element.value
            });
          }
          button.spinner();
          this.collection.get(id).destroy({
            fadeOut: true,
            data: JSON.stringify(param),
            contentType: 'application/json',
            wait: true,
            error: function (model, xhr) {
              var response = 'responseJSON' in xhr ? xhr.responseJSON : xhr;
              button.spinner(false);
              alert(response.msg || '删除失败');
            }
          });
        }, this);
      if (hasPopup) {
        var popup = tp.popup.Manager.popup(_.defaults({
          isRemote: true,
          content: button.attr('href'),
          model: this.collection.get(id)
        }, data));
        popup.on('confirm', destroy, this);
      } else if (confirm(msg)) {
        destroy();
      }
      event.preventDefault();
    },
    edit_clickHandler: function (event) {
      if (event.currentTarget.tagName.toLowerCase() === 'select') {
        return;
      }
      var target = $(event.currentTarget)
        , data = target.data()
        , index = target.closest('td').index()
        , prop = event.currentTarget.hash.substr(1)
        , tr = target.closest('tr')
        , id = tr.attr('id')
        , options = _.extend({
          label: this.$('thead th').eq(index).text()
        }, data);
      if (!id) {
        var relate = tr.attr('class').match(/\brelate-to-(\w+)\b/);
        id = relate ? relate[1] : false;
      }
      if (!id) {
        alert('未查询到对象id，无法启动编辑。');
        return;
      }
      var model = this.collection.get(id);
      options.type = data.type || 'short-text';
      this.$context.trigger('edit-model', model, prop, options);
      event.stopPropagation();
      event.preventDefault();
    },
    model_changeHandler: function (model, options) {
      options = _.omit(options, 'unset') || {};
      this.refresh(options);

      if (this.collection.model && ('start' in model.changed || 'end' in model.changed)) {
        _.extend(this.collection.model.prototype.defaults, _.pick(model.changed, 'start', 'end'));
      }
      this.$el.addClass('loading');
      model.warting = true;
    },
    model_invalidHandler: function (model, error) {
      alert(error);
    },
    order_clickHandler: function (event) {
      var target = $(event.currentTarget)
        , order = target.attr('href').substr(1);
      this.$('.order.active').not(target).removeClass('active inverse');
      target.toggleClass('inverse', target.hasClass('active') && !target.hasClass('inverse')).addClass('active');
      this.model.set({
        order: order,
        seq: target.hasClass('inverse') ? 'desc' : 'asc'
      }, {reset: true});
      event.preventDefault();
    },
    pagesize_changeHandler: function (event) {
      this.collection.setPagesize(event.target.value);
      if (this.model.get('page') === 0) {
        this.model.trigger('change', this.model);
      } else {
       this.model.set('page', 0);
      }
    },
    refreshButton_clickHandler: function (event) {
      this.refresh();
      $(event.currentTarget).spinner();
    },
    select_changeHandler: function (event) {
      var target = $(event.currentTarget)
        , id = target.closest('tr').attr('id');
      this.saveModel(target, id, target.attr('name'), target.val());
    },
    star_changeHandler: function (event) {
      var target = $(event.currentTarget)
        , id = target.closest('tr').attr('id');
      this.saveModel(target.add(target.siblings('.star')), id, target.attr('name'), target.val());
    },
    statusButton_changeHandler: function (event) {
      var target = $(event.currentTarget)
        , data = _.extend({active: 1, deactive: 0}, target.data())
        , value = target.prop('checked') ? data.active : data.deactive
        , id = target.closest('tr').attr('id')
        , button = $(target[0].labels).filter('.btn');
      this.saveModel(button, id, target.attr('name'), value);
    },
    tbodyFilter_clickHandler: function (event) {
      var target = $(event.currentTarget)
        , label = target.text()
        , path = target.attr('href').split('/').slice(-2)
        , hasFilter = this.model.has(path[0])
        , attr = { page: 0 }; // 要自动切回第一页
      attr[path[0]] = path[1];
      if (path[0] != label) {
        attr[path[0] + '_label'] = label;
      }
      this.model.set(attr, {reset: true});
      if (hasFilter) {
        this.$('.filters').find('[href="#/' + path[0] + '"]').replaceWith(target.clone());
      } else {
        this.$('.filters').append(target.clone());
      }
      event.preventDefault();
    },
    theadFilter_clickHandler: function (event) {
      var target = $(event.currentTarget)
        , path = target.attr('href').split('/').slice(-2);
      this.model.set('page', 0, {silent: true}) // 自动切回第一页
        .unset(path[0], {reset: true});
      target.remove();
      event.preventDefault();
    }
  });
}(Nervenet.createNameSpace('tp.component'), _));<commit_msg>  修改defaluts方法参数顺序<commit_after>'use strict';
(function (ns, _) {
  var filterLabel = Handlebars.compile('{{#if label}}{{label}}{{else}}{{value}}{{/if}}');

  /**
   * @class
   */
  ns.SmartTable = ns.BaseList.extend({
    $context: null,
    $ranger: null,
    autoFetch: true,
    events: {
      'click .archive-button': 'archiveButton_clickHandler',
      'click .delete-button': 'deleteButton_clickHandler',
      'click .refresh-button': 'refreshButton_clickHandler',
      'click .edit': 'edit_clickHandler',
      'click tbody .filter': 'tbodyFilter_clickHandler',
      'click thead .filter': 'theadFilter_clickHandler',
      'click .order': 'order_clickHandler',
      'change select.edit': 'select_changeHandler',
      'change .stars input': 'star_changeHandler',
      'change .status-button': 'statusButton_changeHandler'
    },
    initialize: function (options) {
      var data = this.$el.data()
        , autoFetch = 'autoFetch' in data ? data.autoFetch : this.autoFetch
        , typeahead = 'typeahead' in data ? data.typeahead : true;
      ns.BaseList.prototype.initialize.call(this, _.extend(options, {
        autoFetch: false,
        container: 'tbody',
        reset: true
      }));

      // 通过页面中介来实现翻页等功能
      this.model = this.model && this.model instanceof tp.model.TableMemento ? this.model : new tp.model.TableMemento(this.params, {tableId: this.el.id});
      this.model.on('change', this.model_changeHandler, this);
      this.model.on('invalid', this.model_invalidHandler, this);
      if (options.tags) {
        this.model.tags = options.tags.split(',');
      }
      if (this.model.has('start')) {
        if (this.collection.model && !_.isString(this.collection.model)) {
          _.extend(this.collection.model.prototype.defaults, this.model.pick('start', 'end'));
        }
      }
      this.renderHeader();

      // 启用搜索
      if ('search' in options) {
        this.search = new ns.table.Search({
          el: options.search,
          model: this.model,
          collection: this.collection
        });
      }

      // 翻页
      if ('pagesize' in options && options.pagesize > 0) {
        this.pagination = new ns.table.Pager(_.extend({}, options, {
          el: 'pagination' in options ? options.pagination : '.pager',
          model: this.model,
          collection: this.collection
        }));
      }

      // 调整每页数量
      if ('pagesizeController' in options) {
        this.pagesizeController = $(options.pagesizeController);
        this.pagesizeController.val(this.collection.pagesize);
        this.pagesizeController.on('change', _.bind(this.pagesize_changeHandler, this));
      }

      // 起止日期
      if ('ranger' in options) {
        if (!this.model.has('start')) {
          this.model.set(_.pick(options, 'start', 'end'), {silent: true});
        }
        if ('dateFormat' in options) {
          this.model.set('dateFormat', options.dateFormat, {silent: true});
        }
        this.$ranger.use(this.model);
      }

      // 删选器
      if ('filter' in options) {
        this.filter = new ns.table.Filter({
          el: options.filter,
          model: this.model,
          collection: this.collection
        });
      }

      // 导出按钮
      if ('exportButton' in options) {
        this.exportButton = new tp.component.ExportButton({
          model: this.model,
          el: options.exportButton
        });
      }

      // 桌面默认都固定表头
      if (document.body.clientWidth >= 768 && this.$el.closest('modal').length === 0 && typeahead) {
        this.header = new ns.table.FixedHeader({
          target: this
        });
      }

      if (autoFetch) {
        this.refresh(options);
      }
      this.options = options;
    },
    remove: function () {
      if (this.pagination) {
        this.pagination.remove();
      }
      if (this.pagesizeController) {
        this.pagesizeController.off('change');
      }
      if (this.ranger) {
        this.ranger.remove();
      }
      if (this.filter) {
        this.filter.remove();
      }
      if (this.header) {
        this.header.remove();
      }
      if (this.exportButton) {
        this.exportButton.remove();
      }
      this.model.off(null, null, this);
      this.collection.off(null, null, this);
      tp.model.ListCollection.destroyInstance(this.$el.data('collection-id'));
      ns.BaseList.prototype.remove.call(this);
    },
    render: function () {
      ns.BaseList.prototype.render.call(this);
      this.$context.trigger('table-rendered', this);
      this.trigger('table-rendered', this);
      // 排序
      if ('order' in this.model.changed || 'seq' in  this.model.changed) {
        var container = this.container;
        this.collection.each(function (model) {
          container.append(container.find('#' + model.id));
        });
      }
    },
    refresh: function (options) {
      options = options || {};
      options.data = _.extend(this.model.toJSON(), options.data);
      this.collection.fetch(options);
    },
    renderHeader: function () {
      // 排序
      var order = this.model.get('order')
        , seq = this.model.get('seq')
        , status = this.model.getTags()
        , labels = _.chain(status)
          .omit(function (value, key) {
            return key.match(/_label$/);
          })
          .map(function (value, key) {
            var attr = {key: key, value: value};
            if (status[key + '_label']) {
              attr['label'] = status[key + '_label'];
            }
            return filterLabel(attr);
          })
          .value();
      if (order) {
        this.$('.order').removeClass('active inverse');
        this.$('.order[href="#' + order + '"]').addClass('active').toggleClass('inverse', seq == 'desc');
      }
      this.$('.filters').append(labels.join(''));
    },
    saveModel: function (button, id, prop, value, options) {
      button.spinner();
      this.collection.get(id).save(prop, value, {
        patch: true,
        wait: true,
        context: this,
        success: function () {
          button.spinner(false);
          if (options && options.remove) {
            this.collection.remove(id, {fadeOut: true});
          }
        }
      });
    },
    archiveButton_clickHandler: function (event) {
      var button = $(event.currentTarget)
        , msg = button.data('msg') || '确定归档么？';
      if (!confirm(msg)) {
        return;
      }
      var id = button.closest('tr').attr('id');
      this.saveModel(button, id, button.attr('name'), button.val(), {remove: true});
    },
    collection_errorHandler: function (collection, response) {
      this.$('.waiting td').html(ns.Manager.createErrorMsg(response));
    },
    collection_syncHandler: function () {
      ns.BaseList.prototype.collection_syncHandler.call(this);
      this.model.waiting = false;
      if (this.options.amount) {
        var data = this.collection.getAmount(this.options.omits);
        this.$('.amount').remove();
        this.collection_addHandler(data, null, {immediately: true});
      }
    },
    deleteButton_clickHandler: function (event) {
      var button = $(event.currentTarget)
        , id = button.closest('tr').attr('id')
        , data = button.data()
        , msg = data.msg || '确定删除么？'
        , hasPopup = data.hasPopup
        , destroy = _.bind(function (popup) {
          var param = {};
          if (popup) {
            _.each(popup.$el.find('form').serializeArray(), function(element) {
              param[element.name] = element.value
            });
          }
          button.spinner();
          this.collection.get(id).destroy({
            fadeOut: true,
            data: JSON.stringify(param),
            contentType: 'application/json',
            wait: true,
            error: function (model, xhr) {
              var response = 'responseJSON' in xhr ? xhr.responseJSON : xhr;
              button.spinner(false);
              alert(response.msg || '删除失败');
            }
          });
        }, this);
      if (hasPopup) {
        var popup = tp.popup.Manager.popup(_.defaults(data, {
          isRemote: true,
          content: button.attr('href'),
          model: this.collection.get(id)
        }));
        popup.on('confirm', destroy, this);
      } else if (confirm(msg)) {
        destroy();
      }
      event.preventDefault();
    },
    edit_clickHandler: function (event) {
      if (event.currentTarget.tagName.toLowerCase() === 'select') {
        return;
      }
      var target = $(event.currentTarget)
        , data = target.data()
        , index = target.closest('td').index()
        , prop = event.currentTarget.hash.substr(1)
        , tr = target.closest('tr')
        , id = tr.attr('id')
        , options = _.extend({
          label: this.$('thead th').eq(index).text()
        }, data);
      if (!id) {
        var relate = tr.attr('class').match(/\brelate-to-(\w+)\b/);
        id = relate ? relate[1] : false;
      }
      if (!id) {
        alert('未查询到对象id，无法启动编辑。');
        return;
      }
      var model = this.collection.get(id);
      options.type = data.type || 'short-text';
      this.$context.trigger('edit-model', model, prop, options);
      event.stopPropagation();
      event.preventDefault();
    },
    model_changeHandler: function (model, options) {
      options = _.omit(options, 'unset') || {};
      this.refresh(options);

      if (this.collection.model && ('start' in model.changed || 'end' in model.changed)) {
        _.extend(this.collection.model.prototype.defaults, _.pick(model.changed, 'start', 'end'));
      }
      this.$el.addClass('loading');
      model.warting = true;
    },
    model_invalidHandler: function (model, error) {
      alert(error);
    },
    order_clickHandler: function (event) {
      var target = $(event.currentTarget)
        , order = target.attr('href').substr(1);
      this.$('.order.active').not(target).removeClass('active inverse');
      target.toggleClass('inverse', target.hasClass('active') && !target.hasClass('inverse')).addClass('active');
      this.model.set({
        order: order,
        seq: target.hasClass('inverse') ? 'desc' : 'asc'
      }, {reset: true});
      event.preventDefault();
    },
    pagesize_changeHandler: function (event) {
      this.collection.setPagesize(event.target.value);
      if (this.model.get('page') === 0) {
        this.model.trigger('change', this.model);
      } else {
       this.model.set('page', 0);
      }
    },
    refreshButton_clickHandler: function (event) {
      this.refresh();
      $(event.currentTarget).spinner();
    },
    select_changeHandler: function (event) {
      var target = $(event.currentTarget)
        , id = target.closest('tr').attr('id');
      this.saveModel(target, id, target.attr('name'), target.val());
    },
    star_changeHandler: function (event) {
      var target = $(event.currentTarget)
        , id = target.closest('tr').attr('id');
      this.saveModel(target.add(target.siblings('.star')), id, target.attr('name'), target.val());
    },
    statusButton_changeHandler: function (event) {
      var target = $(event.currentTarget)
        , data = _.extend({active: 1, deactive: 0}, target.data())
        , value = target.prop('checked') ? data.active : data.deactive
        , id = target.closest('tr').attr('id')
        , button = $(target[0].labels).filter('.btn');
      this.saveModel(button, id, target.attr('name'), value);
    },
    tbodyFilter_clickHandler: function (event) {
      var target = $(event.currentTarget)
        , label = target.text()
        , path = target.attr('href').split('/').slice(-2)
        , hasFilter = this.model.has(path[0])
        , attr = { page: 0 }; // 要自动切回第一页
      attr[path[0]] = path[1];
      if (path[0] != label) {
        attr[path[0] + '_label'] = label;
      }
      this.model.set(attr, {reset: true});
      if (hasFilter) {
        this.$('.filters').find('[href="#/' + path[0] + '"]').replaceWith(target.clone());
      } else {
        this.$('.filters').append(target.clone());
      }
      event.preventDefault();
    },
    theadFilter_clickHandler: function (event) {
      var target = $(event.currentTarget)
        , path = target.attr('href').split('/').slice(-2);
      this.model.set('page', 0, {silent: true}) // 自动切回第一页
        .unset(path[0], {reset: true});
      target.remove();
      event.preventDefault();
    }
  });
}(Nervenet.createNameSpace('tp.component'), _));<|endoftext|>


<commit_before>var UserCtrl = function ($scope, User, Role) {
    Scope = $scope;
    Scope.Users = User.get();
    Scope.action = "Create";
    Scope.Roles = Role.get();
    Scope.user = {};
    $('#update_button').hide();
    Scope.formChanged = function () {
        $('#save_' + this.user.id).removeClass('disabled');
    };

    Scope.save = function () {
        if(this.user.password == ''){
            delete this.user.password;
        }
        var id = Scope.user.id;
        User.update({id:id}, Scope.user);
    };
    Scope.create = function () {
        var newRec = this.user;
        if(this.user.password == ''){
            delete this.user.password;
        }
        if(!newRec.display_name){
            newRec.display_name = newRec.first_name + ' ' + newRec.last_name;
        }

        User.save(newRec, function(data){
            Scope.Users.record.push(data);
        });

    };
    Scope.promptForNew = function () {
        Scope.action = "Create";
        Scope.user = {};
        Scope.user.password = '';
        $('#save_button').show();
        $('#update_button').hide();
        $('#passwordError').hide();
        $('#passwordRepeat').val('');
        Scope.userform.$setPristine();
    };
    Scope.delete = function () {
        var id = this.user.id;
        User.delete({ id:id }, function () {
            $("#row_" + id).fadeOut();
        });
    };
    Scope.showDetails = function(){
        Scope.action = "Edit";
        Scope.user = this.user;
        Scope.user.password = '';
        $('#save_button').hide();
        $('#update_button').show();
        $('#passwordError').hide();
        $('#passwordRepeat').val('');
        Scope.userform.$setPristine();
    }
    Scope.toggleRoleSelect = function (checked) {

        if(checked == true){
            $('#role_select').prop('disabled', true);
        }else{
            $('#role_select').prop('disabled', false);
        }
    };

};<commit_msg>Selected user highlighted<commit_after>var UserCtrl = function ($scope, User, Role) {
    Scope = $scope;
    Scope.Users = User.get();
    Scope.action = "Create";
    Scope.Roles = Role.get();
    Scope.user = {};
    $('#update_button').hide();
    Scope.formChanged = function () {
        $('#save_' + this.user.id).removeClass('disabled');
    };

    Scope.save = function () {
        if(this.user.password == ''){
            delete this.user.password;
        }
        var id = Scope.user.id;
        User.update({id:id}, Scope.user);
    };
    Scope.create = function () {
        var newRec = this.user;
        if(this.user.password == ''){
            delete this.user.password;
        }
        if(!newRec.display_name){
            newRec.display_name = newRec.first_name + ' ' + newRec.last_name;
        }

        User.save(newRec, function(data){
            Scope.Users.record.push(data);
        });

    };
    Scope.promptForNew = function () {
        Scope.action = "Create";
        Scope.user = {};
        Scope.user.password = '';
        $('#save_button').show();
        $('#update_button').hide();
        $('#passwordError').hide();
        $('#passwordRepeat').val('');
        Scope.userform.$setPristine();
    };
    Scope.delete = function () {
        var id = this.user.id;
        User.delete({ id:id }, function () {
            $("#row_" + id).fadeOut();
        });
    };
    Scope.showDetails = function(){
        $("tr.info").removeClass('info');
        Scope.action = "Edit";
        Scope.user = this.user;
        Scope.user.password = '';
        $('#row_' + Scope.user.id).addClass('info');
        $('#save_button').hide();
        $('#update_button').show();
        $('#passwordError').hide();
        $('#passwordRepeat').val('');
        Scope.userform.$setPristine();

    }
    Scope.toggleRoleSelect = function (checked) {

        if(checked == true){
            $('#role_select').prop('disabled', true);
        }else{
            $('#role_select').prop('disabled', false);
        }
    };

};<|endoftext|>


<commit_before>// Copyright 2014-2018, University of Colorado Boulder

/**
 * Main ScreenView container for Buttons portion of the UI component demo.
 *
 * @author Sam Reid
 */
define( function( require ) {
  'use strict';

  // modules
  var Bounds2 = require( 'DOT/Bounds2' );
  var HSlider = require( 'SUN/HSlider' );
  var inherit = require( 'PHET_CORE/inherit' );
  var LevelCompletedNode = require( 'VEGAS/LevelCompletedNode' );
  var LevelSelectionItemNode = require( 'VEGAS/LevelSelectionItemNode' );
  var OutsideBackgroundNode = require( 'SCENERY_PHET/OutsideBackgroundNode' );
  var ScoreDisplayDiscreteStars = require( 'VEGAS/ScoreDisplayDiscreteStars' );
  var ScoreDisplayNumberAndStar = require( 'VEGAS/ScoreDisplayNumberAndStar' );
  var ScoreDisplayTextAndNumber = require( 'VEGAS/ScoreDisplayTextAndNumber' );
  var PhetColorScheme = require( 'SCENERY_PHET/PhetColorScheme' );
  var PhetFont = require( 'SCENERY_PHET/PhetFont' );
  var Property = require( 'AXON/Property' );
  var RectangularPushButton = require( 'SUN/buttons/RectangularPushButton' );
  var RewardDialog = require( 'VEGAS/RewardDialog' );
  var ScreenView = require( 'JOIST/ScreenView' );
  var StatusBar = require( 'VEGAS/StatusBar' );
  var Text = require( 'SCENERY/nodes/Text' );
  var vegas = require( 'VEGAS/vegas' );

  // constants
  var NUM_STARS = 4;
  var PERFECT_SCORE = 4;

  /**
   * @constructor
   */
  function VegasScreenView() {
    var self = this;
    ScreenView.call( this, { layoutBounds: new Bounds2( 0, 0, 768, 504 ) } );

    // background
    this.addChild( new OutsideBackgroundNode( this.layoutBounds.centerX, this.layoutBounds.centerY + 20, this.layoutBounds.width * 3, this.layoutBounds.height, this.layoutBounds.height ) );

    var scoreProperty = new Property( 1 );

    this.addChild( new ScoreDisplayDiscreteStars( scoreProperty, { left: 20, top: 80, scale: 2, numStars: NUM_STARS, perfectScore: PERFECT_SCORE } ) );
    this.addChild( new ScoreDisplayNumberAndStar( scoreProperty, { left: 20, top: 140, scale: 2, spacing: 14 } ) );
    this.addChild( new ScoreDisplayTextAndNumber( scoreProperty, { left: 20, top: 200, scale: 2 } ) );
    this.addChild( new HSlider( scoreProperty, { min: 0, max: PERFECT_SCORE } ).mutate( { left: 20, top: 260 } ) );

    this.addChild( new StatusBar(
      this.visibleBoundsProperty,
      new Text( 'User provided message' ),
      new ScoreDisplayNumberAndStar( scoreProperty ), {
        backButtonListener: function() { scoreProperty.reset(); }
    } ) );

    //Show a sample LevelCompletedNode that cycles through score values when you press "continue"
    var score = 0;
    var addLevelCompletedNode = function() {
      var maxScore = 12;
      var levelCompletedNode = new LevelCompletedNode( 7, score, maxScore, 4, true, 77, 74, true, function() {
        console.log( 'continue' );
        score++;
        if ( score > maxScore ) {
          score = 0;
        }
        levelCompletedNode.detach();
        addLevelCompletedNode();
      }, {
        right: self.layoutBounds.right - 10,
        top:   self.layoutBounds.top + 80
      } );
      self.addChild( levelCompletedNode );
    };

    addLevelCompletedNode();

    var openDialogButton = new RectangularPushButton( {
      baseColor: PhetColorScheme.PHET_LOGO_YELLOW,
      content: new Text( 'open RewardDialog', { font: new PhetFont( 20 ) } ),
      listener: function() {
        var rewardDialog = new RewardDialog( 10, {
          keepGoingButtonListener: function() {
            console.log( 'Keep Going button' );
            rewardDialog.dispose();
          },
          newLevelButtonListener: function() {
            console.log( 'New Level button' );
            rewardDialog.dispose();
          }
        } );
        rewardDialog.show();
      },
      center: this.layoutBounds.center.plusXY( -20, 0 )
     } );
    this.addChild( openDialogButton );

    var levelSelectionNodeDiscreteStars = LevelSelectionItemNode.createWithScoreDisplayDiscreteStars( new Text( 'icon' ), scoreProperty, {
      scoreDisplayOptions: {
        numStars: NUM_STARS,
        perfectScore: 4,
      },
      listener: function() {
         console.log( 'level start' );
      },
      centerX: 100,
      centerY: 400,
      buttonWidth: 120
    } );
    this.addChild( levelSelectionNodeDiscreteStars );

    var levelSelectionNodeNumberAndStar = LevelSelectionItemNode.createWithScoreDisplayNumberAndStar( new Text( 'icon' ), scoreProperty, {
      listener: function() {
         console.log( 'level start' );
      },
      centerX: 240,
      centerY: 400,
      buttonWidth: 120
    } );
    this.addChild( levelSelectionNodeNumberAndStar );

    var levelSelectionNodeTextAndNumber = LevelSelectionItemNode.createWithScoreDisplayTextAndNumber( new Text( 'icon' ), scoreProperty, {
      listener: function() {
         console.log( 'level start' );
      },
      centerX: 380,
      centerY: 400,
      buttonWidth: 120
    } );
    this.addChild( levelSelectionNodeTextAndNumber );
  }

  vegas.register( 'VegasScreenView', VegasScreenView );

  return inherit( ScreenView, VegasScreenView, {
    step: function( timeElapsed ) {
      // Does nothing for now.
    }
  } );
} );<commit_msg>Use constant PERFECT_SCORE where appropriate<commit_after>// Copyright 2014-2018, University of Colorado Boulder

/**
 * Main ScreenView container for Buttons portion of the UI component demo.
 *
 * @author Sam Reid
 */
define( function( require ) {
  'use strict';

  // modules
  var Bounds2 = require( 'DOT/Bounds2' );
  var HSlider = require( 'SUN/HSlider' );
  var inherit = require( 'PHET_CORE/inherit' );
  var LevelCompletedNode = require( 'VEGAS/LevelCompletedNode' );
  var LevelSelectionItemNode = require( 'VEGAS/LevelSelectionItemNode' );
  var OutsideBackgroundNode = require( 'SCENERY_PHET/OutsideBackgroundNode' );
  var ScoreDisplayDiscreteStars = require( 'VEGAS/ScoreDisplayDiscreteStars' );
  var ScoreDisplayNumberAndStar = require( 'VEGAS/ScoreDisplayNumberAndStar' );
  var ScoreDisplayTextAndNumber = require( 'VEGAS/ScoreDisplayTextAndNumber' );
  var PhetColorScheme = require( 'SCENERY_PHET/PhetColorScheme' );
  var PhetFont = require( 'SCENERY_PHET/PhetFont' );
  var Property = require( 'AXON/Property' );
  var RectangularPushButton = require( 'SUN/buttons/RectangularPushButton' );
  var RewardDialog = require( 'VEGAS/RewardDialog' );
  var ScreenView = require( 'JOIST/ScreenView' );
  var StatusBar = require( 'VEGAS/StatusBar' );
  var Text = require( 'SCENERY/nodes/Text' );
  var vegas = require( 'VEGAS/vegas' );

  // constants
  var NUM_STARS = 4;
  var PERFECT_SCORE = 4;

  /**
   * @constructor
   */
  function VegasScreenView() {
    var self = this;
    ScreenView.call( this, { layoutBounds: new Bounds2( 0, 0, 768, 504 ) } );

    // background
    this.addChild( new OutsideBackgroundNode( this.layoutBounds.centerX, this.layoutBounds.centerY + 20, this.layoutBounds.width * 3, this.layoutBounds.height, this.layoutBounds.height ) );

    var scoreProperty = new Property( 1 );

    this.addChild( new ScoreDisplayDiscreteStars( scoreProperty, { left: 20, top: 80, scale: 2, numStars: NUM_STARS, perfectScore: PERFECT_SCORE } ) );
    this.addChild( new ScoreDisplayNumberAndStar( scoreProperty, { left: 20, top: 140, scale: 2, spacing: 14 } ) );
    this.addChild( new ScoreDisplayTextAndNumber( scoreProperty, { left: 20, top: 200, scale: 2 } ) );
    this.addChild( new HSlider( scoreProperty, { min: 0, max: PERFECT_SCORE } ).mutate( { left: 20, top: 260 } ) );

    this.addChild( new StatusBar(
      this.visibleBoundsProperty,
      new Text( 'User provided message' ),
      new ScoreDisplayNumberAndStar( scoreProperty ), {
        backButtonListener: function() { scoreProperty.reset(); }
    } ) );

    //Show a sample LevelCompletedNode that cycles through score values when you press "continue"
    var score = 0;
    var addLevelCompletedNode = function() {
      var maxScore = 12;
      var levelCompletedNode = new LevelCompletedNode( 7, score, maxScore, 4, true, 77, 74, true, function() {
        console.log( 'continue' );
        score++;
        if ( score > maxScore ) {
          score = 0;
        }
        levelCompletedNode.detach();
        addLevelCompletedNode();
      }, {
        right: self.layoutBounds.right - 10,
        top:   self.layoutBounds.top + 80
      } );
      self.addChild( levelCompletedNode );
    };

    addLevelCompletedNode();

    var openDialogButton = new RectangularPushButton( {
      baseColor: PhetColorScheme.PHET_LOGO_YELLOW,
      content: new Text( 'open RewardDialog', { font: new PhetFont( 20 ) } ),
      listener: function() {
        var rewardDialog = new RewardDialog( 10, {
          keepGoingButtonListener: function() {
            console.log( 'Keep Going button' );
            rewardDialog.dispose();
          },
          newLevelButtonListener: function() {
            console.log( 'New Level button' );
            rewardDialog.dispose();
          }
        } );
        rewardDialog.show();
      },
      center: this.layoutBounds.center.plusXY( -20, 0 )
     } );
    this.addChild( openDialogButton );

    var levelSelectionNodeDiscreteStars = LevelSelectionItemNode.createWithScoreDisplayDiscreteStars( new Text( 'icon' ), scoreProperty, {
      scoreDisplayOptions: {
        numStars: NUM_STARS,
        perfectScore: PERFECT_SCORE,
      },
      listener: function() {
         console.log( 'level start' );
      },
      centerX: 100,
      centerY: 400,
      buttonWidth: 120
    } );
    this.addChild( levelSelectionNodeDiscreteStars );

    var levelSelectionNodeNumberAndStar = LevelSelectionItemNode.createWithScoreDisplayNumberAndStar( new Text( 'icon' ), scoreProperty, {
      listener: function() {
         console.log( 'level start' );
      },
      centerX: 240,
      centerY: 400,
      buttonWidth: 120
    } );
    this.addChild( levelSelectionNodeNumberAndStar );

    var levelSelectionNodeTextAndNumber = LevelSelectionItemNode.createWithScoreDisplayTextAndNumber( new Text( 'icon' ), scoreProperty, {
      listener: function() {
         console.log( 'level start' );
      },
      centerX: 380,
      centerY: 400,
      buttonWidth: 120
    } );
    this.addChild( levelSelectionNodeTextAndNumber );
  }

  vegas.register( 'VegasScreenView', VegasScreenView );

  return inherit( ScreenView, VegasScreenView, {
    step: function( timeElapsed ) {
      // Does nothing for now.
    }
  } );
} );<|endoftext|>


<commit_before>SPE.Group = function( options ) {
    var utils = SPE.utils,
        types = utils.types;

    // Ensure we have a map of options to play with
    options = utils.ensureTypedArg( options, types.OBJECT, {} );

    // Assign a UUID to this instance
    this.uuid = THREE.Math.generateUUID();

    // If no `deltaTime` value is passed to the `SPE.Group.tick` function,
    // the value of this property will be used to advance the simulation.
    this.fixedTimeStep = utils.ensureTypedArg( options.fixedTimeStep, types.NUMBER, 0.016 );

    // Set properties used in the uniforms map.
    this.maxAge = utils.ensureTypedArg( options.maxAge, types.NUMBER, 3 );
    this.texture = utils.ensureInstanceOf( options.texture, THREE.Texture, null );
    this.hasPerspective = utils.ensureTypedArg( options.hasPerspective, types.BOOLEAN, true );
    this.colorize = utils.ensureTypedArg( options.colorize, types.BOOLEAN, true );

    // Set properties used to define the ShaderMaterial's appearance.
    this.blending = utils.ensureTypedArg( options.blending, types.NUMBER, THREE.AdditiveBlending );
    this.transparent = utils.ensureTypedArg( options.transparent, types.BOOLEAN, true );
    this.alphaTest = utils.ensureTypedArg( options.alphaTest, types.NUMBER, 0.5 );
    this.depthWrite = utils.ensureTypedArg( options.depthWrite, types.BOOLEAN, false );
    this.depthTest = utils.ensureTypedArg( options.depthTest, types.BOOLEAN, true );
    this.fog = utils.ensureTypedArg( options.fog, types.BOOLEAN, true );
    this.fogColor = utils.ensureInstanceOf( options.fogColor, THREE.Color, new THREE.Color() );

    // Map of uniforms to be applied to the ShaderMaterial instance.
    this.uniforms = {
        duration: {
            type: 'f',
            value: this.maxAge
        },
        texture: {
            type: 't',
            value: this.texture
        },
        fogColor: {
            type: 'c',
            value: this.fogColor
        },
        fogNear: {
            type: 'f',
            value: 10
        },
        fogFar: {
            type: 'f',
            value: 200
        },
        fogDensity: {
            type: 'f',
            value: 0.5
        }
    };

    // Map of all attributes to be applied to the particles.
    //
    // See SPE.ShaderAttribute for a bit more info on this bit.
    this.attributes = {
        acceleration: new SPE.ShaderAttribute( 'v3' ),
        velocity: new SPE.ShaderAttribute( 'v3' ),
        alive: new SPE.ShaderAttribute( 'f' ),
        age: new SPE.ShaderAttribute( 'f' ),
        size: new SPE.ShaderAttribute( 'v3' ),
        angle: new SPE.ShaderAttribute( 'v4' ),
        colorStart: new SPE.ShaderAttribute( 'c' ),
        colorMiddle: new SPE.ShaderAttribute( 'c' ),
        colorEnd: new SPE.ShaderAttribute( 'c' ),
        opacity: new SPE.ShaderAttribute( 'v3' ),
        position: new SPE.ShaderAttribute( 'v3' )
    };

    // Create the ShaderMaterial instance that'll help render the
    // particles.
    this.material = new THREE.ShaderMaterial( {
        uniforms: this.uniforms,
        // vertexShader: SPE.shaders.vertex,
        // fragmentShader: SPE.shaders.fragment,
        // blending: this.blending,
        // transparent: this.transparent,
        // alphaTest: this.alphaTest,
        // depthWrite: this.depthWrite,
        // depthTest: this.depthTest,
        // defines: this.defines,
        // fog: this.fog
    } );

    // Create the BufferGeometry and Points instances, ensuring
    // the geometry and material are given to the latter.
    this.geometry = new THREE.BufferGeometry();
    this.mesh = new THREE.Points( this.geometry, this.material );
};

SPE.Group.constructor = SPE.Group;

SPE.Group.prototype.addEmitter = function( emitter ) {
    // Ensure an actual emitter instance is passed here.
    //
    // Decided not to throw here, just in case a scene's
    // rendering would be paused. Logging an error instead
    // of stopping execution if exceptions aren't caught.
    if ( emitter instanceof SPE.Emitter === false ) {
        console.error( '`emitter` argument must be instance of SPE.Emitter. Was provided with:', emitter );
        return;
    }

    // Set the `particlesPerSecond` value (PPS) on the emitter.
    // It's used to determine how many particles to release
    // on a per-frame basis.
    emitter._calculatePPSValue( this.maxAge );

    var attributes = this.attributes,
        start = attributes.position.getLength() / 3,
        totalParticleCount = start + emitter.particleCount,
        utils = SPE.utils;

    // Store the offset value in the TypedArray attributes for this emitter.
    emitter.attributeOffset = start;

    // Ensure the attributes and their BufferAttributes exist, and their
    // TypedArrays are of the correct size.
    for ( var attr in attributes ) {
        attributes[ attr ]._createBufferAttribute( totalParticleCount );
    }

    // Loop through each particle this emitter wants to have, and create the attributes values,
    // storing them in the TypedArrays that each attribute holds.
    //
    // TODO: Apply actual values from emitter, not just test data!
    // TODO: Think about attribute packing...esp. with age and alive.
    for ( var i = start; i < totalParticleCount; ++i ) {
        utils.randomVector3( attributes.position, i, new THREE.Vector3( i, i, i ), new THREE.Vector3() );
        utils.randomVector3( attributes.velocity, i, new THREE.Vector3( i, i, i ), new THREE.Vector3() );
        utils.randomVector3( attributes.acceleration, i, new THREE.Vector3( i, i, i ), new THREE.Vector3() );

        // TODO:
        // Don't use utils.randomVector3 here. Size components need to be calculated seperately
        // and there's no need to use a Vec3 to do it in.
        utils.randomVector3( attributes.size, i, new THREE.Vector3( i, i, i ), new THREE.Vector3() );

        // TODO:
        // Don't use utils here. Use emitter's angle values. Again, no need for Vec3 instance.
        // Also, angle is currently a Vec4, but angleAlignVelocity is borked, so I should remove
        // that "feature".
        utils.randomVector3( attributes.angle, i, new THREE.Vector3( i, i, i ), new THREE.Vector3() );

        attributes.age.typedArray.setNumber( i, i ); // index, value
        attributes.alive.typedArray.setNumber( i, i ); // index, value

        utils.randomColor( attributes.colorStart, i, new THREE.Color( Math.random(), Math.random(), Math.random() ), new THREE.Vector3() );
        utils.randomColor( attributes.colorMiddle, i, new THREE.Color( Math.random(), Math.random(), Math.random() ), new THREE.Vector3() );
        utils.randomColor( attributes.colorEnd, i, new THREE.Color( Math.random(), Math.random(), Math.random() ), new THREE.Vector3() );

        utils.randomVector3( attributes.opacity, i, new THREE.Vector3( i, i, i ), new THREE.Vector3() );
    }

    // Update the geometry and make sure the attributes are referencing
    // the typed arrays properly.
    this._applyAttributesToGeometry();

    return this;
};

SPE.Group.prototype._applyAttributesToGeometry = function() {
    for ( var attr in this.attributes ) {
        // Update the array if this attribute exists on the geometry.
        //
        // This needs to be done because the attribute's typed array might have
        // been resized and reinstantiated, and might now be looking at a
        // different ArrayBuffer, so reference needs updating.
        if ( this.geometry.attributes[ attr ] ) {
            this.geometry.attributes[ attr ].array = this.attributes[ attr ].typedArray.array;
        }

        // Add the attribute to the geometry if it doesn't already exist.
        else {
            this.geometry.addAttribute( attr, this.attributes[ attr ].bufferAttribute );
        }
    }
};<commit_msg>Added .defines object to SPE.Group<commit_after>SPE.Group = function( options ) {
    var utils = SPE.utils,
        types = utils.types;

    // Ensure we have a map of options to play with
    options = utils.ensureTypedArg( options, types.OBJECT, {} );

    // Assign a UUID to this instance
    this.uuid = THREE.Math.generateUUID();

    // If no `deltaTime` value is passed to the `SPE.Group.tick` function,
    // the value of this property will be used to advance the simulation.
    this.fixedTimeStep = utils.ensureTypedArg( options.fixedTimeStep, types.NUMBER, 0.016 );

    // Set properties used in the uniforms map.
    this.maxAge = utils.ensureTypedArg( options.maxAge, types.NUMBER, 3 );
    this.texture = utils.ensureInstanceOf( options.texture, THREE.Texture, null );
    this.hasPerspective = utils.ensureTypedArg( options.hasPerspective, types.BOOLEAN, true );
    this.colorize = utils.ensureTypedArg( options.colorize, types.BOOLEAN, true );

    // Set properties used to define the ShaderMaterial's appearance.
    this.blending = utils.ensureTypedArg( options.blending, types.NUMBER, THREE.AdditiveBlending );
    this.transparent = utils.ensureTypedArg( options.transparent, types.BOOLEAN, true );
    this.alphaTest = utils.ensureTypedArg( options.alphaTest, types.NUMBER, 0.5 );
    this.depthWrite = utils.ensureTypedArg( options.depthWrite, types.BOOLEAN, false );
    this.depthTest = utils.ensureTypedArg( options.depthTest, types.BOOLEAN, true );
    this.fog = utils.ensureTypedArg( options.fog, types.BOOLEAN, true );
    this.fogColor = utils.ensureInstanceOf( options.fogColor, THREE.Color, new THREE.Color() );

    // Map of uniforms to be applied to the ShaderMaterial instance.
    this.uniforms = {
        duration: {
            type: 'f',
            value: this.maxAge
        },
        texture: {
            type: 't',
            value: this.texture
        },
        fogColor: {
            type: 'c',
            value: this.fogColor
        },
        fogNear: {
            type: 'f',
            value: 10
        },
        fogFar: {
            type: 'f',
            value: 200
        },
        fogDensity: {
            type: 'f',
            value: 0.5
        }
    };

    // Add some constants into the mix...
    this.defines = {
        HAS_PERSPECTIVE: this.hasPerspective,
        COLORIZE: this.colorize
    };

    // Map of all attributes to be applied to the particles.
    //
    // See SPE.ShaderAttribute for a bit more info on this bit.
    this.attributes = {
        acceleration: new SPE.ShaderAttribute( 'v3' ),
        velocity: new SPE.ShaderAttribute( 'v3' ),
        alive: new SPE.ShaderAttribute( 'f' ),
        age: new SPE.ShaderAttribute( 'f' ),
        size: new SPE.ShaderAttribute( 'v3' ),
        angle: new SPE.ShaderAttribute( 'v4' ),
        colorStart: new SPE.ShaderAttribute( 'c' ),
        colorMiddle: new SPE.ShaderAttribute( 'c' ),
        colorEnd: new SPE.ShaderAttribute( 'c' ),
        opacity: new SPE.ShaderAttribute( 'v3' ),
        position: new SPE.ShaderAttribute( 'v3' )
    };

    // Create the ShaderMaterial instance that'll help render the
    // particles.
    this.material = new THREE.ShaderMaterial( {
        uniforms: this.uniforms,
        vertexShader: SPE.shaders.vertex,
        fragmentShader: SPE.shaders.fragment,
        blending: this.blending,
        transparent: this.transparent,
        alphaTest: this.alphaTest,
        depthWrite: this.depthWrite,
        depthTest: this.depthTest,
        defines: this.defines,
        fog: this.fog
    } );

    // Create the BufferGeometry and Points instances, ensuring
    // the geometry and material are given to the latter.
    this.geometry = new THREE.BufferGeometry();
    this.mesh = new THREE.Points( this.geometry, this.material );
};

SPE.Group.constructor = SPE.Group;

SPE.Group.prototype.addEmitter = function( emitter ) {
    // Ensure an actual emitter instance is passed here.
    //
    // Decided not to throw here, just in case a scene's
    // rendering would be paused. Logging an error instead
    // of stopping execution if exceptions aren't caught.
    if ( emitter instanceof SPE.Emitter === false ) {
        console.error( '`emitter` argument must be instance of SPE.Emitter. Was provided with:', emitter );
        return;
    }

    // Set the `particlesPerSecond` value (PPS) on the emitter.
    // It's used to determine how many particles to release
    // on a per-frame basis.
    emitter._calculatePPSValue( this.maxAge );

    var attributes = this.attributes,
        start = attributes.position.getLength() / 3,
        totalParticleCount = start + emitter.particleCount,
        utils = SPE.utils;

    // Store the offset value in the TypedArray attributes for this emitter.
    emitter.attributeOffset = start;

    // Ensure the attributes and their BufferAttributes exist, and their
    // TypedArrays are of the correct size.
    for ( var attr in attributes ) {
        attributes[ attr ]._createBufferAttribute( totalParticleCount );
    }

    // Loop through each particle this emitter wants to have, and create the attributes values,
    // storing them in the TypedArrays that each attribute holds.
    //
    // TODO: Apply actual values from emitter, not just test data!
    // TODO: Think about attribute packing...esp. with age and alive.
    for ( var i = start; i < totalParticleCount; ++i ) {
        utils.randomVector3( attributes.position, i, new THREE.Vector3( i, i, i ), new THREE.Vector3() );
        utils.randomVector3( attributes.velocity, i, new THREE.Vector3( i, i, i ), new THREE.Vector3() );
        utils.randomVector3( attributes.acceleration, i, new THREE.Vector3( i, i, i ), new THREE.Vector3() );

        // TODO:
        // Don't use utils.randomVector3 here. Size components need to be calculated seperately
        // and there's no need to use a Vec3 to do it in.
        utils.randomVector3( attributes.size, i, new THREE.Vector3( i, i, i ), new THREE.Vector3() );

        // TODO:
        // Don't use utils here. Use emitter's angle values. Again, no need for Vec3 instance.
        // Also, angle is currently a Vec4, but angleAlignVelocity is borked, so I should remove
        // that "feature".
        utils.randomVector3( attributes.angle, i, new THREE.Vector3( i, i, i ), new THREE.Vector3() );

        attributes.age.typedArray.setNumber( i, i ); // index, value
        attributes.alive.typedArray.setNumber( i, i ); // index, value

        utils.randomColor( attributes.colorStart, i, new THREE.Color( Math.random(), Math.random(), Math.random() ), new THREE.Vector3() );
        utils.randomColor( attributes.colorMiddle, i, new THREE.Color( Math.random(), Math.random(), Math.random() ), new THREE.Vector3() );
        utils.randomColor( attributes.colorEnd, i, new THREE.Color( Math.random(), Math.random(), Math.random() ), new THREE.Vector3() );

        utils.randomVector3( attributes.opacity, i, new THREE.Vector3( i, i, i ), new THREE.Vector3() );
    }

    // Update the geometry and make sure the attributes are referencing
    // the typed arrays properly.
    this._applyAttributesToGeometry();

    return this;
};

SPE.Group.prototype._applyAttributesToGeometry = function() {
    for ( var attr in this.attributes ) {
        // Update the array if this attribute exists on the geometry.
        //
        // This needs to be done because the attribute's typed array might have
        // been resized and reinstantiated, and might now be looking at a
        // different ArrayBuffer, so reference needs updating.
        if ( this.geometry.attributes[ attr ] ) {
            this.geometry.attributes[ attr ].array = this.attributes[ attr ].typedArray.array;
        }

        // Add the attribute to the geometry if it doesn't already exist.
        else {
            this.geometry.addAttribute( attr, this.attributes[ attr ].bufferAttribute );
        }
    }
};<|endoftext|>


<commit_before>console.log('Starting to Scream');

var doc = require('dynamodb-doc');

var dynamo = new doc.DynamoDB();

exports.handler = function (event, context) {
    console.log('event:', JSON.stringify(event));
    console.log('context:', JSON.stringify(context));

    context.done(null, event);

    // dynamo.query(
    //     {
    //         'TableName': 'Stalk',
    //         'KeyConditionExpression': "me = :me",
    //         'ExpressionAttributeValues': {
    //             ':me': context.identity.cognitoIdentityId
    //         }
    //     }, function (result) {
    //         console.log(JSON.stringify(result));
    //         // dynamo.putItem(
    //         //     {
    //         //         'TableName': 'Yawn',
    //         //         'Item': {
    //         //             'me': context.identity.cognitoIdentityId,
    //         //             'ref': item
    //         //         }
    //         //     }
    //         //     , context.done);
    //     });
};
<commit_msg>DynamoDB querying based on Cognito event done (from Stalk).<commit_after>console.log('Starting to Scream');

var doc = require('dynamodb-doc');

var dynamo = new doc.DynamoDB();

exports.handler = function (event, context) {
    console.log('event:', JSON.stringify(event));
    console.log('context:', JSON.stringify(context));

    dynamo.query(
        {
            'TableName': 'Stalk',
            'KeyConditionExpression': "me = :me",
            'ExpressionAttributeValues': {
                ':me': event.identityId
            }
        }, function (hmmWhatsThis, goodStuff, hmmmNoIdea) {
            console.log(JSON.stringify(goodStuff));
            context.done(null, event);
            // dynamo.putItem(
            //     {
            //         'TableName': 'Yawn',
            //         'Item': {
            //             'me': context.identity.cognitoIdentityId,
            //             'ref': item
            //         }
            //     }
            //     , context.done);
        });
};
<|endoftext|>


<commit_before>define(['jquery', 'net/meisen/general/Utility'], function ($, Utility) {

  var utilities = {
    createArrow: function(size, direction, click, theme) {
      var arrow = $(document.createElementNS('http://www.w3.org/2000/svg', 'g'));
      arrow.attr('class', 'gantt-scrollbar-arrow');

      el = $(document.createElementNS('http://www.w3.org/2000/svg', 'rect'));
      el.attr({ 'width': size, 'height': size, 'x': 0, y: 0, 'rx': 0, 'ry': 0 });
      el.css({ 'fill': theme.buttonColor, 'stroke': theme.buttonColorBorder, 'stroke-width': 1 });
      el.appendTo(arrow);

      el = $(document.createElementNS('http://www.w3.org/2000/svg', 'path'));
      if (direction == 'left') {
        el.attr({ 'd': 'M 8 4 L 8 10 5 7' });
      } else if (direction == 'right') {
        el.attr({ 'd': 'M 6 4 L 6 10 9 7' });
      } else if (direction == 'top') {
        el.attr({ 'd': 'M 4 8 L 10 8 7 5' });
      } else if (direction == 'bottom') {
        el.attr({ 'd': 'M 4 6 L 10 6 7 9' });
      }
      el.css({ 'fill': theme.arrowColor });
      el.appendTo(arrow);

      arrow.click(function() {
        if ($.isFunction(click)) {
          click({ direction: direction });
        }
      });

      return arrow
    },

    createScroll: function(scrollbar) {
      var _ref = this;

      return function(event) {

        var status = {
          anchor: scrollbar.type == 'horizontal' ? event.pageX : event.pageY,
          scrollbar: scrollbar
        };

        var moveHandler = function(event) {
          var isHorizontal = scrollbar.type == 'horizontal';
          var pos = isHorizontal ? event.pageX : event.pageY;
          var diff = pos - status.anchor;

          if (diff == 0) {
            return;
          } else {
            var direction = diff < 0 ? (isHorizontal ? 'left' : 'top') : (isHorizontal ? 'right' : 'bottom');
            diff = status.scrollbar.pixelToCoord(Math.abs(diff));
            status.scrollbar.move(direction, diff);
          }
          status.anchor = pos;
        };
        var disableHandler = function(event) {
          $(window).unbind('mousemove', moveHandler);
          $(window).unbind('mouseup', disableHandler);
        };

        $(window).bind('mousemove', moveHandler);
        $(window).bind('mouseup', disableHandler);
      };
    }
  };

  /*
   * Default constructor...
   */
  Scrollbar = function(type) {
    this.type = typeof(type) == 'undefined' || type == null ? 'horizontal' : type;
  };

  /*
   * Extended prototype
   */
  Scrollbar.prototype = {
    bar: null,
    scrollarea: null,
    marker: null,
    leftArrow: null,
    rightArrow: null,

    size: { height: 0, width: 0 },

    extent: 0,
    view: {
      position: 0,
      size: 0,
      total: 0
    },

    defaultCfg: {
      theme: {
        arrowSize: 14,
        scrollareaColor: '#EEEEEE',
        markerColor: '#BFC8D1',
        buttonColorBorder: '#666666',
        arrowColor: '#666666',
        buttonColor: '#EBE7E8'
      },
      hideOnNoScroll: true,
      propagateScrollOnNoMove: false,
      step: 1
    },

    init: function(canvas, cfg) {
      var _ref = this;

      this.opts = $.extend(true, {}, this.defaultCfg, cfg);

      // create a group for the scrollbar
      this.bar = $(document.createElementNS('http://www.w3.org/2000/svg', 'g'));
      this.bar.attr('class', 'gantt-scrollbar-container');

      // create the scrollbar
      var extentAttribute = this.type == 'horizontal' ? 'height' : 'width';
      this.scrollarea = $(document.createElementNS('http://www.w3.org/2000/svg', 'rect'));
      this.scrollarea.attr({ y: 0, 'rx': 0, 'ry': 0 });
      this.scrollarea.attr(extentAttribute, this.getFixedExtent());
      this.scrollarea.css({ 'fill': this.opts.theme.scrollareaColor, 'stroke': this.opts.theme.scrollareaColor, 'stroke-width': 1 });
      this.scrollarea.appendTo(this.bar);
      this.scrollarea.click(function(event) {
        var pos = this.type == 'horizontal' ? event.offsetX : event.offsetY;

        var coord = _ref.pixelToCoord(pos - _ref.opts.theme.arrowSize - 1);
        var direction;
        if (this.type == 'horizontal') {
          direction = coord < _ref.view.position ? 'left' : 'right';
        } else {
          direction = coord < _ref.view.position ? 'top' : 'bottom';
        }

        _ref.move(direction);
      });

      // create the scroll-marker
      this.marker = $(document.createElementNS('http://www.w3.org/2000/svg', 'rect'));
      this.marker.attr({ 'y': 0, 'rx': 0, 'ry': 0 });
      this.marker.attr(extentAttribute, this.getFixedExtent());
      this.marker.css({ 'fill': this.opts.theme.markerColor, 'stroke': this.opts.theme.markerColor, 'stroke-width': 1, 'cursor': 'default' });
      this.marker.appendTo(this.bar);
      this.marker.mousedown(utilities.createScroll(this));

      // create the left arrow
      this.leftArrow = utilities.createArrow(this.getFixedExtent(), this.type == 'horizontal' ? 'left' : 'top', function() {
        _ref.move('left', _ref.opts.step);
      }, this.opts.theme);
      this.leftArrow.appendTo(this.bar);

      // create the right arrow
      this.rightArrow = utilities.createArrow(this.getFixedExtent(), this.type == 'horizontal' ? 'right' : 'bottom', function() {
        _ref.move('right', _ref.opts.step);
      }, this.opts.theme);
      this.rightArrow.appendTo(this.bar);

      // append the scrollbar
      this.bar.appendTo(canvas);
    },

    setPosition: function(x, y) {

      /*
       * Nicer sharper look, see:
       * http://stackoverflow.com/questions/18019453/svg-rectangle-blurred-in-all-browsers
       */
      x = Math.floor(x) + 0.5;
      y = Math.floor(y) + 0.5;

      this.bar.attr({ 'transform': 'translate(' + x + ', ' + y + ')' });
    },

    move: function(direction, steps) {
      steps = typeof(steps) == 'undefined' || steps == null ? this.view.size - 1 : steps;

      var newPosition = this.view.position + ((direction == 'left' || direction == 'top' ? -1 : 1) * steps);
      newPosition = Math.max(0, newPosition);
      newPosition = Math.min(newPosition, this.view.total - this.view.size);

      this.setView(newPosition, null, null, false);
    },

    setView: function(position, size, total, force) {
      position = typeof(position) == 'undefined' || position == null ? this.view.position : position;
      size = typeof(size) == 'undefined' || size == null ? this.view.size : size;
      total = typeof(total) == 'undefined' || total == null ? this.view.total : total;
      force = typeof(force) == 'undefined' || force == null ? false : force;

      total = Math.max(0, total);
      position = Math.max(0, position);
      size = Math.max(0, size);

      // validate some values
      if (size > total) {
        size = total;
      }
      if (position + size > total) {
        position = total - size;
      }

      // check if we have a change or if it was forced to update
      var changed = this.view.position != position || this.view.size != size;
      if (!force && !changed && this.view.total == total) {
        return;
      } else {
        this.view = { position: position, size: size, total: total };
      }

      if (!this.opts.hideOnNoScroll || this.isScrollable()) {
        this.bar.css('visibility', 'visible');
      } else {
        this.bar.css('visibility', 'hidden');
      }

      var offset = this.getFixedExtent() + 1;

      var scrollareaExtent = this.getScrollareaExtent();
      scrollareaExtent = isNaN(scrollareaExtent) ? 0 : scrollareaExtent;

      var markerExtent = this.coordToPixel(size);
      var markerPos = offset + this.coordToPixel(position);
      if (this.type == 'horizontal') {
        this.marker.attr({ 'width': markerExtent, 'x': markerPos });
      } else {
        this.marker.attr({ 'height': markerExtent, 'y': markerPos });
      }

      // trigger the event if there was a change
      if (changed) {
        this.bar.trigger('viewchange', { position: position, size: size, total: total });

        // trigger a size change if needed
        var _ref = this;
        setTimeout(function() {
          var bbox = _ref.bar.get(0).getBBox();
          var size = { 'height': bbox.height, 'width': bbox.width };
          if (_ref.size.height != size.height || _ref.size.width != size.width) {
            _ref.size = size;
            _ref.bar.trigger('sizechanged', _ref);
          }
        }, 0);
      }
    },

    isScrollable: function() {
      return this.view.size != this.view.total
    },

    pixelToCoord: function(pixel) {
      return pixel * (this.view.total / this.getScrollareaExtent());
    },

    coordToPixel: function(coord) {
      return this.view.total == 0 ? 0 : (coord / this.view.total) * this.getScrollareaExtent();
    },

    setExtent: function(extent, force) {
      extent = typeof(extent) == 'undefined' || extent == null ? this.extent : extent;
      force = typeof(force) == 'undefined' || force == null ? false : force;

      // check if we have a change or if it was forced to update
      if (!force && this.extent == extent) {
        return;
      } else {
        this.extent = extent;
      }

      // calculate the new values
      var offset = this.getFixedExtent() + 1;
      var scrollareaExtent = this.getScrollareaExtent();

      if (this.type == 'horizontal') {
        this.scrollarea.attr({ 'width': scrollareaExtent, 'x': offset });
        this.rightArrow.attr({ 'transform': 'translate(' + (offset + scrollareaExtent + 1) + ', 0)' });
      } else {
        this.scrollarea.attr({ 'height': scrollareaExtent, 'y': offset });
        this.rightArrow.attr({ 'transform': 'translate(0, ' + (offset + scrollareaExtent + 1) + ')' });
      }

      // force a redraw of the marker
      this.setView(null, null, null, true);
    },

    getFixedExtent: function() {
      return this.opts.theme.arrowSize;
    },

    getView: function() {
      return this.view;
    },

    getExtent: function() {
      return this.extent;
    },

    getScrollareaExtent: function() {
      var offset = this.getFixedExtent() + 1;
      return Math.max(0, this.extent - 2 * offset);
    },

    bindToWheel: function(selector) {
      var el = selector instanceof jQuery ? selector : $(el);

      var eventName = Utility.getSupportedEvent([ 'mousewheel', 'wheel' ]);
      if (eventName == null) {
        return;
      }

      var _ref = this;
      el.on(eventName, function(e) {
        var oEvent = e.originalEvent;
        var delta  = oEvent.deltaY || (-1 * oEvent.wheelDelta);

        var direction = delta > 0 ? 'bottom' : 'top';
        var oldPos = _ref.view.position;
        _ref.move(direction, Math.abs(delta / 120));

        // if there was no scroll propagate it
        return _ref.opts.propagateScrollOnNoMove && oldPos == _ref.view.position;
      });
    },

    on: function(event, handler) {
      this.bar.on(event, handler);
    },

    off: function(event, handler) {
      this.bar.off(event, handler);
    },

    getSize: function() {
      return this.size;
    }
  };

  return Scrollbar;
});<commit_msg>- fixed a bug with the click on the scrollbar, moving in the wrong direction<commit_after>define(['jquery', 'net/meisen/general/Utility'], function ($, Utility) {

  var utilities = {
    createArrow: function(size, direction, click, theme) {
      var arrow = $(document.createElementNS('http://www.w3.org/2000/svg', 'g'));
      arrow.attr('class', 'gantt-scrollbar-arrow');

      el = $(document.createElementNS('http://www.w3.org/2000/svg', 'rect'));
      el.attr({ 'width': size, 'height': size, 'x': 0, y: 0, 'rx': 0, 'ry': 0 });
      el.css({ 'fill': theme.buttonColor, 'stroke': theme.buttonColorBorder, 'stroke-width': 1 });
      el.appendTo(arrow);

      el = $(document.createElementNS('http://www.w3.org/2000/svg', 'path'));
      if (direction == 'left') {
        el.attr({ 'd': 'M 8 4 L 8 10 5 7' });
      } else if (direction == 'right') {
        el.attr({ 'd': 'M 6 4 L 6 10 9 7' });
      } else if (direction == 'top') {
        el.attr({ 'd': 'M 4 8 L 10 8 7 5' });
      } else if (direction == 'bottom') {
        el.attr({ 'd': 'M 4 6 L 10 6 7 9' });
      }
      el.css({ 'fill': theme.arrowColor });
      el.appendTo(arrow);

      arrow.click(function() {
        if ($.isFunction(click)) {
          click({ direction: direction });
        }
      });

      return arrow
    },

    createScroll: function(scrollbar) {
      var _ref = this;

      return function(event) {

        var status = {
          anchor: scrollbar.type == 'horizontal' ? event.pageX : event.pageY,
          scrollbar: scrollbar
        };

        var moveHandler = function(event) {
          var isHorizontal = scrollbar.type == 'horizontal';
          var pos = isHorizontal ? event.pageX : event.pageY;
          var diff = pos - status.anchor;

          if (diff == 0) {
            return;
          } else {
            var direction = diff < 0 ? (isHorizontal ? 'left' : 'top') : (isHorizontal ? 'right' : 'bottom');
            diff = status.scrollbar.pixelToCoord(Math.abs(diff));
            status.scrollbar.move(direction, diff);
          }
          status.anchor = pos;
        };
        var disableHandler = function(event) {
          $(window).unbind('mousemove', moveHandler);
          $(window).unbind('mouseup', disableHandler);
        };

        $(window).bind('mousemove', moveHandler);
        $(window).bind('mouseup', disableHandler);
      };
    }
  };

  /*
   * Default constructor...
   */
  Scrollbar = function(type) {
    this.type = typeof(type) == 'undefined' || type == null ? 'horizontal' : type;
  };

  /*
   * Extended prototype
   */
  Scrollbar.prototype = {
    bar: null,
    scrollarea: null,
    marker: null,
    leftArrow: null,
    rightArrow: null,

    size: { height: 0, width: 0 },

    extent: 0,
    view: {
      position: 0,
      size: 0,
      total: 0
    },

    defaultCfg: {
      theme: {
        arrowSize: 14,
        scrollareaColor: '#EEEEEE',
        markerColor: '#BFC8D1',
        buttonColorBorder: '#666666',
        arrowColor: '#666666',
        buttonColor: '#EBE7E8'
      },
      hideOnNoScroll: true,
      propagateScrollOnNoMove: false,
      step: 1
    },

    init: function(canvas, cfg) {
      var _ref = this;

      this.opts = $.extend(true, {}, this.defaultCfg, cfg);

      // create a group for the scrollbar
      this.bar = $(document.createElementNS('http://www.w3.org/2000/svg', 'g'));
      this.bar.attr('class', 'gantt-scrollbar-container');

      // create the scrollbar
      var extentAttribute = this.type == 'horizontal' ? 'height' : 'width';
      this.scrollarea = $(document.createElementNS('http://www.w3.org/2000/svg', 'rect'));
      this.scrollarea.attr({ y: 0, 'rx': 0, 'ry': 0 });
      this.scrollarea.attr(extentAttribute, this.getFixedExtent());
      this.scrollarea.css({ 'fill': this.opts.theme.scrollareaColor, 'stroke': this.opts.theme.scrollareaColor, 'stroke-width': 1 });
      this.scrollarea.appendTo(this.bar);
      this.scrollarea.click(function(event) {
        var offset = _ref.bar.offset();
        var pos = _ref.type == 'horizontal' ? event.pageX - offset.left : event.pageY - offset.top;
        var coord = _ref.pixelToCoord(pos - (_ref.getFixedExtent() + 1));

        var direction;
        if (this.type == 'horizontal') {
          direction = coord < _ref.view.position ? 'left' : 'right';
        } else {
          direction = coord < _ref.view.position ? 'top' : 'bottom';
        }

        _ref.move(direction);
      });

      // create the scroll-marker
      this.marker = $(document.createElementNS('http://www.w3.org/2000/svg', 'rect'));
      this.marker.attr({ 'y': 0, 'rx': 0, 'ry': 0 });
      this.marker.attr(extentAttribute, this.getFixedExtent());
      this.marker.css({ 'fill': this.opts.theme.markerColor, 'stroke': this.opts.theme.markerColor, 'stroke-width': 1, 'cursor': 'default' });
      this.marker.appendTo(this.bar);
      this.marker.mousedown(utilities.createScroll(this));

      // create the left arrow
      this.leftArrow = utilities.createArrow(this.getFixedExtent(), this.type == 'horizontal' ? 'left' : 'top', function() {
        _ref.move('left', _ref.opts.step);
      }, this.opts.theme);
      this.leftArrow.appendTo(this.bar);

      // create the right arrow
      this.rightArrow = utilities.createArrow(this.getFixedExtent(), this.type == 'horizontal' ? 'right' : 'bottom', function() {
        _ref.move('right', _ref.opts.step);
      }, this.opts.theme);
      this.rightArrow.appendTo(this.bar);

      // append the scrollbar
      this.bar.appendTo(canvas);
    },

    setPosition: function(x, y) {

      /*
       * Nicer sharper look, see:
       * http://stackoverflow.com/questions/18019453/svg-rectangle-blurred-in-all-browsers
       */
      x = Math.floor(x) + 0.5;
      y = Math.floor(y) + 0.5;

      this.bar.attr({ 'transform': 'translate(' + x + ', ' + y + ')' });
    },

    move: function(direction, steps) {
      steps = typeof(steps) == 'undefined' || steps == null ? this.view.size - 1 : steps;

      var newPosition = this.view.position + ((direction == 'left' || direction == 'top' ? -1 : 1) * steps);
      newPosition = Math.max(0, newPosition);
      newPosition = Math.min(newPosition, this.view.total - this.view.size);

      this.setView(newPosition, null, null, false);
    },

    setView: function(position, size, total, force) {
      position = typeof(position) == 'undefined' || position == null ? this.view.position : position;
      size = typeof(size) == 'undefined' || size == null ? this.view.size : size;
      total = typeof(total) == 'undefined' || total == null ? this.view.total : total;
      force = typeof(force) == 'undefined' || force == null ? false : force;

      total = Math.max(0, total);
      position = Math.max(0, position);
      size = Math.max(0, size);

      // validate some values
      if (size > total) {
        size = total;
      }
      if (position + size > total) {
        position = total - size;
      }

      // check if we have a change or if it was forced to update
      var changed = this.view.position != position || this.view.size != size;
      if (!force && !changed && this.view.total == total) {
        return;
      } else {
        this.view = { position: position, size: size, total: total };
      }

      if (!this.opts.hideOnNoScroll || this.isScrollable()) {
        this.bar.css('visibility', 'visible');
      } else {
        this.bar.css('visibility', 'hidden');
      }

      var offset = this.getFixedExtent() + 1;

      var scrollareaExtent = this.getScrollareaExtent();
      scrollareaExtent = isNaN(scrollareaExtent) ? 0 : scrollareaExtent;

      var markerExtent = this.coordToPixel(size);
      var markerPos = offset + this.coordToPixel(position);
      if (this.type == 'horizontal') {
        this.marker.attr({ 'width': markerExtent, 'x': markerPos });
      } else {
        this.marker.attr({ 'height': markerExtent, 'y': markerPos });
      }

      // trigger the event if there was a change
      if (changed) {
        this.bar.trigger('viewchange', { position: position, size: size, total: total });

        // trigger a size change if needed
        var _ref = this;
        setTimeout(function() {
          var bbox = _ref.bar.get(0).getBBox();
          var size = { 'height': bbox.height, 'width': bbox.width };
          if (_ref.size.height != size.height || _ref.size.width != size.width) {
            _ref.size = size;
            _ref.bar.trigger('sizechanged', _ref);
          }
        }, 0);
      }
    },

    isScrollable: function() {
      return this.view.size != this.view.total
    },

    pixelToCoord: function(pixel) {
      return pixel * (this.view.total / this.getScrollareaExtent());
    },

    coordToPixel: function(coord) {
      return this.view.total == 0 ? 0 : (coord / this.view.total) * this.getScrollareaExtent();
    },

    setExtent: function(extent, force) {
      extent = typeof(extent) == 'undefined' || extent == null ? this.extent : extent;
      force = typeof(force) == 'undefined' || force == null ? false : force;

      // check if we have a change or if it was forced to update
      if (!force && this.extent == extent) {
        return;
      } else {
        this.extent = extent;
      }

      // calculate the new values
      var offset = this.getFixedExtent() + 1;
      var scrollareaExtent = this.getScrollareaExtent();

      if (this.type == 'horizontal') {
        this.scrollarea.attr({ 'width': scrollareaExtent, 'x': offset });
        this.rightArrow.attr({ 'transform': 'translate(' + (offset + scrollareaExtent + 1) + ', 0)' });
      } else {
        this.scrollarea.attr({ 'height': scrollareaExtent, 'y': offset });
        this.rightArrow.attr({ 'transform': 'translate(0, ' + (offset + scrollareaExtent + 1) + ')' });
      }

      // force a redraw of the marker
      this.setView(null, null, null, true);
    },

    getFixedExtent: function() {
      return this.opts.theme.arrowSize;
    },

    getView: function() {
      return this.view;
    },

    getExtent: function() {
      return this.extent;
    },

    getScrollareaExtent: function() {
      var offset = this.getFixedExtent() + 1;
      return Math.max(0, this.extent - 2 * offset);
    },

    bindToWheel: function(selector) {
      var el = selector instanceof jQuery ? selector : $(el);

      var eventName = Utility.getSupportedEvent([ 'mousewheel', 'wheel' ]);
      if (eventName == null) {
        return;
      }

      var _ref = this;
      el.on(eventName, function(e) {
        var oEvent = e.originalEvent;
        var delta  = oEvent.deltaY || (-1 * oEvent.wheelDelta);

        var direction = delta > 0 ? 'bottom' : 'top';
        var oldPos = _ref.view.position;
        _ref.move(direction, Math.abs(delta / 120));

        // if there was no scroll propagate it
        return _ref.opts.propagateScrollOnNoMove && oldPos == _ref.view.position;
      });
    },

    on: function(event, handler) {
      this.bar.on(event, handler);
    },

    off: function(event, handler) {
      this.bar.off(event, handler);
    },

    getSize: function() {
      return this.size;
    }
  };

  return Scrollbar;
});<|endoftext|>


<commit_before>var cp  = require('child_process'),
    log = require('./log');

module.exports = {

  start: function (options, callback) {

    var child = this.spawn(options);

    if (options.waitForMessage) {
      this.waitForMessage(options, child, callback);
    } else {
      callback();
    }

    return child;
  },

  spawn: function (options) {
    log.debug('[cuke-monkey][' + options.prefix + ']', 'starting process');

    var child = cp.spawn(options.bin, options.args);

    this.logOutputs(options.prefix, child);

    return child;
  },

  logOutputs: function (prefix, child) {
    child.stdout.on('data', function (data) {
      log.debug('[cuke-monkey][' + prefix + '.stdout]', data.toString());
    });
    child.stderr.on('data', function (data) {
      log.debug('[cuke-monkey][' + prefix + '.stderr]', data.toString());
    });
  },

  waitForMessage: function (options, child, callback) {
    child.stdout.on('data', function onData (data) {
      if (data.toString().match(options.waitForMessage)) {
        child.stdout.removeListener('data', onData);
        log.debug('[cuke-monkey][' + options.prefix + ']', 'started successfully');
        return callback();
      }
      if (data.toString().match(options.errorMessage)) {
        log.error('[cuke-monkey][' + options.prefix + ']', 'failed to start');
        log.error(data);
        callback(data);
      }
    });
  },

  kill: function (options, callback) {

    log.debug('[cuke-monkey][' + options.prefix + ']', 'killing child process with pid', options.child.pid);

    try {
      process.kill(options.child.pid, 0);
      process.kill(options.child.pid);
    } catch (e) {
      options.child = null;
      return callback();
    }

    var delay = 100,
        retries = 10 * (1000 / delay);

    var waitForProcessToDie = setInterval(function () {
      try {
        if (retries-- < 0) {
          throw new Error('Process took too long to die')
        }
        process.kill(options.child.pid, 0);
      } catch (e) {
        clearInterval(waitForProcessToDie);
        if (e.code === 'ESRCH') {
          options.child = null;
          callback();
        } else {
          callback(e);
        }
      }
    }, delay);
  }

};<commit_msg>logs now report strings not array buffers<commit_after>var cp  = require('child_process'),
    log = require('./log');

module.exports = {

  start: function (options, callback) {

    var child = this.spawn(options);

    if (options.waitForMessage) {
      this.waitForMessage(options, child, callback);
    } else {
      callback();
    }

    return child;
  },

  spawn: function (options) {
    log.debug('[cuke-monkey][' + options.prefix + ']', 'starting process');

    var child = cp.spawn(options.bin, options.args);

    this.logOutputs(options.prefix, child);

    return child;
  },

  logOutputs: function (prefix, child) {
    child.stdout.on('data', function (data) {
      log.debug('[cuke-monkey][' + prefix + '.stdout]', data.toString());
    });
    child.stderr.on('data', function (data) {
      log.debug('[cuke-monkey][' + prefix + '.stderr]', data.toString());
    });
  },

  waitForMessage: function (options, child, callback) {
    child.stdout.on('data', function onData (data) {
      if (data.toString().match(options.waitForMessage)) {
        child.stdout.removeListener('data', onData);
        log.debug('[cuke-monkey][' + options.prefix + ']', 'started successfully');
        return callback();
      }
      if (data.toString().match(options.errorMessage)) {
        log.error('[cuke-monkey][' + options.prefix + ']', 'failed to start');
        log.error(data.toString());
        callback(data.toString());
      }
    });
  },

  kill: function (options, callback) {

    log.debug('[cuke-monkey][' + options.prefix + ']', 'killing child process with pid', options.child.pid);

    try {
      process.kill(options.child.pid, 0);
      process.kill(options.child.pid);
    } catch (e) {
      options.child = null;
      return callback();
    }

    var delay = 100,
        retries = 10 * (1000 / delay);

    var waitForProcessToDie = setInterval(function () {
      try {
        if (retries-- < 0) {
          throw new Error('Process took too long to die')
        }
        process.kill(options.child.pid, 0);
      } catch (e) {
        clearInterval(waitForProcessToDie);
        if (e.code === 'ESRCH') {
          options.child = null;
          callback();
        } else {
          callback(e);
        }
      }
    }, delay);
  }

};<|endoftext|>