<commit_before>var generateObjectId   = require("./object_id")
  , _                  = require("underscore")
  , EmbeddedCollection = require("./embedded_collection")
  , idCounter = 0

require("./utils")

var InstanceMethods = {

  /**
   * The constructor for a new instance of LiveDocument
   *
   * The only valid opts param at the moment is validate false, if you don't
   * want the document to be validated it would be nice if we could pass in
   * saved, persisted and loaded as well
   *
   * This will create a new user which has not been persisted to the
   * database, saved, or loaded, and it is automatically assigned an id
   *
   * It is also used internally to create new documents that are received
   * from the server, except the loaded, saved, and persisted flags are
   * manually set, and it's not validated
   *
   * Examples:
   *     user = new User({ name: "Zach" })
   *
   **/

  constructor: function(document, opts) {
    var that = this
    var opts = opts || {}

    this.document = document || {}
    this.id = idCounter++

    this.deleted = false
    this.saved = false
    this.saving = false
    this.persisted = false
    this.loaded = false
    this.alreadyChanging = false

    this.modelName = this.constructor.modelName

    if(!this.document._id && !opts.noId) {
      this.document._id = generateObjectId()
    }

    this.manyAssociations = {}
    this.oneAssociations = {}
    this.belongAssociations = {}

    this.collectionName = this.constructor.collectionName()
    // Make this work for nonMany assocs
    _(this.constructor.hasMany).each(function(Model, collectionName) {
      var collection
      that.manyAssociations[collectionName] = function(callback) {
        var docs
          , query
        if(collection) {
          return collection
        }
        if(Model.embedded) {
          docs = that.document[collectionName] || []
          delete that.document[collectionName]
          collection = new EmbeddedCollection(docs, that, Model)
        } else {
          query = {}
          query[_.uncapitalize(that.modelName) + "Id"] = that.get("_id")
          collection = Model.read(query)
        }
        callback = callback || function() {}
        collection.load(function() {
          callback(collection)
        })
        return collection
      }

    })

    _(this.constructor.hasOne).each(function(obj, collectionName) {
      var Model = obj.model
        , opts = obj.opts || {}
        , foreignKey = opts.foreignKey || _.singularize(that.collectionName) + "Id"

      that.oneAssociations[collectionName] = function(cb) {
        var query = {}
        query[foreignKey] = that.get("_id")
        var model = Model.findOne(query)
        //we couldn't find the model
        model.once("notExist", function(err) {
          model.set("_id", generateObjectId())
          model.save(function() {
            model.emit("load")
          })
        })
        model.once("load", function() {
          cb(model)
        })
        return model
      }
    })

    _(this.constructor.belongingTo).each(function(Model, collectionName) {
      that.belongAssociations[collectionName] = function(cb) {
        var foreignKey = that.get(collectionName + "Id")
        if(!foreignKey) {
          cb()
          return
        }
        var model = Model.findOne(that.get(collectionName + "Id"))
        //we couldn't find the model
        model.once("notExist", function(err) {
          model.save(function() {
            model.emit("load")
          })
        })
        model.once("load", function() {
          cb(model)
        })
        return model
      }

    })

    this.constructor.listenForChanges(this.get("_id"), this)
  }

, stopListening: function() {
    this.constructor.stopListening(this.get("_id"), this)
  }

 /*
  * listen for changes to documents with this id
  * since it's coming from the server we'll assume
  * it validates
  */
, handleChange: function(changes) {
    this.set(changes, {validate: false})
  }

 /*
  * listens for this document having been deleted, if it has
  * emit the delete event and set the deleted attribute to false
  */
, handleRemove: function() {
    this.deleted = true
    this.emit("delete", this)
  }

, sendUpdate: function(query, document, callback) {
    this.constructor.sendUpdateMessage(query, document, callback)
  }

, sendCreate: function(document, callback) {
    this.constructor.sendCreateMessage(document, callback)
  }

, performSave: function(cb) {
    var that = this
      , doc
    this.emit("saving", that)
    this.saving = true
    //if the document has not been already persisted to the database before
    //then its a create event
    if(!this.persisted) {
      this.set("createdAt", (new Date()).getTime())
      this.sendCreate(this.document, function() {
        that.saving = false
        that.saved = true
        that.persisted = true
        that.emit("saved", that)
        cb(that)
      })
    } else {
      // TODO only send changed fields
      doc = _.clone(this.document)
      delete doc._id
      this.set("updatedAt", (new Date()).getTime())
      this.sendUpdate({ _id: that.get("_id") }, doc, function(doc) {
        that.saved = true
        that.saving = false
        that.set(doc)
        cb(that)
        that.emit("saved", that)
      })
    }
  }

 /**
  * Save will create the document on the server if it has not yet been
  * persisted to the database, otherwise it will update the version in the
  * database, calls the callback with itself, returns itself for chaining
  */

, save: function(cb) {
    cb = cb || function() {}
    var that = this
      , doc
      , callNext
      , beforeSaves
      , beforeSave

    if(!this.document._id) {
      throw new Error("document doesn't have an _id, maybe it hasn't loaded yet?")
    }

    //clone the array
    beforeSaves = (that.constructor.beforeSaveFunctions || []).slice(0)
    if(this.constructor.isServer) {
      //it's a create save
      if(!this.persisted) {
        beforeSaves.push.apply(beforeSaves, that.constructor.serverBeforeCreateFunctions || [])
      }
      beforeSaves.push.apply(beforeSaves, that.constructor.serverBeforeSaveFunctions || [])
    }

    beforeSaves.unshift(function(inst, cb) {
      that.validate(function(inst, errors) {
        //dont pass the errors to the callback, because
        //validate emits it's own invalid event
        if(!errors) {
          cb()
        }
      })
    })

    // Run this after all the beforeSave functions have been called in order
    // to actually save the document, unless any of them have errors
    beforeSaves.push(function() {
      that.performSave(cb)
    })

    _.asyncEach(beforeSaves, function(beforeSave, next) {
      _(beforeSave).bind(that)(that, function(err) {
        if(!err) {
          next()
        } else {
          process.nextTick(function() {
            that.emit("error", err)
          })
        }
      })
    })
    return this
  }

 /**
  * Gets the value of field, takes in an optional function as second
  * parameter, which will get called once the field is available, and every
  * time the field is changed. Great for binding
  *
  * If the callback has arity one, it passes the value, otherwise it passes
  * (key, value)
  **/

, get: function(field) {
    return this.document[field]
  }

, assoc: function(assoc, callback) {
    var callback = callback || function() {}
      , model
    if(this.oneAssociations[assoc]) {
      return this.oneAssociations[assoc](callback)
    } else if(this.belongAssociations[assoc]) {
      return this.belongAssociations[assoc](callback)
    } else if (this.manyAssociations[assoc]) {
      return this.manyAssociations[assoc](callback)
    } else {
      throw new Error("No such association " + assoc)
    }
  }

 /**
  * takes in a hash of keys and values to set, or a string as the first arg
  * and a value(anything serializable) as the second.
  * fires a change event, which happens after all of the changes have been made
  *
  * If you call set from inside of a change event, it won't call another change
  * event, phew!
  **/

, set: function(field, value, opts) {
    opts = opts || {}

    if(typeof field === "undefined") {
      throw new Error("Must at least provide a field to set")
    }

    if(field === "_id" && typeof this.document._id !== "undefined" && this.document._id !== value) {
      throw new Error("Can't change _id after its been set")
    }

    var that = this
      , alreadyChanging = this.alreadyChanging
      , oldValue

    this.alreadyChanging = true
    // we're initiating the changes, so we'll store the old values
    if(alreadyChanging == false) {
      this.previousDocument = _.clone(this.document)
    }

    if(typeof field == "object") {
      opts = value || {}
      _.each(field, function(v, k) {
        that.set(k, v)
      })
    } else if(that.manyAssociations[field]) {
      _.each(value, function(doc) {
        that.manyAssociations[field]().add(doc)
      })
    } else {
      oldValue = this.document[field]
      if(this.document[field] != value) {
        this.document[field] = value
        this.emit("change:" + field, value, oldValue, this)
      }
    }

    // if THIS instance of set started the changes, it should emit the change
    // event and then end the changingness
    if(alreadyChanging == false) {
      this.triggerChange(opts)
    }
    return this
  }

, triggerChange: function(opts) {
    var that = this
      , fields = _.union(_.keys(this.document), _.keys(this.previousDocument))
      , changedFields = _.filter(fields, function(key) {
          return that.document[key] != that.previousDocument[key]
        })

    // if something actually changed
    if(changedFields.length > 0) {
      this.saved = false
      this.emit("change", this, changedFields)
      _(changedFields).each(function(field) {
        if(opts.validate !== false) {
          that.validateField(field)
        }
      })
    }
    this.previousDocument = _.clone(this.document)
    this.alreadyChanging = false
  }

, remove: function(callback) {
    this.constructor.delete({ _id: this.get("_id") }, function() {
      callback(this)
    })
  }

, validateField: function(field, callback, opts) {
    opts = opts || {}
    callback = callback || function() {}

    var that = this
    var validations = (this.constructor.validations || {})[field]
    var valid = []
    _.asyncEach(validations, function(value, rule, next) {
      if(rule === "min" && that.get(field) && that.get(field).length < value) {
        valid.push("short")
        next()
      } else if(rule === "max" && that.get(field) && that.get(field).length >= value) {
        valid.push("long")
        next()
      } else if(rule === "required" && !that.get(field)) {
        valid.push("required")
        next()
      } else if(rule === "unique") {
        that.isUnique(field, that.get(field), function(unique) {
          if(!unique) {
            valid.push("unique")
          }
          next()
        })
      } else {
        next()
      }
    }, function() {
      if(valid.length > 0) {
        if(!opts.silent) {
          that.emit("invalid:" + field, that, valid)
        }
        callback(that, valid)
      } else {
        // emit an event when a field is valid
        // useful for removing error messages
        if(!opts.silent) {
          that.emit("valid:" + field, that)
        }
        callback(that)
      }
    })
  }

, validate: function(cb, opts) {
    cb = cb || function() {}

    opts = opts || {}
    var that = this
    _.asyncMap(this.constructor.validations, function(validations, field, next) {
      that.validateField(field, function(instance, errors) {
        if(errors) {
          next(field, errors)
        } else {
          next()
        }
      }, opts)
    }, function(valid) {
      if(_.keys(valid).length != 0) {
        cb(that, valid)
        if(!opts.silent) {
          process.nextTick(function() {
            that.emit("invalid", that, valid)
          })
        }
      } else {
        cb(that)
      }
    })
  }

, isUnique: function(property, value, done) {
    var obj = {_id: {$ne : this.get("_id")}}
    value = value || ""
    obj[property] = value
    this.constructor.read(obj, function(things) {
      done(things.length === 0)
    })
  }
  /**
   * Called as soon as the document is loaded, if the document is already
   * loaded, call it right away
   */
, load: function(callback) {
    if(this.loaded) {
      process.nextTick(callback)
    } else {
      this.once("load", callback)
    }
  }

, keys: function() {
    var keys = _.clone(this.constructor.keys)
    keys.push("_id")
    return keys
  }

, assocs: function() {
    var assocs = _.union(
      _.keys(this.constructor.hasMany || {})
    , _.keys(this.constructor.hasOne || {})
    , _.keys(this.constructor.belongingTo || {})
    )
    return assocs
  }
}
module.exports = InstanceMethods
<commit_msg>when it was created is when it was last updated<commit_after>var generateObjectId   = require("./object_id")
  , _                  = require("underscore")
  , EmbeddedCollection = require("./embedded_collection")
  , idCounter = 0

