<commit_before>var MySQLSchema = function(client, table, rawSchema) {
  this.table = table;
  this.client = client;
  this.rawSchema = rawSchema;
  this.model = null;
  this.validator = require('validator');
  this.check = this.validator.check;
  this.sanitize = this.validator.sanitize;

  this.errors = {};
  this.errors[this.table] = {};
  this.errors[this.table].error = null;
  this.errors[this.table].validationErrors = {}

  this.init();
}

MySQLSchema.prototype.init = function() {
  var self = this
    , model = {};

  Object.keys(this.rawSchema).forEach(function(key) {
    model[key] = null;
    Object.keys(self.rawSchema[key]).forEach(function(ak) {
      switch (ak) {
        case 'type':
          model[key] = new self.rawSchema[key][ak]().valueOf();
          break;
        case 'default':
          model[key] = self.rawSchema[key][ak];
          break;
      }
    })
  })

  this.model = model;
}

MySQLSchema.prototype.getJSON = function(callback) {
  var self = this;

  if (callback && (typeof callback == 'function')) {
    callback(self.model);
  } else {
    return self.model;
  }
}

MySQLSchema.prototype.set = function(key, value, callback) {
  var self = this;

  if (this.model.hasOwnProperty(key)) {
    self.model[key] = value;
    if (callback && (typeof callback == 'function')) {
      callback(null, self);
    } else {
      return self;
    }
  } else {
    if (callback && (typeof callback == 'function')) {
      callback(self.errors[self.table].error = "No such attribute: " + key, null);
    } else {
      throw 'No such attribute.';
    }
  }
}

MySQLSchema.prototype.get = function(key, callback) {
  var self = this;

  if (this.model.hasOwnProperty(key)) {
    if (callback && (typeof callback == 'function')) {
      callback(null, model[key]);
    } else {
      return model[key];
    }
  } else {
    if (callback && (typeof callback == 'function')) {
      callback(self.errors[self.table].error = "No such attribute: " + key, null);
    } else {
      throw 'No such attribute.';
    }
  }
}

MySQLSchema.prototype.build = function(params, callback) {
  var self = this;
  try {
    Object.keys(params).forEach(function(k) {
      if (self.model.hasOwnProperty(k)) {
        self.model[k] = params[k];
      }
    })

    if (callback && (typeof callback == 'function')) {
      callback(null, self);
    } else {
      return self;
    }
  } catch (err) {
    if (callback && (typeof callback == 'function')) {
      callback(err, null);
    } else {
      throw "Error while building dbmodel.";
    }
  }
}

MySQLSchema.prototype.validate = function(mainCallback, callback) {
  var self = this;

  function validationCount (fn) {
    var count = 0;
    Object.keys(self.rawSchema).forEach(function(k) {
      if (self.rawSchema[k].hasOwnProperty('validate')) {
        count += 1;
      }
    });
    fn(count);
  }

  function doValidate (fn) {
    Object.keys(self.rawSchema).forEach(function(k) {
      if (self.rawSchema[k].hasOwnProperty('validate')) {
        for (var i=0; i < self.rawSchema[k].validate.length; i++) {
          if (typeof self.rawSchema[k].validate[i] == 'function') {
            // TODO: enable custom validation
          } else {
            try {
              var c = "self.check(self.model[k])." + self.rawSchema[k].validate[i];
              eval(c);
            } catch (e) {
              self.errors[self.table].error = 'Validation error.';
              self.errors[self.table].validationErrors[k] = e.message;
            }
          }
        };
      }
    })

    fn();
  }

  validationCount(function(count) {
    if (count > 0) {
      doValidate(function() {
        if (Object.keys(self.errors[self.table].validationErrors).length > 0) {
          mainCallback(self.errors, null);
        } else {
          callback();
        }
      })
    } else {
      callback();
    }
  })
}

MySQLSchema.prototype.save = function(callback) {
  var self = this;

  self.getJSON(function(o) {
    if (o.id > 0) {
      self.update(o, callback);
    } else {
      self.create(o, callback);
    }
  })
}

MySQLSchema.prototype.create = function(json, callback) {
  var self = this;

  self.build(json, function(err, dbmodel) {
    if (!err) {
      self.validate(callback, function() {
        self.beforeSave(function() {
          self.beforeCreate(function() {
            var attributes = []
              , values = []
              , query = "insert into " + self.table + " set ";

            for (k in self.model) {
              if (k != 'id') {
                attributes.push(k + " = ?");
                values.push(self.model[k]);
              }
            }

            query += attributes.join(', ');

            self.client.query(query, values, function(err, result) {
              if (!err) {
                self.client.query('select * from ' + self.table + " where id = ? limit 1", [result.insertId], function(err, r) {
                  self.model = r[0];
                  callback(err, self.getJSON());

                  self.afterSave(function() {
                    self.afterCreate(function() {

                    })
                  })
                })
              } else {
                callback(self.errors[self.table].error = err, null);
              }
            })
          })
        })
      })
    } else {
      callback(err, null);
    }
  })
}

MySQLSchema.prototype.update = function(json, callback) {
  var self = this;

  self.build(json, function(err, dbmodel) {
    if (!err) {
      self.validate(callback, function() {
        self.beforeSave(function() {
          self.beforeUpdate(function() {
            var attributes = []
              , values = []
              , query = "update " + self.table + " set ";

            for (k in json) {
              if (k != 'id') {
                attributes.push(k + " = ?");
                values.push(self.model[k]);
              }
            }

            query += attributes.join(", ");
            query += " where id = " + json.id;

            self.client.query(query, values, function(err, result) {
              if (!err) {
                callback(err, self.getJSON());

                self.afterSave(function() {
                  self.afterUpdate(function() {

                  })
                })
              } else {
                callback(self.errors[self.table].error = err, null);
              }
            })
          })
        })
      })
    } else {
      callback(err, null);
    }
  })
}

MySQLSchema.prototype.destroy = function(callback) {
  var self = this;

  this.beforeDestroy(function() {
    var query = "delete from " + self.table + " where id = ?";
    self.client.query(query, [self.model.id], function(err, result) {
      if (!err) {
        self.afterDestroy(function() {
          callback(err, result);
        })
      } else {
        callback(self.errors[self.table].error = err, null);
      }
    })
  })
}

MySQLSchema.prototype.query = function(query, callback) {
  var self = this;
  self.client.query(query, function(err, result) {
    callback(err, result);
  })
}

MySQLSchema.prototype.find = function(where, fields, options, callback) {
  var self = this;

  self.parseQueryWhere(where, function(err, rWhere) {
    if (!err) {
      self.parseQueryFields(fields, function(err, rFields) {
        if (!err) {
          self.parseQueryOptions(options, function(err, rOptions) {
            if (!err) {
              var query = 'select ' + rFields + " from " + self.table;

              if (rWhere.where) {
                query += " " + rWhere.where;
              }

              if (rOptions.length) {
                query += " " + rOptions;
              }

              self.client.query(query, rWhere.values, function(err, results) {
                callback(err, results);
              })
            } else {
              callback(err, null);
            }
          })
        } else {
          callback(err, null);
        }
      })
    } else {
      callback(err, null);
    }
  })
}

MySQLSchema.prototype.findOne = function(where, fields, callback) {
  var self = this;

  self.parseQueryWhere(where, function(err, rWhere) {
    if (!err) {
      self.parseQueryFields(fields, function(err, rFields) {
        if (!err) {
          var query = 'select ' + rFields + ' from ' + self.table;
          if (rWhere.where) {
            query += " " + rWhere.where;
          }
          query += " limit 1";

          self.client.query(query, rWhere.values, function(err, result) {
            callback(err, result[0]);
          })
        } else {
          callback(err, null);
        }
      })
    } else {
      callback(err, null);
    }
  })
}

MySQLSchema.prototype.count = function(where, options, callback) {
  var self = this;

  self.parseQueryWhere(where, function(err, rWhere) {
    if (!err) {
      self.parseQueryOptions(options, function(err, rOptions) {
        if (!err) {
          var query = 'select count(*) as count from ' + self.table;

          if (rWhere.where) {
            query += " " + rWhere.where;
          }

          if (rOptions.length) {
            query += " " + rOptions;
          }

          self.client.query(query, rWhere.values, function(err, result) {
            callback(err, result[0].count);
          })
        } else {
          callback(err, null);
        }
      })
    } else {
      callback(err, null);
    }
  })
}

MySQLSchema.prototype.parseQueryWhere = function (where, callback) {
  var self = this;

  try {
    var conditions = []
      , values = []
      , queryStrings = []
      , queryString = '';

    function processUnit (unit, fn) {
      switch (unit.condition) {
        case ('='):
          if (unit.value === null || unit.value == "NULL") {
            conditions.push(unit.field + " IS ?");
            values.push("NULL");
          } else {
            conditions.push(unit.field + " = ?")
            values.push(unit.value);
          }
          break;
        case ('in'):
          unit.value.map(function(v) {
            return self.client.escape(v);
          })

          conditions.push(unit.field + ' IN ("' + unit.value.join('", "') + '")')
          break;
      }

      if (fn && (typeof fn == 'function')) fn();
    }

    function processQuery (connector, fn) {
      where[connector].forEach(function(unit) {
        processUnit(unit);
      })

      queryStrings.push(conditions.join(" AND "));
      conditions = [];

      if (fn && (typeof fn == 'function')) fn();
    }

    switch (Object.keys(where).length) {
      case 0:
        // do nothing. to generate undefined queryString
        break;
      case 3:
        processUnit(where, function() {
          queryStrings.push(conditions[0]);
        })
        break;
      default:
        Object.keys(where).forEach(function(connector) {
          switch (connector) {
            case 'and':
              processQuery(connector);
              break;
            case 'or':
              processQuery(connector);
              break;
            // TODO: throw exception if connector is not in ['and', 'or']
          }
        })
        break;
    }

    if (queryStrings.length > 1) {
      queryString = queryStrings.join(" OR ");
    } else {
      queryString = queryStrings[0];
    }

    if (queryString) {
      queryString = "where " + queryString
    }

    callback(null, {
      where: queryString
      , values: values
    })

  } catch (err) {
    callback("Error while parsing query where.", null);
  }
}

MySQLSchema.prototype.parseQueryFields = function(fields, callback) {
  try {
    var results = '';

    if (fields.length) {
      results += fields.join(', ');
    } else {
      results += '*';
    }

    callback(null, results);
  } catch (err) {
    callback('Error while parsing query fields.', null);
  }
}

MySQLSchema.prototype.parseQueryOptions = function(options, callback) {
  try {
    var optionsArray = []
      , results = '';

    if (Object.keys(options).length) {
      Object.keys(options).forEach(function(key) {
        var option = options[key];

        switch (key) {
          case 'order':
            if ((option instanceof Array) && (option.length == 2) && (['asc', 'desc'].indexOf(option[1].toLowerCase()) >=0)) {
              optionsArray.push("order by " + option.join(' '));
            } else {
              throw 'order is not an instance of array.';
            }
            break;
          case 'group':
            optionsArray.push('group by ' + option);
            break;
          case 'limit':
            optionsArray.push('limit ' + option);
            break;
          case 'offset':
            optionsArray.push('offset ' + option);
            break;
        }
      })
    }

    results += optionsArray.join(' ');

    callback(null, results);
  } catch (err) {
    callback('Error while parsing query options.', null);
  }
}

