<commit_before>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2018 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var BlendModes = require('../../renderer/BlendModes');

/**
 * Provides methods used for setting the blend mode of a Game Object.
 * Should be applied as a mixin and not used directly.
 *
 * @name Phaser.GameObjects.Components.BlendMode
 * @since 3.0.0
 */

var BlendMode = {

    _blendMode: BlendModes.NORMAL,

    /**
     * Sets the Blend Mode being used by this Game Object.
     *
     * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay)
     *
     * Under WebGL only the following Blend Modes are available:
     *
     * * ADD
     * * MULTIPLY
     * * SCREEN
     *
     * Canvas has more available depending on browser support.
     *
     * You can also create your own custom Blend Modes in WebGL.
     *
     * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending
     * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these
     * reasons try to be careful about the construction of your Scene and the frequency of which blend modes
     * are used.
     *
     * @name Phaser.GameObjects.Components.BlendMode#blendMode
     * @type {integer|string}
     * @since 3.0.0
     */
    blendMode: {

        get: function ()
        {
            return this._blendMode;
        },

        set: function (value)
        {
            if (typeof value === 'string')
            {
                value = BlendModes[value];
            }

            value | 0;

            if (value >= 0)
            {
                this._blendMode = value;
            }
        }

    },

    /**
     * Sets the Blend Mode being used by this Game Object.
     *
     * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay)
     *
     * Under WebGL only the following Blend Modes are available:
     *
     * * ADD
     * * MULTIPLY
     * * SCREEN
     *
     * Canvas has more available depending on browser support.
     *
     * You can also create your own custom Blend Modes in WebGL.
     *
     * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending
     * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these
     * reasons try to be careful about the construction of your Scene and the frequency of which blend modes
     * are used.
     *
     * @method Phaser.GameObjects.Components.BlendMode#setBlendMode
     * @since 3.0.0
     *
     * @param {string|integer} value - The BlendMode value. Either a string or a CONST.
     *
     * @return {Phaser.GameObjects.GameObject} This Game Object instance.
     */
    setBlendMode: function (value)
    {
        this.blendMode = value;

        return this;
    }

};

module.exports = BlendMode;
<commit_msg>Actually round the value.<commit_after>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2018 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var BlendModes = require('../../renderer/BlendModes');

/**
 * Provides methods used for setting the blend mode of a Game Object.
 * Should be applied as a mixin and not used directly.
 *
 * @name Phaser.GameObjects.Components.BlendMode
 * @since 3.0.0
 */

var BlendMode = {

    _blendMode: BlendModes.NORMAL,

    /**
     * Sets the Blend Mode being used by this Game Object.
     *
     * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay)
     *
     * Under WebGL only the following Blend Modes are available:
     *
     * * ADD
     * * MULTIPLY
     * * SCREEN
     *
     * Canvas has more available depending on browser support.
     *
     * You can also create your own custom Blend Modes in WebGL.
     *
     * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending
     * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these
     * reasons try to be careful about the construction of your Scene and the frequency of which blend modes
     * are used.
     *
     * @name Phaser.GameObjects.Components.BlendMode#blendMode
     * @type {integer|string}
     * @since 3.0.0
     */
    blendMode: {

        get: function ()
        {
            return this._blendMode;
        },

        set: function (value)
        {
            if (typeof value === 'string')
            {
                value = BlendModes[value];
            }

            value |= 0;

            if (value >= 0)
            {
                this._blendMode = value;
            }
        }

    },

    /**
     * Sets the Blend Mode being used by this Game Object.
     *
     * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay)
     *
     * Under WebGL only the following Blend Modes are available:
     *
     * * ADD
     * * MULTIPLY
     * * SCREEN
     *
     * Canvas has more available depending on browser support.
     *
     * You can also create your own custom Blend Modes in WebGL.
     *
     * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending
     * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these
     * reasons try to be careful about the construction of your Scene and the frequency of which blend modes
     * are used.
     *
     * @method Phaser.GameObjects.Components.BlendMode#setBlendMode
     * @since 3.0.0
     *
     * @param {string|integer} value - The BlendMode value. Either a string or a CONST.
     *
     * @return {Phaser.GameObjects.GameObject} This Game Object instance.
     */
    setBlendMode: function (value)
    {
        this.blendMode = value;

        return this;
    }

};

module.exports = BlendMode;
<|endoftext|>


<commit_before>/*global QUnit*/

import Emblem from '../../emblem';
import { w } from '../support/utils';
import { compilesTo } from '../support/integration-assertions';

QUnit.module("html: single line");

