<commit_before>'use strict';

const ServiceWorkerBuilder = require('./lib/service-worker-builder');
const mergeTrees = require('broccoli-merge-trees');
const writeFile = require('broccoli-file-creator');
const hashForDep = require('hash-for-dep');
const addonUtils = require('./lib/addon-utils');
const IndexFile = require('./lib/index-file');

module.exports = {
  name: 'ember-service-worker',

  included(app) {
    if (this._super.included) {
      this._super.included.apply(this, arguments);
    }

    // Configures Ember CLI's build system to not add a fingerprint to sw.js
    this.app = app;
    this.app.options = this.app.options || {};
    this.app.options.fingerprint = this.app.options.fingerprint || {};
    this.app.options.fingerprint.exclude = this.app.options.fingerprint.exclude || [];
    this.app.options.fingerprint.exclude.push('sw.js');

    let options = this.app.options['ember-service-worker'] =  this.app.options['ember-service-worker'] || {}
    options.registrationStrategy = options.registrationStrategy || 'default';

    if (options.enabled === undefined) {
      options.enabled = this.app.env !== 'test';
    }

    if (process.env.SW_DISABLED) {
      options.enabled = false;
    }

    if (options.registrationStrategy === 'after-ember' && options.enabled !== false) {
      app.import('vendor/ember-service-worker/load-registration-script.js');
    }
  },

  treeForVendor() {
    return writeFile('ember-service-worker/load-registration-script.js', `
      (function() {
        if (typeof FastBoot === 'undefined') {
          var script = document.createElement('script')
          script.src = '${this._getRootURL()}sw-registration.js';
          document.body.appendChild(script);
        }
      })();
    `);
  },

  postprocessTree(type, appTree) {
    let options = this._getOptions();

    if (type !== 'all' || options.enabled === false) {
      return appTree;
    }

    let plugins = this._findPluginsFor(this.project);

    // Add the project itself as a possible plugin, this way user can add custom
    // service-worker code in their app, without needing to build a plugin.
    plugins = [this].concat(plugins, this.project);

    let serviceWorkerBuilder = new ServiceWorkerBuilder({
      app: this,
      appTree,
      minifyJS: this.app.options.minifyJS,
      plugins,
      rootURL: this._getRootURL(),
      sourcemaps: this.app.options.sourcemaps
    });

    let serviceWorkerTree = serviceWorkerBuilder.build('service-worker');
    let serviceWorkerRegistrationTree =
      serviceWorkerBuilder.build('service-worker-registration');

    return mergeTrees([
      serviceWorkerTree,
      serviceWorkerRegistrationTree,
      appTree
    ], { overwrite: true });
  },

  contentFor(type, config) {
    let options = this._getOptions();

    if (options.enabled === false) {
      return;
    }

    if (type === 'body-footer' && options.registrationStrategy === 'default') {
      return `<script src="${this._getRootURL()}sw-registration.js"></script>`;
    }

    if (type === 'head-footer' && options.registrationStrategy === 'async') {
      return `<script async src="${this._getRootURL()}sw-registration.js"></script>`;
    }
  },

  treeForServiceWorker(swTree, appTree) {
    var options = this._getOptions();
    options.projectVersion = this.project.pkg.version;
    options.projectRevision = hashForDep(this.project.root);

    var indexFile = new IndexFile([appTree], options);

    return mergeTrees([swTree, indexFile]);
  },

  _getRootURL() {
    if (this._projectRootURL) {
      return this._projectRootURL;
    }

    let options = this._getOptions();
    let config = this._getConfig();
    let rootURL = options.rootUrl || config.rootURL || config.baseURL || '/';

    return this._projectRootURL = rootURL;
  },

  _getOptions() {
    return this.app.options['ember-service-worker'];
  },

  _getConfig() {
    return this.project.config(this.app.env);
  },

  _findPluginsFor(project) {
    let addons = project.addons || [];
    return addonUtils.filterByKeyword(addons, 'ember-service-worker-plugin');
  }
};
<commit_msg>Graceful handle failing hashfordep<commit_after>'use strict';

const ServiceWorkerBuilder = require('./lib/service-worker-builder');
const mergeTrees = require('broccoli-merge-trees');
const writeFile = require('broccoli-file-creator');
const hashForDep = require('hash-for-dep');
const addonUtils = require('./lib/addon-utils');
const IndexFile = require('./lib/index-file');

module.exports = {
  name: 'ember-service-worker',

  included(app) {
    if (this._super.included) {
      this._super.included.apply(this, arguments);
    }

    // Configures Ember CLI's build system to not add a fingerprint to sw.js
    this.app = app;
    this.app.options = this.app.options || {};
    this.app.options.fingerprint = this.app.options.fingerprint || {};
    this.app.options.fingerprint.exclude = this.app.options.fingerprint.exclude || [];
    this.app.options.fingerprint.exclude.push('sw.js');

    let options = this.app.options['ember-service-worker'] =  this.app.options['ember-service-worker'] || {}
    options.registrationStrategy = options.registrationStrategy || 'default';

    if (options.enabled === undefined) {
      options.enabled = this.app.env !== 'test';
    }

    if (process.env.SW_DISABLED) {
      options.enabled = false;
    }

    if (options.registrationStrategy === 'after-ember' && options.enabled !== false) {
      app.import('vendor/ember-service-worker/load-registration-script.js');
    }
  },

  treeForVendor() {
    return writeFile('ember-service-worker/load-registration-script.js', `
      (function() {
        if (typeof FastBoot === 'undefined') {
          var script = document.createElement('script')
          script.src = '${this._getRootURL()}sw-registration.js';
          document.body.appendChild(script);
        }
      })();
    `);
  },

  postprocessTree(type, appTree) {
    let options = this._getOptions();

    if (type !== 'all' || options.enabled === false) {
      return appTree;
    }

    let plugins = this._findPluginsFor(this.project);

    // Add the project itself as a possible plugin, this way user can add custom
    // service-worker code in their app, without needing to build a plugin.
    plugins = [this].concat(plugins, this.project);

    let serviceWorkerBuilder = new ServiceWorkerBuilder({
      app: this,
      appTree,
      minifyJS: this.app.options.minifyJS,
      plugins,
      rootURL: this._getRootURL(),
      sourcemaps: this.app.options.sourcemaps
    });

    let serviceWorkerTree = serviceWorkerBuilder.build('service-worker');
    let serviceWorkerRegistrationTree =
      serviceWorkerBuilder.build('service-worker-registration');

    return mergeTrees([
      serviceWorkerTree,
      serviceWorkerRegistrationTree,
      appTree
    ], { overwrite: true });
  },

  contentFor(type, config) {
    let options = this._getOptions();

    if (options.enabled === false) {
      return;
    }

    if (type === 'body-footer' && options.registrationStrategy === 'default') {
      return `<script src="${this._getRootURL()}sw-registration.js"></script>`;
    }

    if (type === 'head-footer' && options.registrationStrategy === 'async') {
      return `<script async src="${this._getRootURL()}sw-registration.js"></script>`;
    }
  },

  treeForServiceWorker(swTree, appTree) {
    var options = this._getOptions();
    options.projectVersion = this.project.pkg.version;

    try {
      options.projectRevision = hashForDep(this.project.root);
    } catch (e) {
      options.projectRevision = '0';
    }

    var indexFile = new IndexFile([appTree], options);

    return mergeTrees([swTree, indexFile]);
  },

  _getRootURL() {
    if (this._projectRootURL) {
      return this._projectRootURL;
    }

    let options = this._getOptions();
    let config = this._getConfig();
    let rootURL = options.rootUrl || config.rootURL || config.baseURL || '/';

    return this._projectRootURL = rootURL;
  },

  _getOptions() {
    return this.app.options['ember-service-worker'];
  },

  _getConfig() {
    return this.project.config(this.app.env);
  },

  _findPluginsFor(project) {
    let addons = project.addons || [];
    return addonUtils.filterByKeyword(addons, 'ember-service-worker-plugin');
  }
};
<|endoftext|>


<commit_before>var request = require('request')
var util = require('util')
var Queue = require('queue3');
var argv = require('minimist')(process.argv.slice(2));
var q
var lineReader

var cspScan = {

	total : 0,
	csp : 0,
	cspX : 0,
	webkit : 0,
	xss : 0,
	xssDisable : 0,
	xssInvalid : 0,
	error : 0,
	noHead : 0,
	verbose: false,

	requestOptions : {
		timeout: 5000,
		maxRedirects: 5,
		headers: {
			'User-Agent': 'cspScan'
		}
	},

	queueOptions : {
		concurrency: 20,
		timeout: 5000
	},

	HEADER_CSP: 'content-security-policy',
	HEADER_X_CSP: 'x-content-security-policy',
	HEADER_WEBKIT_CSP : 'x-webkit-csp',
	HEADER_XSS: 'x-xss-protection',

	scan : function() {

		lineReader.on('line', function (line) {

			if (cspScan.validLine(line)) {
			  q.push(function(fn){

					cspScan.total++

					var uri = cspScan.prefixHost(line)
					request.head(uri, cspScan.requestOptions, function(error, response, body) {

						if (!error && response.statusCode == 200) {
							cspScan.checkHeaders(uri, response)
						} else if (error != undefined) {
							cspScan.error++
							if (cspScan.verbose) console.log(uri,": error during scanning: ",error.message )
						} else if (response.statusCode != 200){
							if(response.statusCode == 405) {
								cspScan.noHead++
							}
							if (cspScan.verbose) console.log(uri,": error during scanning: Status Code ",response.statusCode )
						}
					})
				})
			}
		});

		console.log("all URIs scheduled, waiting for results...")

		process.on('beforeExit', function(code) {
			cspScan.printResult();
		});

	},

	checkHeaders : function(uri, response) {
		if (response.headers[cspScan.HEADER_CSP] != undefined) {
			cspScan.csp++
			if (cspScan.verbose) console.log(uri,": Content-Security Header found")
		}

		if (response.headers[cspScan.HEADER_X_CSP] != undefined) {
			cspScan.cspX++
			if (cspScan.verbose) console.log(uri, ": X-Content-Security Header found")
		}

		if (response.headers[cspScan.HEADER_WEBKIT_CSP] != undefined) {
			cspScan.webkit++
			if (cspScan.verbose) console.log(uri, ": X-Webkit-CSP Header found")
		}

		var xssProtection = response.headers[cspScan.HEADER_XSS]
		if (xssProtection != undefined) {
			if (cspScan.verbose) console.log(uri,": X-XSS-Protection found with value (truncated):",xssProtection.substring(0,1))
			if(xssProtection.startsWith("0")) {
				cspScan.xssDisable++
			} else if (xssProtection.startsWith("1")) {
				cspScan.xss++
			} else {
				cspScan.xssInvalid++
				console.log(uri, ": X-XSS-Protection Header Value not Valid:",xssProtection)
			}
		}
	},

	printResult : function() {
		console.log("-----")
		console.log("Tried to scan",cspScan.total,"URIs")
		console.log("Got status!= 200 or error for",cspScan.error,"URIs")
		console.log("HTTP HEAD Requests not supported: ",cspScan.noHead+"/"+cspScan.error,"URIs")
		console.log("Results for",cspScan.total-cspScan.error,"scanned URIs")
		console.log("Content-Security-Policy Headers:", cspScan.csp)
		console.log("Deprecated X-Content-Security-Policy Headers:", cspScan.cspX)
		console.log("Depricated Webkit Content-Security-Policy Headers:", cspScan.webkit)
		console.log("X-XSS-Protection Headers:", cspScan.xss)
		console.log("Disable X-XSS-Protection Headers:", cspScan.xssDisable)
		console.log("Invalid X-XSS-Protection Headers:", cspScan.xssInvalid)
		console.log("-----")
	},

	prefixHost : function(host) {
		if(host.startsWith("http")) {
			return host
		} else {
			return "http://" + host
		}
	},

	validLine : function(line) {
		if(	line.startsWith("#") ||
				line.startsWith("//")) {
					return false
		}

		return true
	},

	printUsage : function() {
		console.log("usage: index.js [params] uri-file")
		console.log("you shouldn't need to set any params, only -v if you are interessted in the progress")
		console.log("params:")
		console.log(" --help\t show this and exit")
		console.log(" -v\t print detailed scanning results during scan")
		console.log(" -t\t timeout for http requests in ms. default: 5000")
		console.log(" -m\t max number of redirects to follow. default: 5")
		console.log(" -c\t concurrency for queueing. default: 20")
		console.log(" -q\t timeout for queued uris in ms. default: 5000")
		console.log(" -a\t override user-agent header. default: cspScan")
	},

	parseValidArgs : function(args) {

		if (args['v']) cspScan.verbose = true
		if (args['t']) cspScan.requestOptions.timeout = args['t']
		if (args['m']) cspScan.requestOptions.maxRedirects = args['m']
		if (args['a']) cspScan.requestOptions.headers['User-Agent'] = args['a']
		if (args['c']) cspScan.queueOptions.concurrency = args['c']
		if (args['q']) cspScan.queueOptions.timeout = args['q']

		cspScan.init(args['_'][0])
	},

	init : function(filepath) {
		q = new Queue(cspScan.queueOptions);
		lineReader = require('readline').createInterface({
			  input: require('fs').createReadStream(filepath)
		});
	}
}