MySQLSchema.prototype.beforeSave = function(callback) {
  callback();
}

MySQLSchema.prototype.afterSave = function(callback) {
  callback();
}

MySQLSchema.prototype.beforeCreate = function(callback) {
  callback();
}

MySQLSchema.prototype.afterCreate = function(callback) {
  callback();
}

MySQLSchema.prototype.beforeUpdate = function(callback) {
  callback();
}

MySQLSchema.prototype.afterUpdate = function(callback) {
  callback();
}

MySQLSchema.prototype.beforeDestroy = function(callback) {
  callback();
}

MySQLSchema.prototype.afterDestroy = function(callback) {
  callback();
}

exports = module.exports = MySQLSchema;<commit_msg>adding #new method.<commit_after>var MySQLSchema = function(client, table, rawSchema) {
  this.table = table;
  this.client = client;
  this.rawSchema = rawSchema;
  this.model = null;
  this.validator = require('validator');
  this.check = this.validator.check;
  this.sanitize = this.validator.sanitize;

  this.errors = {};
  this.errors[this.table] = {};
  this.errors[this.table].error = null;
  this.errors[this.table].validationErrors = {}

  this.init();
}

MySQLSchema.prototype.init = function() {
  var self = this
    , model = {};

  Object.keys(this.rawSchema).forEach(function(key) {
    model[key] = null;
    Object.keys(self.rawSchema[key]).forEach(function(ak) {
      switch (ak) {
        case 'type':
          model[key] = new self.rawSchema[key][ak]().valueOf();
          break;
        case 'default':
          model[key] = self.rawSchema[key][ak];
          break;
      }
    })
  })

  this.model = model;
}

MySQLSchema.prototype.getJSON = function(callback) {
  var self = this;

  if (callback && (typeof callback == 'function')) {
    callback(self.model);
  } else {
    return self.model;
  }
}

MySQLSchema.prototype.set = function(key, value, callback) {
  var self = this;

  if (this.model.hasOwnProperty(key)) {
    self.model[key] = value;
    if (callback && (typeof callback == 'function')) {
      callback(null, self);
    } else {
      return self;
    }
  } else {
    if (callback && (typeof callback == 'function')) {
      callback(self.errors[self.table].error = "No such attribute: " + key, null);
    } else {
      throw 'No such attribute.';
    }
  }
}

MySQLSchema.prototype.get = function(key, callback) {
  var self = this;

  if (this.model.hasOwnProperty(key)) {
    if (callback && (typeof callback == 'function')) {
      callback(null, model[key]);
    } else {
      return model[key];
    }
  } else {
    if (callback && (typeof callback == 'function')) {
      callback(self.errors[self.table].error = "No such attribute: " + key, null);
    } else {
      throw 'No such attribute.';
    }
  }
}

MySQLSchema.prototype.new = function(callback) {
  var self = this;
  try {
    this.init();

    if (callback && (typeof callback == 'function')) {
      callback(null, self);
    } else {
      return self;
    }
  } catch (err) {
    if (callback && (typeof callback == 'function')) {
      callback(err, null);
    } else {
      throw err;
    }
  }
}

MySQLSchema.prototype.build = function(params, callback) {
  var self = this;
  try {
    Object.keys(params).forEach(function(k) {
      if (self.model.hasOwnProperty(k)) {
        self.model[k] = params[k];
      }
    })

    if (callback && (typeof callback == 'function')) {
      callback(null, self);
    } else {
      return self;
    }
  } catch (err) {
    if (callback && (typeof callback == 'function')) {
      callback(err, null);
    } else {
      throw "Error while building dbmodel.";
    }
  }
}

MySQLSchema.prototype.validate = function(mainCallback, callback) {
  var self = this;

  function validationCount (fn) {
    var count = 0;
    Object.keys(self.rawSchema).forEach(function(k) {
      if (self.rawSchema[k].hasOwnProperty('validate')) {
        count += 1;
      }
    });
    fn(count);
  }

  function doValidate (fn) {
    Object.keys(self.rawSchema).forEach(function(k) {
      if (self.rawSchema[k].hasOwnProperty('validate')) {
        for (var i=0; i < self.rawSchema[k].validate.length; i++) {
          if (typeof self.rawSchema[k].validate[i] == 'function') {
            // TODO: enable custom validation
          } else {
            try {
              var c = "self.check(self.model[k])." + self.rawSchema[k].validate[i];
              eval(c);
            } catch (e) {
              self.errors[self.table].error = 'Validation error.';
              self.errors[self.table].validationErrors[k] = e.message;
            }
          }
        };
      }
    })

    fn();
  }

  validationCount(function(count) {
    if (count > 0) {
      doValidate(function() {
        if (Object.keys(self.errors[self.table].validationErrors).length > 0) {
          mainCallback(self.errors, null);
        } else {
          callback();
        }
      })
    } else {
      callback();
    }
  })
}

MySQLSchema.prototype.save = function(callback) {
  var self = this;

  self.getJSON(function(o) {
    if (o.id > 0) {
      self.update(o, callback);
    } else {
      self.create(o, callback);
    }
  })
}

MySQLSchema.prototype.create = function(json, callback) {
  var self = this;

  self.build(json, function(err, dbmodel) {
    if (!err) {
      self.validate(callback, function() {
        self.beforeSave(function() {
          self.beforeCreate(function() {
            var attributes = []
              , values = []
              , query = "insert into " + self.table + " set ";

            for (k in self.model) {
              if (k != 'id') {
                attributes.push(k + " = ?");
                values.push(self.model[k]);
              }
            }

            query += attributes.join(', ');

            self.client.query(query, values, function(err, result) {
              if (!err) {
                self.client.query('select * from ' + self.table + " where id = ? limit 1", [result.insertId], function(err, r) {
                  self.model = r[0];
                  callback(err, self.getJSON());

                  self.afterSave(function() {
                    self.afterCreate(function() {

                    })
                  })
                })
              } else {
                callback(self.errors[self.table].error = err, null);
              }
            })
          })
        })
      })
    } else {
      callback(err, null);
    }
  })
}

MySQLSchema.prototype.update = function(json, callback) {
  var self = this;

  self.build(json, function(err, dbmodel) {
    if (!err) {
      self.validate(callback, function() {
        self.beforeSave(function() {
          self.beforeUpdate(function() {
            var attributes = []
              , values = []
              , query = "update " + self.table + " set ";

            for (k in json) {
              if (k != 'id') {
                attributes.push(k + " = ?");
                values.push(self.model[k]);
              }
            }

            query += attributes.join(", ");
            query += " where id = " + json.id;

            self.client.query(query, values, function(err, result) {
              if (!err) {
                callback(err, self.getJSON());

                self.afterSave(function() {
                  self.afterUpdate(function() {

                  })
                })
              } else {
                callback(self.errors[self.table].error = err, null);
              }
            })
          })
        })
      })
    } else {
      callback(err, null);
    }
  })
}

MySQLSchema.prototype.destroy = function(callback) {
  var self = this;

  this.beforeDestroy(function() {
    var query = "delete from " + self.table + " where id = ?";
    self.client.query(query, [self.model.id], function(err, result) {
      if (!err) {
        self.afterDestroy(function() {
          callback(err, result);
        })
      } else {
        callback(self.errors[self.table].error = err, null);
      }
    })
  })
}

MySQLSchema.prototype.query = function(query, callback) {
  var self = this;
  self.client.query(query, function(err, result) {
    callback(err, result);
  })
}

MySQLSchema.prototype.find = function(where, fields, options, callback) {
  var self = this;

  self.parseQueryWhere(where, function(err, rWhere) {
    if (!err) {
      self.parseQueryFields(fields, function(err, rFields) {
        if (!err) {
          self.parseQueryOptions(options, function(err, rOptions) {
            if (!err) {
              var query = 'select ' + rFields + " from " + self.table;

              if (rWhere.where) {
                query += " " + rWhere.where;
              }

              if (rOptions.length) {
                query += " " + rOptions;
              }

              self.client.query(query, rWhere.values, function(err, results) {
                callback(err, results);
              })
            } else {
              callback(err, null);
            }
          })
        } else {
          callback(err, null);
        }
      })
    } else {
      callback(err, null);
    }
  })
}

MySQLSchema.prototype.findOne = function(where, fields, callback) {
  var self = this;

  self.parseQueryWhere(where, function(err, rWhere) {
    if (!err) {
      self.parseQueryFields(fields, function(err, rFields) {
        if (!err) {
          var query = 'select ' + rFields + ' from ' + self.table;
          if (rWhere.where) {
            query += " " + rWhere.where;
          }
          query += " limit 1";

          self.client.query(query, rWhere.values, function(err, result) {
            callback(err, result[0]);
          })
        } else {
          callback(err, null);
        }
      })
    } else {
      callback(err, null);
    }
  })
}

MySQLSchema.prototype.count = function(where, options, callback) {
  var self = this;

  self.parseQueryWhere(where, function(err, rWhere) {
    if (!err) {
      self.parseQueryOptions(options, function(err, rOptions) {
        if (!err) {
          var query = 'select count(*) as count from ' + self.table;

          if (rWhere.where) {
            query += " " + rWhere.where;
          }

          if (rOptions.length) {
            query += " " + rOptions;
          }

          self.client.query(query, rWhere.values, function(err, result) {
            callback(err, result[0].count);
          })
        } else {
          callback(err, null);
        }
      })
    } else {
      callback(err, null);
    }
  })
}

MySQLSchema.prototype.parseQueryWhere = function (where, callback) {
  var self = this;

  try {
    var conditions = []
      , values = []
      , queryStrings = []
      , queryString = '';

    function processUnit (unit, fn) {
      switch (unit.condition) {
        case ('='):
          if (unit.value === null || unit.value == "NULL") {
            conditions.push(unit.field + " IS ?");
            values.push("NULL");
          } else {
            conditions.push(unit.field + " = ?")
            values.push(unit.value);
          }
          break;
        case ('in'):
          unit.value.map(function(v) {
            return self.client.escape(v);
          })

          conditions.push(unit.field + ' IN ("' + unit.value.join('", "') + '")')
          break;
      }

      if (fn && (typeof fn == 'function')) fn();
    }

    function processQuery (connector, fn) {
      where[connector].forEach(function(unit) {
        processUnit(unit);
      })

      queryStrings.push(conditions.join(" AND "));
      conditions = [];

      if (fn && (typeof fn == 'function')) fn();
    }

    switch (Object.keys(where).length) {
      case 0:
        // do nothing. to generate undefined queryString
        break;
      case 3:
        processUnit(where, function() {
          queryStrings.push(conditions[0]);
        })
        break;
      default:
        Object.keys(where).forEach(function(connector) {
          switch (connector) {
            case 'and':
              processQuery(connector);
              break;
            case 'or':
              processQuery(connector);
              break;
            // TODO: throw exception if connector is not in ['and', 'or']
          }
        })
        break;
    }

    if (queryStrings.length > 1) {
      queryString = queryStrings.join(" OR ");
    } else {
      queryString = queryStrings[0];
    }

    if (queryString) {
      queryString = "where " + queryString
    }

    callback(null, {
      where: queryString
      , values: values
    })

  } catch (err) {
    callback("Error while parsing query where.", null);
  }
}

