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

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

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

  var isFunction = $.isFunction;

  SC.Resource = SC.Object.extend({});

  SC.Resource.ajax = function(options) {
    options.dataType = options.dataType || 'json';
    options.type     = options.type     || 'GET'

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

    return $.ajax(options);
  };

  SC.Resource.reopen({
    isSCResource: true,

    fetch: function() {
      var url = this.resourceURL();

      if (!url) return;

      SC.set(this, 'resourceState', SC.Resource.Lifecycle.FETCHING);

      var self = this;

      if (this.deferedFetch) return this.deferedFetch;

      this.deferedFetch = SC.Resource.ajax({
        url: url,
        success: function(json) {
          self.setProperties(self.constructor.parse(json))
        }
      });

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

      return this.deferedFetch;
    },

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

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

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

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

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

      return SC.Resource.ajax(ajaxOptions);
    }
  });

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

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

  var resolveType = function(options, key) {
    key = key || 'type';
    if (isString(options[key])) {
      options[key] = SC.getPath(options[key]);
    }
  };

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

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

      resolveType(value);

      if (instance instanceof value.type) {
        return SC.get(instance, 'data');
      } else if (isObject(instance)) {
        return instance
      }
    };

    value.deserialize = value.deserialize || function(data) {
      if (data === undefined || data === null) return data;

      resolveType(value);

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

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

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

      resolveType(value);

      return SC.get(instance, 'id');
    };

    value.deserialize = value.deserialize || function(id) {
      if (id === undefined || id === null) return id;

      resolveType(value);

      return value.type.create({id: id});
    };
  };

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

    value.deserialize = value.deserialize || function(options) {
      resolveType(value, 'itemType');

      options.type = value.itemType;

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

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

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

      resolveType(value, 'itemType');

      var array;
      if (instance instanceof SC.ResourceCollection) {
        array = instance.get('content');
      } else if (instance instanceof Array) {
        array = instance;
      }

      if (array) {
        return array.map(function(item) {
          if (item instanceof value.itemType) {
            return item.get('data');
          } else if (isObject(item)) {
            return item;
          } else {
            throw 'invalid item in collection';
          }
        });
      }
    };

    value.deserialize = value.deserialize || function(data) {
      resolveType(value, 'itemType');

      return value.type.create({
        content: data,
        type: value.itemType,
        parse: value.parse
      });
    };
  };

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

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

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

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

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

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

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

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

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

    return schema;
  };

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

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

      if (serializedValue === undefined) {
        SC.run.next(this, this.fetch);
      }

      value = propertyOptions.deserialize(serializedValue);
    } else { // setter
      var serialized = propertyOptions.serialize(value);

      SC.setPath(data, propertyOptions.path, serialized);

      value = propertyOptions.deserialize(serialized);
    }

    return value;
  };

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

  // The computed property function for a url based has-many association
  hasManyFunction = function(name, value) {
    if (arguments.length === 1) { // getter
      var id = this.get('id');
      if (!id) return undefined;

      var propertyOptions = this.constructor.schema[name];
      var options = SC.copy(propertyOptions);

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

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

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

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

    return properties;
  };

  SC.Resource.reopenClass({
    isSCResource: true,

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

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

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

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

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

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

      klass.reopenClass(classOptions);

      return klass;
    },

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

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

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

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

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

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

      options.prePopulated = !! content;

      var instance;

      if (!options.prePopulated && options.url) {
        this.identityMap = this.identityMap || {};
        var identity = [options.type, options.url];
        instance = this.identityMap[identity] || this._super.call(this, options)
        this.identityMap[identity] = instance;
      }

      if (!instance) {
        instance = this._super.call(this, options);

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

      return instance;
    }
  });
}());
<commit_msg>Replace _.map with Array.map<commit_after>(function(undefined) {
  var expandSchema, expandSchemaItem, propertyFunction,
      createPropertyFunction, hasManyFunction, createSchemaProperties,
      expandRemoteHasOneSchemaItem, expandRemoteHasManySchemaItem,
      expandNestedHasOneSchemaItem, expandNestedHasManySchemaItem;

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

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

  var isFunction = $.isFunction;

  SC.Resource = SC.Object.extend({});

  SC.Resource.ajax = function(options) {
    options.dataType = options.dataType || 'json';
    options.type     = options.type     || 'GET'

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

    return $.ajax(options);
  };

  SC.Resource.reopen({
    isSCResource: true,

    fetch: function() {
      var url = this.resourceURL();

      if (!url) return;

      SC.set(this, 'resourceState', SC.Resource.Lifecycle.FETCHING);

      var self = this;

      if (this.deferedFetch) return this.deferedFetch;

      this.deferedFetch = SC.Resource.ajax({
        url: url,
        success: function(json) {
          self.setProperties(self.constructor.parse(json))
        }
      });

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

      return this.deferedFetch;
    },

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

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

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

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

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

      return SC.Resource.ajax(ajaxOptions);
    }
  });

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

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

  var resolveType = function(options, key) {
    key = key || 'type';
    if (isString(options[key])) {
      options[key] = SC.getPath(options[key]);
    }
  };

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

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

      resolveType(value);

      if (instance instanceof value.type) {
        return SC.get(instance, 'data');
      } else if (isObject(instance)) {
        return instance
      }
    };

    value.deserialize = value.deserialize || function(data) {
      if (data === undefined || data === null) return data;

      resolveType(value);

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

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

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

      resolveType(value);

      return SC.get(instance, 'id');
    };

    value.deserialize = value.deserialize || function(id) {
      if (id === undefined || id === null) return id;

      resolveType(value);

      return value.type.create({id: id});
    };
  };

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

    value.deserialize = value.deserialize || function(options) {
      resolveType(value, 'itemType');

      options.type = value.itemType;

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

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

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

      resolveType(value, 'itemType');

      var array;
      if (instance instanceof SC.ResourceCollection) {
        array = instance.get('content');
      } else if (instance instanceof Array) {
        array = instance;
      }

      if (array) {
        return array.map(function(item) {
          if (item instanceof value.itemType) {
            return item.get('data');
          } else if (isObject(item)) {
            return item;
          } else {
            throw 'invalid item in collection';
          }
        });
      }
    };

    value.deserialize = value.deserialize || function(data) {
      resolveType(value, 'itemType');

      return value.type.create({
        content: data,
        type: value.itemType,
        parse: value.parse
      });
    };
  };

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

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

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

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

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

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

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

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

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

    return schema;
  };

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

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

      if (serializedValue === undefined) {
        SC.run.next(this, this.fetch);
      }

      value = propertyOptions.deserialize(serializedValue);
    } else { // setter
      var serialized = propertyOptions.serialize(value);

      SC.setPath(data, propertyOptions.path, serialized);

      value = propertyOptions.deserialize(serialized);
    }

    return value;
  };

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

  // The computed property function for a url based has-many association
  hasManyFunction = function(name, value) {
    if (arguments.length === 1) { // getter
      var id = this.get('id');
      if (!id) return undefined;

      var propertyOptions = this.constructor.schema[name];
      var options = SC.copy(propertyOptions);

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

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

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

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

    return properties;
  };

  SC.Resource.reopenClass({
    isSCResource: true,

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

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

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

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

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

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

      klass.reopenClass(classOptions);

      return klass;
    },

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

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

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

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

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

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

      options.prePopulated = !! content;

      var instance;

      if (!options.prePopulated && options.url) {
        this.identityMap = this.identityMap || {};
        var identity = [options.type, options.url];
        instance = this.identityMap[identity] || this._super.call(this, options)
        this.identityMap[identity] = instance;
      }

      if (!instance) {
        instance = this._super.call(this, options);

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

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


<commit_before>'use strict';
var gulp = require('gulp');
var expect = require('chai').expect;
var mocha = require('gulp-mocha');
var jshint = require('gulp-jshint');

var appFiles = ['server.js', __dirname + '/lib/**/*.js'];
var testFiles = ['gulpfile.js', __dirname + '/lib/**/*.js'];

gulp.task('jshint:apps', function() {
  return gulp.src(appFiles)
    .pipe(jshint({
      node:true
    }))
    .pipe(jshint.reporter('default'));
});

// Revist globals in tests?
gulp.task('jshint:tests', function() {
  return gulp.src(testFiles)
    .pipe(jshint({
      node:true,
      globals:{
        describe:true,
        it:true,
        before:true
      }
    }))
    .pipe(jshint.reporter('default'));
});

gulp.task('jshint', ['jshint:apps', 'jshint:tests']);

gulp.task('mocha', function() {
  return gulp.src(appFiles)
    .pipe(mocha());
});

gulp.task('watch', function() {
  gulp.watch(appFiles, ['jshint:apps', 'mocha']);
  gulp.watch(testFiles, ['jshint:tests']);
});

gulp.task('default', ['watch']);
<commit_msg>fixed gulpfile<commit_after>'use strict';
var gulp = require('gulp');
var expect = require('chai').expect;
var mocha = require('gulp-mocha');
var jshint = require('gulp-jshint');

var appFiles = ['index.js', __dirname + '/lib/**/*.js'];
var testFiles = ['gulpfile.js', __dirname + '/test/**/*.js'];

gulp.task('jshint:apps', function() {
  return gulp.src(appFiles)
    .pipe(jshint({
      node:true
    }))
    .pipe(jshint.reporter('default'));
});

// Revist globals in tests?
gulp.task('jshint:tests', function() {
  return gulp.src(testFiles)
    .pipe(jshint({
      node:true,
      globals:{
        describe:true,
        it:true,
        before:true
      }
    }))
    .pipe(jshint.reporter('default'));
});

gulp.task('jshint', ['jshint:apps', 'jshint:tests']);

gulp.task('mocha', function() {
  return gulp.src(testFiles)
    .pipe(mocha());
});

gulp.task('watch', function() {
  gulp.watch(appFiles, ['jshint:apps', 'mocha']);
  gulp.watch(testFiles, ['jshint:tests']);
});

gulp.task('default', ['jshint', 'mocha']);
<|endoftext|>


<commit_before>define([
	'angular',
	'app'
	],
	function(angular, app) {

		app.directive('submit', [function() {
			return {
				restrict: 'E', /* E: Element, C: Class, A: Attribute M: Comment */
				templateUrl: 'components/submit.html',
				replace: true,
				scope: {
					type: '=type'
				},
				link: function($scope, $element, attr) {
					$scope.text = '';
					$scope.maxChars = 75;

					$scope.$watch('text', $scope.onTextChange);
				},
				controller: function($scope, $element) {
					var TYPE_PERSON = 0;
					var TYPE_THING = 1;
					var randomPeople = [
						'Bill O\'Reilly',
						'Barack Obama',
						'Jesus',
						'Cookie Monster',
						'The little engine that could'
					];
					var randomEvents = [
						'sexting orphans.',
						'being accidentally racist.',
						'worshiping Satan.',
						'selling drugs to the pope.',
						'slashing tires.'
					];

					var halfMax = $scope.maxChars / 2;

					var rand = Math.floor(Math.random() * 5);
					if($scope.type === TYPE_PERSON) {
						$scope.example = randomPeople[rand];
						$scope.displayType = 'Person';
					} else if($scope.type === TYPE_THING) {
						$scope.example = randomEvents[rand];
						$scope.displayType = 'Event';
					}

					$scope.onTextChange = function(newValue, oldValue) {
						if(newValue === undefined || newValue === null)
							$scope.text = '';
					}
					$scope.characterCount = function() {
						if($scope.text) {
							if($scope.text.length < halfMax)
								return 'alert-success';
							if($scope.text.length < $scope.maxChars)
								return 'alert-warning';
							else
								return 'alert-danger';
						}
					};
				}
			}
		}]);
	}
);<commit_msg>fixed character count bug<commit_after>define([
	'angular',
	'app'
	],
	function(angular, app) {

		app.directive('submit', [function() {
			return {
				restrict: 'E', /* E: Element, C: Class, A: Attribute M: Comment */
				templateUrl: 'components/submit.html',
				replace: true,
				scope: {
					type: '=type'
				},
				link: function($scope, $element, attr) {
					$scope.$watch('text', $scope.onTextChange);
				},
				controller: function($scope, $element) {
					var TYPE_PERSON = 0;
					var TYPE_THING = 1;
					var randomPeople = [
						'Bill O\'Reilly',
						'Barack Obama',
						'Jesus',
						'Cookie Monster',
						'The little engine that could'
					];
					var randomEvents = [
						'sexting orphans.',
						'being accidentally racist.',
						'worshiping Satan.',
						'selling drugs to the pope.',
						'slashing tires.'
					];

					$scope.text = '';
					$scope.maxChars = 75;
					var halfMax = $scope.maxChars / 2;

					var rand = Math.floor(Math.random() * 5);
					if($scope.type === TYPE_PERSON) {
						$scope.example = randomPeople[rand];
						$scope.displayType = 'Person';
					} else if($scope.type === TYPE_THING) {
						$scope.example = randomEvents[rand];
						$scope.displayType = 'Event';
					}

					$scope.onTextChange = function(newValue, oldValue) {
						if(newValue === undefined || newValue === null)
							$scope.text = '';
					}
					$scope.characterCount = function() {
						if($scope.text !== undefined) {
							if($scope.text.length < halfMax)
								return 'alert-success';
							if($scope.text.length < $scope.maxChars)
								return 'alert-warning';
							else
								return 'alert-danger';
						}
					};
				}
			}
		}]);
	}
);<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var Negotiator = require('negotiator');

exports.register = function (server, opts, next) {
    server.ext('onPostHandler', function (request, next) {
        var route = request.route;
        var negotiate = _.get(route, 'settings.plugins.negotiate', {});

        if (_.isFunction(negotiate)) negotiate = negotiate(request);

        if (Object.keys(negotiate).length === 0) return next.continue();

        var mediaType = new Negotiator(request).mediaType(Object.keys(negotiate));
        if (mediaType) {
            negotiate[mediaType](request, next);
        } else {
            next.continue();
        }
    });

    server.decorate('server', 'negotiate', function(routeId, handlers) {
        var route = server.lookup(routeId);
        if (!route) throw new Error('No route with id ' + routeId);
        route.settings.plugins.negotiate = _.assign({}, route.settings.plugins.negotiate, handlers);
    });
    next();
};

exports.register.attributes = { name: 'hapi-everafter' };<commit_msg>added reply decorator<commit_after>'use strict';

var _ = require('lodash');
var Negotiator = require('negotiator');
var boom = require('boom');

exports.register = function (server, opts, next) {
    server.ext('onPostHandler', function (request, next) {
        var route = request.route;

        var negotiate = _.get(route, 'settings.plugins.negotiate', {});

        if (_.isFunction(negotiate)) negotiate = negotiate(request);

        if (Object.keys(negotiate).length === 0) return next.continue();

        var mediaType = new Negotiator(request).mediaType(Object.keys(negotiate));

        if (mediaType) {
            negotiate[mediaType](request, next);
        } else {
            next.continue();
        }
    });

    server.decorate('server', 'negotiate', function(routeId, handlers) {
        var route = server.lookup(routeId);
        if (!route) throw new Error('No route with id ' + routeId);
        route.settings.plugins.negotiate = _.assign({}, route.settings.plugins.negotiate, handlers);
    });

    server.decorate('reply', 'negotiate', function (negotiate) {
        var mediaType = new Negotiator(this.request).mediaType(Object.keys(negotiate));
        if (mediaType) {
            negotiate[mediaType](this.request, this);
        } else {
            this(boom.notAcceptable());
        }
    });

    next();
};

exports.register.attributes = { name: 'hapi-everafter' };<|endoftext|>


<commit_before>//@auth
//@req(url, name)

import com.hivext.api.core.utils.Transport;

//reading script from URL
var body = new Transport().get(url),
    startText = 'start',
    stopText = 'stop'

//delete the script if it exists already
jelastic.dev.scripting.DeleteScript(name);

//create a new script
var resp = jelastic.dev.scripting.CreateScript(name, 'js', body);
if (resp.result !== 0) return resp;

var tasks = jelastic.utils.scheduler.GetTasks().objects;
var description = "start-stop-scheduler";

for (var i = 0, l = tasks.length; i < l; i++){
    var t = tasks[i];
    if (t.script === name) jelastic.utils.scheduler.RemoveTask(t.id);
}

var start = getParam(startText),
    stop = getParam(stopText);

function addTask (action, taskName) {
    //trim string
    var arr = action.replace(/\s+/g, ' ').replace(/^\s+|\s+$/gm,'').split(' ');
    //should be 5 elements
    if (arr.length != 5) return {result: 99, message:'wrong cron format [' + action + ']', type: 'error'}
    //replacing * at "Day of week" to make it compatible with quartz format
    if (arr[4] == '*') arr[4] = '?';
    //adding seconds - always 0
    arr.unshift('0');
    action = arr.join(' ');

    var params = toJSON({action: taskName, envName: '${env.envName}'});
    return jelastic.utils.scheduler.AddTask(appid, session, name, "cron:" + action, description, params);
}

if (start) {
    resp = addTask(start, startText);
    if (resp.result !== 0) return resp;
}

return stop ? addTask(stop, stopText) : resp;

<commit_msg>Update create-service.js<commit_after>//@auth
//@req(url, name)

import com.hivext.api.core.utils.Transport;
import org.json.JSONObject;

var description = "start-stop-scheduler",
    //reading script from URL
    body = new Transport().get(url),
    configureAction = 'action',
    startText = 'start',
    stopText = 'stop',
    checkTask,
    tasks,
    start,
    stop,
    task,
    resp,
    i, l

start = getParam(startText)
stop = getParam(stopText)

//delete the script if it exists already
jelastic.dev.scripting.DeleteScript(name);

//create a new script
resp = jelastic.dev.scripting.CreateScript(name, 'js', body);
if (resp.result != 0) return resp;

resp = jelastic.utils.scheduler.GetTasks();
if (resp.result != 0) return resp;

tasks = resp.objects;

if (getParam(configureAction)) {

    if (start) {
        resp = replaceTask(tasks, startText, start)
        if (resp.result != 0) return resp;
    }

    return stop ? replaceTask(tasks, stopText, stop) : resp
} else {

    if (start) {
        resp = addTask(start, startText)
        if (resp.result != 0) return resp;
    }

    return stop ? addTask(stop, stopText) : resp
}

function replaceTask(tasks, taskName, newTask) {
    for (i = 0, l = tasks.length; i < l; i++) {
        action = toNative(new JSONObject(tasks[i].params.replace('\\\\', '\\'))).action
        checkTask = newTask.substring(0, newTask.length -1)
        // check an identical tasks
        if (action == taskName && tasks[i].trigger.indexOf(checkTask) == -1) {
            // remove task
            resp = jelastic.utils.scheduler.RemoveTask(tasks[i].id);
            if (resp.result != 0) return resp;
            // add new task
            return addTask(newTask, taskName);
        }
    }
    return {
        result: 0
    };
}

function addTask (action, taskName) {
    //trim string
    var arr = action.replace(/\s+/g, ' ').replace(/^\s+|\s+$/gm,'').split(' ');
    //should be 5 elements
    if (arr.length != 5) return {result: 99, message:'wrong cron format [' + action + ']', type: 'error'}
    //replacing * at "Day of week" to make it compatible with quartz format
    if (arr[4] == '*') arr[4] = '?';
    //adding seconds - always 0
    arr.unshift('0');
    action = arr.join(' ');

    var params = toJSON({action: taskName, envName: '${env.envName}'});
    return jelastic.utils.scheduler.AddTask(appid, session, name, "cron:" + action, description, params);
}

return {
    result: 0
};
<|endoftext|>


<commit_before>function openUserGroupDialog()
{
    if (UmbClientMgr.mainTree().getActionNode().nodeId != '-1' && UmbClientMgr.mainTree().getActionNode().nodeType != '') {
        UmbClientMgr.openModalWindow("plugins/usergrouppermissions/dialogs/permissions.aspx?id=" + UmbClientMgr.mainTree().getActionNode().nodeId + '&rnd=', 'Set role permissions', true, 800, 400);
    }
}<commit_msg>no need for js in umb 7<commit_after>function openUserGroupDialog()
{
    /*
    if (UmbClientMgr.mainTree().getActionNode().nodeId != '-1' && UmbClientMgr.mainTree().getActionNode().nodeType != '') {
        UmbClientMgr.openModalWindow("plugins/usergrouppermissions/dialogs/permissions.aspx?id=" + UmbClientMgr.mainTree().getActionNode().nodeId + '&rnd=', 'Set role permissions', true, 800, 400);
    }
    */
}<|endoftext|>


<commit_before>'use strict';
var gulp = require('gulp'),
    lazypipe = require('lazypipe'),
    src = {},
    templates,
    through2 = require('through2'),
    $ = require('gulp-load-plugins')();

function cleanCache(cacheName) {
    /*jslint unparam:true*/
    return lazypipe().pipe(through2.obj, function (file, enc, cb) {
        if (file.event === 'unlink') {
            delete $.cached.caches[cacheName][file.path];
            $.remember.forget(cacheName, file.path);
        } else {
            this.push(file);
        }
        cb();
    });
}

src.templates = 'src/**/*.html';
templates = lazypipe()
    .pipe($.debug, {title: 'from pipe', minimal: false})
    .pipe($.cached, 'templates')
    .pipe($.remember, 'templates')
    .pipe($.debug, {title: 'after remember', minimal: false})
    .pipe($.angularTemplatecache)
    .pipe(gulp.dest, 'dist/');

gulp.task('templates', function () {
    return gulp.src(src.templates).pipe(templates());
});

gulp.task('default', ['templates'], function () {
    $.watch(src.templates, $.batch(function (events, done) {
        events
            .pipe(cleanCache('templates').pipe(templates)())
            .pipe($.util.buffer(function () {
                done();
            }));
    }));
});
<commit_msg>remove jslint code<commit_after>var gulp = require('gulp'),
    lazypipe = require('lazypipe'),
    src = {},
    templates,
    through2 = require('through2'),
    $ = require('gulp-load-plugins')();

function cleanCache(cacheName) {
    return lazypipe().pipe(through2.obj, function (file, enc, cb) {
        if (file.event === 'unlink') {
            delete $.cached.caches[cacheName][file.path];
            $.remember.forget(cacheName, file.path);
        } else {
            this.push(file);
        }
        cb();
    });
}

src.templates = 'src/**/*.html';
templates = lazypipe()
    .pipe($.debug, {title: 'from pipe', minimal: false})
    .pipe($.cached, 'templates')
    .pipe($.remember, 'templates')
    .pipe($.debug, {title: 'after remember', minimal: false})
    .pipe($.angularTemplatecache)
    .pipe(gulp.dest, 'dist/');

gulp.task('templates', function () {
    return gulp.src(src.templates).pipe(templates());
});

gulp.task('default', ['templates'], function () {
    $.watch(src.templates, $.batch(function (events, done) {
        events
            .pipe(cleanCache('templates').pipe(templates)())
            .pipe($.util.buffer(function () {
                done();
            }));
    }));
});
<|endoftext|>


<commit_before>// ===================================================
// Setup
// ===================================================

var gulp            = require('gulp'),
    gulpLoadPlugins = require('gulp-load-plugins'),
    $               = gulpLoadPlugins({
                        rename: {
                          'gulp-minify-css'  : 'mincss',
                          'gulp-minify-html' : 'minhtml',
                          'gulp-gh-pages'    : 'ghPages'
                        }
                      }),
    assemble        = require('assemble'),
    del             = require('del'),
    merge           = require('merge-stream');

$.exec   = require('child_process').exec;
$.fs     = require('fs');

// ===================================================
// Config
// ===================================================

var paths_dir = {
  site: 'site',
  templates : 'templates',
  data: 'data',
  dist: 'dist',
  sitejs: 'js',
  sitecss: 'css',
  sitesass: 'src'
};

var paths = {
  site: paths_dir.site,
  data: paths_dir.data,
  templates: paths_dir.site + '/' + paths_dir.templates,
  dist: paths_dir.dist,
  sitejs: paths_dir.site + '/' + paths_dir.sitejs,
  sitecss: paths_dir.site + '/' + paths_dir.sitecss,
  sitesass: paths_dir.site + '/' + paths_dir.sitecss + '/' + paths_dir.sitesass
};

// ===================================================
// Server
// ===================================================

gulp.task('serve', ['assemble'], function() {
  $.connect.server({
    root: [paths.site],
    port: 5000,
    livereload: true,
    middleware: function(connect) {
      return [
        connect().use(connect.query())
      ];
    }
  });

  $.exec('open http://localhost:5000');
});

// ===================================================
// Stylesheets
// ===================================================

gulp.task('sass', function() {
  var stream = gulp.src(paths.sitesass + '/**/*.scss')
    .pipe($.sass())
    .pipe($.autoprefixer({
      browsers: ['last 2 versions'],
      cascade: false
    }))
    .pipe(gulp.dest(paths.sitecss))
    .pipe($.connect.reload());

  return stream;
});

// ===================================================
// Templates
// ===================================================

assemble.layouts(paths.templates + '/layouts/*.hbs');
assemble.partials(paths.templates + '/includes/**/*.hbs');
assemble.pages(paths.templates + '/pages/*.hbs');
assemble.option('layout', 'default');
assemble.data(paths.data + '/**/*.{json,yaml}');

gulp.task('assemble', function() {
  var stream = assemble.src(paths.templates + '/pages/*.hbs')
    .pipe($.extname())
    .pipe(assemble.dest(paths.site))
    .pipe($.connect.reload());

  return stream;
});

// ===================================================
// SVG
// ===================================================

gulp.task('svgstore', function () {
  return gulp
    .src(paths.site + '/img/icons/linear/*.svg')
    .pipe($.svgmin({
      plugins: [{
        removeDoctype: true
      }]
    }))
    .pipe($.svgstore())
    .pipe($.cheerio(function($) {
        $('svg').attr('style', 'display:none');
    }))
    .pipe(gulp.dest(paths.templates + '/includes/atoms/svg-sprite.svg'));
});

// ===================================================
// Build
// ===================================================

gulp.task('copy', function() {
  return merge(
    // jslibs
    gulp.src([paths.sitejs + '/lib/**/*.js'])
      .pipe(gulp.dest(paths.dist + '/js/lib')),

    // images
    gulp.src([paths.site + '/img/**/*'])
      .pipe(gulp.dest(paths.dist + '/img')),

    // bower
    gulp.src([paths.site + '/bower_components/**/*'])
      .pipe(gulp.dest(paths.dist + '/bower_components')),

    // root files
    gulp.src([
        '*.php',
        paths.site + '/googlee3138e5e7e9413ae.html',
        paths.site + '/*.ico',
        paths.site + '/.htaccess',
        paths.site + '/*.txt'
      ]).pipe(gulp.dest(paths.dist))
  );
});

gulp.task('cssmin', ['sass'], function() {
  var stream = gulp.src(paths.sitecss + '/*.css')
    .pipe($.mincss({ keepBreaks:true }))
    .pipe(gulp.dest(paths.sitecss));

  return stream;
});

gulp.task('usemin', ['assemble', 'cssmin'], function() {
  var stream = gulp.src([
        paths.site + '/index.html'
      ])
      .pipe($.usemin({
        css: [ $.rev() ],
        html: [ $.minhtml({ empty: true }) ],
        js: [ $.uglify(), $.rev() ]
      }))
      .pipe(gulp.dest(paths.dist));

  return stream;
});

gulp.task('minguide', ['assemble', 'cssmin'], function() {
  var stream = gulp.src([
        paths.site + '/atomic-guide.html'
      ])
      .pipe($.usemin({
        css: [ $.rev() ],
        html: [ $.minhtml({ empty: true }) ],
        js: [ $.uglify(), $.rev() ]
      }))
      .pipe(gulp.dest(paths.dist));

  return stream;
});

// ===================================================
// Release
// ===================================================

gulp.task('deploy', function() {
  return gulp.src([paths.dist + '/**/*', paths.dist + '/.htaccess' ])
    .pipe($.ghPages({ branch: 'master' }));
});

// ===================================================
// Cleaning
// ===================================================

gulp.task('clean', function(cb) {
  del([
    'dist',
    paths.site + '/css/*.css',
    paths.site + '/*.html',
    paths.site + '/js/build'
  ], cb);
});

// ===================================================
// Monitoring
// ===================================================

gulp.task('watch', function() {
  gulp.watch([
    paths.dist + '/**/*.scss',
    paths.sitesass + '/**/*.scss'
  ], ['sass']);

  gulp.watch([
    paths.templates + '/includes/**/*.hbs',
    paths.templates + '/pages/*.hbs',
    paths.templates + '/layouts/*.hbs'
  ], ['assemble']);

  gulp.watch([
    paths.site + '/includes/*.html'
  ], [$.connect.reload()]);
});

// ===================================================
// Tasks
// ===================================================

gulp.task('build', ['copy', 'usemin', 'minguide']);
gulp.task('default', ['sass', 'assemble', 'serve', 'watch']);
<commit_msg>single usemin call<commit_after>// ===================================================
// Setup
// ===================================================

var gulp            = require('gulp'),
    gulpLoadPlugins = require('gulp-load-plugins'),
    $               = gulpLoadPlugins({
                        rename: {
                          'gulp-minify-css'  : 'mincss',
                          'gulp-minify-html' : 'minhtml',
                          'gulp-gh-pages'    : 'ghPages'
                        }
                      }),
    assemble        = require('assemble'),
    del             = require('del'),
    merge           = require('merge-stream');

$.exec   = require('child_process').exec;
$.fs     = require('fs');

// ===================================================
// Config
// ===================================================

var paths_dir = {
  site: 'site',
  templates : 'templates',
  data: 'data',
  dist: 'dist',
  sitejs: 'js',
  sitecss: 'css',
  sitesass: 'src'
};

var paths = {
  site: paths_dir.site,
  data: paths_dir.data,
  templates: paths_dir.site + '/' + paths_dir.templates,
  dist: paths_dir.dist,
  sitejs: paths_dir.site + '/' + paths_dir.sitejs,
  sitecss: paths_dir.site + '/' + paths_dir.sitecss,
  sitesass: paths_dir.site + '/' + paths_dir.sitecss + '/' + paths_dir.sitesass
};

// ===================================================
// Server
// ===================================================

gulp.task('serve', ['assemble'], function() {
  $.connect.server({
    root: [paths.site],
    port: 5000,
    livereload: true,
    middleware: function(connect) {
      return [
        connect().use(connect.query())
      ];
    }
  });

  $.exec('open http://localhost:5000');
});

// ===================================================
// Stylesheets
// ===================================================

gulp.task('sass', function() {
  var stream = gulp.src(paths.sitesass + '/**/*.scss')
    .pipe($.sass())
    .pipe($.autoprefixer({
      browsers: ['last 2 versions'],
      cascade: false
    }))
    .pipe(gulp.dest(paths.sitecss))
    .pipe($.connect.reload());

  return stream;
});

// ===================================================
// Templates
// ===================================================

assemble.layouts(paths.templates + '/layouts/*.hbs');
assemble.partials(paths.templates + '/includes/**/*.hbs');
assemble.pages(paths.templates + '/pages/*.hbs');
assemble.option('layout', 'default');
assemble.data(paths.data + '/**/*.{json,yaml}');

gulp.task('assemble', function() {
  var stream = assemble.src(paths.templates + '/pages/*.hbs')
    .pipe($.extname())
    .pipe(assemble.dest(paths.site))
    .pipe($.connect.reload());

  return stream;
});

// ===================================================
// SVG
// ===================================================

gulp.task('svgstore', function () {
  return gulp
    .src(paths.site + '/img/icons/linear/*.svg')
    .pipe($.svgmin({
      plugins: [{
        removeDoctype: true
      }]
    }))
    .pipe($.svgstore())
    .pipe($.cheerio(function($) {
        $('svg').attr('style', 'display:none');
    }))
    .pipe(gulp.dest(paths.templates + '/includes/atoms/svg-sprite.svg'));
});

// ===================================================
// Build
// ===================================================

gulp.task('copy', function() {
  return merge(
    // jslibs
    gulp.src([paths.sitejs + '/lib/**/*.js'])
      .pipe(gulp.dest(paths.dist + '/js/lib')),

    // images
    gulp.src([paths.site + '/img/**/*'])
      .pipe(gulp.dest(paths.dist + '/img')),

    // bower
    gulp.src([paths.site + '/bower_components/**/*'])
      .pipe(gulp.dest(paths.dist + '/bower_components')),

    // root files
    gulp.src([
        '*.php',
        paths.site + '/googlee3138e5e7e9413ae.html',
        paths.site + '/*.ico',
        paths.site + '/.htaccess',
        paths.site + '/*.txt'
      ]).pipe(gulp.dest(paths.dist))
  );
});

gulp.task('cssmin', ['sass'], function() {
  var stream = gulp.src(paths.sitecss + '/*.css')
    .pipe($.mincss({ keepBreaks:true }))
    .pipe(gulp.dest(paths.sitecss));

  return stream;
});

gulp.task('usemin', ['assemble', 'cssmin'], function() {
  var stream = gulp.src([
        paths.site + '/*.html'
      ])
      .pipe($.usemin({
        css: [ $.rev() ],
        html: [ $.minhtml({ empty: true }) ],
        js: [ $.uglify(), $.rev() ]
      }))
      .pipe(gulp.dest(paths.dist));

  return stream;
});

// ===================================================
// Release
// ===================================================

gulp.task('deploy', function() {
  return gulp.src([paths.dist + '/**/*', paths.dist + '/.htaccess' ])
    .pipe($.ghPages({ branch: 'master' }));
});

// ===================================================
// Cleaning
// ===================================================

gulp.task('clean', function(cb) {
  del([
    'dist',
    paths.site + '/css/*.css',
    paths.site + '/*.html',
    paths.site + '/js/build'
  ], cb);
});

// ===================================================
// Monitoring
// ===================================================

gulp.task('watch', function() {
  gulp.watch([
    paths.dist + '/**/*.scss',
    paths.sitesass + '/**/*.scss'
  ], ['sass']);

  gulp.watch([
    paths.templates + '/includes/**/*.hbs',
    paths.templates + '/pages/*.hbs',
    paths.templates + '/layouts/*.hbs'
  ], ['assemble']);

  gulp.watch([
    paths.site + '/includes/*.html'
  ], [$.connect.reload()]);
});

// ===================================================
// Tasks
// ===================================================

gulp.task('build', ['copy', 'usemin']);
gulp.task('default', ['sass', 'assemble', 'serve', 'watch']);
<|endoftext|>


<commit_before>// 空间变换算法
// function [dots]=xrs(dots,wyh)
// % 转动，缩放，平移，依次进行
// % wyh.mid为变换中心
// % wyh.ppt为转动轴的方向
// % wyh.alph为转动角度
// % wyh.scrl为缩放系数，反射可设轴向系数为-1
// % wyh.drag为平移向量
// wyh.alph=pi*wyh.alph/180;
// if size(dots,2)==3
//     if numel(wyh.ppt) == 2
//         theta = pi*wyh.ppt(1)/180;
//         phi = pi*wyh.ppt(2)/180;
//         rot_u = [cos(phi)*cos(theta); cos(phi)*sin(theta); sin(phi)];
//     elseif numel(wyh.ppt) == 3
//         rot_u = wyh.ppt(:)/norm(wyh.ppt);
//     end
//     x_u = rot_u(1);
//     y_u = rot_u(2);
//     z_u = rot_u(3);
//     cosa = cos(wyh.alph);
//     sina = sin(wyh.alph);
//     vera = 1 - cosa;
//     rot = [cosa+x_u^2*vera x_u*y_u*vera-z_u*sina x_u*z_u*vera+y_u*sina; ...
//         x_u*y_u*vera+z_u*sina cosa+y_u^2*vera y_u*z_u*vera-x_u*sina; ...
//         x_u*z_u*vera-y_u*sina y_u*z_u*vera+x_u*sina cosa+z_u^2*vera]';
// else
//     rot=[cos(wyh.alph),-sin(wyh.alph);sin(wyh.alph),cos(wyh.alph)];
// end
// for cx=1:size(dots,1)
//     dots(cx,:)=(dots(cx,:)-wyh.mid).*wyh.scrl*rot+wyh.mid+wyh.drag;
// end
// end
"use strict";

var notMatchLength = new Error("矩阵长度不一致");
function transform(dots, B) {
    var dimention = Math.sqrt(B.length - 1) | 0;
    if (dots.length % dimention !== 0) throw notMatchLength;
    if (dots === B) B = B.slice(0);
    var ds = dots.slice(0);
    var dim2 = B.length % dimention !== 0 ? dimention + 1 : dimention;
    for (var cx = 0, dx = dots.length; cx < dx; cx += dimention) {
        for (var cy = 0, dy = dimention; cy < dy; cy++) {
            var sum = 0;
            for (var ct = 0, dt = dimention; ct < dt; ct++) {
                sum += ds[cx + ct] * B[ct * dim2 + cy];
            }
            sum += B[dimention * dim2 + cy];
            dots[cx + cy] = sum;
        }
    }
    return dots;
};

function translate(A, delta) {
    var [dim2, dim] = size(A);
    var inc = 0;
    for (var cx = dim * dim2, dx = cx + dim; cx < dx; cx++) {
        A[cx] = (A[cx] || 0) + delta[inc++];
    }
    return A;
}

function 负(a) {
    return -a;
}

function multiply(A, B) {
    if (A.length !== B.length) throw notMatchLength;
    var dim = Math.sqrt(A.length) | 0;
    if (dim * dim !== A.length) throw notMatchLength;
    var X = A.slice(0);
    for (var cx = 0, dx = A.length; cx < dx; cx += dim) {
        for (var cy = 0, dy = dim; cy < dy; cy++) {
            var sum = 0;
            for (var ct = 0, dt = dim; ct < dt; ct++) {
                sum += X[cx + ct] * B[ct * dim + cy];
            }
            A[cx + cy] = sum;
        }
    }
    return A;
}

function inner(vec1, vec2) {
    if (vec1.length !== vec2.length) throw notMatchLength;
    var sum = 0;
    for (var cx = 0, dx = vec1.length; cx < dx; cx++) {
        sum += vec1[cx] * vec2[cx];
    }
    return sum;
}
function cross(vec1, vec2) {
    if (vec1.length !== vec2.length) throw notMatchLength;
    var c = new Array(vec1.length);
    for (var cx = 0, dx = vec1.length; cx < dx; cx++) {
        var s = 0, f = 1;
        for (var cy = 1, dy = dx; cy < dy; cy++) {
            var c1 = cx + cy;
            var c2 = c1 + f;
            if (c1 >= dx) c1 -= dx;
            if (c2 >= dx) c2 -= dx;
            f = 0 - f;
            s += vec1[c1] * vec2[c2];
        }
        c[cx] = s;
    }
    return c;
}
function times(vector, factor) {
    for (var cx = 0, dx = vector.length; cx < dx; cx++) {
        vector[cx] *= factor;
    }
    return vector;
}

function olinde(v, vector) {
    // 罗德里格旋转公式
    // https://baike.baidu.com/item/%E7%BD%97%E5%BE%B7%E9%87%8C%E6%A0%BC%E6%97%8B%E8%BD%AC%E5%85%AC%E5%BC%8F/18878562
    // https://www.cnblogs.com/flyinggod/p/8144100.html 旋转矩阵、欧拉角、四元数理论及其转换关系
    var theta = norm(vector);
    var k = times(vector.slice(0), 1 / theta);
    var cosa = Math.cos(theta);
    var sina = Math.sin(theta);
    var inna = inner(k, v);
    var aa = inna * (1 - cosa);
    var kv = cross(k, v);
    for (var cx = 0, dx = k.length; cx < dx; cx++) {
        v[cx] = v[cx] * cosa + aa * k[cx] + sina * kv[cx];
    }
    return v;
}
function matrix2d(theta) {
    var cosa = Math.cos(theta);
    var sina = Math.sin(theta);
    return new Matrix(
        cosa, sina, 0,
        -sina, cosa, 0,
        0, 0, 1
    );
};
function matrix3d(factor) {
    var theta = norm(factor);
    var vec = times(factor, 1 / theta);
    var cosa = Math.cos(theta);
    var sina = Math.sin(theta);
    var vera = 1 - cosa;
    var [x_u, y_u, z_u] = factor ? [0, 0, 1] : vec;

    return new Matrix(
        cosa + x_u * x_u * vera, x_u * y_u * vera - z_u * sina, x_u * z_u * vera + y_u * sina, 0,
        x_u * y_u * vera + z_u * sina, cosa + y_u * y_u * vera, y_u * z_u * vera - x_u * sina, 0,
        x_u * z_u * vera - y_u * sina, y_u * z_u * vera + x_u * sina, cosa + z_u * z_u * vera, 0,
        0, 0, 0, 1
    );
}
var norm = function (vector) {
    var sum = 0;
    for (var cx = 0, dx = vector.length; cx < dx; cx++) {
        sum += vector[cx] * vector[cx];
    }
    return Math.sqrt(sum);
};

var 逆 = function (A) {
    var dim = Math.sqrt(A.length) | 0;
    if (dim * dim !== A.length) throw notMatchLength;
    var E = new Array(A.length).fill(0);
    for (var cx = 0, dx = dim; cx < dx; cx++)E[cx * dim + cx] = 1;
    var X = A.splice(0, A.length);
    A.push.apply(A, E);
    for (var cx = 0, dx = dim; cx < dx; cx++) {
        var start = cx * dim + cx;
        for (var ct = start, dt = X.length; ct < dt; ct += dim) {
            if (X[ct] !== 0) break;
        }
        if (ct !== start) {
            var delta = ct - start;
            var ratio = 1 / X[ct];
            for (var cy = cx * dim, dy = cy + dim; cy < dy; cy++) {
                X[cy] += X[cy + delta] * ratio;
                A[cy] += A[cy + delta] * ratio;
            }
        }
        if (X[start] !== 1) {
            var delta = ct - start;
            var ratio = 1 / X[start];
            for (var cy = cx * dim, dy = cy + dim; cy < dy; cy++) {
                X[cy] *= ratio;
                A[cy] *= ratio;
            }
        }
        for (var ct = start + dim, dt = X.length; ct < dt; ct += dim) {
            if (X[ct] === 0) continue;
            var ratio = -X[ct];
            var delta = start - ct;
            for (var cy = ct - cx, dy = cy + dim; cy < dy; cy++) {
                X[cy] += X[cy + delta] * ratio;
                A[cy] += A[cy + delta] * ratio;
            }
        }
    }
    for (var cx = dim - 2; cx >= 0; cx--) {
        var start = cx * dim + cx + 1;
        for (var ct = start; ct >= 0; ct -= dim) {
            if (X[ct] === 0) continue;
            var ratio = -X[ct];
            var delta = dim + start - ct;
            for (var cy = cx * dim, dy = cy + dim; cy < dy; cy++) {
                X[cy] += X[cy + delta] * ratio;
                A[cy] += A[cy + delta] * ratio;
            }
        }
    }
    return A;
};

function size(A) {
    var dim = Math.sqrt(A.length - 1) | 0;
    var dim2 = dim;
    if (A.length % dim !== 0) {
        dim2++;
    }
    if ((dim + 1) * dim2 !== A.length) throw notMatchLength;
    return [dim2, dim];
}

class Matrix extends Array {
    static create2d(theta = 0) {
        return matrix2d(theta);
    }
    static create3d(factor = [0, 0, 0]) {
        return matrix3d(factor);
    }
    size() {
        return size(this);
    }
    dirty() {
        this._invert = null;
    }
    _invert = null;
    get invert() {
        if (this._invert) return this._invert;
        return this._invert = this.slice().inverse();
    }
    inverse() {
        this.dirty();
        return 逆(this);
    }
    rotate(factor, center) {
        this.dirty();
        if (center) this.translate(center.map(负));
        if (factor.length) {
            this.multiply(matrix3d(factor));
        }
        else {
            this.multiply(matrix2d(factor));
        }
        if (center) this.translate(center);
        return this;
    }
    translate(vector) {
        this.dirty();
        return translate(this, vector);
    }
    scale(ratio) {
        this.dirty();
        times(this, ratio);
        this[this.length - 1] = 1;
        return this;
    }
    multiply(a) {
        this.dirty();
        return multiply(this, a);
    }
    transform(dots) {
        if (dots instanceof Array) return transform(dots, this);
        if (isFinite(dots)) return dots * this[this.length - 1];
        return dots;
    }
}<commit_msg>矩阵数据转置，与DOMMatrix保持一致<commit_after>// 空间变换算法
// function [dots]=xrs(dots,wyh)
// % 转动，缩放，平移，依次进行
// % wyh.mid为变换中心
// % wyh.ppt为转动轴的方向
// % wyh.alph为转动角度
// % wyh.scrl为缩放系数，反射可设轴向系数为-1
// % wyh.drag为平移向量
// wyh.alph=pi*wyh.alph/180;
// if size(dots,2)==3
//     if numel(wyh.ppt) == 2
//         theta = pi*wyh.ppt(1)/180;
//         phi = pi*wyh.ppt(2)/180;
//         rot_u = [cos(phi)*cos(theta); cos(phi)*sin(theta); sin(phi)];
//     elseif numel(wyh.ppt) == 3
//         rot_u = wyh.ppt(:)/norm(wyh.ppt);
//     end
//     x_u = rot_u(1);
//     y_u = rot_u(2);
//     z_u = rot_u(3);
//     cosa = cos(wyh.alph);
//     sina = sin(wyh.alph);
//     vera = 1 - cosa;
//     rot = [cosa+x_u^2*vera x_u*y_u*vera-z_u*sina x_u*z_u*vera+y_u*sina; ...
//         x_u*y_u*vera+z_u*sina cosa+y_u^2*vera y_u*z_u*vera-x_u*sina; ...
//         x_u*z_u*vera-y_u*sina y_u*z_u*vera+x_u*sina cosa+z_u^2*vera]';
// else
//     rot=[cos(wyh.alph),-sin(wyh.alph);sin(wyh.alph),cos(wyh.alph)];
// end
// for cx=1:size(dots,1)
//     dots(cx,:)=(dots(cx,:)-wyh.mid).*wyh.scrl*rot+wyh.mid+wyh.drag;
// end
// end
"use strict";
var notMatchLength = new Error("矩阵长度不一致");

function transform(B, dots) {
    var dimention = Math.sqrt(B.length - 1) | 0;
    if (dots.length % dimention !== 0) throw notMatchLength;
    if (dots === B) B = B.slice(0);
    var ds = dots.slice(0);
    var dim2 = B.length % dimention !== 0 ? dimention + 1 : dimention;
    for (var cx = 0, dx = dots.length; cx < dx; cx += dimention) {
        for (var cy = 0, dy = dimention; cy < dy; cy++) {
            var sum = 0;
            var start = dim2 * cy;
            for (var ct = 0, dt = dimention; ct < dt; ct++) {
                sum += ds[cx + ct] * B[start + ct];
            }
            sum += B[start + dimention];
            dots[cx + cy] = sum;
        }
    }
    return dots;
};

function translate(A, delta) {
    var [dim2, dim] = size(A);
    var inc = 0;
    for (var cx = dim, dx = dim * dim2; cx < dx; cx += dim2) {
        A[cx] = (A[cx] || 0) + delta[inc++];
    }
    return A;
}

function 负(a) {
    return -a;
}

function multiply(A, B) {
    if (A.length !== B.length) throw notMatchLength;
    var dim = Math.sqrt(A.length) | 0;
    if (dim * dim !== A.length) throw notMatchLength;
    var X = A.slice(0);
    for (var cx = 0, dx = A.length; cx < dx; cx += dim) {
        for (var cy = 0, dy = dim; cy < dy; cy++) {
            var sum = 0;
            for (var ct = 0, dt = dim; ct < dt; ct++) {
                sum += B[cx + ct] * X[ct * dim + cy];
            }
            A[cx + cy] = sum;
        }
    }
    return A;
}

function inner(vec1, vec2) {
    if (vec1.length !== vec2.length) throw notMatchLength;
    var sum = 0;
    for (var cx = 0, dx = vec1.length; cx < dx; cx++) {
        sum += vec1[cx] * vec2[cx];
    }
    return sum;
}
function cross(vec1, vec2) {
    if (vec1.length !== vec2.length) throw notMatchLength;
    var c = new Array(vec1.length);
    for (var cx = 0, dx = vec1.length; cx < dx; cx++) {
        var s = 0, f = 1;
        for (var cy = 1, dy = dx; cy < dy; cy++) {
            var c1 = cx + cy;
            var c2 = c1 + f;
            if (c1 >= dx) c1 -= dx;
            if (c2 >= dx) c2 -= dx;
            f = 0 - f;
            s += vec1[c1] * vec2[c2];
        }
        c[cx] = s;
    }
    return c;
}
function times(vector, factor) {
    for (var cx = 0, dx = vector.length; cx < dx; cx++) {
        vector[cx] *= factor;
    }
    return vector;
}

function olinde(v, vector) {
    // 罗德里格旋转公式
    // https://baike.baidu.com/item/%E7%BD%97%E5%BE%B7%E9%87%8C%E6%A0%BC%E6%97%8B%E8%BD%AC%E5%85%AC%E5%BC%8F/18878562
    // https://www.cnblogs.com/flyinggod/p/8144100.html 旋转矩阵、欧拉角、四元数理论及其转换关系
    var theta = norm(vector);
    var k = times(vector.slice(0), 1 / theta);
    var cosa = Math.cos(theta);
    var sina = Math.sin(theta);
    var inna = inner(k, v);
    var aa = inna * (1 - cosa);
    var kv = cross(k, v);
    for (var cx = 0, dx = k.length; cx < dx; cx++) {
        v[cx] = v[cx] * cosa + aa * k[cx] + sina * kv[cx];
    }
    return v;
}

function matrix2d(theta) {
    var cosa = Math.cos(theta);
    var sina = Math.sin(theta);
    return new Matrix(
        cosa, -sina, 0,
        sina, cosa, 0,
        0, 0, 1
    );
}

function matrix3d(factor) {
    var theta = norm(factor);
    var vec = times(factor, 1 / theta);
    var cosa = Math.cos(theta);
    var sina = Math.sin(theta);
    var vera = 1 - cosa;
    var [x_u, y_u, z_u] = factor ? [0, 0, 1] : vec;

    return new Matrix(
        cosa + x_u * x_u * vera, x_u * y_u * vera + z_u * sina, x_u * z_u * vera - y_u * sina, 0,
        x_u * y_u * vera - z_u * sina, cosa + y_u * y_u * vera, y_u * z_u * vera + x_u * sina, 0,
        x_u * z_u * vera + y_u * sina, y_u * z_u * vera - x_u * sina, cosa + z_u * z_u * vera, 0,
        0, 0, 0, 1
    );
}
var norm = function (vector) {
    var sum = 0;
    for (var cx = 0, dx = vector.length; cx < dx; cx++) {
        sum += vector[cx] * vector[cx];
    }
    return Math.sqrt(sum);
};

var 逆 = function (A) {
    var dim = Math.sqrt(A.length) | 0;
    if (dim * dim !== A.length) throw notMatchLength;
    var E = new Array(A.length).fill(0);
    for (var cx = 0, dx = dim; cx < dx; cx++)E[cx * dim + cx] = 1;
    var X = A.splice(0, A.length);
    A.push.apply(A, E);
    for (var cx = 0, dx = dim; cx < dx; cx++) {
        var start = cx * dim + cx;
        var max_ct, v = 0;
        for (var ct = start, dt = cx * dim + dim; ct < dt; ct++) {
            var v0 = Math.abs(X[ct]);
            if (v0 > v) {
                max_ct = ct;
                v = v0;
            }
        }
        ct = max_ct;
        if (ct !== start) {
            var delta = ct - start;
            var ratio = (1 - X[start]) / X[ct];
            for (var cy = cx, dy = X.length; cy < dy; cy += dim) {
                X[cy] += X[cy + delta] * ratio;
                A[cy] += A[cy + delta] * ratio;
            }
        }
        if (X[start] !== 1) {
            var ratio = 1 / X[start];
            for (var cy = cx, dy = X.length; cy < dy; cy += dim) {
                X[cy] *= ratio;
                A[cy] *= ratio;
            }
        }
        for (var ct = start + 1, dt = start + dim - cx; ct < dt; ct++) {
            if (X[ct] === 0) continue;
            var ratio = -X[ct];
            var delta = start - ct;
            for (var cy = cx + ct - start, dy = X.length; cy < dy; cy += dim) {
                X[cy] += X[cy + delta] * ratio;
                A[cy] += A[cy + delta] * ratio;
            }
        }
    }
    for (var cx = dim - 1; cx >= 0; cx--) {
        var start = cx * dim + cx;
        for (var ct = start - 1, dt = start - cx; ct >= dt; ct--) {
            if (X[ct] === 0) continue;
            var ratio = -X[ct];
            var delta = start - ct;
            for (var cy = cx + ct - start, dy = X.length; cy < dy; cy += dim) {
                X[cy] += X[cy + delta] * ratio;
                A[cy] += A[cy + delta] * ratio;
            }
        }
    }
    return A;
};

function size(A) {
    var dim = Math.sqrt(A.length - 1) | 0;
    var dim2 = dim;
    if (A.length % dim !== 0) {
        dim2++;
    }
    if ((dim + 1) * dim2 !== A.length) throw notMatchLength;
    return [dim2, dim];
}

class Matrix extends Array {
    static create2d(theta = 0) {
        return matrix2d(theta);
    }
    static create3d(factor = [0, 0, 0]) {
        return matrix3d(factor);
    }
    size() {
        return size(this);
    }
    dirty() {
        this._invert = null;
    }
    _invert = null;
    get invert() {
        if (this._invert) return this._invert;
        return this._invert = this.slice().inverse();
    }
    transpose() {
        var [size] = this.size();
        for (var cx = 0, dx = size; cx < dx; cx++) {
            for (var cy = cx + 1, dy = dx; cy < dy; cy++) {
                var i = cx * size + cy;
                var j = cy * size + cx;
                var tmp = this[i];
                this[i] = this[j];
                this[j] = tmp;
            }
        }
        return this;
    }
    inverse() {
        this.dirty();
        return 逆(this);
    }
    rotate(factor, center) {
        this.dirty();
        if (center) this.translate(center.map(负));
        if (factor.length) {
            this.multiply(matrix3d(factor));
        }
        else {
            this.multiply(matrix2d(factor));
        }
        if (center) this.translate(center);
        return this;
    }
    translate(vector) {
        this.dirty();
        return translate(this, vector);
    }
    scale(ratio) {
        this.dirty();
        times(this, ratio);
        this[this.length - 1] = 1;
        return this;
    }
    multiply(a) {
        this.dirty();
        return multiply(this, a);
    }
    transform(dots) {
        if (dots instanceof Array) return transform(this, dots);
        if (arguments.length > 1) {
            var a = Array.prototype.slice.apply(arguments, 0);
            return transform(this, a);
        }
        return dots;
    }
}<|endoftext|>


<commit_before>const path = require('path')
const querystring = require('querystring')
const compiler = require('vue-template-compiler')
const transpile = require('vue-template-es2015-compiler')
const genId = require('./modules/gen-id')

module.exports = function (content) {
  this.cacheable()
  const isServer = this.options.target === 'node'
  const compiled = compiler.compile(content)
  const id = `data-v-${genId(this.resourcePath)}`

  // Acquire the query of target file
  const { style: stylePath } = querystring.parse(this.request.split('?').pop())

  compiled.errors.forEach(error => {
    this.emitError('template syntax error ' + error)
  })

  const transpiled = transpile(
    `var render = ${toFunction(compiled.render)}\n` +
    `var staticRenderFns = [${compiled.staticRenderFns.map(toFunction).join(',')}]`
  )

  const shouldHotReload = !isServer &&
    !this.minimize &&
    process.env.NODE_ENV !== 'production'

  let output = writeRenderCode(transpiled, id, stylePath)
  if (shouldHotReload) {
    output += writeHotReloadCode(id)
  }

  return output
}

function writeRenderCode (compiled, id, stylePath) {
  return [
    writeInjectStyle(stylePath, id),
    compiled,
    'module.exports = function (_exports) {',
    '  var options = _exports',
    '  if (typeof _exports === "function") options = _exports.options',
    `  ${writeInjectScopedId(stylePath, id)}`,
    '  options.render = render',
    '  options.staticRenderFns = staticRenderFns',
    '  if (module.hot && api) {',
    `    api.createRecord("${id}", options)`,
    '  }',
    '  return _exports',
    '}\n'
  ].join('\n')
}

function writeInjectStyle (stylePath, id) {
  const loaderPath = path.resolve(__dirname, 'scoped-style-loader.js')
  return stylePath
    ? `require('!!style-loader!css-loader!${loaderPath}?id=${id}!${stylePath}')`
    : ''
}

function writeInjectScopedId (isScoped, id) {
  return isScoped
    ? `options._scopeId = '${id}'`
    : ''
}

function writeHotReloadCode (id) {
  return [
    'var api = null',
    'if (module.hot) {(function () {',
    '  api = require("vue-hot-reload-api")',
    '  api.install(require("vue"))',
    '  if (!api.compatible) return',
    '  module.hot.accept()',
    '  if (module.hot.data) {',
    `    api.rerender("${id}", { render: render, staticRenderFns: staticRenderFns })`,
    '  }',
    '})()}\n'
  ].join('\n')
}

function toFunction (code) {
  return `function(){${code}}`
}
<commit_msg>Thanks to vue-loader<commit_after>/**
 * Some part of codes are borrowed/modified from vue-loader
 * https://github.com/vuejs/vue-loader
 * Released under the MIT License
 */

const path = require('path')
const querystring = require('querystring')
const compiler = require('vue-template-compiler')
const transpile = require('vue-template-es2015-compiler')
const genId = require('./modules/gen-id')

module.exports = function (content) {
  this.cacheable()
  const isServer = this.options.target === 'node'
  const compiled = compiler.compile(content)
  const id = `data-v-${genId(this.resourcePath)}`

  // Acquire the query of target file
  const { style: stylePath } = querystring.parse(this.request.split('?').pop())

  compiled.errors.forEach(error => {
    this.emitError('template syntax error ' + error)
  })

  const transpiled = transpile(
    `var render = ${toFunction(compiled.render)}\n` +
    `var staticRenderFns = [${compiled.staticRenderFns.map(toFunction).join(',')}]`
  )

  const shouldHotReload = !isServer &&
    !this.minimize &&
    process.env.NODE_ENV !== 'production'

  let output = writeRenderCode(transpiled, id, stylePath)
  if (shouldHotReload) {
    output += writeHotReloadCode(id)
  }

  return output
}

function writeRenderCode (compiled, id, stylePath) {
  return [
    writeInjectStyle(stylePath, id),
    compiled,
    'module.exports = function (_exports) {',
    '  var options = _exports',
    '  if (typeof _exports === "function") options = _exports.options',
    `  ${writeInjectScopedId(stylePath, id)}`,
    '  options.render = render',
    '  options.staticRenderFns = staticRenderFns',
    '  if (module.hot && api) {',
    `    api.createRecord("${id}", options)`,
    '  }',
    '  return _exports',
    '}\n'
  ].join('\n')
}

function writeInjectStyle (stylePath, id) {
  const loaderPath = path.resolve(__dirname, 'scoped-style-loader.js')
  return stylePath
    ? `require('!!style-loader!css-loader!${loaderPath}?id=${id}!${stylePath}')`
    : ''
}

function writeInjectScopedId (isScoped, id) {
  return isScoped
    ? `options._scopeId = '${id}'`
    : ''
}

function writeHotReloadCode (id) {
  return [
    'var api = null',
    'if (module.hot) {(function () {',
    '  api = require("vue-hot-reload-api")',
    '  api.install(require("vue"))',
    '  if (!api.compatible) return',
    '  module.hot.accept()',
    '  if (module.hot.data) {',
    `    api.rerender("${id}", { render: render, staticRenderFns: staticRenderFns })`,
    '  }',
    '})()}\n'
  ].join('\n')
}

function toFunction (code) {
  return `function(){${code}}`
}
<|endoftext|>


<commit_before>var TodoAx = function() {
};

_.extend(TodoAx.prototype, {
  inlineLabel: function($elem, labelText) {
    $elem.attr('aria-label', labelText);
  },

  label: function($elem, labelText, labelId) {
    $elem.$label = $('<label>', {
      id: labelId || 'AX-lbl--' + $elem.attr('id'),
      text: $.isFunction(labelText) ? labelText($elem) : labelText,
      'aria-role': 'label',
    });
    this.getLabelsContainer().append($elem.$label);

    $elem.attr('aria-labelledby', $elem.$label.attr('id'));
  },

  getLabelsContainer: function() {
    if (!this.$labelsContainer) {
      this.$labelsContainer = $('<div>', {
        id: 'AX-container--labels',
        css: {
          display: 'none'
        }
      });
      $('body').append(this.$labelsContainer);
    }
    return this.$labelsContainer;
  },

  placeholders: function() {
    var $newTodoField = $('#new-todo');
    this.label($newTodoField, $newTodoField.attr('placeholder'));
  },

  todoPronunciation: function() {
    // TODO VO speaks h1 content instead of label
    var $title = $('.title h1');
    this.inlineLabel($title, 'To Dos');
  },

  todoList: function() {
    this.label($('#todo-list'), 'tasks');
  }

});

$(function() {
  var todoAx = new TodoAx;
  todoAx.placeholders();
  // todoAx.todoPronunciation();
  todoAx.todoList();
});<commit_msg>renamed task list<commit_after>var TodoAx = function() {
};

_.extend(TodoAx.prototype, {
  inlineLabel: function($elem, labelText) {
    $elem.attr('aria-label', labelText);
  },

  label: function($elem, labelText, labelId) {
    $elem.$label = $('<label>', {
      id: labelId || 'AX-lbl--' + $elem.attr('id'),
      text: $.isFunction(labelText) ? labelText($elem) : labelText,
      'aria-role': 'label',
    });
    this.getLabelsContainer().append($elem.$label);

    $elem.attr('aria-labelledby', $elem.$label.attr('id'));
  },

  getLabelsContainer: function() {
    if (!this.$labelsContainer) {
      this.$labelsContainer = $('<div>', {
        id: 'AX-container--labels',
        css: {
          display: 'none'
        }
      });
      $('body').append(this.$labelsContainer);
    }
    return this.$labelsContainer;
  },

  placeholders: function() {
    var $newTodoField = $('#new-todo');
    this.label($newTodoField, $newTodoField.attr('placeholder'));
  },

  todoPronunciation: function() {
    // TODO VO speaks h1 content instead of label
    var $title = $('.title h1');
    this.inlineLabel($title, 'To Dos');
  },

  taskList: function() {
    this.label($('#todo-list'), 'tasks');
  }
});

$(function() {
  var todoAx = new TodoAx;
  todoAx.placeholders();
  // todoAx.todoPronunciation();
  todoAx.taskList();
});<|endoftext|>


<commit_before>var express = require('express');
var path = require('path');
var logger = require('morgan');
var bodyParser = require('body-parser');

var app = express();

app.set('port', process.env.PORT || 3000);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));

app.get('/foo', function(req, res) {
  res.send('FOO BAR');
});

app.listen(app.get('port'), function() {
  console.log('Express server listening on port ' + app.get('port'));
});<commit_msg>added back-end code from the previous newedenfaces repo<commit_after>var express = require('express');
var path = require('path');
var logger = require('morgan');
var bodyParser = require('body-parser');
var async = require('async');
var mongoose = require('mongoose');
var request = require('request');
var xml2js = require('xml2js');

var app = express();

mongoose.connect('localhost');

var Character = mongoose.model('Character', {
  characterId: { type: String, unique: true, index: true },
  name: String,
  race: String,
  gender: String,
  wrongGender: Boolean,
  bloodline: String,
  wins: { type: Number, default: 0 },
  losses: { type: Number, default: 0 },
  reports: { type: Number, default: 0 },
  random: { type: [Number], index: '2d' },
  voted: { type: Boolean, default: false }
});

app.set('port', process.env.PORT || 3000);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));

