<commit_before>/*
 backgrid-grouped-columns
 https://github.com/WRidder/backgrid-grouped-columns

 Copyright (c) 2014 Wilbert van de Ridder and contributors
 Licensed under the MIT @license.
 */
(function (root, factory) {

  // CommonJS
  if (typeof exports == "object") {
    module.exports = factory(require("underscore"), require("backgrid"));
  }
  // Browser
  else factory(root._, root.Backgrid, root.moment);

}(this, function (_, Backgrid) {
  var groupedHeader = Backgrid.Extension.GroupedHeader = Backgrid.Header.extend({
    columnLayout: null,
    columnCollection: Backgrid.Columns,
    headerRows: [],

    initialize: function() {
      Backgrid.Header.prototype.initialize.apply(this, arguments);
      this.listenTo(this.columns, "change:renderable", this.render);
      this.listenTo(this.columns, "add remove", this.render);
    },

    /**
     Renders this table head with a single row of header cells.
     */
    render: function () {
      var view = this;
      view.$el.empty();

      // If a column layout has been defined, determine nesting
      if (view.columnLayout) {
        var key;
        for(key in view.columnLayout) {
          if (view.columnLayout.hasOwnProperty(key)) {
            view.calculateNesting(view.columnLayout[key]);
          }
        }
      }

      // Find amount of header rows
      var rowAmount = view.findDepth();
      var rows = Array.apply(null, new Array(rowAmount));
      rows = _.map(rows, function () { return []; });

      // Loop columns
      var lastNesting = [];
      view.columns.each(function(column) {
        var colNesting = column.get("nesting");
        var renderable = (typeof column.get("renderable") == "undefined" || column.get("renderable"));
        if (colNesting && !_.isEmpty(colNesting) && renderable)  {
          // Check for overlap and uniques with previous column; Use index based intersection
          var overlap = _.filter(lastNesting, function(num, ind) { return num == colNesting[ind];});
          var unique = _.difference(colNesting, overlap);

          // Create unique parents
          _.each(unique, function(element, index) {
            rows[index + overlap.length].push({
              name: element,
              sortable: false,
              editable: false,
              attributes: {
                colspan: 1,
                rowspan: 1
              },
              childColumns: [column.get("name")]
            });
          });

          // Increase colspan for every intersection
          _.each(overlap, function(element, index) {
            var lastElement = _.last(rows[index]);
            lastElement.attributes.colspan++;
            lastElement.childColumns.push(column.get("name"));
          });

          // Add main column
          rows[colNesting.length].push(_.extend({
            attributes: {
              colspan: 1,
              rowspan: rowAmount - colNesting.length
            }}, column.toJSON()));

          // Update nesting
          lastNesting = colNesting;
        }
        else if(renderable) {
          // Reset nesting
          lastNesting = [];

          // Create column definition attributes and add to rows
          rows[0].push(_.extend({
            attributes: {
              colspan: 1,
              rowspan: rowAmount
          }}, column.toJSON()));
        }
      });

      // Render the rows
      view.headerRows = [];
      _.each(rows, function(coll) {
        var row = new Backgrid.HeaderRow({
          columns: coll,
          collection: view.collection
        });
        view.$el.append(row.render().$el);
        view.headerRows.push(row);
      });

      // Trigger event
      view.collection.trigger("backgrid:header:rendered");

      this.delegateEvents();
      return this;
    },
    calculateNesting: function(object, nestArray) {
      var nestingArray = _.clone(nestArray || []);
      if (_.has(object, "children") && _.isArray(object.children) && !_.isEmpty(object.children)) {
        nestingArray.push(object.name);
        _.each(object.children, function(obj) {
          this.calculateNesting(obj, nestingArray);
        }, this);
      }
      else {
        // No children, assume it's an existing column model
        var columnModel = _.first(this.columns.where({ name: object.name}));
        if (columnModel && (typeof columnModel.get("renderable") == "undefined" || columnModel.get("renderable"))) {
          columnModel.set("nesting", nestingArray, {silent: true});
        }
      }
    },
    findDepth: function() {
      var view = this;
      var rows = 0;

      view.columns.each(function(col) {
        if (col.get('nesting')) {
          rows = Math.max(rows, col.get('nesting').length);
        }
      });

      return rows + 1;
    }
  });
}));<commit_msg>- strict mode<commit_after>/*
 backgrid-grouped-columns
 https://github.com/WRidder/backgrid-grouped-columns

 Copyright (c) 2014 Wilbert van de Ridder and contributors
 Licensed under the MIT @license.
 */
(function (root, factory) {

  // CommonJS
  if (typeof exports == "object") {
    module.exports = factory(require("underscore"), require("backgrid"));
  }
  // Browser
  else factory(root._, root.Backgrid, root.moment);

}(this, function (_, Backgrid) {
  "use strict";

  var groupedHeader = Backgrid.Extension.GroupedHeader = Backgrid.Header.extend({
    columnLayout: null,
    columnCollection: Backgrid.Columns,
    headerRows: [],

    initialize: function() {
      Backgrid.Header.prototype.initialize.apply(this, arguments);
      this.listenTo(this.columns, "change:renderable", this.render);
      this.listenTo(this.columns, "add remove", this.render);
    },

    /**
     Renders this table head with a single row of header cells.
     */
    render: function () {
      var view = this;
      view.$el.empty();

      // If a column layout has been defined, determine nesting
      if (view.columnLayout) {
        var key;
        for(key in view.columnLayout) {
          if (view.columnLayout.hasOwnProperty(key)) {
            view.calculateNesting(view.columnLayout[key]);
          }
        }
      }

      // Find amount of header rows
      var rowAmount = view.findDepth();
      var rows = Array.apply(null, new Array(rowAmount));
      rows = _.map(rows, function () { return []; });

      // Loop columns
      var lastNesting = [];
      view.columns.each(function(column) {
        var colNesting = column.get("nesting");
        var renderable = (typeof column.get("renderable") == "undefined" || column.get("renderable"));
        if (colNesting && !_.isEmpty(colNesting) && renderable)  {
          // Check for overlap and uniques with previous column; Use index based intersection
          var overlap = _.filter(lastNesting, function(num, ind) { return num == colNesting[ind];});
          var unique = _.difference(colNesting, overlap);

          // Create unique parents
          _.each(unique, function(element, index) {
            rows[index + overlap.length].push({
              name: element,
              sortable: false,
              editable: false,
              attributes: {
                colspan: 1,
                rowspan: 1
              },
              childColumns: [column.get("name")]
            });
          });

          // Increase colspan for every intersection
          _.each(overlap, function(element, index) {
            var lastElement = _.last(rows[index]);
            lastElement.attributes.colspan++;
            lastElement.childColumns.push(column.get("name"));
          });

          // Add main column
          rows[colNesting.length].push(_.extend({
            attributes: {
              colspan: 1,
              rowspan: rowAmount - colNesting.length
            }}, column.toJSON()));

          // Update nesting
          lastNesting = colNesting;
        }
        else if(renderable) {
          // Reset nesting
          lastNesting = [];

          // Create column definition attributes and add to rows
          rows[0].push(_.extend({
            attributes: {
              colspan: 1,
              rowspan: rowAmount
          }}, column.toJSON()));
        }
      });

      // Render the rows
      view.headerRows = [];
      _.each(rows, function(coll) {
        var row = new Backgrid.HeaderRow({
          columns: coll,
          collection: view.collection
        });
        view.$el.append(row.render().$el);
        view.headerRows.push(row);
      });

      // Trigger event
      view.collection.trigger("backgrid:header:rendered");

      this.delegateEvents();
      return this;
    },
    calculateNesting: function(object, nestArray) {
      var nestingArray = _.clone(nestArray || []);
      if (_.has(object, "children") && _.isArray(object.children) && !_.isEmpty(object.children)) {
        nestingArray.push(object.name);
        _.each(object.children, function(obj) {
          this.calculateNesting(obj, nestingArray);
        }, this);
      }
      else {
        // No children, assume it's an existing column model
        var columnModel = _.first(this.columns.where({ name: object.name}));
        if (columnModel && (typeof columnModel.get("renderable") == "undefined" || columnModel.get("renderable"))) {
          columnModel.set("nesting", nestingArray, {silent: true});
        }
      }
    },
    findDepth: function() {
      var view = this;
      var rows = 0;

      view.columns.each(function(col) {
        if (col.get('nesting')) {
          rows = Math.max(rows, col.get('nesting').length);
        }
      });

      return rows + 1;
    }
  });
}));<|endoftext|>


<commit_before>/**
 * @author Maximilian Greschke <maximilian@veyo-care.com>
 */

'use strict';

Object.defineProperty(exports, '__esModule', {
    value: true
});

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new _errors.TypeError('Cannot call a class as a function'); } }

var _errors = require('./errors');

var _camelcase = require('camelcase');

var _camelcase2 = _interopRequireDefault(_camelcase);

var _decamelize = require('decamelize');

var _decamelize2 = _interopRequireDefault(_decamelize);

/**
 * Recursively changes all key values in a JS object to camelCase or decamelizes them.
 *
 * Does not work with arrays for obvious reasons.
 *
 * @param target - the object to be synchronized
 * @param source - the object to sync data from
 * @param overwrite - overwrites existing keys if true
 * @returns {{}}
 */

var deepCamelClass = (function () {
    function deepCamelClass() {
        _classCallCheck(this, deepCamelClass);
    }

    _createClass(deepCamelClass, [{
        key: 'applyToObjectKeys',
        value: function applyToObjectKeys(obj, func) {

            if (typeof obj !== 'object' || obj instanceof Array) {
                throw new _errors.TypeError('obj must be a object.');
            }

            for (var key in obj) {

                var newKey = func(key);
                var temp = obj[key];

                delete obj[key];
                obj[newKey] = temp;

                if (typeof obj[newKey] === 'object') {
                    obj[newKey] = this.applyToObjectKeys(obj[newKey], func);
                }
            }

            console.log(obj);

            return obj;
        }
    }, {
        key: 'camelize',
        value: function camelize(obj) {
            return this.applyToObjectKeys(obj, _camelcase2['default']);
        }
    }, {
        key: 'decamelize',
        value: function decamelize(obj) {
            return this.applyToObjectKeys(obj, _decamelize2['default']);
        }
    }]);

    return deepCamelClass;
})();

var deepCamel = new deepCamelClass();
exports['default'] = deepCamel;
module.exports = exports['default'];<commit_msg>Rebuild.<commit_after>/**
 * @author Maximilian Greschke <maximilian@veyo-care.com>
 */

'use strict';

