<commit_before>(function(undefined) {
  var expandSchema, expandSchemaItem, propertyFunction,
      createPropertyFunction, hasManyFunction, createSchemaProperties,
      expandRemoteHasOneSchemaItem, expandRemoteHasManySchemaItem,
      expandNestedHasOneSchemaItem, expandNestedHasManySchemaItem;

  function isString(obj) {
    return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
  }

  function isObject(obj) {
    return obj === Object(obj);
  }

  var isFunction = $.isFunction;

  function getJSON(url, callback) {
    var options = {
      url: url,
      dataType: 'json',
      success: callback
    };

    if (SC.Resource.errorHandler) {
      options.error = SC.Resource.errorHandler;
    }

    return $.ajax(options);
  }

  SC.Resource = SC.Object.extend({
    isSCResource: true,

    fetch: function() {
      SC.set(this, 'resourceState', SC.Resource.Lifecycle.FETCHING);

      var self = this;

      this.deferedFetch = getJSON(this.resourceURL(), function(json) {
        SC.set(self, 'data', self.constructor.parse(json));
      });

      this.deferedFetch.always(function() {
        SC.set(self, 'resourceState', SC.Resource.Lifecycle.FETCHED);
      });

      return this.deferedFetch;
    },

    resourceURL: function() {
      return this.constructor.resourceURL(this);
    },

    // Turn this resource into a JSON object to be saved via AJAX. Override
    // this method to produce different syncing behavior.
    toJSON: function() {
      return SC.get(this, 'data');
    },

    isNew: function() {
      return !SC.get(this, 'id');
    },

    save: function() {
      var ajaxOptions = {
        data: this.toJSON()
      };

      if (this.isNew()) {
        ajaxOptions.type = 'POST';
        ajaxOptions.url = this.constructor.resourceURL();
      } else {
        ajaxOptions.type = 'PUT';
        ajaxOptions.url = this.resourceURL();
      }

      return $.ajax(ajaxOptions);
    }
  });

  SC.Resource.Lifecycle = {
    INITIALIZING: 0,
    UNFETCHED:    10,
    FETCHING:     20,
    FETCHED:      30,
    create: function(options) {
      options = options || {};
      options.resourceState = SC.Resource.Lifecycle.INITIALIZING;
      var instance = this._super.call(this, options);
      if (SC.get(instance, 'resourceState') === SC.Resource.Lifecycle.INITIALIZING) {
        SC.set(instance, 'resourceState', SC.Resource.Lifecycle.UNFETCHED);
      }
      return instance;
    }
  };

  SC.Resource.reopenClass(SC.Resource.Lifecycle);

  expandNestedHasOneSchemaItem = function(name, schema) {
    var value = schema[name];
    value.path = value.path || name;

    value.serialize = value.serialize || function(instance) {
      if (instance === undefined || instance === null) return instance;

      return SC.get(instance, 'data');
    };
    value.deserialize = value.deserialize || function(data) {
      if (data === undefined || data === null) return data;

      if (isString(value.type)) {
        value.type = SC.getPath(value.type);
      }
      return value.type.create(data);
    };
  };

  expandRemoteHasOneSchemaItem = function(name, schema) {
    var value = schema[name];
    value.path = value.path || name + '_id';
    if (!schema[value.path]) {
      schema[value.path] = Number;
      expandSchemaItem(value.path, schema);
    }

    value.serialize = value.serialize || function(instance) {
      if (instance === undefined || instance === null) return instance;
      return SC.get(instance, 'id');
    };
    value.deserialize = value.deserialize || function(id) {
      if (id === undefined || id === null) return id;

      if (isString(value.type)) {
        value.type = SC.getPath(value.type);
      }
      return value.type.create({id: id});
    };
  };

  expandRemoteHasManySchemaItem = function(name, schema) {
    var value = schema[name];
    value.deserialize = value.deserialize || function(options) {
      if (isString(value.itemType)) {
        value.itemType = SC.getPath(value.itemType);
      }
      options.type = value.itemType;

      return value.type.create(options);
    };
  };

  expandNestedHasManySchemaItem = function(name, schema) {
    var value = schema[name];
    value.path = value.path || name;
    value.deserialize = value.deserialize || function(data) {
      if (isString(value.itemType)) {
        value.itemType = SC.getPath(value.itemType);
      }
      return value.type.create({
        content: data,
        type: value.itemType,
        parse: value.parse
      });
    };
  };

  expandSchemaItem = function(name, schema) {
    var value = schema[name];

    if (value === Number || value === String || value === Boolean || value === Date || value === Object) {
      value = {type: value};
      schema[name] = value;
    }

    if (isObject(value) && value.type) {

      if (value.type.isSCResource || isString(value.type)) { // a has-one association
        value.nested = !!value.nested;

        if (value.nested) {
          expandNestedHasOneSchemaItem(name, schema);
        } else {
          expandRemoteHasOneSchemaItem(name, schema);
        }

      } else if(value.type.isSCResourceCollection) { // a has-many association
        if (value.url) {
          expandRemoteHasManySchemaItem(name, schema);
        } else if (value.nested) {
          expandNestedHasManySchemaItem(name, schema);
        }
      } else { // a regular attribute
        value.path = value.path || name;
      }

      var serializer;
      switch (value.type) {
        case Number:
          serializer = function(v) { return v === undefined ? undefined : ( v === null ? null : Number(v) ); };
          break;
        case String:
          serializer = function(v) { return v === undefined ? undefined : ( v === null ? null : '' + v ); };
          break;
        case Boolean:
          serializer = function(v) { return v === true || v === 'true'; };
          break;
        case Date:
          serializer = function(v) { return v === undefined ? undefined : ( v === null ? null : new Date(v) ); };
          break;
        case Object:
          serializer = function(v) { return v; };
          break;
      }

      if (serializer) {
        value.serialize   = value.serialize   || serializer;
        value.deserialize = value.deserialize || serializer;
      }
    }
  };

  expandSchema = function(schema) {
    for (var name in schema) {
      if (schema.hasOwnProperty(name)) {
        expandSchemaItem(name, schema);
      }
    }

    return schema;
  };

  // the function for a given regular property
  propertyFunction = function(name, value) {
    var propertyOptions = this.constructor.schema[name];
    var data = SC.get(this, 'data');

    if (arguments.length === 1) { // getter
      var serializedValue;
      if (data) serializedValue = SC.getPath(data, propertyOptions.path);

      if (serializedValue === undefined) {
        SC.run.next(this, this.fetch);
        return;
      } else {
        value = propertyOptions.deserialize(serializedValue);
      }
    } else { // setter
      SC.setPath(data, propertyOptions.path, propertyOptions.serialize(value));
    }

    return value;
  };

  // Build a cumputed property function for a regular property.
  createPropertyFunction = function(propertyOptions) {
    return propertyFunction.property('data.' + propertyOptions.path).cacheable();
  };

  // The computed property function for a url based has-many association
  hasManyFunction = function(name, value) {
    if (arguments.length === 1) { // getter
      var propertyOptions = this.constructor.schema[name];
      var options = SC.copy(propertyOptions);

      if ($.isFunction(options.url)) {
        options.url = options.url(this);
      } else if ('string' === typeof options.url) {
        options.url = options.url.fmt(SC.get(this, 'id'));
      }

      return propertyOptions.deserialize(options);
    } else { // setter
      // throw "You can not set this property";
    }
  }.property('id').cacheable();

  createSchemaProperties = function(schema) {
    var properties = {}, propertyOptions;

    for (var propertyName in schema) {
      if (schema.hasOwnProperty(propertyName)) {
        propertyOptions = schema[propertyName];
        properties[propertyName] = propertyOptions.path ? createPropertyFunction(propertyOptions)
                                                        : hasManyFunction;
      }
    }

    return properties;
  };

  SC.Resource.reopenClass({
    isSCResource: true,

    // Create an instance of this resource. If `options` includes an
    // `id`, first check the identity map and return the existing resource
    // with that ID if found.
    create: function(options) {
      var instance;
      if (options && options.id) {
        var id = options.id.toString();
        this.identityMap = this.identityMap || {};
        instance = this.identityMap[id];
        if (!instance) {
          this.identityMap[id] = instance = this._super.call(this);
          SC.set(instance, 'data', options);
        }
      } else {
        instance = this._super.call(this);
        SC.set(instance, 'data', options);
      }
      return instance;
    },

    // Parse JSON -- likely returned from an AJAX call -- into the
    // properties for an instance of this resource. Override this method
    // to produce different parsing behavior.
    parse: function(json) {
      return json;
    },

    // Define a resource class.
    //
    // Parameters:
    //
    //  * `schema` -- the properties schema for the resource class
    //  * `url` -- either a function that returns the URL for syncing
    //    resources or a string. If the latter, a string of the form
    //    "/widgets" is turned into a function that returns "/widgets" if
    //    the Widget's ID is not present and "/widgets/{id}" if it is.
    //  * `parse` -- the function used to parse JSON returned from AJAX
    //    calls into the resource properties. By default, simply returns
    //    the JSON.
    define: function(options) {
      options = options || {};
      var schema = expandSchema(options.schema);

      var klass = this.extend(createSchemaProperties(schema));

      var classOptions = {
        url: options.url,
        schema: schema
      };

      if (options.parse) {
        classOptions.parse = options.parse;
      }

      klass.reopenClass(classOptions);

      return klass;
    },

    resourceURL: function(instance) {
      if ($.isFunction(this.url)) {
        return this.url(instance);
      } else {
        if (instance) {
          return this.url + '/' + SC.get(instance, 'id');
        } else {
          return this.url;
        }
      }
    }
  });

  SC.ResourceCollection = SC.ArrayProxy.extend({
    isSCResourceCollection: true,
    type: SC.Required,
    fetch: function() {
      if (!this.prePopulated && SC.get(this, 'resourceState') === SC.Resource.Lifecycle.UNFETCHED) {
        SC.set(this, 'resourceState', SC.Resource.Lifecycle.FETCHING);
        var self = this;

        this.deferedFetch = this._fetch(function(json) {
          SC.set(self, 'content', self.instantiateItems(self.parse(json)));
        });

        this.deferedFetch.always(function() {
          SC.set(self, 'resourceState', SC.Resource.Lifecycle.FETCHED);
        });
      }
      return this.deferedFetch;
    },
    _fetch: function(callback) {
      return getJSON(this.url || this.type.resourceURL(), callback);
    },
    instantiateItems: function(items) {
      return items.map(function(item) {
        if (item instanceof this.type) {
          return item;
        } else {
          return this.type.create(item);
        }
      }, this);
    },
    parse: function(json) {
      return _.map(json, this.type.parse);
    },
    content: function(name, value) {
      if (arguments.length === 1) { // getter
        SC.run.next(this, this.fetch);
        return this.realContent;
      } else { // setter
        this.realContent = this.instantiateItems(value);
        return value;
      }
    }.property()
  });

  SC.ResourceCollection.reopenClass(SC.Resource.Lifecycle);

  SC.ResourceCollection.reopenClass({
    isSCResourceCollection: true,
    create: function(options) {
      options = options || {};
      var content = options.content;
      delete options.content;

      options.prePopulated = !! content;

      var instance = this._super.call(this, options);

      if (content) {
        SC.set(instance, 'content', content);
      }

      return instance;
    }
  });
}());
<commit_msg>make better use of SC.ComputedProperty and cacheable for ResourceCollection<commit_after>(function(undefined) {
  var expandSchema, expandSchemaItem, propertyFunction,
      createPropertyFunction, hasManyFunction, createSchemaProperties,
      expandRemoteHasOneSchemaItem, expandRemoteHasManySchemaItem,
      expandNestedHasOneSchemaItem, expandNestedHasManySchemaItem;

  function isString(obj) {
    return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
  }

  function isObject(obj) {
    return obj === Object(obj);
  }

  var isFunction = $.isFunction;

  function getJSON(url, callback) {
    var options = {
      url: url,
      dataType: 'json',
      success: callback
    };

    if (SC.Resource.errorHandler) {
      options.error = SC.Resource.errorHandler;
    }

    return $.ajax(options);
  }

  SC.Resource = SC.Object.extend({
    isSCResource: true,

    fetch: function() {
      SC.set(this, 'resourceState', SC.Resource.Lifecycle.FETCHING);

      var self = this;

      this.deferedFetch = getJSON(this.resourceURL(), function(json) {
        SC.set(self, 'data', self.constructor.parse(json));
      });

      this.deferedFetch.always(function() {
        SC.set(self, 'resourceState', SC.Resource.Lifecycle.FETCHED);
      });

      return this.deferedFetch;
    },

    resourceURL: function() {
      return this.constructor.resourceURL(this);
    },

    // Turn this resource into a JSON object to be saved via AJAX. Override
    // this method to produce different syncing behavior.
    toJSON: function() {
      return SC.get(this, 'data');
    },

    isNew: function() {
      return !SC.get(this, 'id');
    },

    save: function() {
      var ajaxOptions = {
        data: this.toJSON()
      };

      if (this.isNew()) {
        ajaxOptions.type = 'POST';
        ajaxOptions.url = this.constructor.resourceURL();
      } else {
        ajaxOptions.type = 'PUT';
        ajaxOptions.url = this.resourceURL();
      }

      return $.ajax(ajaxOptions);
    }
  });

  SC.Resource.Lifecycle = {
    INITIALIZING: 0,
    UNFETCHED:    10,
    FETCHING:     20,
    FETCHED:      30,
    create: function(options) {
      options = options || {};
      options.resourceState = SC.Resource.Lifecycle.INITIALIZING;
      var instance = this._super.call(this, options);
      if (SC.get(instance, 'resourceState') === SC.Resource.Lifecycle.INITIALIZING) {
        SC.set(instance, 'resourceState', SC.Resource.Lifecycle.UNFETCHED);
      }
      return instance;
    }
  };

  SC.Resource.reopenClass(SC.Resource.Lifecycle);

  expandNestedHasOneSchemaItem = function(name, schema) {
    var value = schema[name];
    value.path = value.path || name;

    value.serialize = value.serialize || function(instance) {
      if (instance === undefined || instance === null) return instance;

      return SC.get(instance, 'data');
    };
    value.deserialize = value.deserialize || function(data) {
      if (data === undefined || data === null) return data;

      if (isString(value.type)) {
        value.type = SC.getPath(value.type);
      }
      return value.type.create(data);
    };
  };

  expandRemoteHasOneSchemaItem = function(name, schema) {
    var value = schema[name];
    value.path = value.path || name + '_id';
    if (!schema[value.path]) {
      schema[value.path] = Number;
      expandSchemaItem(value.path, schema);
    }

    value.serialize = value.serialize || function(instance) {
      if (instance === undefined || instance === null) return instance;
      return SC.get(instance, 'id');
    };
    value.deserialize = value.deserialize || function(id) {
      if (id === undefined || id === null) return id;

      if (isString(value.type)) {
        value.type = SC.getPath(value.type);
      }
      return value.type.create({id: id});
    };
  };

  expandRemoteHasManySchemaItem = function(name, schema) {
    var value = schema[name];
    value.deserialize = value.deserialize || function(options) {
      if (isString(value.itemType)) {
        value.itemType = SC.getPath(value.itemType);
      }
      options.type = value.itemType;

      return value.type.create(options);
    };
  };

  expandNestedHasManySchemaItem = function(name, schema) {
    var value = schema[name];
    value.path = value.path || name;
    value.deserialize = value.deserialize || function(data) {
      if (isString(value.itemType)) {
        value.itemType = SC.getPath(value.itemType);
      }
      return value.type.create({
        content: data,
        type: value.itemType,
        parse: value.parse
      });
    };
  };

  expandSchemaItem = function(name, schema) {
    var value = schema[name];

    if (value === Number || value === String || value === Boolean || value === Date || value === Object) {
      value = {type: value};
      schema[name] = value;
    }

    if (isObject(value) && value.type) {

      if (value.type.isSCResource || isString(value.type)) { // a has-one association
        value.nested = !!value.nested;

        if (value.nested) {
          expandNestedHasOneSchemaItem(name, schema);
        } else {
          expandRemoteHasOneSchemaItem(name, schema);
        }

      } else if(value.type.isSCResourceCollection) { // a has-many association
        if (value.url) {
          expandRemoteHasManySchemaItem(name, schema);
        } else if (value.nested) {
          expandNestedHasManySchemaItem(name, schema);
        }
      } else { // a regular attribute
        value.path = value.path || name;
      }

      var serializer;
      switch (value.type) {
        case Number:
          serializer = function(v) { return v === undefined ? undefined : ( v === null ? null : Number(v) ); };
          break;
        case String:
          serializer = function(v) { return v === undefined ? undefined : ( v === null ? null : '' + v ); };
          break;
        case Boolean:
          serializer = function(v) { return v === true || v === 'true'; };
          break;
        case Date:
          serializer = function(v) { return v === undefined ? undefined : ( v === null ? null : new Date(v) ); };
          break;
        case Object:
          serializer = function(v) { return v; };
          break;
      }

      if (serializer) {
        value.serialize   = value.serialize   || serializer;
        value.deserialize = value.deserialize || serializer;
      }
    }
  };

  expandSchema = function(schema) {
    for (var name in schema) {
      if (schema.hasOwnProperty(name)) {
        expandSchemaItem(name, schema);
      }
    }

    return schema;
  };

  // the function for a given regular property
  propertyFunction = function(name, value) {
    var propertyOptions = this.constructor.schema[name];
    var data = SC.get(this, 'data');

    if (arguments.length === 1) { // getter
      var serializedValue;
      if (data) serializedValue = SC.getPath(data, propertyOptions.path);

      if (serializedValue === undefined) {
        SC.run.next(this, this.fetch);
        return;
      } else {
        value = propertyOptions.deserialize(serializedValue);
      }
    } else { // setter
      SC.setPath(data, propertyOptions.path, propertyOptions.serialize(value));
    }

    return value;
  };

  // Build a cumputed property function for a regular property.
  createPropertyFunction = function(propertyOptions) {
    return propertyFunction.property('data.' + propertyOptions.path).cacheable();
  };

  // The computed property function for a url based has-many association
  hasManyFunction = function(name, value) {
    if (arguments.length === 1) { // getter
      var propertyOptions = this.constructor.schema[name];
      var options = SC.copy(propertyOptions);

      if ($.isFunction(options.url)) {
        options.url = options.url(this);
      } else if ('string' === typeof options.url) {
        options.url = options.url.fmt(SC.get(this, 'id'));
      }

      return propertyOptions.deserialize(options);
    } else { // setter
      // throw "You can not set this property";
    }
  }.property('id').cacheable();

  createSchemaProperties = function(schema) {
    var properties = {}, propertyOptions;

    for (var propertyName in schema) {
      if (schema.hasOwnProperty(propertyName)) {
        propertyOptions = schema[propertyName];
        properties[propertyName] = propertyOptions.path ? createPropertyFunction(propertyOptions)
                                                        : hasManyFunction;
      }
    }

    return properties;
  };

  SC.Resource.reopenClass({
    isSCResource: true,

    // Create an instance of this resource. If `options` includes an
    // `id`, first check the identity map and return the existing resource
    // with that ID if found.
    create: function(options) {
      var instance;
      if (options && options.id) {
        var id = options.id.toString();
        this.identityMap = this.identityMap || {};
        instance = this.identityMap[id];
        if (!instance) {
          this.identityMap[id] = instance = this._super.call(this);
          SC.set(instance, 'data', options);
        }
      } else {
        instance = this._super.call(this);
        SC.set(instance, 'data', options);
      }
      return instance;
    },

    // Parse JSON -- likely returned from an AJAX call -- into the
    // properties for an instance of this resource. Override this method
    // to produce different parsing behavior.
    parse: function(json) {
      return json;
    },

    // Define a resource class.
    //
    // Parameters:
    //
    //  * `schema` -- the properties schema for the resource class
    //  * `url` -- either a function that returns the URL for syncing
    //    resources or a string. If the latter, a string of the form
    //    "/widgets" is turned into a function that returns "/widgets" if
    //    the Widget's ID is not present and "/widgets/{id}" if it is.
    //  * `parse` -- the function used to parse JSON returned from AJAX
    //    calls into the resource properties. By default, simply returns
    //    the JSON.
    define: function(options) {
      options = options || {};
      var schema = expandSchema(options.schema);

      var klass = this.extend(createSchemaProperties(schema));

      var classOptions = {
        url: options.url,
        schema: schema
      };

      if (options.parse) {
        classOptions.parse = options.parse;
      }

      klass.reopenClass(classOptions);

      return klass;
    },

    resourceURL: function(instance) {
      if ($.isFunction(this.url)) {
        return this.url(instance);
      } else {
        if (instance) {
          return this.url + '/' + SC.get(instance, 'id');
        } else {
          return this.url;
        }
      }
    }
  });

  SC.ResourceCollection = SC.ArrayProxy.extend({
    isSCResourceCollection: true,
    type: SC.Required,
    fetch: function() {
      if (!this.prePopulated && SC.get(this, 'resourceState') === SC.Resource.Lifecycle.UNFETCHED) {
        SC.set(this, 'resourceState', SC.Resource.Lifecycle.FETCHING);
        var self = this;

        this.deferedFetch = this._fetch(function(json) {
          SC.set(self, 'content', self.instantiateItems(self.parse(json)));
        });

        this.deferedFetch.always(function() {
          SC.set(self, 'resourceState', SC.Resource.Lifecycle.FETCHED);
        });
      }
      return this.deferedFetch;
    },
    _fetch: function(callback) {
      return getJSON(this.url || this.type.resourceURL(), callback);
    },
    instantiateItems: function(items) {
      return items.map(function(item) {
        if (item instanceof this.type) {
          return item;
        } else {
          return this.type.create(item);
        }
      }, this);
    },
    parse: function(json) {
      return _.map(json, this.type.parse);
    },
    content: function(name, value) {
      if (arguments.length === 1) { // getter
        SC.run.next(this, this.fetch);
      } else { // setter
        return this.instantiateItems(value);
      }
    }.property().cacheable()
  });

  SC.ResourceCollection.reopenClass(SC.Resource.Lifecycle);

  SC.ResourceCollection.reopenClass({
    isSCResourceCollection: true,
    create: function(options) {
      options = options || {};
      var content = options.content;
      delete options.content;

      options.prePopulated = !! content;

      var instance = this._super.call(this, options);

      if (content) {
        SC.set(instance, 'content', content);
      }

      return instance;
    }
  });
}());
<|endoftext|>