/**
 * GET /api/characters
 * Returns two random characters.
 */
app.get('/api/characters', function(req, res, next) {
  var choices = { 0: 'female', 1: 'male' };
  var randomGender = choices[Math.round(Math.random())];

  Character
    .find({ random: { $near: [Math.random(), 0] } })
    .where('voted', false)
    .where('gender', randomGender)
    .limit(2)
    .exec(function(err, characters) {
      if (err) return next(err);

      // When there are no more character pairs given by randomGender,
      // check if there are character pairs of the opposite gender
      if (characters.length < 2) {
        var oppositeRandomGender = randomGender === 'female' ? 'male' : 'female';
        Character
          .find({ random: { $near: [Math.random(), 0] } })
          .where('voted', false)
          .where('gender', oppositeRandomGender)
          .limit(2)
          .exec(function(err, characters) {
            if (err) return next(err);
            // When there are no character pairs left of either gender,
            // reset voted flags, and start the next round
            if (characters.length < 2) {
              Character.update({}, { $set: { voted: false } }, { multi: true }, function(err) {
                if (err) return next(err);
                res.send([]);
              });
            } else {
              res.send(characters);
            }
          });
      } else {
        res.send(characters);
      }
    });
});

/**
 * POST /report
 * Reports a character.
 */
app.post('/api/report', function(req, res, next) {
  var characterId = req.body.characterId;

  Character.findOne({ characterId: characterId }, function(err, character) {
    if (err) return next(err);
    if (!character) return res.send(404, { message: 'Character Not Found' });
    character.reports++;
    if (character.reports > 4) {
      character.remove();
      return res.send({ message: 'Character has been deleted' });
    }
    character.save(function(err) {
      if (err) return next(err);
      res.send(200, { message: character.name + ' has been reported' });
    });
  });
});