require("./utils")

var InstanceMethods = {

  /**
   * The constructor for a new instance of LiveDocument
   *
   * The only valid opts param at the moment is validate false, if you don't
   * want the document to be validated it would be nice if we could pass in
   * saved, persisted and loaded as well
   *
   * This will create a new user which has not been persisted to the
   * database, saved, or loaded, and it is automatically assigned an id
   *
   * It is also used internally to create new documents that are received
   * from the server, except the loaded, saved, and persisted flags are
   * manually set, and it's not validated
   *
   * Examples:
   *     user = new User({ name: "Zach" })
   *
   **/

  constructor: function(document, opts) {
    var that = this
    var opts = opts || {}

    this.document = document || {}
    this.id = idCounter++

    this.deleted = false
    this.saved = false
    this.saving = false
    this.persisted = false
    this.loaded = false
    this.alreadyChanging = false

    this.modelName = this.constructor.modelName

    if(!this.document._id && !opts.noId) {
      this.document._id = generateObjectId()
    }

    this.manyAssociations = {}
    this.oneAssociations = {}
    this.belongAssociations = {}

    this.collectionName = this.constructor.collectionName()
    // Make this work for nonMany assocs
    _(this.constructor.hasMany).each(function(Model, collectionName) {
      var collection
      that.manyAssociations[collectionName] = function(callback) {
        var docs
          , query
        if(collection) {
          return collection
        }
        if(Model.embedded) {
          docs = that.document[collectionName] || []
          delete that.document[collectionName]
          collection = new EmbeddedCollection(docs, that, Model)
        } else {
          query = {}
          query[_.uncapitalize(that.modelName) + "Id"] = that.get("_id")
          collection = Model.read(query)
        }
        callback = callback || function() {}
        collection.load(function() {
          callback(collection)
        })
        return collection
      }

    })

    _(this.constructor.hasOne).each(function(obj, collectionName) {
      var Model = obj.model
        , opts = obj.opts || {}
        , foreignKey = opts.foreignKey || _.singularize(that.collectionName) + "Id"

      that.oneAssociations[collectionName] = function(cb) {
        var query = {}
        query[foreignKey] = that.get("_id")
        var model = Model.findOne(query)
        //we couldn't find the model
        model.once("notExist", function(err) {
          model.set("_id", generateObjectId())
          model.save(function() {
            model.emit("load")
          })
        })
        model.once("load", function() {
          cb(model)
        })
        return model
      }
    })

    _(this.constructor.belongingTo).each(function(Model, collectionName) {
      that.belongAssociations[collectionName] = function(cb) {
        var foreignKey = that.get(collectionName + "Id")
        if(!foreignKey) {
          cb()
          return
        }
        var model = Model.findOne(that.get(collectionName + "Id"))
        //we couldn't find the model
        model.once("notExist", function(err) {
          model.save(function() {
            model.emit("load")
          })
        })
        model.once("load", function() {
          cb(model)
        })
        return model
      }

    })

    this.constructor.listenForChanges(this.get("_id"), this)
  }

, stopListening: function() {
    this.constructor.stopListening(this.get("_id"), this)
  }

 /*
  * listen for changes to documents with this id
  * since it's coming from the server we'll assume
  * it validates
  */
, handleChange: function(changes) {
    this.set(changes, {validate: false})
  }

 /*
  * listens for this document having been deleted, if it has
  * emit the delete event and set the deleted attribute to false
  */
, handleRemove: function() {
    this.deleted = true
    this.emit("delete", this)
  }

, sendUpdate: function(query, document, callback) {
    this.constructor.sendUpdateMessage(query, document, callback)
  }

, sendCreate: function(document, callback) {
    this.constructor.sendCreateMessage(document, callback)
  }

, performSave: function(cb) {
    var that = this
      , doc
      , time = (new Date()).getTime()
    this.emit("saving", that)
    this.saving = true
    //if the document has not been already persisted to the database before
    //then its a create event
    if(!this.persisted) {
      this.set("createdAt", time)
      this.set("updatedAt", time)
      this.sendCreate(this.document, function() {
        that.saving = false
        that.saved = true
        that.persisted = true
        that.emit("saved", that)
        cb(that)
      })
    } else {
      // TODO only send changed fields
      doc = _.clone(this.document)
      delete doc._id
      this.set("updatedAt", time)
      this.sendUpdate({ _id: that.get("_id") }, doc, function(doc) {
        that.saved = true
        that.saving = false
        that.set(doc)
        cb(that)
        that.emit("saved", that)
      })
    }
  }

 /**
  * Save will create the document on the server if it has not yet been
  * persisted to the database, otherwise it will update the version in the
  * database, calls the callback with itself, returns itself for chaining
  */

, save: function(cb) {
    cb = cb || function() {}
    var that = this
      , doc
      , callNext
      , beforeSaves
      , beforeSave

    if(!this.document._id) {
      throw new Error("document doesn't have an _id, maybe it hasn't loaded yet?")
    }

    //clone the array
    beforeSaves = (that.constructor.beforeSaveFunctions || []).slice(0)
    if(this.constructor.isServer) {
      //it's a create save
      if(!this.persisted) {
        beforeSaves.push.apply(beforeSaves, that.constructor.serverBeforeCreateFunctions || [])
      }
      beforeSaves.push.apply(beforeSaves, that.constructor.serverBeforeSaveFunctions || [])
    }

    beforeSaves.unshift(function(inst, cb) {
      that.validate(function(inst, errors) {
        //dont pass the errors to the callback, because
        //validate emits it's own invalid event
        if(!errors) {
          cb()
        }
      })
    })

    // Run this after all the beforeSave functions have been called in order
    // to actually save the document, unless any of them have errors
    beforeSaves.push(function() {
      that.performSave(cb)
    })

    _.asyncEach(beforeSaves, function(beforeSave, next) {
      _(beforeSave).bind(that)(that, function(err) {
        if(!err) {
          next()
        } else {
          process.nextTick(function() {
            that.emit("error", err)
          })
        }
      })
    })
    return this
  }

 /**
  * Gets the value of field, takes in an optional function as second
  * parameter, which will get called once the field is available, and every
  * time the field is changed. Great for binding
  *
  * If the callback has arity one, it passes the value, otherwise it passes
  * (key, value)
  **/

, get: function(field) {
    return this.document[field]
  }

, assoc: function(assoc, callback) {
    var callback = callback || function() {}
      , model
    if(this.oneAssociations[assoc]) {
      return this.oneAssociations[assoc](callback)
    } else if(this.belongAssociations[assoc]) {
      return this.belongAssociations[assoc](callback)
    } else if (this.manyAssociations[assoc]) {
      return this.manyAssociations[assoc](callback)
    } else {
      throw new Error("No such association " + assoc)
    }
  }

 /**
  * takes in a hash of keys and values to set, or a string as the first arg
  * and a value(anything serializable) as the second.
  * fires a change event, which happens after all of the changes have been made
  *
  * If you call set from inside of a change event, it won't call another change
  * event, phew!
  **/

, set: function(field, value, opts) {
    opts = opts || {}

    if(typeof field === "undefined") {
      throw new Error("Must at least provide a field to set")
    }

    if(field === "_id" && typeof this.document._id !== "undefined" && this.document._id !== value) {
      throw new Error("Can't change _id after its been set")
    }

    var that = this
      , alreadyChanging = this.alreadyChanging
      , oldValue

    this.alreadyChanging = true
    // we're initiating the changes, so we'll store the old values
    if(alreadyChanging == false) {
      this.previousDocument = _.clone(this.document)
    }

    if(typeof field == "object") {
      opts = value || {}
      _.each(field, function(v, k) {
        that.set(k, v)
      })
    } else if(that.manyAssociations[field]) {
      _.each(value, function(doc) {
        that.manyAssociations[field]().add(doc)
      })
    } else {
      oldValue = this.document[field]
      if(this.document[field] != value) {
        this.document[field] = value
        this.emit("change:" + field, value, oldValue, this)
      }
    }

    // if THIS instance of set started the changes, it should emit the change
    // event and then end the changingness
    if(alreadyChanging == false) {
      this.triggerChange(opts)
    }
    return this
  }

, triggerChange: function(opts) {
    var that = this
      , fields = _.union(_.keys(this.document), _.keys(this.previousDocument))
      , changedFields = _.filter(fields, function(key) {
          return that.document[key] != that.previousDocument[key]
        })

    // if something actually changed
    if(changedFields.length > 0) {
      this.saved = false
      this.emit("change", this, changedFields)
      _(changedFields).each(function(field) {
        if(opts.validate !== false) {
          that.validateField(field)
        }
      })
    }
    this.previousDocument = _.clone(this.document)
    this.alreadyChanging = false
  }

, remove: function(callback) {
    this.constructor.delete({ _id: this.get("_id") }, function() {
      callback(this)
    })
  }

, validateField: function(field, callback, opts) {
    opts = opts || {}
    callback = callback || function() {}

    var that = this
    var validations = (this.constructor.validations || {})[field]
    var valid = []
    _.asyncEach(validations, function(value, rule, next) {
      if(rule === "min" && that.get(field) && that.get(field).length < value) {
        valid.push("short")
        next()
      } else if(rule === "max" && that.get(field) && that.get(field).length >= value) {
        valid.push("long")
        next()
      } else if(rule === "required" && !that.get(field)) {
        valid.push("required")
        next()
      } else if(rule === "unique") {
        that.isUnique(field, that.get(field), function(unique) {
          if(!unique) {
            valid.push("unique")
          }
          next()
        })
      } else {
        next()
      }
    }, function() {
      if(valid.length > 0) {
        if(!opts.silent) {
          that.emit("invalid:" + field, that, valid)
        }
        callback(that, valid)
      } else {
        // emit an event when a field is valid
        // useful for removing error messages
        if(!opts.silent) {
          that.emit("valid:" + field, that)
        }
        callback(that)
      }
    })
  }

, validate: function(cb, opts) {
    cb = cb || function() {}

    opts = opts || {}
    var that = this
    _.asyncMap(this.constructor.validations, function(validations, field, next) {
      that.validateField(field, function(instance, errors) {
        if(errors) {
          next(field, errors)
        } else {
          next()
        }
      }, opts)
    }, function(valid) {
      if(_.keys(valid).length != 0) {
        cb(that, valid)
        if(!opts.silent) {
          process.nextTick(function() {
            that.emit("invalid", that, valid)
          })
        }
      } else {
        cb(that)
      }
    })
  }

, isUnique: function(property, value, done) {
    var obj = {_id: {$ne : this.get("_id")}}
    value = value || ""
    obj[property] = value
    this.constructor.read(obj, function(things) {
      done(things.length === 0)
    })
  }
  /**
   * Called as soon as the document is loaded, if the document is already
   * loaded, call it right away
   */
, load: function(callback) {
    if(this.loaded) {
      process.nextTick(callback)
    } else {
      this.once("load", callback)
    }
  }

, keys: function() {
    var keys = _.clone(this.constructor.keys)
    keys.push("_id")
    return keys
  }

, assocs: function() {
    var assocs = _.union(
      _.keys(this.constructor.hasMany || {})
    , _.keys(this.constructor.hasOne || {})
    , _.keys(this.constructor.belongingTo || {})
    )
    return assocs
  }
}
module.exports = InstanceMethods
<|endoftext|>