MySQLSchema.prototype.parseQueryFields = function(fields, callback) {
  try {
    var results = '';

    if (fields.length) {
      results += fields.join(', ');
    } else {
      results += '*';
    }

    callback(null, results);
  } catch (err) {
    callback('Error while parsing query fields.', null);
  }
}

MySQLSchema.prototype.parseQueryOptions = function(options, callback) {
  try {
    var optionsArray = []
      , results = '';

    if (Object.keys(options).length) {
      Object.keys(options).forEach(function(key) {
        var option = options[key];

        switch (key) {
          case 'order':
            if ((option instanceof Array) && (option.length == 2) && (['asc', 'desc'].indexOf(option[1].toLowerCase()) >=0)) {
              optionsArray.push("order by " + option.join(' '));
            } else {
              throw 'order is not an instance of array.';
            }
            break;
          case 'group':
            optionsArray.push('group by ' + option);
            break;
          case 'limit':
            optionsArray.push('limit ' + option);
            break;
          case 'offset':
            optionsArray.push('offset ' + option);
            break;
        }
      })
    }

    results += optionsArray.join(' ');

    callback(null, results);
  } catch (err) {
    callback('Error while parsing query options.', null);
  }
}

MySQLSchema.prototype.beforeSave = function(callback) {
  callback();
}

MySQLSchema.prototype.afterSave = function(callback) {
  callback();
}

MySQLSchema.prototype.beforeCreate = function(callback) {
  callback();
}

MySQLSchema.prototype.afterCreate = function(callback) {
  callback();
}

MySQLSchema.prototype.beforeUpdate = function(callback) {
  callback();
}

MySQLSchema.prototype.afterUpdate = function(callback) {
  callback();
}

MySQLSchema.prototype.beforeDestroy = function(callback) {
  callback();
}

MySQLSchema.prototype.afterDestroy = function(callback) {
  callback();
}

exports = module.exports = MySQLSchema;<|endoftext|>


<commit_before>var app = angular.module("adApp", []);

app.controller("dashboardCtrl", function ($scope) {
    $scope.goToAdProduct = goToAdProduct;
    $scope.goToAdCheckout = goToAdCheckout;

    function goToAdProduct() {
        window.location = '../products.html';
    }

    function goToAdCheckout() {
        window.location = '../checkout.html';
    }
});

app.controller("checkoutCtrl", function ($scope, $http) {
    $scope.customers = ['Default', 'UNILEVER', 'APPLE', 'NIKE', 'FORD'];
    $scope.adTypes = [];
    $scope.addItem = addItem;
    $scope.changeCustomer = changeCustomer;
    $scope.totalAddedItems = [];
    var customerSelected;
    getAllProducts();
    $scope.totalCheckoutValue = 0;

    function getAllProducts() {
        $http.get('/products').
            success(function (data) {
                $scope.products = data;
                getAllAdTypes(data);
            }).error(function (data) {
                console.error("error pccured");
            })
    }

    function getAllAdTypes(products) {
        products.forEach(function (product) {
            $scope.adTypes.push(product.name);
        });
    }

    function changeCustomer() {
        if (customerSelected != undefined && customerSelected != $scope.customerName) {
            var confirmChange = confirm("You will lose your current customer info ! Click OK to proceed");
            if (confirmChange) {
                $scope.totalAddedItems = [];
            } else {
                $scope.customerName = customerSelected;
            }
        }
    }

    function addItem() {
        var overwritten;

        if (isNaN($scope.numberOfItems)) {
            alert("Count should be a valid number");
            return false;
        }

        overwritten = false;
        $scope.totalAddedItems.forEach(function (addedItem, index) {
            if ($scope.selectedProduct != undefined && $scope.selectedProduct != null &&
                addedItem.name === $scope.selectedProduct.name) {
                var confirmOverWright = confirm("Do you want to overwright the current entry under the same Ad type ? Click OK to proceed");
                if (confirmOverWright) {
                    $scope.totalAddedItems.splice(index, 1);
                }
            }
        });

        addToCheckoutList();
    }

    function addToCheckoutList() {
        var addedItem = {};
        customerSelected = $scope.customerName;
        addedItem.name = $scope.selectedProduct.name;
        addedItem.id = $scope.selectedProduct.id;
        addedItem.price = $scope.selectedProduct.price;
        addedItem.numberOfItems = $scope.numberOfItems;
        addedItem.discountApplied = false;
        addedItem.totalPrice = discountLogic(addedItem);
        $scope.totalAddedItems.push(addedItem);
        calculateTotalCheckoutValue();
    }

    function calculateTotalCheckoutValue() {
        $scope.totalCheckoutValue = 0;
        $scope.totalAddedItems.forEach(function (addedItem, index) {
            $scope.totalCheckoutValue = $scope.totalCheckoutValue + addedItem.totalPrice;
        });
    }

    function discountLogic(addedItem) {
        var totalPrice = addedItem.totalPrice;
        if (!addedItem.discountApplied) {
            if ($scope.customerName === "UNILEVER") {
                if (addedItem.id === 'classic') {
                    if (addedItem.numberOfItems >= 2) {
                        addedItem.numberOfItems = parseFloat(addedItem.numberOfItems);
                        totalPrice = (parseFloat($scope.numberOfItems) -1) * parseFloat(addedItem.price);
                        addedItem.discountApplied = true;
                    }
                }
            }
            else if ($scope.customerName === 'APPLE') {
                if (addedItem.id === 'standout') {
                   addedItem.price = 299.99;
                   totalPrice = parseFloat($scope.numberOfItems) * parseFloat(addedItem.price);
                   addedItem.discountApplied = true;
                }
            }
            else if ($scope.customerName === 'NIKE') {
                if (addedItem.id === 'premium') {
                    if (addedItem.numberOfItems >= 4) {
                        addedItem.numberOfItems = parseFloat(addedItem.numberOfItems);
                        addedItem.price = 379.99;
                        totalPrice = parseFloat($scope.numberOfItems) * parseFloat(addedItem.price);
                        addedItem.discountApplied = true;
                    }
                }
            }
            else if ($scope.customerName === 'FORD') {

            }
            else {

            }

            totalPrice = totalPrice === addedItem.totalPrice ? parseFloat($scope.numberOfItems) * parseFloat(addedItem.price) : totalPrice;
            return totalPrice;
        }
    }
});

app.controller("productCtrl", function ($scope, $http) {
    $scope.disableField = false;
    $scope.clearFields = clearFields;
    $scope.addProduct = addProduct;
    $scope.editProduct = editProduct;
    $scope.getAllProducts = getAllProducts;

    getAllProducts();

    function getAllProducts() {
        $http.get('/products').
            success(function (data) {
                $scope.products = data
            }).error(function (data) {
                console.error("error pccured");
            })
    }

    function addProduct() {
        var product = {};
        product.id = $scope.id;
        product.name = $scope.name;
        product.price = $scope.price;

        if (product.id == undefined || product.id == "") {
            alert("Product id is mandatory!");
            return false;
        }

        $http.post('/product/add', product).
            success(function (data) {
                console.log("product added successfully");
                getAllProducts();
            }).error(function (data) {
                alert("Product id is mandatory!");
                console.error("error in adding product");
            })
    }

    function editProduct(product) {
        $scope.id = product.id;
        $scope.name = product.name;
        $scope.price = product.price;
        $scope.disableField = true;
    }

    function clearFields() {
        $scope.disableField = false;
        $scope.id = "";
        $scope.name = "";
        $scope.price = "";
    }

});<commit_msg>Exxtend implementation for FORD customer<commit_after>var app = angular.module("adApp", []);

app.controller("dashboardCtrl", function ($scope) {
    $scope.goToAdProduct = goToAdProduct;
    $scope.goToAdCheckout = goToAdCheckout;

    function goToAdProduct() {
        window.location = '../products.html';
    }

    function goToAdCheckout() {
        window.location = '../checkout.html';
    }
});

app.controller("checkoutCtrl", function ($scope, $http) {
    $scope.customers = ['Default', 'UNILEVER', 'APPLE', 'NIKE', 'FORD'];
    $scope.adTypes = [];
    $scope.addItem = addItem;
    $scope.changeCustomer = changeCustomer;
    $scope.totalAddedItems = [];
    var customerSelected;
    getAllProducts();
    $scope.totalCheckoutValue = 0;

    function getAllProducts() {
        $http.get('/products').
            success(function (data) {
                $scope.products = data;
                getAllAdTypes(data);
            }).error(function (data) {
                console.error("error pccured");
            })
    }

    function getAllAdTypes(products) {
        products.forEach(function (product) {
            $scope.adTypes.push(product.name);
        });
    }

    function changeCustomer() {
        if (customerSelected != undefined && customerSelected != $scope.customerName) {
            var confirmChange = confirm("You will lose your current customer info ! Click OK to proceed");
            if (confirmChange) {
                $scope.totalAddedItems = [];
            } else {
                $scope.customerName = customerSelected;
            }
        }
    }

    function addItem() {
        var overwritten;

        if (isNaN($scope.numberOfItems)) {
            alert("Count should be a valid number");
            return false;
        }

        overwritten = false;
        $scope.totalAddedItems.forEach(function (addedItem, index) {
            if ($scope.selectedProduct != undefined && $scope.selectedProduct != null &&
                addedItem.name === $scope.selectedProduct.name) {
                var confirmOverWright = confirm("Do you want to overwright the current entry under the same Ad type ? Click OK to proceed");
                if (confirmOverWright) {
                    $scope.totalAddedItems.splice(index, 1);
                }
            }
        });

        addToCheckoutList();
    }

    function addToCheckoutList() {
        var addedItem = {};
        customerSelected = $scope.customerName;
        addedItem.name = $scope.selectedProduct.name;
        addedItem.id = $scope.selectedProduct.id;
        addedItem.price = $scope.selectedProduct.price;
        addedItem.numberOfItems = $scope.numberOfItems;
        addedItem.discountApplied = false;
        addedItem.totalPrice = discountLogic(addedItem);
        $scope.totalAddedItems.push(addedItem);
        calculateTotalCheckoutValue();
    }

    function calculateTotalCheckoutValue() {
        $scope.totalCheckoutValue = 0;
        $scope.totalAddedItems.forEach(function (addedItem, index) {
            $scope.totalCheckoutValue = $scope.totalCheckoutValue + addedItem.totalPrice;
        });
    }

    function discountLogic(addedItem) {
        var totalPrice = addedItem.totalPrice;
        if (!addedItem.discountApplied) {
            if ($scope.customerName === "UNILEVER") {
                if (addedItem.id === 'classic') {
                    if (addedItem.numberOfItems >= 2) {
                        addedItem.numberOfItems = parseFloat(addedItem.numberOfItems)+1;
                        totalPrice = parseFloat($scope.numberOfItems) * parseFloat(addedItem.price);
                        addedItem.discountApplied = true;
                    }
                }
            }
            else if ($scope.customerName === 'APPLE') {
                if (addedItem.id === 'standout') {
                   addedItem.price = 299.99;
                   totalPrice = parseFloat($scope.numberOfItems) * parseFloat(addedItem.price);
                   addedItem.discountApplied = true;
                }
            }
            else if ($scope.customerName === 'NIKE') {
                if (addedItem.id === 'premium') {
                    if (addedItem.numberOfItems >= 4) {
                        addedItem.numberOfItems = parseFloat(addedItem.numberOfItems);
                        addedItem.price = 379.99;
                        totalPrice = parseFloat($scope.numberOfItems) * parseFloat(addedItem.price);
                        addedItem.discountApplied = true;
                    }
                }
            }
            else if ($scope.customerName === 'FORD') {
                if (addedItem.id === 'classic') {
                    if (addedItem.numberOfItems >= 4) {
                        addedItem.numberOfItems = parseFloat(addedItem.numberOfItems)+1;
                        totalPrice = parseFloat($scope.numberOfItems) * parseFloat(addedItem.price);
                        addedItem.discountApplied = true;
                    }
                }
                if (addedItem.id === 'standout') {
                    addedItem.price = 309.99;
                    totalPrice = parseFloat($scope.numberOfItems) * parseFloat(addedItem.price);
                    addedItem.discountApplied = true;
                }
                if (addedItem.id === 'premium') {
                    if (addedItem.numberOfItems >= 3) {
                        addedItem.numberOfItems = parseFloat(addedItem.numberOfItems);
                        addedItem.price = 389.99;
                        totalPrice = parseFloat($scope.numberOfItems) * parseFloat(addedItem.price);
                        addedItem.discountApplied = true;
                    }
                }
            }

            totalPrice = totalPrice === addedItem.totalPrice ? parseFloat($scope.numberOfItems) * parseFloat(addedItem.price) : totalPrice;
            return totalPrice;
        }
    }
});

