<commit_before>/*
  A.hasOne(B)                 => B.aId
  A.belongsTo(B)              => A.bId
  A.hasMany(B)                => B.aId
  A.hasMany(B) + B.hasMany(A) => AB.aId + AB.bId
*/

SequelizeTable = function(sequelize, tableName, attributes) {
  var table = function(values) {
    var self = this
    SequelizeHelper.Hash.forEach(values, function(value, key) {
      if(attributes[key])
        self[key] = value
    })
    this.id = null // specify id as null to declare this object as unsaved and as not present in the database
    this.table = table
  }

  // class methods
  var classMethods = {
    associations: [],
    attributes: attributes,
    tableName: tableName,

    isCrossAssociatedWith: function(associatedTable) {
      var result = false
      var myTableName = table.tableName

      associatedTable.associations.forEach(function(association) {
        if((association.table.tableName == myTableName) && (association.type == 'hasMany'))
          result = true
      })
      return result
    },

    prepareAssociations: function() {
      table.associations.forEach(function(association) {
        switch(association.type) {
          case 'hasMany':
            if(association.table.isCrossAssociatedWith(table)) {
              // many to many relation
              var _attributes = {}
              _attributes[table.identifier] = Sequelize.INTEGER
              _attributes[association.table.identifier] = Sequelize.INTEGER
              sequelize.define(SequelizeHelper.SQL.manyToManyTableName(table, association.table), _attributes)
            } else {
              // one to many relation
              association.table.attributes[table.identifier] = Sequelize.INTEGER
            }
            break
          case 'hasOne':
            // e.g. assocTable.myTableId = Sequelize.INTEGER
            association.table.attributes[table.identifier] = Sequelize.INTEGER
            break
          case 'belongsTo':
            // e.g. table.dayId = Sequelize.INTEGER
            table.attributes[association.table.identifier] = Sequelize.INTEGER
            break
        }
      })
    },

    sync: function(callback) {
      var fields = ["id INT NOT NULL auto_increment PRIMARY KEY"]
      SequelizeHelper.Hash.forEach(table.attributes, function(type, name) {
        fields.push(name + " " + type)
      })

      sequelize.query(
        Sequelize.sqlQueryFor( 'create', { table: table.tableName, fields: fields.join(', ') } ),
        function() { if(callback) callback(table) }
      )
    },

    drop: function(callback) {
      sequelize.query(
        Sequelize.sqlQueryFor('drop', { table: table.tableName }),
        function() { if(callback) callback(table) }
      )
    },

    // TODO: mysql library currently doesn't support MYSQL_DATE!!! look for fix
    findAll: function(options, callback) {
      // use the first param as callback if it is no object (hash)
      var _callback = (typeof options == 'object') ? callback : options
      var queryOptions = (typeof options == 'object')
        ? SequelizeHelper.Hash.merge(options, { table: table.tableName })
        : { table: table.tableName }

      sequelize.query(
        Sequelize.sqlQueryFor('select', queryOptions),
        function(result) {
          var objects = []

          result.forEach(function(resultSet) {
            objects.push(table.sqlResultToObject(resultSet))
          })

          if(_callback) _callback(objects)
        }
      )
    },

    find: function(conditions, callback) {
      sequelize.query(
        Sequelize.sqlQueryFor('select', {
          table: table.tableName,
          where: SequelizeHelper.SQL.hashToWhereConditions(conditions, table.attributes),
          order: 'id DESC',
          limit: 1
        }), function(result) {
          var _result = result[0] ? table.sqlResultToObject(result[0]) : null
          if (callback) callback(_result)
        }
      )
    },

    // TODO: mysql library currently doesn't support MYSQL_DATE!!! don't merge if fixed
    sqlResultToObject: function(result) {
      if(typeof result == undefined) return null

      var object = new table(SequelizeHelper.Hash.merge({createdAt: new Date(), updatedAt: new Date()}, result, true))
      object.id = result.id
      return object
    },

    hasMany: function(assocName, _table) {
      table.associations.push({
        name: assocName,
        table: _table,
        type: 'hasMany'
      })

      // don't check inside of method to increase performance
      if(_table.isCrossAssociatedWith(table))
        table.prototype[assocName] = function(callback) {
          var whereConditions = [table.identifier, this.id].join("=")
          sequelize.tables[SequelizeHelper.SQL.manyToManyTableName(_table, table)]
            .constructor
            .findAll({ where: whereConditions }, function(result) {
              if(result.length > 0) {
                var ids = []
                result.forEach(function(resultSet) { ids.push(resultSet.id) })

                _table.findAll({where: "id IN (" + ids.join(",") + ")"}, callback)
              }
            })
        }
      else
        table.prototype[assocName] = function(callback) {
          var whereConditions = [table.identifier, this.id].join("=")
          _table.findAll({where: whereConditions}, callback)
        }

      return table
    },

    hasOne: function(assocName, _table) {
      table.associations.push({
        name: assocName,
        table: _table,
        type: 'hasOne'
      })

      table.prototype[assocName] = function(callback) {
        var whereConditions = {}
        whereConditions[table.identifier] = this.id
        _table.find(whereConditions, callback)
      }

      return table
    },

    belongsTo: function(assocName, _table) {
      table.associations.push({
        name: assocName,
        table: _table,
        type: 'belongsTo'
      })

      table.prototype[assocName] = function(callback) {
        var whereConditions = ["id", this[_table.identifier]].join("=")
        _table.find({where: whereConditions}, callback)
      }

      return table
    }
  }
  // don't put this into the hash!
  classMethods.identifier = SequelizeHelper.SQL.asTableIdentifier(classMethods.tableName)

  // instance methods
  table.prototype = {
    get values() {
      var result = {}
      var self = this

      SequelizeHelper.Hash.keys(table.attributes).forEach(function(attribute) {
        result[attribute] = self[attribute]
      })

      return result
    },

    save: function(callback) {
      var query = null
      var self = this

      this.updatedAt = new Date()
      if(this.id == null) {
        this.createdAt = new Date()
        query = Sequelize.sqlQueryFor('insert', {
          table: table.tableName, fields: SequelizeHelper.SQL.fieldsForInsertQuery(this), values: SequelizeHelper.SQL.valuesForInsertQuery(this)
        })
      } else
        query = Sequelize.sqlQueryFor('update', { table: table.tableName, values: SequelizeHelper.SQL.valuesForUpdate(this), id: this.id })

      sequelize.query(query, function() {
        if(self.id == null) {
          table.find(self.values, function(result) {
            self.id = result.id
            if(callback) callback(self)
          })
        } else {
          if(callback) callback(self)
        }
      })
    },

    updateAttributes: function(newValues, callback) {
      var self = this
      SequelizeHelper.Hash.keys(table.attributes).forEach(function(attribute) {
        if(newValues[attribute])
          self[attribute] = newValues[attribute]
      })
      this.save(callback)
    },

    destroy: function(callback) {
      sequelize.query(
        Sequelize.sqlQueryFor('delete', { table: table.tableName, id: this.id }),
        callback
      )
    }
  }

  SequelizeHelper.Hash.forEach(classMethods, function(method, methodName) {
    table[methodName] = method
  })

  return table
}<commit_msg>values method return null instead of undefined<commit_after>/*
  A.hasOne(B)                 => B.aId
  A.belongsTo(B)              => A.bId
  A.hasMany(B)                => B.aId
  A.hasMany(B) + B.hasMany(A) => AB.aId + AB.bId
*/

SequelizeTable = function(sequelize, tableName, attributes) {
  var table = function(values) {
    var self = this
    SequelizeHelper.Hash.forEach(values, function(value, key) {
      if(attributes[key])
        self[key] = value
    })
    this.id = null // specify id as null to declare this object as unsaved and as not present in the database
    this.table = table
  }

  // class methods
  var classMethods = {
    associations: [],
    attributes: attributes,
    tableName: tableName,

    isCrossAssociatedWith: function(associatedTable) {
      var result = false
      var myTableName = table.tableName

      associatedTable.associations.forEach(function(association) {
        if((association.table.tableName == myTableName) && (association.type == 'hasMany'))
          result = true
      })
      return result
    },

    prepareAssociations: function() {
      table.associations.forEach(function(association) {
        switch(association.type) {
          case 'hasMany':
            if(association.table.isCrossAssociatedWith(table)) {
              // many to many relation
              var _attributes = {}
              _attributes[table.identifier] = Sequelize.INTEGER
              _attributes[association.table.identifier] = Sequelize.INTEGER
              sequelize.define(SequelizeHelper.SQL.manyToManyTableName(table, association.table), _attributes)
            } else {
              // one to many relation
              association.table.attributes[table.identifier] = Sequelize.INTEGER
            }
            break
          case 'hasOne':
            // e.g. assocTable.myTableId = Sequelize.INTEGER
            association.table.attributes[table.identifier] = Sequelize.INTEGER
            break
          case 'belongsTo':
            // e.g. table.dayId = Sequelize.INTEGER
            table.attributes[association.table.identifier] = Sequelize.INTEGER
            break
        }
      })
    },

    sync: function(callback) {
      var fields = ["id INT NOT NULL auto_increment PRIMARY KEY"]
      SequelizeHelper.Hash.forEach(table.attributes, function(type, name) {
        fields.push(name + " " + type)
      })

      sequelize.query(
        Sequelize.sqlQueryFor( 'create', { table: table.tableName, fields: fields.join(', ') } ),
        function() { if(callback) callback(table) }
      )
    },

    drop: function(callback) {
      sequelize.query(
        Sequelize.sqlQueryFor('drop', { table: table.tableName }),
        function() { if(callback) callback(table) }
      )
    },

    // TODO: mysql library currently doesn't support MYSQL_DATE!!! look for fix
    findAll: function(options, callback) {
      // use the first param as callback if it is no object (hash)
      var _callback = (typeof options == 'object') ? callback : options
      var queryOptions = (typeof options == 'object')
        ? SequelizeHelper.Hash.merge(options, { table: table.tableName })
        : { table: table.tableName }

      sequelize.query(
        Sequelize.sqlQueryFor('select', queryOptions),
        function(result) {
          var objects = []

          result.forEach(function(resultSet) {
            objects.push(table.sqlResultToObject(resultSet))
          })

          if(_callback) _callback(objects)
        }
      )
    },

    find: function(conditions, callback) {
      sequelize.query(
        Sequelize.sqlQueryFor('select', {
          table: table.tableName,
          where: SequelizeHelper.SQL.hashToWhereConditions(conditions, table.attributes),
          order: 'id DESC',
          limit: 1
        }), function(result) {
          var _result = result[0] ? table.sqlResultToObject(result[0]) : null
          if (callback) callback(_result)
        }
      )
    },

    // TODO: mysql library currently doesn't support MYSQL_DATE!!! don't merge if fixed
    sqlResultToObject: function(result) {
      if(typeof result == undefined) return null

      var object = new table(SequelizeHelper.Hash.merge({createdAt: new Date(), updatedAt: new Date()}, result, true))
      object.id = result.id
      return object
    },

    hasMany: function(assocName, _table) {
      table.associations.push({
        name: assocName,
        table: _table,
        type: 'hasMany'
      })

      // don't check inside of method to increase performance
      if(_table.isCrossAssociatedWith(table))
        table.prototype[assocName] = function(callback) {
          var whereConditions = [table.identifier, this.id].join("=")
          sequelize.tables[SequelizeHelper.SQL.manyToManyTableName(_table, table)]
            .constructor
            .findAll({ where: whereConditions }, function(result) {
              if(result.length > 0) {
                var ids = []
                result.forEach(function(resultSet) { ids.push(resultSet.id) })

                _table.findAll({where: "id IN (" + ids.join(",") + ")"}, callback)
              }
            })
        }
      else
        table.prototype[assocName] = function(callback) {
          var whereConditions = [table.identifier, this.id].join("=")
          _table.findAll({where: whereConditions}, callback)
        }

      return table
    },

    hasOne: function(assocName, _table) {
      table.associations.push({
        name: assocName,
        table: _table,
        type: 'hasOne'
      })

      table.prototype[assocName] = function(callback) {
        var whereConditions = {}
        whereConditions[table.identifier] = this.id
        _table.find(whereConditions, callback)
      }

      return table
    },

    belongsTo: function(assocName, _table) {
      table.associations.push({
        name: assocName,
        table: _table,
        type: 'belongsTo'
      })

      table.prototype[assocName] = function(callback) {
        var whereConditions = ["id", this[_table.identifier]].join("=")
        _table.find({where: whereConditions}, callback)
      }

      return table
    }
  }
  // don't put this into the hash!
  classMethods.identifier = SequelizeHelper.SQL.asTableIdentifier(classMethods.tableName)

  // instance methods
  table.prototype = {
    get values() {
      var result = {}
      var self = this

      SequelizeHelper.Hash.keys(table.attributes).forEach(function(attribute) {
        result[attribute] = self[attribute] || null
      })

      return result
    },

    save: function(callback) {
      var query = null
      var self = this

      this.updatedAt = new Date()
      if(this.id == null) {
        this.createdAt = new Date()
        query = Sequelize.sqlQueryFor('insert', {
          table: table.tableName, fields: SequelizeHelper.SQL.fieldsForInsertQuery(this), values: SequelizeHelper.SQL.valuesForInsertQuery(this)
        })
      } else
        query = Sequelize.sqlQueryFor('update', { table: table.tableName, values: SequelizeHelper.SQL.valuesForUpdate(this), id: this.id })

      sequelize.query(query, function() {
        if(self.id == null) {
          table.find(self.values, function(result) {
            self.id = result.id
            if(callback) callback(self)
          })
        } else {
          if(callback) callback(self)
        }
      })
    },

    updateAttributes: function(newValues, callback) {
      var self = this
      SequelizeHelper.Hash.keys(table.attributes).forEach(function(attribute) {
        if(newValues[attribute])
          self[attribute] = newValues[attribute]
      })
      this.save(callback)
    },

    destroy: function(callback) {
      sequelize.query(
        Sequelize.sqlQueryFor('delete', { table: table.tableName, id: this.id }),
        callback
      )
    }
  }

  SequelizeHelper.Hash.forEach(classMethods, function(method, methodName) {
    table[methodName] = method
  })

  return table
}<|endoftext|>


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