Object.defineProperty(exports, '__esModule', {
    value: true
});

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new _errors.TypeError('Cannot call a class as a function'); } }

var _errors = require('./errors');

var _camelcase = require('camelcase');

var _camelcase2 = _interopRequireDefault(_camelcase);

var _decamelize = require('decamelize');

var _decamelize2 = _interopRequireDefault(_decamelize);

/**
 * Recursively changes all key values in a JS object to camelCase or decamelizes them.
 *
 * Does not work with arrays for obvious reasons.
 *
 * @param target - the object to be synchronized
 * @param source - the object to sync data from
 * @param overwrite - overwrites existing keys if true
 * @returns {{}}
 */

var deepCamelClass = (function () {
    function deepCamelClass() {
        _classCallCheck(this, deepCamelClass);
    }

    _createClass(deepCamelClass, [{
        key: 'applyToObjectKeys',
        value: function applyToObjectKeys(obj, func) {

            if (typeof obj !== 'object' || obj instanceof Array) {
                throw new _errors.TypeError('obj must be a object.');
            }

            for (var key in obj) {

                var newKey = func(key);
                var temp = obj[key];

                delete obj[key];
                obj[newKey] = temp;

                if (typeof obj[newKey] === 'object') {
                    obj[newKey] = this.applyToObjectKeys(obj[newKey], func);
                }
            }

            return obj;
        }
    }, {
        key: 'camelize',
        value: function camelize(obj) {
            return this.applyToObjectKeys(obj, _camelcase2['default']);
        }
    }, {
        key: 'decamelize',
        value: function decamelize(obj) {
            return this.applyToObjectKeys(obj, _decamelize2['default']);
        }
    }]);

    return deepCamelClass;
})();

var deepCamel = new deepCamelClass();
exports['default'] = deepCamel;
module.exports = exports['default'];<|endoftext|>


<commit_before>import DeepEqual from 'deep-equal';
import React from 'react';
import ReactDOM from 'react-dom';

import DOMUtils from '../utils/DOMUtils';

const METHODS_TO_BIND = ['updateDimensions'];

class CollapsingString extends React.Component {
  constructor() {
    super(...arguments);

    this.state = {
      collapsed: false,
      parentWidth: null,
      stringWidth: null
    };

    METHODS_TO_BIND.forEach((method) => {
      this[method] = this[method].bind(this);
    });
  }

  componentDidMount() {
    if (global.window != null) {
      window.addEventListener('resize', this.updateDimensions);
      window.addEventListener('focus', this.updateDimensions);
    }

    this.updateDimensions();
  }

  componentDidUpdate() {
    this.updateDimensions();
  }

  componentWillUnmount() {
    if (global.window != null) {
      window.removeEventListener('resize', this.updateDimensions);
      window.removeEventListener('focus', this.updateDimensions);
    }
  }

  shouldComponentUpdate(nextProps, nextState) {
    if (nextState.parentWidth === null) {
      return false;
    }

    return !DeepEqual(this.props, nextProps)
      || !DeepEqual(this.state, nextState);
  }

  getParentWidth() {
    let parent = null;
    let node = ReactDOM.findDOMNode(this);

    if (this.props.parentSelector != null) {
      parent = DOMUtils.closest(node, this.props.parentSelector);
    } else {
      parent = node.parentNode;
    }

    return DOMUtils.getComputedWidth(parent);
  }

  getStringWidth() {
    if (this.refs.fullString) {
      return DOMUtils.getComputedWidth(this.refs.fullString);
    }

    return null;
  }

  shouldCollapse(parentWidth, stringWidth) {
    if (parentWidth == null || stringWidth == null) {
      return false;
    }

    return stringWidth >= parentWidth;
  }

  updateDimensions() {
    let parentWidth = this.getParentWidth();

    // Return early if the string isn't collapsed and the parent is growing.
    if (this.state.parentWidth != null && parentWidth >= this.state.parentWidth
      && !this.state.collapsed) {
      return;
    }

    // Return early if the string is collapsed and the parent is shrinking.
    if (this.state.parentWidth != null && parentWidth <= this.state.parentWidth
      && this.state.collapsed) {
      return;
    }

    let stringWidth = null;

    if (this.refs.fullString != null) {
      stringWidth = this.getStringWidth();
    }

    this.setState({
      collapsed: this.shouldCollapse(parentWidth, stringWidth),
      parentWidth,
      stringWidth
    });
  }

  render() {
    let fullString = this.props.string;
    let stringEnding = null;

    if (this.state.collapsed) {
      stringEnding = (

          {fullString.substring(fullString.length - this.props.endLength)}

      );
    }

    return (

          {fullString}

            {fullString}

          {stringEnding}

    );
  }
}

CollapsingString.defaultProps = {
  endLength: 15,
  fullStringClassName: 'collapsing-string-full-string',
  truncatedStringEndClassName: 'collapsing-string-truncated-end',
  truncatedStringStartClassName: 'collapsing-string-truncated-start',
  truncatedWrapperClassName: 'collapsing-string-truncated-wrapper',
  wrapperClassName: 'collapsing-string'
};

CollapsingString.propTypes = {
  // The number of characters to keep visible at the end of the string.
  endLength: React.PropTypes.number,
  fullStringClassName: React.PropTypes.string,
  // The selector for the parent whose width should be referenced. By default,
  // the node's direct parent will be used.
  parentSelector: React.PropTypes.string,
  string: React.PropTypes.string.isRequired,
  truncatedStringEndClassName: React.PropTypes.string,
  truncatedStringStartClassName: React.PropTypes.string,
  truncatedWrapperClassName: React.PropTypes.string,
  wrapperClassName: React.PropTypes.string
};

module.exports = CollapsingString;
<commit_msg>Compare state first<commit_after>import DeepEqual from 'deep-equal';
import React from 'react';
import ReactDOM from 'react-dom';

import DOMUtils from '../utils/DOMUtils';

const METHODS_TO_BIND = ['updateDimensions'];

class CollapsingString extends React.Component {
  constructor() {
    super(...arguments);

    this.state = {
      collapsed: false,
      parentWidth: null,
      stringWidth: null
    };

    METHODS_TO_BIND.forEach((method) => {
      this[method] = this[method].bind(this);
    });
  }

  componentDidMount() {
    if (global.window != null) {
      window.addEventListener('resize', this.updateDimensions);
      window.addEventListener('focus', this.updateDimensions);
    }

    this.updateDimensions();
  }

  componentDidUpdate() {
    this.updateDimensions();
  }

  componentWillUnmount() {
    if (global.window != null) {
      window.removeEventListener('resize', this.updateDimensions);
      window.removeEventListener('focus', this.updateDimensions);
    }
  }

  shouldComponentUpdate(nextProps, nextState) {
    if (nextState.parentWidth === null) {
      return false;
    }

    return !DeepEqual(this.state, nextState)
      || !DeepEqual(this.props, nextProps);
  }

  getParentWidth() {
    let parent = null;
    let node = ReactDOM.findDOMNode(this);

    if (this.props.parentSelector != null) {
      parent = DOMUtils.closest(node, this.props.parentSelector);
    } else {
      parent = node.parentNode;
    }

    return DOMUtils.getComputedWidth(parent);
  }

  getStringWidth() {
    if (this.refs.fullString) {
      return DOMUtils.getComputedWidth(this.refs.fullString);
    }

    return null;
  }

  shouldCollapse(parentWidth, stringWidth) {
    if (parentWidth == null || stringWidth == null) {
      return false;
    }

    return stringWidth >= parentWidth;
  }

  updateDimensions() {
    let parentWidth = this.getParentWidth();

    // Return early if the string isn't collapsed and the parent is growing.
    if (this.state.parentWidth != null && parentWidth >= this.state.parentWidth
      && !this.state.collapsed) {
      return;
    }

    // Return early if the string is collapsed and the parent is shrinking.
    if (this.state.parentWidth != null && parentWidth <= this.state.parentWidth
      && this.state.collapsed) {
      return;
    }

    let stringWidth = null;

    if (this.refs.fullString != null) {
      stringWidth = this.getStringWidth();
    }

    this.setState({
      collapsed: this.shouldCollapse(parentWidth, stringWidth),
      parentWidth,
      stringWidth
    });
  }

  render() {
    let fullString = this.props.string;
    let stringEnding = null;

    if (this.state.collapsed) {
      stringEnding = (

          {fullString.substring(fullString.length - this.props.endLength)}

      );
    }

    return (

          {fullString}

            {fullString}

          {stringEnding}

    );
  }
}

CollapsingString.defaultProps = {
  endLength: 15,
  fullStringClassName: 'collapsing-string-full-string',
  truncatedStringEndClassName: 'collapsing-string-truncated-end',
  truncatedStringStartClassName: 'collapsing-string-truncated-start',
  truncatedWrapperClassName: 'collapsing-string-truncated-wrapper',
  wrapperClassName: 'collapsing-string'
};

CollapsingString.propTypes = {
  // The number of characters to keep visible at the end of the string.
  endLength: React.PropTypes.number,
  fullStringClassName: React.PropTypes.string,
  // The selector for the parent whose width should be referenced. By default,
  // the node's direct parent will be used.
  parentSelector: React.PropTypes.string,
  string: React.PropTypes.string.isRequired,
  truncatedStringEndClassName: React.PropTypes.string,
  truncatedStringStartClassName: React.PropTypes.string,
  truncatedWrapperClassName: React.PropTypes.string,
  wrapperClassName: React.PropTypes.string
};

module.exports = CollapsingString;
<|endoftext|>


<commit_before>//var root = "http://localhost:8080/";
//var root = "http://172.19.3.156:8080/";
window.onload= function() {
    var url = "../list";
    var success = function(data) {
        var items = data.data.items;
        var table =  $("<table>").addClass("list_table");
        var head = $("<thead>");
        table.append(head);
        var header = $("<tr>").addClass("header");
        header.append($("<th>").text("Name"));
        header.append($("<th>").text("QTY"));
        head.append(header);
        var body = $("<tbody>");
        table.append(body);
        items.forEach(function(it) {
            var row = $("<tr>");
            row.attr("ID",it.id);
            row.attr("stock",it.stock);
            var name = $("<td>").text(it.name);
            row.append(name);
            var qty = $("<td>").text(it.qty);
            row.append(qty);
            row.css("background-color","#ea8383");
            row.attr("Pressed","false");
            body.append(row);
        });
        $("#table").append(table)
        $("#table tbody tr").click(function(){
            if ($(this).attr("Pressed")=="true"){
                $(this).css("background-color","#ea8383");
                $(this).attr("Pressed","false");
            }else {
                $(this).css("background-color","#95e56e")
                $(this).attr("Pressed","true");
            }

        });
    }
    $.ajax({
        url: url,
        data: null,
        success: success,
        dataType: "json"
    });
}