QUnit.test("element only", function(){
  compilesTo("p", "

");
});

QUnit.test("with text", function(){
  compilesTo("p Hello", "
Hello
");
});

QUnit.test("with more complex text", function(){
  compilesTo(
    "p Hello, how's it going with you today?",
    "
Hello, how's it going with you today?
"
  );
});

QUnit.test("with trailing space", function(){
  compilesTo("p Hello   ", "
Hello
");
});

QUnit.test("can start with angle bracket html", function(){
  var emblem = "Hello";
  compilesTo(emblem, "Hello");
});

QUnit.module("html: multiple lines");

QUnit.test("two lines", function(){
  var emblem = w(
    "p This is",
    "  pretty cool."
  );
  compilesTo(emblem, "
This is pretty cool.
");
});

QUnit.test("three lines", function(){
  var emblem = w(
    "p This is",
    "  pretty damn",
    "  cool."
  );
  compilesTo(emblem, "
This is pretty damn cool.
");
});

QUnit.test("three lines w/ embedded html", function(){
  var emblem = w(
    "p This is",
    "  pretty damn",
    "  cool."
  );
  compilesTo(emblem, "
This is pretty damn cool.
");
});

QUnit.test("indentation doesn't need to match starting inline content's", function(){
  var emblem = w(
    "  span Hello,",
    "    How are you?"
  );
  compilesTo(emblem, "Hello, How are you?");
});

QUnit.test("indentation may vary between parent/child, must be consistent within inline-block", function(){
  var emblem = w(
    "div",
    "      span Hello,",
    "           How are you?",
    "           Excellent.",
    "      p asd"
  );
  compilesTo(emblem,
    "
Hello, How are you? Excellent.
asd

");

  emblem = w(
    "div",
    "  span Hello,",
    "       How are you?",
    "     Excellent."
  );
  QUnit.throws(function(){
    Emblem.compile(emblem);
  });
});

QUnit.test("indentation may vary between parent/child, must be consistent within inline-block pt 2", function(){
  var emblem = w(
    "div",
    "  span Hello,",
    "       How are you?",
    "       Excellent."
  );

  compilesTo(emblem,
    "
Hello, How are you? Excellent.
");
});

QUnit.test("w/ mustaches", function(){
  var emblem = w(
    "div",
    "  span Hello,",
    "       {{foo}} are you?",
    "       Excellent."
  );

  compilesTo(emblem,
    "
Hello, {{foo}} are you? Excellent.
");
});

QUnit.test("with followup", function(){
  var emblem = w(
    "p This is",
    "  pretty cool.",
    "p Hello."
  );
  compilesTo(emblem, "
This is pretty cool.

Hello.
");
});

QUnit.test("can start with angle bracket html and go to multiple lines", function(){
  var emblem = w(
    "Hello dude,",
    "      what's up?"
  );
  compilesTo(emblem, "Hello dude, what's up?");
});

QUnit.module("html: nested");

test("basic", function(){
  var emblem = w(
    "p",
    "  span Hello",
    "  strong Hi",
    "div",
    "  p Hooray"
  );
  compilesTo(emblem,
    '
HelloHi

Hooray

');
});

test("empty nest", function(){
  var emblem = w(
    "p",
    "  span",
    "    strong",
    "      i"
  );
  compilesTo(emblem, '

');
});

test("empty nest w/ attribute shorthand", function(){
  var emblem = w(
    "p.woo",
    "  span#yes",
    "    strong.no.yes",
    "      i"
  );
  compilesTo(emblem,
    '

');
});

QUnit.module("html: self-closing html tags");

test("br", function() {
  var emblem;
  emblem = "br";
  compilesTo(emblem, '
');
});

test("hr", function(assert) {
  var emblem;
  emblem = "hr";
  compilesTo(emblem, '
');
});

test("br paragraph example", function() {
  var emblem;
  emblem = "p\n  | LOL!\n  br\n  | BORF!";
  compilesTo(emblem, '
LOL!
BORF!
');
});

test("input", function() {
  var emblem;
  emblem = "input type=\"text\"";
  compilesTo(emblem, '<input type="text">');
});

test("nested content under self-closing tag should fail", function() {
  var emblem = "hr\n | here is text";
  QUnit.throws( function(){
    Emblem.compile(emblem);
  }, /cannot nest/i);
});
<commit_msg>Add a test for inline html tags after a bare element name<commit_after>/*global QUnit*/

import Emblem from '../../emblem';
import { w } from '../support/utils';
import { compilesTo } from '../support/integration-assertions';

QUnit.module("html: single line");

QUnit.test("element only", function(){
  compilesTo("p", "

");
});

QUnit.test("with text", function(){
  compilesTo("p Hello", "
Hello
");
});

QUnit.test("with more complex text", function(){
  compilesTo(
    "p Hello, how's it going with you today?",
    "
Hello, how's it going with you today?
"
  );
});

QUnit.test("with inline html", function(){
  compilesTo(
    "p Hello, how are you man",
    "
Hello, how are you man
"
  );
});

QUnit.test("with trailing space", function(){
  compilesTo("p Hello   ", "
Hello
");
});

QUnit.test("can start with angle bracket html", function(){
  var emblem = "Hello";
  compilesTo(emblem, "Hello");
});

QUnit.module("html: multiple lines");

QUnit.test("two lines", function(){
  var emblem = w(
    "p This is",
    "  pretty cool."
  );
  compilesTo(emblem, "
This is pretty cool.
");
});

QUnit.test("three lines", function(){
  var emblem = w(
    "p This is",
    "  pretty damn",
    "  cool."
  );
  compilesTo(emblem, "
This is pretty damn cool.
");
});

QUnit.test("three lines w/ embedded html", function(){
  var emblem = w(
    "p This is",
    "  pretty damn",
    "  cool."
  );
  compilesTo(emblem, "
This is pretty damn cool.
");
});

QUnit.test("indentation doesn't need to match starting inline content's", function(){
  var emblem = w(
    "  span Hello,",
    "    How are you?"
  );
  compilesTo(emblem, "Hello, How are you?");
});

QUnit.test("indentation may vary between parent/child, must be consistent within inline-block", function(){
  var emblem = w(
    "div",
    "      span Hello,",
    "           How are you?",
    "           Excellent.",
    "      p asd"
  );
  compilesTo(emblem,
    "
Hello, How are you? Excellent.
asd

");

  emblem = w(
    "div",
    "  span Hello,",
    "       How are you?",
    "     Excellent."
  );
  QUnit.throws(function(){
    Emblem.compile(emblem);
  });
});

QUnit.test("indentation may vary between parent/child, must be consistent within inline-block pt 2", function(){
  var emblem = w(
    "div",
    "  span Hello,",
    "       How are you?",
    "       Excellent."
  );

  compilesTo(emblem,
    "
Hello, How are you? Excellent.
");
});

QUnit.test("w/ mustaches", function(){
  var emblem = w(
    "div",
    "  span Hello,",
    "       {{foo}} are you?",
    "       Excellent."
  );

  compilesTo(emblem,
    "
Hello, {{foo}} are you? Excellent.
");
});

QUnit.test("with followup", function(){
  var emblem = w(
    "p This is",
    "  pretty cool.",
    "p Hello."
  );
  compilesTo(emblem, "
This is pretty cool.

Hello.
");
});

QUnit.test("can start with angle bracket html and go to multiple lines", function(){
  var emblem = w(
    "Hello dude,",
    "      what's up?"
  );
  compilesTo(emblem, "Hello dude, what's up?");
});

QUnit.module("html: nested");

test("basic", function(){
  var emblem = w(
    "p",
    "  span Hello",
    "  strong Hi",
    "div",
    "  p Hooray"
  );
  compilesTo(emblem,
    '
HelloHi

Hooray

');
});

test("empty nest", function(){
  var emblem = w(
    "p",
    "  span",
    "    strong",
    "      i"
  );
  compilesTo(emblem, '

');
});

test("empty nest w/ attribute shorthand", function(){
  var emblem = w(
    "p.woo",
    "  span#yes",
    "    strong.no.yes",
    "      i"
  );
  compilesTo(emblem,
    '

');
});

QUnit.module("html: self-closing html tags");

test("br", function() {
  var emblem;
  emblem = "br";
  compilesTo(emblem, '
');
});

test("hr", function(assert) {
  var emblem;
  emblem = "hr";
  compilesTo(emblem, '
');
});

test("br paragraph example", function() {
  var emblem;
  emblem = "p\n  | LOL!\n  br\n  | BORF!";
  compilesTo(emblem, '
LOL!
BORF!
');
});

test("input", function() {
  var emblem;
  emblem = "input type=\"text\"";
  compilesTo(emblem, '<input type="text">');
});

test("nested content under self-closing tag should fail", function() {
  var emblem = "hr\n | here is text";
  QUnit.throws( function(){
    Emblem.compile(emblem);
  }, /cannot nest/i);
});
<|endoftext|>


<commit_before>/**
  @module ember-data
*/

var get = Ember.get;

var errorProps = [
  'description',
  'fileName',
  'lineNumber',
  'message',
  'name',
  'number',
  'stack'
];

/**
  A `DS.InvalidError` is used by an adapter to signal the external API
  was unable to process a request because the content was not
  semantically correct or meaningful per the API. Usually this means a
  record failed some form of server side validation. When a promise
  from an adapter is rejected with a `DS.InvalidError` the record will
  transition to the `invalid` state and the errors will be set to the
  `errors` property on the record.

  This function should return the entire payload as received from the
  server.  Error object extraction and normalization of model errors
  should be performed by `extractErrors` on the serializer.

  Example

  ```javascript
  App.ApplicationAdapter = DS.RESTAdapter.extend({
    ajaxError: function(jqXHR) {
      var error = this._super(jqXHR);

      if (jqXHR && jqXHR.status === 422) {
        var jsonErrors = Ember.$.parseJSON(jqXHR.responseText);
        return new DS.InvalidError(jsonErrors);
      } else {
        return error;
      }
    }
  });
  ```

  The `DS.InvalidError` must be constructed with a single object whose
  keys are the invalid model properties, and whose values are the
  corresponding error messages. For example:

  ```javascript
  return new DS.InvalidError({
    length: 'Must be less than 15',
    name: 'Must not be blank
  });
  ```

  @class InvalidError
  @namespace DS
*/
function InvalidError(errors) {
  var tmp = Error.prototype.constructor.call(this, "The backend rejected the commit because it was invalid: " + Ember.inspect(errors));
  this.errors = errors;

  for (var i=0, l=errorProps.length; i<l; i++) {
    this[errorProps[i]] = tmp[errorProps[i]];
  }
}

InvalidError.prototype = Ember.create(Error.prototype);

/**
  An adapter is an object that receives requests from a store and
  translates them into the appropriate action to take against your
  persistence layer. The persistence layer is usually an HTTP API, but
  may be anything, such as the browser's local storage. Typically the
  adapter is not invoked directly instead its functionality is accessed
  through the `store`.

  ### Creating an Adapter

  Create a new subclass of `DS.Adapter`, then assign
  it to the `ApplicationAdapter` property of the application.

  ```javascript
  var MyAdapter = DS.Adapter.extend({
    // ...your code here
  });

  App.ApplicationAdapter = MyAdapter;
  ```

  Model-specific adapters can be created by assigning your adapter
  class to the `ModelName` + `Adapter` property of the application.

  ```javascript
  var MyPostAdapter = DS.Adapter.extend({
    // ...Post-specific adapter code goes here
  });

  App.PostAdapter = MyPostAdapter;
  ```

  `DS.Adapter` is an abstract base class that you should override in your
  application to customize it for your backend. The minimum set of methods
  that you should implement is:

    * `find()`
    * `createRecord()`
    * `updateRecord()`
    * `deleteRecord()`
    * `findAll()`
    * `findQuery()`

  To improve the network performance of your application, you can optimize
  your adapter by overriding these lower-level methods:

    * `findMany()`

  For an example implementation, see `DS.RESTAdapter`, the
  included REST adapter.

  @class Adapter
  @namespace DS
  @extends Ember.Object
*/

var Adapter = Ember.Object.extend({

  /**
    If you would like your adapter to use a custom serializer you can
    set the `defaultSerializer` property to be the name of the custom
    serializer.

    Note the `defaultSerializer` serializer has a lower priority than
    a model specific serializer (i.e. `PostSerializer`) or the
    `application` serializer.

    ```javascript
    var DjangoAdapter = DS.Adapter.extend({
      defaultSerializer: 'django'
    });
    ```

    @property defaultSerializer
    @type {String}
  */

  /**
    The `find()` method is invoked when the store is asked for a record that
    has not previously been loaded. In response to `find()` being called, you
    should query your persistence layer for a record with the given ID. Once
    found, you can asynchronously call the store's `push()` method to push
    the record into the store.

    Here is an example `find` implementation:

    ```javascript
    App.ApplicationAdapter = DS.Adapter.extend({
      find: function(store, type, id) {
        var url = [type.typeKey, id].join('/');

        return new Ember.RSVP.Promise(function(resolve, reject) {
          jQuery.getJSON(url).then(function(data) {
            Ember.run(null, resolve, data);
          }, function(jqXHR) {
            jqXHR.then = null; // tame jQuery's ill mannered promises
            Ember.run(null, reject, jqXHR);
          });
        });
      }
    });
    ```

    @method find
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {String} id
    @return {Promise} promise
  */
  find: Ember.required(Function),

  /**
    The `findAll()` method is called when you call `find` on the store
    without an ID (i.e. `store.find('post')`).

    Example

    ```javascript
    App.ApplicationAdapter = DS.Adapter.extend({
      findAll: function(store, type, sinceToken) {
        var url = type;
        var query = { since: sinceToken };
        return new Ember.RSVP.Promise(function(resolve, reject) {
          jQuery.getJSON(url, query).then(function(data) {
            Ember.run(null, resolve, data);
          }, function(jqXHR) {
            jqXHR.then = null; // tame jQuery's ill mannered promises
            Ember.run(null, reject, jqXHR);
          });
        });
      }
    });
    ```

    @private
    @method findAll
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {String} sinceToken
    @return {Promise} promise
  */
  findAll: null,

  /**
    This method is called when you call `find` on the store with a
    query object as the second parameter (i.e. `store.find('person', {
    page: 1 })`).

    Example

    ```javascript
    App.ApplicationAdapter = DS.Adapter.extend({
      findQuery: function(store, type, query) {
        var url = type;
        return new Ember.RSVP.Promise(function(resolve, reject) {
          jQuery.getJSON(url, query).then(function(data) {
            Ember.run(null, resolve, data);
          }, function(jqXHR) {
            jqXHR.then = null; // tame jQuery's ill mannered promises
            Ember.run(null, reject, jqXHR);
          });
        });
      }
    });
    ```

    @private
    @method findQuery
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {Object} query
    @param {DS.AdapterPopulatedRecordArray} recordArray
    @return {Promise} promise
  */
  findQuery: null,

  /**
    If the globally unique IDs for your records should be generated on the client,
    implement the `generateIdForRecord()` method. This method will be invoked
    each time you create a new record, and the value returned from it will be
    assigned to the record's `primaryKey`.

    Most traditional REST-like HTTP APIs will not use this method. Instead, the ID
    of the record will be set by the server, and your adapter will update the store
    with the new ID when it calls `didCreateRecord()`. Only implement this method if
    you intend to generate record IDs on the client-side.

    The `generateIdForRecord()` method will be invoked with the requesting store as
    the first parameter and the newly created record as the second parameter:

    ```javascript
    generateIdForRecord: function(store, record) {
      var uuid = App.generateUUIDWithStatisticallyLowOddsOfCollision();
      return uuid;
    }
    ```

    @method generateIdForRecord
    @param {DS.Store} store
    @param {DS.Model} record
    @return {String|Number} id
  */
  generateIdForRecord: null,

  /**
    Proxies to the serializer's `serialize` method.

    Example

    ```javascript
    App.ApplicationAdapter = DS.Adapter.extend({
      createRecord: function(store, type, record) {
        var data = this.serialize(record, { includeId: true });
        var url = type;

        // ...
      }
    });
    ```

    @method serialize
    @param {DS.Model} record
    @param {Object}   options
    @return {Object} serialized record
  */
  serialize: function(record, options) {
    return get(record, 'store').serializerFor(record.constructor.typeKey).serialize(record, options);
  },

  /**
    Implement this method in a subclass to handle the creation of
    new records.

    Serializes the record and send it to the server.

    Example

    ```javascript
    App.ApplicationAdapter = DS.Adapter.extend({
      createRecord: function(store, type, record) {
        var data = this.serialize(record, { includeId: true });
        var url = type;

        return new Ember.RSVP.Promise(function(resolve, reject) {
          jQuery.ajax({
            type: 'POST',
            url: url,
            dataType: 'json',
            data: data
          }).then(function(data) {
            Ember.run(null, resolve, data);
          }, function(jqXHR) {
            jqXHR.then = null; // tame jQuery's ill mannered promises
            Ember.run(null, reject, jqXHR);
          });
        });
      }
    });
    ```

    @method createRecord
    @param {DS.Store} store
    @param {subclass of DS.Model} type   the DS.Model class of the record
    @param {DS.Model} record
    @return {Promise} promise
  */
  createRecord: Ember.required(Function),

  /**
    Implement this method in a subclass to handle the updating of
    a record.

    Serializes the record update and send it to the server.

    Example

    ```javascript
    App.ApplicationAdapter = DS.Adapter.extend({
      updateRecord: function(store, type, record) {
        var data = this.serialize(record, { includeId: true });
        var id = record.get('id');
        var url = [type, id].join('/');

        return new Ember.RSVP.Promise(function(resolve, reject) {
          jQuery.ajax({
            type: 'PUT',
            url: url,
            dataType: 'json',
            data: data
          }).then(function(data) {
            Ember.run(null, resolve, data);
          }, function(jqXHR) {
            jqXHR.then = null; // tame jQuery's ill mannered promises
            Ember.run(null, reject, jqXHR);
          });
        });
      }
    });
    ```

    @method updateRecord
    @param {DS.Store} store
    @param {subclass of DS.Model} type   the DS.Model class of the record
    @param {DS.Model} record
    @return {Promise} promise
  */
  updateRecord: Ember.required(Function),

  /**
    Implement this method in a subclass to handle the deletion of
    a record.

    Sends a delete request for the record to the server.

    Example

    ```javascript
    App.ApplicationAdapter = DS.Adapter.extend({
      deleteRecord: function(store, type, record) {
        var data = this.serialize(record, { includeId: true });
        var id = record.get('id');
        var url = [type, id].join('/');

        return new Ember.RSVP.Promise(function(resolve, reject) {
          jQuery.ajax({
            type: 'DELETE',
            url: url,
            dataType: 'json',
            data: data
          }).then(function(data) {
            Ember.run(null, resolve, data);
          }, function(jqXHR) {
            jqXHR.then = null; // tame jQuery's ill mannered promises
            Ember.run(null, reject, jqXHR);
          });
        });
      }
    });
    ```

    @method deleteRecord
    @param {DS.Store} store
    @param {subclass of DS.Model} type   the DS.Model class of the record
    @param {DS.Model} record
    @return {Promise} promise
  */
  deleteRecord: Ember.required(Function),

  /**
    By default the store will try to coalesce all `fetchRecord` calls within the same runloop
    into as few requests as possible by calling groupRecordsForFindMany and passing it into a findMany call.
    You can opt out of this behaviour by either not implementing the findMany hook or by setting
    coalesceFindRequests to false

    @property coalesceFindRequests
    @type {boolean}
  */
  coalesceFindRequests: true,

  /**
    Find multiple records at once if coalesceFindRequests is true

    @method findMany
    @param {DS.Store} store
    @param {subclass of DS.Model} type   the DS.Model class of the records
    @param {Array}    ids
    @param {Array} records
    @return {Promise} promise
  */

  /**
    Organize records into groups, each of which is to be passed to separate
    calls to `findMany`.

    For example, if your api has nested URLs that depend on the parent, you will
    want to group records by their parent.

    The default implementation returns the records as a single group.

    @method groupRecordsForFindMany
    @param {DS.Store} store
    @param {Array} records
    @return {Array}  an array of arrays of records, each of which is to be
                      loaded separately by `findMany`.
  */
  groupRecordsForFindMany: function (store, records) {
    return [records];
  }
});

export {
  InvalidError,
  Adapter
};
export default Adapter;
<commit_msg>[DOCS] InvalidError docs missing quote<commit_after>/**
  @module ember-data
*/

var get = Ember.get;

var errorProps = [
  'description',
  'fileName',
  'lineNumber',
  'message',
  'name',
  'number',
  'stack'
];

/**
  A `DS.InvalidError` is used by an adapter to signal the external API
  was unable to process a request because the content was not
  semantically correct or meaningful per the API. Usually this means a
  record failed some form of server side validation. When a promise
  from an adapter is rejected with a `DS.InvalidError` the record will
  transition to the `invalid` state and the errors will be set to the
  `errors` property on the record.

  This function should return the entire payload as received from the
  server.  Error object extraction and normalization of model errors
  should be performed by `extractErrors` on the serializer.

  Example

  ```javascript
  App.ApplicationAdapter = DS.RESTAdapter.extend({
    ajaxError: function(jqXHR) {
      var error = this._super(jqXHR);

      if (jqXHR && jqXHR.status === 422) {
        var jsonErrors = Ember.$.parseJSON(jqXHR.responseText);
        return new DS.InvalidError(jsonErrors);
      } else {
        return error;
      }
    }
  });
  ```

  The `DS.InvalidError` must be constructed with a single object whose
  keys are the invalid model properties, and whose values are the
  corresponding error messages. For example:

  ```javascript
  return new DS.InvalidError({
    length: 'Must be less than 15',
    name: 'Must not be blank'
  });
  ```

  @class InvalidError
  @namespace DS
*/
function InvalidError(errors) {
  var tmp = Error.prototype.constructor.call(this, "The backend rejected the commit because it was invalid: " + Ember.inspect(errors));
  this.errors = errors;

  for (var i=0, l=errorProps.length; i<l; i++) {
    this[errorProps[i]] = tmp[errorProps[i]];
  }
}

InvalidError.prototype = Ember.create(Error.prototype);

/**
  An adapter is an object that receives requests from a store and
  translates them into the appropriate action to take against your
  persistence layer. The persistence layer is usually an HTTP API, but
  may be anything, such as the browser's local storage. Typically the
  adapter is not invoked directly instead its functionality is accessed
  through the `store`.

  ### Creating an Adapter

  Create a new subclass of `DS.Adapter`, then assign
  it to the `ApplicationAdapter` property of the application.

  ```javascript
  var MyAdapter = DS.Adapter.extend({
    // ...your code here
  });

  App.ApplicationAdapter = MyAdapter;
  ```

  Model-specific adapters can be created by assigning your adapter
  class to the `ModelName` + `Adapter` property of the application.

  ```javascript
  var MyPostAdapter = DS.Adapter.extend({
    // ...Post-specific adapter code goes here
  });

  App.PostAdapter = MyPostAdapter;
  ```

  `DS.Adapter` is an abstract base class that you should override in your
  application to customize it for your backend. The minimum set of methods
  that you should implement is:

    * `find()`
    * `createRecord()`
    * `updateRecord()`
    * `deleteRecord()`
    * `findAll()`
    * `findQuery()`

  To improve the network performance of your application, you can optimize
  your adapter by overriding these lower-level methods:

    * `findMany()`

  For an example implementation, see `DS.RESTAdapter`, the
  included REST adapter.

  @class Adapter
  @namespace DS
  @extends Ember.Object
*/

var Adapter = Ember.Object.extend({

  /**
    If you would like your adapter to use a custom serializer you can
    set the `defaultSerializer` property to be the name of the custom
    serializer.

    Note the `defaultSerializer` serializer has a lower priority than
    a model specific serializer (i.e. `PostSerializer`) or the
    `application` serializer.

    ```javascript
    var DjangoAdapter = DS.Adapter.extend({
      defaultSerializer: 'django'
    });
    ```

    @property defaultSerializer
    @type {String}
  */

  /**
    The `find()` method is invoked when the store is asked for a record that
    has not previously been loaded. In response to `find()` being called, you
    should query your persistence layer for a record with the given ID. Once
    found, you can asynchronously call the store's `push()` method to push
    the record into the store.

    Here is an example `find` implementation:

    ```javascript
    App.ApplicationAdapter = DS.Adapter.extend({
      find: function(store, type, id) {
        var url = [type.typeKey, id].join('/');

        return new Ember.RSVP.Promise(function(resolve, reject) {
          jQuery.getJSON(url).then(function(data) {
            Ember.run(null, resolve, data);
          }, function(jqXHR) {
            jqXHR.then = null; // tame jQuery's ill mannered promises
            Ember.run(null, reject, jqXHR);
          });
        });
      }
    });
    ```

    @method find
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {String} id
    @return {Promise} promise
  */
  find: Ember.required(Function),

  /**
    The `findAll()` method is called when you call `find` on the store
    without an ID (i.e. `store.find('post')`).

    Example

    ```javascript
    App.ApplicationAdapter = DS.Adapter.extend({
      findAll: function(store, type, sinceToken) {
        var url = type;
        var query = { since: sinceToken };
        return new Ember.RSVP.Promise(function(resolve, reject) {
          jQuery.getJSON(url, query).then(function(data) {
            Ember.run(null, resolve, data);
          }, function(jqXHR) {
            jqXHR.then = null; // tame jQuery's ill mannered promises
            Ember.run(null, reject, jqXHR);
          });
        });
      }
    });
    ```

    @private
    @method findAll
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {String} sinceToken
    @return {Promise} promise
  */
  findAll: null,

  /**
    This method is called when you call `find` on the store with a
    query object as the second parameter (i.e. `store.find('person', {
    page: 1 })`).

    Example

    ```javascript
    App.ApplicationAdapter = DS.Adapter.extend({
      findQuery: function(store, type, query) {
        var url = type;
        return new Ember.RSVP.Promise(function(resolve, reject) {
          jQuery.getJSON(url, query).then(function(data) {
            Ember.run(null, resolve, data);
          }, function(jqXHR) {
            jqXHR.then = null; // tame jQuery's ill mannered promises
            Ember.run(null, reject, jqXHR);
          });
        });
      }
    });
    ```

    @private
    @method findQuery
    @param {DS.Store} store
    @param {subclass of DS.Model} type
    @param {Object} query
    @param {DS.AdapterPopulatedRecordArray} recordArray
    @return {Promise} promise
  */
  findQuery: null,

  /**
    If the globally unique IDs for your records should be generated on the client,
    implement the `generateIdForRecord()` method. This method will be invoked
    each time you create a new record, and the value returned from it will be
    assigned to the record's `primaryKey`.

    Most traditional REST-like HTTP APIs will not use this method. Instead, the ID
    of the record will be set by the server, and your adapter will update the store
    with the new ID when it calls `didCreateRecord()`. Only implement this method if
    you intend to generate record IDs on the client-side.

    The `generateIdForRecord()` method will be invoked with the requesting store as
    the first parameter and the newly created record as the second parameter:

    ```javascript
    generateIdForRecord: function(store, record) {
      var uuid = App.generateUUIDWithStatisticallyLowOddsOfCollision();
      return uuid;
    }
    ```

    @method generateIdForRecord
    @param {DS.Store} store
    @param {DS.Model} record
    @return {String|Number} id
  */
  generateIdForRecord: null,

  /**
    Proxies to the serializer's `serialize` method.

    Example

    ```javascript
    App.ApplicationAdapter = DS.Adapter.extend({
      createRecord: function(store, type, record) {
        var data = this.serialize(record, { includeId: true });
        var url = type;

        // ...
      }
    });
    ```

    @method serialize
    @param {DS.Model} record
    @param {Object}   options
    @return {Object} serialized record
  */
  serialize: function(record, options) {
    return get(record, 'store').serializerFor(record.constructor.typeKey).serialize(record, options);
  },

  /**
    Implement this method in a subclass to handle the creation of
    new records.

    Serializes the record and send it to the server.

    Example

    ```javascript
    App.ApplicationAdapter = DS.Adapter.extend({
      createRecord: function(store, type, record) {
        var data = this.serialize(record, { includeId: true });
        var url = type;

        return new Ember.RSVP.Promise(function(resolve, reject) {
          jQuery.ajax({
            type: 'POST',
            url: url,
            dataType: 'json',
            data: data
          }).then(function(data) {
            Ember.run(null, resolve, data);
          }, function(jqXHR) {
            jqXHR.then = null; // tame jQuery's ill mannered promises
            Ember.run(null, reject, jqXHR);
          });
        });
      }
    });
    ```

    @method createRecord
    @param {DS.Store} store
    @param {subclass of DS.Model} type   the DS.Model class of the record
    @param {DS.Model} record
    @return {Promise} promise
  */
  createRecord: Ember.required(Function),

  /**
    Implement this method in a subclass to handle the updating of
    a record.

    Serializes the record update and send it to the server.

    Example

    ```javascript
    App.ApplicationAdapter = DS.Adapter.extend({
      updateRecord: function(store, type, record) {
        var data = this.serialize(record, { includeId: true });
        var id = record.get('id');
        var url = [type, id].join('/');

        return new Ember.RSVP.Promise(function(resolve, reject) {
          jQuery.ajax({
            type: 'PUT',
            url: url,
            dataType: 'json',
            data: data
          }).then(function(data) {
            Ember.run(null, resolve, data);
          }, function(jqXHR) {
            jqXHR.then = null; // tame jQuery's ill mannered promises
            Ember.run(null, reject, jqXHR);
          });
        });
      }
    });
    ```

    @method updateRecord
    @param {DS.Store} store
    @param {subclass of DS.Model} type   the DS.Model class of the record
    @param {DS.Model} record
    @return {Promise} promise
  */
  updateRecord: Ember.required(Function),

  /**
    Implement this method in a subclass to handle the deletion of
    a record.

    Sends a delete request for the record to the server.

    Example

    ```javascript
    App.ApplicationAdapter = DS.Adapter.extend({
      deleteRecord: function(store, type, record) {
        var data = this.serialize(record, { includeId: true });
        var id = record.get('id');
        var url = [type, id].join('/');

        return new Ember.RSVP.Promise(function(resolve, reject) {
          jQuery.ajax({
            type: 'DELETE',
            url: url,
            dataType: 'json',
            data: data
          }).then(function(data) {
            Ember.run(null, resolve, data);
          }, function(jqXHR) {
            jqXHR.then = null; // tame jQuery's ill mannered promises
            Ember.run(null, reject, jqXHR);
          });
        });
      }
    });
    ```

    @method deleteRecord
    @param {DS.Store} store
    @param {subclass of DS.Model} type   the DS.Model class of the record
    @param {DS.Model} record
    @return {Promise} promise
  */
  deleteRecord: Ember.required(Function),

  /**
    By default the store will try to coalesce all `fetchRecord` calls within the same runloop
    into as few requests as possible by calling groupRecordsForFindMany and passing it into a findMany call.
    You can opt out of this behaviour by either not implementing the findMany hook or by setting
    coalesceFindRequests to false

    @property coalesceFindRequests
    @type {boolean}
  */
  coalesceFindRequests: true,

  /**
    Find multiple records at once if coalesceFindRequests is true

    @method findMany
    @param {DS.Store} store
    @param {subclass of DS.Model} type   the DS.Model class of the records
    @param {Array}    ids
    @param {Array} records
    @return {Promise} promise
  */

  /**
    Organize records into groups, each of which is to be passed to separate
    calls to `findMany`.

    For example, if your api has nested URLs that depend on the parent, you will
    want to group records by their parent.

    The default implementation returns the records as a single group.

    @method groupRecordsForFindMany
    @param {DS.Store} store
    @param {Array} records
    @return {Array}  an array of arrays of records, each of which is to be
                      loaded separately by `findMany`.
  */
  groupRecordsForFindMany: function (store, records) {
    return [records];
  }
});

export {
  InvalidError,
  Adapter
};
export default Adapter;
<|endoftext|>


<commit_before>import { mount } from '@vue/test-utils'
import Octicon from '../lib/main.js'

describe('Octicon component', () => {
  const icon = require('octicons-modular/lib/icons/zap')

  test('valid', () => {
    const wrapper = mount(Octicon, {
      context: {
        props: { icon }
      }
    })

    expect(wrapper.html()).toMatchSnapshot()
  })

  test('scalable', () => {
    const wrapper = mount(Octicon, {
      context: {
        props: { icon, scale: 2 }
      }
    })

    expect(wrapper.html()).toMatchSnapshot()
  })

  test('scalable with 0', () => {
    const wrapper = mount(Octicon, {
      context: {
        props: { icon, scale: 0 }
      }
    })

    expect(wrapper.html()).toMatchSnapshot()
  })

  test('scalable with fractional values', () => {
    const wrapper = mount(Octicon, {
      context: {
        props: { icon, scale: 1.2345 }
      }
    })

    expect(wrapper.html()).toMatchSnapshot()
  })

  test('accepts an additional class', () => {
    const wrapper = mount(Octicon, {
      context: {
        props: { icon, className: 'an-additional-class' }
      }
    })

    expect(wrapper.html()).toMatchSnapshot()
  })

  test('ignores invalid additional classes', () => {
    const wrapper = mount(Octicon, {
      context: {
        props: { icon, className: null }
      }
    })

    expect(wrapper.html()).toMatchSnapshot()
  })

  test('accepts an label', () => {
    const wrapper = mount(Octicon, {
      context: {
        props: { icon, label: 'label' }
      }
    })

    expect(wrapper.html()).toMatchSnapshot()
  })
})
<commit_msg>vue: test for 424479cab4f6781c39a7496f0e5daafff217ae3f<commit_after>import { mount } from '@vue/test-utils'
import Octicon from '../lib/main.js'

describe('Octicon component', () => {
  const icon = require('octicons-modular/lib/icons/zap')

  test('invalid', () => {
    const wrapper = mount(Octicon, {
      context: {
        props: { icon: {
          svg () {}
        } }
      }
    })

    expect(wrapper.html()).toBeFalsy()
  })

  test('valid', () => {
    const wrapper = mount(Octicon, {
      context: {
        props: { icon }
      }
    })

    expect(wrapper.html()).toMatchSnapshot()
  })

  test('scalable', () => {
    const wrapper = mount(Octicon, {
      context: {
        props: { icon, scale: 2 }
      }
    })

    expect(wrapper.html()).toMatchSnapshot()
  })

  test('scalable with 0', () => {
    const wrapper = mount(Octicon, {
      context: {
        props: { icon, scale: 0 }
      }
    })

    expect(wrapper.html()).toMatchSnapshot()
  })

  test('scalable with fractional values', () => {
    const wrapper = mount(Octicon, {
      context: {
        props: { icon, scale: 1.2345 }
      }
    })

    expect(wrapper.html()).toMatchSnapshot()
  })

  test('accepts an additional class', () => {
    const wrapper = mount(Octicon, {
      context: {
        props: { icon, className: 'an-additional-class' }
      }
    })

    expect(wrapper.html()).toMatchSnapshot()
  })

  test('ignores invalid additional classes', () => {
    const wrapper = mount(Octicon, {
      context: {
        props: { icon, className: null }
      }
    })

    expect(wrapper.html()).toMatchSnapshot()
  })

  test('accepts an label', () => {
    const wrapper = mount(Octicon, {
      context: {
        props: { icon, label: 'label' }
      }
    })

    expect(wrapper.html()).toMatchSnapshot()
  })
})
<|endoftext|>


<commit_before>define([
	'goo/util/StringUtil',
	'goo/util/ObjectUtil',
	/*
	'goo/statemachine/actions/LogVariableAction',
	'goo/statemachine/actions/SetVariableAction',
	'goo/statemachine/actions/AddPositionAction',
	'goo/statemachine/actions/MouseClickAction',
	'goo/statemachine/actions/SetPositionAction',
	'goo/statemachine/actions/AddVariableAction',
	//'goo/statemachine/actions/MouseMoveAction',
	'goo/statemachine/actions/SetRotationAction',
	//'goo/statemachine/actions/AddVectorAction',
	'goo/statemachine/actions/MultiplyVariableAction',
	//'goo/statemachine/actions/TestAngleAction',
	//'goo/statemachine/actions/EventListenerAction',
	'goo/statemachine/actions/NumberCompareAction',
	//'goo/statemachine/actions/TestCollisionAction',
	//'goo/statemachine/actions/FollowEntityAction',
	//'goo/statemachine/actions/RandomEventAction',
	//'goo/statemachine/actions/TestSpeedAction',
	'goo/statemachine/actions/GetPositionAction',
	//'goo/statemachine/actions/ScriptAction',
	//'goo/statemachine/actions/TweenAction',
	//'goo/statemachine/actions/GuiButtonAction',
	'goo/statemachine/actions/SetAnimationAction',
	//'goo/statemachine/actions/TweenPositionAction',
	'goo/statemachine/actions/KeyDownAction',
	'goo/statemachine/actions/SetClearColorAction',
	//'goo/statemachine/actions/TweenRotationAction',
	//'goo/statemachine/actions/KeyPressAction',
	//'goo/statemachine/actions/SetCssPropertyAction',

	'goo/statemachine/actions/KeyUpAction',
	'goo/statemachine/actions/SetLightRangeAction',

	// 'goo/statemachine/actions/TransformAction',
	'goo/statemachine/actions/MoveAction',
	'goo/statemachine/actions/RotateAction'
    */
	'goo/statemachine/actions/WaitAction',
	'goo/statemachine/actions/MoveAction',
	// 'goo/statemachine/actions/MoveWithRotationAction',
	'goo/statemachine/actions/RotateAction',
	'goo/statemachine/actions/ScaleAction',
	// 'goo/statemachine/actions/LookAtAction',

	'goo/statemachine/actions/TweenMoveAction',
	'goo/statemachine/actions/TweenRotationAction',
	'goo/statemachine/actions/TweenScaleAction',
	//'goo/statemachine/actions/TweenLookAtAction',

	'goo/statemachine/actions/HideAction',
	'goo/statemachine/actions/ShowAction',
	'goo/statemachine/actions/RemoveAction',
	'goo/statemachine/actions/AddLightAction',
	'goo/statemachine/actions/RemoveLightAction',

	'goo/statemachine/actions/InBoxAction',
	'goo/statemachine/actions/CompareDistanceAction',

	'goo/statemachine/actions/SetClearColorAction',
	'goo/statemachine/actions/SuspendFSMAction',
	'goo/statemachine/actions/ResumeFSMAction',

	'goo/statemachine/actions/InFrustumAction',
	'goo/statemachine/actions/TransitionAction',
	'goo/statemachine/actions/EmitAction',
	'goo/statemachine/actions/EvalAction',

//	'goo/statemachine/actions/SwitchCameraAction',
	'goo/statemachine/actions/LogMessageAction',
	'goo/statemachine/actions/PauseAnimationAction',
	'goo/statemachine/actions/ResumeAnimationAction',
	'goo/statemachine/actions/SetAnimationAction',

	'goo/statemachine/actions/MouseUpAction',
	'goo/statemachine/actions/MouseDownAction',
	'goo/statemachine/actions/KeyUpAction',
	'goo/statemachine/actions/KeyDownAction',
	'goo/statemachine/actions/WASDAction',
	'goo/statemachine/actions/ArrowsAction',

	'goo/statemachine/actions/AddTVAction'
],
/** @lends */
function(
	StringUtil,
	_
) {
	"use strict";

	var _actions = {};

	var Actions = {};

	Actions.register = function (name, actionClass) {
		_actions[name] = actionClass;
	};

	Actions.actionForType = function (name) {
		return _actions[name];
	};

	Actions.allActions = function() {
		var actions = {};
		var keys = Object.keys(_actions);
		for (var i = 0; i < keys.length; i++) {
			var key = keys[i];
			actions[key] = _actions[key];
		}
		return actions;
	};

	Actions.menuItems = function() {
		var keys = _.keys(_actions).sort();
		var items = {};
		for (var i = 0; i < keys.length; i++) {
			var key = keys[i];
			items[StringUtil.uncapitalize(key)] = { name: key };
		}
		return items;
	};

	function registerAll(args) {
		var actionsStartIndex = 2;
		for (var i = actionsStartIndex; i < args.length; i++) {
			var arg = args[i];
			var stringedFun = arg.toString();
			var type = stringedFun.substring(9, stringedFun.indexOf('('));
			Actions.register(type, arg);
		}
	}

	registerAll(arguments);

	return Actions;
});<commit_msg>#451 Updated actions list<commit_after>define([
	'goo/util/StringUtil',
	'goo/util/ObjectUtil',
	/*
	'goo/statemachine/actions/LogVariableAction',
	'goo/statemachine/actions/SetVariableAction',
	'goo/statemachine/actions/AddPositionAction',
	'goo/statemachine/actions/MouseClickAction',
	'goo/statemachine/actions/SetPositionAction',
	'goo/statemachine/actions/AddVariableAction',
	//'goo/statemachine/actions/MouseMoveAction',
	'goo/statemachine/actions/SetRotationAction',
	//'goo/statemachine/actions/AddVectorAction',
	'goo/statemachine/actions/MultiplyVariableAction',
	//'goo/statemachine/actions/TestAngleAction',
	//'goo/statemachine/actions/EventListenerAction',
	'goo/statemachine/actions/NumberCompareAction',
	//'goo/statemachine/actions/TestCollisionAction',
	//'goo/statemachine/actions/FollowEntityAction',
	//'goo/statemachine/actions/RandomEventAction',
	//'goo/statemachine/actions/TestSpeedAction',
	'goo/statemachine/actions/GetPositionAction',
	//'goo/statemachine/actions/ScriptAction',
	//'goo/statemachine/actions/TweenAction',
	//'goo/statemachine/actions/GuiButtonAction',
	'goo/statemachine/actions/SetAnimationAction',
	//'goo/statemachine/actions/TweenPositionAction',
	'goo/statemachine/actions/KeyDownAction',
	'goo/statemachine/actions/SetClearColorAction',
	//'goo/statemachine/actions/TweenRotationAction',
	//'goo/statemachine/actions/KeyPressAction',
	//'goo/statemachine/actions/SetCssPropertyAction',

	'goo/statemachine/actions/KeyUpAction',
	'goo/statemachine/actions/SetLightRangeAction',

	// 'goo/statemachine/actions/TransformAction',
	'goo/statemachine/actions/MoveAction',
	'goo/statemachine/actions/RotateAction'
    */

	'goo/statemachine/actions/MoveAction',
	'goo/statemachine/actions/MoveWithRotationAction',
	'goo/statemachine/actions/RotateAction',
	'goo/statemachine/actions/ScaleAction',
	// 'goo/statemachine/actions/LookAtAction',

	'goo/statemachine/actions/TweenMoveAction',
	'goo/statemachine/actions/TweenRotationAction',
	'goo/statemachine/actions/TweenScaleAction',
	//'goo/statemachine/actions/TweenLookAtAction',

	'goo/statemachine/actions/HideAction',
	'goo/statemachine/actions/ShowAction',
	'goo/statemachine/actions/RemoveAction',
	'goo/statemachine/actions/AddLightAction',
	'goo/statemachine/actions/RemoveLightAction',

	'goo/statemachine/actions/InBoxAction',
	'goo/statemachine/actions/CompareDistanceAction',

	'goo/statemachine/actions/SetClearColorAction',
	'goo/statemachine/actions/SuspendFSMAction',
	'goo/statemachine/actions/ResumeFSMAction',

	'goo/statemachine/actions/InFrustumAction',
	'goo/statemachine/actions/TransitionAction',
	'goo/statemachine/actions/EmitAction',
	'goo/statemachine/actions/EvalAction',

//	'goo/statemachine/actions/SwitchCameraAction',
	'goo/statemachine/actions/LogMessageAction',
	'goo/statemachine/actions/PauseAnimationAction',
	'goo/statemachine/actions/ResumeAnimationAction',
	'goo/statemachine/actions/SetAnimationAction',

	'goo/statemachine/actions/MouseUpAction',
	'goo/statemachine/actions/MouseDownAction',
	'goo/statemachine/actions/KeyUpAction',
	'goo/statemachine/actions/KeyDownAction',
	'goo/statemachine/actions/WASDAction',
	'goo/statemachine/actions/ArrowsAction',

	'goo/statemachine/actions/AddTVAction',
	'goo/statemachine/actions/WaitAction'
],
/** @lends */
function(
	StringUtil,
	_
) {
	"use strict";

	var _actions = {};

	var Actions = {};

	Actions.register = function (name, actionClass) {
		_actions[name] = actionClass;
	};

	Actions.actionForType = function (name) {
		return _actions[name];
	};

	Actions.allActions = function() {
		var actions = {};
		var keys = Object.keys(_actions);
		for (var i = 0; i < keys.length; i++) {
			var key = keys[i];
			actions[key] = _actions[key];
		}
		return actions;
	};

	Actions.menuItems = function() {
		var keys = _.keys(_actions).sort();
		var items = {};
		for (var i = 0; i < keys.length; i++) {
			var key = keys[i];
			items[StringUtil.uncapitalize(key)] = { name: key };
		}
		return items;
	};

	function registerAll(args) {
		var actionsStartIndex = 2;
		for (var i = actionsStartIndex; i < args.length; i++) {
			var arg = args[i];
			var stringedFun = arg.toString();
			var type = stringedFun.substring(9, stringedFun.indexOf('('));
			Actions.register(type, arg);
		}
	}

	registerAll(arguments);

	return Actions;
});<|endoftext|>


<commit_before>
Template.IMonChoroplethWidget.updateSubscription = function(template){
  // Make sure we're always subscribed to the currently selected indicator.
  // Seems unnecessarily complicated.
  if ( ! Template.currentData().newIndicatorId ) {
    Template.currentData().set({newIndicatorId: Template.IMonChoroplethSettings.defaultIndicatorId});
    //return;
  }
  if ( (Template.currentData().newIndicatorId !== Template.currentData().indicatorId)) {
    Template.currentData().set({indicatorId: Template.currentData().newIndicatorId});

    //return;
  }
  template.subscribe(
    'imon_indicators'
  );
  template.subscribe(
    'imon_data',
    'all',
    [ parseInt(Template.currentData().newIndicatorId) ],
    'id'
  );
};

Template.IMonChoroplethWidget.onCreated(function() {
  Template.IMonChoroplethWidget.updateSubscription(this);
});

Template.IMonChoroplethWidget.onRendered(function() {

  var template = this;

  this.autorun(function() {

    // there must be a better way to do this...
    Template.IMonChoroplethWidget.updateSubscription(template);

    if (!template.subscriptionsReady()) {
      return;
    }

    var indicator = IMonIndicators.findOne({id:parseInt(Template.currentData().indicatorId)});
    var cachedIndicator = Template.currentData().indicator;
    if ( !(cachedIndicator) || (cachedIndicator.id !== indicator.id)){
      Template.currentData().set({indicator: indicator});
    }

    if ( ! indicator ) {
      console.log("No indicator found for indicatorId: " + Template.currentData().indicatorId);
      return;
    }

    d3.select(template.find('.indicator_name')).text(indicator.shortName);

    template.$('.imon-choropleth-data').html('');

    var countryDataByCode = {};
    var query = { };
    var scores=[];
    var scoreSet={};
    query.sourceId = parseInt(indicator.id); // why is this necessary?
    IMonData.find(query).forEach(function(countryData){
      countryDataByCode[countryData.countryCode.toUpperCase()]=countryData;
      if ( countryData.value !== undefined) {
        scores.push(countryData.value);
        if (_.has(scoreSet,countryData.value)){
          scoreSet[countryData.value]+=1;
        } else {
          scoreSet[countryData.value]=1;
        }
      }
    });

    var formatLegendLabelNumber = function formatLegendLabelNumber (number,precision){
      precision = precision ? precision : 1;
      if ( number > 1000000 ) {
        return (number / 1000000).toFixed(precision) + "M";
      } else if ( number > 1000 ) {
        return (number / 1000).toFixed(precision) + "K";
      } else {
        if ( indicator.displaySuffix){
          return number.toFixed(1) + indicator.displaySuffix;
        } else if ( number % 1 === 0 ) {
          return number;
        } else {
          return number.toFixed(precision);
        }
      }
    };

    var range        = ['#ece7f2','#bdd7e7','#6baed6','#3182bd','#08519c'];

    var uniqueScores = Object.keys(scoreSet);
    uniqueScores = uniqueScores.sort(function(a, b){ return a-b; });

    if (uniqueScores.length === 4 ) {
      range        = ['#ece7f2','#bdc9e1','#74a9cf','#0570b0'];
    } else if ( uniqueScores.length === 3 ) {
      range        = ['#ece7f2','#a6bddb','#2b8cbe'];
    }

    // by default, we use a quantile scale.

    var colorScale;
    colorScale = d3.scale.quantile()
      .domain(scores)
      .range(range);

    var useQuantileScale = true;

    // but let's check, are quantile scales appropriate for this data?
    if ( uniqueScores.length < 5 ) {
      useQuantileScale = false;
    }
    _.each(colorScale.quantiles(), function(quantile,i){
      if ( i > 0 && colorScale.quantiles()[i-1] === quantile){
        console.log("Duplicate quantiles. Quantiles not working for this data. Use something else.", colorScale.quantiles());
        useQuantileScale = false;
        return;
      }
    });

    var lengendLabels;

    var setLegendLabels = function setLegendLabels(precision){
      legendLabels = [];
      if (useQuantileScale){
        legendLabels[0]= "< " + formatLegendLabelNumber(colorScale.quantiles()[0],precision);
        _.each(colorScale.quantiles(), function(quantile,i){
          legendLabels[i+1] = ">="+formatLegendLabelNumber(quantile,precision);
        });
      } else {
        colorScale = d3.scale.ordinal().domain(uniqueScores).range(range);
        // sometimes these numbers are strings. why?
        _.each(uniqueScores, function(score,i){
          legendLabels[i] = formatLegendLabelNumber(Number(score),precision);
        });
      }
    };

    var precision =_.max(uniqueScores)>1 ? 1 : 2;

    setLegendLabels(precision);

    var svg = d3.select(template.find('.imon-choropleth')).append("svg:svg")
      .attr("width", Settings.map.width)
      .attr("height", Settings.map.height);

    var projection = d3.geo.winkel3()
      .scale(Settings.map.scale)
      .translate([
        Settings.map.width / 2 - Settings.map.bumpLeft,
        Settings.map.height / 2 + Settings.map.bumpDown
      ])
      ;

    var legend = d3.legend.color()
      .scale(colorScale)
      .labelOffset(5)
      .cells(5)
        .labels(legendLabels);

    svg.append("g")
      .attr("class", "legend")
      .attr("transform", "translate(0, 165)");

    CountryInfo.shapes(function(shapes) {
      var feature = svg.selectAll("path")
          .data(shapes.features)
          .enter().append("svg:path")
          .attr('class', 'country')
	  .style('fill', function(d) {
            var country = countryDataByCode[d.id];
            // We have country data. Make it pretty.
            if (country) {
              return colorScale(country.value);
            } else {
              // No data for this country. Make it gray or something.
              return 'rgb(186,186,186)';
            }
          })
          .style('transform', 'scaleY(' + Settings.map.squash + ')')
          .attr("d", d3.geo.path().projection(projection));

      feature.append("svg:title")
        .text(function(d) {
          var title = d.properties.name;
          var country = countryDataByCode[d.id];
          if (country) {
            return title + ': ' + formatLegendLabelNumber(Number(country.value),precision) + '';
          }
          return title + ' (No data)';
        });

      svg.select(".legend")
        .call(legend);

    });
  });
});
<commit_msg>Use quantize scale when quantile or ordinal doesn't work<commit_after>
Template.IMonChoroplethWidget.updateSubscription = function(template){
  // Make sure we're always subscribed to the currently selected indicator.
  // Seems unnecessarily complicated.
  if ( ! Template.currentData().newIndicatorId ) {
    Template.currentData().set({newIndicatorId: Template.IMonChoroplethSettings.defaultIndicatorId});
    //return;
  }
  if ( (Template.currentData().newIndicatorId !== Template.currentData().indicatorId)) {
    Template.currentData().set({indicatorId: Template.currentData().newIndicatorId});
    //return;
  }
  template.subscribe(
    'imon_indicators'
  );
  template.subscribe(
    'imon_data',
    'all',
    [ parseInt(Template.currentData().newIndicatorId) ],
    'id'
  );
};

Template.IMonChoroplethWidget.onCreated(function() {
  Template.IMonChoroplethWidget.updateSubscription(this);
});

Template.IMonChoroplethWidget.onRendered(function() {

  var template = this;

  this.autorun(function() {

    // there must be a better way to do this...
    Template.IMonChoroplethWidget.updateSubscription(template);

    if (!template.subscriptionsReady()) {
      return;
    }

    var indicator = IMonIndicators.findOne({id:parseInt(Template.currentData().indicatorId)});
    var cachedIndicator = Template.currentData().indicator;
    if ( !(cachedIndicator) || (cachedIndicator.id !== indicator.id)){
      Template.currentData().set({indicator: indicator});
    }

    if ( ! indicator ) {
      console.log('No indicator found for indicatorId: ' + Template.currentData().indicatorId);
      return;
    }

    d3.select(template.find('.indicator_name')).text(indicator.shortName);

    template.$('.imon-choropleth-data').html('');

    var countryDataByCode = {};
    var query = { };
    var scores=[];
    var scoreSet={};
    query.sourceId = parseInt(indicator.id); // why is this necessary?
    IMonData.find(query).forEach(function(countryData){
      countryDataByCode[countryData.countryCode.toUpperCase()]=countryData;
      if ( countryData.value !== undefined) {
        scores.push(countryData.value);
        if (_.has(scoreSet,countryData.value)){
          scoreSet[countryData.value]+=1;
        } else {
          scoreSet[countryData.value]=1;
        }
      }
    });

    var formatLegendLabelNumber = function formatLegendLabelNumber (number,precision){
      precision = precision ? precision : 1;
      if ( number > 1000000 ) {
        return (number / 1000000).toFixed(precision) + "M";
      } else if ( number > 1000 ) {
        return (number / 1000).toFixed(precision) + "K";
      } else {
        if ( indicator.displaySuffix){
          return number.toFixed(1) + indicator.displaySuffix;
        } else if ( number % 1 === 0 ) {
          return number;
        } else {
          return number.toFixed(precision);
        }
      }
    };

    var range        = ['#ece7f2','#bdd7e7','#6baed6','#3182bd','#08519c'];

    var uniqueScores = Object.keys(scoreSet);
    uniqueScores = uniqueScores.sort(function(a, b){ return a-b; });

    if (uniqueScores.length === 4 ) {
      range        = ['#ece7f2','#bdc9e1','#74a9cf','#0570b0'];
    } else if ( uniqueScores.length === 3 ) {
      range        = ['#ece7f2','#a6bddb','#2b8cbe'];
    }

    // by default, we use a quantile scale.

    var colorScale;
    colorScale = d3.scale.quantile()
      .domain(scores)
      .range(range);

    var useQuantileScale = true;

    // but let's check, are quantile scales appropriate for this data?
    if ( uniqueScores.length < 5 ) {
      useQuantileScale = false;
    } else {
      _.each(colorScale.quantiles(), function(quantile,i){
        if ( i > 0 && colorScale.quantiles()[i-1] === quantile){
          console.log("Duplicate quantiles. Quantiles not working for this data. Use quantize.", colorScale.quantiles());
          useQuantileScale = false;
          return;
        }
      });
    }

    var lengendLabels;

    var setLegendLabels = function setLegendLabels(precision){
      legendLabels = [];
      if (useQuantileScale){
        // quantile scale is best, most data-tailored scale when we have sufficient range of values.
        legendLabels[0]= "< " + formatLegendLabelNumber(colorScale.quantiles()[0],precision);
        _.each(colorScale.quantiles(), function(quantile,i){
          legendLabels[i+1] = ">="+formatLegendLabelNumber(quantile,precision);
        });
      } else {
        if ( uniqueScores.length <= 5 ) {
          // use ordinal scale for just a few values.
          colorScale = d3.scale.ordinal().domain(uniqueScores).range(range);
          // sometimes these numbers are strings. why?
          _.each(uniqueScores, function(score,i){
            legendLabels[i] = formatLegendLabelNumber(Number(score),precision);
          });
        } else {
          // use quantize scale to cut into 5 equal groups from min to max
          var max = indicator.max;
          // crude, temporary attempt to bring out resolution with lumpy data.
          if (max > 100 && indicator.min < 10) {
            max = 80;
          }
          colorScale = d3.scale.quantize().domain([indicator.min,max]).range(range);
          var buckets = _.map(range,function(color,i){ return indicator.min + ((i+1)*((max-indicator.min)/5)); });
          legendLabels[0]= "< " + formatLegendLabelNumber(buckets[0],precision);
          _.each(buckets, function(bucket,i){
            legendLabels[i+1] = ">="+formatLegendLabelNumber(bucket,precision);
          });
        }
      }
    };

    var precision =_.max(uniqueScores)>1 ? 1 : 2;

    setLegendLabels(precision);

    var svg = d3.select(template.find('.imon-choropleth')).append("svg:svg")
      .attr("width", Settings.map.width)
      .attr("height", Settings.map.height);

    var projection = d3.geo.winkel3()
      .scale(Settings.map.scale)
      .translate([
        Settings.map.width / 2 - Settings.map.bumpLeft,
        Settings.map.height / 2 + Settings.map.bumpDown
      ])
      ;

    var legend = d3.legend.color()
      .scale(colorScale)
      .labelOffset(5)
      .cells(5)
        .labels(legendLabels);

    svg.append("g")
      .attr("class", "legend")
      .attr("transform", "translate(0, 165)");

    CountryInfo.shapes(function(shapes) {
      var feature = svg.selectAll("path")
          .data(shapes.features)
          .enter().append("svg:path")
          .attr('class', 'country')
	  .style('fill', function(d) {
            var country = countryDataByCode[d.id];
            // We have country data. Make it pretty.
            if (country) {
              return colorScale(country.value);
            } else {
              // No data for this country. Make it gray or something.
              return 'rgb(186,186,186)';
            }
          })
          .style('transform', 'scaleY(' + Settings.map.squash + ')')
          .attr("d", d3.geo.path().projection(projection));

      feature.append("svg:title")
        .text(function(d) {
          var title = d.properties.name;
          var country = countryDataByCode[d.id];
          if (country) {
            return title + ': ' + formatLegendLabelNumber(Number(country.value),precision) + '';
          }
          return title + ' (No data)';
        });

      svg.select(".legend")
        .call(legend);

    });
  });
});
<|endoftext|>


<commit_before>// ==========================================================================
// Project:  SproutCore Metal
// Copyright: ©2011 Strobe Inc. and contributors.
// License:   Licensed under MIT license (see license.js)
// ==========================================================================
/*globals sc_assert */

require('sproutcore-metal/core');
require('sproutcore-metal/platform');
require('sproutcore-metal/utils');

var o_create = SC.platform.create;
var meta = SC.meta;
var guidFor = SC.guidFor;
var a_slice = Array.prototype.slice;

function objectFor(m, obj, writable) {
  var len = arguments.length, idx, keyName, ret;

  for(idx=3; idx<len; idx++) {
    keyName = arguments[idx];
    ret = m[keyName];
    if (writable) {
      if (!ret) {
        ret = m[keyName] = { __scproto__: obj };
      } else if (ret.__scproto__ !== obj) {
        ret = m[keyName] = o_create(ret);
        ret.__scproto__ = obj;
      }
    } else if (!ret || (ret.__scproto__ !== obj)) {
      return undefined;
    }

    m = ret;
  }

  return ret;
}

function listenerSetFor(obj, eventName, target, writable) {
  var targetGuid = guidFor(target);
  return objectFor(meta(obj, writable), obj, writable, 'listeners', eventName, targetGuid);
}

var EV_SKIP = { __scproto__: true };

function invokeEvents(targets, params) {
  var tguid, mguid, methods, info, method, target;
  for(tguid in targets) {
    if (EV_SKIP[tguid]) continue;
    methods = targets[tguid];

    for(mguid in methods) {
      if (EV_SKIP[mguid] || !(info=methods[mguid])) continue;
      method = info.method;
      target = info.target;
      if (!target) target = params[0];  // object
      if ('string' === typeof method) method = target[method];
      if (info.xform) info.xform(target, method, params);
      else method.apply(target, params);
    }
  }
}

function addListener(obj, eventName, target, method, xform) {
  if (!method && 'function'===typeof target) {
    method = target;
    target = null;
  }

  var set  = listenerSetFor(obj, eventName, target, true),
      guid = guidFor(method), ret;

  if (!set[guid]) {
    set[guid] = { target: target, method: method, xform: xform };
  } else {
    set[guid].xform = xform; // used by observers etc to map params
  }

  if (obj && 'function'===typeof obj.didAddListener) {
    obj.didAddListener(eventName, target, method);
  }

  return ret; // return true if this is the first listener.
}

function removeListener(obj, eventName, target, method) {
  if (!method && 'function'===typeof target) {
    method = target;
    target = null;
  }

  var set = listenerSetFor(obj, eventName, target, true),
      guid = guidFor(method);

  // can't delete since it might be inherited
  if (set && set[guid]) set[guid] = null;

  if (obj && 'function'===typeof obj.didRemoveListener) {
    obj.didRemoveListener(eventName, target, method);
  }
}

// returns a list of currently watched events
function watchedEvents(obj) {
  var listeners = meta(obj, false).listeners, ret =[];
  if (listeners) {
    for(var eventName in listeners) {
      if (!EV_SKIP[eventName] && listeners[eventName]) ret.push(eventName);
    }
  }
  return ret;
}

function sendEvent(obj, eventName) {

  // first give object a change to handle it
  if (obj && 'function' === typeof obj.sendEvent) {
    obj.sendEvent.apply(obj, a_slice.call(arguments, 1));
  }

  var set = meta(obj, false).listeners;
  if (set && (set = set[eventName])) {
    invokeEvents(set, arguments);
    return true;
  }

  return false;
}

function hasListeners(obj, eventName) {
  var targets = meta(obj, false).listeners;
  if (targets) targets = targets[eventName];
  if (!targets) return false;

  var tguid, mguid, methods;
  for(tguid in targets) {
    if (EV_SKIP[tguid] || !targets[tguid]) continue;
    methods = targets[tguid];
    for(mguid in methods) {
      if (EV_SKIP[mguid] || !methods[mguid]) continue;
      return true; // stop as soon as we find a valid listener
    }
  }

  // no listeners!  might as well clean this up so it is faster later.
  var set = objectFor(meta(obj, true), obj, true, 'listeners');
  set[eventName] = null;

  return false;
}

function listenersFor(obj, eventName) {
  var targets = meta(obj, false).listeners,
      ret = [];

  if (targets) targets = targets[eventName];
  if (!targets) return ret;

  var tguid, mguid, methods, info;
  for(tguid in targets) {
    if (EV_SKIP[tguid] || !targets[tguid]) continue;
    methods = targets[tguid];
    for(mguid in methods) {
      if (EV_SKIP[mguid] || !methods[mguid]) continue;
      info = methods[mguid];
      ret.push([info.target, info.method]);
    }
  }

  return ret;
}

SC.addListener = addListener;
SC.removeListener = removeListener;
SC.sendEvent = sendEvent;
SC.hasListeners = hasListeners;
SC.watchedEvents = watchedEvents;
SC.listenersFor = listenersFor;
<commit_msg>Add a note to addListener() to describe what an "xform" is.<commit_after>// ==========================================================================
// Project:  SproutCore Metal
// Copyright: ©2011 Strobe Inc. and contributors.
// License:   Licensed under MIT license (see license.js)
// ==========================================================================
/*globals sc_assert */

require('sproutcore-metal/core');
require('sproutcore-metal/platform');
require('sproutcore-metal/utils');

var o_create = SC.platform.create;
var meta = SC.meta;
var guidFor = SC.guidFor;
var a_slice = Array.prototype.slice;

function objectFor(m, obj, writable) {
  var len = arguments.length, idx, keyName, ret;

  for(idx=3; idx<len; idx++) {
    keyName = arguments[idx];
    ret = m[keyName];
    if (writable) {
      if (!ret) {
        ret = m[keyName] = { __scproto__: obj };
      } else if (ret.__scproto__ !== obj) {
        ret = m[keyName] = o_create(ret);
        ret.__scproto__ = obj;
      }
    } else if (!ret || (ret.__scproto__ !== obj)) {
      return undefined;
    }

    m = ret;
  }

  return ret;
}

function listenerSetFor(obj, eventName, target, writable) {
  var targetGuid = guidFor(target);
  return objectFor(meta(obj, writable), obj, writable, 'listeners', eventName, targetGuid);
}

var EV_SKIP = { __scproto__: true };

function invokeEvents(targets, params) {
  var tguid, mguid, methods, info, method, target;
  for(tguid in targets) {
    if (EV_SKIP[tguid]) continue;
    methods = targets[tguid];

    for(mguid in methods) {
      if (EV_SKIP[mguid] || !(info=methods[mguid])) continue;
      method = info.method;
      target = info.target;
      if (!target) target = params[0];  // object
      if ('string' === typeof method) method = target[method];
      if (info.xform) info.xform(target, method, params);
      else method.apply(target, params);
    }
  }
}

/**
  The parameters passed to an event listener are not exactly the
  parameters passed to an observer. if you pass an xform function, it will
  be invoked and is able to translate event listener parameters into the form
  that observers are expecting.
*/
function addListener(obj, eventName, target, method, xform) {
  if (!method && 'function'===typeof target) {
    method = target;
    target = null;
  }

  var set  = listenerSetFor(obj, eventName, target, true),
      guid = guidFor(method), ret;

  if (!set[guid]) {
    set[guid] = { target: target, method: method, xform: xform };
  } else {
    set[guid].xform = xform; // used by observers etc to map params
  }

  if (obj && 'function'===typeof obj.didAddListener) {
    obj.didAddListener(eventName, target, method);
  }

  return ret; // return true if this is the first listener.
}

function removeListener(obj, eventName, target, method) {
  if (!method && 'function'===typeof target) {
    method = target;
    target = null;
  }

  var set = listenerSetFor(obj, eventName, target, true),
      guid = guidFor(method);

  // can't delete since it might be inherited
  if (set && set[guid]) set[guid] = null;

  if (obj && 'function'===typeof obj.didRemoveListener) {
    obj.didRemoveListener(eventName, target, method);
  }
}

// returns a list of currently watched events
function watchedEvents(obj) {
  var listeners = meta(obj, false).listeners, ret =[];
  if (listeners) {
    for(var eventName in listeners) {
      if (!EV_SKIP[eventName] && listeners[eventName]) ret.push(eventName);
    }
  }
  return ret;
}

function sendEvent(obj, eventName) {

  // first give object a change to handle it
  if (obj && 'function' === typeof obj.sendEvent) {
    obj.sendEvent.apply(obj, a_slice.call(arguments, 1));
  }

  var set = meta(obj, false).listeners;
  if (set && (set = set[eventName])) {
    invokeEvents(set, arguments);
    return true;
  }

  return false;
}

function hasListeners(obj, eventName) {
  var targets = meta(obj, false).listeners;
  if (targets) targets = targets[eventName];
  if (!targets) return false;

  var tguid, mguid, methods;
  for(tguid in targets) {
    if (EV_SKIP[tguid] || !targets[tguid]) continue;
    methods = targets[tguid];
    for(mguid in methods) {
      if (EV_SKIP[mguid] || !methods[mguid]) continue;
      return true; // stop as soon as we find a valid listener
    }
  }

  // no listeners!  might as well clean this up so it is faster later.
  var set = objectFor(meta(obj, true), obj, true, 'listeners');
  set[eventName] = null;

  return false;
}

function listenersFor(obj, eventName) {
  var targets = meta(obj, false).listeners,
      ret = [];

  if (targets) targets = targets[eventName];
  if (!targets) return ret;

  var tguid, mguid, methods, info;
  for(tguid in targets) {
    if (EV_SKIP[tguid] || !targets[tguid]) continue;
    methods = targets[tguid];
    for(mguid in methods) {
      if (EV_SKIP[mguid] || !methods[mguid]) continue;
      info = methods[mguid];
      ret.push([info.target, info.method]);
    }
  }

  return ret;
}

SC.addListener = addListener;
SC.removeListener = removeListener;
SC.sendEvent = sendEvent;
SC.hasListeners = hasListeners;
SC.watchedEvents = watchedEvents;
SC.listenersFor = listenersFor;
<|endoftext|>


<commit_before>process.env.BABEL_ENV = 'development';
process.env.NODE_ENV = 'development';

const fs = require('fs-extra');
const path = require('path');
const chalk = require('chalk');
const webpack = require('webpack');
const WebpackServe = require('webpack-serve');
const selfsigned = require('selfsigned');
const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
const openBrowser = require('react-dev-utils/openBrowser');
const clearConsole = require('react-dev-utils/clearConsole');
const { choosePort, prepareUrls } = require('react-dev-utils/WebpackDevServerUtils');

const config = require('../config/webpack.config.dev');

/**
 * Get HTTPS server config
 * @return {Object}
 */
function configureHttps() {
  const certPath = path.join(__dirname, '../ssl/server.pem');

  let validCertExists = fs.existsSync(certPath);
  if (validCertExists) {
    const now = new Date();
    const certStats = fs.statSync(certPath);
    const certTTL = 1000 * 60 * 60 * 24;

    // If the certificate was been created more than 30 days ago
    if ((now - certStats.ctime) / certTTL > 30) {
      console.log('SSL certificate is older than 30 days, removing...');
      fs.removeSync(certPath);
      validCertExists = false;
    }
  }

  // Generate a new certificate if there's not a valid cert
  if (!validCertExists) {
    console.log('Generating new SSL certificate');
    const attrs = [{ name: 'commonName', value: 'localhost' }];
    const pems = selfsigned.generate(attrs, {
      algorithm: 'sha256',
      days: 30,
      keySize: 2048,
    });

    fs.writeFileSync(certPath, pems.private + pems.cert, { encoding: 'utf-8' });
  }

  const fakeCert = fs.readFileSync(certPath);
  return {
    key: fakeCert,
    cert: fakeCert,
  };
}

/**
 * Get development server config
 * @param {Array<String>} args - Arguments when execute the script
 */
function getServerConfig(protocol, host, port) {
  // HTTPS is disabled by default
  let https = false;

  if (protocol === 'https') {
    https = configureHttps();
  }

  return {
    host,
    port,
    quiet: true,
    https,
    clipboard: false,
    dev: {
      logLevel: 'silent',
    },
    logLevel: 'silent',
    hotClient: {
      logLevel: 'silent',
      https: !!https,
      host: {
        server: '0.0.0.0',
        client: 'localhost',
      },
    },
  };
}

function createCompiler() {
  const compiler = webpack(config);

  let isFirstCompile = true;
  compiler.hooks.invalid.tap('Compiling', () => {
    clearConsole();
    console.log('Compiling...');
  });

  // Format messages
  compiler.hooks.done.tap('FormatMessages', (stats) => {
    const rawMessages = stats.toJson({}, true);
    const messages = formatWebpackMessages(rawMessages);

    // If is the first compile don't clearConsole to show the app URL
    if (!isFirstCompile) clearConsole();
    isFirstCompile = false;

    if (messages.errors.length) {
      console.log(chalk.red('Failed to compile.'));
      messages.errors.forEach(e => console.log(e));
      return;
    }

    if (!messages.errors.length && !messages.warnings.length) {
      console.log(chalk.green('Compiled successfully!'));
    }

    if (messages.warnings.length) {
      console.log(chalk.yellow('Compiled with warnings.'));
      messages.warnings.forEach(w => console.log(w));
    }
  });

  return compiler;
}

module.exports = function createDevServer() {
  const args = process.argv.slice(2);
  const protocol = args.indexOf('--https') > -1 ? 'https' : 'http';
  const host = process.env.HOST || '0.0.0.0';
  const defaultPort = process.env.PORT || 3000;
  choosePort(host, defaultPort).then((port) => {
    if (!port) return false;
    const serverConfig = getServerConfig(protocol, host, port);
    const compiler = createCompiler();
    return WebpackServe({}, {
      compiler,
      ...serverConfig,
    }).then(() => {
      const urls = prepareUrls(protocol, serverConfig.host, serverConfig.port);
      if (openBrowser(urls.localUrlForBrowser)) {
        clearConsole();
        console.log('You can view your app on the browser.');
        console.log();
        console.log(`Local: \t\t\t${urls.localUrlForTerminal}`);
        console.log(`On your network: \t${urls.lanUrlForTerminal}`);
      }
    });
  });
};
<commit_msg>Fix messages formating<commit_after>process.env.BABEL_ENV = 'development';
process.env.NODE_ENV = 'development';

const fs = require('fs-extra');
const path = require('path');
const chalk = require('chalk');
const webpack = require('webpack');
const WebpackServe = require('webpack-serve');
const selfsigned = require('selfsigned');
const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
const openBrowser = require('react-dev-utils/openBrowser');
const clearConsole = require('react-dev-utils/clearConsole');
const { choosePort, prepareUrls } = require('react-dev-utils/WebpackDevServerUtils');
const config = require('../config/webpack.config.dev');

/**
 * Get HTTPS server config
 * @return {Object}
 */
function configureHttps() {
  const certPath = path.join(__dirname, '../ssl/server.pem');

  let validCertExists = fs.existsSync(certPath);
  if (validCertExists) {
    const now = new Date();
    const certStats = fs.statSync(certPath);
    const certTTL = 1000 * 60 * 60 * 24;

    // If the certificate was been created more than 30 days ago
    if ((now - certStats.ctime) / certTTL > 30) {
      console.log('SSL certificate is older than 30 days, removing...');
      fs.removeSync(certPath);
      validCertExists = false;
    }
  }

  // Generate a new certificate if there's not a valid cert
  if (!validCertExists) {
    console.log('Generating new SSL certificate');
    const attrs = [{ name: 'commonName', value: 'localhost' }];
    const pems = selfsigned.generate(attrs, {
      algorithm: 'sha256',
      days: 30,
      keySize: 2048,
    });

    fs.writeFileSync(certPath, pems.private + pems.cert, { encoding: 'utf-8' });
  }

  const fakeCert = fs.readFileSync(certPath);
  return {
    key: fakeCert,
    cert: fakeCert,
  };
}

function printInstructions(urls) {
  console.log('You can view your app on the browser.');
  console.log();
  console.log(`Local: \t\t\t${urls.localUrlForTerminal}`);
  console.log(`On your network: \t${urls.lanUrlForTerminal}`);
}

/**
 * Get development server config
 * @param {Array<String>} args - Arguments when execute the script
 */
function getServerConfig(protocol, host, port) {
  // HTTPS is disabled by default
  let https = false;

  if (protocol === 'https') {
    https = configureHttps();
  }

  return {
    host,
    port,
    quiet: true,
    https,
    clipboard: false,
    devMiddleware: {
      logLevel: 'silent',
    },
    logLevel: 'silent',
    hotClient: {
      logLevel: 'silent',
      https: !!https,
      host: {
        server: '0.0.0.0',
        client: 'localhost',
      },
    },
  };
}

function createCompiler(urls) {
  const compiler = webpack(config);

  compiler.hooks.invalid.tap('invalid', () => {
    clearConsole();
    console.log('Compiling...');
  });

  compiler.hooks.done.tap('done', (stats) => {
    // Clear the old console messages
    clearConsole();

    const rawMessages = stats.toJson({}, true);
    const messages = formatWebpackMessages(rawMessages);

    if (messages.errors.length) {
      console.log(chalk.red('Failed to compile.'));
      messages.errors.forEach(e => console.log(e));
      return;
    }

    if (!messages.errors.length && !messages.warnings.length) {
      console.log(chalk.green('Compiled successfully!'));
      printInstructions(urls);
    }

    if (messages.warnings.length) {
      console.log(chalk.yellow('Compiled with warnings.'));
      messages.warnings.forEach(w => console.log(w));
    }
  });

  return compiler;
}

module.exports = function createDevServer() {
  const args = process.argv.slice(2);
  const protocol = args.indexOf('--https') > -1 ? 'https' : 'http';
  const host = process.env.HOST || '0.0.0.0';
  const defaultPort = process.env.PORT || 3000;
  choosePort(host, defaultPort).then((port) => {
    if (!port) return false;
    const serverConfig = getServerConfig(protocol, host, port);
    const urls = prepareUrls(protocol, serverConfig.host, serverConfig.port);
    const compiler = createCompiler(urls);
    return WebpackServe(
      {},
      {
        compiler,
        ...serverConfig,
      },
    ).then(() => openBrowser(urls.localUrlForBrowser));
  });
};
<|endoftext|>


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

'use strict';

// MAIN //

/**
* Returns a cookie string for a provided name-value pair.
*
* @private
* @param {string} name - cookie name
* @param {string} value - cookie value
* @param {Object} [options] - cookie options
* @param {string} [options.path] - cookie path
* @param {string} [options.domain] - cookie domain
* @param {number} [options.maxAge] - maximum age (in seconds; takes precedence over `expire`)
* @param {(string|Date)} [options.expires] - cookie expiration date
* @param {boolean} [options.secure] - boolean indicating whether the cookie may only be transmitted over a secure protocol (e.g., HTTPS)
* @param {string} [options.samesite] - specifies whether the browser should send this cookie along with cross-site requests
* @returns {(string|null)} cookie value (or null)
*/
function cookieString( name, value, options ) {
	var opts;
	var keys;
	var tmp;
	var k;
	var v;
	var i;

	opts = {
		'path': '/docs/api',
		'max-age': 31536000, // 60*60*24*365 (1 year)
		'secure': true,
		'samesite': 'strict'
	};
	if ( arguments.length > 2 ) {
		if ( options.path ) {
			opts.path = options.path;
		}
		if ( options.domain ) {
			opts.domain = options.domain;
		}
		if ( typeof options.maxAge === 'number' ) {
			opts[ 'max-age' ] = options.maxAge;
		}
		if ( options.expires ) {
			if ( options.expires instanceof Date ) {
				opts.expires = options.expires.toUTCString();
			} else {
				opts.expires = options.expires;
			}
		}
		if ( typeof options.secure === 'boolean' ) {
			opts.secure = options.secure;
		}
		if ( options.samesite ) {
			opts.samesite = options.samesite;
		}
	}
	tmp = [ name + '=' + encodeURIComponent( value ) ];
	keys = Object.keys( opts );
	for ( i = 0; i < keys.length; i++ ) {
		k = keys[ i ];
		v = opts[ k ];
		if ( k === 'secure' && v ) {
			tmp.push( k );
		} else {
			tmp.push( k + '=' + v );
		}
	}
	return tmp.join( '; ' );
}

// EXPORTS //

module.exports = cookieString;
<commit_msg>Set path based on configuration<commit_after>/**
* @license Apache-2.0
*
* Copyright (c) 2022 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

// MODULES //

var config = require( 'config' );

// MAIN //

/**
* Returns a cookie string for a provided name-value pair.
*
* @private
* @param {string} name - cookie name
* @param {string} value - cookie value
* @param {Object} [options] - cookie options
* @param {string} [options.path] - cookie path
* @param {string} [options.domain] - cookie domain
* @param {number} [options.maxAge] - maximum age (in seconds; takes precedence over `expire`)
* @param {(string|Date)} [options.expires] - cookie expiration date
* @param {boolean} [options.secure] - boolean indicating whether the cookie may only be transmitted over a secure protocol (e.g., HTTPS)
* @param {string} [options.samesite] - specifies whether the browser should send this cookie along with cross-site requests
* @returns {(string|null)} cookie value (or null)
*/
function cookieString( name, value, options ) {
	var opts;
	var keys;
	var tmp;
	var k;
	var v;
	var i;

	opts = {
		'path': config.mount,
		'max-age': 31536000, // 60*60*24*365 (1 year)
		'secure': true,
		'samesite': 'strict'
	};
	if ( arguments.length > 2 ) {
		if ( options.path ) {
			opts.path = options.path;
		}
		if ( options.domain ) {
			opts.domain = options.domain;
		}
		if ( typeof options.maxAge === 'number' ) {
			opts[ 'max-age' ] = options.maxAge;
		}
		if ( options.expires ) {
			if ( options.expires instanceof Date ) {
				opts.expires = options.expires.toUTCString();
			} else {
				opts.expires = options.expires;
			}
		}
		if ( typeof options.secure === 'boolean' ) {
			opts.secure = options.secure;
		}
		if ( options.samesite ) {
			opts.samesite = options.samesite;
		}
	}
	tmp = [ name + '=' + encodeURIComponent( value ) ];
	keys = Object.keys( opts );
	for ( i = 0; i < keys.length; i++ ) {
		k = keys[ i ];
		v = opts[ k ];
		if ( k === 'secure' && v ) {
			tmp.push( k );
		} else {
			tmp.push( k + '=' + v );
		}
	}
	return tmp.join( '; ' );
}

// EXPORTS //

module.exports = cookieString;
<|endoftext|>