<commit_before>/** section: Language, related to: Hash
 *  $H([object]) -> Hash
 *
 *  Creates a `Hash`. This is purely a convenience wrapper around the Hash
 *  constructor, it does not do anything other than pass any argument it's
 *  given into the Hash constructor and return the result.
 **/
function $H(object) {
  return new Hash(object);
};

/** section: Language
 * class Hash
 *  includes Enumerable
 *
 *  A set of key/value pairs.
 *
 *  `Hash` can be thought of as an associative array, binding unique keys to
 *  values (which are not necessarily unique), though it can not guarantee
 *  consistent order its elements when iterating. Because of the nature of
 *  JavaScript, every object is in fact a hash; but `Hash` adds a number of
 *  methods that let you enumerate keys and values, iterate over key/value
 *  pairs, merge two hashes together, and much more.
 *
 *
Creating a hash

 *
 *  You can create a Hash either via `new Hash()` or the convenience alias
 *  `$H()`; there is **no** difference between them. In either case, you may
 *  optionally pass in an object to seed the `Hash`. If you pass in a `Hash`,
 *  it will be cloned.
 *
**/
var Hash = Class.create(Enumerable, (function() {
  /**
   *  new Hash([object])
   *
   *  Creates a new `Hash`. If `object` is given, the new hash will be populated
   *  with all the object's properties. See [[$H]].
   **/
  function initialize(object) {
    this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
  }

  // Docs for #each even though technically it's implemented by Enumerable
  /**
   *  Hash#each(iterator[, context]) -> Hash
   *  - iterator (Function): A function that expects each item in the `Hash`
   *    as the first argument and a numerical index as the second.
   *  - context (Object): The scope in which to call `iterator`. Determines what
   *    `this` means inside `iterator`.
   *
   *  Iterates over the name/value pairs in the hash.
   *
   *  This is actually just the [[Enumerable#each #each]] method from the
   *  mixed-in [[Enumerable]] module. It is documented here to describe the
   *  structure of the elements passed to the iterator and the order of
   *  iteration.
   *
   *  The iterator's first argument (the "item") is an object with two
   *  properties:
   *
   *  - `key`: the key name as a `String`
   *  - `value`: the corresponding value (which may be `undefined`)
   *
   *  The order of iteration is implementation-dependent, as it relies on
   *  the order of the native `for..in` loop. Although most modern
   *  implementations exhibit *ordered* behavior, this is not standardized and
   *  may not always be the case, and so cannot be relied upon.
   *
   *  ### Example
   *
   *      var h = $H({version: 1.6, author: 'The Core Team'});
   *
   *      h.each(function(pair) {
   *        alert(pair.key + ' = "' + pair.value + '"');
   *      });
   *      // Alerts 'version = "1.6"' and 'author = "The Core Team"'
   *      // -or-
   *      // Alerts 'author = "The Core Team"' and 'version = "1.6"'
  **/

  // Our _internal_ each
  function _each(iterator) {
    for (var key in this._object) {
      var value = this._object[key], pair = [key, value];
      pair.key = key;
      pair.value = value;
      iterator(pair);
    }
  }

  /**
   *  Hash#set(key, value) -> value
   *
   *  Sets the hash's `key` property to `value` and returns `value`.
  **/
  function set(key, value) {
    return this._object[key] = value;
  }

  /**
   *  Hash#get(key) -> value
   *
   *  Returns the value of the hash's `key` property.
  **/
  function get(key) {
    // simulating poorly supported hasOwnProperty
    if (this._object[key] !== Object.prototype[key])
      return this._object[key];
  }

  /**
   *  Hash#unset(key) -> value
   *
   *  Deletes the hash's `key` property and returns its value.
  **/
  function unset(key) {
    var value = this._object[key];
    delete this._object[key];
    return value;
  }

  /**
   *  Hash#toObject() -> Object
   *
   *  Returns a cloned, vanilla object.
  **/
  function toObject() {
    return Object.clone(this._object);
  }

  /**
   *  Hash#keys() -> [String...]
   *
   *  Provides an Array of keys (that is, property names) for the hash.
  **/
  function keys() {
    return this.pluck('key');
  }

  /**
   *  Hash#values() -> Array
   *
   *  Collect the values of a hash and returns them in an array.
  **/
  function values() {
    return this.pluck('value');
  }

  /**
   *  Hash#index(value) -> String
   *
   *  Returns the first key in the hash whose value matches `value`.
   *  Returns `false` if there is no such key.
  **/
  function index(value) {
    var match = this.detect(function(pair) {
      return pair.value === value;
    });
    return match && match.key;
  }

  /**
   *  Hash#merge(object) -> Hash
   *
   *  Returns a new hash with `object`'s key/value pairs merged in.
   *  To modify the original hash in place, use [[Hash#update]].
   *
  **/
  function merge(object) {
    return this.clone().update(object);
  }

  /**
   *  Hash#update(object) -> Hash
   *
   *  Updates hash with the key/value pairs of `object`.
   *  The original hash will be modified. To return a new hash instead, use
   *  [[Hash#merge]].
  **/
  function update(object) {
    return new Hash(object).inject(this, function(result, pair) {
      result.set(pair.key, pair.value);
      return result;
    });
  }

  // Private. No PDoc necessary.
  function toQueryPair(key, value) {
    if (Object.isUndefined(value)) return key;
    return key + '=' + encodeURIComponent(String.interpret(value));
  }

  /** related to: String#toQueryParams
   *  Hash#toQueryString() -> String
   *
   *  Turns a hash into its URL-encoded query string representation.
  **/
  function toQueryString() {
    return this.inject([], function(results, pair) {
      var key = encodeURIComponent(pair.key), values = pair.value;

      if (values && typeof values == 'object') {
        if (Object.isArray(values))
          return results.concat(values.map(toQueryPair.curry(key)));
      } else results.push(toQueryPair(key, values));
      return results;
    }).join('&');
  }

  /** related to: Object.inspect
   *  Hash#inspect() -> String
   *
   *  Returns the debug-oriented string representation of the Hash.
  **/
  function inspect() {
    return '#<Hash:{' + this.map(function(pair) {
      return pair.map(Object.inspect).join(': ');
    }).join(', ') + '}>';
  }

  /** related to: Object.toJSON
   *  Hash#toJSON() -> String
   *
   *  Returns a JSON string.
  **/
  function toJSON() {
    return Object.toJSON(this.toObject());
  }

  /**
   *  Hash#clone() -> Hash
   *
   *  Returns a clone of this Hash.
  **/
  function clone() {
    return new Hash(this);
  }

  return {
    initialize:             initialize,
    _each:                  _each,
    set:                    set,
    get:                    get,
    unset:                  unset,
    toObject:               toObject,
    toTemplateReplacements: toObject,
    keys:                   keys,
    values:                 values,
    index:                  index,
    merge:                  merge,
    update:                 update,
    toQueryString:          toQueryString,
    inspect:                inspect,
    toJSON:                 toJSON,
    clone:                  clone
  };
})());

Hash.from = $H;
<commit_msg>doc: Merged old docs for Hash#get.<commit_after>/** section: Language, related to: Hash
 *  $H([object]) -> Hash
 *
 *  Creates a `Hash`. This is purely a convenience wrapper around the Hash
 *  constructor, it does not do anything other than pass any argument it's
 *  given into the Hash constructor and return the result.
 **/
function $H(object) {
  return new Hash(object);
};

/** section: Language
 * class Hash
 *  includes Enumerable
 *
 *  A set of key/value pairs.
 *
 *  `Hash` can be thought of as an associative array, binding unique keys to
 *  values (which are not necessarily unique), though it can not guarantee
 *  consistent order its elements when iterating. Because of the nature of
 *  JavaScript, every object is in fact a hash; but `Hash` adds a number of
 *  methods that let you enumerate keys and values, iterate over key/value
 *  pairs, merge two hashes together, and much more.
 *
 *
Creating a hash

 *
 *  You can create a Hash either via `new Hash()` or the convenience alias
 *  `$H()`; there is **no** difference between them. In either case, you may
 *  optionally pass in an object to seed the `Hash`. If you pass in a `Hash`,
 *  it will be cloned.
 *
**/
var Hash = Class.create(Enumerable, (function() {
  /**
   *  new Hash([object])
   *
   *  Creates a new `Hash`. If `object` is given, the new hash will be populated
   *  with all the object's properties. See [[$H]].
   **/
  function initialize(object) {
    this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
  }

  // Docs for #each even though technically it's implemented by Enumerable
  /**
   *  Hash#each(iterator[, context]) -> Hash
   *  - iterator (Function): A function that expects each item in the `Hash`
   *    as the first argument and a numerical index as the second.
   *  - context (Object): The scope in which to call `iterator`. Determines what
   *    `this` means inside `iterator`.
   *
   *  Iterates over the name/value pairs in the hash.
   *
   *  This is actually just the [[Enumerable#each #each]] method from the
   *  mixed-in [[Enumerable]] module. It is documented here to describe the
   *  structure of the elements passed to the iterator and the order of
   *  iteration.
   *
   *  The iterator's first argument (the "item") is an object with two
   *  properties:
   *
   *  - `key`: the key name as a `String`
   *  - `value`: the corresponding value (which may be `undefined`)
   *
   *  The order of iteration is implementation-dependent, as it relies on
   *  the order of the native `for..in` loop. Although most modern
   *  implementations exhibit *ordered* behavior, this is not standardized and
   *  may not always be the case, and so cannot be relied upon.
   *
   *  ### Example
   *
   *      var h = $H({version: 1.6, author: 'The Core Team'});
   *
   *      h.each(function(pair) {
   *        alert(pair.key + ' = "' + pair.value + '"');
   *      });
   *      // Alerts 'version = "1.6"' and 'author = "The Core Team"'
   *      // -or-
   *      // Alerts 'author = "The Core Team"' and 'version = "1.6"'
  **/

  // Our _internal_ each
  function _each(iterator) {
    for (var key in this._object) {
      var value = this._object[key], pair = [key, value];
      pair.key = key;
      pair.value = value;
      iterator(pair);
    }
  }

  /**
   *  Hash#set(key, value) -> value
   *
   *  Sets the hash's `key` property to `value` and returns `value`.
  **/
  function set(key, value) {
    return this._object[key] = value;
  }

  /**
   *  Hash#get(key) -> value
   *
   *  Returns the stored value for the given `key`.
   *
   *  ### Examples
   *
   *      var h = new Hash({a: 'apple', b: 'banana', c: 'coconut'});
   *      h.get('a');
   *      // -> 'apple'
  **/
  function get(key) {
    // simulating poorly supported hasOwnProperty
    if (this._object[key] !== Object.prototype[key])
      return this._object[key];
  }

  /**
   *  Hash#unset(key) -> value
   *
   *  Deletes the hash's `key` property and returns its value.
  **/
  function unset(key) {
    var value = this._object[key];
    delete this._object[key];
    return value;
  }

  /**
   *  Hash#toObject() -> Object
   *
   *  Returns a cloned, vanilla object.
  **/
  function toObject() {
    return Object.clone(this._object);
  }

  /**
   *  Hash#keys() -> [String...]
   *
   *  Provides an Array of keys (that is, property names) for the hash.
  **/
  function keys() {
    return this.pluck('key');
  }

  /**
   *  Hash#values() -> Array
   *
   *  Collect the values of a hash and returns them in an array.
  **/
  function values() {
    return this.pluck('value');
  }

  /**
   *  Hash#index(value) -> String
   *
   *  Returns the first key in the hash whose value matches `value`.
   *  Returns `false` if there is no such key.
  **/
  function index(value) {
    var match = this.detect(function(pair) {
      return pair.value === value;
    });
    return match && match.key;
  }

  /**
   *  Hash#merge(object) -> Hash
   *
   *  Returns a new hash with `object`'s key/value pairs merged in.
   *  To modify the original hash in place, use [[Hash#update]].
   *
  **/
  function merge(object) {
    return this.clone().update(object);
  }

  /**
   *  Hash#update(object) -> Hash
   *
   *  Updates hash with the key/value pairs of `object`.
   *  The original hash will be modified. To return a new hash instead, use
   *  [[Hash#merge]].
  **/
  function update(object) {
    return new Hash(object).inject(this, function(result, pair) {
      result.set(pair.key, pair.value);
      return result;
    });
  }

  // Private. No PDoc necessary.
  function toQueryPair(key, value) {
    if (Object.isUndefined(value)) return key;
    return key + '=' + encodeURIComponent(String.interpret(value));
  }

  /** related to: String#toQueryParams
   *  Hash#toQueryString() -> String
   *
   *  Turns a hash into its URL-encoded query string representation.
  **/
  function toQueryString() {
    return this.inject([], function(results, pair) {
      var key = encodeURIComponent(pair.key), values = pair.value;

      if (values && typeof values == 'object') {
        if (Object.isArray(values))
          return results.concat(values.map(toQueryPair.curry(key)));
      } else results.push(toQueryPair(key, values));
      return results;
    }).join('&');
  }

  /** related to: Object.inspect
   *  Hash#inspect() -> String
   *
   *  Returns the debug-oriented string representation of the Hash.
  **/
  function inspect() {
    return '#<Hash:{' + this.map(function(pair) {
      return pair.map(Object.inspect).join(': ');
    }).join(', ') + '}>';
  }

  /** related to: Object.toJSON
   *  Hash#toJSON() -> String
   *
   *  Returns a JSON string.
  **/
  function toJSON() {
    return Object.toJSON(this.toObject());
  }

  /**
   *  Hash#clone() -> Hash
   *
   *  Returns a clone of this Hash.
  **/
  function clone() {
    return new Hash(this);
  }

  return {
    initialize:             initialize,
    _each:                  _each,
    set:                    set,
    get:                    get,
    unset:                  unset,
    toObject:               toObject,
    toTemplateReplacements: toObject,
    keys:                   keys,
    values:                 values,
    index:                  index,
    merge:                  merge,
    update:                 update,
    toQueryString:          toQueryString,
    inspect:                inspect,
    toJSON:                 toJSON,
    clone:                  clone
  };
})());