var counter = 0;
function sendPurchased(){
   $(".list_table tr").each(function(){
        if ($(this).attr("Pressed")=="true"){
            var pur = $(this).children("td")[1].innerText;
            var url= "/stock?id=" +$(this).attr("id") + "&stock=" + (parseFloat($(this).attr("stock")) + parseFloat(pur));
            console.log(url);
            counter++;
            $.ajax({
                url: url,
                data: null,
                success: function(data){
                   if (data.code == 0) {
                       reload();
                       return;
                   } else {
                        console.log(data);
                   }
                },
                dataType: "json"
            });
        }
   });
}

function reload(){
    counter--;
    if (counter == 0){
        location.reload();
    }}
<commit_msg>dev-001<commit_after>//var root = "http://localhost:8080/";
//var root = "http://172.19.3.156:8080/";
window.onload= function() {
    var url = "../list";
    var success = function(data) {
        var items = data.data.items;
        var table =  $("<table>").addClass("list_table");
        var head = $("<thead>");
        table.append(head);
        var header = $("<tr>").addClass("header");
        header.append($("<th>").text("Name"));
        header.append($("<th>").text("QTY"));
        head.append(header);
        var body = $("<tbody>");
        table.append(body);
        items.forEach(function(it) {
            var row = $("<tr>");
            row.attr("ID",it.id);
            row.attr("stock",it.stock);
            var name = $("<td>").text(it.name);
            row.append(name);
            var qty = $("<td>");
            var input = $("<input>");
            input.attr("type","number");
            input.text(it.qty);
            input.click(function(e){e.stopPropagation();});
            qty.append(input);
            row.append(qty);
            row.css("background-color","#ea8383");
            row.attr("Pressed","false");
            body.append(row);
        });
        $("#table").append(table)
        $("#table tbody tr").click(function(){
            if ($(this).attr("Pressed")=="true"){
                $(this).css("background-color","#ea8383");
                $(this).attr("Pressed","false");
            }else {
                $(this).css("background-color","#95e56e")
                $(this).attr("Pressed","true");
            }

        });
    }
    $.ajax({
        url: url,
        data: null,
        success: success,
        dataType: "json"
    });
}

var counter = 0;
function sendPurchased(){
   $(".list_table tr").each(function(){
        if ($(this).attr("Pressed")=="true"){
            var pur = $(this).find('td:eq(1)').html();
            var url= "/stock?id=" +$(this).attr("id") + "&stock=" + (parseFloat($(this).attr("stock")) + parseFloat(pur));
            console.log(url);
            counter++;
            $.ajax({
                url: url,
                data: null,
                success: function(data){
                   if (data.code == 0) {
                       reload();
                       return;
                   } else {
                        console.log(data);
                   }
                },
                dataType: "json"
            });
        }
   });
}

function reload(){
    counter--;
    if (counter == 0){
        location.reload();
    }}
<|endoftext|>