app.controller("productCtrl", function ($scope, $http) {
    $scope.disableField = false;
    $scope.clearFields = clearFields;
    $scope.addProduct = addProduct;
    $scope.editProduct = editProduct;
    $scope.getAllProducts = getAllProducts;

    getAllProducts();

    function getAllProducts() {
        $http.get('/products').
            success(function (data) {
                $scope.products = data
            }).error(function (data) {
                console.error("error pccured");
            })
    }

    function addProduct() {
        var product = {};
        product.id = $scope.id;
        product.name = $scope.name;
        product.price = $scope.price;

        if (product.id == undefined || product.id == "") {
            alert("Product id is mandatory!");
            return false;
        }

        $http.post('/product/add', product).
            success(function (data) {
                console.log("product added successfully");
                getAllProducts();
            }).error(function (data) {
                alert("Product id is mandatory!");
                console.error("error in adding product");
            })
    }

    function editProduct(product) {
        $scope.id = product.id;
        $scope.name = product.name;
        $scope.price = product.price;
        $scope.disableField = true;
    }

    function clearFields() {
        $scope.disableField = false;
        $scope.id = "";
        $scope.name = "";
        $scope.price = "";
    }

});<|endoftext|>


<commit_before>/** @babel */

import {CompositeDisposable, Disposable} from 'atom'

export const config = {
  trafficLightsPadding: {
    description: 'A padding width, in pixels, to accommodate the window traffic lights.',
    type: 'integer',
    minimum: 0,
    default: 80
  },
  automaticTrafficLightsPadding: {
    description: 'Use the width of your left dock as the width for the traffic lights padding.',
    type: 'boolean',
    default: false
  },
  automaticTrafficLightsPaddingOffset: {
    description: 'An offset adjustment width, in pixels, when using automatic padding.',
    type: 'integer',
    default: 0
  },
  enableLiberalWindowDragging: {
    'description': 'Liberally allow window dragging from any "empty" space.',
    type: 'boolean',
    default: true
  }
}

let dockWorkaroundElements = [null, null]
let leftDockVisible = false
let subs = null

export function activate (state) {
  if (!enabledForPlatform(process.platform)) return
  subs = new CompositeDisposable()

  document.body.classList.add('no-title-bar')
  subs.add(new Disposable(() => {
    setPadding(null)
    document.body.classList.remove('no-title-bar')
  }))

  // wait to finish package initialization until atom is fully loaded
  let mutationObserver = new MutationObserver((mutations) => {
    if (mutationObserver) mutationObserver.disconnect()
    mutationObserver = null
    finishInitialize()
  })
  mutationObserver.observe(atom.views.getView(atom.workspace), {attributes: true})
}

export function deactivate () {
  if (subs) subs.dispose()
}

/** Finishes package initialization such as setting up observers, events, styles, etc... */
function finishInitialize () {
  subs.add(
    atom.workspace.getLeftDock().observeVisible(visible => {
      leftDockVisible = visible
      updatePadding()
    }),
    atom.workspace.getRightDock().observeVisible(_ => updatePadding()),
    atom.config.observe('no-title-bar.trafficLightsPadding', () => updatePadding()),
    atom.config.observe('no-title-bar.automaticTrafficLightsPadding', () => updatePadding())
  )
  if (atom.config.get('no-title-bar.enableLiberalWindowDragging')) {
    subs.add(setupLiberalWindowDragging())
  }

  setupDockWorkaround('left')
  setupDockWorkaround('right')
}

/** Workaround window drag issues when there are scrolled panels in side docks.
  *
  * When a the content in a panel in a dock, like the tree-view, is scrolled
  * beyond the height of the window, webkit-app-region drag stops working.
  * To get around this we overlay a hidden element on top of the dock padding,
  * and set its webkit-app-region. For now, this seems to work ok.
  */
function setupDockWorkaround (side) {
  __guard__(document.querySelector([
    'atom-workspace',
    'atom-workspace-axis.horizontal'
    // Putting the element in the side panel container prevents scrolling in the
    // dock contents from interferring with dragging. However, scrolling in the
    // editor's tab-bar can also interfer. So we must put our workaround
    // elements up one level from those containers.
    // `atom-panel-container.${side}`
  ].join(' ')), hook => {
    const pos = side === 'left' ? 0 : 1
    dockWorkaroundElements[pos] = document.createElement('div')
    dockWorkaroundElements[pos].classList.add(`no-title-bar-${side}-dock-workaround`)
    dockWorkaroundElements[pos].style.webkitAppRegion = 'drag'
    dockWorkaroundElements[pos].style.position = 'absolute'
    dockWorkaroundElements[pos].style.backgroundColor = 'red'
    dockWorkaroundElements[pos].style.top = '0'
    if (side === 'left') dockWorkaroundElements[pos].style.left = '0'
    else dockWorkaroundElements[pos].style.right = '0'
    hook.appendChild(dockWorkaroundElements[pos])
    adjustDockWorkaroundElement(side)
    subs.add(new Disposable(() => dockWorkaroundElements[pos].remove()))
  })
}

/** Returns true iff your platform can support no-title-bar. */
export function enabledForPlatform (platform) {
  return document.body.classList.contains(`platform-${platform}`)
}

/** Creates and installs a stylesheet to enable global window dragging.
  *
  * @return A Disposable to easily remove the installed stylesheet.
  */
function setupLiberalWindowDragging () {
  let s = document.createElement('style')
  s.type = 'text/css'
  s.innerText = '.no-title-bar:not(.fullscreen) > atom-workspace { -webkit-app-region: drag; }'
  document.querySelector('head atom-styles').appendChild(s)
  return new Disposable(() => {
    s.parentNode.removeChild(s)
    s = null
  })
}

/** Sets the left padding width to accomodate window traffic lights. */
function setPadding (width) {
  adjustDockWorkaroundElement('left')
  adjustDockWorkaroundElement('right')
  const tabBarPaddingSelector = `.no-title-bar:not(.fullscreen):not(.hidden-title-bar)
    atom-panel-container.left + atom-workspace-axis.vertical
    .pane:nth-child(1)
    .tab-bar
  `
  const found = __guard__(document.querySelector(tabBarPaddingSelector), element => {
    if (width !== null) element.style.paddingLeft = width + 'px'
    else element.style.paddingLeft = ''
    return true
  })
  if (found !== undefined) return found
  return false
}

/** Correctly fit the dock workaround element into its dock container. */
function adjustDockWorkaroundElement (side) {
  const pos = side === 'left' ? 0 : 1
  if (dockWorkaroundElements[pos]) {
    __guard__(document.querySelector([
      '.no-title-bar:not(.fullscreen).custom-title-bar',
      '>',
      'atom-workspace',
      `atom-panel-container.${side}`
    ].join(' ')), panel => {
      dockWorkaroundElements[pos].style.height = window.getComputedStyle(panel).marginTop
      dockWorkaroundElements[pos].style.width = window.getComputedStyle(panel).width
    })
  }
}

/** Calls setPadding() with the correct value width value for Atom's current state. */
function updatePadding () {
  if (leftDockVisible) {
    return setPadding(0)
  }

  if (atom.config.get('no-title-bar.automaticTrafficLightsPadding')) {
    const width = __guard__(atom.workspace.getLeftDock(), x => x.state.size)
    if (width) {
      const offset = atom.config.get('no-title-bar.automaticTrafficLightsPaddingOffset')
      return setPadding(width + offset)
    }
  }

  return setPadding(atom.config.get('no-title-bar.trafficLightsPadding'))
}

function __guard__ (value, transform) {
  return (typeof value !== 'undefined' && value !== null)
    ? transform(value)
    : undefined
}
<commit_msg>Removes red debug color.<commit_after>/** @babel */

import {CompositeDisposable, Disposable} from 'atom'

export const config = {
  trafficLightsPadding: {
    description: 'A padding width, in pixels, to accommodate the window traffic lights.',
    type: 'integer',
    minimum: 0,
    default: 80
  },
  automaticTrafficLightsPadding: {
    description: 'Use the width of your left dock as the width for the traffic lights padding.',
    type: 'boolean',
    default: false
  },
  automaticTrafficLightsPaddingOffset: {
    description: 'An offset adjustment width, in pixels, when using automatic padding.',
    type: 'integer',
    default: 0
  },
  enableLiberalWindowDragging: {
    'description': 'Liberally allow window dragging from any "empty" space.',
    type: 'boolean',
    default: true
  }
}

let dockWorkaroundElements = [null, null]
let leftDockVisible = false
let subs = null

export function activate (state) {
  if (!enabledForPlatform(process.platform)) return
  subs = new CompositeDisposable()

  document.body.classList.add('no-title-bar')
  subs.add(new Disposable(() => {
    setPadding(null)
    document.body.classList.remove('no-title-bar')
  }))

  // wait to finish package initialization until atom is fully loaded
  let mutationObserver = new MutationObserver((mutations) => {
    if (mutationObserver) mutationObserver.disconnect()
    mutationObserver = null
    finishInitialize()
  })
  mutationObserver.observe(atom.views.getView(atom.workspace), {attributes: true})
}

export function deactivate () {
  if (subs) subs.dispose()
}