/**
 * POST /report/gender
 * @param characterId
 * Marks a character with a wrong gender flag
 */
app.post('/api/report/gender', function(req, res, next) {
  Character.findOne({ characterId: req.body.characterId }, function(err, character) {
    if (err) return next(err);
    if (!character) return res.send(404, { message: 'Character Not Found' });
    character.wrongGender = true;
    character.save(function(err) {
      if (err) return next(err);
      res.send(200, { message: character.name + ' has been flagged' });
    });
  });
});

/**
 * PUT /api/vote
 * @param winner
 * @param loser
 * Update winning and losing count for characters
 */
app.put('/api/characters', function(req, res, next) {
  if (!req.body.winner || !req.body.loser) return res.send(400, { message: 'Voting requires two characters' });
  if (req.body.winner === req.body.loser) return res.send(400, { message: 'Cannot vote for and against the same character' });
  Character.findOne({ characterId: req.body.winner }, function(err, winner) {
    if (err) return next(err);
    Character.findOne({ characterId: req.body.loser }, function(err, loser) {
      if (err) return next(err);
      if (!winner || !loser) return res.send(404, { message: 'One of the characters no longer exists' });
      if (winner.voted || loser.voted) return res.send(200);
      async.parallel([
        function(callback) {
          winner.wins++;
          winner.voted = true;
          winner.random = [Math.random(), 0];
          winner.save(function(err) {
            callback(err);
          });
        },
        function(callback) {
          loser.losses++;
          loser.voted = true;
          loser.random = [Math.random(), 0];
          loser.save(function(err) {
            callback(err);
          });
        }
      ], function(err) {
        if (err) return next(err);
        res.send(200);
      });
    });
  });
});