$(function () {
  $.DEPS_QUERY_NAME = 'deps';
  $.SOMEPATH_QUERY_NAME = 'somepath';
  $.ALLPATHS_QUERY_NAME = 'allpaths';

  $.supportedQueries = new Map([
    [$.DEPS_QUERY_NAME, 1],
    [$.ALLPATHS_QUERY_NAME, 2],
    [$.SOMEPATH_QUERY_NAME, 2],
  ]);

  /**
   * Validates the request name to see if it is supported or not.
   *
   * @param {string} queryName the name of the query to check
   * @return {boolean} a value that determines whether the request is supported or not
   */
  $.fn.validateQueryName = function (queryName) {
    return $.supportedQueries.has(queryName);
  };

  /**
   * Validates the number of query parameters.
   *
   * @param {Array<string>} query a full query passed by user with unique name and parameters
   * @return {boolean} a value that determines whether the number of parameters is correct or not
   */
  $.fn.validateParameters = function (query) {
    return $.supportedQueries.get(query[0]) === query.length - 1;
  };
});

$(function () {
  /**
   * Marks input field as invalid and shows a container with error message.
   * @param {string} errorMessage a error message which will be shown under the input field
   */
  $.fn.markInputFieldAsInvalid = function (errorMessage) {
    $("#query-input").removeClass("is-valid").addClass("is-invalid");
    $("#error-message").removeClass("hidden").text(errorMessage);
  };

  /**
   * Marks the input field as valid and hides the container with an error message if shown earlier.
   */
  $.fn.markInputFieldAsValid = function () {
    $("#query-input").removeClass("is-invalid").addClass("is-valid");
    $("#error-message").addClass("hidden");
  };
});

$(function () {
  /**
   * Sends a request to the server with specified query and gets a response.
   * @param url an address with the correct path and request parameters in it
   * @return {Promise<any>} a promise that contains a json with a graph on success
   */
  $.fn.getQueryResults = async function (url) {
    let response = await fetch(url);

    if (response.status === 200) {
      return await response.json();
    }

    throw await response.text();
  };

  /**
   * Processes a valid query by sending a request to the specified URL,
   * receiving a response, and performing UI actions in response.
   *
   * @param url an address with the correct path and request parameters in it
   */
  $.fn.processQuery = async function (url) {
    try {
      const graph = await $(this).getQueryResults(url);
      $(this).markInputFieldAsValid();
    } catch (error) {
      $(this).markInputFieldAsInvalid(error);
    }
  }
});