if(argv['help'] != undefined || argv['_'] == undefined || argv['_'].length != 1) {
	cspScan.printUsage()
} else {
	cspScan.parseValidArgs(argv)
	cspScan.scan();
}
<commit_msg>Use Typesafe Equality<commit_after>var request = require('request')
var util = require('util')
var Queue = require('queue3');
var argv = require('minimist')(process.argv.slice(2));
var q
var lineReader

var cspScan = {

	total : 0,
	csp : 0,
	cspX : 0,
	webkit : 0,
	xss : 0,
	xssDisable : 0,
	xssInvalid : 0,
	error : 0,
	noHead : 0,
	verbose: false,

	requestOptions : {
		timeout: 5000,
		maxRedirects: 5,
		headers: {
			'User-Agent': 'cspScan'
		}
	},

	queueOptions : {
		concurrency: 20,
		timeout: 5000
	},

	HEADER_CSP: 'content-security-policy',
	HEADER_X_CSP: 'x-content-security-policy',
	HEADER_WEBKIT_CSP : 'x-webkit-csp',
	HEADER_XSS: 'x-xss-protection',

	scan : function() {

		lineReader.on('line', function (line) {

			if (cspScan.validLine(line)) {
			  q.push(function(fn){

					cspScan.total++

					var uri = cspScan.prefixHost(line)
					request.head(uri, cspScan.requestOptions, function(error, response, body) {

						if (!error && response.statusCode === 200) {
							cspScan.checkHeaders(uri, response)
						} else if (error !== undefined) {
							cspScan.error++
							if (cspScan.verbose) console.log(uri,": error during scanning: ",error.message )
						} else if (response.statusCode !== 200){
							if(response.statusCode === 405) {
								cspScan.noHead++
							}
							if (cspScan.verbose) console.log(uri,": error during scanning: Status Code ",response.statusCode )
						}
					})
				})
			}
		});

		console.log("all URIs scheduled, waiting for results...")

		process.on('beforeExit', function(code) {
			cspScan.printResult();
		});

	},

	checkHeaders : function(uri, response) {
		if (response.headers[cspScan.HEADER_CSP] !== undefined) {
			cspScan.csp++
			if (cspScan.verbose) console.log(uri,": Content-Security Header found")
		}

		if (response.headers[cspScan.HEADER_X_CSP] !== undefined) {
			cspScan.cspX++
			if (cspScan.verbose) console.log(uri, ": X-Content-Security Header found")
		}

		if (response.headers[cspScan.HEADER_WEBKIT_CSP] !== undefined) {
			cspScan.webkit++
			if (cspScan.verbose) console.log(uri, ": X-Webkit-CSP Header found")
		}

		var xssProtection = response.headers[cspScan.HEADER_XSS]
		if (xssProtection !== undefined) {
			if (cspScan.verbose) console.log(uri,": X-XSS-Protection found with value (truncated):",xssProtection.substring(0,1))
			if(xssProtection.startsWith("0")) {
				cspScan.xssDisable++
			} else if (xssProtection.startsWith("1")) {
				cspScan.xss++
			} else {
				cspScan.xssInvalid++
				console.log(uri, ": X-XSS-Protection Header Value not Valid:",xssProtection)
			}
		}
	},

	printResult : function() {
		console.log("-----")
		console.log("Tried to scan",cspScan.total,"URIs")
		console.log("Got status!= 200 or error for",cspScan.error,"URIs")
		console.log("HTTP HEAD Requests not supported: ",cspScan.noHead+"/"+cspScan.error,"URIs")
		console.log("Results for",cspScan.total-cspScan.error,"scanned URIs")
		console.log("Content-Security-Policy Headers:", cspScan.csp)
		console.log("Deprecated X-Content-Security-Policy Headers:", cspScan.cspX)
		console.log("Depricated Webkit Content-Security-Policy Headers:", cspScan.webkit)
		console.log("X-XSS-Protection Headers:", cspScan.xss)
		console.log("Disable X-XSS-Protection Headers:", cspScan.xssDisable)
		console.log("Invalid X-XSS-Protection Headers:", cspScan.xssInvalid)
		console.log("-----")
	},

	prefixHost : function(host) {
		if(host.startsWith("http")) {
			return host
		} else {
			return "http://" + host
		}
	},

	validLine : function(line) {
		if(	line.startsWith("#") ||
				line.startsWith("//")) {
					return false
		}

		return true
	},

	printUsage : function() {
		console.log("usage: index.js [params] uri-file")
		console.log("you shouldn't need to set any params, only -v if you are interessted in the progress")
		console.log("params:")
		console.log(" --help\t show this and exit")
		console.log(" -v\t print detailed scanning results during scan")
		console.log(" -t\t timeout for http requests in ms. default: 5000")
		console.log(" -m\t max number of redirects to follow. default: 5")
		console.log(" -c\t concurrency for queueing. default: 20")
		console.log(" -q\t timeout for queued uris in ms. default: 5000")
		console.log(" -a\t override user-agent header. default: cspScan")
	},

	parseValidArgs : function(args) {

		if (args['v']) cspScan.verbose = true
		if (args['t']) cspScan.requestOptions.timeout = args['t']
		if (args['m']) cspScan.requestOptions.maxRedirects = args['m']
		if (args['a']) cspScan.requestOptions.headers['User-Agent'] = args['a']
		if (args['c']) cspScan.queueOptions.concurrency = args['c']
		if (args['q']) cspScan.queueOptions.timeout = args['q']

		cspScan.init(args['_'][0])
	},

	init : function(filepath) {
		q = new Queue(cspScan.queueOptions);
		lineReader = require('readline').createInterface({
			  input: require('fs').createReadStream(filepath)
		});
	}
}

if(argv['help'] !== undefined || argv['_'] === undefined || argv['_'].length !== 1) {
	cspScan.printUsage()
} else {
	cspScan.parseValidArgs(argv)
	cspScan.scan();
}
<|endoftext|>


<commit_before>// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
const data = require('./package.json');
const Build = require('@jupyterlab/builder').Build;
const webpack = require('webpack');
const merge = require('webpack-merge').default;
const baseConfig = require('@jupyterlab/builder/lib/webpack.config.base');
const { ModuleFederationPlugin } = webpack.container;
const fs = require('fs-extra');
const path = require('path');
const Handlebars = require('handlebars');

// Ensure a clear build directory.
const buildDir = path.resolve(__dirname, 'build');
if (fs.existsSync(buildDir)) {
  fs.removeSync(buildDir);
}
fs.ensureDirSync(buildDir);

// Configuration to handle extension assets
const extensionAssetConfig = Build.ensureAssets({
  packageNames: jlab.extensions,
  output: buildDir
});

const singletons = {};

jlab.singletonPackages.forEach(element => {
  singletons[element] = { singleton: true };
});

// Create a list of application extensions and mime extensions from
// jlab.extensions
const extensions = {};
const mimeExtensions = {};

for (const key of jlab.extensions) {
  const {
    jupyterlab: { extension, mimeExtension }
  } = require(`${key}/package.json`);
  if (extension !== undefined) {
    extensions[key] = extension === true ? '' : extension;
  }
  if (mimeExtension !== undefined) {
    mimeExtensions[key] = mimeExtension === true ? '' : mimeExtension;
  }
}

// Create the entry point file.
const source = fs.readFileSync('index.template.js').toString();
const template = Handlebars.compile(source);
const extData = {
  jupyterlab_extensions: extensions,
  jupyterlab_mime_extensions: mimeExtensions
};
const result = template(extData);

fs.writeFileSync(path.join(buildDir, 'index.js'), result);

// Make a bootstrap entrypoint
const entryPoint = path.join(buildDir, 'bootstrap.js');
fs.copySync('./bootstrap.js', entryPoint);

if (process.env.NODE_ENV === 'production') {
  baseConfig.mode = 'production';
}

module.exports = [
  merge(baseConfig, {
    mode: 'development',
    entry: ['./publicpath.js', './' + path.relative(__dirname, entryPoint)],
    output: {
      path: buildDir,
      library: {
        type: 'var',
        name: ['_JUPYTERLAB', 'CORE_OUTPUT']
      },
      filename: 'bundle.js'
    },
    plugins: [
      new ModuleFederationPlugin({
        library: {
          type: 'var',
          name: ['_JUPYTERLAB', 'CORE_LIBRARY_FEDERATION']
        },
        name: 'CORE_FEDERATION',
        shared: {
          ...data.resolutions,
          ...singletons
        }
      })
    ]
  })
].concat(extensionAssetConfig);
<commit_msg>Add TODO note about what to do next - check the federated examples webpack config.<commit_after>// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
const data = require('./package.json');
const Build = require('@jupyterlab/builder').Build;
const webpack = require('webpack');
const merge = require('webpack-merge').default;
const baseConfig = require('@jupyterlab/builder/lib/webpack.config.base');
const { ModuleFederationPlugin } = webpack.container;
const fs = require('fs-extra');
const path = require('path');
const Handlebars = require('handlebars');