/**
 * GET /api/characters/shame
 * Return 100 lowest ranked characters for hall of shame
 */
app.get('/api/characters/shame', function(req, res, next) {
  Character
    .find()
    .sort('-losses')
    .limit(100)
    .exec(function(err, characters) {
      if (err) return next(err);
      res.send(characters);
    });
});

/**
 * GET /delete/:id
 * Delete a character
 */
//app.get('/delete/:id', function(req, res) {
//  var id = req.params.id;
//  Character.remove({ characterId: id}, function(err, status) {
//    console.log(err, status);
//  });
//});

/**
 * GET /characters/new
 * Return 100 new characters
 */
app.get('/api/characters/new', function(req, res, next) {
  Character
    .find()
    .sort({ _id: -1 })
    .limit(100)
    .exec(function(err, characters) {
      if (err) return next(err);
      res.send(characters);
    });
});

/**
 * GET /browse
 * @param page
 */
app.get('/api/browse', function(req, res, next) {
  var page = req.query.currentPage;
  Character
    .find()
    .limit(30)
    .skip(page * 30)
    .exec(function(err, characters) {
      if (err) return next(err);
      res.send(characters);
    });
});

/**
 * GET /characters/top
 * Return 100 highest ranked characters
 * Filter gender, race, bloodline by a querystring
 */