/** Finishes package initialization such as setting up observers, events, styles, etc... */
function finishInitialize () {
  subs.add(
    atom.workspace.getLeftDock().observeVisible(visible => {
      leftDockVisible = visible
      updatePadding()
    }),
    atom.workspace.getRightDock().observeVisible(_ => updatePadding()),
    atom.config.observe('no-title-bar.trafficLightsPadding', () => updatePadding()),
    atom.config.observe('no-title-bar.automaticTrafficLightsPadding', () => updatePadding())
  )
  if (atom.config.get('no-title-bar.enableLiberalWindowDragging')) {
    subs.add(setupLiberalWindowDragging())
  }

  setupDockWorkaround('left')
  setupDockWorkaround('right')
}

/** Workaround window drag issues when there are scrolled panels in side docks.
  *
  * When a the content in a panel in a dock, like the tree-view, is scrolled
  * beyond the height of the window, webkit-app-region drag stops working.
  * To get around this we overlay a hidden element on top of the dock padding,
  * and set its webkit-app-region. For now, this seems to work ok.
  */
function setupDockWorkaround (side) {
  __guard__(document.querySelector([
    'atom-workspace',
    'atom-workspace-axis.horizontal'
    // Putting the element in the side panel container prevents scrolling in the
    // dock contents from interferring with dragging. However, scrolling in the
    // editor's tab-bar can also interfer. So we must put our workaround
    // elements up one level from those containers.
    // `atom-panel-container.${side}`
  ].join(' ')), hook => {
    const pos = side === 'left' ? 0 : 1
    dockWorkaroundElements[pos] = document.createElement('div')
    dockWorkaroundElements[pos].classList.add(`no-title-bar-${side}-dock-workaround`)
    dockWorkaroundElements[pos].style.webkitAppRegion = 'drag'
    dockWorkaroundElements[pos].style.position = 'absolute'
    dockWorkaroundElements[pos].style.top = '0'
    if (side === 'left') dockWorkaroundElements[pos].style.left = '0'
    else dockWorkaroundElements[pos].style.right = '0'
    hook.appendChild(dockWorkaroundElements[pos])
    adjustDockWorkaroundElement(side)
    subs.add(new Disposable(() => dockWorkaroundElements[pos].remove()))
  })
}

/** Returns true iff your platform can support no-title-bar. */
export function enabledForPlatform (platform) {
  return document.body.classList.contains(`platform-${platform}`)
}

/** Creates and installs a stylesheet to enable global window dragging.
  *
  * @return A Disposable to easily remove the installed stylesheet.
  */
function setupLiberalWindowDragging () {
  let s = document.createElement('style')
  s.type = 'text/css'
  s.innerText = '.no-title-bar:not(.fullscreen) > atom-workspace { -webkit-app-region: drag; }'
  document.querySelector('head atom-styles').appendChild(s)
  return new Disposable(() => {
    s.parentNode.removeChild(s)
    s = null
  })
}

/** Sets the left padding width to accomodate window traffic lights. */
function setPadding (width) {
  adjustDockWorkaroundElement('left')
  adjustDockWorkaroundElement('right')
  const tabBarPaddingSelector = `.no-title-bar:not(.fullscreen):not(.hidden-title-bar)
    atom-panel-container.left + atom-workspace-axis.vertical
    .pane:nth-child(1)
    .tab-bar
  `
  const found = __guard__(document.querySelector(tabBarPaddingSelector), element => {
    if (width !== null) element.style.paddingLeft = width + 'px'
    else element.style.paddingLeft = ''
    return true
  })
  if (found !== undefined) return found
  return false
}

/** Correctly fit the dock workaround element into its dock container. */
function adjustDockWorkaroundElement (side) {
  const pos = side === 'left' ? 0 : 1
  if (dockWorkaroundElements[pos]) {
    __guard__(document.querySelector([
      '.no-title-bar:not(.fullscreen).custom-title-bar',
      '>',
      'atom-workspace',
      `atom-panel-container.${side}`
    ].join(' ')), panel => {
      dockWorkaroundElements[pos].style.height = window.getComputedStyle(panel).marginTop
      dockWorkaroundElements[pos].style.width = window.getComputedStyle(panel).width
    })
  }
}

/** Calls setPadding() with the correct value width value for Atom's current state. */
function updatePadding () {
  if (leftDockVisible) {
    return setPadding(0)
  }

  if (atom.config.get('no-title-bar.automaticTrafficLightsPadding')) {
    const width = __guard__(atom.workspace.getLeftDock(), x => x.state.size)
    if (width) {
      const offset = atom.config.get('no-title-bar.automaticTrafficLightsPaddingOffset')
      return setPadding(width + offset)
    }
  }

  return setPadding(atom.config.get('no-title-bar.trafficLightsPadding'))
}

function __guard__ (value, transform) {
  return (typeof value !== 'undefined' && value !== null)
    ? transform(value)
    : undefined
}
<|endoftext|>


<commit_before>App = Ember.Application.create();

App.Router.map(function() {
    this.resource('home', {
        path: '/'
    });
    this.resource('about');
    this.resource('contact');
});

App.HomeRoute = Ember.Route.extend({
   beforeModel: function() {
     return $.ajax({
        url: '/'
     })
     .then(function(response) {
        Ember.TEMPLATES.home = Ember.Handlebars.compile(response);
    });
   }
});

App.AboutRoute = Ember.Route.extend({
   beforeModel: function() {
     return $.ajax({
        url: '/about'
     })
     .then(function(response) {
        Ember.TEMPLATES.about = Ember.Handlebars.compile(response);
    });
   }
});

App.ContactRoute = Ember.Route.extend({
   beforeModel: function() {
     return $.ajax({
        url: '/contact'
     })
     .then(function(response) {
        Ember.TEMPLATES.contact = Ember.Handlebars.compile(response);
    });
   }
});

if (window.history && window.history.pushState) {
    App.Router.reopen({
      location: 'history'
    });
}

App.LinkLiComponent = Ember.Component.extend({
  tagName: 'li',
  classNameBindings: ['active'],
  active: function() {
    return this.get('childViews').anyBy('active');
  }.property('childViews.@each.active')
});

Em.Handlebars.helper('link-li', App.LinkLiComponent);<commit_msg>check if template already compiled<commit_after>App = Ember.Application.create();

App.Router.map(function() {
    this.resource('home', {
        path: '/'
    });
    this.resource('about');
    this.resource('contact');
});

App.HomeRoute = Ember.Route.extend({
   beforeModel: function() {
     if (!Ember.TEMPLATES.home) {
        return $.ajax({
           url: '/'
        })
        .then(function(response) {
           Ember.TEMPLATES.home = Ember.Handlebars.compile(response);
       });
     }
//     return 0;
   }
});

App.AboutRoute = Ember.Route.extend({
   beforeModel: function() {
     if (!Ember.TEMPLATES.about) {
        return $.ajax({
           url: '/about'
        })
        .then(function(response) {
           Ember.TEMPLATES.about = Ember.Handlebars.compile(response);
       });
     }
   }
});

App.ContactRoute = Ember.Route.extend({
   beforeModel: function() {
     if (!Ember.TEMPLATES.contact) {
        return $.ajax({
           url: '/contact'
        })
        .then(function(response) {
           Ember.TEMPLATES.contact = Ember.Handlebars.compile(response);
       });
     }
   }
});

if (window.history && window.history.pushState) {
    App.Router.reopen({
      location: 'history'
    });
}

App.LinkLiComponent = Ember.Component.extend({
  tagName: 'li',
  classNameBindings: ['active'],
  active: function() {
    return this.get('childViews').anyBy('active');
  }.property('childViews.@each.active')
});

Em.Handlebars.helper('link-li', App.LinkLiComponent);<|endoftext|>


<commit_before>'use strict';

var request = require('request');
var fs = require('fs');
var zlib = require('zlib');
var Untar = require('tar-async/untar');
var async = require('async');

var tgzPlatforms = [ 'linux', 'darwin', 'sunos'];

/**
 * Method to download the node binary
 * Currently this only wraps the downloadTgz, but it might be extended for other archs
 *
 * @memberof NodeFetcher
 * @instance
 * @function download
 * @param {String} version Version you want to download (latest | system | 0.10.1 ...)
 * @param {String} platform Platform you want to download (linux|darwin|sunos)
 * @param {String} arch Architecture (x84 | x64)
 * @param {String} filename Filename where you'd like to save the node binary
 * @param {Function} callback Callback with (err) if it failed
 */
var download = function(version, platform, arch, filename, callback) {

  var downloadVersion = version;

  if (version === 'system') {
    return copyNode(filename,callback);
  } else {
    async.series([
      function(callback) {
        if (version === 'latest') {
          latestVersion(function(err, version) {
            downloadVersion = version;
            return callback(err, version);
          });
        } else {
          return callback(null);
        }
      },
      function(callback) {
        if ( tgzPlatforms.indexOf(platform) >= 0) {
          return downloadTgz(downloadVersion, platform, arch, filename, callback);
        } else {
          return callback(new Error('unsupported platform ' + platform));
        }
      }
    ],function(err, results) {
      callback(err);
    });

  }
};

var downloadPrefix = 'http://nodejs.org/dist/';

/**
 * Method to copy the system node
 * @memberof NodeFetcher
 * @function copyNode
 * @instance
 * @param {String} filename Destination filename to copy the system node to
 * @param {Function} callback Function to call(err) when done or error
 */
var copyNode = function(filename,callback) {
  var fs = require('fs');
  var systemNode = fs.createReadStream(process.execPath);
  var destNode = fs.createWriteStream(filename);

  systemNode.on('error',function(err) {
    callback(err);
  });

  destNode.on('error', function(err) {
    callback(err);
  });

  destNode.on('finish', function() {
    callback(null);
  });

  systemNode.pipe(destNode);
};

/**
 * Method to generate the full downloadURL
 *
 * @memberof NodeFetcher
 * @function downloadUrl
 * @instance
 * @param {String} version Version you want to download (system | 0.10.1 ...)
 * @param {String} platform Platform you want to download (linux|darwin|sunos)
 * @param {String} arch Architecture (x84 | x64)
 * @returns {String} the full download URL
 */
var downloadUrl = function(version, platform, arch) {
  var url;

  if (version === 'system') {
    url = 'file://'+ encodeURIComponent(process.execPath);
  } else {
    if ( tgzPlatforms.indexOf(platform) >= 0) {
        url =  util.format(downloadPrefix + 'v%s/node-v%s-%s-%s.tar.gz', version, version, platform , arch );
    }
  }

  return url;
};

/**
 * Method to download the node binary
 * Currently this only wraps the downloadTgz, but it might be extended for other archs
 *
 * @memberof NodeFetcher
 * @instance
 * @function downloadTgz
 * @param {String} version Version you want to download (latest | system | 0.10.1 ...)
 * @param {String} platform Platform you want to download (linux|darwin|sunos)
 * @param {String} arch Architecture (x84 | x64)
 * @param {String} filename Filename where you'd like to save the node binary
 * @param {Function} callback Callback with (err) if it failed
 * @private
 */