// TODO: Check this webpack config against the dev_mode webpack config and make sure all relevant changes are copied back.

// Ensure a clear build directory.
const buildDir = path.resolve(__dirname, 'build');
if (fs.existsSync(buildDir)) {
  fs.removeSync(buildDir);
}
fs.ensureDirSync(buildDir);

// Configuration to handle extension assets
const extensionAssetConfig = Build.ensureAssets({
  packageNames: jlab.extensions,
  output: buildDir
});

const singletons = {};

jlab.singletonPackages.forEach(element => {
  singletons[element] = { singleton: true };
});

// Create a list of application extensions and mime extensions from
// jlab.extensions
const extensions = {};
const mimeExtensions = {};

for (const key of jlab.extensions) {
  const {
    jupyterlab: { extension, mimeExtension }
  } = require(`${key}/package.json`);
  if (extension !== undefined) {
    extensions[key] = extension === true ? '' : extension;
  }
  if (mimeExtension !== undefined) {
    mimeExtensions[key] = mimeExtension === true ? '' : mimeExtension;
  }
}

// Create the entry point file.
const source = fs.readFileSync('index.template.js').toString();
const template = Handlebars.compile(source);
const extData = {
  jupyterlab_extensions: extensions,
  jupyterlab_mime_extensions: mimeExtensions
};
const result = template(extData);

fs.writeFileSync(path.join(buildDir, 'index.js'), result);

// Make a bootstrap entrypoint
const entryPoint = path.join(buildDir, 'bootstrap.js');
fs.copySync('./bootstrap.js', entryPoint);

if (process.env.NODE_ENV === 'production') {
  baseConfig.mode = 'production';
}

module.exports = [
  merge(baseConfig, {
    mode: 'development',
    entry: ['./publicpath.js', './' + path.relative(__dirname, entryPoint)],
    output: {
      path: buildDir,
      library: {
        type: 'var',
        name: ['_JUPYTERLAB', 'CORE_OUTPUT']
      },
      filename: 'bundle.js'
    },
    plugins: [
      new ModuleFederationPlugin({
        library: {
          type: 'var',
          name: ['_JUPYTERLAB', 'CORE_LIBRARY_FEDERATION']
        },
        name: 'CORE_FEDERATION',
        shared: {
          ...data.resolutions,
          ...singletons
        }
      })
    ]
  })
].concat(extensionAssetConfig);
<|endoftext|>


<commit_before>(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(factory);
    } else if (typeof exports === 'object') {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like enviroments that support module.exports,
        // like Node.
        module.exports = factory();
    } else {
        // Browser globals (root is window).
        root.mathopt = factory();
  }
}(this, function () {
    var euclideanLength = function(x) {
        var v = 0;
        for(var i = x.length; i--;) {
            v += x[i] * x[i];
        }
        return Math.sqrt(v);
    };
    var copy = function(from, to, n) {
        while(n--){
            to[n] = from[n];
        }
    };
    var vectorize = function(f) {
        return function(x) {
            return f.apply(null, x);
        };
    };
    return {
        basicPSO: function(f, options) {
            var iteration, iterationLoop, result, allIdle, i, j, best, v, p, pbest, c, cbest;

            // Normalize arguments.
            options = options || {};
            options.oniteration = options.oniteration || function(cb) {
                setTimeout(cb, 0);
            };
            options.onstop = options.onstop || null;
            options.inertia = options.inertia || 0.7298;
            options.localAcceleration = options.localAcceleration || 2.9922/2;
            options.globalAcceleration = options.globalAcceleration || 2.9922/2;
            options.particles = options.particles || 20;
            options.idleSpeed = options.idleSpeed || 0.01;
            if(!options.dimensions) {
                options.dimensions = f.length;
                f = vectorize(f);
            }
            if(!options.initialPosition) {
                options.initialPosition = [];
                for(i = options.dimensions; i--;) {
                    options.initialPosition.push(0);
                }
            }

            // Initialize state.
            p = new Array(options.particles);
            pbest = p.slice(0);
            v = p.slice(0);
            cbest = p.slice(0);
            best = 0;
            for(i = p.length; i--;) {
                p[i] = options.initialPosition.slice(0);
                v[i] = [];
                for(j = options.dimensions; j--;) {
                    v[i].push(2 * Math.random());
                }
                pbest[i] = p[i].slice(0);
                cbest[i] = f(p[i]);
                if(cbest[i] < cbest[best]) {
                    best = i;
                }
            }

            // Find result.
            result = pbest[best].slice(0);
            result.iterations = 0;
            iteration = function() {
                result.iterations++;
                allIdle = true;
                for(i = options.particles; i--;) {
                    for(j = options.dimensions; j--;) {
                        v[i][j] = options.inertia * v[i][j] +
                            options.localAcceleration * Math.random() * (pbest[i][j] - p[i][j]) +
                            options.globalAcceleration * Math.random() * (pbest[best][j] - p[i][j]);
                        p[i][j] += v[i][j];
                    }

                    if(euclideanLength(v[i]) > options.idleSpeed) {
                        allIdle = false;
                    }

                    c = f(p[i]);
                    if(c < cbest[i]) {
                        cbest[i] = c;
                        copy(p[i], pbest[i], options.dimensions);
                        if(c < cbest[best]) {
                            best = i;
                        }
                    }
                }
            };
            allIdle = false;
            if(options.onstop) {
                iterationLoop = function() {
                    if(allIdle) {
                        copy(pbest[best], result, options.dimensions);
                        result.value = cbest[best];
                        options.onstop(result);
                    } else {
                        options.oniteration(p, v, pbest, best, function() {
                            iteration();
                            iterationLoop();
                        });
                    }
                };
                iterationLoop();
            } else {
                while(!allIdle) {
                    options.oniteration(p, v, pbest, best);
                    iteration();
                }
                copy(pbest[best], result, options.dimensions);
                result.value = cbest[best];
                return result;
            }
        }
    };
}));
<commit_msg>.basicPSO: .oniteration: add argument "iterations"<commit_after>(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(factory);
    } else if (typeof exports === 'object') {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like enviroments that support module.exports,
        // like Node.
        module.exports = factory();
    } else {
        // Browser globals (root is window).
        root.mathopt = factory();
  }
}(this, function () {
    var euclideanLength = function(x) {
        var v = 0;
        for(var i = x.length; i--;) {
            v += x[i] * x[i];
        }
        return Math.sqrt(v);
    };
    var copy = function(from, to, n) {
        while(n--){
            to[n] = from[n];
        }
    };
    var vectorize = function(f) {
        return function(x) {
            return f.apply(null, x);
        };
    };
    return {
        basicPSO: function(f, options) {
            var iteration, iterationLoop, result, allIdle, i, j, best, v, p, pbest, c, cbest;

            // Normalize arguments.
            options = options || {};
            options.oniteration = options.oniteration || function(i, p, v, pbest, best, cb) {
                cb && setTimeout(cb, 0);
            };
            options.onstop = options.onstop || null;
            options.inertia = options.inertia || 0.7298;
            options.localAcceleration = options.localAcceleration || 2.9922/2;
            options.globalAcceleration = options.globalAcceleration || 2.9922/2;
            options.particles = options.particles || 20;
            options.idleSpeed = options.idleSpeed || 0.01;
            if(!options.dimensions) {
                options.dimensions = f.length;
                f = vectorize(f);
            }
            if(!options.initialPosition) {
                options.initialPosition = [];
                for(i = options.dimensions; i--;) {
                    options.initialPosition.push(0);
                }
            }

            // Initialize state.
            p = new Array(options.particles);
            pbest = p.slice(0);
            v = p.slice(0);
            cbest = p.slice(0);
            best = 0;
            for(i = p.length; i--;) {
                p[i] = options.initialPosition.slice(0);
                v[i] = [];
                for(j = options.dimensions; j--;) {
                    v[i].push(2 * Math.random());
                }
                pbest[i] = p[i].slice(0);
                cbest[i] = f(p[i]);
                if(cbest[i] < cbest[best]) {
                    best = i;
                }
            }

            // Find result.
            result = pbest[best].slice(0);
            result.iterations = 0;
            iteration = function() {
                result.iterations++;
                allIdle = true;
                for(i = options.particles; i--;) {
                    for(j = options.dimensions; j--;) {
                        v[i][j] = options.inertia * v[i][j] +
                            options.localAcceleration * Math.random() * (pbest[i][j] - p[i][j]) +
                            options.globalAcceleration * Math.random() * (pbest[best][j] - p[i][j]);
                        p[i][j] += v[i][j];
                    }

                    if(euclideanLength(v[i]) > options.idleSpeed) {
                        allIdle = false;
                    }

                    c = f(p[i]);
                    if(c < cbest[i]) {
                        cbest[i] = c;
                        copy(p[i], pbest[i], options.dimensions);
                        if(c < cbest[best]) {
                            best = i;
                        }
                    }
                }
            };
            allIdle = false;
            if(options.onstop) {
                iterationLoop = function() {
                    if(allIdle) {
                        copy(pbest[best], result, options.dimensions);
                        result.value = cbest[best];
                        options.onstop(result);
                    } else {
                        options.oniteration(result.iterations, p, v, pbest, best, function() {
                            iteration();
                            iterationLoop();
                        });
                    }
                };
                iterationLoop();
            } else {
                while(!allIdle) {
                    options.oniteration(result.iterations, p, v, pbest, best);
                    iteration();
                }
                copy(pbest[best], result, options.dimensions);
                result.value = cbest[best];
                return result;
            }
        }
    };
}));
<|endoftext|>


<commit_before>import fullNameUI from 'platform/forms-system/src/js/definitions/fullName';
import { VA_FORM_IDS } from 'platform/forms/constants';
import React from 'react';
import FooterInfo from '../components/FooterInfo';
import IntroductionPage from '../components/IntroductionPage';
import PersonalInfoBox from '../components/PersonalInfoBox';
import { schemaFields } from '../constants';
import ConfirmationPage from '../containers/ConfirmationPage';
import fullSchemaMDOT from '../schemas/2346-schema.json';
import { buildAddressSchema } from '../schemas/address-schema';
import UIDefinitions from '../schemas/definitions/2346UI';

const { email, supplies, currentAddress } = fullSchemaMDOT.definitions;

const {
  emailField,
  confirmationEmailField,
  suppliesField,
  permAddressField,
  tempAddressField,
  currentAddressField,
} = schemaFields;

const {
  emailUI,
  confirmationEmailUI,
  batteriesUI,
  accessoriesUI,
  permanentAddressUI,
  temporaryAddressUI,
  currentAddressUI,
} = UIDefinitions.sharedUISchemas;

const formChapterTitles = {
  veteranInformation: 'Veteran Information',
  orderSupplies: 'Order your supplies',
};