app.get('/api/characters/top', function(req, res, next) {
  var conditions = {};
  for (var key in req.query) {
    if (req.query.hasOwnProperty(key)) {
      conditions[key] = new RegExp('^' + req.query[key] + '$', 'i');
    }
  }
  Character
    .find(conditions)
    .sort('-wins')
    .limit(150)
    .exec(function(err, characters) {
      if (err) return next(err);
      characters.sort(function(a, b) {
        if (a.wins / (a.wins + a.losses) < b.wins / (b.wins + b.losses)) return 1;
        if (a.wins / (a.wins + a.losses) > b.wins / (b.wins + b.losses)) return -1;
        return 0;
      });
      res.send(characters.slice(0, 100));
    });
});

/**
 * GET /leaderboard
 * Return 12 characters sorted by the winning percentage
 */
app.get('/api/leaderboard', function(req, res, next) {
  Character
    .find()
    .sort('-wins')
    .limit(18)
    .lean()
    .exec(function(err, characters) {
      if (err) return next(err);
      characters.sort(function(a, b) {
        if (a.wins / (a.wins + a.losses) < b.wins / (b.wins + b.losses)) return 1;
        if (a.wins / (a.wins + a.losses) > b.wins / (b.wins + b.losses)) return -1;
        return 0;
      });
      res.send(characters.slice(0, 12));
    });
});