Hash.from = $H;
<|endoftext|>


<commit_before>const databaseName = 'awstest';

module.exports = {
  development: {
    client: 'postgresql',
    connection: `postgres://localhost:5432/${databaseName}`,
    migrations: {
      directory: __dirname + '/src/server/db/migrations'
    },
    seeds: {
      directory: __dirname + '/src/server/db/seeds'
    }
  },
  test: {
    client: 'postgresql',
    connection: `postgres://localhost:5432/${databaseName}_test`,
    migrations: {
      directory: __dirname + '/src/server/db/migrations'
    },
    seeds: {
      directory: __dirname + '/src/server/db/seeds'
    }
  }
};
<commit_msg>New connection for production.<commit_after>const databaseName = 'awstest';

module.exports = {
  development: {
    client: 'postgresql',
    connection: `postgres://localhost:5432/${databaseName}`,
    migrations: {
      directory: __dirname + '/src/server/db/migrations'
    },
    seeds: {
      directory: __dirname + '/src/server/db/seeds'
    }
  },
  test: {
    client: 'postgresql',
    connection: `postgres://localhost:5432/${databaseName}_test`,
    migrations: {
      directory: __dirname + '/src/server/db/migrations'
    },
    seeds: {
      directory: __dirname + '/src/server/db/seeds'
    }
  },
  production: {
    client: 'postgresql',
    connection: `postgres://${process.env.RDS_HOSTNAME}:${process.env.RDS_PORT}/`,
    migrations: {
      directory: __dirname + '/src/server/db/migrations'
    },
    seeds: {
      directory: __dirname + '/src/server/db/seeds'
    }
  }
};
<|endoftext|>