var downloadTgz = function(version, platform, arch, filename, callback) {
  var self = this;
  var url = downloadUrl(version, platform, arch);

  // Prepare the download stream
  var download = request(url,function (error, response, body) {
    if (error) {
      return callback(error);
    }
  });

  // Prepare the filewrite stream
  var fileWriter = fs.createWriteStream(filename);
  fileWriter.on('error', function(error) {
    if (error) {
      return callback(error);
    }
  });

  // Prepare the gunzip stream
  var gunzip = zlib.createGunzip();
  gunzip.on('error', function(error) {
    return callback(error);
  });

  // Prepare the untar stream
  var untar = new Untar(function (err, header, fileStream) {

    if (header) {
      if (header.filename) {
        if (endsWith(header.filename,'/bin/node')) {
          //console.log(header.filename);
          fileStream.on('end', function() {
            return callback(null);
          });
          fileStream.pipe(fileWriter);
        }
      }
    }
  });

  // Start the download process
  download.pipe(gunzip).pipe(untar);
};

/**
 * Method to retrieve the latest downloadable version
 *
 * @memberof NodeFetcher
 * @instance
 * @function latestVersion
 * @param {Function} callback Callback with (err, version) if it failed
 * @private
 */
var latestVersion = function(callback) {
  var url = 'http://nodejs.org/dist/latest';

  var download = request(url,function (error, response, body) {
    if (error) {
      return callback(error);
    } else {
      var match = body.match(/>node-v([^.]*).([^.]*).([^.]*)-darwin-x64.tar.gz/);
      var version = [ match[1].toString() , match[2] , match[3] ].join('.') ;
      return callback(null, version);
    }
  });
};

var util = require('util');

var endsWith = function endsWith(str, suffix) {
  return str.indexOf(suffix, str.length - suffix.length) !== -1;
};

module.exports = {
  'download': download,
  'downloadUrl': downloadUrl,
  'latestVersion' : latestVersion
};
<commit_msg>listen to writeStream 'end' event instead of 'finish'<commit_after>'use strict';

var request = require('request');
var fs = require('fs');
var zlib = require('zlib');
var Untar = require('tar-async/untar');
var async = require('async');

var tgzPlatforms = [ 'linux', 'darwin', 'sunos'];

/**
 * Method to download the node binary
 * Currently this only wraps the downloadTgz, but it might be extended for other archs
 *
 * @memberof NodeFetcher
 * @instance
 * @function download
 * @param {String} version Version you want to download (latest | system | 0.10.1 ...)
 * @param {String} platform Platform you want to download (linux|darwin|sunos)
 * @param {String} arch Architecture (x84 | x64)
 * @param {String} filename Filename where you'd like to save the node binary
 * @param {Function} callback Callback with (err) if it failed
 */
var download = function(version, platform, arch, filename, callback) {

  var downloadVersion = version;

  if (version === 'system') {
    return copyNode(filename,callback);
  } else {
    async.series([
      function(callback) {
        if (version === 'latest') {
          latestVersion(function(err, version) {
            downloadVersion = version;
            return callback(err, version);
          });
        } else {
          return callback(null);
        }
      },
      function(callback) {
        if ( tgzPlatforms.indexOf(platform) >= 0) {
          return downloadTgz(downloadVersion, platform, arch, filename, callback);
        } else {
          return callback(new Error('unsupported platform ' + platform));
        }
      }
    ],function(err, results) {
      callback(err);
    });

  }
};

var downloadPrefix = 'http://nodejs.org/dist/';

/**
 * Method to copy the system node
 * @memberof NodeFetcher
 * @function copyNode
 * @instance
 * @param {String} filename Destination filename to copy the system node to
 * @param {Function} callback Function to call(err) when done or error
 */
var copyNode = function(filename,callback) {
  var fs = require('fs');
  var systemNode = fs.createReadStream(process.execPath);
  var destNode = fs.createWriteStream(filename);

  systemNode.on('error',function(err) {
    callback(err);
  });

  destNode.on('error', function(err) {
    callback(err);
  });

  destNode.on('end', function() {
    callback(null);
  });

  systemNode.pipe(destNode);
};

/**
 * Method to generate the full downloadURL
 *
 * @memberof NodeFetcher
 * @function downloadUrl
 * @instance
 * @param {String} version Version you want to download (system | 0.10.1 ...)
 * @param {String} platform Platform you want to download (linux|darwin|sunos)
 * @param {String} arch Architecture (x84 | x64)
 * @returns {String} the full download URL
 */
var downloadUrl = function(version, platform, arch) {
  var url;

  if (version === 'system') {
    url = 'file://'+ encodeURIComponent(process.execPath);
  } else {
    if ( tgzPlatforms.indexOf(platform) >= 0) {
        url =  util.format(downloadPrefix + 'v%s/node-v%s-%s-%s.tar.gz', version, version, platform , arch );
    }
  }

  return url;
};

/**
 * Method to download the node binary
 * Currently this only wraps the downloadTgz, but it might be extended for other archs
 *
 * @memberof NodeFetcher
 * @instance
 * @function downloadTgz
 * @param {String} version Version you want to download (latest | system | 0.10.1 ...)
 * @param {String} platform Platform you want to download (linux|darwin|sunos)
 * @param {String} arch Architecture (x84 | x64)
 * @param {String} filename Filename where you'd like to save the node binary
 * @param {Function} callback Callback with (err) if it failed
 * @private
 */
var downloadTgz = function(version, platform, arch, filename, callback) {
  var self = this;
  var url = downloadUrl(version, platform, arch);

  // Prepare the download stream
  var download = request(url,function (error, response, body) {
    if (error) {
      return callback(error);
    }
  });

  // Prepare the filewrite stream
  var fileWriter = fs.createWriteStream(filename);
  fileWriter.on('error', function(error) {
    if (error) {
      return callback(error);
    }
  });

  // Prepare the gunzip stream
  var gunzip = zlib.createGunzip();
  gunzip.on('error', function(error) {
    return callback(error);
  });

  // Prepare the untar stream
  var untar = new Untar(function (err, header, fileStream) {

    if (header) {
      if (header.filename) {
        if (endsWith(header.filename,'/bin/node')) {
          //console.log(header.filename);
          fileStream.on('end', function() {
            return callback(null);
          });
          fileStream.pipe(fileWriter);
        }
      }
    }
  });

  // Start the download process
  download.pipe(gunzip).pipe(untar);
};

/**
 * Method to retrieve the latest downloadable version
 *
 * @memberof NodeFetcher
 * @instance
 * @function latestVersion
 * @param {Function} callback Callback with (err, version) if it failed
 * @private
 */
var latestVersion = function(callback) {
  var url = 'http://nodejs.org/dist/latest';

  var download = request(url,function (error, response, body) {
    if (error) {
      return callback(error);
    } else {
      var match = body.match(/>node-v([^.]*).([^.]*).([^.]*)-darwin-x64.tar.gz/);
      var version = [ match[1].toString() , match[2] , match[3] ].join('.') ;
      return callback(null, version);
    }
  });
};

var util = require('util');

var endsWith = function endsWith(str, suffix) {
  return str.indexOf(suffix, str.length - suffix.length) !== -1;
};

module.exports = {
  'download': download,
  'downloadUrl': downloadUrl,
  'latestVersion' : latestVersion
};
<|endoftext|>


<commit_before>
/**
 * Module exports.
 */

module.exports = exports;

/**
 * Module dependencies.
 */

var fs = require('fs')
  , path = require('path')
  , nopt = require('nopt')
  , log = require('npmlog')
  , child_process = require('child_process')
  , EE = require('events').EventEmitter
  , inherits = require('util').inherits
  , commands = [
      'clean',
      'install',
      'reinstall',
      'build',
      'rebuild',
      'package',
      'testpackage',
      'publish',
      'unpublish',
      'info'
    ]
  , aliases = {
    }

// differentiate node-pre-gyp's logs from npm's
log.heading = 'node-pre-gyp'

exports.find = require('./pre-binding').find;

function Run() {
  var self = this

  this.commands = {}

  commands.forEach(function (command) {
    self.commands[command] = function (argv, callback) {
      log.verbose('command', command, argv)
      return require('./' + command)(self, argv, callback)
    }
  })
}
inherits(Run, EE)
exports.Run = Run
var proto = Run.prototype

/**
 * Export the contents of the package.json.
 */

proto.package = require('../package')

/**
 * nopt configuration definitions
 */

proto.configDefs = {
    help: Boolean     // everywhere
  , arch: String      // 'configure'
  , debug: Boolean    // 'build'
  , directory: String // bin
  , proxy: String     // 'install'
  , loglevel: String  // everywhere
}

/**
 * nopt shorthands
 */

proto.shorthands = {
    release: '--no-debug'
  , C: '--directory'
  , debug: '--debug'
  , j: '--jobs'
  , silly: '--loglevel=silly'
  , verbose: '--loglevel=verbose'
}

/**
 * expose the command aliases for the bin file to use.
 */

proto.aliases = aliases

/**
 * Parses the given argv array and sets the 'opts',
 * 'argv' and 'command' properties.
 */

proto.parseArgv = function parseOpts (argv) {
  this.opts = nopt(this.configDefs, this.shorthands, argv)
  this.argv = this.opts.argv.remain.slice()

  var commands = this.todo = []

  // create a copy of the argv array with aliases mapped
  argv = this.argv.map(function (arg) {
    // is this an alias?
    if (arg in this.aliases) {
      arg = this.aliases[arg]
    }
    return arg
  }, this)

  // process the mapped args into "command" objects ("name" and "args" props)
  argv.slice().forEach(function (arg) {
    if (arg in this.commands) {
      var args = argv.splice(0, argv.indexOf(arg))
      argv.shift()
      if (commands.length > 0) {
        commands[commands.length - 1].args = args
      }
      commands.push({ name: arg, args: [] })
    }
  }, this)
  if (commands.length > 0) {
    commands[commands.length - 1].args = argv.splice(0)
  }

  // support for inheriting config env variables from npm
  var npm_config_prefix = 'npm_config_'
  Object.keys(process.env).forEach(function (name) {
    if (name.indexOf(npm_config_prefix) !== 0) return
    var val = process.env[name]
    if (name === npm_config_prefix + 'loglevel') {
      log.level = val
    } else {
      // add the user-defined options to the config
      name = name.substring(npm_config_prefix.length)
      // avoid npm argv clobber already present args
      // which avoids problem of 'npm test' calling
      // script that runs unique npm install commands
      if (name === 'argv') {
         if (this.opts.argv &&
             this.opts.argv.remain &&
             this.opts.argv.remain.length) {
            // do nothing
         } else {
            this.opts[name] = val
         }
      } else {
        this.opts[name] = val
      }
    }
  }, this)

  if (this.opts.loglevel) {
    log.level = this.opts.loglevel
  }
  log.resume()
}

/**
 * Returns the usage instructions for node-pre-gyp.
 */

