<commit_before>import Babel from "npm:babel";
import Path from 'npm:path';
import blueprints from '../lib/blueprints';
import config from '../config/environment';
import Ember from 'ember';
import moment from 'moment';

const twiddleAppName = 'demo-app';

// These files will be included if not present
const boilerPlateJs = [
  'app',
  'router',
  'initializers/router',
  'initializers/mouse-events'
];

// These files have to be present
const requiredFiles = [
  'twiddle.json'
];

const availableBlueprints = {
  'templates/application': {
    blueprint: 'templates/application',
    filePath: 'application/template.hbs'
  },
  'controllers/application': {
    blueprint: 'controllers/application',
    filePath: 'application/controller.js'
  },
  'app': {
    blueprint: 'app',
    filePath: 'app.js'
  },
  'css': {
    blueprint: 'app.css',
    filePath: 'styles/app.css'
  },
  'component-hbs': {
    blueprint: 'component-hbs',
    filePath: 'my-component/template.hbs'
  },
  'component-js': {
    blueprint: 'component-js',
    filePath: 'my-component/component.js'
  },
  'controller': {
    blueprint: 'controller',
    filePath: 'my-route/controller.js'
  },
  'initializers/router': {
    blueprint: 'initializers/router',
    filePath: 'initializers/router.js'
  },
  'initializers/mouse-events': {
    blueprint: 'initializers/mouse-events',
    filePath: 'initializers/mouse-events.js'
  },
  'model': {
    blueprint: 'model',
    filePath: 'models/my-model.js'
  },
  'helper': {
    blueprint: 'helper',
    filePath: 'helpers/my-helper.js'
  },
  'route': {
    blueprint: 'route',
    filePath: 'my-route/route.js'
  },
  'service': {
    blueprint: 'service',
    filePath: 'my-service/service.js'
  },
  'template': {
    blueprint: 'template',
    filePath: 'my-route/template.hbs'
  },
  'router': {
    blueprint: 'router',
    filePath: 'router.js'
  },
  'twiddle.json': {
    blueprint: 'twiddle.json',
    filePath: 'twiddle.json'
  }
};

const requiredDependencies = [
  'jquery',
  'ember',
  'ember-template-compiler'
];

/**
 * A tiny browser version of the CLI build chain.
 * or more realistically: a hacked reconstruction of it.
 *
 * Parts of this module are directly copied from the ember-cli
 * source code at https://github.com/ember-cli/ember-cli
 */