<commit_before>const canvas = document.getElementById("knockout-canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

window.knockout = {};

knockout.game = new Game(18);
knockout.gui = new Gui(18);
knockout.ais = [];
let takeTurnFn = knockout.game.takeTurn.bind(knockout.game);
knockout.ais.push(new KnockoutAI(knockout.game.addPlayer("AI 1", "blue"), takeTurnFn));
knockout.ais.push(new KnockoutAI(knockout.game.addPlayer("AI 2", "red"), takeTurnFn));

knockout.game.startGame();
<commit_msg>format<commit_after>const canvas = document.getElementById("knockout-canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

window.knockout = {};

knockout.game = new Game(18);
knockout.gui = new Gui(18);
knockout.ais = [];
let takeTurnFn = knockout.game.takeTurn.bind(knockout.game);
knockout.ais.push(
  new KnockoutAI(knockout.game.addPlayer("AI 1", "blue"), takeTurnFn)
);
knockout.ais.push(
  new KnockoutAI(knockout.game.addPlayer("AI 2", "red"), takeTurnFn)
);

knockout.game.startGame();
<|endoftext|>


<commit_before>(function(resourceModule) {
  resourceModule
    .constant('resourcesConf', {
      basePath: 'http://localhost:5984/ventolone%2F',
      numberOfDocs: 10000
    })
    .factory('resourcesConf', function(configuration){
      return configuration.resources
    })
    .factory('Sample', function($resource, resourcesConf) {
      return $resource(resourcesConf.basePath + 'sample/_design/charts/_view/:viewName', {
        group: true,
        descending: false
      }, {
        time: makeView('time'),
        frequency: makeView('frequency'),
        stats: makeStatsView('stats'),
        dates: makeStatsView('dates'),
        statistics: makeStatsView('statistics', {
          group_level: 1
        }),
      })
    })
    .factory('Anemometer', function($resource, resourcesConf) {
      return $resource(resourcesConf.basePath + 'anemometer/:id', {}, {
        query: {
          isArray: true,
          method: 'GET',
          params: {
            id: '_all_docs',
            include_docs: true
          },
          transformResponse: function(data) {
            return getRows(data).map(function(item) {
              return item.doc
            })
          }
        }
      })
    })
    .factory('upload', function($http, $q, resourcesConf) {
      var numberOfDocs = resourcesConf.numberOfDocs
      return function(anemometer, iterator) {
        var numberOfUploads = Math.ceil(iterator.size() / numberOfDocs),
          promises = [],
          deferred = $q.defer()

          for (var i = 0; i < numberOfUploads; i++) {
            (function(batch) {
              var slice = iterator.slice(i * numberOfDocs, (i + 1) * numberOfDocs),
                promise = $http.post(resourcesConf.basePath + 'sample/_bulk_docs', {
                  docs: slice.map(function(item) {
                    if (item.length == 4 && item.reduce(function(acc, value) {
                      return acc && value != null && value != "" && angular.isNumber(parseFloat(value))
                    }, true)) {
                      return {
                        _id: anemometer._id + '_' + item[0],
                        a: anemometer._id,
                        t: item[0],
                        d: item[1],
                        p: item[2],
                        b: item[3],
                        s: item[2] / item[1] * 1.1176
                      }
                    }
                  }).filter(angular.identity)
                }).success(function() {
                  deferred.notify(batch)
                })

                promises.push(promise)
            }(i))

          };

        $q.all(promises).then(function(res) {
          deferred.resolve(res)
        })

        return {
          promise: deferred.promise,
          numberOfUploads: numberOfUploads
        }
      }
    })
    .factory('params', function($http, resourcesConf) {
      return $http({
        method: 'get',
        url: resourcesConf.basePath + 'sample/_design/charts',
        transformResponse: function(data) {
          var exports = {}
          eval(JSON.parse(data).views.lib.params)
          return exports
        }
      }).then(function(response) {
        return response.data
      })
    })

  function getRows(data) {
    return JSON.parse(data).rows
  }

  function makeView(viewName, isArray, transformResponse, params) {
    return {
      method: 'GET',
      transformResponse: transformResponse || getRows,
      isArray: isArray == null ? true : isArray,
      params: angular.extend({
        viewName: viewName,
        stale: 'update_after'
      }, params)
    }
  }

  function makeStatsView(viewName, params) {
    return makeView(viewName, false, function(data) {
      return (getRows(data)[0] || {}).value
    }, params || {})
  }
})(angular.module('Ventolone.resources', [
  'ngResource',
  'Ventolone.configuration'
]))
<commit_msg>removed outdated code<commit_after>(function(resourceModule) {
  resourceModule
    .factory('resourcesConf', function(configuration){
      return configuration.resources
    })
    .factory('Sample', function($resource, resourcesConf) {
      return $resource(resourcesConf.basePath + 'sample/_design/charts/_view/:viewName', {
        group: true,
        descending: false
      }, {
        time: makeView('time'),
        frequency: makeView('frequency'),
        stats: makeStatsView('stats'),
        dates: makeStatsView('dates'),
        statistics: makeStatsView('statistics', {
          group_level: 1
        }),
      })
    })
    .factory('Anemometer', function($resource, resourcesConf) {
      return $resource(resourcesConf.basePath + 'anemometer/:id', {}, {
        query: {
          isArray: true,
          method: 'GET',
          params: {
            id: '_all_docs',
            include_docs: true
          },
          transformResponse: function(data) {
            return getRows(data).map(function(item) {
              return item.doc
            })
          }
        }
      })
    })
    .factory('upload', function($http, $q, resourcesConf) {
      var numberOfDocs = resourcesConf.numberOfDocs
      return function(anemometer, iterator) {
        var numberOfUploads = Math.ceil(iterator.size() / numberOfDocs),
          promises = [],
          deferred = $q.defer()

          for (var i = 0; i < numberOfUploads; i++) {
            (function(batch) {
              var slice = iterator.slice(i * numberOfDocs, (i + 1) * numberOfDocs),
                promise = $http.post(resourcesConf.basePath + 'sample/_bulk_docs', {
                  docs: slice.map(function(item) {
                    if (item.length == 4 && item.reduce(function(acc, value) {
                      return acc && value != null && value != "" && angular.isNumber(parseFloat(value))
                    }, true)) {
                      return {
                        _id: anemometer._id + '_' + item[0],
                        a: anemometer._id,
                        t: item[0],
                        d: item[1],
                        p: item[2],
                        b: item[3],
                        s: item[2] / item[1] * 1.1176
                      }
                    }
                  }).filter(angular.identity)
                }).success(function() {
                  deferred.notify(batch)
                })

                promises.push(promise)
            }(i))

          };

        $q.all(promises).then(function(res) {
          deferred.resolve(res)
        })

        return {
          promise: deferred.promise,
          numberOfUploads: numberOfUploads
        }
      }
    })
    .factory('params', function($http, resourcesConf) {
      return $http({
        method: 'get',
        url: resourcesConf.basePath + 'sample/_design/charts',
        transformResponse: function(data) {
          var exports = {}
          eval(JSON.parse(data).views.lib.params)
          return exports
        }
      }).then(function(response) {
        return response.data
      })
    })

  function getRows(data) {
    return JSON.parse(data).rows
  }

  function makeView(viewName, isArray, transformResponse, params) {
    return {
      method: 'GET',
      transformResponse: transformResponse || getRows,
      isArray: isArray == null ? true : isArray,
      params: angular.extend({
        viewName: viewName,
        stale: 'update_after'
      }, params)
    }
  }

  function makeStatsView(viewName, params) {
    return makeView(viewName, false, function(data) {
      return (getRows(data)[0] || {}).value
    }, params || {})
  }
})(angular.module('Ventolone.resources', [
  'ngResource',
  'Ventolone.configuration'
]))
<|endoftext|>


<commit_before>/*
 * retrospec.js
 * https://github.com/ericsteele/retrospec.js
 *
 * Copyright (c) 2014 Eric Steele
 * Licensed under the MIT license.
 * https://github.com/ericsteele/retrospec.js/blob/master/LICENSE
 *
 * A regression test selection tool for JavaScript.
 */
'use strict';

// exports
module.exports = retrospec;

// libs
var FS      = require('fs'),        // file system
    Q       = require('q'),         // `kriskowal/q` promises
    path    = require('path');      // file path transform utils

// src
var log          = require('./helper/logger'),        // message logger
    fsHelper     = require('./helper/fs-helper'),     // file system helper methods
    buildProject = require('./helper/build-project'), // function that "builds" projects
    diffProjects = require('./helper/diff-projects'), // function that "diffs" projects
    metadata     = require('./helper/metadata'),      // project data storage
    selectTests  = require('./helper/select-tests');  // function that selects regression tests

// metadata extraction plugins
var extractors = {
  // code module
  'angular-module-extractor':            require('./extractors/angular-module-extractor'),
  'requirejs-module-extractor':          require('./extractors/requirejs-module-extractor'),
  // test suite
  'inline-comment-test-suite-extractor': require('./extractors/requirejs-module-extractor'),
  'angular-karma-test-suite-extractor':  require('./extractors/angular-karma-test-suite-extractor'),
  'jqm-test-suite-extractor':            require('./extractors/jqm-test-suite-extractor'),
};

// test execution plugins
var executors = {
  'angular-test-suite-executor': require('./executors/angular-test-suite-executor'),
  'jqm-test-suite-executor-144': require('./executors/jqm-test-suite-executor-144'),
  'jqm-test-suite-executor-131': require('./executors/jqm-test-suite-executor-131')
};

// add Q promise support to file system operations
var readFile = Q.nfbind(FS.readFile);

// current working directory
var cwd = process.cwd();

// CLI arguments
var cliArgs;

/**
 * Invoked by retrospec-cli.
 */
retrospec.cli = function(args) {
  cliArgs = args;

  // read config and run retrospec
  readFile(cliArgs.configPath, 'utf-8')
     .then(parseConfig, log.error)
     .then(retrospec, log.error);

  // parses the config JSON
  function parseConfig(configJSON) {
    log.info('config: ' + configJSON);
    return JSON.parse(configJSON);
  }
};

/**
 * Retrospec's public API.
 *
 * @param  {Object} config - an object with the following structure:
 *
 *  {
 *    "src": {
 *      "path":      {String}  - relative path of the project's source code folder
 *      "blobs":     {Array}   - blobs used to find source code files
 *      "extractor": {String}  - name of the code module extractor to use
 *    },
 *    "test": {
 *      "path":      {String}  - relative path of the project's test code folder
 *      "blobs":     {Array}   - blobs used to find test files
 *      "extractor": {String}  - name of the test suite extractor to use
 *      "executor":  {String}  - name of the test suite executor to use
 *    }
 *  }
 *
 */
function retrospec(config) {
  printHeader();
  validateConfig(config);

  var testExecutor = getExecutor(config.test.executor);

  // project metadata
  var original, // read from metadata in file
      modified; // built from the project's files

  Q(cliArgs.options.reset)
  .then(function (reset) { if(reset) return metadata.reset(cwd); })
  .then(getProjects)
  .then(getTests)
  .then(runTests)
  .then(storeMetadata);

  function getProjects() {
    return Q.all([
      metadata.read(cwd),
      buildProject({
        srcBlobs:      config.src.blobs,
        testBlobs:     config.test.blobs,
        srcDirPath:    path.resolve(cwd, config.src.path),
        testDirPath:   path.resolve(cwd, config.test.path),
        srcExtractor:  getExtractor(config.src.extractor),
        testExtractor: getExtractor(config.test.extractor)
      })
    ]);
  }

  function getTests(projects) {
    original = projects[0];
    modified = projects[1];

    if(original) {
      return selectTests(original, modified);
    }
  }

  function runTests(testPaths) {
    if(testPaths && testPaths.length > 0) {
      return testExecutor.executeTests(testPaths);
    }
  }

  function storeMetadata() {
    if(cliArgs.options.save) {
      return metadata.store(modified, cwd);
    }
  }

}

/**
 * Validates the arguments provided to retrospec.
 *
 * @param  {Object} config - an object with the following structure:
 *
 *  {
 *    "src": {
 *      "path":      {String}  - relative path of the project's source code folder
 *      "blobs":     {Array}   - blobs used to find source code files
 *      "extractor": {String}  - name of the code module extractor to use
 *    },
 *    "test": {
 *      "path":      {String}  - relative path of the project's test code folder
 *      "blobs":     {Array}   - blobs used to find test files
 *      "extractor": {String}  - name of the test suite extractor to use
 *      "executor":  {String}  - name of the test suite executor to use
 *    }
 *  }
 */
function validateConfig(config) {
  if(!config)                throw Error('missing argument "config"');
  if(!config.src)            throw Error('missing argument "config.src"');
  if(!config.src.path)       throw Error('missing argument "config.src.path"');
  if(!config.src.extractor)  throw Error('missing argument "config.src.extractor"');
  if(!config.src)            throw Error('missing argument "config.src"');
  if(!config.src.path)       throw Error('missing argument "config.src.path"');
  if(!config.test)           throw Error('missing argument "config.test"');
  if(!config.test.extractor) throw Error('missing argument "config.test.extractor"');
  if(!config.test.executor)  throw Error('missing argument "config.test.executor"');
}

/**
 * [getExtractor description]
 *
 * @param  {[type]} id [description]
 *
 * @return {[type]}    [description]
 */
function getExtractor(id) {
  // TODO(Eric): need to handle arg as object or function
  if(extractors.hasOwnProperty(id)) {
    return extractors[id];
  }
  throw new Error('could not find extractor "' + id + '"');
}

/**
 * [getExecutor description]
 *
 * @param  {[type]} id [description]
 *
 * @return {[type]}    [description]
 */
function getExecutor(id) {
  // TODO(Eric): need to handle arg as object or function
  if(executors.hasOwnProperty(id)) {
    return executors[id];
  }
  throw new Error('could not find executor "' + id + '"');
}

/**
 * Prints the program header message.
 */
function printHeader() {
  log.divider();
  log.msg(' retrospec.js');
  log.divider();
  log.info('args: ' + JSON.stringify(cliArgs));
}<commit_msg>Fixed Bug: Incorrect reference to angular.js executor after its name was changed.<commit_after>/*
 * retrospec.js
 * https://github.com/ericsteele/retrospec.js
 *
 * Copyright (c) 2014 Eric Steele
 * Licensed under the MIT license.
 * https://github.com/ericsteele/retrospec.js/blob/master/LICENSE
 *
 * A regression test selection tool for JavaScript.
 */
'use strict';

// exports
module.exports = retrospec;

// libs
var FS      = require('fs'),        // file system
    Q       = require('q'),         // `kriskowal/q` promises
    path    = require('path');      // file path transform utils

// src
var log          = require('./helper/logger'),        // message logger
    fsHelper     = require('./helper/fs-helper'),     // file system helper methods
    buildProject = require('./helper/build-project'), // function that "builds" projects
    diffProjects = require('./helper/diff-projects'), // function that "diffs" projects
    metadata     = require('./helper/metadata'),      // project data storage
    selectTests  = require('./helper/select-tests');  // function that selects regression tests

// metadata extraction plugins
var extractors = {
  // code module
  'angular-module-extractor':            require('./extractors/angular-module-extractor'),
  'requirejs-module-extractor':          require('./extractors/requirejs-module-extractor'),
  // test suite
  'inline-comment-test-suite-extractor': require('./extractors/requirejs-module-extractor'),
  'angular-karma-test-suite-extractor':  require('./extractors/angular-karma-test-suite-extractor'),
  'jqm-test-suite-extractor':            require('./extractors/jqm-test-suite-extractor'),
};

// test execution plugins
var executors = {
  'angular-js-test-suite-executor': require('./executors/angular-js-test-suite-executor'),
  'jqm-test-suite-executor-144':    require('./executors/jqm-test-suite-executor-144'),
  'jqm-test-suite-executor-131':    require('./executors/jqm-test-suite-executor-131')
};

// add Q promise support to file system operations
var readFile = Q.nfbind(FS.readFile);

// current working directory
var cwd = process.cwd();

// CLI arguments
var cliArgs;

/**
 * Invoked by retrospec-cli.
 */
retrospec.cli = function(args) {
  cliArgs = args;

  // read config and run retrospec
  readFile(cliArgs.configPath, 'utf-8')
     .then(parseConfig, log.error)
     .then(retrospec, log.error);

  // parses the config JSON
  function parseConfig(configJSON) {
    log.info('config: ' + configJSON);
    return JSON.parse(configJSON);
  }
};

/**
 * Retrospec's public API.
 *
 * @param  {Object} config - an object with the following structure:
 *
 *  {
 *    "src": {
 *      "path":      {String}  - relative path of the project's source code folder
 *      "blobs":     {Array}   - blobs used to find source code files
 *      "extractor": {String}  - name of the code module extractor to use
 *    },
 *    "test": {
 *      "path":      {String}  - relative path of the project's test code folder
 *      "blobs":     {Array}   - blobs used to find test files
 *      "extractor": {String}  - name of the test suite extractor to use
 *      "executor":  {String}  - name of the test suite executor to use
 *    }
 *  }
 *
 */
function retrospec(config) {
  printHeader();
  validateConfig(config);

  var testExecutor = getExecutor(config.test.executor);

  // project metadata
  var original, // read from metadata in file
      modified; // built from the project's files

  Q(cliArgs.options.reset)
  .then(function (reset) { if(reset) return metadata.reset(cwd); })
  .then(getProjects)
  .then(getTests)
  .then(runTests)
  .then(storeMetadata);

  function getProjects() {
    return Q.all([
      metadata.read(cwd),
      buildProject({
        srcBlobs:      config.src.blobs,
        testBlobs:     config.test.blobs,
        srcDirPath:    path.resolve(cwd, config.src.path),
        testDirPath:   path.resolve(cwd, config.test.path),
        srcExtractor:  getExtractor(config.src.extractor),
        testExtractor: getExtractor(config.test.extractor)
      })
    ]);
  }

  function getTests(projects) {
    original = projects[0];
    modified = projects[1];

    if(original) {
      return selectTests(original, modified);
    }
  }

  function runTests(testPaths) {
    if(testPaths && testPaths.length > 0) {
      return testExecutor.executeTests(testPaths);
    }
  }

  function storeMetadata() {
    if(cliArgs.options.save) {
      return metadata.store(modified, cwd);
    }
  }

}

/**
 * Validates the arguments provided to retrospec.
 *
 * @param  {Object} config - an object with the following structure:
 *
 *  {
 *    "src": {
 *      "path":      {String}  - relative path of the project's source code folder
 *      "blobs":     {Array}   - blobs used to find source code files
 *      "extractor": {String}  - name of the code module extractor to use
 *    },
 *    "test": {
 *      "path":      {String}  - relative path of the project's test code folder
 *      "blobs":     {Array}   - blobs used to find test files
 *      "extractor": {String}  - name of the test suite extractor to use
 *      "executor":  {String}  - name of the test suite executor to use
 *    }
 *  }
 */
function validateConfig(config) {
  if(!config)                throw Error('missing argument "config"');
  if(!config.src)            throw Error('missing argument "config.src"');
  if(!config.src.path)       throw Error('missing argument "config.src.path"');
  if(!config.src.extractor)  throw Error('missing argument "config.src.extractor"');
  if(!config.src)            throw Error('missing argument "config.src"');
  if(!config.src.path)       throw Error('missing argument "config.src.path"');
  if(!config.test)           throw Error('missing argument "config.test"');
  if(!config.test.extractor) throw Error('missing argument "config.test.extractor"');
  if(!config.test.executor)  throw Error('missing argument "config.test.executor"');
}

/**
 * [getExtractor description]
 *
 * @param  {[type]} id [description]
 *
 * @return {[type]}    [description]
 */
function getExtractor(id) {
  // TODO(Eric): need to handle arg as object or function
  if(extractors.hasOwnProperty(id)) {
    return extractors[id];
  }
  throw new Error('could not find extractor "' + id + '"');
}

/**
 * [getExecutor description]
 *
 * @param  {[type]} id [description]
 *
 * @return {[type]}    [description]
 */
function getExecutor(id) {
  // TODO(Eric): need to handle arg as object or function
  if(executors.hasOwnProperty(id)) {
    return executors[id];
  }
  throw new Error('could not find executor "' + id + '"');
}

/**
 * Prints the program header message.
 */
function printHeader() {
  log.divider();
  log.msg(' retrospec.js');
  log.divider();
  log.info('args: ' + JSON.stringify(cliArgs));
}<|endoftext|>


<commit_before>var fs = require('fs')
var Path = require('path')
var mapValues = require('lodash.mapvalues')
var csv = require('csv-parser')
var runAuto = require('run-auto')
var through = require('through2')
var uuid = require('node-uuid')
var assign = require('lodash.assign')
var Url = require('url')
var config = require('config')
var debug = require('debug')('holodex:read-csv-data')

var store = require('base/store')
var types = require('types')
var typesByCollection = types.indexedByCollection

module.exports = readData

function readData (opts, cb) {
  var graph = []
  var tasks = mapValues(typesByCollection, function (type, collectionName) {
    return getCollection({
      dir: opts.dir,
      type: type,
      collectionName: collectionName,
      graph: graph
    })
  })
  runAuto(tasks, function (err) {
    if (err) { return cb(err) }
    cb(null, graph)
  })
}

function getCollection (opts) {
  var task = [function (cb, results) {
    readCollection({
      dir: opts.dir,
      collectionName: opts.collectionName
    })
    .pipe(trimify())
    .pipe(typify(opts.collectionName, opts.graph))
    .on('end', function () {
      debug('got', opts.collectionName)
      cb()
    })
    .on('error', cb)
    .resume()
  }]
  if (opts.collectionName === 'relationships') {
    task.unshift('people', 'groups', 'roleTypes', 'relationshipTypes', 'linkTypes')
  }
  return task
}

function readCollection (opts) {
  var fileName = Path.join(opts.dir, opts.collectionName + '.csv')
  var stream = fs.createReadStream(fileName)

  stream.on('error', function (err) {
    // if file not found, end stream
    // TODO check for specific error
    console.log(err.message)
    this.push(null)
  })

  return stream.pipe(csv())
}

function trimify () {
  return through.obj(function (data, enc, cb) {
    cb(null, mapValues(data, function (val) {
      return val.trim()
    }))
  })
}

function typify (collectionName, graph) {
  var type = types.indexedByCollection[collectionName]
  var Model = type.Model

  // hard-coded parsers for types of data
  // TODO fix HACK
  var parsers = {
    Role: function parseRole (attrs) {
      return {
        id: 'roles/' + uuid(),
        type: 'roleTypes/' + attrs.role,
        agent: 'people/' + attrs.agent
      }
    },
    RoleType: function parseRoleType (attrs) {
      return assign(attrs, {
        relationshipType: 'relationshipTypes/' + attrs.relationshipType
      })
    },
    LinkType: function parseLinkType (attrs) {
      return assign(attrs, {
        relationshipType: 'relationshipTypes/' + attrs.relationshipType,
        source: 'roleTypes/' + attrs.source,
        target: 'roleTypes/' + attrs.target
      })
    },
    Relationship: function parseRelationship (attrs) {
      var apiUrl = Url.format(config.api.url)
      var linkType = store.findById(apiUrl + '/linkTypes/' + attrs.link)

      var relId = 'relationships/' + uuid()

      var sourceRole = Model.new({
        '@id': uuid(),
        '@type': 'Role',
        type: linkType.source.getId(),
        agent: findAgent(attrs.source).getId(),
        relationship: relId
      })
      var targetRole = Model.new({
        '@id': uuid(),
        '@type': 'Role',
        type: linkType.target.getId(),
        agent: findAgent(attrs.target).getId(),
        relationship: relId
      })

      graph.push(sourceRole, targetRole)

      return {
        id: uuid(),
        type: linkType.relationshipType.getId(),
      }
    }
  }

  return through.obj(function (attrs, enc, cb) {

    var type = Model.prototype.getType()

    if (parsers[type]) {
      attrs = parsers[type](attrs)
    }

    if (attrs.id == null) {
      attrs.id = uuid()
    }

    // rename idAttribute to '@id'
    attrs['@id'] = collectionName + '/' + attrs.id
    delete attrs.id

    // add '@type' attribute
    attrs['@type'] = type

    var model = Model.new(attrs)

    model.save()

    graph.push(model)

    cb(null, model)
  })
}

function print () {
  return through.obj(function (model, enc, cb) {
    console.log(model.toJSON())
    cb()
  })
}

function findAgent (id) {
  var apiUrl = Url.format(config.api.url)
  return store.findById(apiUrl + '/people/' + id) ||
    store.findById(apiUrl + '/groups/' + id)
}
<commit_msg>debugs<commit_after>var fs = require('fs')
var Path = require('path')
var mapValues = require('lodash.mapvalues')
var csv = require('csv-parser')
var runAuto = require('run-auto')
var through = require('through2')
var uuid = require('node-uuid')
var assign = require('lodash.assign')
var Url = require('url')
var config = require('config')
var debug = require('debug')('holodex:read-csv-data')

var store = require('base/store')
var types = require('types')
var typesByCollection = types.indexedByCollection

module.exports = readData

function readData (opts, cb) {
  var graph = []
  var tasks = mapValues(typesByCollection, function (type, collectionName) {
    return getCollection({
      dir: opts.dir,
      type: type,
      collectionName: collectionName,
      graph: graph
    })
  })
  runAuto(tasks, function (err) {
    if (err) { return cb(err) }
    cb(null, graph)
  })
}

function getCollection (opts) {
  var task = [function (cb, results) {
    debug('starting', opts.collectionName)
    readCollection({
      dir: opts.dir,
      collectionName: opts.collectionName
    })
    .pipe(trimify())
    .pipe(typify(opts.collectionName, opts.graph))
    .on('end', function () {
      debug('finished', opts.collectionName)
      cb()
    })
    .on('error', cb)
    .resume()
  }]
  if (opts.collectionName === 'relationships') {
    task.unshift('people', 'groups', 'roleTypes', 'relationshipTypes', 'linkTypes')
  }
  return task
}

function readCollection (opts) {
  var fileName = Path.join(opts.dir, opts.collectionName + '.csv')
  var stream = fs.createReadStream(fileName)

  stream.on('error', function (err) {
    // if file not found, end stream
    // TODO check for specific error
    console.log(err.message)
    this.push(null)
  })

  return stream.pipe(csv())
}

function trimify () {
  return through.obj(function (data, enc, cb) {
    cb(null, mapValues(data, function (val) {
      return val.trim()
    }))
  })
}

function typify (collectionName, graph) {
  var type = types.indexedByCollection[collectionName]
  var Model = type.Model

  // hard-coded parsers for types of data
  // TODO fix HACK
  var parsers = {
    Role: function parseRole (attrs) {
      return {
        id: 'roles/' + uuid(),
        type: 'roleTypes/' + attrs.role,
        agent: 'people/' + attrs.agent
      }
    },
    RoleType: function parseRoleType (attrs) {
      return assign(attrs, {
        relationshipType: 'relationshipTypes/' + attrs.relationshipType
      })
    },
    LinkType: function parseLinkType (attrs) {
      return assign(attrs, {
        relationshipType: 'relationshipTypes/' + attrs.relationshipType,
        source: 'roleTypes/' + attrs.source,
        target: 'roleTypes/' + attrs.target
      })
    },
    Relationship: function parseRelationship (attrs) {
      var apiUrl = Url.format(config.api.url)
      var linkType = store.findById(apiUrl + '/linkTypes/' + attrs.link)

      var relId = 'relationships/' + uuid()

      var sourceRole = Model.new({
        '@id': uuid(),
        '@type': 'Role',
        type: linkType.source.getId(),
        agent: findAgent(attrs.source).getId(),
        relationship: relId
      })
      var targetRole = Model.new({
        '@id': uuid(),
        '@type': 'Role',
        type: linkType.target.getId(),
        agent: findAgent(attrs.target).getId(),
        relationship: relId
      })

      graph.push(sourceRole, targetRole)

      return {
        id: uuid(),
        type: linkType.relationshipType.getId(),
      }
    }
  }

  return through.obj(function (attrs, enc, cb) {

    var type = Model.prototype.getType()

    if (parsers[type]) {
      attrs = parsers[type](attrs)
    }

    if (attrs.id == null) {
      attrs.id = uuid()
    }

    // rename idAttribute to '@id'
    attrs['@id'] = collectionName + '/' + attrs.id
    delete attrs.id

    // add '@type' attribute
    attrs['@type'] = type

    var model = Model.new(attrs)

    model.save()

    graph.push(model)

    cb(null, model)
  })
}

function print () {
  return through.obj(function (model, enc, cb) {
    console.log(model.toJSON())
    cb()
  })
}

function findAgent (id) {
  var apiUrl = Url.format(config.api.url)
  return store.findById(apiUrl + '/people/' + id) ||
    store.findById(apiUrl + '/groups/' + id)
}
<|endoftext|>


<commit_before>// require("systemjs");

// var lang = require("lively.lang");

(function() {

  function get(url, thenDo) {
    var res, rej, p;
    if (typeof Promise === "function") p = new Promise(function(resolve, reject) { res = resolve; rej = reject; });
    var xhr = new XMLHttpRequest();
    xhr.onerror = function(err) { thenDo && thenDo(err); rej && rej(err); };
    xhr.onreadystatechange = function() {
      if (xhr.readyState == XMLHttpRequest.DONE) {
        thenDo && thenDo(null, xhr.responseText)
        res && res(xhr.responseText)
      }
    };
    xhr.open('GET', url, true); xhr.send(null);
    return p;
  }

  // var root = (function() {
  //   var l = document.location;
  //   return `${l.protocol}//${l.hostname}:${l.port}`
  // })();

  // configures current SystemJS instance to load lively.vm + deps
  function configure(vmPath) {
    return get(vmPath + "/dist/es6-runtime-config-browser.json")
      .then(function(conf) {
        var config = JSON.parse(conf);
        config.baseURL = "/";
        // config.baseURL = System.baseURL;
        config.map["lively.vm"] = vmPath;
        if (!config.paths) config.paths = {};
        config.paths["lively.vm/*"] = vmPath + "/*";
        System.config(config);
        return config;
      })
  }

  // async load of ./index.js
  function load(vmPath) {
    return configure(vmPath)
      .then(function() { return System.import("lively.vm")})
      .then(function(vm) {
        if (!window.lively) window.lively = {};
        window.lively.vm = vm;
        vm.setBootstrapFunction(bootstrap); // vm.bootstrap = bootstrap;
        vm.setLoadFunction(load); // vm.load = load;
        vm.setConfigureFunction(configure); // vm.configure = configure;
        return vm;
      });
  }

  function bootstrap(vmPath) {
    var vm = window.lively && window.lively.vm;

    return new Promise(function(resolve) { return resolve(!vm || !vm.es6 ? load(vmPath) : vm); })
      .then(function(vm) {
        console.log("[lively.vm bootstrap] loaded boot vm");
        // FIXME remove loaded global stuff?
        vm.es6._init(); // create a new System instance
        vm.es6.wrapModuleLoad();
        return load(vmPath);
      })
      .then(function(vm) {
        console.log("[lively.vm bootstrap] loaded bootstraped vm");
        return vm;
      });
  }

  // a hack: to force non esm files that have es6 syntax in them to be
  // transpiled. SystemJS only transpiles proper es6 modules
  var es5CompatFiles = [];
  System._ensureES5Transpile = function(files) {
    es5CompatFiles.push.apply(es5CompatFiles, files);
    if (!System.__es5CompatFetchHookInstalled) {
      System.__es5CompatFetchHookInstalled = true;
      System.fetch = function(load) {
        return this.constructor.prototype.fetch.call(this, load)
          .then(function(source) {
            if (es5CompatFiles.some(function(f) { return load.name.indexOf(f) > -1; })) {
              console.log("[_ensureES5Transpile] " + load.name);
              source = load.source = babel.transform(source, {stage: 2}).code;
            }
            return source;
          });
      }
    }
  }

  if (!window.lively) window.lively = {};
  if (!window.lively.vm) window.lively.vm = {};

  if (window.lively.vm.setBootstrapFunction) window.lively.vm.setBootstrapFunction(bootstrap);
  else window.lively.vm.bootstrap = bootstrap;
  if (window.lively.vm.setLoadFunction) window.lively.vm.setLoadFunction(load);
  else window.lively.vm.load = load;
  if (window.lively.vm.setConfigureFunction) window.lively.vm.setConfigureFunction(configure);
  else window.lively.vm.configure = configure;
})();
<commit_msg>init fix<commit_after>// require("systemjs");

// var lang = require("lively.lang");

(function() {

  function get(url, thenDo) {
    var res, rej, p;
    if (typeof Promise === "function") p = new Promise(function(resolve, reject) { res = resolve; rej = reject; });
    var xhr = new XMLHttpRequest();
    xhr.onerror = function(err) { thenDo && thenDo(err); rej && rej(err); };
    xhr.onreadystatechange = function() {
      if (xhr.readyState == XMLHttpRequest.DONE) {
        thenDo && thenDo(null, xhr.responseText)
        res && res(xhr.responseText)
      }
    };
    xhr.open('GET', url, true); xhr.send(null);
    return p;
  }

  // var root = (function() {
  //   var l = document.location;
  //   return `${l.protocol}//${l.hostname}:${l.port}`
  // })();

  // configures current SystemJS instance to load lively.vm + deps
  function configure(vmPath) {
    return Promise.resolve(System.config({
            "transpiler": "babel",
            "babelOptions": {"stage": 2},
              map: {
                "lively.vm": vmPath,
                "babel": "lively.vm/node_modules/babel-core/browser.js",
                "path": "@empty",
                "module": "@empty",
                "fs": "@empty"

              },
              // packages: {"acorn": { format: "cjs", },},
              paths: {"lively.vm/*": vmPath + "/*"},
              packageConfigPaths: [
                "lively.vm/node_modules/lively.ast/node_modules/*/package.json",
                "lively.vm/node_modules/*/package.json",
                "lively.vm/package.json"]
            }))
  }

  // async load of ./index.js
  function load(vmPath) {
    return configure(vmPath)
      .then(function() { return System.import("lively.vm")})
      .then(function(vm) {
        if (!window.lively) window.lively = {};
        window.lively.vm = vm;
        vm.setBootstrapFunction(bootstrap); // vm.bootstrap = bootstrap;
        vm.setLoadFunction(load); // vm.load = load;
        vm.setConfigureFunction(configure); // vm.configure = configure;
        return vm;
      });
  }

  function bootstrap(vmPath) {
    var vm = window.lively && window.lively.vm;

    return new Promise(function(resolve) { return resolve(!vm || !vm.es6 ? load(vmPath) : vm); })
      .then(function(vm) {
        console.log("[lively.vm bootstrap] loaded boot vm");
        // FIXME remove loaded global stuff?
        vm.es6._init(); // create a new System instance
        vm.es6.wrapModuleLoad();
        return load(vmPath);
      })
      .then(function(vm) {
        console.log("[lively.vm bootstrap] loaded bootstraped vm");
        return vm;
      });
  }

  // a hack: to force non esm files that have es6 syntax in them to be
  // transpiled. SystemJS only transpiles proper es6 modules
  var es5CompatFiles = [];
  System._ensureES5Transpile = function(files) {
    es5CompatFiles.push.apply(es5CompatFiles, files);
    if (!System.__es5CompatFetchHookInstalled) {
      System.__es5CompatFetchHookInstalled = true;
      System.fetch = function(load) {
        return this.constructor.prototype.fetch.call(this, load)
          .then(function(source) {
            if (es5CompatFiles.some(function(f) { return load.name.indexOf(f) > -1; })) {
              console.log("[_ensureES5Transpile] " + load.name);
              source = load.source = babel.transform(source, {stage: 2}).code;
            }
            return source;
          });
      }
    }
  }

  if (!window.lively) window.lively = {};
  if (!window.lively.vm) window.lively.vm = {};

  if (window.lively.vm.setBootstrapFunction) window.lively.vm.setBootstrapFunction(bootstrap);
  else window.lively.vm.bootstrap = bootstrap;
  if (window.lively.vm.setLoadFunction) window.lively.vm.setLoadFunction(load);
  else window.lively.vm.load = load;
  if (window.lively.vm.setConfigureFunction) window.lively.vm.setConfigureFunction(configure);
  else window.lively.vm.configure = configure;
})();
<|endoftext|>


<commit_before>'use babel'

import FS from 'fs'
import Path from 'path'
import {template} from '../defaults'
import {normalizePath} from './common'

const debug = require('debug')('UCompiler:Save')

export function saveFile(contents, config, {root, relativePath, absolutePath}, state) {
  const output = config.outputPath

  if (output === '-') {
    process.stdout.write(contents)
    return contents
  } else if (output === '--') {
    return contents
  } else {
    const parsed = Path.parse(absolutePath)
    const absoluteDir = normalizePath(Path.dirname(absolutePath))
    const relativeDir = normalizePath(Path.relative(root, absoluteDir))

    let outputPath = template.render(output, {
      name: parsed.name,
      nameWithExt: parsed.name + parsed.ext,
      ext: parsed.ext.substr(1),
      root: root,
      relativePath: relativePath,
      relativeDir: relativeDir + '/',
      absolutePath: absolutePath,
      absoluteDir: absoluteDir + '/',
      state: state
    })

    if (config.outputPathTrim) {
      outputPath = outputPath.replace(config.outputPathTrim, '')
    }

    if (outputPath.indexOf('/') === -1) {
      outputPath = Path.join(absoluteDir, outputPath)
    } else if (!Path.isAbsolute(outputPath)) {
      outputPath = Path.join(root, outputPath)
    }

    debug(`Saving ${relativePath} to ${normalizePath(Path.relative(root, outputPath))}`)
    return new Promise(function(resolve, reject) {
      FS.writeFile(outputPath, contents, function(err) {
        if (err) {
          reject(err)
        } else resolve(contents)
      })
    })
  }
}
<commit_msg>:new: Automatically create required directories<commit_after>'use babel'

import FS from 'fs'
import Path from 'path'
import {template} from '../defaults'
import {normalizePath} from './common'
import mkdirp from 'mkdirp'

const debug = require('debug')('UCompiler:Save')

export function saveFile(contents, config, {root, relativePath, absolutePath}, state) {
  const output = config.outputPath

  if (output === '-') {
    process.stdout.write(contents)
    return contents
  } else if (output === '--') {
    return contents
  } else {
    const parsed = Path.parse(absolutePath)
    const absoluteDir = normalizePath(Path.dirname(absolutePath))
    const relativeDir = normalizePath(Path.relative(root, absoluteDir))

    let outputPath = template.render(output, {
      name: parsed.name,
      nameWithExt: parsed.name + parsed.ext,
      ext: parsed.ext.substr(1),
      root: root,
      relativePath: relativePath,
      relativeDir: relativeDir + '/',
      absolutePath: absolutePath,
      absoluteDir: absoluteDir + '/',
      state: state
    })

    if (config.outputPathTrim) {
      outputPath = outputPath.replace(config.outputPathTrim, '')
    }

    if (outputPath.indexOf('/') === -1) {
      outputPath = Path.join(absoluteDir, outputPath)
    } else if (!Path.isAbsolute(outputPath)) {
      outputPath = Path.join(root, outputPath)
    }

    debug(`Saving ${relativePath} to ${normalizePath(Path.relative(root, outputPath))}`)
    let firstTime = true
    return new Promise(function writeFile(resolve, reject) {
      FS.writeFile(outputPath, contents, function(err) {
        if (err) {
          if (err.code === 'ENOENT' && firstTime) {
            firstTime = false
            mkdirp(Path.dirname(outputPath), function(err) {
              if (err) {
                reject(err)
              } else writeFile(resolve, reject)
            })
          } else {
            reject(err)
          }
        } else resolve(contents)
      })
    })
  }
}
<|endoftext|>


<commit_before>/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import Card from './compoment/Card'

import {
  AppRegistry,
  StyleSheet,
  Text,
  ScrollView,
  Image,
  Dimensions,
  View,
  ToolbarAndroid,
  Alert,
  RefreshControl
} from 'react-native';

var {height, width} = Dimensions.get('window');
var nativeImageSource = require('nativeImageSource');

export default class listApp extends Component {

  constructor(props) {
    super(props);

    this.state = {
      images: [],
      refreshing: false,
    };
  }

  componentDidMount() {
     let datas =
      [{
         id: 0,
         url: 'http://d2ku7ggsvxaz7z.cloudfront.net/images/bam/3/MAI_180418427.jpg',
         title: '兩個小孩的托育費用就高達26500元',
         booking: true
       },
       {
         id: 1,
         url: 'http://d2ku7ggsvxaz7z.cloudfront.net/images/bam/9/MAI_144434087.png',
         title: 'AI金融應用－保險',
         booking: false
       },
       {
         id: 2,
         url: 'http://d2ku7ggsvxaz7z.cloudfront.net/images/bam/3/MAI_180418427.jpg',
         title: '兩個小孩的托育費用就高達26500元',
         booking: true
       },
       {
         id: 3,
         url: 'http://d2ku7ggsvxaz7z.cloudfront.net/images/bam/9/MAI_144434087.png',
         title: '兩個小孩的托育費用就高達26500元',
         booking: false
       }];

     this.setState({ images: datas});
  }

  _onRefresh() {
    this.setState({refreshing: true});

    this.setState({refreshing: false});
  }

  render() {
    const routes = [
      { title: 'First Scene', index: 0},
      { title: 'Second Scene', index: 1},
    ];

    buttonPress = (imgId) =>  {
      let m = this.state.images;
      m[imgId].booking = (m[imgId].booking)?false: true;
      this.setState({images : m})
    };

    return (
      <View>
        <ToolbarAndroid actions={toolbarActions}
                        // logo={require('./icon/ic_message_black/ic_message_black.png')}
                        title="ILook"
                        style={styles.toolbar}/>
        <ScrollView
          refreshControl={
            <RefreshControl
              progressViewOffset = {10}
              refreshing={this.state.refreshing}
              onRefresh={this._onRefresh.bind(this)}
          />}
          >
          {this.state.images.map(function(img) {
            return <Card key={img.id}
                         booking={img.booking}
                         url={img.url}
                         title={img.title}
                         onPress={this.buttonPress.bind(this, img.id)}/>;
          })}
        </ScrollView>
      </View>
    );
  }
}

var toolbarActions = [
  {title: 'Feedback', icon: require('./icon/ic_message_black/ic_message_black.png') ,show: 'always'},
];

const styles = StyleSheet.create({
  toolbar: {
    backgroundColor: '#ffffff',
    height: 50
  },
});

AppRegistry.registerComponent('listApp', () => listApp);
<commit_msg>Add scroll-down to push data  to scrollView<commit_after>/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import Card from './compoment/Card'

import {
  AppRegistry,
  StyleSheet,
  Text,
  ScrollView,
  Image,
  Dimensions,
  View,
  ToolbarAndroid,
  Alert,
  RefreshControl,
} from 'react-native';

var {height, width} = Dimensions.get('window');
var nativeImageSource = require('nativeImageSource');
var NativeMethodsMixin = require('NativeMethodsMixin');

export default class listApp extends Component {

  constructor(props) {
    super(props);

    this.state = {
      images: [],
      refreshing: false,
      scrollY : 0
    };
  }

  componentDidMount() {
     let datas =
      [{
         id: 0,
         url: 'http://d2ku7ggsvxaz7z.cloudfront.net/images/bam/3/MAI_180418427.jpg',
         title: '兩個小孩的托育費用就高達26500元',
         booking: true
       },
       {
         id: 1,
         url: 'http://d2ku7ggsvxaz7z.cloudfront.net/images/bam/9/MAI_144434087.png',
         title: 'AI金融應用－保險',
         booking: false
       },
       {
         id: 2,
         url: 'http://d2ku7ggsvxaz7z.cloudfront.net/images/bam/3/MAI_180418427.jpg',
         title: '兩個小孩的托育費用就高達26500元',
         booking: true
       },
       {
         id: 3,
         url: 'http://d2ku7ggsvxaz7z.cloudfront.net/images/bam/9/MAI_144434087.png',
         title: '兩個小孩的托育費用就高達26500元',
         booking: false
       }];

     this.setState({ images: datas});
  }

  _onRefresh() {
    this.setState({refreshing: true});

    this.setState({refreshing: false});
  }

  render() {
    let _scrollView: ScrollView;
    let _card: Card;

    let contentHeight: 0;
    let scrollViewHeight: 0;
    const offsetPage = 60;
    const routes = [
      { title: 'First Scene', index: 0},
      { title: 'Second Scene', index: 1},
    ];

    buttonPress = (imgId) => {
      let m = this.state.images;
      m[imgId].booking = (m[imgId].booking)?false: true;
      this.setState({images : m})
    };

    onActionSelected = (position) => {
      if (position === 0) {
        scrollToBottom();
      }
    };

    loadData = (event) => {
      console.log("offsetY: " + event.nativeEvent.contentOffset.y);
      console.log("scrollViewHeight: " + this.scrollViewHeight);
      console.log("contentHeight:" + this.contentHeight);
      console.log("total:" + (event.nativeEvent.contentOffset.y + this.scrollViewHeight));

      if((event.nativeEvent.contentOffset.y + this.scrollViewHeight + offsetPage) >= this.contentHeight) {

        let id = this.state.images.length;

        var datas = {
         id: id,
         url: 'http://d2ku7ggsvxaz7z.cloudfront.net/images/bam/3/MAI_180418427.jpg',
         title: '兩個小孩的托育費用就高達26500元',
         booking: true
        };

        let d = this.state.images.push(datas);

        this.setState({ images: this.state.images});
        console.log(this.state.images);
      }

    }

    // ScrollView scroll to bottom
    scrollToBottom = (animated = true) => {
      let scrollHeight = this.contentHeight - this.scrollViewHeight;
      if (scrollHeight > 0) {
        _scrollView.scrollTo({y: scrollHeight, animate: animated});
      }
    }

    return (
      <View>
        <ToolbarAndroid actions={toolbarActions}
                        // logo={require('./icon/ic_message_black/ic_message_black.png')}
                        title="ILook"
                        style={styles.toolbar}
                        onActionSelected={onActionSelected}
                        />
        <ScrollView
          onScroll={(event: Object) => loadData(event)}
          ref={(scrollView) => { _scrollView = scrollView; }}
          onContentSizeChange={(w, h) => this.contentHeight = h}
          onLayout={ev => this.scrollViewHeight = ev.nativeEvent.layout.height}
          refreshControl={
            <RefreshControl
              progressViewOffset = {10}
              refreshing={this.state.refreshing}
              onRefresh={this._onRefresh.bind(this)}
          />}
          >
          {this.state.images.map(function(img) {
            return <Card
                         ref={(card) => {_card = card;} }
                         key={img.id}
                         booking={img.booking}
                         url={img.url}
                         title={img.title}
                         onPress={this.buttonPress.bind(this, img.id)}/>;
          })}
        </ScrollView>
      </View>
    );
  }
}

var toolbarActions = [
  {title: 'Chat', icon: require('./icon/ic_message_black/ic_message_black.png') ,show: 'always'},
];

const styles = StyleSheet.create({
  toolbar: {
    backgroundColor: '#ffffff',
    height: 50
  },
});

AppRegistry.registerComponent('listApp', () => listApp);
<|endoftext|>


<commit_before>/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, {Component} from 'react';
import Icon from 'react-native-vector-icons/MaterialIcons';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    StatusBar,
    ScrollView,
} from 'react-native';

export default class fixedFooter extends Component {

    _renderScrollViewContent() {
        const data = Array.from({length: 30});
        return (
            <View>
                {data.map((_, i) =>
                    <View key={i} style={styles.row}>
                        <Text>Simple Text {i + 1}</Text>
                    </View>
                )}
            </View>
        );
    }

    render() {

        return (
            <View style={{flex: 1, alignItems: 'stretch'}}>
                <StatusBar
                    translucent={true}
                    barStyle="light-content"
                    backgroundColor="rgba(0, 0, 0, 0.254)"
                />

                <View style={styles.navigationHeader}>
                    <View style={styles.navigationIcons}>
                        <Icon name="arrow-back" size={30} color="#FFF"  />
                        <Text style={styles.headerText}>Awsome Header</Text>
                        <Icon name="arrow-forward" size={30} color="#FFF" />
                    </View>

                </View>

                <View style={{flex: 1, borderWidth: 0, paddingTop:8}}>
                    <Text style={{alignSelf:'center'}}>I take up loads of space!</Text>
                    <ScrollView
                        scrollEventThrottle={16}

                    >
                        {this._renderScrollViewContent()}
                    </ScrollView>
                </View>
                <View style={styles.Footer}>
                    <View style={styles.footerIcons}>
                        <Icon name="home" size={30} color="#FFF"  />
                        <Icon name="date-range" size={30} color="#FFF"  />
                        <Icon name="school" size={30} color="#FFF"  />
                        <Icon name="map" size={30} color="#FFF"  />
                        <Icon name="person" size={30} color="#FFF"  />
                    </View>
                </View>

            </View>
        );
    }
}

const styles = StyleSheet.create({

    row: {
        height: 40,
        margin: 16,
        backgroundColor: '#D3D3D3',
        alignItems: 'center',
        justifyContent: 'center',

    },
    navigationHeader:{
        alignSelf:'flex-start',
        backgroundColor:'#03A9F4',
        flex:1/16,
        flexDirection:'row',
        paddingTop:26,
    },
    footerIconText:{
        flexDirection:'row',
        flex:1,
        justifyContent:'space-around',
    },
    footerIcons:{
        flexDirection:'row',
        flex:1,
        justifyContent:'space-around',
        paddingTop:4,
    },
    navigationIcons:{
        flexDirection:'row',
        flex:1,
        justifyContent:'space-around',
        paddingLeft:12,
        paddingRight:12,
    },
    Footer:{
        flex:1/12,
        alignSelf: 'flex-end',
        backgroundColor:'#03A9F4',
        flexDirection:'row',

    },
    headerText:{
        fontSize:18 ,
        paddingTop:4,
        color:'#FFF',
        fontWeight:'bold',
    },
});

AppRegistry.registerComponent('fixedFooter', () => fixedFooter);
<commit_msg>Footer Completed the footer<commit_after>/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, {Component} from 'react';
import Icon from 'react-native-vector-icons/MaterialIcons';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    StatusBar,
    ScrollView,
} from 'react-native';