<commit_before>
import BorderLayout from './lib/BorderLayout';
import CenterSubview from './lib/Center';
import Footer from './lib/Footer';
import Header from './lib/Header';
import HorizontalLinearLayout from './lib/HorizontalLinearLayout';
import LinearLayout from './lib/LinearLayout';
import VerticalLinearLayout from './lib/VerticalLinearLayout';

export default {
	BorderLayout,
	Center,
	Footer,
	Header,
	HorizontalLinearLayout,
	LinearLayout,
	VerticalLinearLayout
};
<commit_msg>fix import Center<commit_after>
import BorderLayout from './lib/BorderLayout';
import Center from './lib/Center';
import Footer from './lib/Footer';
import Header from './lib/Header';
import HorizontalLinearLayout from './lib/HorizontalLinearLayout';
import LinearLayout from './lib/LinearLayout';
import VerticalLinearLayout from './lib/VerticalLinearLayout';

export default {
	BorderLayout,
	Center,
	Footer,
	Header,
	HorizontalLinearLayout,
	LinearLayout,
	VerticalLinearLayout
};
<|endoftext|>


<commit_before>var Trello = require('node-trello')
var t = new Trello('81aff9b457de638bc94d7bb2a6d99816', '32cf5bb650eda2702c6d87a797799428ba77e0d9962fe795552ee698124a2a9e')
var moment = require('moment')
var _ = require('lodash')

// t.get('/1/members/me', function (err, data) {
//   if (err) throw err

//   data.idBoards.map(function (idBoard) {
//     t.get('/1/boards/' + idBoard, {lists: 'all'}, function (err, data) {
//       if (data.name === 'Life As She Is Played') {
//         data.lists.map(function (list) {
//           if (list.name === 'Today') {
//             console.log(list.name, list.id)

//           }
//         })
//       }

//     })
//   })

//   // console.log(data)
// })

var lifeAsSheIsPlayedId = '533c26d99c90c43936a3c499'

var dailyProcessesId = '5530c897180c432f729fbf85'
var todayId = '549ccb04f68aa6f4657b5d04'

// function unique (array) {
//   var seen = new Set()
//   return array.filter(function (item) {
//     if (!seen.has(item)) {
//       seen.add(item)
//       return true
//     }
//   })
// }

// Create a new list for today's date
var today = function () {
  t.post('/1/lists', {
    name: moment().format('MMMM Do, YYYY'),
    idBoard: lifeAsSheIsPlayedId,
    idListSource: dailyProcessesId,
    position: '3'
  }, function (err, data) {
    if (err) { throw err }

    // Copy all cards to 'Today'
    t.post('/1/lists/' + data.id + '/moveAllCards', {idBoard: lifeAsSheIsPlayedId, idList: todayId}, function (err, res) {
      if (err) { throw err }

      console.log('Done')
    })
  })
}

// Delete duplicates
var duplicates = function (listId, dailyOnly) {
  listId = listId || todayId
  dailyOnly = dailyOnly || true
  // Get the list of items due Today
  t.get('/1/lists/' + listId, {cards: 'open'}, function (err, data) {
    if (err) throw err

    // Find duplicate cards
    var dupes = _.difference(data.cards, _.uniq(data.cards, 'name'))

    _.each(dupes, function (card) {
      // Only delete daily cards, unless there are other dupes
      if (dailyOnly && _.includes(card.idLabels, '55800cca791f5e61d1e67bd5')) {
        // Delete duplicate cards
        t.del('/1/cards/' + card.id, function (err, res) {
          if (err) throw err

          console.log('Deleted card: ' + card.name + ' (' + card.id + ')')
        })
      }
    })

  })
}

if (process.argv[2] === 'today') today()
if (process.argv[2] === 't') today()
if (process.argv[2] === 'duplicates') duplicates()
if (process.argv[2] === 'd') duplicates()
if (process.argv[2] === 'dupes') duplicates()
if (process.argv[2] === 'dedupe') duplicates()

// module.exports.today = today()
// module.exports.duplicates = duplicates()
<commit_msg>Added tokens to env<commit_after>var Trello = require('node-trello')
var t = new Trello(process.env.TRELLO_KEY, process.env.TRELLO_TOKEN)
var moment = require('moment')
var _ = require('lodash')

// t.get('/1/members/me', function (err, data) {
//   if (err) throw err

//   data.idBoards.map(function (idBoard) {
//     t.get('/1/boards/' + idBoard, {lists: 'all'}, function (err, data) {
//       if (data.name === 'Life As She Is Played') {
//         data.lists.map(function (list) {
//           if (list.name === 'Today') {
//             console.log(list.name, list.id)

//           }
//         })
//       }

//     })
//   })

//   // console.log(data)
// })

var lifeAsSheIsPlayedId = '533c26d99c90c43936a3c499'
var dailyProcessesId = '5530c897180c432f729fbf85'
var todayId = '549ccb04f68aa6f4657b5d04'

// function unique (array) {
//   var seen = new Set()
//   return array.filter(function (item) {
//     if (!seen.has(item)) {
//       seen.add(item)
//       return true
//     }
//   })
// }

// Create a new list for today's date
var today = function () {
  t.post('/1/lists', {
    name: moment().format('MMMM Do, YYYY'),
    idBoard: lifeAsSheIsPlayedId,
    idListSource: dailyProcessesId,
    position: '3'
  }, function (err, data) {
    if (err) { throw err }

    // Copy all cards to 'Today'
    t.post('/1/lists/' + data.id + '/moveAllCards', {idBoard: lifeAsSheIsPlayedId, idList: todayId}, function (err, res) {
      if (err) { throw err }

      console.log('Done')
    })
  })
}