const formPageTitlesLookup = {
  personalDetails: 'Personal Details',
  address: 'Shipping address',
  addAccessoriesPage: 'Add accessories to your order',
  addBatteriesPage: 'Add batteries to your order',
};

const addressSchema = buildAddressSchema(true);

const formConfig = {
  urlPrefix: '/',
  submitUrl: '/posts',
  submit: () =>
    Promise.resolve({ attributes: { confirmationNumber: '123123123' } }),
  trackingPrefix: 'va-2346a-',
  verifyRequiredPrefill: true,
  introduction: IntroductionPage,
  confirmation: ConfirmationPage,
  footerContent: FooterInfo,
  formId: VA_FORM_IDS.FORM_VA_2346A,
  version: 0,
  prefillEnabled: true,
  title: 'Order hearing aid batteries and accessories',
  subTitle: 'VA Form 2346A',
  savedFormMessages: {
    notFound: 'Please start over to apply for benefits.',
    noAuth: 'Please sign in again to continue your application for benefits.',
  },
  defaultDefinitions: {
    email,
    supplies,
    addressSchema,
    currentAddress,
  },
  chapters: {
    veteranInformationChapter: {
      title: formChapterTitles.veteranInformation,
      pages: {
        [formPageTitlesLookup.personalDetails]: {
          path: 'veteran-information',
          title: formPageTitlesLookup.personalDetails,
          uiSchema: {
            'ui:description': ({ formData }) => (
              <PersonalInfoBox formData={formData} />
            ),
            [schemaFields.fullName]: fullNameUI,
          },
          schema: {
            required: [],
            type: 'object',
            properties: {},
          },
        },
        [formPageTitlesLookup.address]: {
          path: 'veteran-information/addresses',
          title: formPageTitlesLookup.address,
          uiSchema: {
            [permAddressField]: permanentAddressUI,
            [tempAddressField]: temporaryAddressUI,
            [emailField]: emailUI,
            [confirmationEmailField]: confirmationEmailUI,
            [currentAddressField]: currentAddressUI,
          },
          schema: {
            type: 'object',
            properties: {
              [permAddressField]: addressSchema,
              [tempAddressField]: addressSchema,
              [emailField]: email,
              [confirmationEmailField]: email,
              [currentAddressField]: currentAddress,
            },
          },
        },
      },
    },
    orderSuppliesChapter: {
      title: formChapterTitles.orderSupplies,
      pages: {
        [formPageTitlesLookup.addBatteriesPage]: {
          path: 'batteries',
          title: formPageTitlesLookup.addBatteriesPage,
          schema: {
            type: 'object',
            properties: {
              [suppliesField]: supplies,
            },
          },
          uiSchema: {
            [suppliesField]: batteriesUI,
          },
        },
        [formPageTitlesLookup.addAccessoriesPage]: {
          path: 'accessories',
          title: formPageTitlesLookup.addAccessoriesPage,
          schema: {
            type: 'object',
            properties: {
              [suppliesField]: supplies,
            },
          },
          uiSchema: {
            [suppliesField]: accessoriesUI,
          },
        },
      },
    },
  },
};
export default formConfig;
<commit_msg>MDOT- 403 Veteran Deceased Error Message (#12729)<commit_after>import fullNameUI from 'platform/forms-system/src/js/definitions/fullName';
import { VA_FORM_IDS } from 'platform/forms/constants';
import React from 'react';
import FooterInfo from '../components/FooterInfo';
import IntroductionPage from '../components/IntroductionPage';
import PersonalInfoBox from '../components/PersonalInfoBox';
import { schemaFields } from '../constants';
import ConfirmationPage from '../containers/ConfirmationPage';
import fullSchemaMDOT from '../schemas/2346-schema.json';
import { buildAddressSchema } from '../schemas/address-schema';
import UIDefinitions from '../schemas/definitions/2346UI';

const { email, supplies, currentAddress } = fullSchemaMDOT.definitions;

const {
  emailField,
  confirmationEmailField,
  suppliesField,
  permAddressField,
  tempAddressField,
  currentAddressField,
} = schemaFields;

const {
  emailUI,
  confirmationEmailUI,
  batteriesUI,
  accessoriesUI,
  permanentAddressUI,
  temporaryAddressUI,
  currentAddressUI,
} = UIDefinitions.sharedUISchemas;

const formChapterTitles = {
  veteranInformation: 'Veteran Information',
  orderSupplies: 'Order your supplies',
};

const formPageTitlesLookup = {
  personalDetails: 'Personal Details',
  address: 'Shipping address',
  addAccessoriesPage: 'Add accessories to your order',
  addBatteriesPage: 'Add batteries to your order',
};

const addressSchema = buildAddressSchema(true);

const formConfig = {
  urlPrefix: '/',
  submitUrl: '/posts',
  submit: () =>
    Promise.resolve({ attributes: { confirmationNumber: '123123123' } }),
  trackingPrefix: 'va-2346a-',
  verifyRequiredPrefill: true,
  introduction: IntroductionPage,
  confirmation: ConfirmationPage,
  footerContent: FooterInfo,
  formId: VA_FORM_IDS.FORM_VA_2346A,
  version: 0,
  prefillEnabled: true,
  title: 'Order hearing aid batteries and accessories',
  subTitle: 'VA Form 2346A',
  savedFormMessages: {
    notFound: 'Please start over to apply for benefits.',
    noAuth: 'Please sign in again to continue your application for benefits.',
    forbidden:
      'We can’t fulfill an order for this Veteran because they are deceased in our records. If this information is incorrect, please call Veterans Benefits Assistance at 800-827-1000, Monday through Friday, 8:00 a.m. to 9:00 p.m. ET.',
  },
  defaultDefinitions: {
    email,
    supplies,
    addressSchema,
    currentAddress,
  },
  chapters: {
    veteranInformationChapter: {
      title: formChapterTitles.veteranInformation,
      pages: {
        [formPageTitlesLookup.personalDetails]: {
          path: 'veteran-information',
          title: formPageTitlesLookup.personalDetails,
          uiSchema: {
            'ui:description': ({ formData }) => (
              <PersonalInfoBox formData={formData} />
            ),
            [schemaFields.fullName]: fullNameUI,
          },
          schema: {
            required: [],
            type: 'object',
            properties: {},
          },
        },
        [formPageTitlesLookup.address]: {
          path: 'veteran-information/addresses',
          title: formPageTitlesLookup.address,
          uiSchema: {
            [permAddressField]: permanentAddressUI,
            [tempAddressField]: temporaryAddressUI,
            [emailField]: emailUI,
            [confirmationEmailField]: confirmationEmailUI,
            [currentAddressField]: currentAddressUI,
          },
          schema: {
            type: 'object',
            properties: {
              [permAddressField]: addressSchema,
              [tempAddressField]: addressSchema,
              [emailField]: email,
              [confirmationEmailField]: email,
              [currentAddressField]: currentAddress,
            },
          },
        },
      },
    },
    orderSuppliesChapter: {
      title: formChapterTitles.orderSupplies,
      pages: {
        [formPageTitlesLookup.addBatteriesPage]: {
          path: 'batteries',
          title: formPageTitlesLookup.addBatteriesPage,
          schema: {
            type: 'object',
            properties: {
              [suppliesField]: supplies,
            },
          },
          uiSchema: {
            [suppliesField]: batteriesUI,
          },
        },
        [formPageTitlesLookup.addAccessoriesPage]: {
          path: 'accessories',
          title: formPageTitlesLookup.addAccessoriesPage,
          schema: {
            type: 'object',
            properties: {
              [suppliesField]: supplies,
            },
          },
          uiSchema: {
            [suppliesField]: accessoriesUI,
          },
        },
      },
    },
  },
};
export default formConfig;
<|endoftext|>


<commit_before>const fetch = require('isomorphic-fetch');

const USER_ID = process.env.IDT_USER_ID;
const API_KEY = process.env.IDT_API_KEY;
const SLACK_HOOK = process.env.IDT_SLACK_HOOK;

if (!USER_ID) throw new Error('Must define `IDT_USER_ID` in environment.');
if (!API_KEY) throw new Error('Must define `IDT_API_KEY` in environment.');
if (!SLACK_HOOK) throw new Error('Must define `IDT_SLACK_HOOK` in environment.');

process.on('unhandledRejection', err => { throw err; });

const now = new Date();
const today = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;

function pad(n) { return n < 10 ? '0' + n : n; }

fetch(
  'https://beta.idonethis.com/api/v2/entries',
  {
    headers: {
      Authorization: `Token ${API_KEY}`
    }
  }
)
  .then(response => response.json())
  .then(entries => {
    if (entries.error) throw new Error(entries.error);

    const list = entries
      .filter(entry => entry.user.hash_id === USER_ID && entry.occurred_on === today && entry.status === 'goal')
      .map(entry => `* ${entry.body}`)
      .join('\n');

    if (!list) throw new Error('No goals in IDT today.');

    const message = `My list of goals in I Done This for today:\n\n${list}`;

    fetch(
      `https://hooks.slack.com/services/${SLACK_HOOK}`,
      {
        method: 'POST',
        body: JSON.stringify({text: message})
      }
    )
      .then(response => {
        if (!response.ok) throw new Error(response.statusText);
        console.log('Posted to Slack');
      });
  });
<commit_msg>Correcting bin script<commit_after>#!/usr/bin/env node

const fetch = require('isomorphic-fetch');

const USER_ID = process.env.IDT_USER_ID;
const API_KEY = process.env.IDT_API_KEY;
const SLACK_HOOK = process.env.IDT_SLACK_HOOK;

if (!USER_ID) throw new Error('Must define `IDT_USER_ID` in environment.');
if (!API_KEY) throw new Error('Must define `IDT_API_KEY` in environment.');
if (!SLACK_HOOK) throw new Error('Must define `IDT_SLACK_HOOK` in environment.');

process.on('unhandledRejection', err => { throw err; });

const now = new Date();
const today = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;

function pad(n) { return n < 10 ? '0' + n : n; }

fetch(
  'https://beta.idonethis.com/api/v2/entries',
  {
    headers: {
      Authorization: `Token ${API_KEY}`
    }
  }
)
  .then(response => response.json())
  .then(entries => {
    if (entries.error) throw new Error(entries.error);

    const list = entries
      .filter(entry => entry.user.hash_id === USER_ID && entry.occurred_on === today && entry.status === 'goal')
      .map(entry => `* ${entry.body}`)
      .join('\n');

    if (!list) throw new Error('No goals in IDT today.');

    const message = `My list of goals in I Done This for today:\n\n${list}`;

    fetch(
      `https://hooks.slack.com/services/${SLACK_HOOK}`,
      {
        method: 'POST',
        body: JSON.stringify({text: message})
      }
    )
      .then(response => {
        if (!response.ok) throw new Error(response.statusText);
        console.log('Posted to Slack');
      });
  });
<|endoftext|>


<commit_before>var app = angular.module('StarterApp', ['ngMaterial']);

app.config(function ($sceProvider) {
    $sceProvider.enabled(false);
});

app.factory('chartConfigPersister', ['$location', function ($location) {
    var toJSON = function (chartConfigs) {
        return angular.toJson(chartConfigs);
    };

    var toChartConfigs = function (json) {
        return angular.fromJson(json);
    };

    return {
        getPersistedChartConfigs: function () {
            var persistedChartConfig = $location.hash();
            if (persistedChartConfig) {
                return toChartConfigs(persistedChartConfig);
            }
            return [];
        },
        persistChartConfigs: function (chartConfigs) {
            var chartConfigJSON = toJSON(chartConfigs);
            $location.hash(chartConfigJSON);
        }
    };
}]);

app.directive('sampleLinearChart', function () {
    return {
        restrict: 'EA',
        template: '<svg width="275" height="100"></svg>',
        replace: true,
        link: function (scope, elem, attrs) {
            var lineChartData = [
                {date: "2011-10-01 00:00", close: 70},
                {date: "2011-10-02 00:00", close: 0},
                {date: "2011-10-03 00:00", close: 60},
                {date: "2011-10-04 00:00", close: 120}
            ];
            var parseDateTime = d3.timeParse("%Y-%m-%e %H:%M");
            lineChartData.forEach(function (d) {
                d.date = parseDateTime(d.date);
            });

            var id = attrs.id;
            var svg = d3.select("#" + id),
                margin = {top: 25, right: 15, bottom: 30, left: 25},
                width = +svg.attr("width") - margin.left - margin.right,
                height = +svg.attr("height") - margin.top - margin.bottom,
                g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

            var x = d3.scaleTime()
                .rangeRound([0, width]);

            var y = d3.scaleLinear()
                .domain([0, 100])
                .range([height, 0]);

            var line = d3.line()
                .x(function (d) {
                    return x(d.date);
                })
                .y(function (d) {
                    return y(d.close);
                });

            x.domain(d3.extent(lineChartData, function (d) {
                return d.date;
            }));
            y.domain(d3.extent(lineChartData, function (d) {
                return d.close;
            }));

            g.append("g")
                .attr("transform", "translate(0," + height + ")")
                .call(d3
                    .axisBottom(x)
                    .ticks(3)
                    .tickSize(2)
                    .tickFormat(d3.timeFormat("%b %e")))
                .select(".domain");

            svg.selectAll(".tick text")
                .attr("transform", function (d) {
                    return "translate(" + this.getBBox().height * -2 + "," + this.getBBox().height + 10 + ")rotate(-45)";
                });

            g.append("g")
                .call(d3
                    .axisLeft(y)
                    .ticks(3)
                    .tickSize(2))
                .append("text")
                .attr("fill", "#000")
                .attr("transform", "rotate(-90)")
                .attr("y", 6)
                .attr("dy", "0.71em")
                .attr("text-anchor", "end");

            g.append("path")
                .datum(lineChartData)
                .attr("fill", "none")
                .attr("stroke", "steelblue")
                .attr("stroke-linejoin", "round")
                .attr("stroke-linecap", "round")
                .attr("stroke-width", 1.5)
                .attr("d", line);
        }
    }
});

app.directive('linearChart', ['$http', 'chartConfigPersister', function ($http, chartConfigPersister) {
    return {
        restrict: 'EA',
        scope: true,
        template: '<md-card ng-init="showEditForm=false" ng-mouseover="showEditButton=true" ng-mouseleave="showEditButton=false" width="{{chartConfig.width}}" height="{{chartConfig.height}}">' +
        '<svg ng-style="{width: chartConfig.width + \'px\', height: chartConfig.height + chartConfig.paddingBottom + \'px\'}"></svg>' +
        '
' +
        '
' +
        '<md-button class="md-icon-button" ng-click="showEditForm=true" aria-label="Edit">' +
        '<md-icon md-svg-icon="edit.svg"></md-icon>' +
        '</md-button>' +
        '
' +
        '
' +
        '{{chartConfig.title}}' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '<md-input-container>' +
        'Title' +
        '<input ng-model="chartConfig.title"/>' +
        '</md-input-container>' +
        '<md-input-container>' +
        'Width' +
        '<input type="number" ng-model="chartConfig.width" ng-change="getChartData()" ng-model-options="{debounce: 1000}"/>' +
        '</md-input-container>' +
        '<md-input-container>' +
        'Height' +
        '<input type="number" ng-model="chartConfig.height" ng-change="getChartData()" ng-model-options="{debounce: 1000}"/>' +
        '</md-input-container>' +
        '
' +
        '<md-input-container>' +
        'Datasource' +
        '<input ng-model="chartConfig.datasource" ng-change="getChartData()" ng-model-options="{debounce: 1000}">' +
        '</md-input-container>' +
        '
' +
        '<md-input-container>' +
        'Domain' +
        '<input ng-model="chartConfig.domain" ng-change="getChartData()" ng-model-options="{debounce: 1000}">' +
        '</md-input-container>' +
        '<md-input-container>' +
        'Ticks' +
        '<input type="number" ng-model="chartConfig.domainTicks" ng-change="getChartData()" ng-model-options="{debounce: 1000}">' +
        '</md-input-container>' +
        '<md-input-container>' +
        'Format' +
        '<input ng-model="chartConfig.domainTickFormat" ng-change="getChartData()" ng-model-options="{debounce: 1000}">' +
        '
More details here
' +
        '</md-input-container>' +
        '<md-input-container>' +
        'Padding bottom' +
        '<input type="number" ng-model="chartConfig.paddingBottom" ng-change="getChartData()" ng-model-options="{debounce: 1000}">' +
        '</md-input-container>' +
        '
' +
        '
' +
        '<md-input-container>' +
        'Codomain' +
        '<input ng-model="chartConfig.codomain" ng-change="getChartData()" ng-model-options="{debounce: 1000}">' +
        '</md-input-container>' +
        '
' +
        '
' +
        '<md-card-actions layout="row" layout-align="start center" ng-show="showEditForm">' +
        '<md-button class="md-icon-button" ng-click="editDone()" aria-label="Done">' +
        '<md-icon md-svg-icon="done.svg"></md-icon>' +
        '</md-button>' +
        '</md-card-actions>' +
        '</md-card>',
        replace: true,
        link: {
            post: function (scope, elem, attrs) {
                var chartConfig = scope.chartConfig;

                scope.getChartData = function () {
                    removeChart();
                    $http.get(chartConfig.datasource)
                        .then(function (response) {
                            scope.chartData = response.data;
                            createChart();
                        });
                };

                scope.editDone = function () {
                    scope.showEditForm = false;
                    chartConfigPersister.persistChartConfigs(scope.chartConfigs);
                };

                function removeChart() {
                    var id = attrs.id;
                    var svg = d3.select("#" + id + ">svg");
                    svg.selectAll("*").remove();
                }

                function createChart() {
                    var lineChartData = scope.chartData;
                    var domain = scope.chartConfig.domain;
                    var domainTicks = scope.chartConfig.domainTicks;
                    var domainTickFormat = scope.chartConfig.domainTickFormat;
                    var codomain = scope.chartConfig.codomain
                    lineChartData.forEach(function (d) {
                        d.date = new Date(d[domain]);
                        d.value = d[codomain];
                    });

                    var id = attrs.id;
                    var svg = d3.select("#" + id + ">svg");
                    var margin = {top: 0, right: 0, bottom: 35, left: 35};
                    var width = attrs.width - margin.left - margin.right;
                    var height = attrs.height - margin.top - margin.bottom;
                    var g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

                    var x = d3.scaleTime()
                        .rangeRound([0, width]);

                    var y = d3.scaleLinear()
                        .domain([0, 100])
                        .range([height, 0]);

                    var line = d3.line()
                        .x(function (d) {
                            return x(d[domain]);
                        })
                        .y(function (d) {
                            return y(d[codomain]);
                        });

                    x.domain(d3.extent(lineChartData, function (d) {
                        return d[domain];
                    }));
                    y.domain(d3.extent(lineChartData, function (d) {
                        return d[codomain];
                    }));

                    g.append("g")
                        .attr("transform", "translate(0," + height + ")")
                        .call(d3
                            .axisBottom(x)
                            .ticks(domainTicks)
                            .tickSize(2)
                            .tickFormat(d3.timeFormat(domainTickFormat)))
                        .select(".domain");

                    svg.selectAll(".tick text")
                        .attr("transform", function (d) {
                            return "translate(" + this.getBBox().height * -2 + "," + this.getBBox().height + 10 + ")rotate(-45)";
                        });

                    g.append("g")
                        .call(d3
                            .axisLeft(y)
                            .ticks(3)
                            .tickSize(2))
                        .append("text")
                        .attr("fill", "#000")
                        .attr("transform", "rotate(-90)")
                        .attr("y", 6)
                        .attr("dy", "0.71em")
                        .attr("text-anchor", "end");

                    g.append("path")
                        .datum(lineChartData)
                        .attr("fill", "none")
                        .attr("stroke", "steelblue")
                        .attr("stroke-linejoin", "round")
                        .attr("stroke-linecap", "round")
                        .attr("stroke-width", 1.5)
                        .attr("d", line);
                }

                scope.getChartData();
            }
        }
    }
}]);

app.controller('AppCtrl', ['$scope', '$mdSidenav', '$mdToast', 'chartConfigPersister', function ($scope, $mdSidenav, $mdToast, chartConfigPersister) {
    $scope.toggleSidenav = function () {
        $mdSidenav('left').toggle();
    };

    $scope.chartConfigs = chartConfigPersister.getPersistedChartConfigs();

    $scope.addLinearChart = function () {
        var chartConfig = {
            id: $scope.chartConfigs.length,
            type: 'linear',
            width: 1480,
            height: 200,
            title: 'Chart ' + new Date().getSeconds(),
            datasource: 'https://sync-monitor.dev2.mdl.swisscom.ch/monitor',
            domain: 'start',
            domainTicks: 10,
            domainTickFormat: '%m-%e %H:%M',
            codomain: 'duration',
            paddingBottom: -50
        };

        $scope.chartConfigs.push(chartConfig);

        chartConfigPersister.persistChartConfigs($scope.chartConfigs);

        $mdToast.show(
            $mdToast.simple()
                .textContent('Linear chart added')
                .hideDelay(1)
        );
    }
}]);<commit_msg>Add title padding bottom/left config capabilities<commit_after>var app = angular.module('StarterApp', ['ngMaterial']);

app.config(function ($sceProvider) {
    $sceProvider.enabled(false);
});

app.factory('chartConfigPersister', ['$location', function ($location) {
    var toJSON = function (chartConfigs) {
        return angular.toJson(chartConfigs);
    };

    var toChartConfigs = function (json) {
        return angular.fromJson(json);
    };

    return {
        getPersistedChartConfigs: function () {
            var persistedChartConfig = $location.hash();
            if (persistedChartConfig) {
                return toChartConfigs(persistedChartConfig);
            }
            return [];
        },
        persistChartConfigs: function (chartConfigs) {
            var chartConfigJSON = toJSON(chartConfigs);
            $location.hash(chartConfigJSON);
        }
    };
}]);

app.directive('sampleLinearChart', function () {
    return {
        restrict: 'EA',
        template: '<svg width="275" height="100"></svg>',
        replace: true,
        link: function (scope, elem, attrs) {
            var lineChartData = [
                {date: "2011-10-01 00:00", close: 70},
                {date: "2011-10-02 00:00", close: 0},
                {date: "2011-10-03 00:00", close: 60},
                {date: "2011-10-04 00:00", close: 120}
            ];
            var parseDateTime = d3.timeParse("%Y-%m-%e %H:%M");
            lineChartData.forEach(function (d) {
                d.date = parseDateTime(d.date);
            });

            var id = attrs.id;
            var svg = d3.select("#" + id),
                margin = {top: 25, right: 15, bottom: 30, left: 25},
                width = +svg.attr("width") - margin.left - margin.right,
                height = +svg.attr("height") - margin.top - margin.bottom,
                g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

            var x = d3.scaleTime()
                .rangeRound([0, width]);

            var y = d3.scaleLinear()
                .domain([0, 100])
                .range([height, 0]);

            var line = d3.line()
                .x(function (d) {
                    return x(d.date);
                })
                .y(function (d) {
                    return y(d.close);
                });

            x.domain(d3.extent(lineChartData, function (d) {
                return d.date;
            }));
            y.domain(d3.extent(lineChartData, function (d) {
                return d.close;
            }));

            g.append("g")
                .attr("transform", "translate(0," + height + ")")
                .call(d3
                    .axisBottom(x)
                    .ticks(3)
                    .tickSize(2)
                    .tickFormat(d3.timeFormat("%b %e")))
                .select(".domain");

            svg.selectAll(".tick text")
                .attr("transform", function (d) {
                    return "translate(" + this.getBBox().height * -2 + "," + this.getBBox().height + 10 + ")rotate(-45)";
                });

            g.append("g")
                .call(d3
                    .axisLeft(y)
                    .ticks(3)
                    .tickSize(2))
                .append("text")
                .attr("fill", "#000")
                .attr("transform", "rotate(-90)")
                .attr("y", 6)
                .attr("dy", "0.71em")
                .attr("text-anchor", "end");

            g.append("path")
                .datum(lineChartData)
                .attr("fill", "none")
                .attr("stroke", "steelblue")
                .attr("stroke-linejoin", "round")
                .attr("stroke-linecap", "round")
                .attr("stroke-width", 1.5)
                .attr("d", line);
        }
    }
});

app.directive('linearChart', ['$http', 'chartConfigPersister', function ($http, chartConfigPersister) {
    return {
        restrict: 'EA',
        scope: true,
        template: '<md-card ng-init="showEditForm=false" ng-mouseover="showEditButton=true" ng-mouseleave="showEditButton=false" width="{{chartConfig.width}}" height="{{chartConfig.height}}">' +
        '<svg ng-style="{width: chartConfig.width + \'px\', height: chartConfig.height + chartConfig.paddingBottom + \'px\'}"></svg>' +
        '
' +
        '
' +
        '<md-button class="md-icon-button" ng-click="showEditForm=true" aria-label="Edit">' +
        '<md-icon md-svg-icon="edit.svg"></md-icon>' +
        '</md-button>' +
        '
' +
        '
' +
        '{{chartConfig.title}}' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '<md-input-container>' +
        'Title' +
        '<input ng-model="chartConfig.title"/>' +
        '</md-input-container>' +
        '<md-input-container>' +
        'Margin left' +
        '<input type="number" ng-model="chartConfig.titleMarginLeft" ng-change="getChartData()" ng-model-options="{debounce: 1000}"/>' +
        '</md-input-container>' +
        '<md-input-container>' +
        'Margin bottom' +
        '<input type="number" ng-model="chartConfig.titleMarginBottom" ng-change="getChartData()" ng-model-options="{debounce: 1000}"/>' +
        '</md-input-container>' +
        '
' +
        '
' +
        '<md-input-container>' +
        'Width' +
        '<input type="number" ng-model="chartConfig.width" ng-change="getChartData()" ng-model-options="{debounce: 1000}"/>' +
        '</md-input-container>' +
        '<md-input-container>' +
        'Height' +
        '<input type="number" ng-model="chartConfig.height" ng-change="getChartData()" ng-model-options="{debounce: 1000}"/>' +
        '</md-input-container>' +
        '
' +
        '<md-input-container>' +
        'Datasource' +
        '<input ng-model="chartConfig.datasource" ng-change="getChartData()" ng-model-options="{debounce: 1000}">' +
        '</md-input-container>' +
        '
' +
        '<md-input-container>' +
        'Domain' +
        '<input ng-model="chartConfig.domain" ng-change="getChartData()" ng-model-options="{debounce: 1000}">' +
        '</md-input-container>' +
        '<md-input-container>' +
        'Ticks' +
        '<input type="number" ng-model="chartConfig.domainTicks" ng-change="getChartData()" ng-model-options="{debounce: 1000}">' +
        '</md-input-container>' +
        '<md-input-container>' +
        'Format' +
        '<input ng-model="chartConfig.domainTickFormat" ng-change="getChartData()" ng-model-options="{debounce: 1000}">' +
        '
More details here
' +
        '</md-input-container>' +
        '<md-input-container>' +
        'Padding bottom' +
        '<input type="number" ng-model="chartConfig.paddingBottom" ng-change="getChartData()" ng-model-options="{debounce: 1000}">' +
        '</md-input-container>' +
        '
' +
        '
' +
        '<md-input-container>' +
        'Codomain' +
        '<input ng-model="chartConfig.codomain" ng-change="getChartData()" ng-model-options="{debounce: 1000}">' +
        '</md-input-container>' +
        '
' +
        '
' +
        '<md-card-actions layout="row" layout-align="start center" ng-show="showEditForm">' +
        '<md-button class="md-icon-button" ng-click="editDone()" aria-label="Done">' +
        '<md-icon md-svg-icon="done.svg"></md-icon>' +
        '</md-button>' +
        '</md-card-actions>' +
        '</md-card>',
        replace: true,
        link: {
            post: function (scope, elem, attrs) {
                var chartConfig = scope.chartConfig;

                scope.getChartData = function () {
                    removeChart();
                    $http.get(chartConfig.datasource)
                        .then(function (response) {
                            scope.chartData = response.data;
                            createChart();
                        });
                };

                scope.editDone = function () {
                    scope.showEditForm = false;
                    chartConfigPersister.persistChartConfigs(scope.chartConfigs);
                };

                function removeChart() {
                    var id = attrs.id;
                    var svg = d3.select("#" + id + ">svg");
                    svg.selectAll("*").remove();
                }

                function createChart() {
                    var lineChartData = scope.chartData;
                    var domain = scope.chartConfig.domain;
                    var codomain = scope.chartConfig.codomain
                    lineChartData.forEach(function (d) {
                        d.date = new Date(d[domain]);
                        d.value = d[codomain];
                    });

                    var id = attrs.id;
                    var svg = d3.select("#" + id + ">svg");
                    var margin = {
                        top: 0,
                        right: 0,
                        bottom: scope.chartConfig.titleMarginBottom,
                        left: scope.chartConfig.titleMarginLeft
                    };
                    var width = attrs.width - margin.left - margin.right;
                    var height = attrs.height - margin.top - margin.bottom;
                    var g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

                    var x = d3.scaleTime()
                        .rangeRound([0, width]);

                    var y = d3.scaleLinear()
                        .domain([0, 100])
                        .range([height, 0]);

                    var line = d3.line()
                        .x(function (d) {
                            return x(d[domain]);
                        })
                        .y(function (d) {
                            return y(d[codomain]);
                        });

                    x.domain(d3.extent(lineChartData, function (d) {
                        return d[domain];
                    }));
                    y.domain(d3.extent(lineChartData, function (d) {
                        return d[codomain];
                    }));

                    g.append("g")
                        .attr("transform", "translate(0," + height + ")")
                        .call(d3
                            .axisBottom(x)
                            .ticks(scope.chartConfig.domainTicks)
                            .tickSize(2)
                            .tickFormat(d3.timeFormat(scope.chartConfig.domainTickFormat)))
                        .select(".domain");

                    svg.selectAll(".tick text")
                        .attr("transform", function (d) {
                            return "translate(" + this.getBBox().height * -2 + "," + this.getBBox().height + 10 + ")rotate(-45)translate(0,10)";
                        });

                    g.append("g")
                        .call(d3
                            .axisLeft(y)
                            .ticks(3)
                            .tickSize(2))
                        .append("text")
                        .attr("fill", "#000")
                        .attr("transform", "rotate(-90)")
                        .attr("y", 6)
                        .attr("dy", "0.71em")
                        .attr("text-anchor", "end");

                    g.append("path")
                        .datum(lineChartData)
                        .attr("fill", "none")
                        .attr("stroke", "steelblue")
                        .attr("stroke-linejoin", "round")
                        .attr("stroke-linecap", "round")
                        .attr("stroke-width", 1.5)
                        .attr("d", line);
                }

                scope.getChartData();
            }
        }
    }
}]);

app.controller('AppCtrl', ['$scope', '$mdSidenav', '$mdToast', 'chartConfigPersister', function ($scope, $mdSidenav, $mdToast, chartConfigPersister) {
    $scope.toggleSidenav = function () {
        $mdSidenav('left').toggle();
    };

    $scope.chartConfigs = chartConfigPersister.getPersistedChartConfigs();

    $scope.addLinearChart = function () {
        var chartConfig = {
            id: $scope.chartConfigs.length,
            type: 'linear',
            width: 1480,
            height: 200,
            title: 'Chart ' + new Date().getSeconds(),
            titleMarginBottom: 30,
            titleMarginLeft: 50,
            datasource: 'https://sync-monitor.dev2.mdl.swisscom.ch/monitor',
            domain: 'start',
            domainTicks: 10,
            domainTickFormat: '%m-%e %H:%M',
            codomain: 'duration',
            paddingBottom: 20
        };

        $scope.chartConfigs.push(chartConfig);

        chartConfigPersister.persistChartConfigs($scope.chartConfigs);

        $mdToast.show(
            $mdToast.simple()
                .textContent('Linear chart added')
                .hideDelay(1)
        );
    }
}]);<|endoftext|>


<commit_before>var es = require('event-stream');
var spawn = require('child_process').spawn;

var WinPath = __dirname + '\\node_modules\\.bin\\cucumber-js.cmd';
var UnixPath = __dirname + '/node_modules/cucumber/bin/cucumber.js';

var cucumber = function(options) {

    var runOptions = [];

    if (options.steps) {
        runOptions.push('-r');
        runOptions.push(options.steps);
    }

    if (process.platform === 'win32') {
        binPath = WinPath;
    } else {
        binPath = UnixPath;
    }

    var run = function(argument, callback) {
        var filename = argument.path;
        if (filename.indexOf(".feature") === -1) {
            return callback();
        }

        var processOptions = runOptions.slice(0);

        processOptions.push(filename);

        var cli = spawn(binPath, processOptions);

        var output = [];

        cli.stdout.on('data', function(data) {
            output.push(data);
        });

        cli.on('exit', function(exitCode) {
            var data = Buffer.concat(output).toString();
            var startIndex = data.substring(0, data.indexOf('"keyword": "Feature"')).lastIndexOf('[');
            var featureOutput = data.substring(startIndex);
            process.stdout.write(featureOutput.trim());
            process.stdout.write('\r\nFeature: ' + filename);
        });
        return callback();
    };
    return es.map(run);
};

module.exports = cucumber;
<commit_msg>fix: path to cucumber binary<commit_after>var es = require('event-stream');
var spawn = require('child_process').spawn;

var WinPath = process.cwd() + '\\node_modules\\.bin\\cucumber-js.cmd';
var UnixPath = process.cwd() + '/node_modules/cucumber/bin/cucumber.js';

var cucumber = function(options) {

    var runOptions = [];

    if (options.steps) {
        runOptions.push('-r');
        runOptions.push(options.steps);
    }

    if (process.platform === 'win32') {
        binPath = WinPath;
    } else {
        binPath = UnixPath;
    }

    var run = function(argument, callback) {
        var filename = argument.path;
        if (filename.indexOf(".feature") === -1) {
            return callback();
        }

        var processOptions = runOptions.slice(0);

        processOptions.push(filename);

        var cli = spawn(binPath, processOptions);

        var output = [];

        cli.stdout.on('data', function(data) {
            output.push(data);
        });

        cli.on('exit', function(exitCode) {
            var data = Buffer.concat(output).toString();
            var startIndex = data.substring(0, data.indexOf('"keyword": "Feature"')).lastIndexOf('[');
            var featureOutput = data.substring(startIndex);
            process.stdout.write(featureOutput.trim());
            process.stdout.write('\r\nFeature: ' + filename);
        });
        return callback();
    };
    return es.map(run);
};

module.exports = cucumber;
<|endoftext|>


<commit_before>var readline = require('readline');

var defaultSpinnerString = 0;
var defaultSpinnerDelay = 60;

var Spinner = function(textToShow){
  this.text = textToShow || '';
  this.setSpinnerString(defaultSpinnerString);
  this.setSpinnerDelay(defaultSpinnerDelay);
};

Spinner.spinners = [
  '|/-\\',
  '⠂-–—–-',
  '◐◓◑◒',
  '◴◷◶◵',
  '◰◳◲◱',
  '▖▘▝▗',
  '▌▀▐▄',
  '▉▊▋▌▍▎▏▎▍▌▋▊▉',
  '▁▃▄▅▆▇█▇▆▅▄▃',
  '←↖↑↗→↘↓↙',
  '┤┘┴└├┌┬┐',
  '◢◣◤◥',
  '.oO°Oo.',
  '.oO@*',
  '◡◡ ⊙⊙ ◠◠',
  '☱☲☴',
  '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏',
  '⠋⠙⠚⠞⠖⠦⠴⠲⠳⠓',
  '⠄⠆⠇⠋⠙⠸⠰⠠⠰⠸⠙⠋⠇⠆',
  '⠋⠙⠚⠒⠂⠂⠒⠲⠴⠦⠖⠒⠐⠐⠒⠓⠋',
  '⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠴⠲⠒⠂⠂⠒⠚⠙⠉⠁',
  '⠈⠉⠋⠓⠒⠐⠐⠒⠖⠦⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈',
  '⠁⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈⠈',
  '⢄⢂⢁⡁⡈⡐⡠',
  '⢹⢺⢼⣸⣇⡧⡗⡏',
  '⣾⣽⣻⢿⡿⣟⣯⣷',
  '⠁⠂⠄⡀⢀⠠⠐⠈'
];

Spinner.setDefaultSpinnerString = function(value) {
  defaultSpinnerString = value;
};

Spinner.setDefaultSpinnerDelay = function(value) {
  defaultSpinnerDelay = value;
};

Spinner.prototype.start = function() {
  var current = 0;
  var self = this;
  var hasPos = self.text.indexOf('%s') > -1;
  this.id = setInterval(function() {
    var msg = hasPos ? self.text.replace('%s', self.chars[current]) : self.chars[current] + ' ' + self.text;
    clearLine();
    process.stdout.write(msg);
    current = ++current % self.chars.length;
  }, this.delay);
};

Spinner.prototype.setSpinnerDelay = function(n) {
  this.delay = n;
};

Spinner.prototype.setSpinnerString = function(str) {
  this.chars = mapToSpinner(str, this.spinners).split('');
};

Spinner.prototype.stop = function(clear) {
  clearInterval(this.id);
  if (clear) {
    clearLine();
  }
};

// Helpers

function isInt(value) {
  return (typeof value==='number' && (value%1)===0);
}

function mapToSpinner(value, spinners) {
  // Not an integer, return as strng
  if (!isInt(value)) {
    return value + '';
  }

  // Check if index is within bounds
  value = (value >= Spinner.spinners.length) ? 0 : value;
  // If negative, count from the end
  value = (value < 0) ? Spinner.spinners.length + value : value;

  return Spinner.spinners[value];
}

function clearLine() {
    readline.clearLine(process.stdout, 0);
    readline.cursorTo(process.stdout, 0);
}

exports.Spinner = Spinner;
<commit_msg>Add spinning Earth and one more box-alike spinning<commit_after>var readline = require('readline');

var defaultSpinnerString = 0;
var defaultSpinnerDelay = 60;

var Spinner = function(textToShow){
  this.text = textToShow || '';
  this.setSpinnerString(defaultSpinnerString);
  this.setSpinnerDelay(defaultSpinnerDelay);
};

Spinner.spinners = [
  '|/-\\',
  '⠂-–—–-',
  '◐◓◑◒',
  '◴◷◶◵',
  '◰◳◲◱',
  '▖▘▝▗',
  '■□▪▫',
  '▌▀▐▄',
  '▉▊▋▌▍▎▏▎▍▌▋▊▉',
  '▁▃▄▅▆▇█▇▆▅▄▃',
  '←↖↑↗→↘↓↙',
  '┤┘┴└├┌┬┐',
  '◢◣◤◥',
  '.oO°Oo.',
  '.oO@*',
  '🌍🌎🌏',
  '◡◡ ⊙⊙ ◠◠',
  '☱☲☴',
  '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏',
  '⠋⠙⠚⠞⠖⠦⠴⠲⠳⠓',
  '⠄⠆⠇⠋⠙⠸⠰⠠⠰⠸⠙⠋⠇⠆',
  '⠋⠙⠚⠒⠂⠂⠒⠲⠴⠦⠖⠒⠐⠐⠒⠓⠋',
  '⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠴⠲⠒⠂⠂⠒⠚⠙⠉⠁',
  '⠈⠉⠋⠓⠒⠐⠐⠒⠖⠦⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈',
  '⠁⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈⠈',
  '⢄⢂⢁⡁⡈⡐⡠',
  '⢹⢺⢼⣸⣇⡧⡗⡏',
  '⣾⣽⣻⢿⡿⣟⣯⣷',
  '⠁⠂⠄⡀⢀⠠⠐⠈'
];

Spinner.setDefaultSpinnerString = function(value) {
  defaultSpinnerString = value;
};

Spinner.setDefaultSpinnerDelay = function(value) {
  defaultSpinnerDelay = value;
};

Spinner.prototype.start = function() {
  var current = 0;
  var self = this;
  var hasPos = self.text.indexOf('%s') > -1;
  this.id = setInterval(function() {
    var msg = hasPos ? self.text.replace('%s', self.chars[current]) : self.chars[current] + ' ' + self.text;
    clearLine();
    process.stdout.write(msg);
    current = ++current % self.chars.length;
  }, this.delay);
};

Spinner.prototype.setSpinnerDelay = function(n) {
  this.delay = n;
};

Spinner.prototype.setSpinnerString = function(str) {
  this.chars = mapToSpinner(str, this.spinners).split('');
};

Spinner.prototype.stop = function(clear) {
  clearInterval(this.id);
  if (clear) {
    clearLine();
  }
};

// Helpers

function isInt(value) {
  return (typeof value==='number' && (value%1)===0);
}

function mapToSpinner(value, spinners) {
  // Not an integer, return as strng
  if (!isInt(value)) {
    return value + '';
  }

  // Check if index is within bounds
  value = (value >= Spinner.spinners.length) ? 0 : value;
  // If negative, count from the end
  value = (value < 0) ? Spinner.spinners.length + value : value;

  return Spinner.spinners[value];
}

function clearLine() {
    readline.clearLine(process.stdout, 0);
    readline.cursorTo(process.stdout, 0);
}

exports.Spinner = Spinner;
<|endoftext|>


<commit_before>/* jshint node: true */
'use strict';

const VersionChecker = require('ember-cli-version-checker');
const clone = require('clone');
const path = require('path');

function addBaseDir(Plugin) {
  let type = typeof Plugin;

  if (type === 'function' && !Plugin.baseDir) {
    Plugin.baseDir = () => __dirname;
  } else if (type === 'object' && Plugin !== null && Plugin.default) {
    addBaseDir(Plugin.default);
  }
}

module.exports = {
  name: 'ember-cli-babel',
  configKey: 'ember-cli-babel',

  init: function() {
    this._super.init && this._super.init.apply(this, arguments);

    let checker = new VersionChecker(this);
    let dep = this.emberCLIChecker = checker.for('ember-cli', 'npm');

    this._shouldShowBabelDeprecations = !dep.lt('2.11.0-beta.2');
  },

  setupPreprocessorRegistry: function(type, registry) {
    let addon = this;

    registry.add('js', {
      name: 'ember-cli-babel',
      ext: 'js',
      toTree: function(tree) {
        return require('broccoli-babel-transpiler')(tree, addon._getBabelOptions());
      }
    });
  },

  _shouldIncludePolyfill: function() {
    let addonOptions = this._getAddonOptions();
    let babelOptions = addonOptions.babel;
    let customOptions = addonOptions['ember-cli-babel'];

    if (this._shouldShowBabelDeprecations && !this._polyfillDeprecationPrinted &&
      babelOptions && 'includePolyfill' in babelOptions) {

      this._polyfillDeprecationPrinted = true;

      // we can use writeDeprecateLine() here because the warning will only be shown on newer Ember CLIs
      this.ui.writeDeprecateLine(
        'Putting the "includePolyfill" option in "babel" is deprecated, please put it in "ember-cli-babel" instead.');
    }

    if (customOptions && 'includePolyfill' in customOptions) {
      return customOptions.includePolyfill === true;
    } else if (babelOptions && 'includePolyfill' in babelOptions) {
      return babelOptions.includePolyfill === true;
    } else {
      return false;
    }
  },

  _importPolyfill: function(app) {
    let polyfillPath = 'vendor/babel-polyfill/polyfill.js';

    if (this.import) {  // support for ember-cli >= 2.7
      this.import(polyfillPath, { prepend: true });
    } else if (app.import) { // support ember-cli < 2.7
      app.import(polyfillPath, { prepend: true });
    } else {
      console.warn('Please run: ember install ember-cli-import-polyfill');
    }
  },

  treeForVendor: function() {
    if (!this._shouldIncludePolyfill()) { return; }

    const Funnel = require('broccoli-funnel');
    const UnwatchedDir = require('broccoli-source').UnwatchedDir;

    // Find babel-core's browser polyfill and use its directory as our vendor tree
    let polyfillDir = path.dirname(require.resolve('babel-polyfill/dist/polyfill'));

    return new Funnel(new UnwatchedDir(polyfillDir), {
      destDir: 'babel-polyfill'
    });
  },

  included: function(app) {
    this._super.included.apply(this, arguments);
    this.app = app;

    if (this._shouldIncludePolyfill()) {
      this._importPolyfill(app);
    }
  },

  isPluginRequired(plugin) {
    const isPluginRequired = require('babel-preset-env').isPluginRequired;
    let targets = this._getTargets();

    return isPluginRequired(targets, plugin);
  },

  _getAddonOptions: function() {
    return (this.parent && this.parent.options) || (this.app && this.app.options) || {};
  },

  _getBabelOptions: function() {
    let parentName;

    if (this.parent) {
      if (typeof this.parent.name === 'function') {
        parentName = this.parent.name();
      } else {
        parentName = this.parent.name;
      }
    }

    let addonOptions = this._getAddonOptions();
    let options = clone(addonOptions.babel || {});

    // used only to support using ember-cli-babel@6 at the
    // top level (app or addon during development) on ember-cli
    // older than 2.13
    //
    // without this, we mutate the same shared `options.babel.plugins`
    // that is used to transpile internally (via `_prunedBabelOptions`
    // in older ember-cli versions)
    let babel6Options = clone(addonOptions.babel6 || {});

    // options.modules is set only for things assuming babel@5 usage
    if (options.modules) {
      // using babel@5 configuration with babel@6
      // without overriding here we would trigger
      // an error
      options = {
        plugins: [].concat(
          babel6Options.plugins,
          options.plugins
        ).filter(Boolean)
      };
    }

    let shouldCompileModules = this._shouldCompileModules();

    let userPlugins = [].concat(options.plugins, babel6Options.plugins).filter(Boolean);

    options.plugins = [].concat(
      userPlugins,
      shouldCompileModules && this._getModulesPlugin(),
      this._getPresetEnvPlugins()
    ).filter(Boolean);
    options.moduleIds = true;

    if (shouldCompileModules) {
      options.resolveModuleSource = require('amd-name-resolver').moduleResolve;
    }

    options.highlightCode = false;

    return options;
  },

  _getPresetEnvPlugins() {
    const presetEnv = require('babel-preset-env').default;
    let targets = this._getTargets();
    let browsers = targets && targets.browsers;
    let presetEnvPlugins = presetEnv(null, {
      browsers,
      modules: false,
    }).plugins;

    presetEnvPlugins.forEach(function(pluginArray) {
      let Plugin = pluginArray[0];
      addBaseDir(Plugin);
    });

    return presetEnvPlugins;
  },

  _getTargets() {
    return this.project && this.project.targets && this.project.targets.browsers;
  },

  _getModulesPlugin() {
    const ModulesTransform = require('babel-plugin-transform-es2015-modules-amd');

    addBaseDir(ModulesTransform);

    return [
      [ModulesTransform, { noInterop: true }],
    ];
  },

  _shouldCompileModules() {
    let addonOptions = this._getAddonOptions();

    if (addonOptions['ember-cli-babel'] && 'compileModules' in addonOptions['ember-cli-babel']) {
      return addonOptions['ember-cli-babel'].compileModules;
    } else if (addonOptions.babel && 'compileModules' in addonOptions.babel) {
      if (this._shouldShowBabelDeprecations && !this._compileModulesDeprecationPrinted) {
        this._compileModulesDeprecationPrinted = true;
        // we can use writeDeprecateLine() here because the warning will only be shown on newer Ember CLIs
        this.ui.writeDeprecateLine('Putting the "compileModules" option in "babel" is deprecated, please put it in "ember-cli-babel" instead.');
      }

      return addonOptions.babel.compileModules;
    } else {
      return this.emberCLIChecker.gt('2.12.0-alpha.1');
    }
  },

};
<commit_msg>Prevent error when isPluginRequired is called without targets.<commit_after>/* jshint node: true */
'use strict';

const VersionChecker = require('ember-cli-version-checker');
const clone = require('clone');
const path = require('path');

function addBaseDir(Plugin) {
  let type = typeof Plugin;

  if (type === 'function' && !Plugin.baseDir) {
    Plugin.baseDir = () => __dirname;
  } else if (type === 'object' && Plugin !== null && Plugin.default) {
    addBaseDir(Plugin.default);
  }
}

module.exports = {
  name: 'ember-cli-babel',
  configKey: 'ember-cli-babel',

  init: function() {
    this._super.init && this._super.init.apply(this, arguments);

    let checker = new VersionChecker(this);
    let dep = this.emberCLIChecker = checker.for('ember-cli', 'npm');

    this._shouldShowBabelDeprecations = !dep.lt('2.11.0-beta.2');
  },

  setupPreprocessorRegistry: function(type, registry) {
    let addon = this;

    registry.add('js', {
      name: 'ember-cli-babel',
      ext: 'js',
      toTree: function(tree) {
        return require('broccoli-babel-transpiler')(tree, addon._getBabelOptions());
      }
    });
  },

  _shouldIncludePolyfill: function() {
    let addonOptions = this._getAddonOptions();
    let babelOptions = addonOptions.babel;
    let customOptions = addonOptions['ember-cli-babel'];

    if (this._shouldShowBabelDeprecations && !this._polyfillDeprecationPrinted &&
      babelOptions && 'includePolyfill' in babelOptions) {

      this._polyfillDeprecationPrinted = true;

      // we can use writeDeprecateLine() here because the warning will only be shown on newer Ember CLIs
      this.ui.writeDeprecateLine(
        'Putting the "includePolyfill" option in "babel" is deprecated, please put it in "ember-cli-babel" instead.');
    }

    if (customOptions && 'includePolyfill' in customOptions) {
      return customOptions.includePolyfill === true;
    } else if (babelOptions && 'includePolyfill' in babelOptions) {
      return babelOptions.includePolyfill === true;
    } else {
      return false;
    }
  },

  _importPolyfill: function(app) {
    let polyfillPath = 'vendor/babel-polyfill/polyfill.js';

    if (this.import) {  // support for ember-cli >= 2.7
      this.import(polyfillPath, { prepend: true });
    } else if (app.import) { // support ember-cli < 2.7
      app.import(polyfillPath, { prepend: true });
    } else {
      console.warn('Please run: ember install ember-cli-import-polyfill');
    }
  },

  treeForVendor: function() {
    if (!this._shouldIncludePolyfill()) { return; }

    const Funnel = require('broccoli-funnel');
    const UnwatchedDir = require('broccoli-source').UnwatchedDir;

    // Find babel-core's browser polyfill and use its directory as our vendor tree
    let polyfillDir = path.dirname(require.resolve('babel-polyfill/dist/polyfill'));

    return new Funnel(new UnwatchedDir(polyfillDir), {
      destDir: 'babel-polyfill'
    });
  },

  included: function(app) {
    this._super.included.apply(this, arguments);
    this.app = app;

    if (this._shouldIncludePolyfill()) {
      this._importPolyfill(app);
    }
  },

  isPluginRequired(plugin) {
    const isPluginRequired = require('babel-preset-env').isPluginRequired;
    let targets = this._getTargets();

    // if no targets are setup, assume that all plugins are required
    if (!targets) { return true; }

    return isPluginRequired(targets, plugin);
  },

  _getAddonOptions: function() {
    return (this.parent && this.parent.options) || (this.app && this.app.options) || {};
  },

  _getBabelOptions: function() {
    let parentName;

    if (this.parent) {
      if (typeof this.parent.name === 'function') {
        parentName = this.parent.name();
      } else {
        parentName = this.parent.name;
      }
    }

    let addonOptions = this._getAddonOptions();
    let options = clone(addonOptions.babel || {});

    // used only to support using ember-cli-babel@6 at the
    // top level (app or addon during development) on ember-cli
    // older than 2.13
    //
    // without this, we mutate the same shared `options.babel.plugins`
    // that is used to transpile internally (via `_prunedBabelOptions`
    // in older ember-cli versions)
    let babel6Options = clone(addonOptions.babel6 || {});

    // options.modules is set only for things assuming babel@5 usage
    if (options.modules) {
      // using babel@5 configuration with babel@6
      // without overriding here we would trigger
      // an error
      options = {
        plugins: [].concat(
          babel6Options.plugins,
          options.plugins
        ).filter(Boolean)
      };
    }

    let shouldCompileModules = this._shouldCompileModules();

    let userPlugins = [].concat(options.plugins, babel6Options.plugins).filter(Boolean);

    options.plugins = [].concat(
      userPlugins,
      shouldCompileModules && this._getModulesPlugin(),
      this._getPresetEnvPlugins()
    ).filter(Boolean);
    options.moduleIds = true;

    if (shouldCompileModules) {
      options.resolveModuleSource = require('amd-name-resolver').moduleResolve;
    }

    options.highlightCode = false;

    return options;
  },

  _getPresetEnvPlugins() {
    const presetEnv = require('babel-preset-env').default;
    let targets = this._getTargets();
    let browsers = targets && targets.browsers;
    let presetEnvPlugins = presetEnv(null, {
      browsers,
      modules: false,
    }).plugins;

    presetEnvPlugins.forEach(function(pluginArray) {
      let Plugin = pluginArray[0];
      addBaseDir(Plugin);
    });

    return presetEnvPlugins;
  },

  _getTargets() {
    return this.project && this.project.targets && this.project.targets.browsers;
  },

  _getModulesPlugin() {
    const ModulesTransform = require('babel-plugin-transform-es2015-modules-amd');

    addBaseDir(ModulesTransform);

    return [
      [ModulesTransform, { noInterop: true }],
    ];
  },

  _shouldCompileModules() {
    let addonOptions = this._getAddonOptions();

    if (addonOptions['ember-cli-babel'] && 'compileModules' in addonOptions['ember-cli-babel']) {
      return addonOptions['ember-cli-babel'].compileModules;
    } else if (addonOptions.babel && 'compileModules' in addonOptions.babel) {
      if (this._shouldShowBabelDeprecations && !this._compileModulesDeprecationPrinted) {
        this._compileModulesDeprecationPrinted = true;
        // we can use writeDeprecateLine() here because the warning will only be shown on newer Ember CLIs
        this.ui.writeDeprecateLine('Putting the "compileModules" option in "babel" is deprecated, please put it in "ember-cli-babel" instead.');
      }

      return addonOptions.babel.compileModules;
    } else {
      return this.emberCLIChecker.gt('2.12.0-alpha.1');
    }
  },

};
<|endoftext|>