<commit_before>// ---------------- Operation --------------------------------------------------

var bodyParser = require('body-parser'),
    express = require('express'),
    // Server
    server = require('./../../../webserver'),
    URL = server.serverUrl,
    // REST-API-Router
    api = require('./../rest-api'),
    // Database Access (salesforce REST-API)
    db = require('./../database/salesforce/database'),

    i2c = require('masterthesis-i2c-library');
    // Express.js Application
    app = module.exports = express();

app.use( bodyParser.json() );       // to support JSON-encoded bodies

// ---------------- API --------------------------------------------------------

var OPERATION = '/light';

// ---------------- Operations --------------------------------------------

var requestBars = function (req, res, next) {
  db.getBars(req, res, next);
};

var requestBar = function (req, res, next) {
  db.getBar(req, res, next);
};

var requestSide = function (req, res, next) {
  db.getSideByLabel(req, res, next);
};

var requestAllSides = function (req, res, next) {
  db.getSidesByBar(req, res, next);
};

var sendI2CRequest = function (req, res, next) {

  var id, receiver, side, operation, lednumber, color, brightness;

  if (req.response._success) {

    if (req.ledControl) {

      operation = req.params.operation;
      lednumber = req.params.led;

      if (operation.toLowerCase() != 'new' &&
          typeof lednumber == 'undefined') {

         res.json(
         {
           "leds" : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
         });
	 next();

      } else if (operation.toLowerCase() == 'new') {
        lednumber = 0;
      }

      receiver = req.ledControl;
      id = req.response.object._fields.id;
      operation = req.params.operation;
      side = req.selectedSide;

      if (!req.params.color)
        color = 'ff0000';
      else
        color = req.params.color;

      if (!req.params.brightness)
        brightness = 100;
      else
        brightness = parseInt(req.params.brightness);

      if (operation.toLowerCase() === 'new')
        operation = '*';
      else if (operation.toLowerCase() === 'add')
        operation = '+';
      else if (operation.toLowerCase() === 'remove')
        operation = '-';

      lednumber = parseInt(req.params.led) + 1;

      console.log('>> SEND I2C REQUEST: '+receiver+', '+operation+', '+lednumber+', '+color+', '+brightness);
      i2c.light(receiver, side, operation, lednumber, color, brightness);
      req.body =
        {

        };

    } else {
      res.send('ERROR: sendI2CRequest(): No LED Controller');
    }
  } else {
    res.send('ERROR: sendI2CRequest(): No Side Found');
  }
  next();
};