<commit_before>(function($) {
	/**
	* Title: jQuery UI Vertical Scrollbar
	* Adds a vertical scrollbar to DOM object using jQuery UI
	*
	* Usage:
	*	$('.element').addScrollbar();
	*	$('.element').addScrollbar({location:""});
	*
	* Dependencies: jquery.ui, jquery.mousewheel
	* License:
	* 	Copyright (c) 2011 Patrick O'Toole
	*	Licensed Under the MIT/X-11 License
	* 	www.rickotoole.com
	*
	* Version: 0.0.1a -- rough draft
	**/

	$.fn.addScrollbar = function(user_options) {
		var defaultOptions = {
			toolbar : {
				location : "left",
				width: 10,
				margin: 2,
				background_color : "black",
				color : "grey",
				end_cap_size : 20,
				incrementSize : undefined,//25
				horizontalVisible : true
			},
			scrollDifference : 0,
			contentHeight : 0
		};
		defaultOptions.toolbar = MergeOptions(user_options)
		var options = defaultOptions;

		/**
		* Function: MergeOptions
		* Merges the default toolbar options with the user specified options
		* Parameters:
		* 	options - hash of user defined options
		*/
		function MergeOptions(options){
			return jQuery.extend(true,defaultOptions.toolbar,options);
		}

		/**
		* Function GenerateToolbar
		* Uses options.toolbar to create a DOM toolbar
		* Parameters: id - id of parent DOM object
		*/
		function GenerateToolbar(id) {
			var margin_l = (options.toolbar.location == "left") ? 0 : options.toolbar.margin;
			var margin_r = (options.toolbar.location == "right") ? 0 : options.toolbar.margin;

			var scroll_wrap = jQuery('

').css({
				"margin-right"	: margin_r,
				"margin-left"	: margin_l,
				"position"		: "relative",
				"float"			: options.toolbar.location
			}).attr('class','scrollbar_outer');
			var scroll_bar = jQuery('

').attr('class','scrollbar').slider({
				orientation: 'vertical',
				min:0,
				max:100,
				value:100,
				slide: function(event, ui) {
					var topValue = -((100-ui.value)*options.scrollDifference/100);
					$('#' + id + ' > .scroll_content_wrapper > .scroll_content').css({top:topValue});
				}
			}).css({
				"width"			: options.toolbar.width,
				"overflow"		: "visible",
				"border"		: "0px"
			});
			scroll_wrap.append(scroll_bar)
			return scroll_wrap;
		}

		/**
		* Function: GenerateWrappedContent
		* Creates an object with attributes specified in options.toolbar that
		* size the object such that if can be position next to the scroll wrapper.
		* Parameters: current_content - current, selected DOM object
		*/
		function GenerateWrappedContent(current_content) {
			var s_content = current_content.clone(true);
			jQuery(s_content).css({
				"position"	:"absolute",
				"left"		:0,
				"top"		:0,
//				"overflow-x": "visible"
			}).attr("class","scroll_content").removeAttr("id");

			jQuery(current_content).after(s_content);
			options.contentHeight = jQuery(s_content).height();
			jQuery(s_content).remove();

			var sc_wrap = jQuery('

').css({
				"position"	: "relative",
				"float"		: "left",
				'width'		: jQuery(current_content).width() - options.toolbar.width - options.toolbar.margin,
				'height'	: options.contentHeight,
				"overflow-y": "hidden",
//				'overflow-x': 'visible'
			}).addClass('scroll_content_wrapper');

			(!options.toolbar.horizontalVisible) ? sc_wrap.css({"overflow-x":"hidden"}) : null;
			sc_wrap.append(s_content);

			return sc_wrap;
		}

		/**
		* Function: GenerateScrollBackground
		* Creates background objects for scrollbar and handles clicks on background
		* Parameters:
		*	sliderMargin - height of background margin
		* 	id - id of parent DOM object
		*/
		function GenerateScrollBackground(sliderMargin,id) {
			var background = jQuery('

').attr('class','ui-widget-content');
			$('#' + id + ' >.scrollbar_outer').
				prepend(background.clone(true).addClass('scroll_top')).
				append(background.clone(true).addClass('scroll_bottom'));

			$('#' + id + ' > .scrollbar_outer > .scroll_top').click(function() {IncrementSlider(100,id);});
			$('#' + id + ' > .scrollbar_outer > .scroll_bottom').click(function() {IncrementSlider(-100,id);});
		}

		/**
		* Function: GenerateScrollEndcaps
		* Creates endcap objects for scrollbar, handles clicks, populates default content
		* Parameters:
		*	end_caps - height of end caps
		*	scrollStep - size of scrollbar movement
		* 	id - id of parent DOM object
		*/
		function GenerateScrollEndcaps(end_caps,scrollStep,id) {
			var arrow = jQuery('

').attr('class','ui-widget-content');
			$('#' + id + ' >.scrollbar_outer').
				prepend(arrow.clone(true).addClass('scroll_up')).
				append(arrow.clone(true).addClass('scroll_down'));

			$('#' + id + ' > .scrollbar_outer > .scroll_up').click(function() {IncrementSlider(scrollStep,id);});
			$('#' + id + ' > .scrollbar_outer > .scroll_down').click(function() {IncrementSlider(-scrollStep,id);});

			$('#' + id + ' > .scrollbar_outer > .scroll_up').html('↑').css({"text-align":"center","cursor":"default"});
			$('#' + id + ' > .scrollbar_outer > .scroll_down').html('↓').css({"text-align":"center","cursor":"default"});
		}

		/**
		* Function: GenerateMouseScrollControl
		* Creates controls to handle mousewheel scrolling
		* Parameters:
		*	scrollStep - size of scrollbar movement
		*	id - id of parent DOM object
		*/
		function GenerateMouseScrollControl(scrollStep,id) {
			$("#"+id).mousewheel(function(event, amount){
				if (
					(($('#' + id + ' > .scrollbar_outer > .scrollbar').slider("value") == 0 ) && (amount > 0)) ||
					(($('#' + id + ' > .scrollbar_outer > .scrollbar').slider("value") == 100 ) && (amount < 0)) ||
					(($('#' + id + ' > .scrollbar_outer > .scrollbar').slider("value") > 0 ) && ($('#' + id + ' > .scrollbar_outer >.scrollbar').slider("value") < 100 ))
					)
				{
					var multiplier = 50;
					IncrementSlider(amount*scrollStep,id);
					event.preventDefault();
				}
			});
		}

		/**
		* Function: GenerateTouchScrollControl
		* Creates controls to handle iOS style scrolling
		* Parameters: id - id of parent DOM object
		*/
		function GenerateTouchScrollControl(id) {
			$("#"+id).live('touchstart',function(start_event) {
				start_event.preventDefault();
				var original = this;
				var e = start_event.originalEvent;

				if (e.targetTouches.length != 1)
					return false;

				var previousY = e.targetTouches[0].clientY;
				var currentY = previousY;

				$("#"+id).live('touchmove',
					function(move_event) {
						var me = start_event.originalEvent;
						previousY = currentY;
						currentY = me.targetTouches[0].clientY;
						var deltaY = previousY - currentY;

						IncrementSlider(-deltaY,id);
						move_event.preventDefault();
					}
				);

				$("#"+id).live('touchend',
					function(end_event) {
						$("#"+id).die('touchmove');
						$("#"+id).die('touchend');
					}
				);
			});
		}

		/**
		* Function: IncrementSlider
		* Moves slider and corresponding content by specified amount
		* Parameters: step - increment size
		*/
		function IncrementSlider(step,id) {
			var slider_val = $('#' + id + ' > .scrollbar_outer > .scrollbar').slider("value");
			slider_val += step;
			$('#' + id + ' > .scrollbar_outer > .scrollbar').slider("value", slider_val);

			var top_val = ((100-slider_val)*options.scrollDifference)/100;
			(top_val < 0) ? top_val = 0 : undefined;
			(Math.abs(top_val)>options.scrollDifference) ? top_val = options.scrollDifference : undefined;

			$('#' + id + ' > .scroll_content_wrapper > .scroll_content').css({top:-top_val});

		}

		return this.each(function(index) {
			var c = jQuery(this),
				w = c.width(),h = c.height(),
				cl = c.attr("class"),
				id = c.attr("id") || "scrollable_content_" + index;

			var original_content = c.children('.scroll_content_wrapper').children('.scroll_content') || [];
			(original_content.length > 0) ? c.html(original_content.html()).removeAttr("style") : null;

			// Create div with current objects dimensions, styling
			var new_c = jQuery("

").
				attr("class",cl).
				attr("id",id).
				css({
					'position'	: 'relative',
					'overflow-y': 'hidden',
					'overflow-x': 'visible',
					'width'		: w,
					'height'	: h,
				});

			var scrollContentWrapper = GenerateWrappedContent(this);
			options.scrollDifference = options.contentHeight - h;

			if (options.scrollDifference > 0)
			{
				var toolbar = GenerateToolbar(id);

				new_c.append(toolbar);
				new_c.append(scrollContentWrapper);
				c.after(new_c);
				c.remove();

				var end_caps = options.toolbar.end_cap_size;
				var handle_h = (1-((options.contentHeight-h)/options.contentHeight))*h - end_caps*2;
				handle_h = (handle_h > options.toolbar.end_cap_size*2) ? handle_h : options.toolbar.end_cap_size*2;

				var sliderHeight 	= h - handle_h - end_caps*2;
				var sliderMargin 	= (h - sliderHeight)*0.5 - end_caps;
				sliderMargin = (sliderMargin > 0) ? sliderMargin : 0;
				var scrollStep = (options.toolbar.incrementSize) ? options.toolbar.incrementSize : parseInt(sliderHeight/5);
				var handle_border = parseInt($(".ui-slider-handle").css('border-top-width')) + parseInt($(".ui-slider-handle").css('border-bottom-width'));

				// Set positioning of SliderUI components
				$("#" + id + " .scrollbar_outer > .scrollbar > .ui-slider-handle").css({
					height	: handle_h - handle_border+"px",
					left	: 0,
					width	: options.toolbar.width-2,
					'margin-bottom':-0.5*handle_h
				});
				$("#" + id + " .scrollbar_outer > .ui-slider-vertical").css({
					height : sliderHeight,
					"border-radius": 0,
					"-moz-border-radius": 0
				});
			    $("#" + id + " .scrollbar_outer > .scrollbar > .ui-slider-range").css({top: -sliderMargin});

				GenerateScrollBackground(sliderMargin,id);
				(end_caps > 0) ? GenerateScrollEndcaps(end_caps,scrollStep,id) : null;
				jQuery.isFunction(jQuery.fn.mousewheel) ? GenerateMouseScrollControl(scrollStep,id,cl) : null;
				GenerateTouchScrollControl(id);
			}
			else
			{
				console.log(id);

			}

		});
	};
})(jQuery);<commit_msg>updates to structure, stubbed out secondary functions, added methods -- update to readme needed<commit_after>(function($) {
	/**
	* Title: jQuery UI Vertical Scrollbar
	* Adds a vertical scrollbar to DOM object using jQuery UI
	*
	* Usage:
	*	$('.element').scrollbar();
	*	$('.element').scrollbar("destroy");
	*	$('.element').scrollbar("refresh");
	*	$('.element').scrollbar("create",{location:"right"});
	*
	* Dependencies: jquery.ui, jquery.mousewheel
	* License:
	* 	Copyright (c) 2011 Patrick O'Toole
	*	Licensed Under the MIT/X-11 License
	* 	www.rickotoole.com
	*
	* Version: 0.0.1c
	**/

	var options;
	$.fn.scrollbar = function(method,user_options) {
		options = {
			scrollbar : $.extend({},user_options,$.fn.scrollbar.defaults),
			scrollDifference : 0,
			setContentHeight : function(content,place_after_object) {
				var height;
				place_after_object = place_after_object ? place_after_object : jQuery('body').children().first();
				jQuery(place_after_object).after(content);
				height = jQuery(content).outerHeight();
				jQuery(content).remove();

				this.contentHeight = height;
				return height;
			}
		}
		var handlers = {
			init : function (scrollStep,id) {
				this.clicks(scrollStep,id);
				this.mousewheel(scrollStep,id);
				this.touch(id);
			},
			/**
			* Function: handlers.clicks
			* Handles clicks which occur inside scrollbar wrapper. Specifically, endcap and background clicks.
			* Parameters:
			*	scrollStep - size of step
			* 	id - id of parent DOM object
			*/
			clicks : function (scrollStep,id) {
				var scrollDifference = (function (opt) {return opt.scrollDifference})(options);

				$.fn.scrollbar.click("up",id,scrollStep,scrollDifference);
				$.fn.scrollbar.click("down",id,scrollStep,scrollDifference);
				$.fn.scrollbar.click("top",id,scrollStep,scrollDifference);
				$.fn.scrollbar.click("bottom",id,scrollStep,scrollDifference);
			},
			/**
			* Function: handlers.mousewheel
			* Creates controls to handle mousewheel scrolling
			* Parameters:
			*	scrollStep - size for one wheel iteration
			*	id - id of parent DOM object
			*/
			mousewheel : function (scrollStep,id) {
				var scrollDifference = (function (opt) {return opt.scrollDifference})(options);
				$.fn.scrollbar.wheel(id,scrollStep,scrollDifference);
			},
			/**
			* Function: handlers.touch
			* Creates controls to handle iOS style scrolling
			* Parameters: id - id of parent DOM object
			*/
			touch : function (id) {
				var scrollDifference = (function (opt) {return opt.scrollDifference})(options);
				$.fn.scrollbar.touch(id,scrollDifference);
			}
		}
		var methods = {
			create : function () {
				return this.each(function(index) {
					options = $.extend(true,options,jQuery(this).data("scroll-options"));
					var c = jQuery(this),
						w = c.outerWidth(),
						h = c.outerHeight(),
						cl = c.attr("class"),
						id = c.attr("id") || (jQuery("scrollable_content_" + index).length > 0) ? "scrollable_content_" + index : "scrollable_content_" + cl;

					var scrollContentWrapper = WrapContent(this);
					options.scrollDifference = options.contentHeight - h;

					if (options.scrollDifference > 0)
					{
						// Create div with current objects dimensions, styling
						var scroll_slider = CreateSlider(id);
						var new_c = jQuery("

").attr("class",cl).attr("id",id).css({'position': 'relative','overflow-y': 'hidden','overflow-x':'visible','width': w,'height': h});

						new_c.append(scroll_slider);
						new_c.append(scrollContentWrapper);
						c.after(new_c);
						c.remove();

						SliderToScrollbar(id,h);
						GenerateScrollControls(id);
						new_c.data("scroll-options",options);
					}
					else
					{
						c.data("scroll-options",options);
					}
				});
			},
			refresh : function () {
				this.each(function() {
					RemoveScrollbar(jQuery(this));
				});
				return methods.create.call(this);
			},
			increment : function (step) {
				return this.each(function() {
					var $this = jQuery(this)
					var id = $this.attr("id")
					scrollDifference = $this.children(".scroll_content_wrapper").children(".scroll_content").height() - $this.height();
					$.fn.scrollbar.incrementSlider(step,id,scrollDifference);
				});
			},
			destroy : function () {
				return this.each(function(index) {
					RemoveScrollbar(jQuery(this));
				});
			}
		}

		/**
		* Function CreateSlider
		* Uses options.scrollbar to create a DOM scrollbar
		* Parameters: id - id of parent DOM object
		*/
		function CreateSlider(id) {
			var margin_l = (options.scrollbar.location == "left") ? 0 : options.scrollbar.margin;
			var margin_r = (options.scrollbar.location == "right") ? 0 : options.scrollbar.margin;
			var scrollDifference = (function(opt) {return opt.scrollDifference;})(options)

			// Create Scroll wrapper and slider
			var scroll_wrap = jQuery('

').css({"margin-right": margin_r,"margin-left": margin_l,"position": "relative","float": options.scrollbar.location}).attr('class','scrollbar_outer');
			var scroll_slider = jQuery('

').attr('class','scrollbar').slider({
				orientation: 'vertical',
				min:0,
				max:100,
				value:100,
				slide: function(event, ui) {
					var topValue = -((100-ui.value)*scrollDifference/100);
					$('#' + id + ' > .scroll_content_wrapper > .scroll_content').css({top:topValue});
				}
			}).css({"width": options.scrollbar.width,"overflow": "visible","border": "0px"});

			scroll_wrap.append(scroll_slider)
			return scroll_wrap;
		}

		/**
		* Function: WrapContent
		* Creates an object with attributes specified in options.scrollbar that
		* size the object such that if can be position next to the scroll wrapper.
		* Parameters: current_content - current, selected DOM object
		*/
		function WrapContent(current_content) {
			var s_content = jQuery(current_content).clone(true);
			jQuery(s_content).css({"position":"absolute","left":0,"top":0}).attr("class","scroll_content").removeAttr("id");

			options.setContentHeight(s_content,current_content);

			var sc_wrap = jQuery('

').css({
				"position"	: "relative",
				"float"		: "left",
				'width'		: jQuery(current_content).outerWidth() - options.scrollbar.width - options.scrollbar.margin,
				'height'	: options.contentHeight,
				"overflow-y": "hidden"
			}).addClass('scroll_content_wrapper');

			(!options.scrollbar.horizontalVisible) ? sc_wrap.css({"overflow-x":"hidden"}) : null;
			sc_wrap.append(s_content);

			return sc_wrap;
		}

		/**
		* Function: RemoveScrollbar
		* Removes scrollbar from div
		* Parameters: c - current jQuery object
		*/
		function RemoveScrollbar(c) {
			var original_content = c.children('.scroll_content_wrapper').children('.scroll_content') || [];
			if (original_content.length > 0) {
				c.html(original_content.html()).removeAttr("style");
				console.log(c.data());
				(c.attr("id").split("_")[0] = "scrollable") ? c.removeAttr("id") : null;
			}
		}

		/**
		* Function: SliderToScrollbar
		* Reformats the UI Slider to look like a scrollbar by adding endcaps, background
		* and changing the dimensions of the slider as specified in options.scrollbar and
		* applicable by the div dimensions.
		* Parameters:
		* 	id - id of wrapping object
		* 	h - height of wrapping object
		*/
		function SliderToScrollbar(id,h) {

			// Declare vars, set dimensions
			var end_caps = options.scrollbar.end_cap_size;
			var handle_h = (1-((options.contentHeight-h)/options.contentHeight))*h - end_caps*2;
			handle_h = (handle_h > options.scrollbar.end_cap_size*2) ? handle_h : options.scrollbar.end_cap_size*2;

			var sliderHeight = h - handle_h - end_caps*2;
			var sliderMargin = (h - sliderHeight)*0.5 - end_caps;
			sliderMargin = (sliderMargin > 0) ? sliderMargin : 0;
			var handle_border = parseInt($(".ui-slider-handle").css('border-top-width')) + parseInt($(".ui-slider-handle").css('border-bottom-width'));

			// Style scrollbar components
			var scroll_outer = $("#" + id + " .scrollbar_outer"),
				scroll_bar = scroll_outer.children(".scrollbar");

			scroll_outer.children(".ui-slider-vertical").css({height:sliderHeight,"border-radius":0,"-moz-border-radius":0});
			scroll_bar.children(".ui-slider-handle").css({height: handle_h - handle_border+"px",left: 0,width: options.scrollbar.width-2,'margin-bottom':-0.5*handle_h});
		    scroll_bar.children(".ui-slider-range").css({top: -sliderMargin});

			// Create scrollbar background
			var background = jQuery('

').attr('class','ui-widget-content');
			scroll_outer.prepend(background.clone(true).addClass('scroll_top'));
			scroll_outer.append(background.clone(true).addClass('scroll_bottom'));

			// Create scrollbar endcaps
			if (end_caps > 0)
			{
				var arrow = jQuery('

').attr('class','ui-widget-content');
				scroll_outer.prepend(arrow.clone(true).addClass('scroll_up'));
				scroll_outer.append(arrow.clone(true).addClass('scroll_down'));
				scroll_outer.children('.scroll_up').html('↑').css({"text-align":"center","cursor":"default"});
				scroll_outer.children('.scroll_down').html('↓').css({"text-align":"center","cursor":"default"});
			}
		}

		function GenerateScrollControls(id) {
			var scrollbar_v = $("#" + id + " .scrollbar_outer > .ui-slider-vertical");
			options.scrollbar.incrementSize = (options.scrollbar.incrementSize) ? options.scrollbar.incrementSize : parseInt(scrollbar_v.height()/5);
			handlers.init(options.scrollbar.incrementSize,id);
		}

		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		} else if (typeof method === 'object' || !method) {
			options.scrollbar = $.extend({},$.fn.scrollbar.defaults,method);
			return methods.create.apply(this, arguments);
		} else {
			$.error('Method ' +  method + ' does not exist');
		}
	};

	$.fn.scrollbar.defaults = {
		location : "left",
		width: 10,
		margin: 2,
		end_cap_size : 20,
		incrementSize : undefined,
		horizontalVisible : true
	};

	/**
	* Function: $.fn.scrollbar.incrementSlider
	* Moves slider and corresponding content by specified amount
	* Parameters:
	*	step - increment size
	*	id  - id of wrapping object
	*	scrollDifference - total distance scrollbar can travel
	*/
	$.fn.scrollbar.incrementSlider = function(step,id,scrollDifference) {
		console.log(scrollDifference);
		var scroll_bar = $('#' + id + ' > .scrollbar_outer > .scrollbar');
		var slider_val = scroll_bar.slider("value");

		slider_val += step;
		scroll_bar.slider("value", slider_val);

		var top_val = ((100-slider_val)*scrollDifference)/100;
		(top_val < 0) ? top_val = 0 : undefined;
		(Math.abs(top_val) > scrollDifference) ? top_val = scrollDifference : undefined;

		$('#' + id + ' > .scroll_content_wrapper > .scroll_content').css({top:-top_val});
	};
	$.fn.scrollbar.click = function (type,id,scrollStep,scrollDifference) {
		$.fn.scrollbar.click.types[type] (id,scrollStep,scrollDifference);
	};
	$.fn.scrollbar.click.types = {
		up : function (id,scrollStep,scrollDifference) {
			$("#" + id + " .scrollbar_outer").children('.scroll_up').click(
				function() {$.fn.scrollbar.incrementSlider(scrollStep,id,scrollDifference);});
		},
		down : function (id,scrollStep,scrollDifference) {
			$("#" + id + " .scrollbar_outer").children('.scroll_down').click(
				function() {$.fn.scrollbar.incrementSlider(-scrollStep,id,scrollDifference);});
		},
		top : function (id,scrollStep,scrollDifference) {
			$("#" + id + " .scrollbar_outer").children('.scroll_top').click(
				function() {$.fn.scrollbar.incrementSlider(100,id,scrollDifference);});
		},
		bottom : function (id,scrollStep,scrollDifference) {
			$("#" + id + " .scrollbar_outer").children('.scroll_bottom').click(
				function() {$.fn.scrollbar.incrementSlider(-100,id,scrollDifference);});
		}
	};
	$.fn.scrollbar.wheel = function (id,scrollStep,scrollDifference) {
		if (jQuery.isFunction(jQuery.fn.mousewheel)) {
			$("#"+id).mousewheel(function(event, amount){
				var slider_value = $('#' + id + ' > .scrollbar_outer > .scrollbar').slider("value");

				if (((slider_value == 0 ) && (amount > 0)) || ((slider_value == 100 ) && (amount < 0)) ||((slider_value > 0 ) && (slider_value < 100 )))
				{
					var multiplier = 50;
					$.fn.scrollbar.incrementSlider(amount*scrollStep,id,scrollDifference);
					event.preventDefault();
				}
			});
		}
	};
	$.fn.scrollbar.touch = function (id,scrollDifference) {
		$("#"+id).live('touchstart',function(start_event) {

			var original = this;
			var e = start_event.originalEvent;

			if (e.targetTouches.length != 1)
				return false;

			var previousY = e.targetTouches[0].clientY;
			var currentY = previousY;
			var isClick = true;

			$("#"+id).live('touchmove',
				function(move_event) {
					isClick = false;
					var me = start_event.originalEvent;
					previousY = currentY;
					currentY = me.targetTouches[0].clientY;
					var deltaY = previousY - currentY;

					$.fn.scrollbar.incrementSlider(-deltaY,id,scrollDifference);
					move_event.preventDefault();
				}
			);

			$("#"+id).live('touchend',
				function(end_event) {
					$("#"+id).die('touchmove');
					$("#"+id).die('touchend');

					var end_e = end_event.originalEvent;
					var touch_point = end_e.targetTouches[0] || e.targetTouches[0];

					// Propagate mouse click event
					mouse_click = document.createEvent('MouseEvent');
					if (isClick === true)
					{
						mouse_click.initMouseEvent('click',true,true,touch_point.view,1,touch_point.screenX,touch_point.screenY,touch_point.clickX,touch_point.clientY, false, false, false, false, 0, null);
						touch_point.target.dispatchEvent(mouse_click);
					}

				}
			);
			start_event.preventDefault();
		});
	}

})(jQuery);<|endoftext|>


<commit_before>function buildDocs() {

	console.log('Building Leaflet documentation with Leafdoc ...');

	var LeafDoc = require('leafdoc');
	var doc = new LeafDoc({
		templateDir: 'build/leafdoc-templates',
		showInheritancesWhenEmpty: true,
		leadingCharacter: '@'
	});

	// Note to Vladimir: Iván's never gonna uncomment the following line. He's
	// too proud of the little leaves around the code.
	// doc.setLeadingChar('@');

	// Leaflet uses a couple of non-standard documentable things. They are not
	// important enough to be classes/namespaces of their own, and should
	// just be listed in a table like the rest of documentables:
	doc.registerDocumentable('pane', 'Map panes');
	doc.registerDocumentable('projection', 'Defined projections');
	doc.registerDocumentable('crs', 'Defined CRSs');

	doc.addFile('build/docs-index.leafdoc', false);
	doc.addDir('src');
	doc.addFile('build/docs-misc.leafdoc', false);

	var out = doc.outputStr();
	var path = 'docs/reference.html';

	var fs = require('fs');

	fs.writeFileSync(path, out);
	console.log('Successfully built ' + path);
}

if (require.main === module) {
	buildDocs();
} else {
	module.exports = buildDocs;
}
<commit_msg>simplify build/docs.js<commit_after>console.log('Building Leaflet documentation with Leafdoc ...');

var LeafDoc = require('leafdoc');
var doc = new LeafDoc({
	templateDir: 'build/leafdoc-templates',
	showInheritancesWhenEmpty: true,
	leadingCharacter: '@'
});

// Note to Vladimir: Iván's never gonna uncomment the following line. He's
// too proud of the little leaves around the code.
// doc.setLeadingChar('@');

// Leaflet uses a couple of non-standard documentable things. They are not
// important enough to be classes/namespaces of their own, and should
// just be listed in a table like the rest of documentables:
doc.registerDocumentable('pane', 'Map panes');
doc.registerDocumentable('projection', 'Defined projections');
doc.registerDocumentable('crs', 'Defined CRSs');

doc.addFile('build/docs-index.leafdoc', false);
doc.addDir('src');
doc.addFile('build/docs-misc.leafdoc', false);

var out = doc.outputStr();
var path = 'docs/reference.html';

var fs = require('fs');

fs.writeFileSync(path, out);
console.log('Successfully built ' + path);
<|endoftext|>


<commit_before>const raf = require('raf')
const create = require('virtual-dom/create-element')
const diff = require('virtual-dom/diff')
const patch = require('virtual-dom/patch')
const VText = require('virtual-dom/vnode/vtext')
const virtualize = require('vdom-virtualize')

// hack for virtual-dom trying to set contentEditable to ''
const removeContentEditable = (vnode) => {
  if (vnode.properties != null)
    delete ref.contentEditable
  if (!vnode.children) return
  for (let node of vnode.children)
    removeContentEditable(node)
}

module.exports = (component, state, params, hub, parent, options) => {
  let time = (description, cb) => cb()
  if ((options != null ? options.hub : void 0) != null) {
    time = function(description, cb) {
      var endedAt, startedAt
      startedAt = new Date().getTime()
      cb()
      endedAt = new Date().getTime()
      return options.hub.emit('Odo.js {description} in {duration}ms', {
        description: description,
        startedAt: startedAt,
        endedAt: endedAt,
        duration: endedAt - startedAt
      })
    }
  }
  status = 'init'
  tree = null
  target = null
  time('scene created', function() {
    return tree = component(state, params, hub)
  })
  status = 'idle'
  apply = function(state, params, hub) {
    if (status === 'rendering') {
      throw new Error('Mutant rampage')
    }
    status = 'rendering'
    time('scene updated', function() {
      var newTree, patches
      newTree = component(state, params, hub)
      patches = diff(tree, newTree)
      target = patch(target, patches)
      return tree = newTree
    })
    return status = 'idle'
  }
  payload = null
  return {
    target: function() {
      return target
    },
    status: function() {
      return status
    },
    mount: function() {
      var existing, patches
      existing = virtualize(parent)
      removeContentEditable(existing)
      patches = diff(existing, tree)
      return target = patch(parent, patches)
    },
    update: function(state, params, hub) {
      if (status === 'rendering') {
        throw new Error('Mutant rampage')
      }
      // pending apply, update state and params
      if (status === 'pending') {
        payload = {
          state: state,
          params: params,
          hub: hub
        }
        return
      }
      // wait for animation frame to apply
      if (status === 'idle') {
        status = 'pending'
        payload = {
          state: state,
          params: params,
          hub: hub
        }
        return raf(function() {
          // have already applied the state
          if (payload === null) {
            return
          }
          apply(payload.state, payload.params, payload.hub)
          return payload = null
        })
      }
    },
    apply: apply,
    unmount: function() {
      // patch against nothing for unmount
      return patch(target, diff(tree, new VText('')))
    }
  }
}
<commit_msg>fixed ref<commit_after>const raf = require('raf')
const create = require('virtual-dom/create-element')
const diff = require('virtual-dom/diff')
const patch = require('virtual-dom/patch')
const VText = require('virtual-dom/vnode/vtext')
const virtualize = require('vdom-virtualize')

// hack for virtual-dom trying to set contentEditable to ''
const removeContentEditable = (vnode) => {
  if (vnode.properties != null)
    delete vnode.properties.contentEditable
  if (!vnode.children) return
  for (let node of vnode.children)
    removeContentEditable(node)
}

module.exports = (component, state, params, hub, parent, options) => {
  let time = (description, cb) => cb()
  if ((options != null ? options.hub : void 0) != null) {
    time = function(description, cb) {
      var endedAt, startedAt
      startedAt = new Date().getTime()
      cb()
      endedAt = new Date().getTime()
      return options.hub.emit('Odo.js {description} in {duration}ms', {
        description: description,
        startedAt: startedAt,
        endedAt: endedAt,
        duration: endedAt - startedAt
      })
    }
  }
  status = 'init'
  tree = null
  target = null
  time('scene created', function() {
    return tree = component(state, params, hub)
  })
  status = 'idle'
  apply = function(state, params, hub) {
    if (status === 'rendering') {
      throw new Error('Mutant rampage')
    }
    status = 'rendering'
    time('scene updated', function() {
      var newTree, patches
      newTree = component(state, params, hub)
      patches = diff(tree, newTree)
      target = patch(target, patches)
      return tree = newTree
    })
    return status = 'idle'
  }
  payload = null
  return {
    target: function() {
      return target
    },
    status: function() {
      return status
    },
    mount: function() {
      var existing, patches
      existing = virtualize(parent)
      removeContentEditable(existing)
      patches = diff(existing, tree)
      return target = patch(parent, patches)
    },
    update: function(state, params, hub) {
      if (status === 'rendering') {
        throw new Error('Mutant rampage')
      }
      // pending apply, update state and params
      if (status === 'pending') {
        payload = {
          state: state,
          params: params,
          hub: hub
        }
        return
      }
      // wait for animation frame to apply
      if (status === 'idle') {
        status = 'pending'
        payload = {
          state: state,
          params: params,
          hub: hub
        }
        return raf(function() {
          // have already applied the state
          if (payload === null) {
            return
          }
          apply(payload.state, payload.params, payload.hub)
          return payload = null
        })
      }
    },
    apply: apply,
    unmount: function() {
      // patch against nothing for unmount
      return patch(target, diff(tree, new VText('')))
    }
  }
}
<|endoftext|>


<commit_before>/* global gl, Flash */
/* eslint-disable no-param-reassign */

((gl) => {
  gl.PipelineStore = class {
    fetchDataLoop(Vue, pageNum, url) {
      const setVueResources = () => { Vue.activeResources = 1; };
      const resetVueResources = () => { Vue.activeResources = 0; };
      const addToVueResources = () => { Vue.activeResources += 1; };
      const subtractFromVueResources = () => { Vue.activeResources -= 1; };

      resetVueResources();

      const updatePipelineNums = (count) => {
        const { all } = count;
        const running = count.running_or_pending;
        document.querySelector('.js-totalbuilds-count').innerHTML = all;
        document.querySelector('.js-running-count').innerHTML = running;
      };

      const resourceChecker = () => {
        if (Vue.activeResources === 0) {
          setVueResources();
        } else {
          addToVueResources();
        }
      };

      const goFetch = () =>
        this.$http.get(`${url}?page=${pageNum}`)
          .then((response) => {
            const res = JSON.parse(response.body);
            Vue.set(this, 'updatedAt', res.updated_at);
            Vue.set(this, 'pipelines', res.pipelines);
            Vue.set(this, 'count', res.count);
            updatePipelineNums(this.count);
            this.pageRequest = false;
            subtractFromVueResources();
          }, () => new Flash(
            'Something went wrong on our end.',
          ));

      resourceChecker();
      goFetch();

      const removePipelineInterval = () => {
        this.allTimeIntervals.forEach(e => clearInterval(e.id));
      };

      const startIntervalLoops = () => {
        this.allTimeIntervals.forEach(e => e.start());
      };

      window.onbeforeunload = function onClose() {
        removePipelineInterval();
      };

      window.onblur = function remove() {
        removePipelineInterval();
      };

      window.onfocus = function start() {
        startIntervalLoops();
      };
    }
  };
})(window.gl || (window.gl = {}));
<commit_msg>deal with preventing DDOS<commit_after>/* global gl, Flash */
/* eslint-disable no-param-reassign */

((gl) => {
  gl.PipelineStore = class {
    fetchDataLoop(Vue, pageNum, url) {
      const setVueResources = () => { Vue.activeResources = 1; };
      const resetVueResources = () => { Vue.activeResources = 0; };
      const addToVueResources = () => { Vue.activeResources += 1; };
      const subtractFromVueResources = () => { Vue.activeResources -= 1; };

      resetVueResources();

      const updatePipelineNums = (count) => {
        const { all } = count;
        const running = count.running_or_pending;
        document.querySelector('.js-totalbuilds-count').innerHTML = all;
        document.querySelector('.js-running-count').innerHTML = running;
      };

      const resourceChecker = () => {
        if (Vue.activeResources === 0) {
          setVueResources();
        } else {
          addToVueResources();
        }
      };

      const goFetch = () =>
        this.$http.get(`${url}?page=${pageNum}`)
          .then((response) => {
            const res = JSON.parse(response.body);
            Vue.set(this, 'updatedAt', res.updated_at);
            Vue.set(this, 'pipelines', res.pipelines);
            Vue.set(this, 'count', res.count);
            updatePipelineNums(this.count);
            this.pageRequest = false;
            subtractFromVueResources();
          }, () => new Flash(
            'Something went wrong on our end.',
          ));

      resourceChecker();
      goFetch();

      const removePipelineIntervals = () => {
        this.allTimeIntervals.forEach(e => clearInterval(e.id));
      };

      const startIntervalLoops = () => {
        this.allTimeIntervals.forEach(e => e.start());
      };

      const removeAll = () => {
        removePipelineIntervals();
        window.removeEventListener('beforeunload', () => {});
        window.removeEventListener('focus', () => {});
        window.removeEventListener('blur', () => {});
        document.removeEventListener('page:fetch', () => {});
      };

      window.addEventListener('beforeunload', removePipelineIntervals);
      window.addEventListener('focus', startIntervalLoops);
      window.addEventListener('blur', removePipelineIntervals);
      document.addEventListener('page:fetch', removeAll);
    }
  };
})(window.gl || (window.gl = {}));
<|endoftext|>


<commit_before>define([
	"dojo/_base/declare", "dojo/_base/lang", "dojo/on", "dojo/topic",
	"dijit/popup", "dijit/TooltipDialog",
	"./TranscriptomicsGeneGrid", "./GridContainer"
], function(declare, lang, on, Topic,
			popup, TooltipDialog,
			TranscriptomicsGeneGrid, GridContainer){

	return declare([GridContainer], {
		gridCtor: TranscriptomicsGeneGrid,
		containerType: "transcriptomics_gene_data",
		facetFields: [],
		enableFilterPanel: false,
		constructor: function(){
			var self = this;
			Topic.subscribe("TranscriptomicsGene", lang.hitch(self, function(){
				var key = arguments[0], value = arguments[1];

				switch(key){
					case "updateTgState":
						self.tgState = value;
						break;
					default:
						break;
				}
			}));
		},
		buildQuery: function(){
			// prevent further filtering. DO NOT DELETE
		},
		_setQueryAttr: function(query){
			//block default query handler for now.
		},
		_setStateAttr: function(state){
			this.inherited(arguments);
			if(!state){
				return;
			}
			// console.log("TranscriptomicsGeneGridContainer _setStateAttr: ", state);
			if(this.grid){
				// console.log("   call set state on this.grid: ", this.grid);
				this.grid.set('state', state);
			}else{
				console.log("No Grid Yet (TranscriptomicsGeneGridContainer)");
			}

			this._set("state", state);
		}
	});
});
<commit_msg>hide console.log<commit_after>define([
	"dojo/_base/declare", "dojo/_base/lang", "dojo/on", "dojo/topic",
	"dijit/popup", "dijit/TooltipDialog",
	"./TranscriptomicsGeneGrid", "./GridContainer"
], function(declare, lang, on, Topic,
			popup, TooltipDialog,
			TranscriptomicsGeneGrid, GridContainer){

	return declare([GridContainer], {
		gridCtor: TranscriptomicsGeneGrid,
		containerType: "transcriptomics_gene_data",
		facetFields: [],
		enableFilterPanel: false,
		constructor: function(){
			var self = this;
			Topic.subscribe("TranscriptomicsGene", lang.hitch(self, function(){
				var key = arguments[0], value = arguments[1];

				switch(key){
					case "updateTgState":
						self.tgState = value;
						break;
					default:
						break;
				}
			}));
		},
		buildQuery: function(){
			// prevent further filtering. DO NOT DELETE
		},
		_setQueryAttr: function(query){
			//block default query handler for now.
		},
		_setStateAttr: function(state){
			this.inherited(arguments);
			if(!state){
				return;
			}
			// console.log("TranscriptomicsGeneGridContainer _setStateAttr: ", state);
			if(this.grid){
				// console.log("   call set state on this.grid: ", this.grid);
				this.grid.set('state', state);
			}else{
				// console.log("No Grid Yet (TranscriptomicsGeneGridContainer)");
			}

			this._set("state", state);
		}
	});
});
<|endoftext|>


<commit_before>var ejs = require('./ejs.js');
var lf = require('./lfcli.js');

/**
 * Takes care of retrieving data for and rendering the
 * suggestion page.
 *
 * @param state The state object of the current HTTP-Request
 */
exports.show = function(state) {
	// configuration stuff
	var OPINIONS_PER_PAGE = 4;

	// we need a valid user session...
	if(!state.session_key()) {
		state.sendToLogin();
		return;
	}

	var suggestion_id = state.url.query.suggestion_id;

	// the variables to that will be set by the data retrievers
	// and if set the page will be rendered
	var suggestion_info, opinions_info, my_opinion_info, paging_info;

	var finish = function() {
		var ctx = state.context;

		if(suggestion_info !== undefined && opinions_info !== undefined && my_opinion_info !== undefined && paging_info !== undefined) {
			ctx.suggestion = suggestion_info;
			suggestion_info.opinions = opinions_info;
			suggestion_info.isayimplemented = my_opinion_info.i_say_implemented;
			suggestion_info.smiley = my_opinion_info.smiley;
			suggestion_info.my_opinion = my_opinion_info.opinion;
			suggestion_info.opinionpage = paging_info.opinionpage;
			suggestion_info.opinionpages = paging_info.opinionpages;

			ctx.meta.currentpage = "suggestion";
			ejs.render(state, '/suggestion.tpl');
		}
	}

	// get the initiative
	lf.query('/suggestion', { 'suggestion_id': suggestion_id, 'include_initiatives': true }, state, function(res) {
		console.log(JSON.stringify(res));
		var suggestion_res = res.result[0];
		console.log('SUGGESTION: ' + JSON.stringify(suggestion_res));
		var initiative = res.initiatives[suggestion_res.initiative_id];
		console.log('INITIATIVE: ' + JSON.stringify(initiative));

		var total_supporters = initiative.supporter_count;

		var tmp_suggestion = {
			initiative: {
				name: initiative.name
			},
			name: suggestion_res.name,
			text: suggestion_res.content,

			mustsupporter: suggestion_res.plus2_unfulfilled_count + suggestion_res.plus2_fulfilled_count,
			shouldsupporter: suggestion_res.plus1_unfulfilled_count + suggestion_res.plus1_fulfilled_count,
			neutralsupporter: total_supporters
			                  - (suggestion_res.plus2_unfulfilled_count + suggestion_res.plus2_fulfilled_count)
			                  - (suggestion_res.plus1_unfulfilled_count + suggestion_res.plus1_fulfilled_count)
			                  - (suggestion_res.minus2_unfulfilled_count + suggestion_res.minus2_fulfilled_count)
			                  - (suggestion_res.minus1_unfulfilled_count + suggestion_res.minus1_fulfilled_count),
			shouldnotsupporter: suggestion_res.minus1_unfulfilled_count + suggestion_res.minus1_fulfilled_count,
			mustnotsupporter: suggestion_res.minus2_unfulfilled_count + suggestion_res.minus2_fulfilled_count,

			notimplementedmustsupporter: suggestion_res.plus2_unfulfilled_count,
			notimplementedshouldsupporter: suggestion_res.plus1_unfulfilled_count,
			notimplementedshouldnotsupporter: suggestion_res.minus1_unfulfilled_count,
			notimplementedmustnotsupporter: suggestion_res.minus2_unfulfilled_count,

			implementedmustsupporter: suggestion_res.plus2_fulfilled_count,
			implementedshouldsupporter: suggestion_res.plus1_fulfilled_count,
			implementedshouldnotsupporter: suggestion_res.minus1_fulfilled_count,
			implementedmustnotsupporter: suggestion_res.minus2_fulfilled_count,
		};
		notimplementedneutralsupporter = tmp_suggestion.neutralsupporter;
		implementedneutralsupporter = tmp_suggestion.neutralsupporter;

		tmp_suggestion.mustsupportwidth = tmp_suggestion.mustsupporter * 100 / total_supporters + "%";
		tmp_suggestion.shouldsupportwidth = tmp_suggestion.shouldsupporter * 100 / total_supporters + "%";
		tmp_suggestion.neutralsupportwidth = tmp_suggestion.neutralsupporter * 100 / total_supporters + "%";
		tmp_suggestion.shouldnotsupportwidth = tmp_suggestion.shouldnotsupporter * 100 / total_supporters + "%";
		tmp_suggestion.mustnotsupportwidth = tmp_suggestion.mustnotsupporter * 100 / total_supporters + "%";

		tmp_suggestion.notimplementedmustsupportwidth = tmp_suggestion.notimplementedmustsupporter * 100 / total_supporters + "%";
		tmp_suggestion.notimplementedshouldsupportwidth = tmp_suggestion.notimplementedshouldsupporter * 100 / total_supporters + "%";
		tmp_suggestion.notimplementedneutralsupportwidth = tmp_suggestion.notimplementedneutralsupporter * 100 / total_supporters + "%";
		tmp_suggestion.notimplementedshouldnotsupportwidth = tmp_suggestion.notimplementedshouldnotsupporter * 100 / total_supporters + "%";
		tmp_suggestion.notimplementedmustnotsupportwidth = tmp_suggestion.notimplementedmustnotsupporter * 100 / total_supporters + "%";
		tmp_suggestion.implementedmustsupportwidth = tmp_suggestion.notimplementedmustsupporter * 100 / total_supporters + "%";
		tmp_suggestion.implementedshouldsupportwidth = tmp_suggestion.notimplementedshouldsupporter * 100 / total_supporters + "%";
		tmp_suggestion.implementedneutralsupportwidth = tmp_suggestion.notimplementedneutralsupporter * 100 / total_supporters + "%";
		tmp_suggestion.implementedshouldnotsupportwidth = tmp_suggestion.notimplementedshouldnotsupporter * 100 / total_supporters + "%";
		tmp_suggestion.implementedmustnotsupportwidth = tmp_suggestion.notimplementedmustnotsupporter * 100 / total_supporters + "%";

		// add author info
		lf.query('/member', { 'member_id': suggestion_res.author_id }, state, function(res) {
			var author = res.result[0];
			console.log("AUTHOR: " + JSON.stringify(author));

			tmp_suggestion.author = {
				nick: author.name,
				name: author.realname || author.name,
				picsmall: "avatar/" + author.id,
				picmini: "picbig/" + author.id
			}

			suggestion_info = tmp_suggestion;
			finish();
		});
	});

	lf.query('/opinion', { 'suggestion_id': suggestion_id }, state, function(res) {
		var lf_opinions = res.result;

		/**
		 * Calculate the hapiness smiley for the given opinion.
		 * Result is 1 for very happy, 4 for very unhappy
		 */
		var calculate_smiley = function(lf_opinion) {
			var smiley = 1; // if degree == 0 we don't care, so we are happy
			if(lf_opinion.degree !== 0) {
				// renormalize (map to 0...4 and then to 1...4)
				smiley = lf_opinion.degree + 2;
				if(smiley < 2) {
					smiley += 2;
				}
				// if fullfilled highest value is happy
				if(lf_opinion.fulfilled) {
					smiley = 5 - smiley;
				}
			}
			return smiley;
		}

		console.log('OPINIONS:' + JSON.stringify(res));
		tmp_my_opinion = {
			i_say_implemented: false,
			smiley: 1,
			opinion: 0
		};
		var members_to_resolve = '';

		paging_info = function() {
			var tmp = {
				opinionpages: Math.floor(lf_opinions.length / OPINIONS_PER_PAGE) + 1,
				opinionpage: state.url.query.opinionpage || 1
			}
			if(tmp.opinionpage < 1 || tmp.opinionpage > tmp.opinionpages) {
				console.log('WARNING: Opinion page ' + tmp.opinionpage + ' requested, but only pages 1 to ' + tmp.opinionpages + ' valid for suggestion ' + suggestion_id);
				tmp.opinionpage = 1;
			}
			return tmp;
		}();
		console.log('PAGING INFO ' + JSON.stringify(paging_info));

		for(var i = OPINIONS_PER_PAGE * (paging_info.opinionpage - 1); i < lf_opinions.length && i < OPINIONS_PER_PAGE * (paging_info.opinionpage); i++) {
			var lf_opinion = lf_opinions[i];
			if(lf_opinion.member_id == state.user_id()) {
				tmp_my_opinion.i_say_implemented = lf_opinion.fulfilled;
				tmp_my_opinion.smiley = calculate_smiley(lf_opinion);
				tmp_my_opinion.opinion = lf_opinion.degree;
			}

			if(members_to_resolve != '') {
				members_to_resolve += ',';
			}
			members_to_resolve += lf_opinion.member_id;
		}
		my_opinion_info = tmp_my_opinion;

		lf.query('/member', { 'member_id': members_to_resolve }, state, function(res) {
			var i;
			var lf_member;
			var lf_members = res.result;
			var lf_members_by_id = {};
			for(i = 0; i < lf_members.length; i++) {
				lf_member = lf_members[i];
				lf_members_by_id[lf_member.id] = lf_member;
			}

			var tmp_opinion;
			var tmp_opinions = [];

			var calculate_action = function(lf_opinion) {
				switch(lf_opinion.degree) {
					case -2:
					case -1:
						return 'against';
					case 1:
					case 2:
						return 'for';
					default:
						return '';
				}
			};

		for(var i = OPINIONS_PER_PAGE * (paging_info.opinionpage - 1); i < lf_opinions.length && i < OPINIONS_PER_PAGE * (paging_info.opinionpage); i++) {
				lf_opinion = lf_opinions[i];
				// TODO filter own opinion
				console.log('LF OPINION: ' + JSON.stringify(lf_opinion));
				lf_member = lf_members_by_id[lf_opinion.member_id];
				console.log('LF member: ' + JSON.stringify(lf_member));
				tmp_opinion = {
					user: {
						nick: lf_member.name,
						name: lf_member.realname,
						picsmall: 'avatar/' + lf_member.id,
						picmini: 'avatar/' + lf_member.id
					},
					action: calculate_action(lf_opinion),
					implemented: lf_opinion.fulfilled,
					smiley: calculate_smiley(lf_opinion)
				}
				tmp_opinions.push(tmp_opinion);
			}
			opinions_info = tmp_opinions;

			finish();
		});
	});
}
<commit_msg>Don't show on opinion in opinions box on suggestion screen<commit_after>var ejs = require('./ejs.js');
var lf = require('./lfcli.js');

/**
 * Takes care of retrieving data for and rendering the
 * suggestion page.
 *
 * @param state The state object of the current HTTP-Request
 */
exports.show = function(state) {
	// configuration stuff
	var OPINIONS_PER_PAGE = 4;

	// we need a valid user session...
	if(!state.session_key()) {
		state.sendToLogin();
		return;
	}

	var suggestion_id = state.url.query.suggestion_id;

	// the variables to that will be set by the data retrievers
	// and if set the page will be rendered
	var suggestion_info, opinions_info, my_opinion_info, paging_info;

	var finish = function() {
		var ctx = state.context;

		if(suggestion_info !== undefined && opinions_info !== undefined && my_opinion_info !== undefined && paging_info !== undefined) {
			ctx.suggestion = suggestion_info;
			suggestion_info.opinions = opinions_info;
			suggestion_info.isayimplemented = my_opinion_info.i_say_implemented;
			suggestion_info.smiley = my_opinion_info.smiley;
			suggestion_info.my_opinion = my_opinion_info.opinion;
			suggestion_info.opinionpage = paging_info.opinionpage;
			suggestion_info.opinionpages = paging_info.opinionpages;

			ctx.meta.currentpage = "suggestion";
			ejs.render(state, '/suggestion.tpl');
		}
	}

	// get the initiative
	lf.query('/suggestion', { 'suggestion_id': suggestion_id, 'include_initiatives': true }, state, function(res) {
		console.log(JSON.stringify(res));
		var suggestion_res = res.result[0];
		console.log('SUGGESTION: ' + JSON.stringify(suggestion_res));
		var initiative = res.initiatives[suggestion_res.initiative_id];
		console.log('INITIATIVE: ' + JSON.stringify(initiative));

		var total_supporters = initiative.supporter_count;

		var tmp_suggestion = {
			initiative: {
				name: initiative.name
			},
			name: suggestion_res.name,
			text: suggestion_res.content,

			mustsupporter: suggestion_res.plus2_unfulfilled_count + suggestion_res.plus2_fulfilled_count,
			shouldsupporter: suggestion_res.plus1_unfulfilled_count + suggestion_res.plus1_fulfilled_count,
			neutralsupporter: total_supporters
			                  - (suggestion_res.plus2_unfulfilled_count + suggestion_res.plus2_fulfilled_count)
			                  - (suggestion_res.plus1_unfulfilled_count + suggestion_res.plus1_fulfilled_count)
			                  - (suggestion_res.minus2_unfulfilled_count + suggestion_res.minus2_fulfilled_count)
			                  - (suggestion_res.minus1_unfulfilled_count + suggestion_res.minus1_fulfilled_count),
			shouldnotsupporter: suggestion_res.minus1_unfulfilled_count + suggestion_res.minus1_fulfilled_count,
			mustnotsupporter: suggestion_res.minus2_unfulfilled_count + suggestion_res.minus2_fulfilled_count,

			notimplementedmustsupporter: suggestion_res.plus2_unfulfilled_count,
			notimplementedshouldsupporter: suggestion_res.plus1_unfulfilled_count,
			notimplementedshouldnotsupporter: suggestion_res.minus1_unfulfilled_count,
			notimplementedmustnotsupporter: suggestion_res.minus2_unfulfilled_count,

			implementedmustsupporter: suggestion_res.plus2_fulfilled_count,
			implementedshouldsupporter: suggestion_res.plus1_fulfilled_count,
			implementedshouldnotsupporter: suggestion_res.minus1_fulfilled_count,
			implementedmustnotsupporter: suggestion_res.minus2_fulfilled_count,
		};
		notimplementedneutralsupporter = tmp_suggestion.neutralsupporter;
		implementedneutralsupporter = tmp_suggestion.neutralsupporter;

		tmp_suggestion.mustsupportwidth = tmp_suggestion.mustsupporter * 100 / total_supporters + "%";
		tmp_suggestion.shouldsupportwidth = tmp_suggestion.shouldsupporter * 100 / total_supporters + "%";
		tmp_suggestion.neutralsupportwidth = tmp_suggestion.neutralsupporter * 100 / total_supporters + "%";
		tmp_suggestion.shouldnotsupportwidth = tmp_suggestion.shouldnotsupporter * 100 / total_supporters + "%";
		tmp_suggestion.mustnotsupportwidth = tmp_suggestion.mustnotsupporter * 100 / total_supporters + "%";

		tmp_suggestion.notimplementedmustsupportwidth = tmp_suggestion.notimplementedmustsupporter * 100 / total_supporters + "%";
		tmp_suggestion.notimplementedshouldsupportwidth = tmp_suggestion.notimplementedshouldsupporter * 100 / total_supporters + "%";
		tmp_suggestion.notimplementedneutralsupportwidth = tmp_suggestion.notimplementedneutralsupporter * 100 / total_supporters + "%";
		tmp_suggestion.notimplementedshouldnotsupportwidth = tmp_suggestion.notimplementedshouldnotsupporter * 100 / total_supporters + "%";
		tmp_suggestion.notimplementedmustnotsupportwidth = tmp_suggestion.notimplementedmustnotsupporter * 100 / total_supporters + "%";
		tmp_suggestion.implementedmustsupportwidth = tmp_suggestion.notimplementedmustsupporter * 100 / total_supporters + "%";
		tmp_suggestion.implementedshouldsupportwidth = tmp_suggestion.notimplementedshouldsupporter * 100 / total_supporters + "%";
		tmp_suggestion.implementedneutralsupportwidth = tmp_suggestion.notimplementedneutralsupporter * 100 / total_supporters + "%";
		tmp_suggestion.implementedshouldnotsupportwidth = tmp_suggestion.notimplementedshouldnotsupporter * 100 / total_supporters + "%";
		tmp_suggestion.implementedmustnotsupportwidth = tmp_suggestion.notimplementedmustnotsupporter * 100 / total_supporters + "%";

		// add author info
		lf.query('/member', { 'member_id': suggestion_res.author_id }, state, function(res) {
			var author = res.result[0];
			console.log("AUTHOR: " + JSON.stringify(author));

			tmp_suggestion.author = {
				nick: author.name,
				name: author.realname || author.name,
				picsmall: "avatar/" + author.id,
				picmini: "picbig/" + author.id
			}

			suggestion_info = tmp_suggestion;
			finish();
		});
	});

	lf.query('/opinion', { 'suggestion_id': suggestion_id }, state, function(res) {
		var lf_opinions = res.result;

		/**
		 * Calculate the hapiness smiley for the given opinion.
		 * Result is 1 for very happy, 4 for very unhappy
		 */
		var calculate_smiley = function(lf_opinion) {
			var smiley = 1; // if degree == 0 we don't care, so we are happy
			if(lf_opinion.degree !== 0) {
				// renormalize (map to 0...4 and then to 1...4)
				smiley = lf_opinion.degree + 2;
				if(smiley < 2) {
					smiley += 2;
				}
				// if fullfilled highest value is happy
				if(lf_opinion.fulfilled) {
					smiley = 5 - smiley;
				}
			}
			return smiley;
		}

		console.log('OPINIONS:' + JSON.stringify(res));
		tmp_my_opinion = {
			i_say_implemented: false,
			smiley: 1,
			opinion: 0
		};
		var members_to_resolve = '';

		paging_info = function() {
			var tmp = {
				opinionpages: Math.floor(lf_opinions.length / OPINIONS_PER_PAGE) + 1,
				opinionpage: state.url.query.opinionpage || 1
			}
			if(tmp.opinionpage < 1 || tmp.opinionpage > tmp.opinionpages) {
				console.log('WARNING: Opinion page ' + tmp.opinionpage + ' requested, but only pages 1 to ' + tmp.opinionpages + ' valid for suggestion ' + suggestion_id);
				tmp.opinionpage = 1;
			}
			return tmp;
		}();
		console.log('PAGING INFO ' + JSON.stringify(paging_info));

		for(var i = OPINIONS_PER_PAGE * (paging_info.opinionpage - 1); i < lf_opinions.length && i < OPINIONS_PER_PAGE * (paging_info.opinionpage); i++) {
			var lf_opinion = lf_opinions[i];
			if(lf_opinion.member_id == state.user_id()) {
				tmp_my_opinion.i_say_implemented = lf_opinion.fulfilled;
				tmp_my_opinion.smiley = calculate_smiley(lf_opinion);
				tmp_my_opinion.opinion = lf_opinion.degree;
			}

			if(members_to_resolve != '') {
				members_to_resolve += ',';
			}
			members_to_resolve += lf_opinion.member_id;
		}
		my_opinion_info = tmp_my_opinion;

		lf.query('/member', { 'member_id': members_to_resolve }, state, function(res) {
			var i;
			var lf_member;
			var lf_members = res.result;
			var lf_members_by_id = {};
			for(i = 0; i < lf_members.length; i++) {
				lf_member = lf_members[i];
				lf_members_by_id[lf_member.id] = lf_member;
			}

			var tmp_opinion;
			var tmp_opinions = [];

			var calculate_action = function(lf_opinion) {
				switch(lf_opinion.degree) {
					case -2:
					case -1:
						return 'against';
					case 1:
					case 2:
						return 'for';
					default:
						return '';
				}
			};

		for(var i = OPINIONS_PER_PAGE * (paging_info.opinionpage - 1); i < lf_opinions.length && i < OPINIONS_PER_PAGE * (paging_info.opinionpage); i++) {
				lf_opinion = lf_opinions[i];
				// filter own opinion
				if(lf_opinion.member_id != state.user_id()) {
					console.log('LF OPINION: ' + JSON.stringify(lf_opinion));
					lf_member = lf_members_by_id[lf_opinion.member_id];
					console.log('LF member: ' + JSON.stringify(lf_member));
					tmp_opinion = {
						user: {
							nick: lf_member.name,
							name: lf_member.realname,
							picsmall: 'avatar/' + lf_member.id,
							picmini: 'avatar/' + lf_member.id
						},
						action: calculate_action(lf_opinion),
						implemented: lf_opinion.fulfilled,
						smiley: calculate_smiley(lf_opinion)
					}
					tmp_opinions.push(tmp_opinion);
				}
			}
			opinions_info = tmp_opinions;

			finish();
		});
	});
}
<|endoftext|>