$("#query-input").on('keydown keyup change', function (event) {
  const query = $(this).val().trim().split(' ');
  const queryName = query[0];

  const queryNameElement = $(this).closest('.interactive-input-container').find('.query-name');
  if (!$(this).validateQueryName(queryName)) {
    queryNameElement.hide();
    return;
  }

  // Highlights query's name when it is valid.
  queryNameElement.html(queryName).show();

  if (event.key === 'Enter' && $(this).validateParameters(query)) {
    const url = new URL(`http://localhost:4921/daggerquery/`);
    url.searchParams.append('query', query.join(' '));

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

$(function () {
  $.DEPS_QUERY_NAME = 'deps';
  $.SOMEPATH_QUERY_NAME = 'somepath';
  $.ALLPATHS_QUERY_NAME = 'allpaths';

  $.supportedQueries = new Map([
    [$.DEPS_QUERY_NAME, 1],
    [$.ALLPATHS_QUERY_NAME, 2],
    [$.SOMEPATH_QUERY_NAME, 2],
  ]);

  /**
   * Validates the request name to see if it is supported or not.
   *
   * @param {string} queryName the name of the query to check
   * @return {boolean} a value that determines whether the request is supported or not
   */
  $.fn.validateQueryName = function (queryName) {
    return $.supportedQueries.has(queryName);
  };

  /**
   * Validates the number of query parameters.
   *
   * @param {Array<string>} query a full query passed by user with unique name and parameters
   * @return {boolean} a value that determines whether the number of parameters is correct or not
   */
  $.fn.validateParameters = function (query) {
    return $.supportedQueries.get(query[0]) === query.length - 1;
  };
});

$(function () {
  /**
   * Marks input field as invalid and shows a container with error message.
   * @param {string} errorMessage a error message which will be shown under the input field
   */
  $.fn.markInputFieldAsInvalid = function (errorMessage) {
    $("#query-input").removeClass("is-valid").addClass("is-invalid");
    $("#error-message").removeClass("hidden").text(errorMessage);
  };

  /**
   * Marks the input field as valid and hides the container with an error message if shown earlier.
   */
  $.fn.markInputFieldAsValid = function () {
    $("#query-input").removeClass("is-invalid").addClass("is-valid");
    $("#error-message").addClass("hidden");
  };
});

$(function () {
  /**
   * Sends a request to the server with specified query and gets a response.
   * @param url an address with the correct path and request parameters in it
   * @return {Promise<any>} a promise that contains a json with a graph on success
   */
  $.fn.getQueryResults = async function (url) {
    let response = await fetch(url);

    if (response.status === 200) {
      return await response.json();
    }

    throw await response.text();
  };

  /**
   * Processes a valid query by sending a request to the specified URL,
   * receiving a response, and performing UI actions in response.
   *
   * @param {string[]} query a valid query which will be executed
   */
  $.fn.processQuery = async function (query) {
    try {
      const url = new URL(`http://localhost:4921/daggerquery/`);
      url.searchParams.append('query', query.join(' '));
      const graph = await $(this).getQueryResults(url);
      $(this).markInputFieldAsValid();
    } catch (error) {
      $(this).markInputFieldAsInvalid(error);
    }
  }
});

$("#query-input").on('keydown keyup change', function (event) {
  const query = $(this).val().trim().split(' ');
  const queryName = query[0];

  const queryNameElement = $(this).closest('.interactive-input-container').find('.query-name');
  if (!$(this).validateQueryName(queryName)) {
    queryNameElement.hide();
    return;
  }

  // Highlights query's name when it is valid.
  queryNameElement.html(queryName).show();

  if (event.key === 'Enter' && $(this).validateParameters(query)) {
    $(this).processQuery(query);
  }
});
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'backbone',
    'underscore',
    'i18n!find/nls/bundle',
    'find/app/model/similar-documents-collection',
    'find/app/vent',
    'text!find/templates/app/page/search/document/similar-documents-tab.html'
], function(Backbone, _, i18n, SimilarDocumentsCollection, vent, template) {
    'use strict';

    return Backbone.View.extend({
        similarDocumentTemplate: _.template('<li data-cid="<%-cid%>" class="clickable">
<%-model.get("title")%>

<%-model.get("summary").trim().substring(0, 200) + "..."%>

'),
        template: _.template(template),

        events: {
            'click [data-cid]': function(e) {
                var cid = $(e.currentTarget).data('cid');
                var model = this.collection.get(cid);

                vent.navigateToDetailRoute(model);
            }
        },

        initialize: function(options) {
            this.indexesCollection = options.indexesCollection;
            this.collection = this.createCollection();
        },

        render: function() {
            this.$el.html(this.template({
                i18n:i18n
            }));

            this.postRender();

            if(this.indexesCollection.length) {
                this.getSimilarDocuments();
            } else {
                this.listenTo(this.indexesCollection, 'sync', this.getSimilarDocuments);
            }
        },

        getSimilarDocuments: function() {
            this.$('.loading-spinner').removeClass('hide');

            this.collection.fetch({
                data: this.fetchData()
            })
                .done(_.bind(function() {
                    var filteredModels = this.collection.filter(function (model) {
                        return model.get('reference') !== this.model.get('reference');
                    }, this);

                    if (filteredModels.length === 0) {
                        this.$('ul').html(i18n['search.similarDocuments.none']);
                    } else {
                        var html = _.map(filteredModels, function (model) {
                                return this.similarDocumentTemplate({
                                    model: model,
                                    cid: model.cid
                                });
                            }, this)
                            .join('');
                        this.$('ul').html(html);
                    }
                    }, this)
                )
                .fail(_.bind(function() {
                    this.$el.html(i18n['search.similarDocuments.error']);
                }, this))
                .always(_.bind(function() {
                    this.$('.loading-spinner').addClass('hide');
                }, this));
        },

        createCollection: null,
        fetchData: null,
        postRender: _.noop

    });
});
<commit_msg>[BIFHI-63] fix broken abort and error cases on similar dates [rev Matt Gordon]<commit_after>/*
 * Copyright 2016 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'backbone',
    'underscore',
    'i18n!find/nls/bundle',
    'find/app/model/similar-documents-collection',
    'find/app/vent',
    'text!find/templates/app/page/search/document/similar-documents-tab.html'
], function(Backbone, _, i18n, SimilarDocumentsCollection, vent, template) {
    'use strict';

    return Backbone.View.extend({
        similarDocumentTemplate: _.template('<li data-cid="<%-cid%>" class="clickable">
<%-model.get("title")%>

<%-model.get("summary").trim().substring(0, 200) + "..."%>

'),
        template: _.template(template),

        events: {
            'click [data-cid]': function(e) {
                var cid = $(e.currentTarget).data('cid');
                var model = this.collection.get(cid);

                vent.navigateToDetailRoute(model);
            }
        },

        initialize: function(options) {
            this.indexesCollection = options.indexesCollection;
            this.collection = this.createCollection();
        },

        render: function() {
            this.$el.html(this.template({
                i18n:i18n
            }));

            this.postRender();

            if(this.indexesCollection.length) {
                this.getSimilarDocuments();
            } else {
                this.listenTo(this.indexesCollection, 'sync', this.getSimilarDocuments);
            }
        },

        getSimilarDocuments: function() {
            this.$('.loading-spinner').removeClass('hide');

            this.$('ul').empty();

            this.collection.fetch({
                data: this.fetchData()
            })
                .done(_.bind(function() {
                    var filteredModels = this.collection.filter(function (model) {
                        return model.get('reference') !== this.model.get('reference');
                    }, this);

                    if (filteredModels.length === 0) {
                        this.$('ul').html(i18n['search.similarDocuments.none']);
                    } else {
                        var html = _.map(filteredModels, function (model) {
                                return this.similarDocumentTemplate({
                                    model: model,
                                    cid: model.cid
                                });
                            }, this)
                            .join('');
                        this.$('ul').html(html);
                    }
                    }, this)
                )
                .fail(_.bind(function(xhr) {
                    if (xhr.status !== 0) {
                        this.$('ul').html(i18n['search.similarDocuments.error']);
                    }
                }, this))
                .always(_.bind(function(results, success) {
                    if (success !== 'abort') {
                        this.$('.loading-spinner').addClass('hide');
                    }
                }, this));
        },

        createCollection: null,
        fetchData: null,
        postRender: _.noop

    });
});
<|endoftext|>


<commit_before>import React from 'react';
import Enzyme, { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import SprkTextInput from './SprkTextInput';
import SprkIcon from '../../SprkIcon/SprkIcon';

Enzyme.configure({ adapter: new Adapter() });

it('should render an element with the correct class', () => {
  const wrapper = mount(<SprkTextInput />);
  expect(wrapper.find('.sprk-b-InputContainer').length).toBe(1);
});

it('should render a huge text input with the correct class', () => {
  const wrapper = mount(<SprkTextInput type="hugeTextInput" />);
  expect(
    wrapper
      .find('.sprk-b-InputContainer')
      .hasClass('sprk-b-InputContainer--huge'),
  ).toBe(true);
});

it('should add classes when additionalClasses has a value', () => {
  const wrapper = mount(<SprkTextInput additionalClasses="sprk-u-man" />);
  expect(wrapper.find('.sprk-b-InputContainer.sprk-u-man').length).toBe(1);
});

it('should assign data-analytics when analyticsString has a value', () => {
  const wrapper = mount(<SprkTextInput analyticsString="321" />);
  expect(wrapper.find('[data-analytics="321"]').length).toBe(1);
});

it('should assign data-id when idString has a value', () => {
  const wrapper = mount(<SprkTextInput idString="321" />);
  expect(wrapper.find('[data-id="321"]').length).toBe(1);
});

it('should render an icon if leadingIcon is supplied', () => {
  const wrapper = mount(<SprkTextInput leadingIcon="calendar" />);
  expect(wrapper.find(SprkIcon).length).toBe(1);
});

it('should render a textarea is type is set to textarea', () => {
  const wrapper = mount(<SprkTextInput type="textarea" />);
  expect(wrapper.find('textarea.sprk-b-TextArea').length).toBe(1);
});

it('should run the supplied formatter', () => {
  const formatter = jest.fn(() => true);
  const onChangeMock = jest.fn();
  mount(
    <SprkTextInput type="text" formatter={formatter} onChange={onChangeMock} />,
  );
  expect(formatter.mock.calls.length).toBe(2);
});

it('should not run the formatter if the field is invalid', () => {
  const formatter = jest.fn();
  mount(<SprkTextInput type="text" formatter={formatter} valid={false} />);
  expect(formatter.mock.calls.length).toBe(0);
});

it('should run the supplied formatter (textarea)', () => {
  const formatter = jest.fn(() => true);
  const onChangeMock = jest.fn();
  mount(
    <SprkTextInput
      type="textarea"
      formatter={formatter}
      onChange={onChangeMock}
    />,
  );
  expect(formatter.mock.calls.length).toBe(2);
});

it('should not run the formatter if the field is invalid (textarea)', () => {
  const formatter = jest.fn();
  mount(<SprkTextInput type="textarea" formatter={formatter} valid={false} />);
  expect(formatter.mock.calls.length).toBe(0);
});

it('should render helper text if supplied', () => {
  const wrapper = mount(<SprkTextInput helperText="sample helper text" />);
  expect(wrapper.find('.sprk-b-HelperText').length).toBe(1);
});

it('should not render helper text if not supplied', () => {
  const wrapper = mount(<SprkTextInput helperText="" />);
  expect(wrapper.find('.sprk-b-HelperText').length).toBe(0);
});
<commit_msg>Write tests for blurr out with value<commit_after>import React from 'react';
import Enzyme, { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import SprkTextInput from './SprkTextInput';
import SprkIcon from '../../SprkIcon/SprkIcon';

Enzyme.configure({ adapter: new Adapter() });

it('should render an element with the correct class', () => {
  const wrapper = mount(<SprkTextInput />);
  expect(wrapper.find('.sprk-b-InputContainer').length).toBe(1);
});

it('should render a huge text input with the correct class', () => {
  const wrapper = mount(<SprkTextInput type="hugeTextInput" />);
  expect(
    wrapper
      .find('.sprk-b-InputContainer')
      .hasClass('sprk-b-InputContainer--huge'),
  ).toBe(true);
});

it('should add float-label class to huge text when a value is present and blurred out', () => {
  const wrapper = mount(
    <SprkTextInput type="hugeTextInput" />,
  );
  const input = wrapper.find('input');

  // on blur pass object into blur handler
  // Enzyme does not update state of the DOM but we can simulate update to the DOM state by passing same state into react function
  input.simulate("blur", { target: { value: "foo" } })

  expect(
    wrapper
      .find('.sprk-b-TextInput')
      .hasClass('sprk-b-TextInput--float-label'),
  ).toBe(true);
});

it('should remove/not have float-label class to huge text when a value is not present and blurred out', () => {
  const wrapper = mount(
    <SprkTextInput type="hugeTextInput" />,
  );
  const input = wrapper.find('input');

  input.simulate("blur", { target: { value: "" } })

  expect(
    wrapper
      .find('.sprk-b-TextInput')
      .hasClass('sprk-b-TextInput--float-label'),
  ).toBe(false);
});

it('should have float-label class to huge text when there is value', () => {
  const wrapper = mount(<SprkTextInput value="value present" type="hugeTextInput" />);
  expect(
    wrapper
      .find('.sprk-b-TextInput')
      .hasClass('sprk-b-TextInput--float-label'),
  ).toBe(true);
});

it('should add classes when additionalClasses has a value', () => {
  const wrapper = mount(<SprkTextInput additionalClasses="sprk-u-man" />);
  expect(wrapper.find('.sprk-b-InputContainer.sprk-u-man').length).toBe(1);
});

it('should assign data-analytics when analyticsString has a value', () => {
  const wrapper = mount(<SprkTextInput analyticsString="321" />);
  expect(wrapper.find('[data-analytics="321"]').length).toBe(1);
});

it('should assign data-id when idString has a value', () => {
  const wrapper = mount(<SprkTextInput idString="321" />);
  expect(wrapper.find('[data-id="321"]').length).toBe(1);
});

it('should render an icon if leadingIcon is supplied', () => {
  const wrapper = mount(<SprkTextInput leadingIcon="calendar" />);
  expect(wrapper.find(SprkIcon).length).toBe(1);
});

it('should render a textarea is type is set to textarea', () => {
  const wrapper = mount(<SprkTextInput type="textarea" />);
  expect(wrapper.find('textarea.sprk-b-TextArea').length).toBe(1);
});

it('should run the supplied formatter', () => {
  const formatter = jest.fn(() => true);
  const onChangeMock = jest.fn();
  mount(
    <SprkTextInput type="text" formatter={formatter} onChange={onChangeMock} />,
  );
  expect(formatter.mock.calls.length).toBe(2);
});

it('should not run the formatter if the field is invalid', () => {
  const formatter = jest.fn();
  mount(<SprkTextInput type="text" formatter={formatter} valid={false} />);
  expect(formatter.mock.calls.length).toBe(0);
});

it('should run the supplied formatter (textarea)', () => {
  const formatter = jest.fn(() => true);
  const onChangeMock = jest.fn();
  mount(
    <SprkTextInput
      type="textarea"
      formatter={formatter}
      onChange={onChangeMock}
    />,
  );
  expect(formatter.mock.calls.length).toBe(2);
});

it('should not run the formatter if the field is invalid (textarea)', () => {
  const formatter = jest.fn();
  mount(<SprkTextInput type="textarea" formatter={formatter} valid={false} />);
  expect(formatter.mock.calls.length).toBe(0);
});

it('should render helper text if supplied', () => {
  const wrapper = mount(<SprkTextInput helperText="sample helper text" />);
  expect(wrapper.find('.sprk-b-HelperText').length).toBe(1);
});

it('should not render helper text if not supplied', () => {
  const wrapper = mount(<SprkTextInput helperText="" />);
  expect(wrapper.find('.sprk-b-HelperText').length).toBe(0);
});
<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');

var template = fs.readFileSync(__dirname + '/variable-upload-dialog.html', 'utf8');

var Controller = [
  '$uibModalInstance',
  '$scope',
  'Notifications',
  'Uri',
  'basePath',
  'variable',
  '$translate',
  '$browser',
  function(
    $modalInstance,
    $scope,
    Notifications,
    Uri,
    basePath,
    variable,
    $translate,
    $browser
  ) {

    var BEFORE_UPLOAD = 'beforeUpload',
        PERFORM_UPLOAD = 'performUpload',
        UPLOAD_SUCCESS = 'uploadSuccess',
        UPLOAD_FAILED = 'uploadFailed';

    $scope.status = BEFORE_UPLOAD;

    $scope.variable = variable;

    var file;

    $scope.$on('$routeChangeStart', function() {
      $modalInstance.dismiss();
    });

    $scope.upload = function() {

    // progress listeners

      function uploadProgress(evt) {
        $scope.$apply(function() {
          $scope.status = PERFORM_UPLOAD;
          if (evt.lengthComputable) {
            $scope.progress = Math.round(evt.loaded * 100 / evt.total);
          }
        });
      }

      function uploadComplete(xhr) {
        $scope.$apply(function() {

          if(xhr.status === 204) {
            $scope.status = UPLOAD_SUCCESS;
            Notifications.addMessage({
              status: $translate.instant('VARIABLE_UPLOAD_FILE'),
              message: $translate.instant('VARIABLE_UPLOAD_MESSAGE_ADD')
            });
          }
          else {
            $scope.status = UPLOAD_FAILED;
            Notifications.addError({
              status: $translate.instant('VARIABLE_UPLOAD_FILE'),
              message: $translate.instant('VARIABLE_UPLOAD_MESSAGE_ERR'),
              exclusive: true
            });
          }
        });
      }

      function uploadFailed() {
        $scope.$apply(function() {
          $scope.status = UPLOAD_FAILED;
          Notifications.addError({
            status: $translate.instant('VARIABLE_UPLOAD_FILE'),
            message: $translate.instant('VARIABLE_UPLOAD_MESSAGE_ERR'),
            exclusive: true
          });
        });
      }

    // perform HTML 5 file opload (not supported by IE 9)
      var fd = new FormData();
      fd.append('data', file);
      fd.append('valueType', variable.type);

      var xhr = new XMLHttpRequest();

      xhr.upload.addEventListener('progress', uploadProgress, false);
      xhr.addEventListener('load', function() {
        uploadComplete(xhr);
      }, false);
      xhr.addEventListener('error', uploadFailed, false);
      xhr.addEventListener('abort', uploadFailed, false);
      xhr.open('POST', Uri.appUri(basePath + '/data'));

      var token = $browser.cookies()['XSRF-TOKEN'];
      if (token) {
        xhr.setRequestHeader('X-XSRF-TOKEN', token);
      }

      xhr.send(fd);

    };

    $scope.setFile = function(element) {
      file = element.files[0];
    };

  }];

module.exports = {
  template: template,
  controller: Controller
};
<commit_msg>chore(webapps): replace $browser with $cookies<commit_after>'use strict';

var fs = require('fs');

var template = fs.readFileSync(__dirname + '/variable-upload-dialog.html', 'utf8');

var Controller = [
  '$uibModalInstance',
  '$scope',
  'Notifications',
  'Uri',
  'basePath',
  'variable',
  '$translate',
  '$cookies',
  function(
    $modalInstance,
    $scope,
    Notifications,
    Uri,
    basePath,
    variable,
    $translate,
    $cookies
  ) {

    var BEFORE_UPLOAD = 'beforeUpload',
        PERFORM_UPLOAD = 'performUpload',
        UPLOAD_SUCCESS = 'uploadSuccess',
        UPLOAD_FAILED = 'uploadFailed';

    $scope.status = BEFORE_UPLOAD;

    $scope.variable = variable;

    var file;

    $scope.$on('$routeChangeStart', function() {
      $modalInstance.dismiss();
    });

    $scope.upload = function() {

    // progress listeners

      function uploadProgress(evt) {
        $scope.$apply(function() {
          $scope.status = PERFORM_UPLOAD;
          if (evt.lengthComputable) {
            $scope.progress = Math.round(evt.loaded * 100 / evt.total);
          }
        });
      }

      function uploadComplete(xhr) {
        $scope.$apply(function() {

          if(xhr.status === 204) {
            $scope.status = UPLOAD_SUCCESS;
            Notifications.addMessage({
              status: $translate.instant('VARIABLE_UPLOAD_FILE'),
              message: $translate.instant('VARIABLE_UPLOAD_MESSAGE_ADD')
            });
          }
          else {
            $scope.status = UPLOAD_FAILED;
            Notifications.addError({
              status: $translate.instant('VARIABLE_UPLOAD_FILE'),
              message: $translate.instant('VARIABLE_UPLOAD_MESSAGE_ERR'),
              exclusive: true
            });
          }
        });
      }

      function uploadFailed() {
        $scope.$apply(function() {
          $scope.status = UPLOAD_FAILED;
          Notifications.addError({
            status: $translate.instant('VARIABLE_UPLOAD_FILE'),
            message: $translate.instant('VARIABLE_UPLOAD_MESSAGE_ERR'),
            exclusive: true
          });
        });
      }

    // perform HTML 5 file opload (not supported by IE 9)
      var fd = new FormData();
      fd.append('data', file);
      fd.append('valueType', variable.type);

      var xhr = new XMLHttpRequest();

      xhr.upload.addEventListener('progress', uploadProgress, false);
      xhr.addEventListener('load', function() {
        uploadComplete(xhr);
      }, false);
      xhr.addEventListener('error', uploadFailed, false);
      xhr.addEventListener('abort', uploadFailed, false);
      xhr.open('POST', Uri.appUri(basePath + '/data'));

      var token = $cookies.get('XSRF-TOKEN');
      if (token) {
        xhr.setRequestHeader('X-XSRF-TOKEN', token);
      }

      xhr.send(fd);

    };

    $scope.setFile = function(element) {
      file = element.files[0];
    };

  }];

module.exports = {
  template: template,
  controller: Controller
};
<|endoftext|>


<commit_before>import axios from 'axios';
import { getCumulative } from 'services/climate';

export default ({ params }) =>
  axios.all([...getCumulative({ ...params })]).then(
    axios.spread((y2015, y2016, y2017, y2018) => {
      const years = [2015, 2016, 2017, 2018].map(year => ({
        label: year,
        value: year
      }));
      const data = {
        2015: y2015.data && y2015.data.data,
        2016: y2016.data && y2016.data.data,
        2017: y2017.data && y2017.data.data,
        2018: y2018.data && y2018.data.data
      };

      return {
        data,
        options: { years },
        settings: {
          year: years[0].value
        }
      };
    })
  );
<commit_msg>Fixed original year issue<commit_after>import axios from 'axios';
import { getCumulative } from 'services/climate';

export default ({ params }) =>
  axios.all([...getCumulative({ ...params })]).then(
    axios.spread((y2015, y2016, y2017, y2018) => {
      const years = [2015, 2016, 2017, 2018].map(year => ({
        label: year,
        value: year
      }));
      const data = {
        2015: y2015.data && y2015.data.data,
        2016: y2016.data && y2016.data.data,
        2017: y2017.data && y2017.data.data,
        2018: y2018.data && y2018.data.data
      };

      return {
        data,
        options: { years }
      };
    })
  );
<|endoftext|>


<commit_before>FormplayerFrontend.module("Entities", function (Entities, FormplayerFrontend, Backbone, Marionette, $, _) {
    Entities.AppSelect = Backbone.Model.extend({
        urlRoot: "appSelects"
    });

    Entities.configureStorage("FormplayerFrontend.Entities.AppSelect");

    Entities.AppSelectCollection = Backbone.Collection.extend({
        url: "appSelects",
        model: Entities.AppSelect
    });

    Entities.configureStorage("FormplayerFrontend.Entities.AppSelectCollection");

    var storeApps = function (apps) {

        old_apps = new Entities.AppSelectCollection();
        var defer = $.Deferred();
        old_apps.fetch({
            success: function (data) {
                defer.resolve(data);
            }
        });

        var promise = defer.promise();
        $.when(promise).done(function (oldApps) {
            if (oldApps.length === 0) {
                apps = new Entities.AppSelectCollection(apps);
                apps.forEach(function (app) {
                    app.save();
                });
                oldApps.reset(apps.models);
            }
        });
        return promise;
    };

    var API = {
        getAppEntities: function () {
            var apps = new Entities.AppSelectCollection();
            var defer = $.Deferred();
            apps.fetch({
                success: function (request) {
                    defer.resolve(request);
                }
            });
            return defer.promise();
        },

        storeApps: function (apps) {
            storeApps(apps);
        }
    };

    FormplayerFrontend.reqres.setHandler("appselect:apps", function () {
        return API.getAppEntities();
    });

    FormplayerFrontend.reqres.setHandler("appselect:storeapps", function (apps) {
        return API.storeApps(apps);
    })
});<commit_msg>clear local storage<commit_after>FormplayerFrontend.module("Entities", function (Entities, FormplayerFrontend, Backbone, Marionette, $, _) {
    Entities.AppSelect = Backbone.Model.extend({
        urlRoot: "appSelects"
    });

    Entities.configureStorage("FormplayerFrontend.Entities.AppSelect");

    Entities.AppSelectCollection = Backbone.Collection.extend({
        url: "appSelects",
        model: Entities.AppSelect
    });

    Entities.configureStorage("FormplayerFrontend.Entities.AppSelectCollection");

    var storeApps = function (apps) {
        old_apps = new Entities.AppSelectCollection();
        var defer = $.Deferred();
        old_apps.fetch({
            success: function (data) {
                defer.resolve(data);
            }
        });
        var promise = defer.promise();
        $.when(promise).done(function (oldApps) {
            // clear app's local storage when we load new list of apps
            window.localStorage.clear();
            apps = new Entities.AppSelectCollection(apps);
            apps.forEach(function (app) {
                app.save();
            });
            oldApps.reset(apps.models);
        });
        return promise;
    };

    var API = {
        getAppEntities: function () {
            var apps = new Entities.AppSelectCollection();
            var defer = $.Deferred();
            apps.fetch({
                success: function (request) {
                    defer.resolve(request);
                }
            });
            return defer.promise();
        },

        storeApps: function (apps) {
            storeApps(apps);
        }
    };

    FormplayerFrontend.reqres.setHandler("appselect:apps", function () {
        return API.getAppEntities();
    });

    FormplayerFrontend.reqres.setHandler("appselect:storeapps", function (apps) {
        return API.storeApps(apps);
    })
});<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011-2013, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */

/*jslint anon:true, sloppy:true, nomen:true*/

YUI.add('flickrBinderIndex', function (Y, NAME) {

/**
 * The flickrBinderIndex module.
 *
 * @module flickrBinderIndex
 */

    /**
     * Constructor for the Binder class.
     *
     * @param mojitProxy {Object} The proxy to allow the binder to interact
     *        with its owning mojit.
     *
     * @class Binder
     * @constructor
     */
    Y.namespace('mojito.binders')[NAME] = {

        /**
         * Binder initialization method, invoked after all binders on the page
         * have been constructed.
         */
        init: function (mojitProxy) {
            this.mojitProxy = mojitProxy;
        },

        /**
         * The binder method, invoked to allow the mojit to attach DOM event
         * handlers.
         *
         * @param node {Node} The DOM node to which this mojit is attached.
         */
        bind: function (node) {
            this.node = node;
            Y.log('NODE: ' + Y.dump(this.node));
            var nodeId = node.get('id'),
                binderId = this.mojitProxy._guid,
                handleClick = function() {
                    this.node.one('div').set('innerHTML', "clicked on " + new Date());
                };
            Y.log(nodeId + ' node bound', 'debug', NAME);
            if (nodeId !== binderId) {
                throw new Error("bad node binding to binder!");
            }

            this.node.append("
" + nodeId + " bound
");
            this.node.on('click', handleClick, this);

        },
        _updateId: function(msg) {
            var nodeId = this.node.get('id');
            msg = msg || 'bound';
            this.node.one("p").set('innerHTML', nodeId + ' ' + msg);
        }
    };

}, '0.0.1', {requires: []});
<commit_msg>fix example app<commit_after>/*
 * Copyright (c) 2011-2013, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */

/*jslint anon:true, sloppy:true, nomen:true*/

YUI.add('flickrBinderIndex', function (Y, NAME) {

/**
 * The flickrBinderIndex module.
 *
 * @module flickrBinderIndex
 */

    /**
     * Constructor for the Binder class.
     *
     * @param mojitProxy {Object} The proxy to allow the binder to interact
     *        with its owning mojit.
     *
     * @class Binder
     * @constructor
     */
    Y.namespace('mojito.binders')[NAME] = {

        /**
         * Binder initialization method, invoked after all binders on the page
         * have been constructed.
         */
        init: function (mojitProxy) {
            this.mojitProxy = mojitProxy;
        },

        /**
         * The binder method, invoked to allow the mojit to attach DOM event
         * handlers.
         *
         * @param node {Node} The DOM node to which this mojit is attached.
         */
        bind: function (node) {
            this.node = node;
            Y.log('NODE: ' + Y.dump(this.node));
            var nodeId = node.get('id'),
                binderId = this.mojitProxy.getId(),
                handleClick = function() {
                    this.node.one('div').set('innerHTML', "clicked on " + new Date());
                };
            Y.log(nodeId + ' node bound', 'debug', NAME);
            if (nodeId !== binderId) {
                throw new Error("bad node binding to binder!");
            }

            this.node.append("
" + nodeId + " bound
");
            this.node.on('click', handleClick, this);

        },
        _updateId: function(msg) {
            var nodeId = this.node.get('id');
            msg = msg || 'bound';
            this.node.one("p").set('innerHTML', nodeId + ' ' + msg);
        }
    };

}, '0.0.1', {requires: []});
<|endoftext|>


<commit_before>var $ = require('jquery');
var _ = require('underscore');
var Backbone = require('backbone');
var template = require('./slider.tpl');
require('jquery');
require('jquery-ui');

Backbone.Form.editors.Slider = Backbone.Form.editors.Base.extend({

  tagName: 'ul',
  className: 'CDB-OptionInput-container CDB-OptionInput-container--noMargin',

  options: {
    direction: ''
  },

  events: {
    focus: function () {
      this.trigger('focus', this);
    },
    blur: function () {
      this.trigger('blur', this);
    }
  },

  initialize: function (opts) {
    Backbone.Form.editors.Base.prototype.initialize.call(this, opts);

    this._setOptions(opts);

    if (!this.options.labels) {
      throw new Error('labels is required');
    }

    if (this.options.values && this.options.labels.length !== this.options.values.length) {
      throw new Error('values and labels should have the same length');
    }

    this._values = this.options.values;
    this._labels = this.options.labels;

    this._initViews();
  },

  _initViews: function () {
    this.$el.html(
      template({
        direction: this.options.direction
      })
    );

    var step = this._getStepPercentage();
    this._ticks = this._getTicks(step);

    this.$('.js-slider').slider({
      range: 'min',
      value: this._ticks[this.value],
      step: step,
      orientation: 'horizontal',
      disabled: this.options.disabled,
      slide: this._onSlideChange.bind(this),
      stop: this._onSlideStop.bind(this)
    });

    this._addTicks(step);
    this._updateUI(this._getInitialValue());
  },

  _getInitialValue: function () {
    var value = this.value;

    if (this._values) {
      value = this._values.indexOf(this.value);

      if (value === -1) {
        value = 0;
      }
    } else {
      value = 0;
    }

    return value;
  },

  _updateUI: function (value) {
    if (!value) {
      value = 0;
    }

    this._updateLabel(value);
    this._highlightTick(value);
  },

  _getTickIndex: function () {
    var v = 0;

    if (this.value) {
      v = this._calculateTickValue(this.value);
    }

    return this._ticks.indexOf(v);
  },

  _addTicks: function (step) {
    _.each(this._ticks, function (amount) {
      $('

')
        .css('left', amount + '%')
        .appendTo(this.$('.js-slider'));
    }, this);
  },

  _highlightTick: function (tickID) {
    this.$('.js-tick').removeClass('is-highlighted');
    $(this.$('.js-tick').get(tickID)).addClass('is-highlighted');
  },

  _updateLabel: function (tickID) {
    this.$('.js-label').text(this._labels[tickID]);
  },

  _getTicks: function (step) {
    var self = this;

    return [0].concat(_(this._labels.length - 1).times(function (n) {
      return self._calculateTickValue(step * (n + 1));
    }));
  },

  _getStepPercentage: function () {
    return (100 / (this._labels.length - 1));
  },

  _calculateTickValue: function (value) {
    return +value.toFixed(2);
  },

  _onSlideChange: function (ev, ui) {
    this.value = ui.value;

    this._updateUI(this._getTickIndex());
  },

  _onSlideStop: function (ev, ui) {
    this.trigger('change', this);
  },

  _hasSlider: function () {
    return this.$('.js-slider').data('ui-slider');
  },

  getValue: function () {
    var value = this._values ? this._values[this._getTickIndex()] : this._getTickIndex();
    return (this.value === '') ? null : value;
  },

  setValue: function (value) {
    this.$('.js-slider').slider('value', value);
    this.value = value;
  },

  _destroySlider: function () {
    if (this._hasSlider()) {
      this.$('.js-slider').slider('destroy');
    }
  },

  remove: function () {
    this._destroySlider();
    Backbone.Form.editors.Base.prototype.remove.apply(this);
  },

  clean: function () {
    this.$el.remove();
  }
});
<commit_msg>Refactor<commit_after>var $ = require('jquery');
var _ = require('underscore');
var Backbone = require('backbone');
var template = require('./slider.tpl');
require('jquery');
require('jquery-ui');

Backbone.Form.editors.Slider = Backbone.Form.editors.Base.extend({

  tagName: 'ul',
  className: 'CDB-OptionInput-container CDB-OptionInput-container--noMargin',

  options: {
    direction: ''
  },

  events: {
    focus: function () {
      this.trigger('focus', this);
    },
    blur: function () {
      this.trigger('blur', this);
    }
  },

  initialize: function (opts) {
    Backbone.Form.editors.Base.prototype.initialize.call(this, opts);

    this._setOptions(opts);

    if (!this.options.labels) {
      throw new Error('labels is required');
    }

    if (this.options.values && this.options.labels.length !== this.options.values.length) {
      throw new Error('values and labels should have the same length');
    }

    this._values = this.options.values;
    this._labels = this.options.labels;

    this._initViews();
  },

  _initViews: function () {
    this.$el.html(
      template({
        direction: this.options.direction
      })
    );

    var step = this._getStepPercentage();
    this._ticks = this._getTicks(step);

    var tickID = this._getInitialTickID();

    this.$('.js-slider').slider({
      range: 'min',
      value: this._ticks[tickID],
      step: step,
      orientation: 'horizontal',
      disabled: this.options.disabled,
      slide: this._onSlideChange.bind(this),
      stop: this._onSlideStop.bind(this)
    });

    this._addTicks(step);
    this._updateUI(tickID);
  },

  _getInitialTickID: function () {
    var value = this.value;

    if (this._values) {
      value = this._values.indexOf(this.value);

      if (value === -1) {
        value = 0;
      }
    } else if (!value) {
      value = 0;
    }

    return value;
  },

  _updateUI: function (tickID) {
    if (tickID === undefined) {
      tickID = 0;
    }

    this._updateLabel(tickID);
    this._highlightTick(tickID);
  },

  _getTickID: function () {
    var v = 0;

    if (this.value && _.isNumber(this.value)) {
      v = this._calculateTickValue(this.value);
    }

    return this._ticks.indexOf(v);
  },

  _addTicks: function (step) {
    _.each(this._ticks, function (amount) {
      $('

')
        .css('left', amount + '%')
        .appendTo(this.$('.js-slider'));
    }, this);
  },

  _highlightTick: function (tickID) {
    this.$('.js-tick').removeClass('is-highlighted');
    $(this.$('.js-tick').get(tickID)).addClass('is-highlighted');
  },

  _updateLabel: function (tickID) {
    this.$('.js-label').text(this._labels[tickID]);
  },

  _getTicks: function (step) {
    var self = this;

    return [0].concat(_(this._labels.length - 1).times(function (n) {
      return self._calculateTickValue(step * (n + 1));
    }));
  },

  _getStepPercentage: function () {
    return (100 / (this._labels.length - 1));
  },

  _calculateTickValue: function (value) {
    return +value.toFixed(2);
  },

  _onSlideChange: function (ev, ui) {
    this.value = ui.value;

    this._updateUI(this._getTickID());
  },

  _onSlideStop: function (ev, ui) {
    this.trigger('change', this);
  },

  _hasSlider: function () {
    return this.$('.js-slider').data('ui-slider');
  },

  getValue: function () {
    var value = this._values ? this._values[this._getTickID()] : this._getTickID();
    return (this.value === '') ? null : value;
  },

  setValue: function (value) {
    this.$('.js-slider').slider('value', value);
    this.value = value;
  },

  _destroySlider: function () {
    if (this._hasSlider()) {
      this.$('.js-slider').slider('destroy');
    }
  },

  remove: function () {
    this._destroySlider();
    Backbone.Form.editors.Base.prototype.remove.apply(this);
  },

  clean: function () {
    this.$el.remove();
  }
});
<|endoftext|>


<commit_before>'use strict';

// MODULES //

var resolve = require( 'path' ).resolve;
var bench = require( '@stdlib/bench' );
var randu = require( '@stdlib/math/base/random/randu' );
var floor = require( '@stdlib/math/base/special/floor' );
var pow = require( '@stdlib/math/base/special/pow' );
var isnan = require( '@stdlib/math/base/utils/is-nan' );
var tryRequire = require( '@stdlib/utils/try-require' );
var pkg = require( './../package.json' ).name;
var dasum = require( './../lib/main.js' );
var wasm = require( './../lib/wasm.js' )();

// VARIABLES //

var ndasum = tryRequire( resolve( __dirname, './../lib/native.js' ) );
var opts = {
	'skip': ( ndasum instanceof Error )
};

// FUNCTIONS //

/**
* Creates a benchmark function.
*
* @private
* @param {PositiveInteger} len - array length
* @returns {Function} benchmark function
*/
function createBenchmark1( len ) {
	var idx;
	var x;
	var i;

	x = new Float64Array( len );
	for ( i = 0; i < x.length; i++ ) {
		x[ i ] = ( randu()*10000.0 ) - 20000.0;
	}
	idx = floor( len / 10 );

	return benchmark;

	/**
	* Benchmark function.
	*
	* @private
	* @param {Benchmark} b - benchmark instance
	*/
	function benchmark( b ) {
		var y;
		var v;
		var i;

		b.tic();
		for ( i = 0; i < b.iterations; i++ ) {
			v = ( randu()*10000.0 ) - 20000.0;
			x[ idx ] = v;
			y = dasum( x.length, x, 1 );
			if ( isnan( y ) ) {
				b.fail( 'should not return NaN' );
			}
		}
		b.toc();
		if ( isnan( y ) ) {
			b.fail( 'should not return NaN' );
		}
		b.pass( 'benchmark finished' );
		b.end();
	} // end FUNCTION benchmark()
} // end FUNCTION createBenchmark1()

/**
* Creates a benchmark function.
*
* @private
* @param {PositiveInteger} len - array length
* @returns {Function} benchmark function
*/
function createBenchmark2( len ) {
	var idx;
	var x;
	var i;

	x = new Float64Array( len );
	for ( i = 0; i < x.length; i++ ) {
		x[ i ] = ( randu()*10000.0 ) - 20000.0;
	}
	idx = floor( len / 10 );

	return benchmark;

	/**
	* Benchmark function.
	*
	* @private
	* @param {Benchmark} b - benchmark instance
	*/
	function benchmark( b ) {
		var y;
		var v;
		var i;

		b.tic();
		for ( i = 0; i < b.iterations; i++ ) {
			v = ( randu()*10000.0 ) - 20000.0;
			x[ idx ] = v;
			y = ndasum( x.length, x, 1 );
			if ( isnan( y ) ) {
				b.fail( 'should not return NaN' );
			}
		}
		b.toc();
		if ( isnan( y ) ) {
			b.fail( 'should not return NaN' );
		}
		b.pass( 'benchmark finished' );
		b.end();
	} // end FUNCTION benchmark()
} // end FUNCTION createBenchmark2()

/**
* Creates a benchmark function.
*
* @private
* @param {PositiveInteger} len - array length
* @returns {Function} benchmark function
*/
function createBenchmark3( len ) {
	var idx;
	var x;
	var i;

	x = new Float64Array( len );
	for ( i = 0; i < x.length; i++ ) {
		x[ i ] = ( randu()*10000.0 ) - 20000.0;
	}
	idx = floor( len/10 * x.BYTES_PER_ELEMENT );

	return benchmark;

	/**
	* Benchmark function.
	*
	* @private
	* @param {Benchmark} b - benchmark instance
	*/
	function benchmark( b ) {
		var nbytes;
		var heap;
		var y;
		var v;
		var i;

		nbytes = x.length * x.BYTES_PER_ELEMENT;
		heap = wasm.malloc( nbytes );
		heap.set( new Uint8Array( x.buffer ) );

		b.tic();
		for ( i = 0; i < b.iterations; i++ ) {
			v = ( randu()*10000.0 ) - 20000.0;
			heap.setValue( idx, v );
			y = wasm( x.length, heap, 1 );
			if ( isnan( y ) ) {
				b.fail( 'should not return NaN' );
			}
		}
		b.toc();
		if ( isnan( y ) ) {
			b.fail( 'should not return NaN' );
		}
		b.pass( 'benchmark finished' );

		wasm.free( heap );
		b.end();
	} // end FUNCTION benchmark()
} // end FUNCTION createBenchmark3()

// MAIN //

/**
* Main execution sequence.
*
* @private
*/
function main() {
	var len;
	var min;
	var max;
	var f;
	var i;

	min = 1; // 10^min
	max = 6; // 10^max

	for ( i = min; i <= max; i++ ) {
		len = pow( 10, i );

		f = createBenchmark1( len );
		bench( pkg+'::memory-reuse,main:len='+len, f );

		f = createBenchmark3( len );
		bench( pkg+'::memory-reuse,wasm:len='+len, f );

		f = createBenchmark2( len );
		bench( pkg+'::memory-reuse,native:len='+len, opts, f );
	}
} // end FUNCTION main()

main();
<commit_msg>Update descriptions<commit_after>'use strict';

// MODULES //

var resolve = require( 'path' ).resolve;
var bench = require( '@stdlib/bench' );
var randu = require( '@stdlib/math/base/random/randu' );
var floor = require( '@stdlib/math/base/special/floor' );
var pow = require( '@stdlib/math/base/special/pow' );
var isnan = require( '@stdlib/math/base/utils/is-nan' );
var tryRequire = require( '@stdlib/utils/try-require' );
var pkg = require( './../package.json' ).name;
var dasum = require( './../lib/main.js' );
var wasm = require( './../lib/wasm.js' )();

// VARIABLES //

var ndasum = tryRequire( resolve( __dirname, './../lib/native.js' ) );
var opts = {
	'skip': ( ndasum instanceof Error )
};

// FUNCTIONS //

/**
* Creates a benchmark function for measuring vanilla JavaScript interface.
*
* @private
* @param {PositiveInteger} len - array length
* @returns {Function} benchmark function
*/
function createBenchmark1( len ) {
	var idx;
	var x;
	var i;

	x = new Float64Array( len );
	for ( i = 0; i < x.length; i++ ) {
		x[ i ] = ( randu()*10000.0 ) - 20000.0;
	}
	idx = floor( len / 10 );

	return benchmark;

	/**
	* Benchmark function.
	*
	* @private
	* @param {Benchmark} b - benchmark instance
	*/
	function benchmark( b ) {
		var y;
		var v;
		var i;

		b.tic();
		for ( i = 0; i < b.iterations; i++ ) {
			v = ( randu()*10000.0 ) - 20000.0;
			x[ idx ] = v;
			y = dasum( x.length, x, 1 );
			if ( isnan( y ) ) {
				b.fail( 'should not return NaN' );
			}
		}
		b.toc();
		if ( isnan( y ) ) {
			b.fail( 'should not return NaN' );
		}
		b.pass( 'benchmark finished' );
		b.end();
	} // end FUNCTION benchmark()
} // end FUNCTION createBenchmark1()

/**
* Creates a benchmark function for measuring native add-on interface.
*
* @private
* @param {PositiveInteger} len - array length
* @returns {Function} benchmark function
*/
function createBenchmark2( len ) {
	var idx;
	var x;
	var i;

	x = new Float64Array( len );
	for ( i = 0; i < x.length; i++ ) {
		x[ i ] = ( randu()*10000.0 ) - 20000.0;
	}
	idx = floor( len / 10 );

	return benchmark;

	/**
	* Benchmark function.
	*
	* @private
	* @param {Benchmark} b - benchmark instance
	*/
	function benchmark( b ) {
		var y;
		var v;
		var i;

		b.tic();
		for ( i = 0; i < b.iterations; i++ ) {
			v = ( randu()*10000.0 ) - 20000.0;
			x[ idx ] = v;
			y = ndasum( x.length, x, 1 );
			if ( isnan( y ) ) {
				b.fail( 'should not return NaN' );
			}
		}
		b.toc();
		if ( isnan( y ) ) {
			b.fail( 'should not return NaN' );
		}
		b.pass( 'benchmark finished' );
		b.end();
	} // end FUNCTION benchmark()
} // end FUNCTION createBenchmark2()

/**
* Creates a benchmark function for measuring WASM interface and using `setValue` heap method.
*
* @private
* @param {PositiveInteger} len - array length
* @returns {Function} benchmark function
*/
function createBenchmark3( len ) {
	var idx;
	var x;
	var i;

	x = new Float64Array( len );
	for ( i = 0; i < x.length; i++ ) {
		x[ i ] = ( randu()*10000.0 ) - 20000.0;
	}
	idx = floor( len/10 * x.BYTES_PER_ELEMENT );

	return benchmark;

	/**
	* Benchmark function.
	*
	* @private
	* @param {Benchmark} b - benchmark instance
	*/
	function benchmark( b ) {
		var nbytes;
		var heap;
		var y;
		var v;
		var i;

		nbytes = x.length * x.BYTES_PER_ELEMENT;
		heap = wasm.malloc( nbytes );
		heap.set( new Uint8Array( x.buffer ) );

		b.tic();
		for ( i = 0; i < b.iterations; i++ ) {
			v = ( randu()*10000.0 ) - 20000.0;
			heap.setValue( idx, v );
			y = wasm( x.length, heap, 1 );
			if ( isnan( y ) ) {
				b.fail( 'should not return NaN' );
			}
		}
		b.toc();
		if ( isnan( y ) ) {
			b.fail( 'should not return NaN' );
		}
		b.pass( 'benchmark finished' );

		wasm.free( heap );
		b.end();
	} // end FUNCTION benchmark()
} // end FUNCTION createBenchmark3()

// MAIN //

/**
* Main execution sequence.
*
* @private
*/
function main() {
	var len;
	var min;
	var max;
	var f;
	var i;

	min = 1; // 10^min
	max = 6; // 10^max

	for ( i = min; i <= max; i++ ) {
		len = pow( 10, i );

		f = createBenchmark1( len );
		bench( pkg+'::memory-reuse,main:len='+len, f );

		f = createBenchmark2( len );
		bench( pkg+'::memory-reuse,native:len='+len, opts, f );

		f = createBenchmark3( len );
		bench( pkg+'::memory-reuse,wasm:len='+len, f );
	}
} // end FUNCTION main()

main();
<|endoftext|>


<commit_before>import { default as d } from 'debug';
import WebSocketPlus from './websocket-plus';
import { createError } from './error';
import { GenericCommand, CommandType } from '../proto/message';
import { trim, isWeapp } from './utils';

const debug = d('LC:Connection');

const COMMAND_TIMEOUT = 20000;

export default class Connection extends WebSocketPlus {
  constructor(getUrl, { format, version }) {
    debug('initializing Connection');
    const protocolString = `lc.${format}.${version}`;
    if (!isWeapp) {
      super(getUrl, protocolString);
    } else {
      super(getUrl().then(urls => urls.map(url =>
        `${url}${url.indexOf('?') === -1 ? '?' : '&'}subprotocol=${encodeURIComponent(protocolString)}`
      )));
    }
    this._protocalFormat = format;
    this._commands = {};
    this._serialId = 0;
  }

  send(command, waitingForRespond = true) {
    let serialId;
    if (waitingForRespond) {
      this._serialId += 1;
      serialId = this._serialId;
      command.i = serialId; // eslint-disable-line no-param-reassign
    }
    debug('↑', trim(command), 'sent');

    let message;
    if (this._protocalFormat === 'protobase64') {
      message = command.toBase64();
    } else if (command.toBuffer) {
      message = command.toBuffer();
    } else if (command.toArrayBuffer) {
      message = command.toArrayBuffer();
    }
    if (!message) {
      throw new TypeError(`${command} is not a GenericCommand`);
    }

    super.send(message);

    if (!waitingForRespond) {
      return Promise.resolve();
    }
    return new Promise((resolve, reject) => {
      this._commands[serialId] = {
        resolve,
        reject,
      };
      setTimeout(
        () => {
          if (this._commands[serialId]) {
            debug('✗', trim(command), 'timeout');
            reject(new Error('Command Timeout.'));
            delete this._commands[serialId];
          }
        },
        COMMAND_TIMEOUT
      );
    });
  }

  handleMessage(msg) {
    let message;
    try {
      message = GenericCommand.decode(msg);
      debug('↓', trim(message), 'received');
    } catch (e) {
      console.warn('Decode message failed', msg);
    }
    this.emit('allmessage', message);
    const serialId = message.i;
    if (serialId) {
      if (this._commands[serialId]) {
        if (message.cmd === CommandType.error) {
          this
            ._commands[serialId]
            .reject(createError(message.errorMessage));
        } else {
          this
            ._commands[serialId]
            .resolve(message);
        }
        delete this._commands[serialId];
      } else {
        console.warn(`Unexpected command received with serialId [${serialId}],
         which have timed out or never been requested.`);
      }
    } else if (message.cmd === CommandType.error) {
      this.emit('error', createError(message.errorMessage));
    } else {
      this.emit('message', message);
    }
  }

  ping() {
    return this.send(new GenericCommand({
      cmd: 'echo',
    })).catch(error => console.warn('ping failed:', error));
  }
}
<commit_msg>chore: stop complaining about ping failures<commit_after>import { default as d } from 'debug';
import WebSocketPlus from './websocket-plus';
import { createError } from './error';
import { GenericCommand, CommandType } from '../proto/message';
import { trim, isWeapp } from './utils';

const debug = d('LC:Connection');

const COMMAND_TIMEOUT = 20000;

export default class Connection extends WebSocketPlus {
  constructor(getUrl, { format, version }) {
    debug('initializing Connection');
    const protocolString = `lc.${format}.${version}`;
    if (!isWeapp) {
      super(getUrl, protocolString);
    } else {
      super(getUrl().then(urls => urls.map(url =>
        `${url}${url.indexOf('?') === -1 ? '?' : '&'}subprotocol=${encodeURIComponent(protocolString)}`
      )));
    }
    this._protocalFormat = format;
    this._commands = {};
    this._serialId = 0;
  }

  send(command, waitingForRespond = true) {
    let serialId;
    if (waitingForRespond) {
      this._serialId += 1;
      serialId = this._serialId;
      command.i = serialId; // eslint-disable-line no-param-reassign
    }
    debug('↑', trim(command), 'sent');

    let message;
    if (this._protocalFormat === 'protobase64') {
      message = command.toBase64();
    } else if (command.toBuffer) {
      message = command.toBuffer();
    } else if (command.toArrayBuffer) {
      message = command.toArrayBuffer();
    }
    if (!message) {
      throw new TypeError(`${command} is not a GenericCommand`);
    }

    super.send(message);

    if (!waitingForRespond) {
      return Promise.resolve();
    }
    return new Promise((resolve, reject) => {
      this._commands[serialId] = {
        resolve,
        reject,
      };
      setTimeout(
        () => {
          if (this._commands[serialId]) {
            debug('✗', trim(command), 'timeout');
            reject(new Error('Command Timeout.'));
            delete this._commands[serialId];
          }
        },
        COMMAND_TIMEOUT
      );
    });
  }

  handleMessage(msg) {
    let message;
    try {
      message = GenericCommand.decode(msg);
      debug('↓', trim(message), 'received');
    } catch (e) {
      console.warn('Decode message failed', msg);
    }
    this.emit('allmessage', message);
    const serialId = message.i;
    if (serialId) {
      if (this._commands[serialId]) {
        if (message.cmd === CommandType.error) {
          this
            ._commands[serialId]
            .reject(createError(message.errorMessage));
        } else {
          this
            ._commands[serialId]
            .resolve(message);
        }
        delete this._commands[serialId];
      } else {
        console.warn(`Unexpected command received with serialId [${serialId}],
         which have timed out or never been requested.`);
      }
    } else if (message.cmd === CommandType.error) {
      this.emit('error', createError(message.errorMessage));
    } else {
      this.emit('message', message);
    }
  }

  ping() {
    return this.send(new GenericCommand({
      cmd: CommandType.echo,
    })).catch(error => debug('ping failed:', error));
  }
}
<|endoftext|>


<commit_before>Date.prototype.toDateInputValue = (function() {
    var local = new Date(this);
    local.setMinutes(this.getMinutes() - this.getTimezoneOffset());
    return local.toJSON().slice(0,10);
});

var admonitus = {};
admonitus.transFreqNoToName = function(num)
{
	switch (num)
	{
	case 0:
		return "One-time";
	case 1:
		return "Daily";
	case 2:
		return "Weekly";
	case 3:
		return "Monthly";
	default:
		return "Invalid";
	}
}

var mainObj = function() {

	this.refreshRemindersList = function()
	{
		$.ajax({
			type : "GET",
			dataType : "json",
			url : "/Admonitus/ctl/Reminder/get",
			success : function(response) {

				$("#remindersList > tbody").find("tr:gt(1)").remove();

				$.each(response.data, function(index, entry) {
					newrow = $("#template").clone();
					newrow.find("td.number").text(index + 1);
					newrow.find("td.text").text(entry['text']);
					newrow.find("button[name=deleteButton]").attr('data-id', entry['id']);
					newrow.attr("id", entry['id']);
					newrow.find("td.startingat").text(new Date(entry['datestart']).format('d-M-Y'))
					newrow.find("td.frequency").text(
						admonitus.transFreqNoToName(entry['frequency'])
					);

					newrow.show();
					$("#remindersList").append(newrow);
				});

			}

		});
	}

	var self = this;

	console.log("It works!");
	$("input[name=startingat]").val((new Date()).toDateInputValue());

	$(document).on("click", "#logoutButton",
		function(e)
		{
			e.preventDefault();
			$.ajax({
				type: "GET",
				dataType: "json",
				url: "/Admonitus/ctl/User/logout",
				context: self,
				success: function(response)
				{
					if(response.success)
					{
						$(".loggedOut").show();
						$(".loggedIn").hide();
					}
					else
					{
						$("#jsonErrorText").text(response.error);
						$('#jsonErrorModal').modal('show');
					}
				}
			});
		}
	);

	$(document).on("click", "#loginButton",
		function(e)
		{
			e.preventDefault();
			var request = {
				"email": $("input[id=loginEmail]").val(),
				"password": $("input[id=loginPassword]").val()
			}
			$.ajax({
				type: "POST",
				dataType: "json",
				url: "/Admonitus/ctl/User/login",
				data: request,
				context: self,
				success: function(response)
				{
					if(response.success)
					{
						// TODO: Refresh the task list and change the login form
						// etc...
						$("#emailAddress").text(response.data.email);
						$(".loggedOut").hide();
						$(".loggedIn").show();
						self.refreshRemindersList();
					}
					else
					{
						$("#jsonErrorText").text(response.error);
						$('#jsonErrorModal').modal('show');
					}
				}
			});
		}
	);

	$("#deleteModal").on('show.bs.modal',
		function(e)
		{
	    	$("button[name=deleteConfirm]").attr("data-id", $(e.relatedTarget).data('id'));
		}
	);

	$("#jsonEditModal").on('show.bs.modal'),
		function(e)
		{

		}

	$.ajax({
		type : "POST",
		dataType : "json",
		url : "/Admonitus/ctl/Reminder/add",
		data : request,
		context: self,
		success: function(response)
		{
			self.refreshRemindersList();
		}
	});

	$(document).on('click', "button[name=deleteConfirm]",
		function(e)
		{
			var id = $(this).attr("data-id");
			console.log("Delete id " + id);

			$.ajax({
				type: "GET",
				dataType: "json",
				url: "/Admonitus/ctl/Reminder/delete/" + id
			});

			$("#remindersList").find("tr[id=" + id + "]").remove();
		}
	);

	$("#reminderForm").submit(function(e) {
		e.preventDefault();

		var request = {
			"frequency": $("input[name=frequency]:checked").val(),
			"text": $("input[name=text]").val(),
			"startingat": $("input[name=startingat]").val()
		}
		$.ajax({
			type : "POST",
			dataType : "json",
			url : "/Admonitus/ctl/Reminder/add",
			data : request,
			context: self,
			success: function(response)
			{
				self.refreshRemindersList();
			}
		});
	});

}

$("document").ready(mainObj);
<commit_msg>JS: check if user already is logged in and do GUI work accordingly<commit_after>Date.prototype.toDateInputValue = (function() {
    var local = new Date(this);
    local.setMinutes(this.getMinutes() - this.getTimezoneOffset());
    return local.toJSON().slice(0,10);
});

var admonitus = {};
admonitus.transFreqNoToName = function(num)
{
	switch (num)
	{
	case 0:
		return "One-time";
	case 1:
		return "Daily";
	case 2:
		return "Weekly";
	case 3:
		return "Monthly";
	default:
		return "Invalid";
	}
}

var mainObj = function() {
	var self = this;

	this.refreshRemindersList = function()
	{
		$.ajax({
			type : "GET",
			dataType : "json",
			url : "/Admonitus/ctl/Reminder/get",
			success : function(response) {

				$("#remindersList > tbody").find("tr:gt(1)").remove();

				$.each(response.data, function(index, entry) {
					newrow = $("#template").clone();
					newrow.find("td.number").text(index + 1);
					newrow.find("td.text").text(entry['text']);
					newrow.find("button[name=deleteButton]").attr('data-id', entry['id']);
					newrow.attr("id", entry['id']);
					newrow.find("td.startingat").text(new Date(entry['datestart']).format('d-M-Y'))
					newrow.find("td.frequency").text(
						admonitus.transFreqNoToName(entry['frequency'])
					);

					newrow.show();
					$("#remindersList").append(newrow);
				});

			}

		});
	}

	this.switchToLoggedIn = function(response)
	{
		$("#emailAddress").text(response.data.email);
		$(".loggedOut").hide();
		$(".loggedIn").show();
		self.refreshRemindersList();
	}

	this.switchToLoggedOut = function()
	{
		$(".loggedOut").show();
		$(".loggedIn").hide();
	}

	console.log("It works!");
	$("input[name=startingat]").val((new Date()).toDateInputValue());

	$(document).on("click", "#logoutButton",
		function(e)
		{
			e.preventDefault();
			$.ajax({
				type: "GET",
				dataType: "json",
				url: "/Admonitus/ctl/User/logout",
				context: self,
				success: function(response)
				{
					if(response.success)
					{
						self.switchToLoggedOut();
					}
					else
					{
						$("#jsonErrorText").text(response.error);
						$('#jsonErrorModal').modal('show');
					}
				}
			});
		}
	);

	$(document).on("click", "#loginButton",
		function(e)
		{
			e.preventDefault();
			var request = {
				"email": $("input[id=loginEmail]").val(),
				"password": $("input[id=loginPassword]").val()
			}
			$.ajax({
				type: "POST",
				dataType: "json",
				url: "/Admonitus/ctl/User/login",
				data: request,
				context: self,
				success: function(response)
				{
					if(response.success)
					{
						self.switchToLoggedIn(response);
					}
					else
					{
						$("#jsonErrorText").text(response.error);
						$('#jsonErrorModal').modal('show');
					}
				}
			});
		}
	);

	$("#deleteModal").on('show.bs.modal',
		function(e)
		{
	    	$("button[name=deleteConfirm]").attr("data-id", $(e.relatedTarget).data('id'));
		}
	);

	$("#jsonEditModal").on('show.bs.modal'),
		function(e)
		{

		}

	$(document).on('click', "button[name=deleteConfirm]",
		function(e)
		{
			var id = $(this).attr("data-id");
			console.log("Delete id " + id);

			$.ajax({
				type: "GET",
				dataType: "json",
				url: "/Admonitus/ctl/Reminder/delete/" + id
			});

			$("#remindersList").find("tr[id=" + id + "]").remove();
		}
	);

	$("#reminderForm").submit(function(e) {
		e.preventDefault();

		var request = {
			"frequency": $("input[name=frequency]:checked").val(),
			"text": $("input[name=text]").val(),
			"startingat": $("input[name=startingat]").val()
		}
		$.ajax({
			type : "POST",
			dataType : "json",
			url : "/Admonitus/ctl/Reminder/add",
			data : request,
			context: self,
			success: function(response)
			{
				self.refreshRemindersList();
			}
		});
	});

	$.ajax({
		type: "GET",
		dataType: "json",
		url: "/Admonitus/ctl/User/isLoggedIn",
		context: self,
		success: function(response)
		{
			if(response.data)
			{
				self.switchToLoggedIn(response);
			}
		}
	});

}

$("document").ready(mainObj);
<|endoftext|>


<commit_before>// Given an unweighted, undirected graph which represents a metro map as follows
// vertices are stations
// edges are the path between two stations

// Given a start station and ending station, determine the minimum number of stops that must be made to get to the destination.

// Input: A Graph (unweighted/undirected), a starting Vertex, and an ending Vertex
// Output: Integer

// Example
// Input:

// The graph represented below, Vertex A, Vertex F

// Output:

// 2 Stops (From A stop at C, and then stop at F)

// Data Structure  -----------------------------------------------

class Vertex {
  constructor(val) {
    this.value = val;
    this.edges = {};
  }
}

class Graph {
  constructor() {
    this.vertices = {};
    this.totalVertices = 0;
    this.totalEdges = 0;
  }

  addVertex(val) {
    if (!this.vertices[val]) {
      const vertex = new Vertex(val);
      this.vertices[val] = vertex;
      this.totalVertices += 1;
    } else {
      return 'val exists';
    }
  }

  getVertex(val) {
    return this.vertices[val] ? this.vertices[val] : 'val not found';
  }

  removeVertex(val) {
    const delVert = this.vertices[val];
    const delEdges = delVert.edges;

    for (const key in delEdges) {
      this.removeEdge(key, val);
    }

    delete this.vertices[val];
    this.vertices -= 1;
  }

  addEdge(valOne, valTwo) {
    const vertOne = this.vertices[valOne];
    const vertTwo = this.vertices[valTwo];

    vertOne.edges[valTwo] = vertTwo;
    vertTwo.edges[valOne] = vertOne;

    this.totalEdges += 1;
  }

  removeEdge(valOne, valTwo) {
    if (this.vertices[valOne] && this.vertices[valTwo]) {
      const vertOne = this.vertices[valOne];
      const vertTwo = this.vertices[valTwo];

      delete vertOne.edges;
      delete vertTwo.edges;

      this.edges -= 1;
    } else {
      return 'edges dont exist';
    }
  }

  findNeighbors(val) {
    const neighborsArr = [];
    for (const key in this.vertices[val].edges) {
      neighborsArr.push(key);
    }
    return neighborsArr;
  }

  forEachNode(cb) {
    const results = [];
    for (let i = 0; i < this.vertices.length; i += 1) {
      results.push(cb(this.vertices[i]));
    }
    return results;
  }

}

const graph = new Graph();
graph.addVertex('A');
graph.addVertex('B');
graph.addVertex('C');
graph.addVertex('D');
graph.addVertex('E');
graph.addVertex('F');
graph.addVertex('G');

graph.addEdge('A', 'C');
graph.addEdge('A', 'D');
graph.addEdge('A', 'B');
graph.addEdge('B', 'E');
graph.addEdge('C', 'F');
graph.addEdge('D', 'G');
graph.addEdge('F', 'G');
graph.addEdge('F', 'E');

// ---------------------------------------------

// SOLUTIONS

// Recursive Approach
  // walk through each edge of the starting vertex and its edges as well if needed
  // for every recursive call update steps by 1 for that stack
  // if update min when end vertex is reached IF NEEDED
    // if end vertex is reached no need to loop through its edges - return stack
  // only walk through edges if edge hasn't been visited
  // return min at the end

function shortestPath(graph, a, b) {
  let min = Number.MAX_VALUE;
  const visited = {};

  function walk(vertex, steps) {
    visited[vertex.value] = true;
    for (const key in vertex.edges) {
      if (key === b.value) {
        if (steps < min) min = steps;
        return;
      }
      if (!visited[key]) walk(vertex.edges[key], steps + 1);
    }
  }
  walk(a, 1);
  return min;
}

// --------------------------------------------------

// Recursive Approach w/ extra conditonal break
  // walk through each edge of the starting vertex and its edges as well if needed
  // for every recursive call update steps by 1 for that stack
  // check to see if steps is less than current min when end vertex is reached, and update IF NEEDED
    // if end vertex is reached no need to loop through its edges - return stack
  // only walk through edges if edge hasn't been visited AND steos is still less than current minimum number of steps reached
  // return min at the end

function shortestPathTwo(graph, a, b) {
  let min = Number.MAX_VALUE;
  const visited = {};

  function walk(vertex, steps) {
    visited[vertex.value] = true;
    for (const key in vertex.edges) {
      if (key === b.value) {
        if (steps < min) min = steps;
        return;
      }
      if (!visited[key] && min > steps + 1) walk(vertex.edges[key], steps + 1);
    }
  }
  walk(a, 1);
  return min;
}

// ----------------------------------------------------

// BFS approach
  // store current vertex and steps in a tuple, in our q
    // update steps in current stack
    // update min when end vertex is reached IF NEEDED

function shortestPathThree(graph, a, b) {
  const visited = {};
  const q = [];
  let min = Number.MAX_VALUE;
  q.push([a, 0]);

  while (q.length) {
    let tuple = q.shift();
    const currentV = tuple[0];
    let steps = tuple[1];
    visited[currentV.value] = true;

    if (currentV.value === b.value) {
      if (steps < min) min = steps;
    }
    for (const k in currentV.edges) {
      if (!visited[k]) q.push([currentV.edges[k], steps + 1]);
    }
  }
  return min;
}

// #BFS

// --------------------------------------------------------------------------------------------
// function benchMark( g, a, b, results){
//   var start = new Date();
//   shortestPathThree(g, a, b);
//   var end = new Date();
//   return Number(end - start) // number of miliseconds
// }

// console.time('bm');
// console.log( benchMark( graph, graph.getVertex('A'), graph.getVertex('F')) );
// console.timeEnd('bm');
console.log( shortestPath( graph, graph.getVertex('A'), graph.getVertex('F')) );
<commit_msg>add soltuion + logic<commit_after>// Given an unweighted, undirected graph which represents a metro map as follows
// vertices are stations
// edges are the path between two stations

// Given a start station and ending station, determine the minimum number of stops that must be made to get to the destination.

// Input: A Graph (unweighted/undirected), a starting Vertex, and an ending Vertex
// Output: Integer

// Example
// Input:

// The graph represented below, Vertex A, Vertex F

// Output:

// 2 Stops (From A stop at C, and then stop at F)

// Data Structure  -----------------------------------------------

class Vertex {
  constructor(val) {
    this.value = val;
    this.edges = {};
  }
}

class Graph {
  constructor() {
    this.vertices = {};
    this.totalVertices = 0;
    this.totalEdges = 0;
  }

  addVertex(val) {
    if (!this.vertices[val]) {
      const vertex = new Vertex(val);
      this.vertices[val] = vertex;
      this.totalVertices += 1;
    } else {
      return 'val exists';
    }
  }

  getVertex(val) {
    return this.vertices[val] ? this.vertices[val] : 'val not found';
  }

  removeVertex(val) {
    const delVert = this.vertices[val];
    const delEdges = delVert.edges;

    for (const key in delEdges) {
      this.removeEdge(key, val);
    }

    delete this.vertices[val];
    this.vertices -= 1;
  }

  addEdge(valOne, valTwo) {
    const vertOne = this.vertices[valOne];
    const vertTwo = this.vertices[valTwo];

    vertOne.edges[valTwo] = vertTwo;
    vertTwo.edges[valOne] = vertOne;

    this.totalEdges += 1;
  }

  removeEdge(valOne, valTwo) {
    if (this.vertices[valOne] && this.vertices[valTwo]) {
      const vertOne = this.vertices[valOne];
      const vertTwo = this.vertices[valTwo];

      delete vertOne.edges;
      delete vertTwo.edges;

      this.edges -= 1;
    } else {
      return 'edges dont exist';
    }
  }

  findNeighbors(val) {
    const neighborsArr = [];
    for (const key in this.vertices[val].edges) {
      neighborsArr.push(key);
    }
    return neighborsArr;
  }

  forEachNode(cb) {
    const results = [];
    for (let i = 0; i < this.vertices.length; i += 1) {
      results.push(cb(this.vertices[i]));
    }
    return results;
  }

}

const graph = new Graph();
graph.addVertex('A');
graph.addVertex('B');
graph.addVertex('C');
graph.addVertex('D');
graph.addVertex('E');
graph.addVertex('F');
graph.addVertex('G');

graph.addEdge('A', 'C');
graph.addEdge('A', 'D');
graph.addEdge('A', 'B');
graph.addEdge('B', 'E');
graph.addEdge('C', 'F');
graph.addEdge('D', 'G');
graph.addEdge('F', 'G');
graph.addEdge('F', 'E');

// ---------------------------------------------

// SOLUTIONS

// Recursive Approach
  // walk through each edge of the starting vertex and its edges as well if needed
  // for every recursive call update steps by 1 for that stack
  // if update min when end vertex is reached IF NEEDED
    // if end vertex is reached no need to loop through its edges - return stack
  // only walk through edges if edge hasn't been visited
  // return min at the end

function shortestPath(graph, a, b) {
  let min = Number.MAX_VALUE;
  const visited = {};

  function walk(vertex, steps) {
    visited[vertex.value] = true;
    for (const key in vertex.edges) {
      if (key === b.value) {
        if (steps < min) min = steps;
        return;
      }
      if (!visited[key]) walk(vertex.edges[key], steps + 1);
    }
  }
  walk(a, 1);
  return min;
}

// --------------------------------------------------

// Recursive Approach w/ extra conditonal break
  // walk through each edge of the starting vertex and its edges as well if needed
  // for every recursive call update steps by 1 for that stack
  // check to see if steps is less than current min when end vertex is reached, and update IF NEEDED
    // if end vertex is reached no need to loop through its edges - return stack
  // only walk through edges if edge hasn't been visited AND steos is still less than current minimum number of steps reached
  // return min at the end

function shortestPathTwo(graph, a, b) {
  let min = Number.MAX_VALUE;
  const visited = {};

  function walk(vertex, steps) {
    visited[vertex.value] = true;
    for (const key in vertex.edges) {
      if (key === b.value) {
        if (steps < min) min = steps;
        return;
      }
      if (!visited[key] && min > steps + 1) walk(vertex.edges[key], steps + 1);
    }
  }
  walk(a, 1);
  return min;
}

// ----------------------------------------------------

// BFS approach
  // store current vertex and steps in a tuple, in our q
    // update steps in current stack
    // update min when end vertex is reached IF NEEDED

function shortestPathThree(graph, a, b) {
  const visited = {};
  const q = [];
  let min = Number.MAX_VALUE;
  q.push([a, 0]);

  while (q.length) {
    let tuple = q.shift();
    const currentV = tuple[0];
    let steps = tuple[1];
    visited[currentV.value] = true;

    if (currentV.value === b.value) {
      if (steps < min) min = steps;
    }
    for (const k in currentV.edges) {
      if (!visited[k]) q.push([currentV.edges[k], steps + 1]);
    }
  }
  return min;
}

// #BFS

// --------------------------------------------------------------------------------------------

// BFS Approach

// Create a ‘distance’ hashtable.
  // Store each vertex value as the key, and a distance of INFINITY
  // Set the ‘start’ vertex value to 0
// Create a ‘visited’ hashtable
// Instantiate a queue and place the starting vertex in the queue
// While there is something in the queue
  // Dequeue the ‘current’ vertex and mark it as visited.
  // For each edge, if the associated ‘neighbor’ has not been visited
    // Update the neighbor’s ‘distance’ as the minimum of:
      // the distance of ‘neighbor’
      // the distance of the ‘current’ + 1
    // Add the neighbor to the queue
// Return the distance of ‘end’ vertex

function shortestPathFour(graph, a, b) {
  const distance = {};
  const visited = {};
  for (const key in graph.vertices) {
    distance[key] = Number.MAX_VALUE;
  }
  distance[a.value] = 0;
  const q = [a];
  while (q.length) {
    const currentV = q.shift();
    visited[currentV.value] = true;
    for (const key in currentV.edges) {
      if (!visited[key]) {
        distance[key] = Math.min(distance[key], distance[currentV.value] + 1);
        q.push(currentV.edges[key]);
      }
    }
  }
  return distance[b.value];
}
// function benchMark( g, a, b, results){
//   var start = new Date();
//   shortestPathThree(g, a, b);
//   var end = new Date();
//   return Number(end - start) // number of miliseconds
// }

// console.time('bm');
// console.log( benchMark( graph, graph.getVertex('A'), graph.getVertex('F')) );
// console.timeEnd('bm');
console.log( shortestPathFour( graph, graph.getVertex('A'), graph.getVertex('F')) );
<|endoftext|>