export default Ember.Service.extend({
  dependencyResolver: Ember.inject.service(),

  init (...args) {
    this._super(...args);
    this.set('store', this.container.lookup("service:store"));
  },

  generate(type) {
    return this.store.createRecord('gistFile', this.buildProperties(type));
  },

  buildProperties(type, replacements) {
    if (type in availableBlueprints) {
      let blueprint = availableBlueprints[type];
      let content = blueprints[blueprint.blueprint];

      if (replacements) {
        Object.keys(replacements).forEach(key => {
          let token = `<%= ${key} %>`;
          let value = replacements[key];

          content = content.replace(new RegExp(token, 'g'), value);
        });
      }

      return {
        filePath: blueprint.filePath,
        content: content.replace(/<\%\=(.*)\%\>/gi,'')
      };
    }
  },

  nameWithModule: function (filePath) {
    // Remove app prefix if present
    let name = filePath.replace(/^app\//, '');

    return Path.join(twiddleAppName,
      Path.dirname(name), Path.basename(name, Path.extname(name)));
  },

  /**
   * Build a gist into an Ember app.
   *
   * @param  {Gist} gist    Gist to build
   * @return {Ember Object}       Source code for built Ember app
   */
  compileGist (gist) {
    var promise = new Ember.RSVP.Promise((resolve, reject) => {
      let errors = [];
      let out = [];
      let cssOut = [];

      this.checkRequiredFiles(out, gist);

      gist.get('files').forEach(file => {
        try {
          switch(file.get('extension')) {
            case '.js':
              out.push(this.compileJs(file.get('content'), file.get('filePath')));
              break;
            case '.hbs':
              out.push(this.compileHbs(file.get('content'), file.get('filePath')));
              break;
            case '.css':
              cssOut.push(this.compileCss(file.get('content'), file.get('filePath')));
              break;
            case '.json':
              break;
          }
        }
        catch(e) {
          e.message = `${file.get('filePath')}: ${e.message}`;
          errors.push(e);
        }
      });

      if (errors.length) {
        return reject(errors);
      }

      this.addBoilerPlateFiles(out, gist);
      this.addConfig(out, gist);

      let twiddleJson = this.getTwiddleJson(gist);

      // Add boot code
      contentForAppBoot(out, {modulePrefix: twiddleAppName, dependencies: twiddleJson.dependencies});

      resolve(this.buildHtml(gist, out.join('\n'), cssOut.join('\n')));
    });

    return promise;
  },

  buildHtml (gist, appJS, appCSS) {
    if (gist.get('initialRoute')) {
      appJS += "window.location.hash='" + gist.get('initialRoute') + "';";
    }

    let index = blueprints['index.html'];
    let twiddleJSON = this.getTwiddleJson(gist);
    let deps = twiddleJSON.dependencies;

    let depCssLinkTags = '';
    let depScriptTags ='';
    let appScriptTag = `<script type="text/javascript">${appJS}</script>`;
    let appStyleTag = `<style type="text/css">${appCSS}</style>`;
    let testStuff = '';

    let EmberENV = twiddleJSON.EmberENV || {};
    depScriptTags += `<script type="text/javascript">EmberENV = ${JSON.stringify(EmberENV)};</script>`;

    Object.keys(deps).forEach(function(depKey) {
      let dep = deps[depKey];
      if (dep.substr(dep.lastIndexOf(".")) === '.css') {
        depCssLinkTags += `<link rel="stylesheet" type="text/css" href="${dep}">`;
      } else {
        depScriptTags += `<script type="text/javascript" src="${dep}"></script>`;
      }
    });

    depScriptTags += `<script type="text/javascript" src="${config.assetsHost}assets/twiddle-deps.js?${config.APP.version}"></script>`;

    const testingEnabled = twiddleJSON.options && twiddleJSON.options["enable-testing"];

    if (testingEnabled) {
      const testJSFiles = ['assets/test-loader.js', 'assets/test-support.js', 'testem.js'];

      testJSFiles.forEach(jsFile => {
        depScriptTags += `<script type="text/javascript" src="${config.assetsHost}${jsFile}?${config.APP.version}"></script>`;
      });

      depCssLinkTags += `<link rel="stylesheet" type="text/css" href="${config.assetsHost}assets/test-support.css?${config.APP.version}">`;

      testStuff += `

`;
    }

    index = index.replace('{{content-for \'head\'}}', `${depCssLinkTags}\n${appStyleTag}`);
    index = index.replace('{{content-for \'body\'}}', `${depScriptTags}\n${appScriptTag}\n${testStuff}\n`);

    // replace the {{build-timestamp}} placeholder with the number of
    // milliseconds since the Unix Epoch:
    // http://momentjs.com/docs/#/displaying/unix-offset/
    index = index.replace('{{build-timestamp}}', +moment());

    return index;
  },

  checkRequiredFiles (out, gist) {
    requiredFiles.forEach(filePath => {
      var file = gist.get('files').findBy('filePath', filePath);
      if(!file) {
        gist.get('files').pushObject(this.store.createRecord('gistFile', {
          filePath: filePath,
          content: blueprints[filePath]
        }));
      }
    });
  },

  addBoilerPlateFiles (out, gist) {
    boilerPlateJs.forEach(blueprintName => {
      let blueprint = availableBlueprints[blueprintName];
      if(!gist.get('files').findBy('filePath', blueprint.filePath)) {
        out.push(this.compileJs(blueprints[blueprint.blueprint], blueprint.filePath));
      }
    });
  },

  addConfig (out) {
    let config = {
      modulePrefix: "demo-app",
      TWIDDLE_ORIGIN: location.origin
    };

    let configJs = 'export default ' + JSON.stringify(config);
    out.push(this.compileJs(configJs, 'config/environment'));
  },

  getTwiddleJson (gist) {
    var twiddleJson = JSON.parse(gist.get('files').findBy('filePath', 'twiddle.json').get('content'));

    // Fill in any missing required dependencies
    var dependencies = JSON.parse(blueprints['twiddle.json']).dependencies;
    requiredDependencies.forEach(function(dep) {
      if (!twiddleJson.dependencies[dep] && dependencies[dep]) {
        if (dep === 'ember-template-compiler') {
          twiddleJson.dependencies[dep] = twiddleJson.dependencies['ember'].replace('ember.debug.js', 'ember-template-compiler.js');
        } else {
          twiddleJson.dependencies[dep] = dependencies[dep];
        }
      }
    });

    var dependencyResolver = this.get('dependencyResolver');
    dependencyResolver.resolveDependencies(twiddleJson.dependencies);

    return twiddleJson;
  },

  updateDependencyVersion: function(gist, dependencyName, version) {
    return new Ember.RSVP.Promise(function(resolve, reject) {
      var twiddle = gist.get('files').findBy('filePath', 'twiddle.json');

      var json;
      try {
        json = JSON.parse(twiddle.get('content'));
      } catch (e) {
        return reject(e);
      }

      json.dependencies[dependencyName] = version;

      // since ember and ember-template-compiler should always have the same
      // version, we update the version for the ember-template-compiler too, if
      // the ember dependency is updated
      if (dependencyName === 'ember' && json.dependencies.hasOwnProperty('ember-template-compiler')) {
        json.dependencies['ember-template-compiler'] = version;
      }

      json = JSON.stringify(json, null, '  ');
      twiddle.set('content', json);

      resolve();
    });
  },

  /**
   * Compile a javascript file. This means that we
   * transform it using Babel.
   *
   * @param  {String} code       ES6 module code
   * @param  {String} filePath   File path (will be used for module name)
   * @return {String}            Transpiled module code
   */
  compileJs (code, filePath) {
    let moduleName = this.nameWithModule(filePath);
    return Babel.transform(code, babelOpts(moduleName)).code;
  },

  /**
   * Compile a Handlebars template into an AMD module.
   *
   * @param  {String} code       hbs code
   * @param  {String} filePath   File path (will be used for module name)
   * @return {String}            AMD module code
   */
  compileHbs (code, filePath) {
    // TODO: Is there a way to precompile using the template compiler brought in via twiddle.json?
    // let templateCode = Ember.HTMLBars.precompile(code || '');

    // Compiles all templates at runtime.
    let moduleName = this.nameWithModule(filePath);

    const mungedCode = (code || '')
            .replace(/\\/g, "\\\\") // Prevent backslashes from being escaped
            .replace(/`/g, "\\`"); // Prevent backticks from causing syntax errors

    return this.compileJs('export default Ember.HTMLBars.compile(`' + mungedCode + '`, { moduleName: `' + moduleName + '`});', filePath);
  },

  compileCss(code, moduleName) {
    var prefix = "styles/";
    if (moduleName.substring(0, prefix.length) === prefix) {
        return code;
    }
    return '';
  }
});

/**
 * Generate babel options for the specified module
 * @param  {String} moduleName
 * @return {Object}            Babel options
 */
function babelOpts(moduleName) {
  return {
    modules:'amd',
    moduleIds:true,
    moduleId: moduleName
  };
}

/**
 * Generate the application boot code
 * @param  {Array} content  Code buffer to append to
 * @param  {Object} config  App configuration
 * @return {Array}          Code buffer
 */
function contentForAppBoot (content, config) {

  // Some modules are not actually transpiled so Babel
  // doesn't recognize them properly...
  var monkeyPatchModules = [
    'ember',
    'ember/load-initializers',
    'ember-resolver'
  ];

  if ("ember-data" in config.dependencies) {
    monkeyPatchModules.push('ember-data');
  }

  monkeyPatchModules.forEach(function(mod) {
    content.push('  require("'+mod+'").__esModule=true;');
  });

  content.push('  require("' +
    config.modulePrefix +
    '/app")["default"].create(' +
    calculateAppConfig(config) +
    ');');
}

/**
 * Directly copied from ember-cli
 */
function calculateAppConfig(config) {
  return JSON.stringify(config.APP || {});
}
<commit_msg>Avoid security error and hide toolbar<commit_after>import Babel from "npm:babel";
import Path from 'npm:path';
import blueprints from '../lib/blueprints';
import config from '../config/environment';
import Ember from 'ember';
import moment from 'moment';

const twiddleAppName = 'demo-app';

// These files will be included if not present
const boilerPlateJs = [
  'app',
  'router',
  'initializers/router',
  'initializers/mouse-events'
];

// These files have to be present
const requiredFiles = [
  'twiddle.json'
];

const availableBlueprints = {
  'templates/application': {
    blueprint: 'templates/application',
    filePath: 'application/template.hbs'
  },
  'controllers/application': {
    blueprint: 'controllers/application',
    filePath: 'application/controller.js'
  },
  'app': {
    blueprint: 'app',
    filePath: 'app.js'
  },
  'css': {
    blueprint: 'app.css',
    filePath: 'styles/app.css'
  },
  'component-hbs': {
    blueprint: 'component-hbs',
    filePath: 'my-component/template.hbs'
  },
  'component-js': {
    blueprint: 'component-js',
    filePath: 'my-component/component.js'
  },
  'controller': {
    blueprint: 'controller',
    filePath: 'my-route/controller.js'
  },
  'initializers/router': {
    blueprint: 'initializers/router',
    filePath: 'initializers/router.js'
  },
  'initializers/mouse-events': {
    blueprint: 'initializers/mouse-events',
    filePath: 'initializers/mouse-events.js'
  },
  'model': {
    blueprint: 'model',
    filePath: 'models/my-model.js'
  },
  'helper': {
    blueprint: 'helper',
    filePath: 'helpers/my-helper.js'
  },
  'route': {
    blueprint: 'route',
    filePath: 'my-route/route.js'
  },
  'service': {
    blueprint: 'service',
    filePath: 'my-service/service.js'
  },
  'template': {
    blueprint: 'template',
    filePath: 'my-route/template.hbs'
  },
  'router': {
    blueprint: 'router',
    filePath: 'router.js'
  },
  'twiddle.json': {
    blueprint: 'twiddle.json',
    filePath: 'twiddle.json'
  }
};

const requiredDependencies = [
  'jquery',
  'ember',
  'ember-template-compiler'
];

/**
 * A tiny browser version of the CLI build chain.
 * or more realistically: a hacked reconstruction of it.
 *
 * Parts of this module are directly copied from the ember-cli
 * source code at https://github.com/ember-cli/ember-cli
 */
export default Ember.Service.extend({
  dependencyResolver: Ember.inject.service(),

  init (...args) {
    this._super(...args);
    this.set('store', this.container.lookup("service:store"));
  },

  generate(type) {
    return this.store.createRecord('gistFile', this.buildProperties(type));
  },

  buildProperties(type, replacements) {
    if (type in availableBlueprints) {
      let blueprint = availableBlueprints[type];
      let content = blueprints[blueprint.blueprint];

      if (replacements) {
        Object.keys(replacements).forEach(key => {
          let token = `<%= ${key} %>`;
          let value = replacements[key];

          content = content.replace(new RegExp(token, 'g'), value);
        });
      }

      return {
        filePath: blueprint.filePath,
        content: content.replace(/<\%\=(.*)\%\>/gi,'')
      };
    }
  },

  nameWithModule: function (filePath) {
    // Remove app prefix if present
    let name = filePath.replace(/^app\//, '');

    return Path.join(twiddleAppName,
      Path.dirname(name), Path.basename(name, Path.extname(name)));
  },

  /**
   * Build a gist into an Ember app.
   *
   * @param  {Gist} gist    Gist to build
   * @return {Ember Object}       Source code for built Ember app
   */
  compileGist (gist) {
    var promise = new Ember.RSVP.Promise((resolve, reject) => {
      let errors = [];
      let out = [];
      let cssOut = [];

      this.checkRequiredFiles(out, gist);

      gist.get('files').forEach(file => {
        try {
          switch(file.get('extension')) {
            case '.js':
              out.push(this.compileJs(file.get('content'), file.get('filePath')));
              break;
            case '.hbs':
              out.push(this.compileHbs(file.get('content'), file.get('filePath')));
              break;
            case '.css':
              cssOut.push(this.compileCss(file.get('content'), file.get('filePath')));
              break;
            case '.json':
              break;
          }
        }
        catch(e) {
          e.message = `${file.get('filePath')}: ${e.message}`;
          errors.push(e);
        }
      });

      if (errors.length) {
        return reject(errors);
      }

      this.addBoilerPlateFiles(out, gist);
      this.addConfig(out, gist);

      let twiddleJson = this.getTwiddleJson(gist);

      // Add boot code
      contentForAppBoot(out, {modulePrefix: twiddleAppName, dependencies: twiddleJson.dependencies});

      resolve(this.buildHtml(gist, out.join('\n'), cssOut.join('\n')));
    });

    return promise;
  },

  buildHtml (gist, appJS, appCSS) {
    if (gist.get('initialRoute')) {
      appJS += "window.location.hash='" + gist.get('initialRoute') + "';";
    }

    // avoids security error
    appJS += "window.history.pushState = function() {}; window.history.replaceState = function() {};";

    // Hide toolbar since it is not working
    appCSS += `\n#qunit-testrunner-toolbar { display: none; }\n`;

    let index = blueprints['index.html'];
    let twiddleJSON = this.getTwiddleJson(gist);
    let deps = twiddleJSON.dependencies;

    let depCssLinkTags = '';
    let depScriptTags ='';
    let appScriptTag = `<script type="text/javascript">${appJS}</script>`;
    let appStyleTag = `<style type="text/css">${appCSS}</style>`;
    let testStuff = '';

    let EmberENV = twiddleJSON.EmberENV || {};
    depScriptTags += `<script type="text/javascript">EmberENV = ${JSON.stringify(EmberENV)};</script>`;

    Object.keys(deps).forEach(function(depKey) {
      let dep = deps[depKey];
      if (dep.substr(dep.lastIndexOf(".")) === '.css') {
        depCssLinkTags += `<link rel="stylesheet" type="text/css" href="${dep}">`;
      } else {
        depScriptTags += `<script type="text/javascript" src="${dep}"></script>`;
      }
    });

    depScriptTags += `<script type="text/javascript" src="${config.assetsHost}assets/twiddle-deps.js?${config.APP.version}"></script>`;

    const testingEnabled = twiddleJSON.options && twiddleJSON.options["enable-testing"];

    if (testingEnabled) {
      const testJSFiles = ['assets/test-loader.js', 'assets/test-support.js', 'testem.js'];

      testJSFiles.forEach(jsFile => {
        depScriptTags += `<script type="text/javascript" src="${config.assetsHost}${jsFile}?${config.APP.version}"></script>`;
      });

      depCssLinkTags += `<link rel="stylesheet" type="text/css" href="${config.assetsHost}assets/test-support.css?${config.APP.version}">`;

      testStuff += `

`;
    }

    index = index.replace('{{content-for \'head\'}}', `${depCssLinkTags}\n${appStyleTag}`);
    index = index.replace('{{content-for \'body\'}}', `${depScriptTags}\n${appScriptTag}\n${testStuff}\n`);

    // replace the {{build-timestamp}} placeholder with the number of
    // milliseconds since the Unix Epoch:
    // http://momentjs.com/docs/#/displaying/unix-offset/
    index = index.replace('{{build-timestamp}}', +moment());

    return index;
  },

  checkRequiredFiles (out, gist) {
    requiredFiles.forEach(filePath => {
      var file = gist.get('files').findBy('filePath', filePath);
      if(!file) {
        gist.get('files').pushObject(this.store.createRecord('gistFile', {
          filePath: filePath,
          content: blueprints[filePath]
        }));
      }
    });
  },

  addBoilerPlateFiles (out, gist) {
    boilerPlateJs.forEach(blueprintName => {
      let blueprint = availableBlueprints[blueprintName];
      if(!gist.get('files').findBy('filePath', blueprint.filePath)) {
        out.push(this.compileJs(blueprints[blueprint.blueprint], blueprint.filePath));
      }
    });
  },

  addConfig (out) {
    let config = {
      modulePrefix: "demo-app",
      TWIDDLE_ORIGIN: location.origin
    };

    let configJs = 'export default ' + JSON.stringify(config);
    out.push(this.compileJs(configJs, 'config/environment'));
  },

  getTwiddleJson (gist) {
    var twiddleJson = JSON.parse(gist.get('files').findBy('filePath', 'twiddle.json').get('content'));

    // Fill in any missing required dependencies
    var dependencies = JSON.parse(blueprints['twiddle.json']).dependencies;
    requiredDependencies.forEach(function(dep) {
      if (!twiddleJson.dependencies[dep] && dependencies[dep]) {
        if (dep === 'ember-template-compiler') {
          twiddleJson.dependencies[dep] = twiddleJson.dependencies['ember'].replace('ember.debug.js', 'ember-template-compiler.js');
        } else {
          twiddleJson.dependencies[dep] = dependencies[dep];
        }
      }
    });

    var dependencyResolver = this.get('dependencyResolver');
    dependencyResolver.resolveDependencies(twiddleJson.dependencies);

    return twiddleJson;
  },

  updateDependencyVersion: function(gist, dependencyName, version) {
    return new Ember.RSVP.Promise(function(resolve, reject) {
      var twiddle = gist.get('files').findBy('filePath', 'twiddle.json');

      var json;
      try {
        json = JSON.parse(twiddle.get('content'));
      } catch (e) {
        return reject(e);
      }

      json.dependencies[dependencyName] = version;

      // since ember and ember-template-compiler should always have the same
      // version, we update the version for the ember-template-compiler too, if
      // the ember dependency is updated
      if (dependencyName === 'ember' && json.dependencies.hasOwnProperty('ember-template-compiler')) {
        json.dependencies['ember-template-compiler'] = version;
      }

      json = JSON.stringify(json, null, '  ');
      twiddle.set('content', json);

      resolve();
    });
  },

  /**
   * Compile a javascript file. This means that we
   * transform it using Babel.
   *
   * @param  {String} code       ES6 module code
   * @param  {String} filePath   File path (will be used for module name)
   * @return {String}            Transpiled module code
   */
  compileJs (code, filePath) {
    let moduleName = this.nameWithModule(filePath);
    return Babel.transform(code, babelOpts(moduleName)).code;
  },

  /**
   * Compile a Handlebars template into an AMD module.
   *
   * @param  {String} code       hbs code
   * @param  {String} filePath   File path (will be used for module name)
   * @return {String}            AMD module code
   */
  compileHbs (code, filePath) {
    // TODO: Is there a way to precompile using the template compiler brought in via twiddle.json?
    // let templateCode = Ember.HTMLBars.precompile(code || '');

    // Compiles all templates at runtime.
    let moduleName = this.nameWithModule(filePath);

    const mungedCode = (code || '')
            .replace(/\\/g, "\\\\") // Prevent backslashes from being escaped
            .replace(/`/g, "\\`"); // Prevent backticks from causing syntax errors

    return this.compileJs('export default Ember.HTMLBars.compile(`' + mungedCode + '`, { moduleName: `' + moduleName + '`});', filePath);
  },

  compileCss(code, moduleName) {
    var prefix = "styles/";
    if (moduleName.substring(0, prefix.length) === prefix) {
        return code;
    }
    return '';
  }
});

/**
 * Generate babel options for the specified module
 * @param  {String} moduleName
 * @return {Object}            Babel options
 */
function babelOpts(moduleName) {
  return {
    modules:'amd',
    moduleIds:true,
    moduleId: moduleName
  };
}

/**
 * Generate the application boot code
 * @param  {Array} content  Code buffer to append to
 * @param  {Object} config  App configuration
 * @return {Array}          Code buffer
 */
function contentForAppBoot (content, config) {

  // Some modules are not actually transpiled so Babel
  // doesn't recognize them properly...
  var monkeyPatchModules = [
    'ember',
    'ember/load-initializers',
    'ember-resolver'
  ];

  if ("ember-data" in config.dependencies) {
    monkeyPatchModules.push('ember-data');
  }

  monkeyPatchModules.forEach(function(mod) {
    content.push('  require("'+mod+'").__esModule=true;');
  });

  content.push('  require("' +
    config.modulePrefix +
    '/app")["default"].create(' +
    calculateAppConfig(config) +
    ');');
}

/**
 * Directly copied from ember-cli
 */
function calculateAppConfig(config) {
  return JSON.stringify(config.APP || {});
}
<|endoftext|>


<commit_before>import { inject as service } from '@ember/service';
import { singularize } from 'ember-inflector';
import Service from '@ember/service';
import ENUMS from 'irene/enums';
import ENV from 'irene/config/environment';

export default class WebsocketService extends Service {
  @service store;
  @service configuration;
  @service logger;
  @service realtime;
  @service notifications;
  @service('socket-io') socketIOService;

  connectionPath = '/websocket';

  currentUser = null;
  currentSocketID = null;
  connectedSocket = null;

  reset() {
    this.currentUser = null;
    this.currentSocketID = null;
    this.connectedSocket = null;
  }

  getHost() {
    const hostFromConfig = this.configuration.serverData.websocket;
    if (hostFromConfig) {
      return hostFromConfig;
    }
    return '/';
  }

  async configure(user) {
    if (!user) {
      return;
    }
    const socketId = user.socketId;
    if (!socketId) {
      return;
    }
    this.currentSocketID = socketId;
    this.currentUser = user;
    await this.connect();
  }

  async connect() {
    const host = this.getHost();
    this.logger.debug(`Connecting websocket to ${host}`);
    const socket = this.socketIOService.socketFor(host, {
      path: this.connectionPath,
    });
    this.connectedSocket = socket;
    this._initializeSocket(socket);
  }

  async _initializeSocket(socket) {
    socket.on('connect', this.onConnect, this);
    socket.on('object', this.onObject, this);
    socket.on('newobject', this.onNewObject, this);
    socket.on('message', this.onMessage, this);
    socket.on('counter', this.onCounter, this);
    socket.on('close', (event) => {
      this.logger.warning('socket close called. Trying to reconnect', event);
      socket.reconnect();
    });
  }

  onConnect() {
    const socket = this.connectedSocket;
    this.logger.debug('Connecting to room: ' + this.currentSocketID);
    socket.emit('subscribe', {
      room: this.currentSocketID,
    });
  }

  onObject(data = {}) {
    if (!data) {
      this.logger.error(`invalid data for onObject`);
      return;
    }
    if (!data.id || !data.type) {
      this.logger.error(`invalid data for onObject ${JSON.stringify(data)}`);
      return;
    }

    const objectID = data.id;
    const objectType = data.type;

    const modelName = singularize(objectType);
    this.pullModel(modelName, objectID);
  }

  onNewObject(...args) {
    return this.onObject(...args);
  }

  onMessage(data) {
    if (!data) {
      this.logger.error(`invalid data for onMessage`);
      return;
    }

    if (!data.message || !data.notifyType) {
      this.logger.error(`invalid data for onMessage ${JSON.stringify(data)}`);
      return;
    }
    const message = data.message;
    const notifyType = data.notifyType;

    if (notifyType === ENUMS.NOTIFY.INFO) {
      this.notifications.info(message, ENV.notifications);
    }
    if (notifyType === ENUMS.NOTIFY.SUCCESS) {
      this.notifications.success(message, ENV.notifications);
    }
    if (notifyType === ENUMS.NOTIFY.WARNING) {
      this.notifications.warning(message, ENV.notifications);
    }
    if (notifyType === ENUMS.NOTIFY.ALERT) {
      this.notifications.alert(message, ENV.notifications);
    }
    if (notifyType === ENUMS.NOTIFY.ERROR) {
      this.notifications.error(message, {
        autoClear: false,
      });
    }
    this.logger.debug(`${notifyType}: ${message}`);
  }

  onCounter(data) {
    if (!data) {
      this.logger.error(`invalid data for onCounter`);
      return;
    }
    if (!data.type) {
      this.logger.error(`invalid data for onCounter ${JSON.stringify(data)}`);
      return;
    }

    this.realtime.incrementProperty(`${data.type}Counter`);
    this.logger.debug(`Realtime increment for ${data.type}`);
  }

  pullModel(modelName, id) {
    try {
      this.store.modelFor(modelName);
      this.store.findRecord(modelName, id);
    } catch (error) {
      this.logger.error(error);
    }
    this.logger.debug(`Pulling ${modelName}: ${id}`);
  }
}
<commit_msg>Fix websocket resolution for unconfigured websocket in configuration endpoint<commit_after>import { inject as service } from '@ember/service';
import { singularize } from 'ember-inflector';
import Service from '@ember/service';
import ENUMS from 'irene/enums';
import ENV from 'irene/config/environment';

export default class WebsocketService extends Service {
  @service store;
  @service configuration;
  @service logger;
  @service realtime;
  @service notifications;
  @service network;
  @service('socket-io') socketIOService;

  connectionPath = '/websocket';

  currentUser = null;
  currentSocketID = null;
  connectedSocket = null;

  reset() {
    this.currentUser = null;
    this.currentSocketID = null;
    this.connectedSocket = null;
  }

  getHost() {
    const hostFromConfig = this.configuration.serverData.websocket;
    if (hostFromConfig) {
      return hostFromConfig;
    }
    if (this.network.host) {
      return this.network.host;
    }
    return '/';
  }

  async configure(user) {
    if (!user) {
      return;
    }
    const socketId = user.socketId;
    if (!socketId) {
      return;
    }
    this.currentSocketID = socketId;
    this.currentUser = user;
    await this.connect();
  }

  async connect() {
    const host = this.getHost();
    this.logger.debug(`Connecting websocket to ${host}`);
    const socket = this.socketIOService.socketFor(host, {
      path: this.connectionPath,
    });
    this.connectedSocket = socket;
    this._initializeSocket(socket);
  }

  async _initializeSocket(socket) {
    socket.on('connect', this.onConnect, this);
    socket.on('object', this.onObject, this);
    socket.on('newobject', this.onNewObject, this);
    socket.on('message', this.onMessage, this);
    socket.on('counter', this.onCounter, this);
    socket.on('close', (event) => {
      this.logger.warning('socket close called. Trying to reconnect', event);
      socket.reconnect();
    });
  }

  onConnect() {
    const socket = this.connectedSocket;
    this.logger.debug('Connecting to room: ' + this.currentSocketID);
    socket.emit('subscribe', {
      room: this.currentSocketID,
    });
  }

  onObject(data = {}) {
    if (!data) {
      this.logger.error(`invalid data for onObject`);
      return;
    }
    if (!data.id || !data.type) {
      this.logger.error(`invalid data for onObject ${JSON.stringify(data)}`);
      return;
    }

    const objectID = data.id;
    const objectType = data.type;

    const modelName = singularize(objectType);
    this.pullModel(modelName, objectID);
  }

  onNewObject(...args) {
    return this.onObject(...args);
  }

  onMessage(data) {
    if (!data) {
      this.logger.error(`invalid data for onMessage`);
      return;
    }

    if (!data.message || !data.notifyType) {
      this.logger.error(`invalid data for onMessage ${JSON.stringify(data)}`);
      return;
    }
    const message = data.message;
    const notifyType = data.notifyType;

    if (notifyType === ENUMS.NOTIFY.INFO) {
      this.notifications.info(message, ENV.notifications);
    }
    if (notifyType === ENUMS.NOTIFY.SUCCESS) {
      this.notifications.success(message, ENV.notifications);
    }
    if (notifyType === ENUMS.NOTIFY.WARNING) {
      this.notifications.warning(message, ENV.notifications);
    }
    if (notifyType === ENUMS.NOTIFY.ALERT) {
      this.notifications.alert(message, ENV.notifications);
    }
    if (notifyType === ENUMS.NOTIFY.ERROR) {
      this.notifications.error(message, {
        autoClear: false,
      });
    }
    this.logger.debug(`${notifyType}: ${message}`);
  }

  onCounter(data) {
    if (!data) {
      this.logger.error(`invalid data for onCounter`);
      return;
    }
    if (!data.type) {
      this.logger.error(`invalid data for onCounter ${JSON.stringify(data)}`);
      return;
    }

    this.realtime.incrementProperty(`${data.type}Counter`);
    this.logger.debug(`Realtime increment for ${data.type}`);
  }

  pullModel(modelName, id) {
    try {
      this.store.modelFor(modelName);
      this.store.findRecord(modelName, id);
    } catch (error) {
      this.logger.error(error);
    }
    this.logger.debug(`Pulling ${modelName}: ${id}`);
  }
}
<|endoftext|>


<commit_before>/**
 * @ngdoc     overview
 * @name      alquimia
 * @author    Mauro Constantinescu <mauro.constantinescu@gmail.com>
 * @copyright © 2015 White, Red & Green Digital S.r.l.
 *
 * @description
 * The `alquimia` module provides utility objects for using the Alquimia framework as efficiently as possible.
 * The main goal of this module is to help developers handling `$location`'s **HTML5 mode** and communicating
 * with the Wordpress' **WP REST API** plugin and specifically with the Alquimia Wordpress plugin for the API.
 */
var module = angular.module( 'alquimia', ['restangular'] )

if ( window.location && window.location.hostname === 'localhost' ) {
  module.directive( 'a', ['$location', require( './d-a' )] )
}

if ( global.oauth ) {
  module.provider( 'oauth', require( './p-oauth' ) );
}

module.provider( 'WPApi', require( './p-wp-api' ) );
<commit_msg>Update index.js<commit_after>/**
 * @ngdoc     overview
 * @name      alquimia
 * @author    Mauro Constantinescu <mauro.constantinescu@gmail.com>
 * @copyright © 2015 White, Red & Green Digital S.r.l.
 *
 * @description
 * The `alquimia` module provides utility objects for using the Alquimia framework as efficiently as possible.
 * The main goal of this module is to help developers handling `$location`'s **HTML5 mode** and communicating
 * with the Wordpress' **WP REST API** plugin and specifically with the Alquimia Wordpress plugin for the API.
 */
var deps = ['restangular'];

if ( global.oauth ) deps.push( 'ngCookies' );

var module = angular.module( 'alquimia', deps );

if ( window.location && window.location.hostname === 'localhost' ) {
  module.directive( 'a', ['$location', require( './d-a' )] )
}

if ( global.oauth ) {
  module.provider( 'oauth', [require( './p-oauth' )] );
}

module.provider( 'WPApi', require( './p-wp-api' ) );
<|endoftext|>


<commit_before>$('.dropdown-toggle').dropdown();

moment.locale('ja', { week: { dow: 1 } });

var DateFormat = 'YYYY-MM-DD';
$(function () {
    $('#searchform-date').datetimepicker({
        inline: true,
        locale: moment.locale('ja'),
        format: DateFormat
    });

    $('#order-results').change(function() {
        var Url = window.location.href;
        switch(this.value){
            case "開始日(昇順）":
                var desc = "asc";
                break;
            case "開始日(降順)":
                var desc = "desc";
                break;
            default:
                var desc = "";
                break;
        }
        var regex = /\b(order_by=start_time-)[^&]*/;
        if(regex.test(Url)){
            var newUrl = Url.replace(regex, '$1' + desc);
        } else{
            var newUrl = Url + "&order_by=start_time-" + desc;
        }
        newUrl = newUrl.replace(/\bpage=\d+/,"page=1");
        window.location.replace(newUrl);
    });

    $('#result-number').change(function() {
        var Url = window.location.href;
        num = this.value
        var regex = /\b(numperpage=)[^&]*/;
        if(regex.test(Url)){
            var newUrl = Url.replace(regex, '$1' + num);
        } else{
            var newUrl = Url + "&numperpage=" + num;
        }
        window.location.replace(newUrl)
    });
});

<commit_msg>変数のスコープをファイルの中に抑えるようにしました<commit_after>(function (window) {
  var $ = window.jQuery;
  var moment = window.moment;

$('.dropdown-toggle').dropdown();

moment.locale('ja', { week: { dow: 1 } });

var DateFormat = 'YYYY-MM-DD';
$(function () {
    $('#searchform-date').datetimepicker({
        inline: true,
        locale: moment.locale('ja'),
        format: DateFormat
    });

    $('#order-results').change(function() {
        var Url = window.location.href;
        switch(this.value){
            case "開始日(昇順）":
                var desc = "asc";
                break;
            case "開始日(降順)":
                var desc = "desc";
                break;
            default:
                var desc = "";
                break;
        }
        var regex = /\b(order_by=start_time-)[^&]*/;
        if(regex.test(Url)){
            var newUrl = Url.replace(regex, '$1' + desc);
        } else{
            var newUrl = Url + "&order_by=start_time-" + desc;
        }
        newUrl = newUrl.replace(/\bpage=\d+/,"page=1");
        window.location.replace(newUrl);
    });

    $('#result-number').change(function() {
        var Url = window.location.href;
        num = this.value
        var regex = /\b(numperpage=)[^&]*/;
        if(regex.test(Url)){
            var newUrl = Url.replace(regex, '$1' + num);
        } else{
            var newUrl = Url + "&numperpage=" + num;
        }
        window.location.replace(newUrl)
    });
});

})(this);
<|endoftext|>


<commit_before>// Use '[[' and ']]' tags since Django using Mustache's default template tags.
Mustache.tags = ['[[', ']]'];

$(function(){
  var swiper = new Swiper('.swiper-container', {
    loop : true,
    pagination: '.swiper-pagination',
    nextButton: '.swiper-button-next',
    prevButton: '.swiper-button-prev',
    slidesPerView: 'auto',
    centeredSlides: true,
    paginationClickable: true,
    spaceBetween: 30
  });
  $('#top-tabs').tabs({
    selected: 0
  });
});

(function (window) {
  var $ = window.jQuery;
  var moment = window.moment;

  $('.dropdown-toggle').dropdown();

  $(function () {
    webshim.activeLang('ja');
    $.webshims.setOptions('extendNative', true);
    $.webshims.polyfill('forms');
  });

  moment.locale('ja', {week: {dow: 1}});

  var DateFormat = 'YYYY-MM-DD';
  $(function () {
    $('#searchform-date').datetimepicker({
      inline: true,
      locale: moment.locale('ja'),
      format: DateFormat
    });

    $('#order-results').change(function() {
      var Url = window.location.href;
      var desc;
      switch (this.value) {
        case "開始日(昇順）":
          desc = "asc";
          break;
        case "開始日(降順)":
          desc = "desc";
          break;
        default:
          desc = "";
          break;
      }
      var regex = /\b(order_by=start_time-)[^&]*/;
      var newUrl;
      if (regex.test(Url)) {
        newUrl = Url.replace(regex, '$1' + desc);
      } else {
        newUrl = Url + "&order_by=start_time-" + desc;
      }
      newUrl = newUrl.replace(/\bpage=\d+/, "page=1");
      window.location.replace(newUrl);
    });

    $('#result-number').change(function() {
      var Url = window.location.href;
      var num = this.value;
      var regex = /\b(numperpage=)[^&]*/;
      var newUrl;
      if (regex.test(Url)) {
        newUrl = Url.replace(regex, '$1' + num);
      } else {
        newUrl = Url + "&numperpage=" + num;
      }
      window.location.replace(newUrl);
    });
  });
})(this);

/**
 * bootstrap-confirmation2
 */
(function (global) {
  global.jQuery(function ($) {
    $('[data-toggle=confirmation]').confirmation({
      rootSelector: '[data-toggle=confirmation]',
      title: '本当によろしいですか？',
      btnOkLabel: 'はい',
      btnCancelLabel: 'いいえ'
    });
  });
})(this);

/**
 * croppie-upload - use croppie.js to crop uploaded images
 */
(function (global) {
  var $ = global.jQuery;
  var Blob = global.Blob;
  var alert = global.alert;
  var FileReader = global.FileReader;
  var FormData = global.FormData;

  var base64ToBlob = function (src) {
    var chunkSize = 1024;

    var srcList = src.split(/[:;,]/);
    var mime = srcList[1];
    var byteChars = global.atob(srcList[3]);
    var byteArrays = [];

    for (var c = 0, len = byteChars.length; c < len; c += chunkSize) {
      var slice = byteChars.slice(c, c + chunkSize);
      var byteNumbers = new Array(slice.length);
      for (var i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }
      var byteArray = new Uint8Array(byteNumbers);
      byteArrays.push(byteArray);
    }

    return new Blob(byteArrays, {type: mime});
  };

  $.fn.extend({
    croppieUpload: function (opt) {
      var self = this;
      var div;

      // read file
      self.on('change', function () {
        $('.croppie-upload-ready').remove();

        div = $('<div>')
          .addClass('croppie-upload-ready')
          .croppie(
            $.extend({
              enableExif: true,
              viewport: {
                width: 200,
                height: 200,
                type: 'square'
              },
              boundary: {
                width: 300,
                height: 300
              }
            }, opt)
          );

        if (!this.files || !this.files[0]) {
          alert("Sorry - your browser doesn't support the FileReader API");
          return false;
        }

        var reader = new FileReader();
        reader.onload = function (e) {
          div.croppie('bind', {
            url: e.target.result
          });
        };
        reader.readAsDataURL(this.files[0]);
        self.after(div);
      });

      self.closest('form').submit(function () {
        var form = $(this);
        var formData = new FormData(form.get(0));
        var name = self.attr('name');

        div
          .croppie('result', {
            type: 'canvas',
            size: 'viewport'
          })
          .then(function (resp) {
            formData.append(name, base64ToBlob(resp), 'cropped');
            $.ajax({
              cache: true,
              async: false,
              url: form.attr('action'),
              type: form.attr('method'),
              cache: false,
              processData: false,
              contentType: false,
              data: formData,
            })
            .done(function () {
              global.location.reload();
            });
          });

        return false;
      });
    }
  });
})(this);
<commit_msg>[REFACTOR] \#order-results is no longer available<commit_after>// Use '[[' and ']]' tags since Django using Mustache's default template tags.
Mustache.tags = ['[[', ']]'];

$(function(){
  var swiper = new Swiper('.swiper-container', {
    loop : true,
    pagination: '.swiper-pagination',
    nextButton: '.swiper-button-next',
    prevButton: '.swiper-button-prev',
    slidesPerView: 'auto',
    centeredSlides: true,
    paginationClickable: true,
    spaceBetween: 30
  });
  $('#top-tabs').tabs({
    selected: 0
  });
});

(function (window) {
  var $ = window.jQuery;
  var moment = window.moment;

  $('.dropdown-toggle').dropdown();

  $(function () {
    webshim.activeLang('ja');
    $.webshims.setOptions('extendNative', true);
    $.webshims.polyfill('forms');
  });

  moment.locale('ja', {week: {dow: 1}});

  var DateFormat = 'YYYY-MM-DD';
  $(function () {
    $('#searchform-date').datetimepicker({
      inline: true,
      locale: moment.locale('ja'),
      format: DateFormat
    });

    $('#result-number').change(function() {
      var Url = window.location.href;
      var num = this.value;
      var regex = /\b(numperpage=)[^&]*/;
      var newUrl;
      if (regex.test(Url)) {
        newUrl = Url.replace(regex, '$1' + num);
      } else {
        newUrl = Url + "&numperpage=" + num;
      }
      window.location.replace(newUrl);
    });
  });
})(this);

/**
 * bootstrap-confirmation2
 */
(function (global) {
  global.jQuery(function ($) {
    $('[data-toggle=confirmation]').confirmation({
      rootSelector: '[data-toggle=confirmation]',
      title: '本当によろしいですか？',
      btnOkLabel: 'はい',
      btnCancelLabel: 'いいえ'
    });
  });
})(this);

/**
 * croppie-upload - use croppie.js to crop uploaded images
 */
(function (global) {
  var $ = global.jQuery;
  var Blob = global.Blob;
  var alert = global.alert;
  var FileReader = global.FileReader;
  var FormData = global.FormData;

  var base64ToBlob = function (src) {
    var chunkSize = 1024;

    var srcList = src.split(/[:;,]/);
    var mime = srcList[1];
    var byteChars = global.atob(srcList[3]);
    var byteArrays = [];

    for (var c = 0, len = byteChars.length; c < len; c += chunkSize) {
      var slice = byteChars.slice(c, c + chunkSize);
      var byteNumbers = new Array(slice.length);
      for (var i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }
      var byteArray = new Uint8Array(byteNumbers);
      byteArrays.push(byteArray);
    }

    return new Blob(byteArrays, {type: mime});
  };

  $.fn.extend({
    croppieUpload: function (opt) {
      var self = this;
      var div;

      // read file
      self.on('change', function () {
        $('.croppie-upload-ready').remove();

        div = $('<div>')
          .addClass('croppie-upload-ready')
          .croppie(
            $.extend({
              enableExif: true,
              viewport: {
                width: 200,
                height: 200,
                type: 'square'
              },
              boundary: {
                width: 300,
                height: 300
              }
            }, opt)
          );

        if (!this.files || !this.files[0]) {
          alert("Sorry - your browser doesn't support the FileReader API");
          return false;
        }

        var reader = new FileReader();
        reader.onload = function (e) {
          div.croppie('bind', {
            url: e.target.result
          });
        };
        reader.readAsDataURL(this.files[0]);
        self.after(div);
      });

      self.closest('form').submit(function () {
        var form = $(this);
        var formData = new FormData(form.get(0));
        var name = self.attr('name');

        div
          .croppie('result', {
            type: 'canvas',
            size: 'viewport'
          })
          .then(function (resp) {
            formData.append(name, base64ToBlob(resp), 'cropped');
            $.ajax({
              cache: true,
              async: false,
              url: form.attr('action'),
              type: form.attr('method'),
              cache: false,
              processData: false,
              contentType: false,
              data: formData,
            })
            .done(function () {
              global.location.reload();
            });
          });

        return false;
      });
    }
  });
})(this);
<|endoftext|>


<commit_before>import Ember from 'ember';

const { computed } = Ember;

/**
 * @see https://github.com/emberjs/ember.js/blob/v2.14.1/packages/ember-views/lib/mixins/action_support.js
 */
export default Ember.Mixin.create({

  /**
   * you need to override this
   */
  states: undefined,

  currentState: computed({
    get() {
      return this._defaultStateMapping[''];
    },
    set(key, value) {
      const theState = this._defaultStateMapping[value];
      if (Ember.isNone(theState)) {
        throw new Error(`Invalid state transition attempted. Unknown state: ${value}`);
      }
      return theState;
    },
  }),

  /**
   * If the current State is 'a.b.c', this property is `{ a: { b: { c: {}}}}`
   * The idea is to simplify state checks, e.g.
   * `if (this.get('state.a.b')) { ... }` will work in state 'a.b.c' and 'a.b.d',
   * epsecially for templates.
   *
   * @property {Object} state
   */
  state: computed('currentState', function() {
    return this.get('currentState').split('.').reduceRight((acc, s) => {
      return { [s]: acc };
    }, {});
  }),

  _defaultStateMapping: undefined,

  init(...args) {
    this._super(...args);
    const states = this.get('states');
    // put some empty actions into the actions hash so components don't complain
    const newRootStateActions = {};
    const stateToDefaultStateMap = {};
    // process in reverse order, because default states will be listed first
    states.reverse().forEach(state => {
      let stateParts = state.split('.');
      if (Ember.isNone(stateToDefaultStateMap[state])) {
        stateToDefaultStateMap[state] = state;
        // if stateToDefaultStateMap[state] is already set, the consumer
        // used a redundant intermediate state
      }
      while(stateParts.length > 0) {
        const thisState = stateParts.join('.');
        const parentState = stateParts.slice(0, -1).join('.');
        // we don't use Ember.set here, because keys will contain periods
        stateToDefaultStateMap[parentState] = thisState;
        const partlyActionsHash = this.get(`actions.${thisState}`);
        Object.keys(partlyActionsHash).forEach(actionName => {
          const maybeAction = partlyActionsHash[actionName];
          if (Ember.isNone(newRootStateActions[actionName])) {
            const rootAction = this.actions[actionName];
            if (Ember.isNone(rootAction)) {
              newRootStateActions[actionName] = function(...args) {
                throw new Error(`A root action named '${actionName}' was not found in ${this}`);
              }
            } else {
              newRootStateActions[actionName] = rootAction;
            }
            this.actions[actionName] = function(...args) {
              this.send(actionName, ...args);
            }
          }
        });
        stateParts.pop();
      }
    });
    this._defaultStateMapping = stateToDefaultStateMap;
    this.actions._root = newRootStateActions;
  },

  send(actionName, ...args) {

    let stateParts = this.get('currentState').split('.');
    let shouldBubble = true;

    while(shouldBubble && stateParts.length > 0) {
      const action = this.get(`actions.${stateParts.join('.')}.${actionName}`);
      if (action) {
        shouldBubble = action.apply(this, args) === true;
      }
      stateParts.pop();
    };
    if (shouldBubble) {
      this.actions._root[actionName].apply(this, args);
    }
  },

  transitionTo(state) {
    this.set('currentState', state);
  },
});
<commit_msg>account for actions not being defined at all internal states<commit_after>import Ember from 'ember';

const { computed } = Ember;

/**
 * @see https://github.com/emberjs/ember.js/blob/v2.14.1/packages/ember-views/lib/mixins/action_support.js
 */
export default Ember.Mixin.create({

  /**
   * you need to override this
   */
  states: undefined,

  currentState: computed({
    get() {
      return this._defaultStateMapping[''];
    },
    set(key, value) {
      const theState = this._defaultStateMapping[value];
      if (Ember.isNone(theState)) {
        throw new Error(`Invalid state transition attempted. Unknown state: ${value}`);
      }
      return theState;
    },
  }),

  /**
   * If the current State is 'a.b.c', this property is `{ a: { b: { c: {}}}}`
   * The idea is to simplify state checks, e.g.
   * `if (this.get('state.a.b')) { ... }` will work in state 'a.b.c' and 'a.b.d',
   * epsecially for templates.
   *
   * @property {Object} state
   */
  state: computed('currentState', function() {
    return this.get('currentState').split('.').reduceRight((acc, s) => {
      return { [s]: acc };
    }, {});
  }),

  _defaultStateMapping: undefined,

  init(...args) {
    this._super(...args);
    const states = this.get('states');
    // put some empty actions into the actions hash so components don't complain
    const newRootStateActions = {};
    const stateToDefaultStateMap = {};
    // process in reverse order, because default states will be listed first
    states.reverse().forEach(state => {
      let stateParts = state.split('.');
      if (Ember.isNone(stateToDefaultStateMap[state])) {
        stateToDefaultStateMap[state] = state;
        // if stateToDefaultStateMap[state] is already set, the consumer
        // used a redundant intermediate state
      }
      while(stateParts.length > 0) {
        const thisState = stateParts.join('.');
        const parentState = stateParts.slice(0, -1).join('.');
        // we don't use Ember.set here, because keys will contain periods
        stateToDefaultStateMap[parentState] = thisState;
        const partlyActionsHash = this.get(`actions.${thisState}`) || {};
        Object.keys(partlyActionsHash).forEach(actionName => {
          const maybeAction = partlyActionsHash[actionName];
          if (Ember.isNone(newRootStateActions[actionName])) {
            const rootAction = this.actions[actionName];
            if (Ember.isNone(rootAction)) {
              newRootStateActions[actionName] = function(...args) {
                throw new Error(`A root action named '${actionName}' was not found in ${this}`);
              }
            } else {
              newRootStateActions[actionName] = rootAction;
            }
            this.actions[actionName] = function(...args) {
              this.send(actionName, ...args);
            }
          }
        });
        stateParts.pop();
      }
    });
    this._defaultStateMapping = stateToDefaultStateMap;
    this.actions._root = newRootStateActions;
  },

  send(actionName, ...args) {

    let stateParts = this.get('currentState').split('.');
    let shouldBubble = true;

    while(shouldBubble && stateParts.length > 0) {
      const action = this.get(`actions.${stateParts.join('.')}.${actionName}`);
      if (action) {
        shouldBubble = action.apply(this, args) === true;
      }
      stateParts.pop();
    };
    if (shouldBubble) {
      this.actions._root[actionName].apply(this, args);
    }
  },

  transitionTo(state) {
    this.set('currentState', state);
  },
});
<|endoftext|>


<commit_before>const chai = require('chai')
const dirtyChai = require('dirty-chai')
const http = require('http')
const fs = require('fs')
const os = require('os')
const path = require('path')
const ChildProcess = require('child_process')
const { remote } = require('electron')
const { session } = remote
const appPath = path.join(__dirname, 'fixtures', 'api', 'net-log')
const dumpFile = path.join(os.tmpdir(), 'net_log.json')
const dumpFileDynamic = path.join(os.tmpdir(), 'net_log_dynamic.json')

const { expect } = chai
chai.use(dirtyChai)
const isCI = remote.getGlobal('isCi')
const netLog = session.fromPartition('net-log').netLog

describe('netLog module', () => {
  let server
  const connections = new Set()

  before(done => {
    server = http.createServer()
    server.listen(0, '127.0.0.1', () => {
      server.url = `http://127.0.0.1:${server.address().port}`
      done()
    })
    server.on('connection', (connection) => {
      connections.add(connection)
      connection.once('close', () => {
        connections.delete(connection)
      })
    })
    server.on('request', (request, response) => {
      response.end()
    })
  })

  after(done => {
    for (const connection of connections) {
      connection.destroy()
    }
    server.close(() => {
      server = null
      done()
    })
  })

  afterEach(() => {
    try {
      if (fs.existsSync(dumpFile)) {
        fs.unlinkSync(dumpFile)
      }
      if (fs.existsSync(dumpFileDynamic)) {
        fs.unlinkSync(dumpFileDynamic)
      }
    } catch (e) {
      // Ignore error
    }
  })

  it('should begin and end logging to file when .startLogging() and .stopLogging() is called', done => {
    expect(netLog.currentlyLogging).to.be.false()
    expect(netLog.currentlyLoggingPath).to.equal('')

    netLog.startLogging(dumpFileDynamic)

    expect(netLog.currentlyLogging).to.be.true()
    expect(netLog.currentlyLoggingPath).to.equal(dumpFileDynamic)

    netLog.stopLogging((path) => {
      expect(netLog.currentlyLogging).to.be.false()
      expect(netLog.currentlyLoggingPath).to.equal('')

      expect(path).to.equal(dumpFileDynamic)
      expect(fs.existsSync(dumpFileDynamic)).to.be.true()

      done()
    })
  })

  it('should silence when .stopLogging() is called without calling .startLogging()', done => {
    expect(netLog.currentlyLogging).to.be.false()
    expect(netLog.currentlyLoggingPath).to.equal('')

    netLog.stopLogging(path => {
      expect(netLog.currentlyLogging).to.be.false()
      expect(netLog.currentlyLoggingPath).to.equal('')

      expect(path).to.equal('')

      done()
    })
  })

  it('should begin and end logging automatically when --log-net-log is passed', done => {
    if (isCI && process.platform === 'linux') {
      done()
      return
    }

    const appProcess = ChildProcess.spawn(remote.process.execPath,
      [appPath], {
        env: {
          TEST_REQUEST_URL: server.url,
          TEST_DUMP_FILE: dumpFile
        }
      })

    appProcess.once('exit', () => {
      expect(fs.existsSync(dumpFile)).to.be.true()
      done()
    })
  })

  // FIXME(deepak1556): Ch69 follow up.
  xit('should begin and end logging automtically when --log-net-log is passed, and behave correctly when .startLogging() and .stopLogging() is called', done => {
    if (isCI && process.platform === 'linux') {
      done()
      return
    }

    const appProcess = ChildProcess.spawn(remote.process.execPath,
      [appPath], {
        env: {
          TEST_REQUEST_URL: server.url,
          TEST_DUMP_FILE: dumpFile,
          TEST_DUMP_FILE_DYNAMIC: dumpFileDynamic,
          TEST_MANUAL_STOP: true
        }
      })

    appProcess.once('exit', () => {
      expect(fs.existsSync(dumpFile)).to.be.true()
      expect(fs.existsSync(dumpFileDynamic)).to.be.true()
      done()
    })
  })

  it('should end logging automatically when only .startLogging() is called', done => {
    if (isCI && process.platform === 'linux') {
      done()
      return
    }

    const appProcess = ChildProcess.spawn(remote.process.execPath,
      [appPath], {
        env: {
          TEST_REQUEST_URL: server.url,
          TEST_DUMP_FILE_DYNAMIC: dumpFileDynamic
        }
      })

    appProcess.once('close', () => {
      expect(fs.existsSync(dumpFileDynamic)).to.be.true()
      done()
    })
  })
})
<commit_msg>chore: re-enable failing netlog spec (#15484)<commit_after>const chai = require('chai')
const dirtyChai = require('dirty-chai')
const http = require('http')
const fs = require('fs')
const os = require('os')
const path = require('path')
const ChildProcess = require('child_process')
const { remote } = require('electron')
const { session } = remote
const appPath = path.join(__dirname, 'fixtures', 'api', 'net-log')
const dumpFile = path.join(os.tmpdir(), 'net_log.json')
const dumpFileDynamic = path.join(os.tmpdir(), 'net_log_dynamic.json')

const { expect } = chai
chai.use(dirtyChai)
const isCI = remote.getGlobal('isCi')
const netLog = session.fromPartition('net-log').netLog

describe('netLog module', () => {
  let server
  const connections = new Set()

  before(done => {
    server = http.createServer()
    server.listen(0, '127.0.0.1', () => {
      server.url = `http://127.0.0.1:${server.address().port}`
      done()
    })
    server.on('connection', (connection) => {
      connections.add(connection)
      connection.once('close', () => {
        connections.delete(connection)
      })
    })
    server.on('request', (request, response) => {
      response.end()
    })
  })

  after(done => {
    for (const connection of connections) {
      connection.destroy()
    }
    server.close(() => {
      server = null
      done()
    })
  })

  afterEach(() => {
    try {
      if (fs.existsSync(dumpFile)) {
        fs.unlinkSync(dumpFile)
      }
      if (fs.existsSync(dumpFileDynamic)) {
        fs.unlinkSync(dumpFileDynamic)
      }
    } catch (e) {
      // Ignore error
    }
  })

  it('should begin and end logging to file when .startLogging() and .stopLogging() is called', done => {
    expect(netLog.currentlyLogging).to.be.false()
    expect(netLog.currentlyLoggingPath).to.equal('')

    netLog.startLogging(dumpFileDynamic)

    expect(netLog.currentlyLogging).to.be.true()
    expect(netLog.currentlyLoggingPath).to.equal(dumpFileDynamic)

    netLog.stopLogging((path) => {
      expect(netLog.currentlyLogging).to.be.false()
      expect(netLog.currentlyLoggingPath).to.equal('')

      expect(path).to.equal(dumpFileDynamic)
      expect(fs.existsSync(dumpFileDynamic)).to.be.true()

      done()
    })
  })

  it('should silence when .stopLogging() is called without calling .startLogging()', done => {
    expect(netLog.currentlyLogging).to.be.false()
    expect(netLog.currentlyLoggingPath).to.equal('')

    netLog.stopLogging(path => {
      expect(netLog.currentlyLogging).to.be.false()
      expect(netLog.currentlyLoggingPath).to.equal('')

      expect(path).to.equal('')

      done()
    })
  })

  it('should begin and end logging automatically when --log-net-log is passed', done => {
    if (isCI && process.platform === 'linux') {
      done()
      return
    }

    const appProcess = ChildProcess.spawn(remote.process.execPath,
      [appPath], {
        env: {
          TEST_REQUEST_URL: server.url,
          TEST_DUMP_FILE: dumpFile
        }
      })

    appProcess.once('exit', () => {
      expect(fs.existsSync(dumpFile)).to.be.true()
      done()
    })
  })

  // FIXME(deepak1556): Ch69 follow up.
  it('should begin and end logging automtically when --log-net-log is passed, and behave correctly when .startLogging() and .stopLogging() is called', done => {
    if (isCI && process.platform === 'linux') {
      done()
      return
    }

    const appProcess = ChildProcess.spawn(remote.process.execPath,
      [appPath], {
        env: {
          TEST_REQUEST_URL: server.url,
          TEST_DUMP_FILE: dumpFile,
          TEST_DUMP_FILE_DYNAMIC: dumpFileDynamic,
          TEST_MANUAL_STOP: true
        }
      })

    appProcess.once('exit', () => {
      expect(fs.existsSync(dumpFile)).to.be.true()
      expect(fs.existsSync(dumpFileDynamic)).to.be.true()
      done()
    })
  })

  it('should end logging automatically when only .startLogging() is called', done => {
    if (isCI && process.platform === 'linux') {
      done()
      return
    }

    const appProcess = ChildProcess.spawn(remote.process.execPath,
      [appPath], {
        env: {
          TEST_REQUEST_URL: server.url,
          TEST_DUMP_FILE_DYNAMIC: dumpFileDynamic
        }
      })

    appProcess.once('close', () => {
      expect(fs.existsSync(dumpFileDynamic)).to.be.true()
      done()
    })
  })
})
<|endoftext|>


<commit_before>/*global -$ */
'use strict';
// generated on <%= (new Date).toISOString().split('T')[0] %> using <%= pkg.name %> <%= pkg.version %>
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var browserSync = require('browser-sync');
var reload = browserSync.reload;

gulp.task('styles', function () {<% if (includeSass) { %>
  return gulp.src('app/styles/main.scss')
    .pipe($.sourcemaps.init())
    .pipe($.sass({
      outputStyle: 'nested', // libsass doesn't support expanded yet
      precision: 10,
      includePaths: ['.'],
      onError: console.error.bind(console, 'Sass error:')
    }))<% } else { %>
  return gulp.src('app/styles/main.css')<% } %>
    .pipe($.sourcemaps.init())
    .pipe($.postcss([
      require('autoprefixer-core')({browsers: ['last 1 version']})
    ]))
    .pipe($.sourcemaps.write())
    .pipe(gulp.dest('.tmp/styles'));
});

gulp.task('jshint', function () {
  return gulp.src('app/scripts/**/*.js')
    .pipe(reload({stream: true, once: true}))
    .pipe($.jshint())
    .pipe($.jshint.reporter('jshint-stylish'))
    .pipe($.if(!browserSync.active, $.jshint.reporter('fail')));
});

gulp.task('html', ['styles'], function () {
  var assets = $.useref.assets({searchPath: ['.tmp', 'app', '.']});

  return gulp.src('app/*.html')
    .pipe(assets)
    .pipe($.if('*.js', $.uglify()))
    .pipe($.if('*.css', $.csso()))
    .pipe(assets.restore())
    .pipe($.useref())
    .pipe($.if('*.html', $.minifyHtml({conditionals: true, loose: true})))
    .pipe(gulp.dest('dist'));
});

gulp.task('images', function () {
  return gulp.src('app/images/**/*')
    .pipe($.cache($.imagemin({
      progressive: true,
      interlaced: true
    })))
    .pipe(gulp.dest('dist/images'));
});

gulp.task('fonts', function () {
  return gulp.src(require('main-bower-files')().concat('app/fonts/**/*'))
    .pipe($.filter('**/*.{eot,svg,ttf,woff,woff2}'))
    .pipe($.flatten())
    .pipe(gulp.dest('.tmp/fonts'))
    .pipe(gulp.dest('dist/fonts'));
});

gulp.task('extras', function () {
  return gulp.src([
    'app/*.*',
    '!app/*.html'
  ], {
    dot: true
  }).pipe(gulp.dest('dist'));
});

gulp.task('clean', require('del').bind(null, ['.tmp', 'dist']));

gulp.task('serve', ['styles', 'fonts'], function () {
  browserSync({
    notify: false,
    port: 9000,
    server: {
      baseDir: ['.tmp', 'app'],
      routes: {
        '/bower_components': 'bower_components'
      }
    }
  });

  // watch for changes
  gulp.watch([
    'app/*.html',
    '.tmp/styles/**/*.css',
    'app/scripts/**/*.js',
    'app/images/**/*'
  ]).on('change', reload);

  gulp.watch('app/styles/**/*.<%= includeSass ? 'scss' : 'css' %>', ['styles', reload]);
  gulp.watch('bower.json', ['wiredep', 'fonts', reload]);
});

// inject bower components
gulp.task('wiredep', function () {
  var wiredep = require('wiredep').stream;
<% if (includeSass) { %>
  gulp.src('app/styles/*.scss')
    .pipe(wiredep({
      ignorePath: /^(\.\.\/)+/
    }))
    .pipe(gulp.dest('app/styles'));
<% } %>
  gulp.src('app/*.html')
    .pipe(wiredep({<% if (includeSass && includeBootstrap) { %>
      exclude: ['bootstrap-sass-official'],<% } %>
      ignorePath: /^(\.\.\/)*\.\./
    }))
    .pipe(gulp.dest('app'));
});

gulp.task('build', ['jshint', 'html', 'images', 'fonts', 'extras'], function () {
  return gulp.src('dist/**/*').pipe($.size({title: 'build', gzip: true}));
});

gulp.task('default', ['clean'], function () {
  gulp.start('build');
});
<commit_msg>Don't remove IDs from SVGs when optimizing<commit_after>/*global -$ */
'use strict';
// generated on <%= (new Date).toISOString().split('T')[0] %> using <%= pkg.name %> <%= pkg.version %>
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var browserSync = require('browser-sync');
var reload = browserSync.reload;

gulp.task('styles', function () {<% if (includeSass) { %>
  return gulp.src('app/styles/main.scss')
    .pipe($.sourcemaps.init())
    .pipe($.sass({
      outputStyle: 'nested', // libsass doesn't support expanded yet
      precision: 10,
      includePaths: ['.'],
      onError: console.error.bind(console, 'Sass error:')
    }))<% } else { %>
  return gulp.src('app/styles/main.css')<% } %>
    .pipe($.sourcemaps.init())
    .pipe($.postcss([
      require('autoprefixer-core')({browsers: ['last 1 version']})
    ]))
    .pipe($.sourcemaps.write())
    .pipe(gulp.dest('.tmp/styles'));
});

gulp.task('jshint', function () {
  return gulp.src('app/scripts/**/*.js')
    .pipe(reload({stream: true, once: true}))
    .pipe($.jshint())
    .pipe($.jshint.reporter('jshint-stylish'))
    .pipe($.if(!browserSync.active, $.jshint.reporter('fail')));
});

gulp.task('html', ['styles'], function () {
  var assets = $.useref.assets({searchPath: ['.tmp', 'app', '.']});

  return gulp.src('app/*.html')
    .pipe(assets)
    .pipe($.if('*.js', $.uglify()))
    .pipe($.if('*.css', $.csso()))
    .pipe(assets.restore())
    .pipe($.useref())
    .pipe($.if('*.html', $.minifyHtml({conditionals: true, loose: true})))
    .pipe(gulp.dest('dist'));
});

gulp.task('images', function () {
  return gulp.src('app/images/**/*')
    .pipe($.cache($.imagemin({
      progressive: true,
      interlaced: true,
      // don't remove IDs from SVGs, they are often used
      // as hooks for embedding and styling
      svgoPlugins: [{cleanupIDs: false}]
    })))
    .pipe(gulp.dest('dist/images'));
});

gulp.task('fonts', function () {
  return gulp.src(require('main-bower-files')().concat('app/fonts/**/*'))
    .pipe($.filter('**/*.{eot,svg,ttf,woff,woff2}'))
    .pipe($.flatten())
    .pipe(gulp.dest('.tmp/fonts'))
    .pipe(gulp.dest('dist/fonts'));
});

gulp.task('extras', function () {
  return gulp.src([
    'app/*.*',
    '!app/*.html'
  ], {
    dot: true
  }).pipe(gulp.dest('dist'));
});

gulp.task('clean', require('del').bind(null, ['.tmp', 'dist']));

gulp.task('serve', ['styles', 'fonts'], function () {
  browserSync({
    notify: false,
    port: 9000,
    server: {
      baseDir: ['.tmp', 'app'],
      routes: {
        '/bower_components': 'bower_components'
      }
    }
  });

  // watch for changes
  gulp.watch([
    'app/*.html',
    '.tmp/styles/**/*.css',
    'app/scripts/**/*.js',
    'app/images/**/*'
  ]).on('change', reload);

  gulp.watch('app/styles/**/*.<%= includeSass ? 'scss' : 'css' %>', ['styles', reload]);
  gulp.watch('bower.json', ['wiredep', 'fonts', reload]);
});

// inject bower components
gulp.task('wiredep', function () {
  var wiredep = require('wiredep').stream;
<% if (includeSass) { %>
  gulp.src('app/styles/*.scss')
    .pipe(wiredep({
      ignorePath: /^(\.\.\/)+/
    }))
    .pipe(gulp.dest('app/styles'));
<% } %>
  gulp.src('app/*.html')
    .pipe(wiredep({<% if (includeSass && includeBootstrap) { %>
      exclude: ['bootstrap-sass-official'],<% } %>
      ignorePath: /^(\.\.\/)*\.\./
    }))
    .pipe(gulp.dest('app'));
});

gulp.task('build', ['jshint', 'html', 'images', 'fonts', 'extras'], function () {
  return gulp.src('dist/**/*').pipe($.size({title: 'build', gzip: true}));
});

gulp.task('default', ['clean'], function () {
  gulp.start('build');
});
<|endoftext|>


<commit_before>'use strict';

/**
 * Tasks that will zip all the files so that the zip file can be deployed to
 * AWS Lambda.
 *
 * @author <%= name %>		<<%= email %>>
 * @since  <%= date %>
 */

// module dependencies
var gulp = require('gulp');
var install = require('gulp-install');
var zip = require('gulp-zip');
var del = require('del');

gulp.task('clean', ['zip'], function () {
	return del('.temp');
});

gulp.task('copyAndInstall', function () {
	return gulp.src(['./**', '!./**/*.md', '!.gitignore', '!gulpfile.js', '!travis.yml', '!./{dist,dist/**}', '!./{test,test/**}', '!./{node_modules,node_modules/**}'])
		.pipe(gulp.dest('.temp'))
		.pipe(install({production: true}));
});

gulp.task('zip', ['copyAndInstall'], function () {
	return gulp.src('.temp/**')
		.pipe(zip('build.zip'))
		.pipe(gulp.dest('dist'));
});

gulp.task('build', ['zip', 'clean']);
gulp.task('default', ['build']);
<commit_msg>Fixed #10<commit_after>'use strict';

/**
 * Tasks that will zip all the files so that the zip file can be deployed to
 * AWS Lambda.
 *
 * @author <%= name %>		<<%= email %>>
 * @since  <%= date %>
 */

// module dependencies
var gulp = require('gulp');
var install = require('gulp-install');
var zip = require('gulp-zip');
var del = require('del');

gulp.task('clean', ['zip'], function () {
	return del('.temp');
});

gulp.task('rmaws', ['copyAndInstall'], function () {
	return del('.temp/node_modules/aws-sdk');
});

gulp.task('copyAndInstall', function () {
	return gulp.src(['./**', '!./**/*.md', '!.gitignore', '!.aws.json', '!gulpfile.js', '!.travis.yml', '!./{dist,dist/**}', '!./{test,test/**}', '!./{node_modules,node_modules/**}'])
		.pipe(gulp.dest('.temp'))
		.pipe(install({production: true}));
});

gulp.task('zip', ['copyAndInstall', 'rmaws'], function () {
	return gulp.src('.temp/**')
		.pipe(zip('build.zip'))
		.pipe(gulp.dest('dist'));
});

gulp.task('build', ['copyAndInstall', 'rmaws', 'zip', 'clean']);
gulp.task('default', ['build']);
<|endoftext|>


<commit_before>import {
  indigo300, indigo700, indigo900,
  pinkA100, pinkA200, pinkA400, pinkA700,
  pink500, pink700,
  grey100, grey300, grey400, grey500,
  cyan500, cyan700,
  white, darkBlack, fullBlack
} from 'material-ui/styles/colors';
import { fade } from 'material-ui/utils/colorManipulator';
// import spacing from '../spacing';

const palette = {
  primary1Color: indigo900,
  primary2Color: indigo700,
  primary3Color: indigo300,
  accent1Color: pinkA200,
  accent2Color: pinkA100,
  accent3Color: pinkA400,
  textColor: white,
  alternateTextColor: white,
  canvasColor: indigo300,
  borderColor: grey300,
  disabledColor: fade(darkBlack, 0.3),
  pickerHeaderColor: cyan500,
  clockCircleColor: fade(darkBlack, 0.07),
  shadowColor: fullBlack,
};

export default {
  // spacing: spacing,
  palette,
  fontFamily: 'Roboto, sans-serif',
  raisedButton: {
    disabledColor: pinkA100,
    disabledTextColor: fade(white, 0.6),
  },
  menu: {
    backgroundColor: palette.canvasColor,
    containerBackgroundColor: palette.canvasColor,
  },
  menuItem: {
    // dataHeight: 32,
    // height: 48,
    hoverColor: fade(palette.textColor, 0.9),
    // padding: spacing.desktopGutter,
    selectedTextColor: palette.accent1Color,
    rightIconDesktopFill: indigo700,
  },
  // menuSubheader: {
  //   padding: spacing.desktopGutter,
  //   borderColor: palette.borderColor,
  //   textColor: palette.primary1Color,
  // },
  body:{
    backgroundColor: palette.primary2Color,
  }
};
<commit_msg>Indigo theme done<commit_after>import {
  indigo900 as primary1Color,
  indigo700 as primary2Color,
  indigo300 as primary3Color,

  pinkA200 as accent1Color,
  pinkA100 as accent2Color,
  pinkA400 as accent3Color,

  red800 as errorColor,
  grey300,
  white, darkBlack, fullBlack
} from 'material-ui/styles/colors';
import { fade } from 'material-ui/utils/colorManipulator';

const palette = {
  primary1Color,
  primary2Color,
  primary3Color,
  accent1Color,
  accent2Color,
  accent3Color,
  textColor: white,
  alternateTextColor: white,
  canvasColor: primary3Color,
  borderColor: grey300,
  disabledColor: fade(darkBlack, 0.3),
  pickerHeaderColor: white,
  clockCircleColor: fade(darkBlack, 0.7),
  shadowColor: fullBlack,
};

export default {
  palette,
  fontFamily: 'Roboto, sans-serif',
  raisedButton: {
    secondaryColor: accent1Color,
    disabledColor: accent2Color,
    disabledTextColor: fade(white, 0.6),
  },
  textField: {
    errorColor: errorColor,
  },
  menuItem: {
    hoverColor: fade(primary2Color, 0.6),
  },
  body:{
    backgroundColor: palette.primary2Color,
  }
};
<|endoftext|>


<commit_before>import { animate, Promise } from "liquid-fire";

export default function flyTo(opts={}) {
  if (!this.newElement) {
    return Promise.resolve();
  } else if (!this.oldElement) {
    this.newElement.css({visibility: ''});
    return Promise.resolve();
  }

  var oldOffset = this.oldElement.offset();
  var newOffset = this.newElement.offset();

  var motion = {
    translateX: newOffset.left - oldOffset.left,
    translateY: newOffset.top - oldOffset.top,
    outerWidth: this.newElement.outerWidth(),
    outerHeight: this.newElement.outerHeight()
  };

  this.newElement.css({ visibility: 'hidden' });
  return animate(this.oldElement, motion, opts).then(() => {
    this.newElement.css({ visibility: ''});
  });
}
<commit_msg>new `movingSide` option on the fly-to transition<commit_after>import { animate, Promise } from "liquid-fire";

export default function flyTo(opts={}) {
  if (!this.newElement) {
    return Promise.resolve();
  } else if (!this.oldElement) {
    this.newElement.css({visibility: ''});
    return Promise.resolve();
  }

  var oldOffset = this.oldElement.offset();
  var newOffset = this.newElement.offset();

  if (opts.movingSide === 'new') {
    let motion = {
      translateX: [0, oldOffset.left - newOffset.left],
      translateY: [0, oldOffset.top - newOffset.top],
      outerWidth: [this.newElement.outerWidth(), this.oldElement.outerWidth()],
      outerHeight: [this.newElement.outerHeight(), this.oldElement.outerHeight()]
    };
    this.oldElement.css({ visibility: 'hidden' });
    return animate(this.newElement, motion, opts);
  } else {
    let motion = {
      translateX: newOffset.left - oldOffset.left,
      translateY: newOffset.top - oldOffset.top,
      outerWidth: this.newElement.outerWidth(),
      outerHeight: this.newElement.outerHeight()
    };
    this.newElement.css({ visibility: 'hidden' });
    return animate(this.oldElement, motion, opts).then(() => {
      this.newElement.css({ visibility: ''});
    });
  }
}
<|endoftext|>


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

    /**
     * Component for the home page.
     * @returns {directive}
     */
    var homeDirective = function() {
        return {
            restrict: 'E',
            scope: {},
            controller: 'vgHomeCtrl',
            controllerAs: 'homeVm',
            bindToController: true,
            templateUrl: '/veganaut/home/home.tpl.html'
        };
    };

    var homeCtrl = [
        '$scope', '$location', '$translate', 'backendService', 'angularPiwik',
        'mainMapService', 'geocodeService', 'alertService', 'localeService',
        function($scope, $location, $translate, backendService, angularPiwik,
            mainMapService, geocodeService, alertService, localeService)
        {
            var vm = this;

            /**
             * Zoom on the map used when we show the place returned
             * by the browser's geo location API.
             * @type {number}
             */
            var GEO_LOCATION_ZOOM = 15;

            // Expose the global methods we still need
            // TODO: find a better way to do this
            vm.legacyGlobals = {
                goToView: $scope.$parent.goToView,
                isLoggedIn: $scope.$parent.isLoggedIn
            };

            /**
             * Cta form input model
             * @type {string}
             */
            vm.ctaFormInput = '';

            /**
             * Whether we are currently running geo locating
             * @type {boolean}
             */
            vm.geolocating = false;

            /**
             * The target place to show on the map when submitting the cta form.
             * @type {{}}
             */
            var targetPlace;

            /**
             * Whether to clear the cta input field on the next focus event
             * @type {boolean}
             */
            var clearCtaInputOnFocus = true;

            /**
             * Uses the geocodeService to search for places with the given name
             * @param {string} searchInput
             * @returns {GeocodeResult[]}
             */
            vm.getSearchResults = function(searchInput) {
                // TODO: should use piwik's search tracking
                angularPiwik.track('home.cta', 'home.cta.searchStart');

                return geocodeService.search(searchInput).then(function(response) {
                    return response;
                });
            };

            /**
             * Whether the cta form can currently be submitted
             * @returns {boolean}
             */
            vm.canSubmitCta = function() {
                // Can only submit when we have a target and it's currently shown in the input field
                return (angular.isObject(targetPlace) && targetPlace.displayName === vm.ctaFormInput);
            };

            /**
             * Handler for when the user selects a result from the auto-complete.
             * @param {GeocodeResult} selected
             */
            vm.onResultSelected = function(selected) {
                // Set the target place
                targetPlace = {
                    lat: selected.lat,
                    lng: selected.lng,
                    boundingBox: selected.bounds,
                    displayName: selected.getDisplayName()
                };

                // We no longer want to clear the input field on focus
                clearCtaInputOnFocus = false;

                angularPiwik.track('home.cta', 'home.cta.selectResult');
            };

            /**
             * Handler for the focus event of the cta input.
             */
            vm.onCtaInputFocus = function() {
                if (clearCtaInputOnFocus) {
                    vm.ctaFormInput = '';
                }
            };

            /**
             * Handler for the blur event of the cta input.
             */
            vm.onCtaInputBlur = function() {
                // If the user leaves the input and we cannot submit the form
                // but we have a target place, set that place again
                if (!vm.canSubmitCta() && angular.isObject(targetPlace)) {
                    vm.ctaFormInput = targetPlace.displayName;
                }
            };

            /**
             * Handler for submission of the cta form.
             * Will go to the selected place on the map.
             */
            vm.onCtaSubmit = function() {
                mainMapService.setTargetPlace(targetPlace);
                $location.path('map');

                angularPiwik.track('home.cta', 'home.cta.submit');
            };

            /**
             * Gets the location from the browser's geolocation API
             * and sets the target place based on that.
             */
            vm.getUserLocation = function() {
                vm.geolocating = true;
                navigator.geolocation.getCurrentPosition(function(position) {
                    $scope.$apply(function() {
                        vm.geolocating = false;

                        // Extract the lat and lng
                        var lat = position.coords.latitude;
                        var lng = position.coords.longitude;

                        // Set the display name to some value that the user recognises it worked
                        vm.ctaFormInput = $translate.instant('home.callToAction.geolocate') +
                            ': ' + lat.toFixed(3) + ', ' + lng.toFixed(3)
                        ;

                        // Set the target place
                        targetPlace = {
                            lat: lat,
                            lng: lng,
                            zoom: GEO_LOCATION_ZOOM,
                            displayName: vm.ctaFormInput
                        };

                        // When the user focuses the input field, clear it
                        clearCtaInputOnFocus = true;

                        angularPiwik.track('home.geolocation', 'home.geolocation.found');
                    });
                }, function() {
                    $scope.$apply(function() {
                        vm.geolocating = false;
                        alertService.addAlert($translate.instant('message.geolocate.error'), 'danger');

                        angularPiwik.track('home.geolocation', 'home.geolocation.error');
                    });
                }, {
                    enableHighAccuracy: true,
                    timeout: 30000,
                    maximumAge: 0
                });

                angularPiwik.track('home.geolocation', 'home.geolocation.start');
            };

            // Get the location (country) from the backend
            // TODO: only do that if not already located (local storage?)
            backendService.getGeoIP(localeService.getLocale()).then(function(res) {
                var data = res.data;
                if (_.isObject(data) && Object.keys(data) > 0) {
                    vm.ctaFormInput = data.countryName;

                    targetPlace = {
                        lat: data.lat,
                        lng: data.lng,
                        boundingBox: data.boundingBox,
                        displayName: vm.ctaFormInput
                    };
                }
                // If nothing valid found, we can't do anything
            });
        }
    ];

    // Expose as directive
    angular.module('veganaut.app.home')
        .controller('vgHomeCtrl', homeCtrl)
        .directive('vgHome', [homeDirective])
    ;
})();
<commit_msg>Typo Refs #186<commit_after>(function() {
    'use strict';

    /**
     * Component for the home page.
     * @returns {directive}
     */
    var homeDirective = function() {
        return {
            restrict: 'E',
            scope: {},
            controller: 'vgHomeCtrl',
            controllerAs: 'homeVm',
            bindToController: true,
            templateUrl: '/veganaut/home/home.tpl.html'
        };
    };

    var homeCtrl = [
        '$scope', '$location', '$translate', 'backendService', 'angularPiwik',
        'mainMapService', 'geocodeService', 'alertService', 'localeService',
        function($scope, $location, $translate, backendService, angularPiwik,
            mainMapService, geocodeService, alertService, localeService)
        {
            var vm = this;

            /**
             * Zoom on the map used when we show the place returned
             * by the browser's geo location API.
             * @type {number}
             */
            var GEO_LOCATION_ZOOM = 15;

            // Expose the global methods we still need
            // TODO: find a better way to do this
            vm.legacyGlobals = {
                goToView: $scope.$parent.goToView,
                isLoggedIn: $scope.$parent.isLoggedIn
            };

            /**
             * Cta form input model
             * @type {string}
             */
            vm.ctaFormInput = '';

            /**
             * Whether we are currently running geo locating
             * @type {boolean}
             */
            vm.geolocating = false;

            /**
             * The target place to show on the map when submitting the cta form.
             * @type {{}}
             */
            var targetPlace;

            /**
             * Whether to clear the cta input field on the next focus event
             * @type {boolean}
             */
            var clearCtaInputOnFocus = true;

            /**
             * Uses the geocodeService to search for places with the given name
             * @param {string} searchInput
             * @returns {GeocodeResult[]}
             */
            vm.getSearchResults = function(searchInput) {
                // TODO: should use piwik's search tracking
                angularPiwik.track('home.cta', 'home.cta.searchStart');

                return geocodeService.search(searchInput).then(function(response) {
                    return response;
                });
            };

            /**
             * Whether the cta form can currently be submitted
             * @returns {boolean}
             */
            vm.canSubmitCta = function() {
                // Can only submit when we have a target and it's currently shown in the input field
                return (angular.isObject(targetPlace) && targetPlace.displayName === vm.ctaFormInput);
            };

            /**
             * Handler for when the user selects a result from the auto-complete.
             * @param {GeocodeResult} selected
             */
            vm.onResultSelected = function(selected) {
                // Set the target place
                targetPlace = {
                    lat: selected.lat,
                    lng: selected.lng,
                    boundingBox: selected.bounds,
                    displayName: selected.getDisplayName()
                };

                // We no longer want to clear the input field on focus
                clearCtaInputOnFocus = false;

                angularPiwik.track('home.cta', 'home.cta.selectResult');
            };

            /**
             * Handler for the focus event of the cta input.
             */
            vm.onCtaInputFocus = function() {
                if (clearCtaInputOnFocus) {
                    vm.ctaFormInput = '';
                }
            };

            /**
             * Handler for the blur event of the cta input.
             */
            vm.onCtaInputBlur = function() {
                // If the user leaves the input and we cannot submit the form
                // but we have a target place, set that place again
                if (!vm.canSubmitCta() && angular.isObject(targetPlace)) {
                    vm.ctaFormInput = targetPlace.displayName;
                }
            };

            /**
             * Handler for submission of the cta form.
             * Will go to the selected place on the map.
             */
            vm.onCtaSubmit = function() {
                mainMapService.setTargetPlace(targetPlace);
                $location.path('map');

                angularPiwik.track('home.cta', 'home.cta.submit');
            };

            /**
             * Gets the location from the browser's geolocation API
             * and sets the target place based on that.
             */
            vm.getUserLocation = function() {
                vm.geolocating = true;
                navigator.geolocation.getCurrentPosition(function(position) {
                    $scope.$apply(function() {
                        vm.geolocating = false;

                        // Extract the lat and lng
                        var lat = position.coords.latitude;
                        var lng = position.coords.longitude;

                        // Set the display name to some value that the user recognises it worked
                        vm.ctaFormInput = $translate.instant('home.callToAction.geolocate') +
                            ': ' + lat.toFixed(3) + ', ' + lng.toFixed(3)
                        ;

                        // Set the target place
                        targetPlace = {
                            lat: lat,
                            lng: lng,
                            zoom: GEO_LOCATION_ZOOM,
                            displayName: vm.ctaFormInput
                        };

                        // When the user focuses the input field, clear it
                        clearCtaInputOnFocus = true;

                        angularPiwik.track('home.geolocation', 'home.geolocation.found');
                    });
                }, function() {
                    $scope.$apply(function() {
                        vm.geolocating = false;
                        alertService.addAlert($translate.instant('message.geolocate.error'), 'danger');

                        angularPiwik.track('home.geolocation', 'home.geolocation.error');
                    });
                }, {
                    enableHighAccuracy: true,
                    timeout: 30000,
                    maximumAge: 0
                });

                angularPiwik.track('home.geolocation', 'home.geolocation.start');
            };

            // Get the location (country) from the backend
            // TODO: only do that if not already located (local storage?)
            backendService.getGeoIP(localeService.getLocale()).then(function(res) {
                var data = res.data;
                if (_.isObject(data) && Object.keys(data).length > 0) {
                    vm.ctaFormInput = data.countryName;

                    targetPlace = {
                        lat: data.lat,
                        lng: data.lng,
                        boundingBox: data.boundingBox,
                        displayName: vm.ctaFormInput
                    };
                }
                // If nothing valid found, we can't do anything
            });
        }
    ];

    // Expose as directive
    angular.module('veganaut.app.home')
        .controller('vgHomeCtrl', homeCtrl)
        .directive('vgHome', [homeDirective])
    ;
})();
<|endoftext|>


<commit_before>'use strict';

var jsonSchemaTest = require('json-schema-test')
  , path = require('path');

var Ajv = require(typeof window == 'object' ? 'ajv' : '../lib/ajv')
  , ajv = Ajv({ beautify: true })
  , fullAjv = Ajv({ allErrors: true, verbose: true, format: 'full', beautify: true });

var remoteRefs = {
    // for JSON-Schema-Test-Suite
    'http://localhost:1234/integer.json': require('./JSON-Schema-Test-Suite/remotes/integer.json'),
    'http://localhost:1234/subSchemas.json': require('./JSON-Schema-Test-Suite/remotes/subSchemas.json'),
    'http://localhost:1234/folder/folderInteger.json': require('./JSON-Schema-Test-Suite/remotes/folder/folderInteger.json'),
    // for tests
    'http://localhost:1234/name.json': require('./remotes/name.json')
};

var remoteRefsWithIds = [ // order is important
  require('./remotes/bar.json'),
  require('./remotes/foo.json'),
  require('./remotes/buu.json'),
];

addRemoteRefs();

jsonSchemaTest([ ajv, fullAjv ], {
  suites: testSuites(),
  only: [
    // 'type', 'not', 'allOf', 'anyOf', 'oneOf', 'enum',
    // 'maximum', 'minimum', 'multipleOf', 'maxLength', 'minLength', 'pattern',
    // 'properties', 'patternProperties', 'additionalProperties',
    // 'dependencies', 'required',
    // 'maxProperties', 'minProperties', 'maxItems', 'minItems',
    // 'items', 'additionalItems', 'uniqueItems',
    // 'optional/format', 'optional/bignum',
    // 'ref', 'refRemote', 'definitions',
    // 'schemas/complex', 'schemas/basic', 'schemas/advanced',
  ],
  skip: [
    'optional/zeroTerminatedFloats'
  ],
  cwd: __dirname,
  hideFolder: 'draft4/'
});

function testSuites() {
  if (typeof window == 'object') {
    var suites = {
      'JSON-Schema tests draft4': require('./JSON-Schema-Test-Suite/tests/draft4/{**/,}*.json', {mode: 'hash'}),
      'Advanced schema tests': require('./tests/{**/,}*.json', {mode: 'hash'})
    };
    for (var suiteName in suites) {
      var suite = suites[suiteName];
      var suiteArr = [];
      for (var testSetName in suite)
        suiteArr.push({ name: testSetName, test: suite[testSetName] });
      suites[suiteName] = suiteArr;
    }
  } else {
    var suites = {
      'JSON-Schema tests draft4': './JSON-Schema-Test-Suite/tests/draft4/{**/,}*.json',
      'Advanced schema tests': './tests/{**/,}*.json'
    }
  }
  return suites;
}

function addRemoteRefs() {
  for (var id in remoteRefs) {
    ajv.addSchema(remoteRefs[id], id);
    fullAjv.addSchema(remoteRefs[id], id);
  }

  ajv.addSchema(remoteRefsWithIds);
  fullAjv.addSchema(remoteRefsWithIds);
}
<commit_msg>test: additional validator instance {verbose: true, allErrors: false}<commit_after>'use strict';

var jsonSchemaTest = require('json-schema-test')
  , path = require('path');

var Ajv = require(typeof window == 'object' ? 'ajv' : '../lib/ajv')
  , ajv = Ajv({ beautify: true })
  , verboseAjv = Ajv({ verbose: true, beautify: true })
  , fullAjv = Ajv({ allErrors: true, verbose: true, format: 'full', beautify: true });

var remoteRefs = {
    // for JSON-Schema-Test-Suite
    'http://localhost:1234/integer.json': require('./JSON-Schema-Test-Suite/remotes/integer.json'),
    'http://localhost:1234/subSchemas.json': require('./JSON-Schema-Test-Suite/remotes/subSchemas.json'),
    'http://localhost:1234/folder/folderInteger.json': require('./JSON-Schema-Test-Suite/remotes/folder/folderInteger.json'),
    // for tests
    'http://localhost:1234/name.json': require('./remotes/name.json')
};

var remoteRefsWithIds = [ // order is important
  require('./remotes/bar.json'),
  require('./remotes/foo.json'),
  require('./remotes/buu.json'),
];

var instances = [ ajv, fullAjv, verboseAjv ];

instances.forEach(addRemoteRefs);

jsonSchemaTest(instances, {
  suites: testSuites(),
  only: [
    // 'type', 'not', 'allOf', 'anyOf', 'oneOf', 'enum',
    // 'maximum', 'minimum', 'multipleOf', 'maxLength', 'minLength', 'pattern',
    // 'properties', 'patternProperties', 'additionalProperties',
    // 'dependencies', 'required',
    // 'maxProperties', 'minProperties', 'maxItems', 'minItems',
    // 'items', 'additionalItems', 'uniqueItems',
    // 'optional/format', 'optional/bignum',
    // 'ref', 'refRemote', 'definitions',
    // 'schemas/complex', 'schemas/basic', 'schemas/advanced',
  ],
  skip: [
    'optional/zeroTerminatedFloats'
  ],
  cwd: __dirname,
  hideFolder: 'draft4/'
});

function testSuites() {
  if (typeof window == 'object') {
    var suites = {
      'JSON-Schema tests draft4': require('./JSON-Schema-Test-Suite/tests/draft4/{**/,}*.json', {mode: 'hash'}),
      'Advanced schema tests': require('./tests/{**/,}*.json', {mode: 'hash'})
    };
    for (var suiteName in suites) {
      var suite = suites[suiteName];
      var suiteArr = [];
      for (var testSetName in suite)
        suiteArr.push({ name: testSetName, test: suite[testSetName] });
      suites[suiteName] = suiteArr;
    }
  } else {
    var suites = {
      'JSON-Schema tests draft4': './JSON-Schema-Test-Suite/tests/draft4/{**/,}*.json',
      'Advanced schema tests': './tests/{**/,}*.json'
    }
  }
  return suites;
}

function addRemoteRefs(ajv) {
  for (var id in remoteRefs) {
    ajv.addSchema(remoteRefs[id], id);
  }

  ajv.addSchema(remoteRefsWithIds);
}
<|endoftext|>