proto.usage = function usage () {
  var str = [
      ''
    , '  Usage: node-pre-gyp <command> [options]'
    , ''
    , '  where <command> is one of:'
    , commands.map(function (c) {
        return '    - ' + c + ' - ' + require('./' + c).usage
      }).join('\n')
    , ''
    , '  for specific command usage and options try:'
    , '    $ node-pre-gyp <command> --help'
    , ''
    , 'node-pre-gyp@' + this.version + '  ' + path.resolve(__dirname, '..')
    , 'node@' + process.versions.node
  ].join('\n')
  return str
}

/**
 * Version number getter.
 */

Object.defineProperty(proto, 'version', {
    get: function () {
      return this.package.version
    }
  , enumerable: true
})

<commit_msg>match https://github.com/TooTallNate/node-gyp/commit/e82e4387bed35cc59d61a6433dc23d9caf0bdc01<commit_after>
/**
 * Module exports.
 */

module.exports = exports;

/**
 * Module dependencies.
 */

var fs = require('fs')
  , path = require('path')
  , nopt = require('nopt')
  , log = require('npmlog')
  , child_process = require('child_process')
  , EE = require('events').EventEmitter
  , inherits = require('util').inherits
  , commands = [
      'clean',
      'install',
      'reinstall',
      'build',
      'rebuild',
      'package',
      'testpackage',
      'publish',
      'unpublish',
      'info'
    ]
  , aliases = {
    }

// differentiate node-pre-gyp's logs from npm's
log.heading = 'node-pre-gyp'

exports.find = require('./pre-binding').find;

function Run() {
  var self = this

  this.commands = {}

  commands.forEach(function (command) {
    self.commands[command] = function (argv, callback) {
      log.verbose('command', command, argv)
      return require('./' + command)(self, argv, callback)
    }
  })
}
inherits(Run, EE)
exports.Run = Run
var proto = Run.prototype

/**
 * Export the contents of the package.json.
 */

proto.package = require('../package')

/**
 * nopt configuration definitions
 */

proto.configDefs = {
    help: Boolean     // everywhere
  , arch: String      // 'configure'
  , debug: Boolean    // 'build'
  , directory: String // bin
  , proxy: String     // 'install'
  , loglevel: String  // everywhere
}

/**
 * nopt shorthands
 */

proto.shorthands = {
    release: '--no-debug'
  , C: '--directory'
  , debug: '--debug'
  , j: '--jobs'
  , silly: '--loglevel=silly'
  , verbose: '--loglevel=verbose'
}

/**
 * expose the command aliases for the bin file to use.
 */

proto.aliases = aliases

/**
 * Parses the given argv array and sets the 'opts',
 * 'argv' and 'command' properties.
 */

proto.parseArgv = function parseOpts (argv) {
  this.opts = nopt(this.configDefs, this.shorthands, argv)
  this.argv = this.opts.argv.remain.slice()

  var commands = this.todo = []

  // create a copy of the argv array with aliases mapped
  argv = this.argv.map(function (arg) {
    // is this an alias?
    if (arg in this.aliases) {
      arg = this.aliases[arg]
    }
    return arg
  }, this)

  // process the mapped args into "command" objects ("name" and "args" props)
  argv.slice().forEach(function (arg) {
    if (arg in this.commands) {
      var args = argv.splice(0, argv.indexOf(arg))
      argv.shift()
      if (commands.length > 0) {
        commands[commands.length - 1].args = args
      }
      commands.push({ name: arg, args: [] })
    }
  }, this)
  if (commands.length > 0) {
    commands[commands.length - 1].args = argv.splice(0)
  }

  // support for inheriting config env variables from npm
  var npm_config_prefix = 'npm_config_'
  Object.keys(process.env).forEach(function (name) {
    if (name.indexOf(npm_config_prefix) !== 0) return
    var val = process.env[name]
    if (name === npm_config_prefix + 'loglevel') {
      log.level = val
    } else {
      // add the user-defined options to the config
      name = name.substring(npm_config_prefix.length)
      // avoid npm argv clobber already present args
      // which avoids problem of 'npm test' calling
      // script that runs unique npm install commands
      if (name === 'argv') {
         if (this.opts.argv &&
             this.opts.argv.remain &&
             this.opts.argv.remain.length) {
            // do nothing
         } else {
            this.opts[name] = val
         }
      } else {
        this.opts[name] = val
      }
    }
  }, this)

  if (this.opts.loglevel) {
    log.level = this.opts.loglevel
  }
  log.resume()
}

/**
 * Returns the usage instructions for node-pre-gyp.
 */

proto.usage = function usage () {
  var str = [
      ''
    , '  Usage: node-pre-gyp <command> [options]'
    , ''
    , '  where <command> is one of:'
    , commands.map(function (c) {
        return '    - ' + c + ' - ' + require('./' + c).usage
      }).join('\n')
    , ''
    , 'node-pre-gyp@' + this.version + '  ' + path.resolve(__dirname, '..')
    , 'node@' + process.versions.node
  ].join('\n')
  return str
}

/**
 * Version number getter.
 */

Object.defineProperty(proto, 'version', {
    get: function () {
      return this.package.version
    }
  , enumerable: true
})

<|endoftext|>


<commit_before>var Q = require('q'),
    INHERIT = require('inherit'),
    UTIL = require('../util'),
    PATH = require('path'),
    createLevel = require('../index').createLevel,

    MagicNode = require('./magic').MagicNode,
    FileNode = require('./file').FileNode,
    BemCreateNode = require('./create').BemCreateNode,
    BemBuildNode = require('./build').BemBuildNode,
    registry = require('../make').NodesRegistry,
    LOGGER = require('../logger');

var BundleNode = exports.BundleNode = INHERIT(MagicNode, {

    __constructor: function(level, bundleNameOrItem, subBundleName) {
        this.level = typeof level == 'string'? createLevel(level) : level;

        this.item = (typeof bundleNameOrItem === 'string')? createItem(bundleNameOrItem, subBundleName) : bundleNameOrItem;

        this.__base(PATH.dirname(this.getNodePrefix()));
    },

    make: function(ctx) {

        return ctx.arch.withLock(this.alterArch(ctx), this);

    },

    alterArch: function(ctx) {

        return function() {

            // create real node for page
            var arch = ctx.arch,
                bundleNode;

            if (arch.hasNode(this.path)) {
                bundleNode = arch.getNode(this.path);
            } else {
                bundleNode = new FileNode(this.path);
                arch.setNode(bundleNode, arch.getParents(this));
            }

            // generate targets for page files
            var techTargets = {};
            this.getTechDeps().map(function(tech) {
                var techNode = this.createNode(ctx, tech, bundleNode, this);
                techTargets[tech] = techNode.getId();

                this.createOptimizerNode(ctx, bundleNode, techNode, tech);
            }, this);

            // link targets for page files with each other
            // FIXME: rewrite, move linking to create*() methods
            return this.linkNodes(ctx, techTargets);
        };

    },

    lastModified: function() {
        return Q.resolve(0);
    },

    createNode: function(ctx, tech, bundleNode, magicNode) {
        return (this['create-' + tech + '-node'] ||
            this.createDefaultNode).call(this, ctx, tech, bundleNode, magicNode);
    },

    createOptimizerNode: function(ctx, bundleNode, sourceNode, tech) {
        return (this['create-' + tech + '-optimizer-node'] ||
            this.createDefaultOptimizerNode).call(this, ctx, sourceNode, bundleNode, tech);
    },

    linkNodes: function(ctx, techTargets) {
        return Q.all(Object.keys(techTargets).map(function(target) {
            var targetNode = ctx.arch.nodes[techTargets[target]];
            if (targetNode.getCreateDependencies)
                return Q.when(targetNode.getCreateDependencies(ctx), function(deps) {
                    for(var d = 0; d < deps.length; d++) ctx.arch.link(
                        deps[d],
                        techTargets[target]);
                });
        }));
    },

    getPath: function(tech) {
        // TODO: use Tech object to construct paths
        return this.getNodePrefix() + '.' + tech;
    },

    getTechDeps: function() {
        return [
            'bemjson.js',
            'bemdecl.js',
            'deps.js',
            'html',
            'bemhtml.js',
            'css',
            'ie.css',
            'js'
        ];
    },

    cleanup: function(ctx) {
        var arch = ctx.arch;
        if (!arch.hasNode(this.path)) return;
        arch.removeTree(this.path);
    },

    getNodePrefix: function() {
        if (!this._nodePrefix) {
            this._nodePrefix = this.__self._createId(this.level, this.item);
        }
        return this._nodePrefix;
    },

    getLevels: function(prefix) {
        return [].concat(
            this.level.getConfig().bundleBuildLevels,
            [ PATH.join(PATH.dirname(prefix), 'blocks') ]);
    },

    /**
     * Create a bem build node, add it to the arch,
     * then creates a meta node and link it to the build node.
     *
     * @param ctx
     * @param techName
     * @param techPath
     * @param declTech
     * @param {String} bundleNode
     * @param {String} magicNode
     * @param {Boolean} [forked]
     * @return {String} ID of the node that has been created
     */
    setBemBuildNode: function(ctx, techName, techPath, declTech, bundleNode, magicNode, forked) {
        var arch = ctx.arch,
            buildNode = new BemBuildNode(
                this.getLevels(PATH.resolve(ctx.root, this.getNodePrefix())),
                this.getPath(declTech),
                techPath,
                techName,
                this.getNodePrefix(),
                forked);

        arch.setNode(buildNode);

        bundleNode && arch.addParents(buildNode, bundleNode);
        magicNode && arch.addChildren(buildNode, magicNode);

        arch.setNode(buildNode.getMetaNode(),
            buildNode,
            UTIL.getNodeTechPath(this.level, this.item, declTech));

        return buildNode;
    },

    createDefaultNode: function(ctx, tech, bundleNode, magicNode) {
        var arch = ctx.arch,
            node = new FileNode(this.getPath(tech));

        arch.setNode(node);

        bundleNode && arch.link(node, bundleNode);
        magicNode && arch.link(magicNode, node);

        return node;
    },

    'create-bemdecl.js-node': function(ctx, tech, bundleNode, magicNode) {
        var arch = ctx.arch,
            node = new BemCreateNode(this.level, this.item, tech, tech);

        arch.setNode(node);

        bundleNode && arch.link(node, bundleNode);
        magicNode && arch.link(magicNode, node);

        return node;
    },

    'create-deps.js-node': function(ctx, tech, bundleNode, magicNode) {
        return this.setBemBuildNode(ctx, tech, tech, 'bemdecl.js', bundleNode, magicNode);
    },

    'create-html-node': function(ctx, tech, bundleNode, magicNode) {
        // TODO: move node to bem-bl/blocks-common/i-bem/bem
        var arch = ctx.arch,
            node = new BemCreateNode(
                this.level,
                this.item,
                require.resolve(PATH.resolve(this.level.dir, '../bem-bl/blocks-common/i-bem/bem/techs/html')),
                tech,
                true);

        arch.setNode(node);

        bundleNode && arch.link(node, bundleNode);
        magicNode && arch.link(magicNode, node);

        return node;

    },

    'create-bemhtml.js-node': function(ctx, tech, bundleNode, magicNode) {
        // TODO: move node to bem-bl/blocks-common/i-bem/bem
        var techBemHtml = require.resolve(PATH.resolve(this.level.dir, '../bem-bl/blocks-common/i-bem/bem/techs/bemhtml.js'));
        return this.setBemBuildNode(ctx, tech, techBemHtml, 'deps.js', bundleNode, magicNode, true);
    },

    'create-js-node': function(ctx, tech, bundleNode, magicNode) {
        return this.setBemBuildNode(ctx, tech, tech, 'deps.js', bundleNode, magicNode);
    },

    'create-css-node': function(ctx, tech, bundleNode, magicNode) {
        return this['create-js-node'].apply(this, arguments);
    },

    'create-ie.css-node': function(ctx, tech, bundleNode, magicNode) {
        return this['create-css-node'].apply(this, arguments);
    },

    createDefaultOptimizerNode: function(ctx, sourceNode, bundleNode, tech) {},

    'create-js-optimizer-node': function(ctx, sourceNode, bundleNode) {
        var arch = ctx.arch,
            node = new (registry.getNodeClass('BorschikNode'))(sourceNode, 'js', true);

        arch.setNode(node);

        arch.link(sourceNode, node);
        arch.link(node, bundleNode);

        return node;
    },

    'create-css-optimizer-node': function(ctx, sourceNode, bundleNode) {
        var arch = ctx.arch,
            node = new (registry.getNodeClass('BorschikNode'))(sourceNode, 'css-fast', true);

        arch.setNode(node);

        arch.link(sourceNode, node);
        arch.link(node, bundleNode);

        return node;
    },

    'create-ie.css-optimizer-node': function(ctx, sourceNode, bundleNode) {
        var node = this['create-css-optimizer-node'](ctx, sourceNode, bundleNode);

        ctx.arch.link(
            UTIL.getNodeTechPath(this.level, this.item, 'css'),
            node);

        return node;
    }

}, {

    createId: function(level, bundleNameOrItem, subBundleName) {
        return this.__base(PATH.dirname(this._createId(level, bundleNameOrItem, subBundleName)));
    },

    _createId:  function(level, bundleNameOrItem, subBundleName) {
        return UTIL.getNodePrefix(
            (typeof level == 'string')? createLevel(level) : level,
            (typeof bundleNameOrItem === 'string')? createItem(bundleNameOrItem, subBundleName) : bundleNameOrItem);
    }

});