// Delete duplicates
var duplicates = function (listId, dailyOnly) {
  listId = listId || todayId
  dailyOnly = dailyOnly || true
  // Get the list of items due Today
  t.get('/1/lists/' + listId, {cards: 'open'}, function (err, data) {
    if (err) throw err

    // Find duplicate cards
    var dupes = _.difference(data.cards, _.uniq(data.cards, 'name'))

    _.each(dupes, function (card) {
      // Only delete daily cards, unless there are other dupes
      if (dailyOnly && _.includes(card.idLabels, '55800cca791f5e61d1e67bd5')) {
        // Delete duplicate cards
        t.del('/1/cards/' + card.id, function (err, res) {
          if (err) throw err

          console.log('Deleted card: ' + card.name + ' (' + card.id + ')')
        })
      }
    })

  })
}

if (process.argv[2] === 'today') today()
if (process.argv[2] === 't') today()
if (process.argv[2] === 'duplicates') duplicates()
if (process.argv[2] === 'd') duplicates()
if (process.argv[2] === 'dupes') duplicates()
if (process.argv[2] === 'dedupe') duplicates()

// module.exports.today = today()
// module.exports.duplicates = duplicates()
<|endoftext|>


<commit_before>var Q = require('q');
var aws = require('aws-sdk');

var S3 = new aws.S3();

module.exports = function(options) {
  var def = Q.defer();
  if (!options) {
    def.reject(new Error("expected options object with Bucket and Prefix. No options object"));
  } else if (!options.Bucket) {
    def.reject(new Error("expected options object with Bucket and Prefix. No options.Bucket"));
  } else if (!options.Prefix) {
    def.reject(new Error("expected options object with Bucket and Prefix. No options.Bucket"));
  } else {

    S3.listObjects({
      Bucket: options.Bucket,
      Prefix: options.Prefix
    }, function(err, data) {
      if (err) {
        def.reject(err);
      } else {

        var keys = data.Contents;
        if (options.pattern) {
          //TODO: pull in lambduh-validate api?
          keys = keys.map(function(object) {
            if (options.pattern.test(object.Key)) {
              return object.Key;
            }
          });
        }

        def.resolve(keys);
      }
    });

  }

  return def.promise;
}

<commit_msg>remove undefined/null keys from array<commit_after>var Q = require('q');
var aws = require('aws-sdk');

var S3 = new aws.S3();

module.exports = function(options) {
  var def = Q.defer();
  if (!options) {
    def.reject(new Error("expected options object with Bucket and Prefix. No options object"));
  } else if (!options.Bucket) {
    def.reject(new Error("expected options object with Bucket and Prefix. No options.Bucket"));
  } else if (!options.Prefix) {
    def.reject(new Error("expected options object with Bucket and Prefix. No options.Bucket"));
  } else {

    S3.listObjects({
      Bucket: options.Bucket,
      Prefix: options.Prefix
    }, function(err, data) {
      if (err) {
        def.reject(err);
      } else {

        var keys = data.Contents;
        if (options.pattern) {
          //TODO: pull in lambduh-validate api?
          keys = keys.map(function(object) {
            if (options.pattern.test(object.Key)) {
              return object.Key;
            }
          });
          keys = keys.filter(function(v) { return v; });
        }

        def.resolve(keys);
      }
    });

  }

  return def.promise;
}

<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
 */
'use strict';

addTest('Microphone', 'Audio capture', function() {
  var test = new MicTest();
  test.run();
});

function MicTest() {
  this.inputChannels = 6;
  this.outputChannels = 2;
  this.lowVolumeThreshold = -60;
  // Buffer size set to 0 to let Chrome choose based on the platform.
  this.bufferSize = 0;
  this.inputBuffer = [];
  // Turning off echoCancellation constraint enables stereo input.
  this.constraints = {
    audio: {
      optional: [
        { echoCancellation: false }
      ]
    }
  };
}

MicTest.prototype = {
  run: function() {
    doGetUserMedia(this.constraints, this.gotStream.bind(this));
  },

  gotStream: function(stream) {
    if (!this.checkAudioTracks(stream)) {
      return;
    }
    this.createAudioBuffer(stream);
  },

  setTimeoutWithProgressBar: function (timeoutCallback, timeoutMs) {
    var start = new Date();
    var updateProgressBar = setInterval(function () {
      var now = new Date();
      setTestProgress((now - start) * 100 / timeoutMs);
    }, 100);

    setTimeout(function () {
      clearInterval(updateProgressBar);
      setTestProgress(100);
      timeoutCallback();
    }, timeoutMs);
  },

  checkAudioTracks: function(stream) {
    this.stream = stream;
    var audioTracks = stream.getAudioTracks();
    if (audioTracks.length < 1) {
      reportFatal('No audio track in returned stream.');
      return false;
    }
    reportSuccess('Audio track created using device=' + audioTracks[0].label);
    return true;
  },

  createAudioBuffer: function() {
    this.audioSource = audioContext.createMediaStreamSource(this.stream);
    this.scriptNode = audioContext.createScriptProcessor(this.bufferSize,
        this.inputChannels, this.outputChannels);
    this.audioSource.connect(this.scriptNode);
    this.scriptNode.connect(audioContext.destination);
    this.scriptNode.onaudioprocess = this.collectAudio.bind(this);
    this.setTimeoutWithProgressBar(this.stopCollectingAudio.bind(this), 1000);
  },

  collectAudio: function(event) {
    this.inputBuffer = event.inputBuffer;
  },

  stopCollectingAudio: function() {
    this.stream.stop();
    this.audioSource.disconnect(this.scriptNode);
    this.scriptNode.disconnect(audioContext.destination);
    // Start analyzing the audio buffer.
    this.testNumberOfActiveChannels(this.inputBuffer);
  },

  testNumberOfActiveChannels: function(buffer) {
    var sampleData = [ [], [] ];
    var numberOfChannels = buffer.numberOfChannels;
    var activeChannels = [];
    for (var channel = 0; channel < numberOfChannels; channel++) {
      var numberOfZeroSamples = 0;
      for (var sample = 0; sample < buffer.length; sample++) {
        if (buffer.getChannelData(channel)[sample] !== 0) {
          sampleData[channel][sample] = buffer.getChannelData(channel)[sample];
        } else {
          numberOfZeroSamples++;
        }
      }
      if (numberOfZeroSamples !== buffer.length ) {
        activeChannels[channel] = this.testInputVolume(buffer, channel);
      }
    }
    // Validate the result.
    if (activeChannels.length === 0) {
      reportError('No active input channels detected. Microphone is most ' +
                  'likely muted or broken, please check if muted in the ' +
                  'sound settings or physically on the device. Then rerun ' +
                  'the test.');
    } else {
      reportSuccess('Audio input channels=' + activeChannels.length);
    }
    // If two channel input compare samples on channel 0 and 1 to determine if
    // it is a mono microphone.
    if (activeChannels.length === 2) {
      var samplesMatched = 0;
      var epsilon = buffer.length * 0.15;
      for (var i= 0; i < sampleData[0].length; i++) {
        if (sampleData[0][i] === sampleData[1][i]) {
          samplesMatched++;
        }
      }
      if (samplesMatched > buffer.length - epsilon) {
        reportInfo('Mono microphone detected.');
      } else {
        reportInfo('Multiple channel microphone detected.');
      }
    }
    testFinished();
  },

  testInputVolume: function(buffer, channel) {
    var data = buffer.getChannelData(channel);
    var sum = 0;
    for (var sample = 0; sample < buffer.length; ++sample) {
      sum += Math.abs(data[sample]);
    }
    var rms = Math.sqrt(sum / buffer.length);
    var db = 20 * Math.log(rms) / Math.log(10);

    // Check input audio level.
    if (db < this.lowVolumeThreshold) {
      // Use Math.round to display up to two decimal places.
      reportError('Audio input level = ' + Math.round(db * 1000) / 1000 + ' db' +
                  'Microphone input level is low, increase input volume or' +
                  'move closer to the microphone.');
    } else {
      reportSuccess('Audio power for channel ' + channel + '=' + Math.round(db * 1000) / 1000 + ' db');
    }
  }
};
<commit_msg>moved testfinished to stopCollectingAudio() and added back stereo mic message<commit_after>/*
 *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
 */
'use strict';

addTest('Microphone', 'Audio capture', function() {
  var test = new MicTest();
  test.run();
});

function MicTest() {
  this.inputChannels = 6;
  this.outputChannels = 2;
  this.lowVolumeThreshold = -60;
  // Buffer size set to 0 to let Chrome choose based on the platform.
  this.bufferSize = 0;
  this.inputBuffer = [];
  // Turning off echoCancellation constraint enables stereo input.
  this.constraints = {
    audio: {
      optional: [
        { echoCancellation: false }
      ]
    }
  };
}