var updateBarSides = function (req, res, next) {
  //db.updateSides(req, res, next);
};

// ---------------- Routing -----------------------------------------------

/*
 * ## List all receivers
 */
app.get('/', [requestBars], function(req, res) {
  res.json(req.response);
});

/*
 * ## Get a bar by label
 */
app.get('/:label', [requestBar, requestAllSides], function(req, res) {
 res.json(req.response);
});

/*
 * ## Get a bar by label (A1, A2, ...), side(a, b, c, d)
 */
app.get('/:label/:side', [requestBar, requestSide], function(req, res) {
 res.json(req.response);
});

/*
 * ## Get a bar by label (A1, A2, ...), side(a, b, c, d)  operation (new, add, remove)
 */
app.get('/:label/:side/:operation', [requestBar, requestSide, sendI2CRequest, updateBarSides], function(req, res) {
 res.json(
   {
     "leds" : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
   }
  );
});

/*
 * ## Get a bar by label (A1, A2, ...), side(a, b, c, d), operation (new, add, remove), led number (0-10),
 */
app.get('/:label/:side/:operation/:led', [requestBar, requestSide, sendI2CRequest, updateBarSides], function(req, res) {
 res.json(req.response);
});

/*
 * ## Get a bar by label (A1, A2, ...), side(a, b, c, d), operation (new, add, remove), led number (0-10), color (ff0000)
 */
app.get('/:label/:side/:operation/:led/:color', [requestBar, requestSide, sendI2CRequest, updateBarSides], function(req, res) {
 res.json(req.response);
});

/*
 * ## Get a bar by label (A1, A2, ...), side(a, b, c, d), operation (new, add, remove), led number (0-10), color (ff0000), brightness (0-100)
 */
app.get('/:label/:side/:operation/:led/:color/:brightness', [requestBar, requestSide, sendI2CRequest, updateBarSides], function(req, res) {
 res.json(req.response);
});
<commit_msg>C:/Program Files (x86)/Git/light update<commit_after>// ---------------- Operation --------------------------------------------------

var bodyParser = require('body-parser'),
    express = require('express'),
    // Server
    server = require('./../../../webserver'),
    URL = server.serverUrl,
    // REST-API-Router
    api = require('./../rest-api'),
    // Database Access (salesforce REST-API)
    db = require('./../database/salesforce/database'),

    i2c = require('masterthesis-i2c-library');
    // Express.js Application
    app = module.exports = express();

app.use( bodyParser.json() );       // to support JSON-encoded bodies

// ---------------- API --------------------------------------------------------

var OPERATION = '/light';

// ---------------- Operations --------------------------------------------

var requestBars = function (req, res, next) {
  db.getBars(req, res, next);
};

var requestBar = function (req, res, next) {
  db.getBar(req, res, next);
};

var requestSide = function (req, res, next) {
  db.getSideByLabel(req, res, next);
};

var requestAllSides = function (req, res, next) {
  db.getSidesByBar(req, res, next);
};

var sendI2CRequest = function (req, res, next) {

  var id, receiver, side, operation, lednumber, color, brightness;

  if (req.response._success) {

    if (req.ledControl) {

      operation = req.params.operation;
      lednumber = req.params.led;

      if (operation.toLowerCase() != 'new' &&
          typeof lednumber == 'undefined') {

         res.json(
         {
           "leds" : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
         });
	 next();

      } else if (operation.toLowerCase() == 'new') {
        lednumber = 0;
      }

      receiver = req.ledControl;
      id = req.response.object._fields.id;
      operation = req.params.operation;
      side = req.selectedSide;

      if (!req.params.color)
        color = 'ff0000';
      else
        color = req.params.color;

      if (!req.params.brightness)
        brightness = 100;
      else
        brightness = parseInt(req.params.brightness);

      if (operation.toLowerCase() === 'new')
        operation = '*';
      else if (operation.toLowerCase() === 'add')
        operation = '+';
      else if (operation.toLowerCase() === 'remove')
        operation = '-';

      lednumber = parseInt(req.params.led) + 1;
      var leds = Array(11);

      switch (lednumber) {
        case 1: leds[0] = color; break;
        case 2: leds[1] = color; break;
        case 3: leds[2] = color; break;
        case 4: leds[3] = color; break;
        case 5: leds[4] = color; break;
        case 6: leds[5] = color; break;
        case 7: leds[6] = color; break;
        case 8: leds[7] = color; break;
        case 9: leds[8] = color; break;
        case 10: leds[9] = color; break;
        case 11: leds[10] = color; break;
        default: break;
      }

      console.log('>> SEND I2C REQUEST: '+receiver+', '+operation+', '+lednumber+', '+color+', '+brightness);
      i2c.light(receiver, side, operation, lednumber, color, brightness);
      req.body =
        {
          "led_0__c": leds[0],
          "led_1__c": leds[1],
          "led_2__c": leds[2],
          "led_3__c": leds[3],
          "led_4__c": leds[4],
          "led_5__c": leds[5],
          "led_6__c": leds[6],
          "led_7__c": leds[7],
          "led_8__c": leds[8],
          "led_9__c": leds[9],
          "led_10__c": leds[10]
        };

    } else {
      res.send('ERROR: sendI2CRequest(): No LED Controller');
    }
  } else {
    res.send('ERROR: sendI2CRequest(): No Side Found');
  }
  next();
};

var updateBarSides = function (req, res, next) {
  db.updateSide(req, res, next);
};

// ---------------- Routing -----------------------------------------------

/*
 * ## List all receivers
 */
app.get('/', [requestBars], function(req, res) {
  res.json(req.response);
});

/*
 * ## Get a bar by label
 */
app.get('/:label', [requestBar, requestAllSides], function(req, res) {
 res.json(req.response);
});

/*
 * ## Get a bar by label (A1, A2, ...), side(a, b, c, d)
 */
app.get('/:label/:side', [requestBar, requestSide], function(req, res) {
 res.json(req.response);
});

/*
 * ## Get a bar by label (A1, A2, ...), side(a, b, c, d)  operation (new, add, remove)
 */
app.get('/:label/:side/:operation', [requestBar, requestSide, sendI2CRequest, updateBarSides], function(req, res) {
 res.json(
   {
     "leds" : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
   }
  );
});

/*
 * ## Get a bar by label (A1, A2, ...), side(a, b, c, d), operation (new, add, remove), led number (0-10),
 */
app.get('/:label/:side/:operation/:led', [requestBar, requestSide, sendI2CRequest, updateBarSides], function(req, res) {
 res.json(req.response);
});

/*
 * ## Get a bar by label (A1, A2, ...), side(a, b, c, d), operation (new, add, remove), led number (0-10), color (ff0000)
 */
app.get('/:label/:side/:operation/:led/:color', [requestBar, requestSide, sendI2CRequest, updateBarSides], function(req, res) {
 res.json(req.response);
});

/*
 * ## Get a bar by label (A1, A2, ...), side(a, b, c, d), operation (new, add, remove), led number (0-10), color (ff0000), brightness (0-100)
 */
app.get('/:label/:side/:operation/:led/:color/:brightness', [requestBar, requestSide, sendI2CRequest, updateBarSides], function(req, res) {
 res.json(req.response);
});
<|endoftext|>


<commit_before>module.exports = function(grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        sass: { //task
            options: { // Target options
                outputStyle: 'compressed',
                sourceMap: true
            },
            dist: { // Target
                files: { // Dictionary of files
                    '../assets/css/main.min.css': 'sass/main.scss' //target: source
                }
            }
        },
        uglify: {
          dist: {
            options: {
              sourceMap: true
            },
            files: {
              '../assets/js/main.min.js':
                [
                  'js/functions.js',
                  'js/ready.js'
                ]
            }
          }
        },
        jshint: {
            // define the files to lint
            files: ['js/**/*.js'],
            options: {
//                ignores: [''],
                globals: {
                    jQuery: true,
                    console: true,
                    module: true
                }
            }
        },
        watch: { //watch task
            js: {
                files: ['<%= jshint.files %>'],
                tasks: ['jshint', 'uglify']
            },
            livereload: {
	            // We use this target to watch files that will trigger the livereload
                files: [
                    // Anytime css is edited or compiled by sass, trigger the livereload on those files
                    '../assets/css/*.css'
                    // Or a js file
                    '../assets/js/*.js'
                ],
                options: { livereload: true }
            }
        }
    });

    grunt.loadNpmTasks('grunt-sass');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');

    grunt.registerTask('build', ['jshint', 'uglify', 'sass']); //alias
};
<commit_msg>Update gruntfile.js<commit_after>module.exports = function(grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        sass: { //task
            options: { // Target options
                outputStyle: 'compressed',
                sourceMap: true
            },
            dist: { // Target
                files: { // Dictionary of files
                    '../assets/css/main.min.css': 'sass/main.scss' //target: source
                }
            }
        },
        uglify: {
          dist: {
            options: {
              sourceMap: true
            },
            files: {
              '../assets/js/main.min.js':
                [
                  'js/functions.js',
                  'js/ready.js'
                ]
            }
          }
        },
        jshint: {
            // define the files to lint
            files: ['js/**/*.js'],
            options: {
//                ignores: [''],
                globals: {
                    jQuery: true,
                    console: true,
                    module: true
                }
            }
        },
        watch: { //watch task
            js: {
                files: ['<%= jshint.files %>'],
                tasks: ['jshint', 'uglify']
            },
            livereload: {
	            // We use this target to watch files that will trigger the livereload
                files: [
                    // Anytime css is edited or compiled by sass, trigger the livereload on those files
                    '../assets/css/*.css',
                    // Or a js file
                    '../assets/js/*.js'
                ],
                options: { livereload: true }
            }
        }
    });

    grunt.loadNpmTasks('grunt-sass');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');

    grunt.registerTask('build', ['jshint', 'uglify', 'sass']); //alias
};
<|endoftext|>