export default class fixedFooter extends Component {

    _renderScrollViewContent() {
        const data = Array.from({length: 30});
        return (
            <View>
                {data.map((_, i) =>
                    <View key={i} style={styles.row}>
                        <Text>Simple Text {i + 1}</Text>
                    </View>
                )}
            </View>
        );
    }

    render() {

        return (
            <View style={{flex: 1, alignItems: 'stretch'}}>
                <StatusBar
                    translucent={true}
                    barStyle="light-content"
                    backgroundColor="rgba(0, 0, 0, 0.254)"
                />

                <View style={styles.navigationHeader}>
                    <View style={styles.navigationIcons}>
                        <Icon name="arrow-back" size={30} color="#FFF"/>
                        <Text style={styles.headerText}>Awsome Header</Text>
                        <Icon name="arrow-forward" size={30} color="#FFF"/>
                    </View>

                </View>

                <View style={{flex: 1, borderWidth: 0, paddingTop:8}}>
                    <Text style={{alignSelf:'center'}}>I take up loads of space!</Text>
                    <ScrollView
                        scrollEventThrottle={16}

                    >
                        {this._renderScrollViewContent()}
                    </ScrollView>
                </View>
                <View style={styles.Footer}>
                    <View style={styles.footerIcons}>
                        <View style={styles.footerIcon}>
                            <Icon name="home" size={30} color="#FFF"/>
                            <Text style={styles.footerIconLegend}>Home</Text>
                        </View>

                        <View style={styles.footerIcon}>
                            <Icon name="date-range" size={30} color="#FFF"/>
                            <Text style={styles.footerIconLegend}>Calender</Text>
                        </View>
                        <View style={styles.footerIcon}>
                            <Icon name="school" size={30} color="#FFF"/>
                            <Text style={styles.footerIconLegend}>Trainings</Text>
                        </View>
                        <View style={styles.footerIcon}>
                            <Icon name="map" size={30} color="#FFF"/>
                            <Text style={styles.footerIconLegend}>Nearby</Text>
                        </View>
                        <View style={styles.footerIcon}>
                            <Icon name="person" size={30} color="#FFF"/>
                            <Text style={styles.footerIconLegend}>Profile</Text>
                        </View>
                    </View>
                </View>

            </View>
        );
    }
}