MicTest.prototype = {
  run: function() {
    doGetUserMedia(this.constraints, this.gotStream.bind(this));
  },

  gotStream: function(stream) {
    if (!this.checkAudioTracks(stream)) {
      return;
    }
    this.createAudioBuffer(stream);
  },

  setTimeoutWithProgressBar: function (timeoutCallback, timeoutMs) {
    var start = new Date();
    var updateProgressBar = setInterval(function () {
      var now = new Date();
      setTestProgress((now - start) * 100 / timeoutMs);
    }, 100);

    setTimeout(function () {
      clearInterval(updateProgressBar);
      setTestProgress(100);
      timeoutCallback();
    }, timeoutMs);
  },

  checkAudioTracks: function(stream) {
    this.stream = stream;
    var audioTracks = stream.getAudioTracks();
    if (audioTracks.length < 1) {
      reportFatal('No audio track in returned stream.');
      return false;
    }
    reportSuccess('Audio track created using device=' + audioTracks[0].label);
    return true;
  },

  createAudioBuffer: function() {
    this.audioSource = audioContext.createMediaStreamSource(this.stream);
    this.scriptNode = audioContext.createScriptProcessor(this.bufferSize,
        this.inputChannels, this.outputChannels);
    this.audioSource.connect(this.scriptNode);
    this.scriptNode.connect(audioContext.destination);
    this.scriptNode.onaudioprocess = this.collectAudio.bind(this);
    this.setTimeoutWithProgressBar(this.stopCollectingAudio.bind(this), 1000);
  },

  collectAudio: function(event) {
    this.inputBuffer = event.inputBuffer;
  },

  stopCollectingAudio: function() {
    this.stream.stop();
    this.audioSource.disconnect(this.scriptNode);
    this.scriptNode.disconnect(audioContext.destination);
    // Start analyzing the audio buffer.
    this.testNumberOfActiveChannels(this.inputBuffer);
    testFinished();
  },

  testNumberOfActiveChannels: function(buffer) {
    var sampleData = [ [], [] ];
    var numberOfChannels = buffer.numberOfChannels;
    var activeChannels = [];
    for (var channel = 0; channel < numberOfChannels; channel++) {
      var numberOfZeroSamples = 0;
      for (var sample = 0; sample < buffer.length; sample++) {
        if (buffer.getChannelData(channel)[sample] !== 0) {
          sampleData[channel][sample] = buffer.getChannelData(channel)[sample];
        } else {
          numberOfZeroSamples++;
        }
      }
      if (numberOfZeroSamples !== buffer.length ) {
        activeChannels[channel] = this.testInputVolume(buffer, channel);
      }
    }
    // Validate the result.
    if (activeChannels.length === 0) {
      reportError('No active input channels detected. Microphone is most ' +
                  'likely muted or broken, please check if muted in the ' +
                  'sound settings or physically on the device. Then rerun ' +
                  'the test.');
    } else {
      reportSuccess('Audio input channels=' + activeChannels.length);
    }
    // If two channel input compare samples on channel 0 and 1 to determine if
    // it is a mono microphone.
    if (activeChannels.length === 2) {
      var samplesMatched = 0;
      var epsilon = buffer.length * 0.15;
      for (var i= 0; i < sampleData[0].length; i++) {
        if (sampleData[0][i] === sampleData[1][i]) {
          samplesMatched++;
        }
      }
      if (samplesMatched > buffer.length - epsilon) {
        reportInfo('Mono microphone detected.');
      } else {
        reportInfo('Stereo microphone detected.');
      }
    }
  },

  testInputVolume: function(buffer, channel) {
    var data = buffer.getChannelData(channel);
    var sum = 0;
    for (var sample = 0; sample < buffer.length; ++sample) {
      sum += Math.abs(data[sample]);
    }
    var rms = Math.sqrt(sum / buffer.length);
    var db = 20 * Math.log(rms) / Math.log(10);

    // Check input audio level.
    if (db < this.lowVolumeThreshold) {
      // Use Math.round to display up to two decimal places.
      reportError('Audio input level = ' + Math.round(db * 1000) / 1000 + ' db' +
                  'Microphone input level is low, increase input volume or' +
                  'move closer to the microphone.');
    } else {
      reportSuccess('Audio power for channel ' + channel + '=' + Math.round(db * 1000) / 1000 + ' db');
    }
  }
};
<|endoftext|>


<commit_before>var vdf = require('vdf');
var fs = require('fs');
var SteamID = require('steamid');

var protomask = 0x80000000;

var Language = require(__dirname + '/language.js');
var Protos = require(__dirname + '/protos.js');

var base_gcmessages = Protos.base_gcmessages;
var tf_gcmessages = Protos.tf_gcmessages;

module.exports = TeamFortress2;

require('util').inherits(TeamFortress2, require('events').EventEmitter);

function TeamFortress2(steam) {
	this._steam = steam;
	this.haveGCSession = false;

	var self = this;

	// "extend" the default steam.gamesPlayed function so we can catch when TF2 starts up
	var gamesPlayed = steam.gamesPlayed;
	steam.gamesPlayed = function(appids) {
		if(appids.indexOf(440) != -1 && !self.haveGCSession) {
			self._connect();
		} else if(self._helloInterval) {
			clearInterval(self._helloInterval);
			self._helloInterval = null;
		}

		gamesPlayed.call(steam, appids);
	};

	steam.on('fromGC', function(appID, type, body) {
		if(appID != 440) {
			// Not from the TF2 GC
			return;
		}

		var protobuf = !!(type & protomask);
		type &= ~protomask;

		if(self._handlers[type]) {
			self._handlers[type].call(self, body);
		} else {
			var msgName = type;
			for(var i in Language) {
				if(Language[i] == type) {
					msgName = i;
					break;
				}
			}

			self.emit('debug', "Got unhandled GC message " + msgName + (protobuf ? " (protobuf)" : ""));
		}
	});
}

TeamFortress2.prototype._connect = function() {
	var self = this;
	this._helloInterval = setInterval(function() {
		if(self.haveGCSession) {
			clearInterval(self._helloInterval);
			self._helloInterval = null;
			return;
		}

		self._send(Language.ClientHello, base_gcmessages.CMsgClientHello, {});
	}, 2000);
};

TeamFortress2.prototype._send = function(type, protobuf, body) {
	var msgName = type;
	for(var i in Language) {
		if(Language[i] == type) {
			msgName = i;
			break;
		}
	}

	this.emit('debug', "Sending GC message " + msgName);

	if(protobuf) {
		this._steam.toGC(440, type | protomask, protobuf.serialize(body));
	} else {
		this._steam.toGC(440, type, body);
	}
};

TeamFortress2.prototype.setLang = function(langFile) {
	var lang = vdf.parse(langFile);
	// The vdf parser appears to add some random characters and quotes to the root 'lang' key, so we'll just use a loop to find it
	for(var i in lang) {
		this.lang = lang[i].Tokens;
	}
};

TeamFortress2.prototype.craft = function(items, recipe) {
	var buffer = new Buffer(2 + 2 + (8 * items.length));
	buffer.writeInt16LE(recipe || -2, 0); // -2 is wildcard
	buffer.writeInt16LE(items.length, 2);
	for(var i = 0; i < items.length; i++) {
		buffer.writeUInt64LE(items[i], 4 + (i * 8));
	}

	this._send(Language.Craft, null, buffer);
};

TeamFortress2.prototype.trade = function(steamID) {
	var buffer = new Buffer(12);
	buffer.writeUInt32LE(0, 0);
	buffer.writeUInt64LE(steamID, 4);
	this._send(Language.Trading_InitiateTradeRequest, null, buffer);
};

TeamFortress2.prototype.cancelTradeRequest = function() {
	var buffer = new Buffer(0);
	this._send(Language.Trading_CancelSession, null, buffer);
};

TeamFortress2.prototype.respondToTrade = function(tradeID, accept) {
	var buffer = new Buffer(8);
	buffer.writeUInt32LE(accept ? TeamFortress2.TradeResponse.Accepted : TeamFortress2.TradeResponse.Declined, 0);
	buffer.writeUInt32LE(tradeID, 4);
	this._send(Language.Trading_InitiateTradeResponse, null, buffer);
};

TeamFortress2.prototype.setStyle = function(item, style) {
	var buffer = new Buffer(12);
	buffer.writeUInt64LE(item, 0);
	buffer.writeUInt32LE(style, 8);
	this._send(Language.SetItemStyle, null, buffer);
};

TeamFortress2.prototype.setPosition = function(item, position) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(item, 0);
	buffer.writeUInt64LE(position, 8);
	this._send(Language.SetSingleItemPosition, null, buffer);
};

TeamFortress2.prototype.setPositions = function(items) {
	this._send(Language.SetItemPositions, base_gcmessages.CMsgSetItemPositions, {"itemPositions": items});
};

TeamFortress2.prototype.deleteItem = function(item) {
	var buffer = new Buffer(8);
	buffer.writeUInt64LE(item);
	this._send(Language.Delete, null, buffer);
};

TeamFortress2.prototype.wrapItem = function(wrapID, itemID) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(wrapID, 0);
	buffer.writeUInt64LE(itemID, 8);
	this._send(Language.GiftWrapItem, null, buffer);
};

TeamFortress2.prototype.deliverGift = function(gift, steamID) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(gift, 0);
	buffer.writeUInt64LE(steamID, 8);
	this._send(Language.DeliverGift, null, buffer);
};

TeamFortress2.prototype.unwrapGift = function(gift) {
	var buffer = new Buffer(8);
	buffer.writeUInt64LE(gift);
	this._send(Language.UnwrapGiftRequest, null, buffer);
};

TeamFortress2.prototype.useItem = function(item) {
	this._send(Language.UseItemRequest, base_gcmessages.CMsgUseItem, {"itemId": item});
};

TeamFortress2.prototype.sortBackpack = function(sortType) {
	this._send(Language.SortItems, base_gcmessages.CMsgSortItems, {"sortType": sortType});
};

TeamFortress2.prototype.sendProfessorSpeks = function(steamID) {
	this._send(Language.FreeTrial_ChooseMostHelpfulFriend, tf_gcmessages.CMsgTFFreeTrialChooseMostHelpfulFriend, {"accountIdFriend": new SteamID(steamID).accountid});
};

TeamFortress2.prototype.createServerIdentity = function() {
	this._send(Language.GameServer_CreateIdentity, tf_gcmessages.CMsgGC_GameServer_CreateIdentity, {"accountId": new SteamID(this._steam.steamID).accountid});
};