/**
 * GET /characters/all
 * Returns a total # of characters in the DB
 */
app.get('/api/characters/all', function(req, res, next) {
  Character.count({}, function(err, count) {
    if (err) return next(err);
    res.send({ count: count });
  });
});

/**
 * POST /characters/search
 * @param name
 * Character search
 */
app.post('/api/characters/search', function(req, res, next) {
  var characterName = new RegExp(req.body.name, 'i');
  Character.findOne({ name: characterName }, function(err, character) {
    if (err) return next(err);
    if (character) {
      res.send(character);
    } else {
      res.send({});
    }
  });
});

/**
 * GET /characters/wrong-gender
 * Display characters marked as Wrong Gender
 */
app.get('/api/characters/wrong-gender', function(req, res, next) {
  Character.where('wrongGender', true).exec(function(err, characters) {
    if (err) return next(err);
    res.send(characters);
  });
});

/**
 * GET /characters/:id
 * @param id
 * Return detailed character information
 */
app.get('/api/characters/:id', function(req, res, next) {
  Character.findOne({ characterId: req.params.id }, function(err, character) {
    if (err) return next(err);
    if (character) {
      res.send(character);
    } else {
      res.send(404, { message: 'Character Not Found' });
    }
  });
});

/**
 * POST /api/characters
 * Add new character
 */