const styles = StyleSheet.create({

    row: {
        height: 40,
        margin: 16,
        backgroundColor: '#D3D3D3',
        alignItems: 'center',
        justifyContent: 'center',

    },
    navigationHeader: {
        alignSelf: 'flex-start',
        backgroundColor: '#03A9F4',
        flex: 1 / 16,
        flexDirection: 'row',
        paddingTop: 26,
    },
    footerIcons: {
        flexDirection: 'row',
        flex: 1,
        justifyContent: 'space-around',
        paddingTop: 4,
    },
    navigationIcons: {
        flexDirection: 'row',
        flex: 1,
        justifyContent: 'space-around',
        paddingLeft: 12,
        paddingRight: 12,
    },
    Footer: {
        flex: 1 / 10,
        alignSelf: 'flex-end',
        backgroundColor: '#03A9F4',
        flexDirection: 'row',

    },
    FooterIcon:{
        flexDirection:'column',
        alignItems:'center'
    },
    footerIconLegend:{
        fontSize:10,
        color:'#FFF',
        paddingTop:3,
    },
    headerText: {
        fontSize: 18,
        paddingTop: 4,
        color: '#FFF',
        fontWeight: 'bold',
    },
});

AppRegistry.registerComponent('fixedFooter', () => fixedFooter);
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react'
import classNames from 'classnames'
import { connect } from 'react-redux'
import { debounce } from 'lodash'
import { autoCompleteUsers, loadEmojis } from '../actions/posts'
import { loadProfile } from '../actions/profile'
import { setIsOffsetLayout } from '../actions/gui'
import * as ACTION_TYPES from '../constants/action_types'
import Analytics from '../components/analytics/Analytics'
import DevTools from '../components/devtools/DevTools'
import { AppHelmet } from '../components/helmets/AppHelmet'
import Modal from '../components/modals/Modal'
import Navbar from '../components/navbar/Navbar'
import Omnibar from '../components/omnibar/Omnibar'
import Completer from '../components/completers/Completer'
import TextTools from '../components/editor/TextTools'
import { addInputObject, removeInputObject } from '../components/editor/InputComponent'
import { addFeatureDetection } from '../components/interface/Viewport'
import { addGlobalDrag, removeGlobalDrag } from '../components/interface/GlobalDrag'
import { replaceWordFromSelection } from '../components/editor/SelectionUtil'
import FooterContainer from '../containers/FooterContainer'