<commit_before>function TagControl($input, $fileList) {
	var that = this;

	function tagify(input) {
		return input.split(' ')
		.filter(function(val)
		{
			return val !== '#' && val.length > 0;
		})
		.map(function(val)
		{
			if (!val.length || val[0] === '#')
				return val;

			return '#' + val;
		});
	}

	$input.on('keyup', function()
	{
		setTimeout(function()
		{
			var tags = tagify($input.val());
			$fileList.filterByTags(tags);
			$input.val(tags.join(' '));
		}, 0);

		return true;
	});
};
_.extend(TagControl.prototype, Backbone.Events);

function FileSelectControl(handlebars) {
	var that = this;

	this._handlebars = handlebars || window.Handlebars
	this._frame = null;
	this._fileList = new FileList();
	this._fileList.on('change:files', this._onFilesChange, this);

	this._cb = function() {}
	this._buttons = {
		'Cancel': this.cancel.bind(this),
		'Ok': this.close.bind(this)
	}

	this._template = E2.views.filebrowser.generic;
	this._frameTemplate = E2.views.filebrowser.frame;

	// setup partials
	['upload', 'tags']
	.forEach(function(pname)
	{
		that._handlebars.registerPartial('filebrowser/'+pname, E2.views.filebrowser[pname]);
	});
}

FileSelectControl.prototype._onFilesChange = function(model)
{
	if (!this._frame)
		return;

	$('.file-selector', this._frame).html(this._renderFiles());
	this._bindTable();
};

FileSelectControl.prototype.template = function(name)
{
	this._template = E2.views.filebrowser[name];
	return this;
};

FileSelectControl.prototype.frame = function(name)
{
	this._frameTemplate = E2.views.filebrowser[name];
	return this;
};

FileSelectControl.prototype.url = function(url)
{
	this._url = url;
	return this;
};

FileSelectControl.prototype.files = function(files)
{
	var items = files.map(function(file)
	{
		if (typeof(file) === 'string')
			return { path: file };

		return file;
	});

	this._fileList.setFiles(items);

	return this;
};

FileSelectControl.prototype.selected = function(file) {
	this._original = file
	this._selected = file
	return this
};

FileSelectControl.prototype.onChange = function(cb) {
	this._cb = cb;
	return this;
};

FileSelectControl.prototype.buttons = function(buttons) {
	this._buttons = buttons;
	return this;
};

FileSelectControl.prototype.modal = function()
{
	this._render();
	return this;
};

FileSelectControl.prototype._renderFiles = function()
{
	var that = this;
	var files = this._fileList.get('files');
	var html = this._template(
	{
		original: this._original,
		url: this._url,
		user: E2.models.user.toJSON(),
		files: files
		.map(function(file)
		{
			if (file._creator)
				file._creator = file._creator.username;

			file.selected = (file.path === that._selected);
			file.name = file.path.substring(file.path.lastIndexOf('/')+1);
			return file;
		})
	});

	return html;
};

FileSelectControl.prototype._render = function()
{
	var self = this;

	this._frame = $(this._frameTemplate(
	{
		original: this._original,
		url: this._url,
		user: E2.models.user.toJSON()
	}));

	$('.file-selector', this._frame).html(this._renderFiles());

	var el = bootbox.dialog(
	{
		message: this._frame
	});

	this._el = el;
	this._inputEl = $('#file-url', this._el);
	this._selectedEl = $('tr.success', this._el);

	// add buttons
	var btnEl = $('.buttons', el)

	Object.keys(this._buttons).map(function(name) {
		$('<button class="btn btn-default">'+name+'</button>')
		.click(function(e) {
			e.preventDefault();
			e.stopPropagation();
			self._buttons[name].call(self, self._inputEl.val(), self._tagsEl.val());
			self.close();
			return false;
		})
		.appendTo(btnEl);
	});

	$('button:last', el)
		.removeClass('btn-default')
		.addClass('btn-primary');

	// bind file rows and click handlers
	this._bindTable();

	$('input', el).on('change', this._onChange.bind(this))
	$('button.close', el).click(this.close.bind(this))

	el.bind('keydown', this._onKeyPress.bind(this))

	// show selected file when modal is opened
	$(el).on('shown.bs.modal', function (e) {
		$('table', el).attr('tabindex', 1).focus();

		if (!self._selectedEl.length)
			return;

		$('table', el).scrollTop(0)
			.scrollTop(
				self._selectedEl.position().top
				- self._selectedEl.height()
				* 10)

	});

	// bind upload form
	this._bindUploadForm();

	// attach TagControl to tags input
	this._tagsEl = $('#tags', el);
	new TagControl(this._tagsEl, this._fileList);

	// show
	el.appendTo('body');

	return this;
};

FileSelectControl.prototype._bindTable = function()
{
	var self = this;

	// bind file rows and click handlers
	function _onClick(e) {
		var tr = $(e.target).closest('tr');
		$('tr.success', self._el).removeClass('success');
		tr.addClass('success');
		self._onSelect(tr);
	}

	$('.file-row', self._el).click(_onClick);
	$('.file-row', self._el).dblclick(function(e) {
		_onClick(e);
		self._onChange();
	});
};