app.post('/api/characters', function(req, res, next) {
  var gender = req.body.gender;
  var parser = new xml2js.Parser();
  var characterName = decodeURIComponent(req.body.name || '');
  var characterIdUrl = 'https://api.eveonline.com/eve/CharacterID.xml.aspx?names=' + characterName;

  async.waterfall([
    function(callback) {
      request.get(characterIdUrl, function(e, r, xml) {
        if (e) return next(e);
        parser.parseString(xml, function(err, parsedXml) {
          if (err) return next(err);
          try {
            var characterId = parsedXml.eveapi.result[0].rowset[0].row[0].$.characterID;
            Character.findOne({ characterId: characterId }, function(err, character) {
              if (character) return res.send(409, { characterId: character.characterId });
              callback(err, characterId);
            });
          } catch (e) {
            return res.send(404, { message: 'Character Not Found' });
          }

        });
      });
    },
    function(characterId, callback) {
      var characterInfoUrl = 'https://api.eveonline.com/eve/CharacterInfo.xml.aspx?characterID=' + characterId;
      request.get({ url: characterInfoUrl }, function(e, r, xml) {
        if (e) return next(e);
        parser.parseString(xml, function(err, parsedXml) {
          if (err) return res.send(err);
          try {
            var name = parsedXml.eveapi.result[0].characterName[0];
            var race = parsedXml.eveapi.result[0].race[0];
            var bloodline = parsedXml.eveapi.result[0].bloodline[0];

            var character = new Character({
              characterId: characterId,
              name: name,
              race: race,
              bloodline: bloodline,
              gender: gender,
              random: [Math.random(), 0]
            });
            character.save(function(err) {
              if (err) return next(err);
              res.send(character);
            });
            callback(null);
          } catch (e) {
            return res.send(404, { message: 'Character Not Found' });
          }

        });
      });
    }
  ]);
});