class App extends Component {

  static propTypes = {
    authentication: PropTypes.object.isRequired,
    children: PropTypes.node.isRequired,
    completions: PropTypes.shape({
      data: PropTypes.array,
      type: PropTypes.string,
    }),
    dispatch: PropTypes.func.isRequired,
    editorStore: PropTypes.object.isRequired,
    emoji: PropTypes.object.isRequired,
    isOffsetLayout: PropTypes.bool,
    location: PropTypes.shape({
      pathname: PropTypes.string,
    }).isRequired,
    pathname: PropTypes.string.isRequired,
    params: PropTypes.shape({
      username: PropTypes.string,
      token: PropTypes.string,
    }).isRequired,
  }

  static defaultProps = {
    editorStore: {},
  }

  componentWillMount() {
    this.state = {
      activeTools: {},
      coordinates: { top: -200, left: -666 },
      hideCompleter: true,
      hideTextTools: true,
    }
    this.onUserCompleter = debounce(this.onUserCompleter, 300)
  }

  componentDidMount() {
    addFeatureDetection()
    addInputObject(this)
    addGlobalDrag()
    this.updateIsOffsetLayout()
  }

  componentWillReceiveProps(nextProps) {
    const prevAuthentication = this.props.authentication
    const { authentication, dispatch } = nextProps
    if (authentication &&
        !prevAuthentication.isLoggedIn &&
        authentication.isLoggedIn) {
      dispatch(loadProfile())
    }
  }