TeamFortress2.prototype.getRegisteredServers = function() {
	this._send(Language.GameServer_List, tf_gcmessages.CMsgGC_GameServer_List, {"accountId": new SteamID(this._steam.steamID).accountid});
};

TeamFortress2.prototype.resetServerIdentity = function(id) {
	this._send(Language.GameServer_ResetIdentity, tf_gcmessages.CMsgGC_GameServer_ResetIdentity, {"gameServerAccountId": id});
};

TeamFortress2.prototype.openCrate = function(keyID, crateID) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(keyID, 0);
	buffer.writeUInt64LE(crateID, 8);
	this._send(Language.UnlockCrate, null, buffer);
};

TeamFortress2.prototype._handlers = {};

require('./enums.js');
require('./handlers.js');<commit_msg>Added method to request Spy vs. Engi War stats<commit_after>var vdf = require('vdf');
var fs = require('fs');
var SteamID = require('steamid');

var protomask = 0x80000000;

var Language = require(__dirname + '/language.js');
var Protos = require(__dirname + '/protos.js');

var base_gcmessages = Protos.base_gcmessages;
var tf_gcmessages = Protos.tf_gcmessages;

module.exports = TeamFortress2;

require('util').inherits(TeamFortress2, require('events').EventEmitter);

function TeamFortress2(steam) {
	this._steam = steam;
	this.haveGCSession = false;

	var self = this;

	// "extend" the default steam.gamesPlayed function so we can catch when TF2 starts up
	var gamesPlayed = steam.gamesPlayed;
	steam.gamesPlayed = function(appids) {
		if(appids.indexOf(440) != -1 && !self.haveGCSession) {
			self._connect();
		} else if(self._helloInterval) {
			clearInterval(self._helloInterval);
			self._helloInterval = null;
		}

		gamesPlayed.call(steam, appids);
	};

	steam.on('fromGC', function(appID, type, body) {
		if(appID != 440) {
			// Not from the TF2 GC
			return;
		}

		var protobuf = !!(type & protomask);
		type &= ~protomask;

		if(self._handlers[type]) {
			self._handlers[type].call(self, body);
		} else {
			var msgName = type;
			for(var i in Language) {
				if(Language[i] == type) {
					msgName = i;
					break;
				}
			}

			self.emit('debug', "Got unhandled GC message " + msgName + (protobuf ? " (protobuf)" : ""));
		}
	});
}

TeamFortress2.prototype._connect = function() {
	var self = this;
	this._helloInterval = setInterval(function() {
		if(self.haveGCSession) {
			clearInterval(self._helloInterval);
			self._helloInterval = null;
			return;
		}

		self._send(Language.ClientHello, base_gcmessages.CMsgClientHello, {});
	}, 2000);
};

TeamFortress2.prototype._send = function(type, protobuf, body) {
	var msgName = type;
	for(var i in Language) {
		if(Language[i] == type) {
			msgName = i;
			break;
		}
	}

	this.emit('debug', "Sending GC message " + msgName);

	if(protobuf) {
		this._steam.toGC(440, type | protomask, protobuf.serialize(body));
	} else {
		this._steam.toGC(440, type, body);
	}
};

TeamFortress2.prototype.setLang = function(langFile) {
	var lang = vdf.parse(langFile);
	// The vdf parser appears to add some random characters and quotes to the root 'lang' key, so we'll just use a loop to find it
	for(var i in lang) {
		this.lang = lang[i].Tokens;
	}
};

TeamFortress2.prototype.craft = function(items, recipe) {
	var buffer = new Buffer(2 + 2 + (8 * items.length));
	buffer.writeInt16LE(recipe || -2, 0); // -2 is wildcard
	buffer.writeInt16LE(items.length, 2);
	for(var i = 0; i < items.length; i++) {
		buffer.writeUInt64LE(items[i], 4 + (i * 8));
	}

	this._send(Language.Craft, null, buffer);
};

TeamFortress2.prototype.trade = function(steamID) {
	var buffer = new Buffer(12);
	buffer.writeUInt32LE(0, 0);
	buffer.writeUInt64LE(steamID, 4);
	this._send(Language.Trading_InitiateTradeRequest, null, buffer);
};

TeamFortress2.prototype.cancelTradeRequest = function() {
	var buffer = new Buffer(0);
	this._send(Language.Trading_CancelSession, null, buffer);
};

TeamFortress2.prototype.respondToTrade = function(tradeID, accept) {
	var buffer = new Buffer(8);
	buffer.writeUInt32LE(accept ? TeamFortress2.TradeResponse.Accepted : TeamFortress2.TradeResponse.Declined, 0);
	buffer.writeUInt32LE(tradeID, 4);
	this._send(Language.Trading_InitiateTradeResponse, null, buffer);
};

TeamFortress2.prototype.setStyle = function(item, style) {
	var buffer = new Buffer(12);
	buffer.writeUInt64LE(item, 0);
	buffer.writeUInt32LE(style, 8);
	this._send(Language.SetItemStyle, null, buffer);
};

TeamFortress2.prototype.setPosition = function(item, position) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(item, 0);
	buffer.writeUInt64LE(position, 8);
	this._send(Language.SetSingleItemPosition, null, buffer);
};

TeamFortress2.prototype.setPositions = function(items) {
	this._send(Language.SetItemPositions, base_gcmessages.CMsgSetItemPositions, {"itemPositions": items});
};

TeamFortress2.prototype.deleteItem = function(item) {
	var buffer = new Buffer(8);
	buffer.writeUInt64LE(item);
	this._send(Language.Delete, null, buffer);
};

TeamFortress2.prototype.wrapItem = function(wrapID, itemID) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(wrapID, 0);
	buffer.writeUInt64LE(itemID, 8);
	this._send(Language.GiftWrapItem, null, buffer);
};

TeamFortress2.prototype.deliverGift = function(gift, steamID) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(gift, 0);
	buffer.writeUInt64LE(steamID, 8);
	this._send(Language.DeliverGift, null, buffer);
};

TeamFortress2.prototype.unwrapGift = function(gift) {
	var buffer = new Buffer(8);
	buffer.writeUInt64LE(gift);
	this._send(Language.UnwrapGiftRequest, null, buffer);
};

TeamFortress2.prototype.useItem = function(item) {
	this._send(Language.UseItemRequest, base_gcmessages.CMsgUseItem, {"itemId": item});
};

TeamFortress2.prototype.sortBackpack = function(sortType) {
	this._send(Language.SortItems, base_gcmessages.CMsgSortItems, {"sortType": sortType});
};

TeamFortress2.prototype.sendProfessorSpeks = function(steamID) {
	this._send(Language.FreeTrial_ChooseMostHelpfulFriend, tf_gcmessages.CMsgTFFreeTrialChooseMostHelpfulFriend, {"accountIdFriend": new SteamID(steamID).accountid});
};

TeamFortress2.prototype.createServerIdentity = function() {
	this._send(Language.GameServer_CreateIdentity, tf_gcmessages.CMsgGC_GameServer_CreateIdentity, {"accountId": new SteamID(this._steam.steamID).accountid});
};

TeamFortress2.prototype.getRegisteredServers = function() {
	this._send(Language.GameServer_List, tf_gcmessages.CMsgGC_GameServer_List, {"accountId": new SteamID(this._steam.steamID).accountid});
};

TeamFortress2.prototype.resetServerIdentity = function(id) {
	this._send(Language.GameServer_ResetIdentity, tf_gcmessages.CMsgGC_GameServer_ResetIdentity, {"gameServerAccountId": id});
};

TeamFortress2.prototype.openCrate = function(keyID, crateID) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(keyID, 0);
	buffer.writeUInt64LE(crateID, 8);
	this._send(Language.UnlockCrate, null, buffer);
};

TeamFortress2.prototype.requestSpyVsEngiWarStats = function() {
	this._send(Language.SpyVsEngyWar_RequestGlobalStats, tf_gcmessages.CGCMsgGC_SpyVsEngyWar_RequestGlobalStats, {});
};

TeamFortress2.prototype._handlers = {};

require('./enums.js');
require('./handlers.js');<|endoftext|>


<commit_before>var sound = require('./sound'), capture = require('./capture');

capture.on('capture', sound.addSound);
<commit_msg>Make it actually play the sound<commit_after>var sound = require('./sound'), capture = require('./capture');

capture.on('capture', sound.addSound);

sound.run();
<|endoftext|>


<commit_before>'use strict';

var fs = require('graceful-fs');
var path = require('path');
var childProcess = require('child_process');
var shell = require('shelljs');

var HAS_NATIVE_EXECSYNC = childProcess.hasOwnProperty('spawnSync');
var PATH_SEP = path.sep;
var RE_BRANCH = /^ref: refs\/heads\/(.*)\n/;

function _command(cmd, args) {
  var result;

  if (HAS_NATIVE_EXECSYNC) {
    result = childProcess.spawnSync(cmd, args);

    if (result.status !== 0) {
      throw new Error('[git-rev-sync] failed to execute command: ' + result.error.code);
    }

    return result.stdout.toString('utf8').replace(/^\s+|\s+$/g, '');
  }

  result = shell.exec(cmd + ' ' + args.join(' '), {silent: true});

  if (result.code !== 0) {
    throw new Error('[git-rev-sync] failed to execute command: ' + result.output);
  }

  return result.output.toString('utf8').replace(/^\s+|\s+$/g, '');
}

function _getGitDirectory(start) {
  if (start === undefined) {
    start = module.parent.filename;
  }

  if (typeof start === 'string') {
    start = start.split(PATH_SEP);
  }

  var testPath = start.join(PATH_SEP);

  if (!testPath.length) {
    throw new Error('[git-rev-sync] no git repository found');
  }

  testPath = path.resolve(testPath, '.git');

  if (fs.existsSync(testPath)) {
    return testPath;
  }

  start.pop();

  return _getGitDirectory(start);
}