/**
 * GET /api/stats
 * Display DB statistics
 */
app.get('/api/stats', function(req, res, next) {
  async.parallel([
      function(callback) {
        Character.count({}, function(err, count) {
          callback(err, count);
        });
      },
      function(callback) {
        Character.count({ race: 'Amarr' }, function(err, amarrCount) {
          callback(err, amarrCount);
        });
      },
      function(callback) {
        Character.count({ race: 'Caldari' }, function(err, caldariCount) {
          callback(err, caldariCount);
        });
      },
      function(callback) {
        Character.count({ race: 'Gallente' }, function(err, gallenteCount) {
          callback(err, gallenteCount);
        });
      },
      function(callback) {
        Character.count({ race: 'Minmatar' }, function(err, minmatarCount) {
          callback(err, minmatarCount);
        });
      },
      function(callback) {
        // Total males
        Character.count({ gender: 'male' }, function(err, maleCount) {
          callback(err, maleCount);
        });
      },
      function(callback) {
        // Total females
        Character.count({ gender: 'female' }, function(err, femaleCount) {
          callback(err, femaleCount);
        });
      },
      function(callback) {
        // Total votes cast
        Character.aggregate(
          { $group: { _id: null, total: { $sum: '$wins' } } },
          function(err, winsCount) {
            callback(err, winsCount[0].total);
          }
        );
      },
      function(callback) {
        // Race count in Top 100
        Character
          .find()
          .sort('-wins')
          .limit(100)
          .select('race')
          .exec(function(err, characters) {
            if (err) return next(err);
            var raceCount = _.countBy(characters, function(character) {
              return character.race;
            });
            var max = _.max(raceCount, function(race) {
              return race
            });
            var inverted = _.invert(raceCount);
            var topRace = inverted[max];
            var topCount = raceCount[topRace];
            callback(err, { race: topRace, count: topCount });
          });
      },
      function(callback) {
        // Race count in Top 100
        Character
          .find()
          .sort('-wins')
          .limit(100)
          .select('bloodline')
          .exec(function(err, characters) {
            if (err) return next(err);
            var bloodlineCount = _.countBy(characters, function(character) {
              return character.bloodline;
            });
            var max = _.max(bloodlineCount, function(bloodline) {
              return bloodline
            });
            var inverted = _.invert(bloodlineCount);
            var topBloodline = inverted[max];
            var topCount = bloodlineCount[topBloodline];
            callback(err, { bloodline: topBloodline, count: topCount });
          });
      }
    ],
    function(err, results) {
      if (err) return next(err);
      var totalCount = results[0];
      var amarrCount = results[1];
      var caldariCount = results[2];
      var gallenteCount = results[3];
      var minmatarCount = results[4];
      var maleCount = results[5];
      var femaleCount = results[6];
      var totalVotes = results[7];
      var leadingRace = results[8];
      var leadingBloodline = results[9];

      res.send({
        totalCount: totalCount,
        amarrCount: amarrCount,
        caldariCount: caldariCount,
        gallenteCount: gallenteCount,
        minmatarCount: minmatarCount,
        maleCount: maleCount,
        femaleCount: femaleCount,
        totalVotes: totalVotes,
        leadingRace: leadingRace,
        leadingBloodline: leadingBloodline
      });
    });
});

/**
 * POST /api/gender
 * @param characterId
 * @param gender
 * Update character's gender
 */
app.post('/api/gender', function(req, res, next) {
  var characterId = req.body.characterId;
  var gender = req.body.gender;
  Character.findOne({ characterId: characterId }, function(err, character) {
    if (err) return next(err);
    if (!character) return res.send(404);
    character.gender = gender;
    character.wrongGender = false;
    character.save(function(err) {
      if (err) return next(err);
      res.send(200);
    });
  });
});

app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.send({ message: err.message });
});

app.listen(app.get('port'), function() {
  console.log('Express server listening on port ' + app.get('port'));
});<|endoftext|>


<commit_before>(function(undefined) {
    'use strict';

    module.exports = {
        getContentsFromFile: function(file, callback) {
            var reader = new FileReader();
            reader.onload = function(e) {
                return callback(undefined, e.target.result);
            };
            reader.readAsBinaryString(file);
        },

        getContentsFromUrl: function(url, callback) {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', url, true);
            xhr.overrideMimeType('text/plain; charset=x-user-defined');
            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4) {
                    callback(undefined, xhr.responseText);
                }
            };
            xhr.send(null);
        }
    };

})();
<commit_msg>Altered the coding style of the browser readers abstraction<commit_after>'use strict';

exports.getContentsFromFile = function(file, callback) {
    var reader = new FileReader();
    reader.onload = function(e) {
        return callback(undefined, e.target.result);
    };
    reader.readAsBinaryString(file);
};

exports.getContentsFromUrl = function(url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.overrideMimeType('text/plain; charset=x-user-defined');
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            callback(undefined, xhr.responseText);
        }
    };
    xhr.send(null);
};
<|endoftext|>