function createItem(bundleName, subBundleName) {
    var item = { block: bundleName };

    if (subBundleName) item.elem = subBundleName;

    return item;
}
<commit_msg>BundleNode: Use `js-i` tech to build .js files for bundles<commit_after>var Q = require('q'),
    INHERIT = require('inherit'),
    UTIL = require('../util'),
    PATH = require('path'),
    createLevel = require('../index').createLevel,

    MagicNode = require('./magic').MagicNode,
    FileNode = require('./file').FileNode,
    BemCreateNode = require('./create').BemCreateNode,
    BemBuildNode = require('./build').BemBuildNode,
    registry = require('../make').NodesRegistry,
    LOGGER = require('../logger');

var BundleNode = exports.BundleNode = INHERIT(MagicNode, {

    __constructor: function(level, bundleNameOrItem, subBundleName) {
        this.level = typeof level == 'string'? createLevel(level) : level;

        this.item = (typeof bundleNameOrItem === 'string')? createItem(bundleNameOrItem, subBundleName) : bundleNameOrItem;

        this.__base(PATH.dirname(this.getNodePrefix()));
    },

    make: function(ctx) {

        return ctx.arch.withLock(this.alterArch(ctx), this);

    },

    alterArch: function(ctx) {

        return function() {

            // create real node for page
            var arch = ctx.arch,
                bundleNode;

            if (arch.hasNode(this.path)) {
                bundleNode = arch.getNode(this.path);
            } else {
                bundleNode = new FileNode(this.path);
                arch.setNode(bundleNode, arch.getParents(this));
            }

            // generate targets for page files
            var techTargets = {};
            this.getTechDeps().map(function(tech) {
                var techNode = this.createNode(ctx, tech, bundleNode, this);
                techTargets[tech] = techNode.getId();

                this.createOptimizerNode(ctx, bundleNode, techNode, tech);
            }, this);

            // link targets for page files with each other
            // FIXME: rewrite, move linking to create*() methods
            return this.linkNodes(ctx, techTargets);
        };

    },

    lastModified: function() {
        return Q.resolve(0);
    },

    createNode: function(ctx, tech, bundleNode, magicNode) {
        return (this['create-' + tech + '-node'] ||
            this.createDefaultNode).call(this, ctx, tech, bundleNode, magicNode);
    },

    createOptimizerNode: function(ctx, bundleNode, sourceNode, tech) {
        return (this['create-' + tech + '-optimizer-node'] ||
            this.createDefaultOptimizerNode).call(this, ctx, sourceNode, bundleNode, tech);
    },

    linkNodes: function(ctx, techTargets) {
        return Q.all(Object.keys(techTargets).map(function(target) {
            var targetNode = ctx.arch.nodes[techTargets[target]];
            if (targetNode.getCreateDependencies)
                return Q.when(targetNode.getCreateDependencies(ctx), function(deps) {
                    for(var d = 0; d < deps.length; d++) ctx.arch.link(
                        deps[d],
                        techTargets[target]);
                });
        }));
    },

    getPath: function(tech) {
        // TODO: use Tech object to construct paths
        return this.getNodePrefix() + '.' + tech;
    },

    getTechDeps: function() {
        return [
            'bemjson.js',
            'bemdecl.js',
            'deps.js',
            'html',
            'bemhtml.js',
            'css',
            'ie.css',
            'js'
        ];
    },

    cleanup: function(ctx) {
        var arch = ctx.arch;
        if (!arch.hasNode(this.path)) return;
        arch.removeTree(this.path);
    },

    getNodePrefix: function() {
        if (!this._nodePrefix) {
            this._nodePrefix = this.__self._createId(this.level, this.item);
        }
        return this._nodePrefix;
    },

    getLevels: function(prefix) {
        return [].concat(
            this.level.getConfig().bundleBuildLevels,
            [ PATH.join(PATH.dirname(prefix), 'blocks') ]);
    },

    /**
     * Create a bem build node, add it to the arch,
     * then creates a meta node and link it to the build node.
     *
     * @param ctx
     * @param techName
     * @param techPath
     * @param declTech
     * @param {String} bundleNode
     * @param {String} magicNode
     * @param {Boolean} [forked]
     * @return {String} ID of the node that has been created
     */
    setBemBuildNode: function(ctx, techName, techPath, declTech, bundleNode, magicNode, forked) {
        var arch = ctx.arch,
            buildNode = new BemBuildNode(
                this.getLevels(PATH.resolve(ctx.root, this.getNodePrefix())),
                this.getPath(declTech),
                techPath,
                techName,
                this.getNodePrefix(),
                forked);

        arch.setNode(buildNode);

        bundleNode && arch.addParents(buildNode, bundleNode);
        magicNode && arch.addChildren(buildNode, magicNode);

        arch.setNode(buildNode.getMetaNode(),
            buildNode,
            UTIL.getNodeTechPath(this.level, this.item, declTech));

        return buildNode;
    },

    createDefaultNode: function(ctx, tech, bundleNode, magicNode) {
        var arch = ctx.arch,
            node = new FileNode(this.getPath(tech));

        arch.setNode(node);

        bundleNode && arch.link(node, bundleNode);
        magicNode && arch.link(magicNode, node);

        return node;
    },

    'create-bemdecl.js-node': function(ctx, tech, bundleNode, magicNode) {
        var arch = ctx.arch,
            node = new BemCreateNode(this.level, this.item, tech, tech);

        arch.setNode(node);

        bundleNode && arch.link(node, bundleNode);
        magicNode && arch.link(magicNode, node);

        return node;
    },

    'create-deps.js-node': function(ctx, tech, bundleNode, magicNode) {
        return this.setBemBuildNode(ctx, tech, tech, 'bemdecl.js', bundleNode, magicNode);
    },

    'create-html-node': function(ctx, tech, bundleNode, magicNode) {
        // TODO: move node to bem-bl/blocks-common/i-bem/bem
        var arch = ctx.arch,
            node = new BemCreateNode(
                this.level,
                this.item,
                require.resolve(PATH.resolve(this.level.dir, '../bem-bl/blocks-common/i-bem/bem/techs/html')),
                tech,
                true);

        arch.setNode(node);

        bundleNode && arch.link(node, bundleNode);
        magicNode && arch.link(magicNode, node);

        return node;

    },

    'create-bemhtml.js-node': function(ctx, tech, bundleNode, magicNode) {
        // TODO: move node to bem-bl/blocks-common/i-bem/bem
        var techBemHtml = require.resolve(PATH.resolve(this.level.dir, '../bem-bl/blocks-common/i-bem/bem/techs/bemhtml.js'));
        return this.setBemBuildNode(ctx, tech, techBemHtml, 'deps.js', bundleNode, magicNode, true);
    },

    'create-js-node': function(ctx, tech, bundleNode, magicNode) {
        return this.setBemBuildNode(ctx, tech, 'js-i', 'deps.js', bundleNode, magicNode);
    },

    'create-css-node': function(ctx, tech, bundleNode, magicNode) {
        return this.setBemBuildNode(ctx, tech, tech, 'deps.js', bundleNode, magicNode);
    },

    'create-ie.css-node': function(ctx, tech, bundleNode, magicNode) {
        return this['create-css-node'].apply(this, arguments);
    },

    createDefaultOptimizerNode: function(ctx, sourceNode, bundleNode, tech) {},

    'create-js-optimizer-node': function(ctx, sourceNode, bundleNode) {
        var arch = ctx.arch,
            node = new (registry.getNodeClass('BorschikNode'))(sourceNode, 'js', true);

        arch.setNode(node);

        arch.link(sourceNode, node);
        arch.link(node, bundleNode);

        return node;
    },

    'create-css-optimizer-node': function(ctx, sourceNode, bundleNode) {
        var arch = ctx.arch,
            node = new (registry.getNodeClass('BorschikNode'))(sourceNode, 'css-fast', true);

        arch.setNode(node);

        arch.link(sourceNode, node);
        arch.link(node, bundleNode);

        return node;
    },

    'create-ie.css-optimizer-node': function(ctx, sourceNode, bundleNode) {
        var node = this['create-css-optimizer-node'](ctx, sourceNode, bundleNode);

        ctx.arch.link(
            UTIL.getNodeTechPath(this.level, this.item, 'css'),
            node);

        return node;
    }

}, {

    createId: function(level, bundleNameOrItem, subBundleName) {
        return this.__base(PATH.dirname(this._createId(level, bundleNameOrItem, subBundleName)));
    },

    _createId:  function(level, bundleNameOrItem, subBundleName) {
        return UTIL.getNodePrefix(
            (typeof level == 'string')? createLevel(level) : level,
            (typeof bundleNameOrItem === 'string')? createItem(bundleNameOrItem, subBundleName) : bundleNameOrItem);
    }

});

function createItem(bundleName, subBundleName) {
    var item = { block: bundleName };

    if (subBundleName) item.elem = subBundleName;

    return item;
}
<|endoftext|>