function branch(dir) {
  var gitDir = _getGitDirectory(dir);

  var head = fs.readFileSync(path.resolve(gitDir, 'HEAD'), 'utf8');
  var b = head.match(RE_BRANCH);

  if (b) {
    return b[1];
  }

  return 'Detatched: ' + head.trim();
}

function long(dir) {
  var b = branch(dir);

  if (/Detatched: /.test(b)) {
    return b.substr(11);
  }

  var gitDir = _getGitDirectory(dir);
  var refsFilePath = path.resolve(gitDir, 'refs', 'heads', b);
  var ref;

  if (fs.existsSync(refsFilePath)) {
    ref = fs.readFileSync(refsFilePath, 'utf8');
  }

  else {
    // If there isn't an entry in /refs/heads for this branch, it may be that
    // the ref is stored in the packfile (.git/packed-refs). Fall back to
    // looking up the hash here.
    var refToFind = path.join('refs', 'heads', b);
    var packfileContents = fs.readFileSync(path.resolve(gitDir, 'packed-refs'), 'utf8');
    var packfileRegex = new RegExp('(.*) ' + refToFind);
    ref = packfileRegex.exec(packfileContents)[1];
  }

  return ref.trim();
}

function short(dir) {
  return long(dir).substr(0, 7);
}

function message() {
  return _command('git', ['log', '-1', '--pretty=%B']);
}

function tag(markDirty) {
  if (markDirty) {
    return _command('git', ['describe', '--always', '--tag', '--dirty', '--abbrev=0']);
  }

  return _command('git', ['describe', '--always', '--tag', '--abbrev=0']);
}

function count() {
  return parseInt(_command('git', ['rev-list', '--all', '--count']), 10);
}

function log() {
  throw new Error('not implemented');
}

module.exports = {
  branch : branch,
  count: count,
  log : log,
  long : long,
  message : message,
  short : short,
  tag : tag
};
<commit_msg>Fixing the path creation for Windows users<commit_after>'use strict';

var fs = require('graceful-fs');
var path = require('path');
var childProcess = require('child_process');
var shell = require('shelljs');

var HAS_NATIVE_EXECSYNC = childProcess.hasOwnProperty('spawnSync');
var PATH_SEP = path.sep;
var RE_BRANCH = /^ref: refs\/heads\/(.*)\n/;

function _command(cmd, args) {
  var result;

  if (HAS_NATIVE_EXECSYNC) {
    result = childProcess.spawnSync(cmd, args);

    if (result.status !== 0) {
      throw new Error('[git-rev-sync] failed to execute command: ' + result.error.code);
    }

    return result.stdout.toString('utf8').replace(/^\s+|\s+$/g, '');
  }

  result = shell.exec(cmd + ' ' + args.join(' '), {silent: true});

  if (result.code !== 0) {
    throw new Error('[git-rev-sync] failed to execute command: ' + result.output);
  }

  return result.output.toString('utf8').replace(/^\s+|\s+$/g, '');
}

function _getGitDirectory(start) {
  if (start === undefined) {
    start = module.parent.filename;
  }

  if (typeof start === 'string') {
    start = start.split(PATH_SEP);
  }

  var testPath = start.join(PATH_SEP);

  if (!testPath.length) {
    throw new Error('[git-rev-sync] no git repository found');
  }

  testPath = path.resolve(testPath, '.git');

  if (fs.existsSync(testPath)) {
    return testPath;
  }

  start.pop();

  return _getGitDirectory(start);
}

function branch(dir) {
  var gitDir = _getGitDirectory(dir);

  var head = fs.readFileSync(path.resolve(gitDir, 'HEAD'), 'utf8');
  var b = head.match(RE_BRANCH);

  if (b) {
    return b[1];
  }

  return 'Detatched: ' + head.trim();
}

function long(dir) {
  var b = branch(dir);

  if (/Detatched: /.test(b)) {
    return b.substr(11);
  }

  var gitDir = _getGitDirectory(dir);
  var refsFilePath = path.resolve(gitDir, 'refs', 'heads', b);
  var ref;

  if (fs.existsSync(refsFilePath)) {
    ref = fs.readFileSync(refsFilePath, 'utf8');
  }

  else {
    // If there isn't an entry in /refs/heads for this branch, it may be that
    // the ref is stored in the packfile (.git/packed-refs). Fall back to
    // looking up the hash here.
    var refToFind = ['refs', 'heads', b].join('/');
    var packfileContents = fs.readFileSync(path.resolve(gitDir, 'packed-refs'), 'utf8');
    var packfileRegex = new RegExp('(.*) ' + refToFind);
    ref = packfileRegex.exec(packfileContents)[1];
  }

  return ref.trim();
}

function short(dir) {
  return long(dir).substr(0, 7);
}

function message() {
  return _command('git', ['log', '-1', '--pretty=%B']);
}

function tag(markDirty) {
  if (markDirty) {
    return _command('git', ['describe', '--always', '--tag', '--dirty', '--abbrev=0']);
  }

  return _command('git', ['describe', '--always', '--tag', '--abbrev=0']);
}

function count() {
  return parseInt(_command('git', ['rev-list', '--all', '--count']), 10);
}

function log() {
  throw new Error('not implemented');
}

module.exports = {
  branch : branch,
  count: count,
  log : log,
  long : long,
  message : message,
  short : short,
  tag : tag
};
<|endoftext|>


<commit_before>var path = require('path'),
    router = require('./lib/router'),
    bindings = module.exports = require('./lib/bindings');

var init = bindings.init;

bindings.init = function() {
  var app = init.apply(null, arguments);

  app.extend = function extend(mod){
    Object.keys(mod.prototype).forEach(function(key){
      app[key] = mod.prototype[key];
    });
    mod.call(app);
  }

  app.extend(router);

  app.on("exit",function(){
    process.nextTick(function(){
      process.exit();
    });
  });

  var createWindow = app.createWindow;

  app.createWindow = function(url,settings){

    if (settings.icons) {
      ['smaller', 'small', 'big', 'bigger'].forEach(function(size){
        settings.icons[size] = path.resolve(settings.icons[size]);
      });
    }

    return createWindow.call(app,url,settings);
  }

  return app;
}
<commit_msg>Add some extensions to Window and App prototypes and some support for sync ipc<commit_after>var path = require('path'),
    router = require('./lib/router'),
    bindings = require('./lib/bindings');

var App = bindings.App,
    Window = bindings.Window;

function extend(obj){
  var desc = { enumerable: false, configurable: true, writable: true };
  for (var i=1; i < arguments.length; i++) {
    Object.keys(arguments[i]).forEach(function(key){
      desc.value = this[key];
      Object.defineProperty(obj, key, desc);
    }, arguments[i]);
  }
}

var _extend = extend;
var createWin = App.prototype.createWindow;

extend(App.prototype, {
  extend: function extend(mod){
    _extend(this, mod.prototype);
    mod.call(this);
  },
  createWindow: function createWindow(url, settings){
    if (settings.icons) {
      ['smaller', 'small', 'big', 'bigger'].forEach(function(size){
        settings.icons[size] = path.resolve(settings.icons[size] || '');
      });
    } else {
      settings.icons = {};
    }

    var win = createWin.call(this, url, settings);
    this.windows.push(win);
    win.once('ready', function(){
      win.runInBrowser(initBrowser);
    });
    return win;
  },
  send: function send(window, type, msg){
    if (arguments.length === 2) {
      msg = type;
      type = window;
      window = 0;
    }
    if (window in this.windows) {
      return this.windows[window].send(type, msg);
    }
  }
});

var IPC = {
  encode: function encode(msg){
    if (msg == null)
      return '{}';
    else if (typeof msg === 'object')
      return JSON.stringify(msg);
    else if (typeof msg === 'string')
      return msg;
    else
      throw new TypeError("Tried to encode invalid type");
  },
  decode: function decode(msg){
    try {
      return JSON.parse(msg);
    } catch (e) {
      return { error: e };
    }
  }
};

function initBrowser(){
  var sendSync = appjs.send;
  var events = {};

  function encode(msg){
    if (msg == null)
      return '{}';
    else if (typeof msg === 'object')
      return JSON.stringify(msg);
    else if (typeof msg === 'string')
      return msg;
    else
      throw new TypeError("Tried to encode invalid type");
  }

  function decode(msg){
    try {
      return JSON.parse(msg);
    } catch (e) {
      return { error: e };
    }
  }

  appjs.on = function on(types, handler){
    types.split(/\s+/).forEach(function(type){
      var listeners = events[type] || (events[type] = []);
      if (!~listeners.indexOf(handler)) {
        listeners.push(handler);
      }
    });
  };

  appjs.off = function off(types, handler){
    types.split(/\s+/).forEach(function(type){
      if (events[type]) {
        var index = events[type].indexOf(type);
        ~index && events[type].splice(index, 1);
      }
    });
  };

  appjs.onmessage = function message(msg){
    var result = {};
    msg = decode(msg);

    if (msg && msg.type && events[msg.type]) {
      var listeners = events[msg.type];
      var temp;
      for (var i=0; i < listeners.length; i++) {
        temp = listeners[i].call(appjs, msg.msg, result);
        if (temp != null) {
          result = temp;
        }
      }
    }
    return encode(result);
  };

  appjs.send = function send(type, msg){
    msg = { type: type, msg: msg };
    return decode(sendSync.call(appjs, encode(msg)));
  };

  appjs.on('log', function(obj){
    console.log(obj);
  });
}