  componentDidUpdate(prevProps) {
    if (prevProps.location.pathname === this.props.location.pathname) { return }
    this.updateIsOffsetLayout()
  }

  componentWillUnmount() {
    removeInputObject(this)
    removeGlobalDrag()
  }

  onHideCompleter() {
    const { completions, dispatch } = this.props
    this.setState({ hideCompleter: true })
    if (completions) {
      dispatch({ type: ACTION_TYPES.POST.AUTO_COMPLETE_CLEAR })
    }
  }

  onPositionChange(props) {
    this.setState(props)
  }

  onShowTextTools({ activeTools }) {
    this.setState({ hideTextTools: false, activeTools })
  }

  onHideTextTools() {
    this.setState({ hideTextTools: true })
  }

  onUserCompleter({ word }) {
    const { dispatch } = this.props
    dispatch(autoCompleteUsers('user', word))
    this.setState({ hideCompleter: false })
  }

  onEmojiCompleter({ word }) {
    const { dispatch, emoji } = this.props
    if (emoji.emojis && emoji.emojis.length) {
      dispatch({
        type: ACTION_TYPES.EMOJI.LOAD_SUCCESS,
        payload: {
          response: {
            emojis: emoji.emojis,
          },
          type: 'emoji',
          word,
        },
      })
    } else {
      dispatch(loadEmojis('emoji', word))
    }
    this.setState({ hideCompleter: false })
  }

  onCancelAutoCompleter = () => {
    this.onHideCompleter()
    this.onHideTextTools()
    // TODO: maybe clear out the completions from the editor store
  }

  onCompletion = ({ value }) => {
    replaceWordFromSelection(value)
    this.onCancelAutoCompleter()
  }

  // TODO: Maybe move this out to a Viewport object?
  updateIsOffsetLayout() {
    const { isOffsetLayout, location: { pathname }, params: { username, token } } = this.props
    const isUserDetailOrSettings = (username && !token) || pathname === '/settings'
    if (isOffsetLayout !== isUserDetailOrSettings) {
      this.props.dispatch(setIsOffsetLayout({ isOffsetLayout: isUserDetailOrSettings }))
    }
  }