FileSelectControl.prototype._bindUploadForm = function()
{
	var that = this;
	var container = $('#upload', this._el);
	var $form = $('form.fileUploadForm', container);

	if (!$form)
		return;

	$form.on('submit', function(e)
	{
		e.preventDefault();
		e.stopPropagation();

		var formData = new FormData($form[0]);
		$.ajax(
		{
			url: $form[0].action,
			type: 'POST',
			success: function(file)
			{
				console.log("File uploaded:", file.url);
				$('#message', container).html('
'+file.name+' uploaded successfully!
');
				that.selected(file.path);
				that._fileList.addFile(file);

				setTimeout(function()
				{
					that._onSelect($('tr.file-row:first', that._el));
					$('.nav-tabs a:first', that._el).tab('show');
				}, 1000);
			},
			error: function(err)
			{
				$('#message', container).html('
Upload failed: '+err.responseJSON.msg+'
');
			},
			data: formData,
			cache: false,
			contentType: false,
			processData: false,
			dataType: 'json'
		});

		$('#message', container).html('
Please wait...
');

		return false;
	});
};

FileSelectControl.prototype._onKeyPress = function(e) {
	e.stopPropagation();

	switch(e.keyCode) {
		case 27:
			this.cancel()
			break;
		case 13:
			$('button:last', this._el).click()
			break;
		case 38:
			e.preventDefault();
			var prev = this._selectedEl.prev('tr')
			if (prev.length)
				this._onSelect(prev)
			this._scroll(-1)
			break;
		case 40:
			e.preventDefault();
			var next = this._selectedEl.next('tr')
			if (next.length)
				this._onSelect(next)
			this._scroll(1)
			break;
	};
};

FileSelectControl.prototype._scroll = function(amt) {
	if (!this._selectedEl.length)
		return;

	var container = $('.fixed-table-container-inner');
	var threshold = 4 * this._selectedEl.height();
	container.scrollTop(this._selectedEl.offset().top - container.offset().top + container.scrollTop() - threshold);
};

FileSelectControl.prototype._onChange = function() {
	this._cb(this._inputEl.val());
};

FileSelectControl.prototype._onSelect = function(row) {
	var path = row.data('url');

	this._selectedEl.removeClass('success');
	row.addClass('success');

	this._selectedEl = row;
	this._inputEl.val(path);
	this._onChange();
};

FileSelectControl.prototype.cancel = function() {
	this._cb(this._original);
	this.close();
};

FileSelectControl.prototype.close = function() {
	$(this._el).modal('hide');
};

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

function createSelector(path, selected, okButton, okFn, cb)
{
	var ctl = new FileSelectControl();

	okButton = okButton || 'Ok';
	okFn = okFn || function() {};

	if (selected && selected.indexOf('://') === -1)
		selected = selected.substring(selected.lastIndexOf('/') + 1);

	E2.dom.load_spinner.show();

	$.get(path, function(files)
	{
		E2.dom.load_spinner.hide();

		var buttons = {
			'Download': function(file) {
				var url = '/dl' + path + file;
				var iframe = $('#dl-frame');
				if (!iframe.length)
					iframe = $('').hide().appendTo('body');
				iframe.attr('src', url);
			},
			'Cancel': function() {}
		};

		buttons[okButton] = okFn;

		ctl
		.url(path)
		.buttons(buttons)
		.files(files)
		.selected(selected)

		cb(ctl)
	});

	return ctl;
};

FileSelectControl.createGraphSelector = function(selected, okButton, okFn)
{
	return createSelector('/graph', selected, okButton, okFn, function(ctl)
	{
		ctl
		.template('graph')
		.modal();
	});
};

FileSelectControl.createVideoSelector = function(selected, okButton, okFn)
{
	return createSelector('/video', selected, okButton, okFn, function(ctl)
	{
		ctl
		.modal();
	});
};

FileSelectControl.createJsonSelector = function(selected, okButton, okFn)
{
	return createSelector('/json', selected, okButton, okFn, function(ctl)
	{
		ctl
		.modal();
	});
};

FileSelectControl.createAudioSelector = function(selected, okButton, okFn)
{
	return createSelector('/audio', selected, okButton, okFn, function(ctl)
	{
		ctl
		.modal();
	});
};

FileSelectControl.createSceneSelector = function(selected, okButton, okFn)
{
	return createSelector('/scene', selected, okButton, okFn, function(ctl)
	{
		ctl
		.modal();
	});
};

FileSelectControl.createTextureSelector = function(selected, okButton, okFn)
{
	return createSelector('/image', selected, okButton, okFn, function(ctl)
	{
		ctl
		.template('texture')
		.modal();
	});
};

FileSelectControl.createForUrl = function(path, selected, okButton, okFn) {
	return createSelector(path, selected, okButton, okFn, function(ctl)
	{
		ctl
		.modal();
	});
}

if (typeof(exports) !== 'undefined')
	exports.FileSelectControl = FileSelectControl;
<commit_msg>handle http errors that have no JSON response<commit_after>function TagControl($input, $fileList) {
	var that = this;

	function tagify(input) {
		return input.split(' ')
		.filter(function(val)
		{
			return val !== '#' && val.length > 0;
		})
		.map(function(val)
		{
			if (!val.length || val[0] === '#')
				return val;

			return '#' + val;
		});
	}

	$input.on('keyup', function()
	{
		setTimeout(function()
		{
			var tags = tagify($input.val());
			$fileList.filterByTags(tags);
			$input.val(tags.join(' '));
		}, 0);

		return true;
	});
};
_.extend(TagControl.prototype, Backbone.Events);

function FileSelectControl(handlebars) {
	var that = this;

	this._handlebars = handlebars || window.Handlebars
	this._frame = null;
	this._fileList = new FileList();
	this._fileList.on('change:files', this._onFilesChange, this);

	this._cb = function() {}
	this._buttons = {
		'Cancel': this.cancel.bind(this),
		'Ok': this.close.bind(this)
	}

	this._template = E2.views.filebrowser.generic;
	this._frameTemplate = E2.views.filebrowser.frame;

	// setup partials
	['upload', 'tags']
	.forEach(function(pname)
	{
		that._handlebars.registerPartial('filebrowser/'+pname, E2.views.filebrowser[pname]);
	});
}

FileSelectControl.prototype._onFilesChange = function(model)
{
	if (!this._frame)
		return;

	$('.file-selector', this._frame).html(this._renderFiles());
	this._bindTable();
};

FileSelectControl.prototype.template = function(name)
{
	this._template = E2.views.filebrowser[name];
	return this;
};

FileSelectControl.prototype.frame = function(name)
{
	this._frameTemplate = E2.views.filebrowser[name];
	return this;
};

FileSelectControl.prototype.url = function(url)
{
	this._url = url;
	return this;
};

FileSelectControl.prototype.files = function(files)
{
	var items = files.map(function(file)
	{
		if (typeof(file) === 'string')
			return { path: file };

		return file;
	});

	this._fileList.setFiles(items);

	return this;
};

FileSelectControl.prototype.selected = function(file) {
	this._original = file
	this._selected = file
	return this
};

FileSelectControl.prototype.onChange = function(cb) {
	this._cb = cb;
	return this;
};

FileSelectControl.prototype.buttons = function(buttons) {
	this._buttons = buttons;
	return this;
};

FileSelectControl.prototype.modal = function()
{
	this._render();
	return this;
};

FileSelectControl.prototype._renderFiles = function()
{
	var that = this;
	var files = this._fileList.get('files');
	var html = this._template(
	{
		original: this._original,
		url: this._url,
		user: E2.models.user.toJSON(),
		files: files
		.map(function(file)
		{
			if (file._creator)
				file._creator = file._creator.username;

			file.selected = (file.path === that._selected);
			file.name = file.path.substring(file.path.lastIndexOf('/')+1);
			return file;
		})
	});

	return html;
};

FileSelectControl.prototype._render = function()
{
	var self = this;

	this._frame = $(this._frameTemplate(
	{
		original: this._original,
		url: this._url,
		user: E2.models.user.toJSON()
	}));

	$('.file-selector', this._frame).html(this._renderFiles());

	var el = bootbox.dialog(
	{
		message: this._frame
	});

	this._el = el;
	this._inputEl = $('#file-url', this._el);
	this._selectedEl = $('tr.success', this._el);

	// add buttons
	var btnEl = $('.buttons', el)

	Object.keys(this._buttons).map(function(name) {
		$('<button class="btn btn-default">'+name+'</button>')
		.click(function(e) {
			e.preventDefault();
			e.stopPropagation();
			self._buttons[name].call(self, self._inputEl.val(), self._tagsEl.val());
			self.close();
			return false;
		})
		.appendTo(btnEl);
	});

	$('button:last', el)
		.removeClass('btn-default')
		.addClass('btn-primary');

	// bind file rows and click handlers
	this._bindTable();

	$('input', el).on('change', this._onChange.bind(this))
	$('button.close', el).click(this.close.bind(this))

	el.bind('keydown', this._onKeyPress.bind(this))

	// show selected file when modal is opened
	$(el).on('shown.bs.modal', function (e) {
		$('table', el).attr('tabindex', 1).focus();

		if (!self._selectedEl.length)
			return;

		$('table', el).scrollTop(0)
			.scrollTop(
				self._selectedEl.position().top
				- self._selectedEl.height()
				* 10)

	});

	// bind upload form
	this._bindUploadForm();

	// attach TagControl to tags input
	this._tagsEl = $('#tags', el);
	new TagControl(this._tagsEl, this._fileList);

	// show
	el.appendTo('body');

	return this;
};

FileSelectControl.prototype._bindTable = function()
{
	var self = this;

	// bind file rows and click handlers
	function _onClick(e) {
		var tr = $(e.target).closest('tr');
		$('tr.success', self._el).removeClass('success');
		tr.addClass('success');
		self._onSelect(tr);
	}

	$('.file-row', self._el).click(_onClick);
	$('.file-row', self._el).dblclick(function(e) {
		_onClick(e);
		self._onChange();
	});
};

FileSelectControl.prototype._bindUploadForm = function()
{
	var that = this;
	var container = $('#upload', this._el);
	var $form = $('form.fileUploadForm', container);

	if (!$form)
		return;

	$form.on('submit', function(e)
	{
		e.preventDefault();
		e.stopPropagation();

		var formData = new FormData($form[0]);
		$.ajax(
		{
			url: $form[0].action,
			type: 'POST',
			success: function(file)
			{
				console.log("File uploaded:", file.url);
				$('#message', container).html('
'+file.name+' uploaded successfully!
');
				that.selected(file.path);
				that._fileList.addFile(file);

				setTimeout(function()
				{
					that._onSelect($('tr.file-row:first', that._el));
					$('.nav-tabs a:first', that._el).tab('show');
				}, 1000);
			},
			error: function(err)
			{
				$('#message', container).html('
Upload failed: '
					+ err.responseJSON ? err.responseJSON.msg : err
					+'
');
			},
			data: formData,
			cache: false,
			contentType: false,
			processData: false,
			dataType: 'json'
		});

		$('#message', container).html('
Please wait...
');

		return false;
	});
};

FileSelectControl.prototype._onKeyPress = function(e) {
	e.stopPropagation();

	switch(e.keyCode) {
		case 27:
			this.cancel()
			break;
		case 13:
			$('button:last', this._el).click()
			break;
		case 38:
			e.preventDefault();
			var prev = this._selectedEl.prev('tr')
			if (prev.length)
				this._onSelect(prev)
			this._scroll(-1)
			break;
		case 40:
			e.preventDefault();
			var next = this._selectedEl.next('tr')
			if (next.length)
				this._onSelect(next)
			this._scroll(1)
			break;
	};
};

FileSelectControl.prototype._scroll = function(amt) {
	if (!this._selectedEl.length)
		return;

	var container = $('.fixed-table-container-inner');
	var threshold = 4 * this._selectedEl.height();
	container.scrollTop(this._selectedEl.offset().top - container.offset().top + container.scrollTop() - threshold);
};

FileSelectControl.prototype._onChange = function() {
	this._cb(this._inputEl.val());
};

FileSelectControl.prototype._onSelect = function(row) {
	var path = row.data('url');

	this._selectedEl.removeClass('success');
	row.addClass('success');

	this._selectedEl = row;
	this._inputEl.val(path);
	this._onChange();
};

FileSelectControl.prototype.cancel = function() {
	this._cb(this._original);
	this.close();
};

FileSelectControl.prototype.close = function() {
	$(this._el).modal('hide');
};

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

function createSelector(path, selected, okButton, okFn, cb)
{
	var ctl = new FileSelectControl();

	okButton = okButton || 'Ok';
	okFn = okFn || function() {};

	if (selected && selected.indexOf('://') === -1)
		selected = selected.substring(selected.lastIndexOf('/') + 1);

	E2.dom.load_spinner.show();

	$.get(path, function(files)
	{
		E2.dom.load_spinner.hide();

		var buttons = {
			'Download': function(file) {
				var url = '/dl' + path + file;
				var iframe = $('#dl-frame');
				if (!iframe.length)
					iframe = $('').hide().appendTo('body');
				iframe.attr('src', url);
			},
			'Cancel': function() {}
		};

		buttons[okButton] = okFn;

		ctl
		.url(path)
		.buttons(buttons)
		.files(files)
		.selected(selected)

		cb(ctl)
	});

	return ctl;
};

FileSelectControl.createGraphSelector = function(selected, okButton, okFn)
{
	return createSelector('/graph', selected, okButton, okFn, function(ctl)
	{
		ctl
		.template('graph')
		.modal();
	});
};

FileSelectControl.createVideoSelector = function(selected, okButton, okFn)
{
	return createSelector('/video', selected, okButton, okFn, function(ctl)
	{
		ctl
		.modal();
	});
};

FileSelectControl.createJsonSelector = function(selected, okButton, okFn)
{
	return createSelector('/json', selected, okButton, okFn, function(ctl)
	{
		ctl
		.modal();
	});
};

FileSelectControl.createAudioSelector = function(selected, okButton, okFn)
{
	return createSelector('/audio', selected, okButton, okFn, function(ctl)
	{
		ctl
		.modal();
	});
};

FileSelectControl.createSceneSelector = function(selected, okButton, okFn)
{
	return createSelector('/scene', selected, okButton, okFn, function(ctl)
	{
		ctl
		.modal();
	});
};

FileSelectControl.createTextureSelector = function(selected, okButton, okFn)
{
	return createSelector('/image', selected, okButton, okFn, function(ctl)
	{
		ctl
		.template('texture')
		.modal();
	});
};

FileSelectControl.createForUrl = function(path, selected, okButton, okFn) {
	return createSelector(path, selected, okButton, okFn, function(ctl)
	{
		ctl
		.modal();
	});
}

if (typeof(exports) !== 'undefined')
	exports.FileSelectControl = FileSelectControl;
<|endoftext|>


<commit_before> /*
  * Copyright 2017 Apigee Corporation.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
  * in the Software without restriction, including without limitation the rights
  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  * copies of the Software, and to permit persons to whom the Software is
  * furnished to do so, subject to the following conditions:
  *
  * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
 // Load the http module to create an http server.
 var http = require("http");
 var apigee = require("apigee-access");
 var rs = require("jsrsasign");
 var jws = require("jws");
 var port = process.env.PORT || 10010;

 var err = {
     "error": "invalid_request",
     "error_description": "invalid request"
 };

 var token = {

 };

 // Header
 var jwtHeader = {
     alg: "RS256",
     typ: "JWT"
 };

 var server = http.createServer(function(request, response) {

     var privateKey = apigee.getVariable(request, "private.privateKey");
     var tstamp = rs.KJUR.jws.IntDate.get('now');

     //check for custom claims
     var customClaims = JSON.parse(apigee.getVariable(request, "claims")) || null;
     if (customClaims) {
         token = customClaims;
     }

     token.api_product_list = apigee.getVariable(request, "apiProductList");
     token.audience = "microgateway";
     token.jti = apigee.getVariable(request, "jti");
     token.iss = apigee.getVariable(request, "iss");
     token.access_token = apigee.getVariable(request, "apigee.access_token");
     token.client_id = apigee.getVariable(request, "apigee.client_id");
     token.nbf = tstamp;
     token.iat = tstamp;

     try {
         if (request.url == "/publicKey" && request.method == "GET") {
             response.writeHead(200, {
                 "Content-Type": "text/plain"
             });
             response.end("");
         }
         else if ((request.url == "/refresh" || request.url == "/token") && request.method == "POST") {
             token.application_name = apigee.getVariable(request, "AccessEntity.ChildNodes.Access-App-Info.App.AppId");
             token.scopes = apigee.getVariable(request, "scope");
             token.exp = tstamp + parseInt(apigee.getVariable(request, "token_expiry"));
         } else if (request.url == "/verifyApiKey" && request.method == "POST") {
             token.application_name = apigee.getVariable(request, "apigee.developer.app.name");
             token.exp = tstamp + 300;//hard code expiry
         } else if (request.url == "/jwkPublicKeys" && request.method == "GET") {
             var publicKey1 = apigee.getVariable(request, "private.publicKey1");
             var publicKey2 = apigee.getVariable(request, "private.publicKey2");
             var certificatelist = {};

             certificatelist.keys = [];

             if (!publicKey1) {
                 response.writeHead(500, {
                     "Content-Type": "application/json"
                 });
                 response.end(JSON.stringify(err));
             } else {
                 var key1 = rs.KEYUTIL.getKey(publicKey1);
                 var jwk1 = rs.KEYUTIL.getJWKFromKey(key1);
                 var public_key1_kid = apigee.getVariable(request, "private.public_key1_kid") || null;
                 if (public_key1_kid !== null) {
                     jwk1.kid = public_key1_kid;
                 }
                 certificatelist.keys.push(jwk1);
                 if (publicKey2) {
                     var key2 = rs.KEYUTIL.getKey(publicKey2);
                     var jwk2 = rs.KEYUTIL.getJWKFromKey(key2);
                     var public_key2_kid = apigee.getVariable(request, "private.public_key2_kid") || null;
                     if (public_key2_kid !== null) {
                         jwk2.kid = public_key2_kid;
                     }

                     certificatelist.keys.push(jwk2);
                 }
                 response.writeHead(200, {
                     "Content-Type": "application/json"
                 });
                 response.end(JSON.stringify(certificatelist));
             }

         } else {
             response.writeHead(404, {
                 "Content-Type": "application/json"
             });
             response.end(JSON.stringify(err));
         }
         var prvKeyObj = rs.KEYUTIL.getKey(privateKey);
         var private_key_kid = apigee.getVariable(request, "private.private_key_kid") || null;
         if (private_key_kid !== null) {
             jwtHeader.kid = private_key_kid;
         }
         var signed_token = {
             "token": jws.sign({header: jwtHeader, payload: token, secret: privateKey})
             //rs.jws.JWS.sign("RS256", JSON.stringify(jwtHeader), token, prvKeyObj)
         };
         response.writeHead(200, {
             "Content-Type": "application/json"
         });
         response.end(JSON.stringify(signed_token));
     } catch (error) {
         response.writeHead(500, {
             "Content-Type": "application/json"
         });
         response.end(JSON.stringify(error));
     }
 });

 server.listen(port);
<commit_msg>add jwk parameters<commit_after> /*
  * Copyright 2017 Apigee Corporation.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
  * in the Software without restriction, including without limitation the rights
  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  * copies of the Software, and to permit persons to whom the Software is
  * furnished to do so, subject to the following conditions:
  *
  * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
 // Load the http module to create an http server.
 var http = require("http");
 var apigee = require("apigee-access");
 var rs = require("jsrsasign");
 var jws = require("jws");
 var port = process.env.PORT || 10010;

 var err = {
     "error": "invalid_request",
     "error_description": "invalid request"
 };

 var token = {

 };

 // Header
 var jwtHeader = {
     alg: "RS256",
     typ: "JWT"
 };

 var server = http.createServer(function(request, response) {

     var privateKey = apigee.getVariable(request, "private.privateKey");
     var tstamp = rs.KJUR.jws.IntDate.get('now');

     //check for custom claims
     var customClaims = JSON.parse(apigee.getVariable(request, "claims")) || null;
     if (customClaims) {
         token = customClaims;
     }

     token.api_product_list = apigee.getVariable(request, "apiProductList");
     token.audience = "microgateway";
     token.jti = apigee.getVariable(request, "jti");
     token.iss = apigee.getVariable(request, "iss");
     token.access_token = apigee.getVariable(request, "apigee.access_token");
     token.client_id = apigee.getVariable(request, "apigee.client_id");
     token.nbf = tstamp;
     token.iat = tstamp;

     try {
         if (request.url == "/publicKey" && request.method == "GET") {
             response.writeHead(200, {
                 "Content-Type": "text/plain"
             });
             response.end("");
         }
         else if ((request.url == "/refresh" || request.url == "/token") && request.method == "POST") {
             token.application_name = apigee.getVariable(request, "AccessEntity.ChildNodes.Access-App-Info.App.AppId");
             token.scopes = apigee.getVariable(request, "scope");
             token.exp = tstamp + parseInt(apigee.getVariable(request, "token_expiry"));
         } else if (request.url == "/verifyApiKey" && request.method == "POST") {
             token.application_name = apigee.getVariable(request, "apigee.developer.app.name");
             token.exp = tstamp + 300;//hard code expiry
         } else if (request.url == "/jwkPublicKeys" && request.method == "GET") {
             var publicKey1 = apigee.getVariable(request, "private.publicKey1");
             var publicKey2 = apigee.getVariable(request, "private.publicKey2");
             var certificatelist = {};

             certificatelist.keys = [];

             if (!publicKey1) {
                 response.writeHead(500, {
                     "Content-Type": "application/json"
                 });
                 response.end(JSON.stringify(err));
             } else {
                 var key1 = rs.KEYUTIL.getKey(publicKey1);
                 var jwk1 = rs.KEYUTIL.getJWKFromKey(key1);
                 var public_key1_kid = apigee.getVariable(request, "private.public_key1_kid") || null;
                 if (public_key1_kid !== null) {
                     jwk1.kid = public_key1_kid;
                     jwk1.kty = "RSA";
                     jwk1.use = "sig";
                 }
                 certificatelist.keys.push(jwk1);
                 if (publicKey2) {
                     var key2 = rs.KEYUTIL.getKey(publicKey2);
                     var jwk2 = rs.KEYUTIL.getJWKFromKey(key2);
                     var public_key2_kid = apigee.getVariable(request, "private.public_key2_kid") || null;
                     if (public_key2_kid !== null) {
                         jwk2.kid = public_key2_kid;
                         jwk2.kty = "RSA";
                         jwk2.use = "sig";
                     }

                     certificatelist.keys.push(jwk2);
                 }
                 response.writeHead(200, {
                     "Content-Type": "application/json"
                 });
                 response.end(JSON.stringify(certificatelist));
             }

         } else {
             response.writeHead(404, {
                 "Content-Type": "application/json"
             });
             response.end(JSON.stringify(err));
         }
         var prvKeyObj = rs.KEYUTIL.getKey(privateKey);
         var private_key_kid = apigee.getVariable(request, "private.private_key_kid") || null;
         if (private_key_kid !== null) {
             jwtHeader.kid = private_key_kid;
         }
         var signed_token = {
             "token": jws.sign({header: jwtHeader, payload: token, secret: privateKey})
             //rs.jws.JWS.sign("RS256", JSON.stringify(jwtHeader), token, prvKeyObj)
         };
         response.writeHead(200, {
             "Content-Type": "application/json"
         });
         response.end(JSON.stringify(signed_token));
     } catch (error) {
         response.writeHead(500, {
             "Content-Type": "application/json"
         });
         response.end(JSON.stringify(error));
     }
 });

 server.listen(port);
<|endoftext|>


<commit_before>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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
 *
 *   http://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.
 *
*/

/*
 * This probably should live in plugman/cli world
 * Transoforms old require calls to new node-style require calls
 */

var fs = require('fs');
var path = require('path');
var through = require('through');
var UglifyJS = require('uglify-js');
var root = fs.realpathSync(path.join(__dirname, '..', '..'));

var requireTr = {

  transform: function(file) {
    var data = '';

    function write(buf) {
      data += buf;
    }

    function end() {
      // getting rid of define and require properties of cordova
     // if(file.match(/cordova.js$/)) {
     //   data = data.replace(/ *(define:define|require:require),\n/, '');
     // }
      this.queue(_updateRequires(data));
      this.queue(null);
    }

    return through(write, end);
  },
  getSymbolList: function() {
    return this.symbolList;
  },
  platform: null,
  symbolList: []
}

/*
 * visits AST and modifies all the require('cordova/*')
 */
function _updateRequires(code) {

  var ast = UglifyJS.parse(code);

  var walker = new UglifyJS.TreeWalker(function(node) {

    // check all function calls
    if(node instanceof UglifyJS.AST_Call) {
      // check if function call is a require('module') call
      if(node.expression.name === "require" && node.args.length === 1) {
        var module = node.args[0].value;
        // make sure require only has one argument and that it starts with cordova (old style require.js)
        if(module !== undefined &&
           module.indexOf("cordova") === 0) {

          // adding symbolList bullcrap
          if(requireTr.symbolList && requireTr.symbolList.indexOf(module) === -1) {
            requireTr.symbolList.push(module);
          }

          // require('cordova') -> cordova.js
          if(module === "cordova") {
            node.args[0].value = path.join(root, "src", "cordova_b");
          // android and amazon-fireos have some special require's
          } else if(module.match(/cordova\/(android|amazon-fireos)\/(.+)/)) {
            node.args[0].value = module.replace(/cordova\/(android|amazon-fireos)\/(.+)/,
                                    path.join(root, "src", "$1", "android", "$2"));
          // require('cordova/exec') and require('cordova/platform') -> platform's exec/platform
          } else if(module.match(/cordova\/(platform|exec)$/)) {
            node.args[0].value = module.replace(/cordova\/(platform|exec)/,
                                                path.join(root, "src", requireTr.platform, "$1"));
          // require('cordova/anything') should be under common/
          } else if(module.match(/cordova\/(.+)/)) {
            node.args[0].value = module.replace(/cordova\/(.+)/,
                                    path.join(root, "src", "common", "$1"));
          }
        }
      }
    }
  });

  ast.walk(walker);

  var stream = UglifyJS.OutputStream({beautify:true});

  ast.print(stream);

  return stream.toString();
}

module.exports = requireTr;
<commit_msg>replacing init with init_b<commit_after>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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
 *
 *   http://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.
 *
*/

/*
 * This probably should live in plugman/cli world
 * Transoforms old require calls to new node-style require calls
 */

var fs = require('fs');
var path = require('path');
var through = require('through');
var UglifyJS = require('uglify-js');
var root = fs.realpathSync(path.join(__dirname, '..', '..'));

var requireTr = {

  transform: function(file) {
    var data = '';

    function write(buf) {
      data += buf;
    }

    function end() {
      // getting rid of define and require properties of cordova
     // if(file.match(/cordova.js$/)) {
     //   data = data.replace(/ *(define:define|require:require),\n/, '');
     // }
      this.queue(_updateRequires(data));
      this.queue(null);
    }

    return through(write, end);
  },
  getSymbolList: function() {
    return this.symbolList;
  },
  platform: null,
  symbolList: []
}

/*
 * visits AST and modifies all the require('cordova/*')
 */
function _updateRequires(code) {

  var ast = UglifyJS.parse(code);

  var walker = new UglifyJS.TreeWalker(function(node) {

    // check all function calls
    if(node instanceof UglifyJS.AST_Call) {
      // check if function call is a require('module') call
      if(node.expression.name === "require" && node.args.length === 1) {
        var module = node.args[0].value;
        // make sure require only has one argument and that it starts with cordova (old style require.js)
        if(module !== undefined &&
           module.indexOf("cordova") === 0) {

          // adding symbolList bullcrap
          if(requireTr.symbolList && requireTr.symbolList.indexOf(module) === -1) {
            requireTr.symbolList.push(module);
          }

          // require('cordova') -> cordova.js
          if(module === "cordova") {
            node.args[0].value = path.join(root, "src", "cordova_b");
          // android and amazon-fireos have some special require's
          }  else if(module.match(/cordova\/init/)) {
            node.args[0].value = module.replace(/cordova\/init/,
                                    path.join(root, "src", "common", "init_b"));
          // require('cordova/exec') and require('cordova/platform') -> platform's exec/platform
          } else if(module.match(/cordova\/(android|amazon-fireos)\/(.+)/)) {
            node.args[0].value = module.replace(/cordova\/(android|amazon-fireos)\/(.+)/,
                                    path.join(root, "src", "$1", "android", "$2"));
          // require('cordova/exec') and require('cordova/platform') -> platform's exec/platform
          } else if(module.match(/cordova\/(platform|exec)$/)) {
            node.args[0].value = module.replace(/cordova\/(platform|exec)/,
                                                path.join(root, "src", requireTr.platform, "$1"));
          // require('cordova/anything') should be under common/
          } else if(module.match(/cordova\/(.+)/)) {
            node.args[0].value = module.replace(/cordova\/(.+)/,
                                    path.join(root, "src", "common", "$1"));
          }
        }
      }
    }
  });

  ast.walk(walker);

  var stream = UglifyJS.OutputStream({beautify:true});

  ast.print(stream);

  return stream.toString();
}

module.exports = requireTr;
<|endoftext|>


<commit_before>"use strict";

// GameObject constructor
var GameObject = function(x, y) {
    this.x = x;
    this.y = y;
}

// GameObject functions
GameObject.prototype.init = function() { }

GameObject.prototype.update = function() { }

GameObject.prototype.draw = function(ctx) { }

// Ball constructor
var Ball = function(x, y, vx, vy, r) {
    // call parent constructor
    GameObject.call(this, x, y);
    this.radius = r;
    this.vx = vx;
    this.vy = vy;
}

// set Ball parent
Ball.prototype = Object.create(GameObject.prototype);
Ball.prototype.constructor = Ball;

// Ball functions
Ball.prototype.draw = function(ctx) {
    // draw circle
    ctx.fillStyle = "black";
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
    ctx.fill();
}

// Field constructor
var Field = function (x, y, w, h) {
    GameObject.call(this, x, y);
    this.width = w;
    this.height = h;
}

// set Field parent
Field.prototype = Object.create(GameObject.prototype);
Field.prototype.constructor = Field;

// Field functions
Field.prototype.draw = function(ctx) {
    // draw the field
    ctx.strokeStyle = "black";
    ctx.strokeRect(this.x, this.y, this.width, this.height);
}

// Global

// how long (in ms) between updates
var fixedDelta = 16; // roughly 60 fps
var deltaTime = fixedDelta / 1000;
var interval;

var canvas;
var ctx;

var field, ball;

function preinit() {
    // get canvas
    canvas = document.getElementById("canvas");

    // get graphics context
    ctx = canvas.getContext("2d");

    // set frame interval
    interval = setInterval(function() {
        update();
        draw(ctx);
    }, fixedDelta);

    // call init
    init();
}

function init() {
    // create field
    field = new Field(0, 0, canvas.width, canvas.height);

    // create ball in center of field
    ball = new Ball(field.x + field.width / 2, field.y + field.height / 2, 5, 5, 20);
}

function update() {
    // clear canvas for drawing
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // update field
    field.update();

    // update ball
    ball.update();
}

function draw(ctx) {
    // draw field
    field.draw(ctx);

    // draw ball
    ball.draw(ctx);
}

window.onload = preinit;<commit_msg>ball collides with field<commit_after>"use strict";

// GameObject constructor
var GameObject = function(x, y) {
    this.x = x;
    this.y = y;
}

// GameObject functions
GameObject.prototype.init = function() { }

GameObject.prototype.update = function() { }

GameObject.prototype.draw = function(ctx) { }

// Ball constructor
var Ball = function(x, y, vx, vy, r, field) {
    // call parent constructor
    GameObject.call(this, x, y);
    this.radius = r;
    this.vx = vx;
    this.vy = vy;
    this.field = field;
}

// set Ball parent
Ball.prototype = Object.create(GameObject.prototype);
Ball.prototype.constructor = Ball;

// Ball functions
Ball.prototype.update = function() {
    this.x += this.vx * deltaTime;
    this.y += this.vy * deltaTime;

    // if there is a field and this ball knows about it
    if(this.field) {
        // check collisions
        if (this.x + this.radius > field.x + field.width) {
            // off right screen
            this.vx = -this.vx;
        }
        else if (this.x - this.radius < field.x) {
            // off left screen
            this.vx = -this.vx;
        }

        if (this.y + this.radius > field.y + field.height) {
            // off bottom screen
            this.vy = -this.vy;
        }
        else if (this.y - this.radius < field.y) {
            // off top screen
            this.vy = -this.vy;
        }
    }
}

Ball.prototype.draw = function(ctx) {
    // draw circle
    ctx.fillStyle = "black";
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
    ctx.fill();
}

// Field constructor
var Field = function (x, y, w, h) {
    GameObject.call(this, x, y);
    this.width = w;
    this.height = h;
}

// set Field parent
Field.prototype = Object.create(GameObject.prototype);
Field.prototype.constructor = Field;

// Field functions
Field.prototype.draw = function(ctx) {
    // draw the field
    ctx.strokeStyle = "black";
    ctx.strokeRect(this.x, this.y, this.width, this.height);
}

// Global

// how long (in ms) between updates
var fixedDelta = 16; // roughly 60 fps
var deltaTime = fixedDelta / 1000;
var interval;

var canvas;
var ctx;

var field, ball;

function preinit() {
    // get canvas
    canvas = document.getElementById("canvas");

    // get graphics context
    ctx = canvas.getContext("2d");

    // set frame interval
    interval = setInterval(function() {
        update();
        draw(ctx);
    }, fixedDelta);

    // call init
    init();
}

function init() {
    // create field
    field = new Field(0, 0, canvas.width, canvas.height);

    // create ball in center of field
    ball = new Ball(field.x + field.width / 2, field.y + field.height / 2, 60, 50, 20, field);
}

function update() {
    // clear canvas for drawing
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // update field
    field.update();

    // update ball
    ball.update();
}

function draw(ctx) {
    // draw field
    field.draw(ctx);

    // draw ball
    ball.draw(ctx);
}

window.onload = preinit;<|endoftext|>


<commit_before>// TO DO
//  Take into account the angle of the boards when deflecting
//  Need universal variable naming convention for Kinetic shapes on object to replace Puck.puck & Player.player

function Puck (hockey) {
    this.hockey = hockey;
    this.stage = hockey.stage;
    this.velocity = 0.0;
    this.angle = 0.0;
    this.location = { x:110, y:260 };
    this.shot = null;
    this.layer = new Kinetic.Layer({ id: 'puck'});
    this.render();
}

Puck.prototype.render = function() {
    this.puck = new Kinetic.Circle( // Hockey.puck.puck is probably a terrible name
	{
	    x: this.location.x + this.hockey.rink.offset.x,
	    y: this.location.y + this.hockey.rink.offset.y,
	    radius: 3,
	    fill: '#111',
	    stroke: '#000'
	}
    );
    this.layer.add(this.puck);
    this.stage.add(this.layer);
};

Puck.prototype.shoot = function(velocity, angle) {
    this.stopShot();
    this.velocity = velocity? velocity : Math.random() * 10;
    this.angle = angle? angle : Math.random() * 2 * Math.PI;
    var _this = this;
    this.shot = new Kinetic.Animation(
	function(frame) {
	        _this.advance();
        }, _this.layer
    );
    this.shot.start();
};

Puck.prototype.advance = function() {
    this.location.x = this.location.x + this.velocity * Math.sin(this.angle);
    this.location.y = this.location.y + this.velocity * Math.cos(this.angle);

    if(this.velocity > 0) {
        this.velocity -= .05; // Drag
    } else {
        this.shot.stop();
    }

    if(this.location.x > 220) {
        this.location.x = 220 - (this.location.x - 220);
        this.deflect(0, 1, 0);
    } else if(this.location.x < 0) {
        this.location.x = Math.abs(this.location.x);
        this.deflect(0, 1, 0);
    }

    if(this.location.y > 520) {
        this.location.y = 520 - (this.location.y - 520);
        this.deflect(Math.PI, 1, 0);
    } else if (this.location.y < 0) {
        this.location.y = Math.abs(this.location.y);
        this.deflect(Math.PI, 1, 0);
    }
    this.hockey.handleCollisions();
    this.puck.setX(this.location.x + this.hockey.rink.offset.x);
    this.puck.setY(this.location.y + this.hockey.rink.offset.y);
};

Puck.prototype.deflect = function(deflectionAngle, rotationDirection, rotationSpeed) {
	// Basic x-axis deflection
	this.angle = 2 * Math.PI - this.angle;
	// Add the angle of deflection
	this.angle += deflectionAngle;
	// Factor in rotation direction

    // Rotation Direction isn't really what matters most.  What matters is which surface of the stick is hit.
	// This should come through with the deflectionAngle.

	//this.angle *= rotationDirection;

	// Simplify
	this.angle = this.hockey.rink.simplifyRadians(this.angle);
	if(console) console.log('deflection');
};

Puck.prototype.stopShot = function() {
    if(this.shot) this.shot.stop();
};

<commit_msg>reset puck velocity when stopping shot animation<commit_after>// TO DO
//  Take into account the angle of the boards when deflecting
//  Need universal variable naming convention for Kinetic shapes on object to replace Puck.puck & Player.player

function Puck (hockey) {
    this.hockey = hockey;
    this.stage = hockey.stage;
    this.velocity = 0.0;
    this.angle = 0.0;
    this.location = { x:110, y:260 };
    this.shot = null;
    this.layer = new Kinetic.Layer({ id: 'puck'});
    this.render();
}

Puck.prototype.render = function() {
    this.puck = new Kinetic.Circle( // Hockey.puck.puck is probably a terrible name
	{
	    x: this.location.x + this.hockey.rink.offset.x,
	    y: this.location.y + this.hockey.rink.offset.y,
	    radius: 3,
	    fill: '#111',
	    stroke: '#000'
	}
    );
    this.layer.add(this.puck);
    this.stage.add(this.layer);
};

Puck.prototype.shoot = function(velocity, angle) {
    this.stopShot();
    this.velocity = velocity? velocity : Math.random() * 10;
    this.angle = angle? angle : Math.random() * 2 * Math.PI;
    var _this = this;
    this.shot = new Kinetic.Animation(
	function(frame) {
	        _this.advance();
        }, _this.layer
    );
    this.shot.start();
};

Puck.prototype.advance = function() {
    this.location.x = this.location.x + this.velocity * Math.sin(this.angle);
    this.location.y = this.location.y + this.velocity * Math.cos(this.angle);

    if(this.velocity > 0) {
        this.velocity -= .05; // Drag
    } else {
    	this.velocity = 0;
        this.shot.stop();
    }

    if(this.location.x > 220) {
        this.location.x = 220 - (this.location.x - 220);
        this.deflect(0, 1, 0);
    } else if(this.location.x < 0) {
        this.location.x = Math.abs(this.location.x);
        this.deflect(0, 1, 0);
    }

    if(this.location.y > 520) {
        this.location.y = 520 - (this.location.y - 520);
        this.deflect(Math.PI, 1, 0);
    } else if (this.location.y < 0) {
        this.location.y = Math.abs(this.location.y);
        this.deflect(Math.PI, 1, 0);
    }
    this.hockey.handleCollisions();
    this.puck.setX(this.location.x + this.hockey.rink.offset.x);
    this.puck.setY(this.location.y + this.hockey.rink.offset.y);
};

Puck.prototype.deflect = function(deflectionAngle, rotationDirection, rotationSpeed) {
	// Basic x-axis deflection
	this.angle = 2 * Math.PI - this.angle;
	// Add the angle of deflection
	this.angle += deflectionAngle;
	// Factor in rotation direction

    // Rotation Direction isn't really what matters most.  What matters is which surface of the stick is hit.
	// This should come through with the deflectionAngle.

	//this.angle *= rotationDirection;

	// Simplify
	this.angle = this.hockey.rink.simplifyRadians(this.angle);
	if(console) console.log('deflection');
};

Puck.prototype.stopShot = function() {
    if(this.shot) this.shot.stop();
};

<|endoftext|>


<commit_before>/*
 * grunt-plovr-extended
 * https://github.com/ITspirit/grunt-plovr-extended
 *
 * Copyright (c) 2014 Michael Frank
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  var shell = require('shelljs'),
      path = require('path');

  grunt.registerMultiTask('plovr_extended', 'Grunt plugin wrapper for google closure tool plovr - includes all Features without the need of an external config File for Plovr', function() {

    // config filename - check if file already exists - if yes: delete them first
    var configfilename = 'plovr.config.js';

    if (grunt.file.exists(configfilename))
    {
        grunt.file.delete(configfilename);
    }

    var configFileContent = '{\n';
    var cwd = '';

    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({});

    var options_ = '';
    var seperator = '';
    for (var key in options) {
    var switchkey = key.toLowerCase();
    switch (switchkey) {
        // String Input Values
        case "id":
        case "closure-library":
        case "mode":
        case "level":
        case "inherits":
        //case "output-file": ==> triggered via "dest" Files !
        case "output-charset":
        case "module-output-path":
        case "module-production-uri":
        case "module-info-path":
        case "global-scope-name":
        case "jsdoc-html-output-path":
        case "variable-map-input-file":
        case "variable-map-output-file":
        case "property-map-input-file":
        case "property-map-output-file":
        case "test-template":
	    if( (typeof options[key] == "string") && (options[key] !== null) )
            {
	        configFileContent += seperator + '"' + switchkey + '": "' + options[key] + '"';
            }
            else
            {
		grunt.fail.warn('Option "' + switchkey + '" is not type of boolean!' );
            }
          break;
        // boolean Input Values
        case "custom-externs-only":
        case "debug":
        case "experimental-exclude-closure-library":
        case "pretty-print":
        case "print-input-delimiter":
        case "fingerprint":
        case "treat-warnings-as-errors":
        case "export-test-functions":
        case "ambiguate-properties":
        case "disambiguate-properties":
	    if( (typeof options[key] == "boolean") && (options[key] !== null) )
            {
	  	configFileContent += seperator + '"' + switchkey + '": ' + options[key];
            }
            else
            {
		grunt.fail.warn('Option "' + switchkey + '" is not type of boolean!' );
            }
          break;
        // object Input Values
        case "define":
        case "checks":
        case "experimental-compiler-options":
	    if( (typeof options[key] == "object") && (options[key] !== null) )
            {
	        configFileContent += seperator + '"' + switchkey + '": ' + JSON.stringify(options[key],null,"    ");
            }
            else
            {
		grunt.fail.warn('Option "' + switchkey + '" is not type of object!' );
            }
          break;
        case "paths":
        case "externs":
        case "modules":
        case "output-wrapper":
        case "name-suffixes-to-strip":
        case "type-prefixes-to-strip":
        case "id-generators":
        case "soy-function-plugins":
        case "test-excludes":
	    if( (typeof options[key] == "string") && (options[key] !== null) )
            {
	        configFileContent += seperator + '"' + switchkey + '": ' + options[key];
            }
            else if( (typeof options[key] == "object") && (options[key] !== null) )
            {
	        configFileContent += seperator + '"' + switchkey + '": ' + JSON.stringify(options[key],null,"            ");
            }
            else
            {
		grunt.fail.warn('Option "' + switchkey + '" is not type of string or array - is type:' + typeof options[key] );
            }
          break;
        default:
            options_ += ' --' + key + ' ' + options[key];
          break;
      }
      seperator = ',\n';
    }

    // Iterate over all specified file groups.
    this.files.forEach(function(f) {

      var files = f.src.filter(function(filepath) {
        if (!grunt.file.exists(filepath)) {
	  grunt.fail.warn('File ' + filepath + ' does not exist!');
          return false;
        }
        else if (grunt.file.isDir(filepath)) {
	  grunt.fail.warn('File ' + filepath + ' is a directory!');
          return false;
        }
        else {
          return true;
        }
      });

      if (files.length > 0)
      {
        configFileContent += seperator + '"inputs": [\n';
        for (var i = 0; i < files.length; i++) {
          configFileContent += (i>0?',\n':'') + '            "' + files[i] + '"';
        }
        configFileContent += '\n          ]';
      }

      if ( (typeof f.dest == "string") && (f.dest !== null) )
      {
        configFileContent += seperator + '"output-file": "' + f.dest + '"';
      }
    });

    configFileContent += '\n}';

    if(this.data.expand === true) {
        if(this.data.cwd) {
            cwd = this.data.cwd;
            configfilename = path.join(cwd, configfilename);
        }
    };

    // Write configFileContent
    grunt.file.write(configfilename,configFileContent);

        // do the plovr job
    var cmd = 'cd ' + cwd + '; java -jar ' + __dirname + '/../bin/plovr.jar build ' + configfilename + options_;

    var prog = shell.exec(cmd);
    // delete temporary configfile
    grunt.file.delete(configfilename);
    if (prog.code !== 0) {
      grunt.fail.warn(cmd);
    }

  });

};

<commit_msg>remove expand that do nothing at multitask<commit_after>/*
 * grunt-plovr-extended
 * https://github.com/ITspirit/grunt-plovr-extended
 *
 * Copyright (c) 2014 Michael Frank
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  var shell = require('shelljs'),
      path = require('path');

  grunt.registerMultiTask('plovr_extended', 'Grunt plugin wrapper for google closure tool plovr - includes all Features without the need of an external config File for Plovr', function() {

    // config filename - check if file already exists - if yes: delete them first
    var configfilename = 'plovr.config.js';

    if (grunt.file.exists(configfilename))
    {
        grunt.file.delete(configfilename);
    }

    var configFileContent = '{\n',
      cwd,
      cd_cwd = '';

    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({});

    var options_ = '';
    var seperator = '';
    for (var key in options) {
    var switchkey = key.toLowerCase();
    switch (switchkey) {
        // String Input Values
        case "id":
        case "closure-library":
        case "mode":
        case "level":
        case "inherits":
        //case "output-file": ==> triggered via "dest" Files !
        case "output-charset":
        case "module-output-path":
        case "module-production-uri":
        case "module-info-path":
        case "global-scope-name":
        case "jsdoc-html-output-path":
        case "variable-map-input-file":
        case "variable-map-output-file":
        case "property-map-input-file":
        case "property-map-output-file":
        case "test-template":
	    if( (typeof options[key] == "string") && (options[key] !== null) )
            {
	        configFileContent += seperator + '"' + switchkey + '": "' + options[key] + '"';
            }
            else
            {
		grunt.fail.warn('Option "' + switchkey + '" is not type of boolean!' );
            }
          break;
        // boolean Input Values
        case "custom-externs-only":
        case "debug":
        case "experimental-exclude-closure-library":
        case "pretty-print":
        case "print-input-delimiter":
        case "fingerprint":
        case "treat-warnings-as-errors":
        case "export-test-functions":
        case "ambiguate-properties":
        case "disambiguate-properties":
	    if( (typeof options[key] == "boolean") && (options[key] !== null) )
            {
	  	configFileContent += seperator + '"' + switchkey + '": ' + options[key];
            }
            else
            {
		grunt.fail.warn('Option "' + switchkey + '" is not type of boolean!' );
            }
          break;
        // object Input Values
        case "define":
        case "checks":
        case "experimental-compiler-options":
	    if( (typeof options[key] == "object") && (options[key] !== null) )
            {
	        configFileContent += seperator + '"' + switchkey + '": ' + JSON.stringify(options[key],null,"    ");
            }
            else
            {
		grunt.fail.warn('Option "' + switchkey + '" is not type of object!' );
            }
          break;
        case "paths":
        case "externs":
        case "modules":
        case "output-wrapper":
        case "name-suffixes-to-strip":
        case "type-prefixes-to-strip":
        case "id-generators":
        case "soy-function-plugins":
        case "test-excludes":
	    if( (typeof options[key] == "string") && (options[key] !== null) )
            {
	        configFileContent += seperator + '"' + switchkey + '": ' + options[key];
            }
            else if( (typeof options[key] == "object") && (options[key] !== null) )
            {
	        configFileContent += seperator + '"' + switchkey + '": ' + JSON.stringify(options[key],null,"            ");
            }
            else
            {
		grunt.fail.warn('Option "' + switchkey + '" is not type of string or array - is type:' + typeof options[key] );
            }
          break;
        default:
            options_ += ' --' + key + ' ' + options[key];
          break;
      }
      seperator = ',\n';
    }

    // Iterate over all specified file groups.
    this.files.forEach(function(f) {

      var files = f.src.filter(function(filepath) {
        if (!grunt.file.exists(filepath)) {
	  grunt.fail.warn('File ' + filepath + ' does not exist!');
          return false;
        }
        else if (grunt.file.isDir(filepath)) {
	  grunt.fail.warn('File ' + filepath + ' is a directory!');
          return false;
        }
        else {
          return true;
        }
      });

      if (files.length > 0)
      {
        configFileContent += seperator + '"inputs": [\n';
        for (var i = 0; i < files.length; i++) {
          configFileContent += (i>0?',\n':'') + '            "' + files[i] + '"';
        }
        configFileContent += '\n          ]';
      }

      if ( (typeof f.dest == "string") && (f.dest !== null) )
      {
        configFileContent += seperator + '"output-file": "' + f.dest + '"';
      }
    });

    configFileContent += '\n}';
    console.log(this);
    if(this.data.cwd) {
        cwd = this.data.cwd;
        cd_cwd = 'cd ' + cwd + ';';
        console.log('cwd', cwd);
        configfilename = path.join(cwd, configfilename);
    };

    // Write configFileContent
    grunt.file.write(configfilename,configFileContent);

        // do the plovr job
    var cmd = cd_cwd + ' java -jar ' + __dirname + '/../bin/plovr.jar build ' + configfilename + options_;

    var prog = shell.exec(cmd);
    // delete temporary configfile
    grunt.file.delete(configfilename);
    if (prog.code !== 0) {
      grunt.fail.warn(cmd);
    }

  });

};

<|endoftext|>