var sendSync = Window.prototype.send;
delete Window.prototype.sendSync;

Window.prototype.__proto__ = process.EventEmitter.prototype;

extend(Window.prototype, {
  onmessage: function onmessage(msg){
    var result = {};
    msg = IPC.decode(msg);

    if (msg && msg.type && this.listeners[msg.type]) {
      this.emit(msg.type, msg.msg, result);
    }

    return IPC.encode(result);
  },
  send: function send(type, msg){
    msg = { type: type, msg: msg };
    return IPC.decode(sendSync.call(this, IPC.encode(msg)));
  }
});

module.exports = {
  init: function init() {
    var app = bindings.init.apply(null, arguments);

    app.windows = [];

    app.extend(router);

    app.on("exit",function(){
      process.nextTick(function(){
        process.exit();
      });
    });

    return app;
  }
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

/**
 * Created by apizzimenti on 4/2/16.
 */

/**
 * @ignore
 */

var h = require('./tools/helper_functions');

/**
 * @summary Deletes value(s) from the specified index or list of indices/
 *
 * @param index {Number | Number[]} index or list of indices to be deleted
 *
 * @this {Array} current array object
 *
 * @throws RangeError
 *
 * @returns {Array}
 *
 * @since 0.0.1
 *
 * @example
 * var a = [1, 2, 3, 4, 5];
 * a.removeIndex(2)
 * // [ 1, 2, 4, 5 ]
 *
 * var b = [1, 2, 3, 4, 5];
 * b.removeIndex([0, 1, 2]);
 * // [ 4, 5 ]
 *
 * var c = [1, 2, 3, 4, 5],
 *     d = c.removeIndex(2);
 * // [ 1, 2, 4, 5 ]
 */

var removeIndex = function (index) {
    var indices = Array.isArray(index) ? index : [index],
        greatest_val = h._quicksort(indices, 0, indices.length - 1)[indices.length - 1];

    if (indices.length > this.length || greatest_val > this.length - 1) {

        throw new RangeError();

    } else {

        var amount_gone = 0;

        for (var i = 0; i < indices.length; i++) {
            var curr_index = indices[i] - amount_gone,
                length = this.length;

            for (var k = curr_index; k < length - 1; k++) {
                this[k] = this[k + 1];
            }

            delete this[length - 1];
            this.length = length - 1;
            amount_gone++;
        }
    }

    return this;
};

Array.prototype.removeIndex = removeIndex;

/**
 * @summary Deletes all specified value(s) in an array.
 *
 * @param value {Number | Array} value or list of values to be deleted
 *
 * @this {Array} current array object
 *
 * @throws ReferenceError
 *
 * @returns {Array}
 *
 * @since 0.0.1
 *
 * @example
 * var a = [1, 2, 3, 4, 5];
 * a.removeValue(3);
 * // [ 1, 2, 4, 5 ]
 *
 * var b = [1, 2, 3, 4, 5];
 * b.removeValue([2, 3, 5]);
 * // [ 1, 4 ]
 *
 * var c = [1, 2, 3, 4, 5],
 *     d = c.removeValue(3);
 * // [ 1, 2, 4, 5 ]
 *
 */

var removeValue = function (value) {
    var vals = Array.isArray(value) ? value : [value],
        indices = [];

    for (var i = 0; i < vals.length; i++) {
        for (var j = 0; j < this.length; j++) {
            if (vals[i] === this[j]) {
                indices.push(j);
            }
        }
    }

    if (indices.length === 0) {

        throw new ReferenceError();

    } else {

        var amount_gone = 0;

        for (var k = 0; k < indices.length; k++) {
            var index = indices[k] - amount_gone,
                length = this.length;

            for (var l = index; l < length; l++) {
                this[l] = this[l + 1];
            }

            delete this[length - 1];
            this.length = length - 1;
            amount_gone++;
        }
    }

    return this;
};

Array.prototype.removeValue = removeValue;

/**
 * @summary Groups the values of the array by step; groups array values into groups of size step.
 *
 * @param step {Number} size of group
 *
 * @this {Array} current Array object
 *
 * @returns {Array}
 *
 * @since 1.0.5
 *
 * @example
 * var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 * a.groupByStep(3)
 * // [ [1, 2, 3], [4, 5, 6], [7, 8, 9], [10] ]
 *
 * var b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
 *     c = b.groupByStep(2)
 * // [ [1, 2], [3, 4], [5, 6], [7, 8], [9, 10] ]
 */

var groupByStep = function (step) {

    var right = this.length % step,
        last_length = this.length - right,
        step_array = [],
        last_array = [],
        index = 0;

    for (var i = 0; i < this.length - right; i++) {

        step_array.push(this[i]);
        index = Math.floor((i + 1) / step) - 1;

        if ((i + 1) % step === 0) {

            this[index] = step_array;
            step_array = [];
        }
    }

    for (var j = this.length - right; j < this.length; j++) {
        last_array.push(this[j]);
        delete this[j];
    }

    this.length = last_length;

    for (var k = last_length - last_array.length; k < last_length; k++) {
        delete this[k];
    }

    this.length = this.length / step;
    this.push(last_array);

    return this;
};

Array.prototype.groupByStep = groupByStep;

<commit_msg>fix @since tags<commit_after>#!/usr/bin/env node

/**
 * Created by apizzimenti on 4/2/16.
 */

/**
 * @ignore
 */

var h = require('./tools/helper_functions');

/**
 * @summary Deletes value(s) from the specified index or list of indices/
 *
 * @param index {Number | Number[]} index or list of indices to be deleted
 *
 * @this {Array} current array object
 *
 * @throws RangeError
 *
 * @returns {Array}
 *
 * @since 1.0.1
 *
 * @example
 * var a = [1, 2, 3, 4, 5];
 * a.removeIndex(2)
 * // [ 1, 2, 4, 5 ]
 *
 * var b = [1, 2, 3, 4, 5];
 * b.removeIndex([0, 1, 2]);
 * // [ 4, 5 ]
 *
 * var c = [1, 2, 3, 4, 5],
 *     d = c.removeIndex(2);
 * // [ 1, 2, 4, 5 ]
 */

var removeIndex = function (index) {
    var indices = Array.isArray(index) ? index : [index],
        greatest_val = h._quicksort(indices, 0, indices.length - 1)[indices.length - 1];

    if (indices.length > this.length || greatest_val > this.length - 1) {

        throw new RangeError();

    } else {

        var amount_gone = 0;

        for (var i = 0; i < indices.length; i++) {
            var curr_index = indices[i] - amount_gone,
                length = this.length;

            for (var k = curr_index; k < length - 1; k++) {
                this[k] = this[k + 1];
            }

            delete this[length - 1];
            this.length = length - 1;
            amount_gone++;
        }
    }

    return this;
};

Array.prototype.removeIndex = removeIndex;

/**
 * @summary Deletes all specified value(s) in an array.
 *
 * @param value {Number | Array} value or list of values to be deleted
 *
 * @this {Array} current array object
 *
 * @throws ReferenceError
 *
 * @returns {Array}
 *
 * @since 1.0.1
 *
 * @example
 * var a = [1, 2, 3, 4, 5];
 * a.removeValue(3);
 * // [ 1, 2, 4, 5 ]
 *
 * var b = [1, 2, 3, 4, 5];
 * b.removeValue([2, 3, 5]);
 * // [ 1, 4 ]
 *
 * var c = [1, 2, 3, 4, 5],
 *     d = c.removeValue(3);
 * // [ 1, 2, 4, 5 ]
 *
 */

var removeValue = function (value) {
    var vals = Array.isArray(value) ? value : [value],
        indices = [];

    for (var i = 0; i < vals.length; i++) {
        for (var j = 0; j < this.length; j++) {
            if (vals[i] === this[j]) {
                indices.push(j);
            }
        }
    }

    if (indices.length === 0) {

        throw new ReferenceError();

    } else {

        var amount_gone = 0;

        for (var k = 0; k < indices.length; k++) {
            var index = indices[k] - amount_gone,
                length = this.length;

            for (var l = index; l < length; l++) {
                this[l] = this[l + 1];
            }

            delete this[length - 1];
            this.length = length - 1;
            amount_gone++;
        }
    }

    return this;
};

Array.prototype.removeValue = removeValue;

/**
 * @summary Groups the values of the array by step; groups array values into groups of size step.
 *
 * @param step {Number} size of group
 *
 * @this {Array} current Array object
 *
 * @returns {Array}
 *
 * @since 1.0.6
 *
 * @example
 * var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 * a.groupByStep(3)
 * // [ [1, 2, 3], [4, 5, 6], [7, 8, 9], [10] ]
 *
 * var b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
 *     c = b.groupByStep(2)
 * // [ [1, 2], [3, 4], [5, 6], [7, 8], [9, 10] ]
 */

var groupByStep = function (step) {

    var right = this.length % step,
        last_length = this.length - right,
        step_array = [],
        last_array = [],
        index = 0;

    for (var i = 0; i < this.length - right; i++) {

        step_array.push(this[i]);
        index = Math.floor((i + 1) / step) - 1;

        if ((i + 1) % step === 0) {

            this[index] = step_array;
            step_array = [];
        }
    }

    for (var j = this.length - right; j < this.length; j++) {
        last_array.push(this[j]);
        delete this[j];
    }

    this.length = last_length;

    for (var k = last_length - last_array.length; k < last_length; k++) {
        delete this[k];
    }

    this.length = this.length / step;
    this.push(last_array);

    return this;
};

Array.prototype.groupByStep = groupByStep;

<|endoftext|>