  render() {
    const { authentication, children, completions, pathname } = this.props
    const { activeTools, coordinates, hideCompleter, hideTextTools } = this.state
    const { isLoggedIn } = authentication
    const appClasses = classNames(
      'App',
      { isLoggedIn },
      { isLoggedOut: !isLoggedIn },
    )
    return (

        <AppHelmet pathname={ pathname } />
        { isLoggedIn ? <Omnibar /> : null }

          { children }

        { !hideCompleter && completions ?
          <Completer
            completions={ completions }
            onCancel={ this.onCancelAutoCompleter }
            onCompletion={ this.onCompletion }
          /> :
          null
        }
        { !hideTextTools ?
          <TextTools
            activeTools={ activeTools }
            isHidden={ hideTextTools }
            coordinates={ coordinates }
            key={ JSON.stringify(activeTools) }
          /> :
          null
        }
        <Navbar />
        <FooterContainer />
        <Modal />
        <DevTools />
        <Analytics isLoggedIn={ isLoggedIn } />

    )
  }
}

App.preRender = (store) => {
  const state = store.getState()
  if (state.authentication && state.authentication.isLoggedIn) {
    store.dispatch(loadProfile())
  }
}

function mapStateToProps(state, ownProps) {
  return {
    authentication: state.authentication,
    completions: state.editor.completions,
    emoji: state.emoji,
    pathname: ownProps.location.pathname,
    isOffsetLayout: state.gui.isOffsetLayout,
  }
}

export default connect(mapStateToProps)(App)

<commit_msg>Load the profile from App if isLoggedIn.<commit_after>import React, { Component, PropTypes } from 'react'
import classNames from 'classnames'
import { connect } from 'react-redux'
import { debounce, get } from 'lodash'
import { autoCompleteUsers, loadEmojis } from '../actions/posts'
import { loadProfile } from '../actions/profile'
import { setIsOffsetLayout } from '../actions/gui'
import * as ACTION_TYPES from '../constants/action_types'
import Analytics from '../components/analytics/Analytics'
import DevTools from '../components/devtools/DevTools'
import { AppHelmet } from '../components/helmets/AppHelmet'
import Modal from '../components/modals/Modal'
import Navbar from '../components/navbar/Navbar'
import Omnibar from '../components/omnibar/Omnibar'
import Completer from '../components/completers/Completer'
import TextTools from '../components/editor/TextTools'
import { addInputObject, removeInputObject } from '../components/editor/InputComponent'
import { addFeatureDetection } from '../components/interface/Viewport'
import { addGlobalDrag, removeGlobalDrag } from '../components/interface/GlobalDrag'
import { replaceWordFromSelection } from '../components/editor/SelectionUtil'
import FooterContainer from '../containers/FooterContainer'

class App extends Component {

  static propTypes = {
    authentication: PropTypes.object.isRequired,
    children: PropTypes.node.isRequired,
    completions: PropTypes.shape({
      data: PropTypes.array,
      type: PropTypes.string,
    }),
    dispatch: PropTypes.func.isRequired,
    editorStore: PropTypes.object.isRequired,
    emoji: PropTypes.object.isRequired,
    isOffsetLayout: PropTypes.bool,
    location: PropTypes.shape({
      pathname: PropTypes.string,
    }).isRequired,
    pathname: PropTypes.string.isRequired,
    params: PropTypes.shape({
      username: PropTypes.string,
      token: PropTypes.string,
    }).isRequired,
  }

  static defaultProps = {
    editorStore: {},
  }

  componentWillMount() {
    this.state = {
      activeTools: {},
      coordinates: { top: -200, left: -666 },
      hideCompleter: true,
      hideTextTools: true,
    }
    this.onUserCompleter = debounce(this.onUserCompleter, 300)
  }

  componentDidMount() {
    addFeatureDetection()
    addInputObject(this)
    addGlobalDrag()
    this.updateIsOffsetLayout()
    if (get(this.props, 'authentication.isLoggedIn')) {
      const { dispatch } = this.props
      dispatch(loadProfile())
    }
  }

  componentWillReceiveProps(nextProps) {
    const prevAuthentication = this.props.authentication
    const { authentication, dispatch } = nextProps
    if (authentication &&
        !prevAuthentication.isLoggedIn &&
        authentication.isLoggedIn) {
      dispatch(loadProfile())
    }
  }

  componentDidUpdate(prevProps) {
    if (prevProps.location.pathname === this.props.location.pathname) { return }
    this.updateIsOffsetLayout()
  }

  componentWillUnmount() {
    removeInputObject(this)
    removeGlobalDrag()
  }

  onHideCompleter() {
    const { completions, dispatch } = this.props
    this.setState({ hideCompleter: true })
    if (completions) {
      dispatch({ type: ACTION_TYPES.POST.AUTO_COMPLETE_CLEAR })
    }
  }

  onPositionChange(props) {
    this.setState(props)
  }

  onShowTextTools({ activeTools }) {
    this.setState({ hideTextTools: false, activeTools })
  }

  onHideTextTools() {
    this.setState({ hideTextTools: true })
  }

  onUserCompleter({ word }) {
    const { dispatch } = this.props
    dispatch(autoCompleteUsers('user', word))
    this.setState({ hideCompleter: false })
  }

  onEmojiCompleter({ word }) {
    const { dispatch, emoji } = this.props
    if (emoji.emojis && emoji.emojis.length) {
      dispatch({
        type: ACTION_TYPES.EMOJI.LOAD_SUCCESS,
        payload: {
          response: {
            emojis: emoji.emojis,
          },
          type: 'emoji',
          word,
        },
      })
    } else {
      dispatch(loadEmojis('emoji', word))
    }
    this.setState({ hideCompleter: false })
  }

  onCancelAutoCompleter = () => {
    this.onHideCompleter()
    this.onHideTextTools()
    // TODO: maybe clear out the completions from the editor store
  }

  onCompletion = ({ value }) => {
    replaceWordFromSelection(value)
    this.onCancelAutoCompleter()
  }

  // TODO: Maybe move this out to a Viewport object?
  updateIsOffsetLayout() {
    const { isOffsetLayout, location: { pathname }, params: { username, token } } = this.props
    const isUserDetailOrSettings = (username && !token) || pathname === '/settings'
    if (isOffsetLayout !== isUserDetailOrSettings) {
      this.props.dispatch(setIsOffsetLayout({ isOffsetLayout: isUserDetailOrSettings }))
    }
  }

  render() {
    const { authentication, children, completions, pathname } = this.props
    const { activeTools, coordinates, hideCompleter, hideTextTools } = this.state
    const { isLoggedIn } = authentication
    const appClasses = classNames(
      'App',
      { isLoggedIn },
      { isLoggedOut: !isLoggedIn },
    )
    return (

        <AppHelmet pathname={ pathname } />
        { isLoggedIn ? <Omnibar /> : null }

          { children }

        { !hideCompleter && completions ?
          <Completer
            completions={ completions }
            onCancel={ this.onCancelAutoCompleter }
            onCompletion={ this.onCompletion }
          /> :
          null
        }
        { !hideTextTools ?
          <TextTools
            activeTools={ activeTools }
            isHidden={ hideTextTools }
            coordinates={ coordinates }
            key={ JSON.stringify(activeTools) }
          /> :
          null
        }
        <Navbar />
        <FooterContainer />
        <Modal />
        <DevTools />
        <Analytics isLoggedIn={ isLoggedIn } />

    )
  }
}

App.preRender = (store) => {
  const state = store.getState()
  if (state.authentication && state.authentication.isLoggedIn) {
    store.dispatch(loadProfile())
  }
}

function mapStateToProps(state, ownProps) {
  return {
    authentication: state.authentication,
    completions: state.editor.completions,
    emoji: state.emoji,
    pathname: ownProps.location.pathname,
    isOffsetLayout: state.gui.isOffsetLayout,
  }
}

export default connect(mapStateToProps)(App)

<|endoftext|>


<commit_before>// @flow

import Command from 'cli-engine-command'
import Plugins from './plugins'
import path from 'path'
import fs from 'fs-extra'

export default class extends Command {
  plugins: Plugins

  async run () {
    this.plugins = new Plugins(this.out)
    let file = path.join(this.config.dataDir, 'plugins', 'plugins.json')
    let pljson = await this.getPluginsJson(file)
    if (!pljson) return
    this.out.debug('Migrating V5 plugins...')
    for (let p of pljson) {
      if (this.plugins.isPluginInstalled(p.name)) {
        this.out.debug('Skipping already installed plugin: ', p.name)
      } else {
        await this.installPlugin(p.name, p.tag)
      }
    }
  }

  async getPluginsJson (file: string) {
    try {
      return fs.readJSONSync(file)
    } catch (err) {
      this.out.debug(err.message)
    }
  }

  async installPlugin (name: string, tag: string) {
    try {
      if (tag === 'symlink') {
        await this.reinstallViaSymlink(name)
      } else {
        if (tag === '') tag = 'latest'
        await this.addToPJSON(name, tag)
      }
    } catch (err) {
      this.out.warn(err)
    }
  }

  async reinstallViaSymlink (name: string) {
    this.out.debug('Installing via symlink: ', name)
    let pluginPath = fs.realpathSync(path.join(this.config.dataDir, 'plugins', 'node_modules', name))
    await this.plugins.addLinkedPlugin(pluginPath)
  }

  async addToPJSON (name: string, tag: string) {
    this.out.debug('Adding to plugins pjson: ', name)
    this.plugins.addPackageToPJSON(name, tag)
  }
}
<commit_msg>Edit migration debug output (#62)<commit_after>// @flow

import Command from 'cli-engine-command'
import Plugins from './plugins'
import path from 'path'
import fs from 'fs-extra'

export default class extends Command {
  plugins: Plugins

  async run () {
    this.plugins = new Plugins(this.out)
    let file = path.join(this.config.dataDir, 'plugins', 'plugins.json')
    let pljson = await this.getPluginsJson(file)
    if (!pljson) return
    this.out.debug('Migrating V5 plugins...')
    for (let p of pljson) {
      if (this.plugins.isPluginInstalled(p.name)) {
        this.out.debug(`Skipping already installed plugin: ${p.name}`)
      } else {
        await this.installPlugin(p.name, p.tag)
      }
    }
  }

  async getPluginsJson (file: string) {
    try {
      return fs.readJSONSync(file)
    } catch (err) {
      this.out.debug(err.message)
    }
  }

  async installPlugin (name: string, tag: string) {
    try {
      if (tag === 'symlink') {
        await this.reinstallViaSymlink(name)
      } else {
        if (tag === '') tag = 'latest'
        await this.addToPJSON(name, tag)
      }
    } catch (err) {
      this.out.warn(err)
    }
  }

  async reinstallViaSymlink (name: string) {
    this.out.debug(`Installing via symlink: ${name}`)
    let pluginPath = fs.realpathSync(path.join(this.config.dataDir, 'plugins', 'node_modules', name))
    await this.plugins.addLinkedPlugin(pluginPath)
  }

  async addToPJSON (name: string, tag: string) {
    this.out.debug(`Adding to plugins pjson: ${name}`)
    this.plugins.addPackageToPJSON(name, tag)
  }
}
<|endoftext|>