<commit_before>/*
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/

'use strict';

// Include Gulp & tools we'll use
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var del = require('del');
var runSequence = require('run-sequence');
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var merge = require('merge-stream');
var path = require('path');
var fs = require('fs');
var glob = require('glob');
var historyApiFallback = require('connect-history-api-fallback');
var packageJson = require('./package.json');
var crypto = require('crypto');
var config = require('./config');

// Get a task path
function task(filename) {
  return './tasks/' + filename;
}

// Lint JavaScript
gulp.task('jshint', function () {
  return gulp.src([
      'app/scripts/**/*.js',
      '!app/scripts/analytics.js',
      'app/elements/**/*.js',
      'gulpfile.js'
    ])
    .pipe($.jshint())
    .pipe($.jshint.reporter('jshint-stylish'))
    .pipe($.if(!browserSync.active, $.jshint.reporter('fail')));
});

// Optimize images
gulp.task('images', function () {
  return gulp.src('app/images/**/*')
    .pipe($.imagemin({
      progressive: true,
      interlaced: true
    }))
    .pipe(gulp.dest('dist/images'))
    .pipe($.size({title: 'Copy optimized images to dist/images dir:'}));
});

// Copy all files at the root level (app)
gulp.task('copy', function () {
  var app = gulp.src([
    'app/*',
    '!app/cache-config.json',
    '!app/content',
    '!app/manifest.json',
    '!app/test',
    '!app/views'
  ], {
    dot: true
  }).pipe(gulp.dest('dist'));

  var bower = gulp.src([
    'bower_components/**/*.{css,html,js}',
    '!bower_components/**/index.html',
    '!bower_components/**/{demo,test}/**/*'
  ]).pipe(gulp.dest('dist/bower_components'));

  var elements = gulp.src([
    'app/elements/elements.html',
    'app/elements/routing.html'
  ]).pipe(gulp.dest('dist/elements'));

  var icons = gulp.src(['app/themes/' + config.theme + '/icons.html'])
    .pipe(gulp.dest('dist/themes/' + config.theme));

  var scripts = gulp.src(['app/scripts/analytics.js'])
    .pipe(gulp.dest('dist/scripts'));

  var swBootstrap = gulp.src(['bower_components/platinum-sw/bootstrap/*.js'])
    .pipe(gulp.dest('dist/elements/bootstrap'));

  var swToolbox = gulp.src(['bower_components/sw-toolbox/*.js'])
    .pipe(gulp.dest('dist/sw-toolbox'));

  var vulcanized = gulp.src(['app/elements/elements.html'])
    .pipe($.rename('elements.vulcanized.html'))
    .pipe(gulp.dest('dist/elements'));

  return merge(app, bower, elements, icons, scripts, swBootstrap, swToolbox, vulcanized)
    .pipe($.size({title: 'Copy files to dist dir:'}));
});

// Copy web fonts to dist
gulp.task('fonts', function () {
  return gulp.src(['app/themes/' + config.theme + '/fonts/**/*.{css,woff,woff2}'])
    .pipe(gulp.dest('dist/themes/' + config.theme + '/fonts'))
    .pipe($.size({title: 'Copy fonts to dist/themes/' + config.theme + '/fonts dir:'}));
});

// Scan your HTML for assets & optimize them
gulp.task('html', ['views'], function () {
  var assets = $.useref.assets({searchPath: ['dist']});

  return gulp.src(['app/*.html', '.tmp/*.html'])
    // Replace path for vulcanized assets
    .pipe($.if('*.html', $.replace('elements/elements.html', 'elements/elements.vulcanized.html')))
    .pipe(assets)
    // Concatenate and minify JavaScript
    .pipe($.if('*.js', $.uglify({preserveComments: 'some'})))
    .pipe(assets.restore())
    .pipe($.useref())
    // Minify any HTML
    .pipe($.if('*.html', $.minifyHtml({
      empty: true,  // KEEP empty attributes
      loose: true,  // KEEP one whitespace
      quotes: true, // KEEP arbitrary quotes
      spare: true   // KEEP redundant attributes
    })))
    // Output files
    .pipe(gulp.dest('dist'))
    .pipe($.size({title: 'Copy optimized html and assets files to dist dir:'}));
});

// Vulcanize granular configuration
gulp.task('vulcanize', function () {
  return gulp.src('dist/elements/elements.vulcanized.html')
    .pipe($.plumber())
    .pipe($.vulcanize({
      stripComments: true,
      inlineCss: true,
      inlineScripts: true
    }))
    // Split inline scripts from an HTML file for CSP compliance
    .pipe($.crisper())
    // Minify elements.vulcanized.html
    // https://github.com/PolymerLabs/polybuild/issues/3
    .pipe($.if('*.html', $.htmlmin({
      customAttrAssign: [
        {source:'\\$='}
      ],
      customAttrSurround: [
        [ {source: '\\({\\{'}, {source: '\\}\\}'} ],
        [ {source: '\\[\\['}, {source: '\\]\\]'}  ]
      ],
      removeComments: true,
      collapseWhitespace: true
    })))
    // Remove newline characters
    .pipe($.if('*.html', $.replace(/[\n]/g, '')))
    // Remove 2 or more spaces from CSS
    // (single spaces can be syntactically significant)
    .pipe($.if('*.html', $.replace(/ {2,}/g, '')))
    // Remove CSS comments
    .pipe($.if('*.html', $.stripCssComments({preserve: false})))
    // Minify elements.vulcanized.js
    .pipe($.if('*.js', $.uglify()))
    .pipe(gulp.dest('dist/elements'))
    .pipe($.size({title: 'Copy vulcanized elements to dist/elements dir:'}));
});

// Generate config data for the <sw-precache-cache> element.
// This include a list of files that should be precached, as well as a (hopefully unique) cache
// id that ensure that multiple PSK projects don't share the same Cache Storage.
gulp.task('cache-config', function (callback) {
  var dir = 'dist';
  var config = {
    cacheId: packageJson.name || path.basename(__dirname),
    disabled: false
  };

  return glob('{elements,scripts,themes}/**/*.*', {cwd: dir}, function(error, files) {
    if (error) {
      callback(error);
    } else {
      files.push('index.html', './', 'bower_components/webcomponentsjs/webcomponents-lite.min.js');
      config.precache = files;

      var md5 = crypto.createHash('md5');
      md5.update(JSON.stringify(config.precache));
      config.precacheFingerprint = md5.digest('hex');

      var configPath = path.join(dir, 'cache-config.json');
      fs.writeFile(configPath, JSON.stringify(config), callback);
    }
  });
});

// Clean output directory
gulp.task('clean', function (cb) {
  del(['.tmp', 'dist', 'deploy'], cb);
});

// Watch files for changes & reload
gulp.task('serve', ['js', 'styles', 'views'], function () {
  browserSync({
    browser: config.browserSync.browser,
    https: config.browserSync.https,
    notify: config.browserSync.notify,
    port: config.browserSync.port,
    logPrefix: 'PSK',
    snippetOptions: {
      rule: {
        match: '',
        fn: function (snippet) {
          return snippet;
        }
      }
    },
    server: {
      baseDir: ['.tmp', 'app'],
      middleware: [ historyApiFallback() ],
      routes: {
        '/bower_components': 'bower_components'
      }
    },
    ui: {
      port: config.browserSync.ui.port
    }
  });

  gulp.watch([
    'app/*.html',
    'app/views/**/*.html',
    'app/content/**/*.md'
  ], ['views', reload]);
  gulp.watch(['app/{elements,themes}/**/*.{css,html}'], ['styles', reload]);
  gulp.watch(['app/{scripts,elements}/**/*.{js,html}'], ['jshint', 'js']);
  gulp.watch(['app/images/**/*'], reload);
});

// Build and serve the output from the dist build
gulp.task('serve:dist', ['default'], function () {
  browserSync({
    browser: config.browserSync.browser,
    https: config.browserSync.https,
    notify: config.browserSync.notify,
    port: config.browserSync.port,
    logPrefix: 'PSK',
    snippetOptions: {
      rule: {
        match: '',
        fn: function (snippet) {
          return snippet;
        }
      }
    },
    server: 'dist',
    middleware: [ historyApiFallback() ],
    ui: {
      port: config.browserSync.ui.port
    }
  });
});

// Clean dist directory
gulp.task('clean-dist', require(task('clean-dist'))(del));

// Fix path to sw-toolbox.js
gulp.task('fix-path-sw-toolbox', require(task('fix-path-sw-toolbox'))($, gulp));

// Transpile all JS from ES2015 (ES6) to ES5
gulp.task('js', require(task('js-babel'))($, gulp));

// Add colors to Web Application Manifest - manifest.json
gulp.task('manifest', require(task('manifest'))($, config, gulp));

// Minify JavaScript in dist directory
gulp.task('minify-dist', require(task('minify-dist'))($, gulp, merge));

// Static asset revisioning by appending content hash to filenames
gulp.task('revision', require(task('revision'))($, gulp));

// Build and serve the output from the dist build with GAE tool
gulp.task('serve:gae', ['default'], require(task('serve-gae'))($, gulp));

// Transform styles with PostCSS
gulp.task('styles', require(task('styles'))($, config, gulp, merge));

// Compile HTML files with Nunjucks templating engine
gulp.task('views', require(task('views-nunjucks'))($, config, gulp));

// Build Production Files, the Default Task
gulp.task('default', ['clean'], function (cb) {
  runSequence(
    ['copy', 'js', 'jshint', 'lint', 'manifest', 'styles'],
    ['fonts', 'html', 'images'],
    'vulcanize',
    ['clean-dist', 'minify-dist'],
    'cache-config',
    cb);
});

// Initializing app
gulp.task('init', function (cb) {
  runSequence(
    ['download:analytics', 'download:fonts'],
    cb);
});

// Deploy Tasks
// ------------

// Pre-deploy tasks
gulp.task('pre-deploy', function(cb) {
  runSequence(
    'default',
    'fix-path-sw-toolbox',
    'revision',
    cb);
});

// Deploy to development environment
gulp.task('deploy:dev', ['pre-deploy'],
  require(task('deploy'))($, config, gulp, 'development'));

// Deploy to staging environment
gulp.task('deploy:stag', ['pre-deploy'],
  require(task('deploy'))($, config, gulp, 'staging'));

// Deploy to production environment
gulp.task('deploy:prod', ['pre-deploy'],
  require(task('deploy'))($, config, gulp, 'production'));

// Promote the staging version to the production environment
gulp.task('deploy:promote',
  require(task('deploy'))($, config, gulp, 'promote'));

// Tool Tasks
// ----------

// Download Google Fonts for load page performance and offline using
gulp.task('download:fonts', require(task('download-fonts'))($, config, gulp));

// Run PageSpeed Insights
gulp.task('pagespeed', require(task('pagespeed'))(config));

// Load custom tasks from the `tasks` directory
try { require('require-dir')('tasks/tests'); } catch (err) {}
<commit_msg>Remove lint from default task<commit_after>/*
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/

'use strict';

// Include Gulp & tools we'll use
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var del = require('del');
var runSequence = require('run-sequence');
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var merge = require('merge-stream');
var path = require('path');
var fs = require('fs');
var glob = require('glob');
var historyApiFallback = require('connect-history-api-fallback');
var packageJson = require('./package.json');
var crypto = require('crypto');
var config = require('./config');

// Get a task path
function task(filename) {
  return './tasks/' + filename;
}

// Lint JavaScript
gulp.task('jshint', function () {
  return gulp.src([
      'app/scripts/**/*.js',
      '!app/scripts/analytics.js',
      'app/elements/**/*.js',
      'gulpfile.js'
    ])
    .pipe($.jshint())
    .pipe($.jshint.reporter('jshint-stylish'))
    .pipe($.if(!browserSync.active, $.jshint.reporter('fail')));
});

// Optimize images
gulp.task('images', function () {
  return gulp.src('app/images/**/*')
    .pipe($.imagemin({
      progressive: true,
      interlaced: true
    }))
    .pipe(gulp.dest('dist/images'))
    .pipe($.size({title: 'Copy optimized images to dist/images dir:'}));
});

// Copy all files at the root level (app)
gulp.task('copy', function () {
  var app = gulp.src([
    'app/*',
    '!app/cache-config.json',
    '!app/content',
    '!app/manifest.json',
    '!app/test',
    '!app/views'
  ], {
    dot: true
  }).pipe(gulp.dest('dist'));

  var bower = gulp.src([
    'bower_components/**/*.{css,html,js}',
    '!bower_components/**/index.html',
    '!bower_components/**/{demo,test}/**/*'
  ]).pipe(gulp.dest('dist/bower_components'));

  var elements = gulp.src([
    'app/elements/elements.html',
    'app/elements/routing.html'
  ]).pipe(gulp.dest('dist/elements'));

  var icons = gulp.src(['app/themes/' + config.theme + '/icons.html'])
    .pipe(gulp.dest('dist/themes/' + config.theme));

  var scripts = gulp.src(['app/scripts/analytics.js'])
    .pipe(gulp.dest('dist/scripts'));

  var swBootstrap = gulp.src(['bower_components/platinum-sw/bootstrap/*.js'])
    .pipe(gulp.dest('dist/elements/bootstrap'));

  var swToolbox = gulp.src(['bower_components/sw-toolbox/*.js'])
    .pipe(gulp.dest('dist/sw-toolbox'));

  var vulcanized = gulp.src(['app/elements/elements.html'])
    .pipe($.rename('elements.vulcanized.html'))
    .pipe(gulp.dest('dist/elements'));

  return merge(app, bower, elements, icons, scripts, swBootstrap, swToolbox, vulcanized)
    .pipe($.size({title: 'Copy files to dist dir:'}));
});

// Copy web fonts to dist
gulp.task('fonts', function () {
  return gulp.src(['app/themes/' + config.theme + '/fonts/**/*.{css,woff,woff2}'])
    .pipe(gulp.dest('dist/themes/' + config.theme + '/fonts'))
    .pipe($.size({title: 'Copy fonts to dist/themes/' + config.theme + '/fonts dir:'}));
});

// Scan your HTML for assets & optimize them
gulp.task('html', ['views'], function () {
  var assets = $.useref.assets({searchPath: ['dist']});

  return gulp.src(['app/*.html', '.tmp/*.html'])
    // Replace path for vulcanized assets
    .pipe($.if('*.html', $.replace('elements/elements.html', 'elements/elements.vulcanized.html')))
    .pipe(assets)
    // Concatenate and minify JavaScript
    .pipe($.if('*.js', $.uglify({preserveComments: 'some'})))
    .pipe(assets.restore())
    .pipe($.useref())
    // Minify any HTML
    .pipe($.if('*.html', $.minifyHtml({
      empty: true,  // KEEP empty attributes
      loose: true,  // KEEP one whitespace
      quotes: true, // KEEP arbitrary quotes
      spare: true   // KEEP redundant attributes
    })))
    // Output files
    .pipe(gulp.dest('dist'))
    .pipe($.size({title: 'Copy optimized html and assets files to dist dir:'}));
});

// Vulcanize granular configuration
gulp.task('vulcanize', function () {
  return gulp.src('dist/elements/elements.vulcanized.html')
    .pipe($.plumber())
    .pipe($.vulcanize({
      stripComments: true,
      inlineCss: true,
      inlineScripts: true
    }))
    // Split inline scripts from an HTML file for CSP compliance
    .pipe($.crisper())
    // Minify elements.vulcanized.html
    // https://github.com/PolymerLabs/polybuild/issues/3
    .pipe($.if('*.html', $.htmlmin({
      customAttrAssign: [
        {source:'\\$='}
      ],
      customAttrSurround: [
        [ {source: '\\({\\{'}, {source: '\\}\\}'} ],
        [ {source: '\\[\\['}, {source: '\\]\\]'}  ]
      ],
      removeComments: true,
      collapseWhitespace: true
    })))
    // Remove newline characters
    .pipe($.if('*.html', $.replace(/[\n]/g, '')))
    // Remove 2 or more spaces from CSS
    // (single spaces can be syntactically significant)
    .pipe($.if('*.html', $.replace(/ {2,}/g, '')))
    // Remove CSS comments
    .pipe($.if('*.html', $.stripCssComments({preserve: false})))
    // Minify elements.vulcanized.js
    .pipe($.if('*.js', $.uglify()))
    .pipe(gulp.dest('dist/elements'))
    .pipe($.size({title: 'Copy vulcanized elements to dist/elements dir:'}));
});

// Generate config data for the <sw-precache-cache> element.
// This include a list of files that should be precached, as well as a (hopefully unique) cache
// id that ensure that multiple PSK projects don't share the same Cache Storage.
gulp.task('cache-config', function (callback) {
  var dir = 'dist';
  var config = {
    cacheId: packageJson.name || path.basename(__dirname),
    disabled: false
  };

  return glob('{elements,scripts,themes}/**/*.*', {cwd: dir}, function(error, files) {
    if (error) {
      callback(error);
    } else {
      files.push('index.html', './', 'bower_components/webcomponentsjs/webcomponents-lite.min.js');
      config.precache = files;

      var md5 = crypto.createHash('md5');
      md5.update(JSON.stringify(config.precache));
      config.precacheFingerprint = md5.digest('hex');

      var configPath = path.join(dir, 'cache-config.json');
      fs.writeFile(configPath, JSON.stringify(config), callback);
    }
  });
});

// Clean output directory
gulp.task('clean', function (cb) {
  del(['.tmp', 'dist', 'deploy'], cb);
});

// Watch files for changes & reload
gulp.task('serve', ['js', 'styles', 'views'], function () {
  browserSync({
    browser: config.browserSync.browser,
    https: config.browserSync.https,
    notify: config.browserSync.notify,
    port: config.browserSync.port,
    logPrefix: 'PSK',
    snippetOptions: {
      rule: {
        match: '',
        fn: function (snippet) {
          return snippet;
        }
      }
    },
    server: {
      baseDir: ['.tmp', 'app'],
      middleware: [ historyApiFallback() ],
      routes: {
        '/bower_components': 'bower_components'
      }
    },
    ui: {
      port: config.browserSync.ui.port
    }
  });

  gulp.watch([
    'app/*.html',
    'app/views/**/*.html',
    'app/content/**/*.md'
  ], ['views', reload]);
  gulp.watch(['app/{elements,themes}/**/*.{css,html}'], ['styles', reload]);
  gulp.watch(['app/{scripts,elements}/**/*.{js,html}'], ['jshint', 'js']);
  gulp.watch(['app/images/**/*'], reload);
});

// Build and serve the output from the dist build
gulp.task('serve:dist', ['default'], function () {
  browserSync({
    browser: config.browserSync.browser,
    https: config.browserSync.https,
    notify: config.browserSync.notify,
    port: config.browserSync.port,
    logPrefix: 'PSK',
    snippetOptions: {
      rule: {
        match: '',
        fn: function (snippet) {
          return snippet;
        }
      }
    },
    server: 'dist',
    middleware: [ historyApiFallback() ],
    ui: {
      port: config.browserSync.ui.port
    }
  });
});

// Clean dist directory
gulp.task('clean-dist', require(task('clean-dist'))(del));

// Fix path to sw-toolbox.js
gulp.task('fix-path-sw-toolbox', require(task('fix-path-sw-toolbox'))($, gulp));

// Transpile all JS from ES2015 (ES6) to ES5
gulp.task('js', require(task('js-babel'))($, gulp));

// Add colors to Web Application Manifest - manifest.json
gulp.task('manifest', require(task('manifest'))($, config, gulp));

// Minify JavaScript in dist directory
gulp.task('minify-dist', require(task('minify-dist'))($, gulp, merge));

// Static asset revisioning by appending content hash to filenames
gulp.task('revision', require(task('revision'))($, gulp));

// Build and serve the output from the dist build with GAE tool
gulp.task('serve:gae', ['default'], require(task('serve-gae'))($, gulp));

// Transform styles with PostCSS
gulp.task('styles', require(task('styles'))($, config, gulp, merge));

// Compile HTML files with Nunjucks templating engine
gulp.task('views', require(task('views-nunjucks'))($, config, gulp));

// Build Production Files, the Default Task
gulp.task('default', ['clean'], function (cb) {
  runSequence(
    ['copy', 'js', 'jshint', 'manifest', 'styles'],
    ['fonts', 'html', 'images'],
    'vulcanize',
    ['clean-dist', 'minify-dist'],
    'cache-config',
    cb);
});

// Initializing app
gulp.task('init', function (cb) {
  runSequence(
    ['download:analytics', 'download:fonts'],
    cb);
});

// Deploy Tasks
// ------------

// Pre-deploy tasks
gulp.task('pre-deploy', function(cb) {
  runSequence(
    'default',
    'fix-path-sw-toolbox',
    'revision',
    cb);
});

// Deploy to development environment
gulp.task('deploy:dev', ['pre-deploy'],
  require(task('deploy'))($, config, gulp, 'development'));

// Deploy to staging environment
gulp.task('deploy:stag', ['pre-deploy'],
  require(task('deploy'))($, config, gulp, 'staging'));

// Deploy to production environment
gulp.task('deploy:prod', ['pre-deploy'],
  require(task('deploy'))($, config, gulp, 'production'));

// Promote the staging version to the production environment
gulp.task('deploy:promote',
  require(task('deploy'))($, config, gulp, 'promote'));

// Tool Tasks
// ----------

// Download Google Fonts for load page performance and offline using
gulp.task('download:fonts', require(task('download-fonts'))($, config, gulp));

// Run PageSpeed Insights
gulp.task('pagespeed', require(task('pagespeed'))(config));

// Load custom tasks from the `tasks` directory
try { require('require-dir')('tasks/tests'); } catch (err) {}
<|endoftext|>


<commit_before>/*eslint no-console: 0 */
// @flow

import program from 'commander'
import chalk from 'chalk'
import ReleasabilityChecker from '../lib/releasability-checker'
import ReleaseExecutor from '../lib/release-executor'

export default function run() {

    program
        .option('--prefix <version prefix>', 'version prefix')
        .option('--branch', 'create branch')
        .option('--shrinkwrap', 'make shrinkwrap.json')
        .parse(process.argv)

    const {prefix, branch, shrinkwrap} = program

    // get version
    const ver = checkReleasability()
    const version = prefix + ver

    // release
    const executor = new ReleaseExecutor()
    const result = executor.release(version, shrinkwrap, branch)
    if (result) {
        console.log(chalk.green(`The tag "${version}" was successfully released.`))
    }
    else {
        const { CIRCLE_PROJECT_USERNAME, CIRCLE_PROJECT_REPONAME } = process.env
        console.log(chalk.red(SHOW_HOW_TO_RELEASE_IN_CIRCLE_CI(CIRCLE_PROJECT_USERNAME, CIRCLE_PROJECT_REPONAME)))
        process.exit(0)
    }

    // npm publish
    const {NPM_EMAIL, NPM_AUTH} = process.env
    if (NPM_EMAIL && NPM_AUTH) {
        executor.publishNpm(NPM_EMAIL, NPM_AUTH)
    }
    else {
        const { CIRCLE_PROJECT_USERNAME, CIRCLE_PROJECT_REPONAME } = process.env
        console.log(SHOW_HOW_TO_NPM_PUBLISH(CIRCLE_PROJECT_USERNAME, CIRCLE_PROJECT_REPONAME))
    }
}

const SHOW_HOW_TO_RELEASE_IN_CIRCLE_CI = (userName: string, repoName: string): string => `
----------------------------------------------------------------------
    Release failed.

    In most cases, it is due to the ssh key registered in CircleCI.
    Check the key have permission to write to github.

    https://circleci.com/gh/${userName}/${repoName}

----------------------------------------------------------------------
`

const SHOW_HOW_TO_NPM_PUBLISH = (userName: string, repoName: string): string => `
-----------------------------------------------------------------------------------------------------
    'npm publish' was not executed as $NPM_AUTH and $NPM_EMAIL environment variables does not exist.

    Set it at
        https://circleci.com/gh/${userName}/${repoName}/edit#checkout

    Name: NPM_AUTH
    Value: (value of '_auth' at your .npmrc after 'npm login')

    Name: NPM_EMAIL
    Value: (your email registered to npm)
-----------------------------------------------------------------------------------------------------
`

function checkReleasability(): ?string {

    const checker = new ReleasabilityChecker()
    const warnMessage = checker.check()

    if (warnMessage) {
        console.error(chalk.yellow(warnMessage))
        process.exit(0)
    }

    return checker.getVersionFromLog()
}

if (require.main === module) run()
<commit_msg>exit(1) when release fails<commit_after>/*eslint no-console: 0 */
// @flow

import program from 'commander'
import chalk from 'chalk'
import ReleasabilityChecker from '../lib/releasability-checker'
import ReleaseExecutor from '../lib/release-executor'

export default function run() {

    program
        .option('--prefix <version prefix>', 'version prefix')
        .option('--branch', 'create branch')
        .option('--shrinkwrap', 'make shrinkwrap.json')
        .parse(process.argv)

    const {prefix, branch, shrinkwrap} = program

    // get version
    const ver = checkReleasability()
    const version = prefix + ver

    // release
    const executor = new ReleaseExecutor()
    const result = executor.release(version, shrinkwrap, branch)
    if (result) {
        console.log(chalk.green(`The tag "${version}" was successfully released.`))
    }
    else {
        const { CIRCLE_PROJECT_USERNAME, CIRCLE_PROJECT_REPONAME } = process.env
        console.log(chalk.red(SHOW_HOW_TO_RELEASE_IN_CIRCLE_CI(CIRCLE_PROJECT_USERNAME, CIRCLE_PROJECT_REPONAME)))
        process.exit(1)
    }

    // npm publish
    const {NPM_EMAIL, NPM_AUTH} = process.env
    if (NPM_EMAIL && NPM_AUTH) {
        executor.publishNpm(NPM_EMAIL, NPM_AUTH)
    }
    else {
        const { CIRCLE_PROJECT_USERNAME, CIRCLE_PROJECT_REPONAME } = process.env
        console.log(SHOW_HOW_TO_NPM_PUBLISH(CIRCLE_PROJECT_USERNAME, CIRCLE_PROJECT_REPONAME))
    }
}

const SHOW_HOW_TO_RELEASE_IN_CIRCLE_CI = (userName: string, repoName: string): string => `
----------------------------------------------------------------------
    Release failed.

    In most cases, it is due to the ssh key registered in CircleCI.
    Check the key have permission to write to github.

    https://circleci.com/gh/${userName}/${repoName}

----------------------------------------------------------------------
`

const SHOW_HOW_TO_NPM_PUBLISH = (userName: string, repoName: string): string => `
-----------------------------------------------------------------------------------------------------
    'npm publish' was not executed as $NPM_AUTH and $NPM_EMAIL environment variables does not exist.

    Set it at
        https://circleci.com/gh/${userName}/${repoName}/edit#checkout

    Name: NPM_AUTH
    Value: (value of '_auth' at your .npmrc after 'npm login')

    Name: NPM_EMAIL
    Value: (your email registered to npm)
-----------------------------------------------------------------------------------------------------
`

function checkReleasability(): ?string {

    const checker = new ReleasabilityChecker()
    const warnMessage = checker.check()

    if (warnMessage) {
        console.error(chalk.yellow(warnMessage))
        process.exit(0)
    }

    return checker.getVersionFromLog()
}

if (require.main === module) run()
<|endoftext|>


<commit_before>"use babel"
// @flow
import type { Info } from "../types"

// TimeCop was reporting that it took over 600ms for js-hyperclick to start.
// Converting this `import` to a `require` reduced it to under 250ms Moving it
// to require inside `findIdentifiers` and `parseCode` moved it off the TimeCop
// list (under 5ms)

/*
import { parse, traverse, types as t } from 'babel-core'
*/

const parseErrorTag = Symbol()

const identifierReducer = (tmp, node) => {
  let value = node
  if (node.value) {
    value = node.value
  }
  const { types: t } = require("babel-core")
  let newIdentifiers
  if (t.isIdentifier(value)) {
    newIdentifiers = [value]
  } else if (t.isObjectPattern(value)) {
    newIdentifiers = findIdentifiers(value)
  } else if (t.isArrayPattern(value)) {
    newIdentifiers = findIdentifiers(value)
  }

  /* istanbul ignore next: If this throws, it's a mistake in my code or an
    /* unsupported syntax */
  if (!newIdentifiers) {
    throw new Error("No identifiers found")
  }

  return [...tmp, ...newIdentifiers]
}
function findIdentifiers(node, identifiers = []) {
  const { types: t } = require("babel-core")

  if (t.isObjectPattern(node)) {
    return node.properties.reduce(identifierReducer, identifiers)
  } else if (t.isArrayPattern(node)) {
    return node.elements.reduce(identifierReducer, identifiers)
  } else if (t.isIdentifier(node)) {
    return [node]
  }
  /* istanbul ignore next */
  throw new Error("Unknown node type")
}

export default function parseCode(code: string): Info {
  const { traverse, types: t } = require("babel-core")
  const { Hub, NodePath } = traverse
  const { parse } = require("babylon")
  let ast = undefined

  try {
    ast = parse(code, {
      sourceType: "module",
      plugins: [
        "jsx",
        "flow",
        "doExpressions",
        "objectRestSpread",
        "decorators",
        "classProperties",
        "exportExtensions",
        "asyncGenerators",
        "functionBind",
        "functionSent",
      ],
    })
  } catch (parseError) {
    /* istanbul ignore next */
    return { parseError }
  }

  // console.log(JSON.stringify(ast, null, 4))

  const scopes = []
  const externalModules = []
  const exports = {}
  const paths = []

  const addModule = (moduleName, identifier, imported = "default") => {
    externalModules.push({
      local: identifier.name,
      start: identifier.start,
      end: identifier.end,
      moduleName,
      imported,
    })
  }
  const addUnboundModule = (
    moduleName,
    identifier,
    imported = identifier.name,
  ) => {
    paths.push({
      imported,
      moduleName,
      range: {
        start: identifier.start,
        end: identifier.end,
      },
    })
  }

  const isModuleDotExports = node =>
    t.isMemberExpression(node) &&
    t.isIdentifier(node.object, { name: "module" }) &&
    t.isIdentifier(node.property, { name: "exports" })

  const visitors = {
    Scope({ scope }) {
      scopes.push(scope)
    },
    CallExpression({ node, parent }) {
      const isRequire = t.isIdentifier(node.callee, { name: "require" })

      const isRequireResolve =
        t.isMemberExpression(node.callee, { computed: false }) &&
        t.isIdentifier(node.callee.object, { name: "require" }) &&
        t.isIdentifier(node.callee.property, { name: "resolve" })

      if (isRequire || isRequireResolve) {
        if (t.isLiteral(node.arguments[0])) {
          let moduleName
          const arg = node.arguments[0]
          if (t.isLiteral(arg)) {
            moduleName = arg.value
          }
          if (
            moduleName == null &&
            t.isTemplateLiteral(arg) &&
            arg.quasis.length === 1
          ) {
            const quasi = arg.quasis[0]
            moduleName = quasi.value.cooked
          }
          const { id } = parent

          if (moduleName != null) {
            if (
              t.isAssignmentExpression(parent) &&
              isModuleDotExports(parent.left)
            ) {
              addUnboundModule(moduleName, parent.left, "default")
            }

            paths.push({
              imported: "default",
              moduleName,
              range: {
                start: node.arguments[0].start,
                end: node.arguments[0].end,
              },
            })

            if (t.isIdentifier(id)) {
              addModule(moduleName, id)
            }
            if (t.isObjectPattern(id) || t.isArrayPattern(id)) {
              findIdentifiers(id).forEach(identifier => {
                addModule(moduleName, identifier)
              })
            }
          }
        }
      }
    },
    ImportDeclaration({ node }) {
      if (t.isLiteral(node.source)) {
        const moduleName = node.source.value
        node.specifiers.forEach(({ local, imported }) => {
          let importedName = "default"
          if (imported != null) {
            addUnboundModule(moduleName, imported)
            importedName = imported.name
          }

          addModule(moduleName, local, importedName)
        })
        paths.push({
          imported: "default",
          moduleName,
          range: {
            start: node.source.start,
            end: node.source.end,
          },
        })
      }
    },
    ExportDefaultDeclaration({ node }) {
      const { declaration } = node

      if (t.isIdentifier(declaration)) {
        exports.default = {
          start: declaration.start,
          end: declaration.end,
        }
        return
      }

      exports.default = {
        start: node.start,
        end: node.end,
      }
    },
    ExportNamedDeclaration({ node }) {
      const { specifiers, declaration } = node

      const moduleName = t.isLiteral(node.source)
        ? node.source.value
        : undefined

      specifiers.forEach(spec => {
        if (t.isExportSpecifier(spec)) {
          const { name, start, end } = spec.exported
          exports[name] = { start, end }

          // export ... from does not create a local binding, so I'm
          // gathering it in the paths. build-suggestion will convert
          // it back to a `from-module`
          if (moduleName && t.isIdentifier(spec.local)) {
            addUnboundModule(moduleName, spec.local)
            // paths.push({
            //     imported: spec.local.name,
            //     moduleName,
            //     range: {
            //         start: spec.local.start,
            //         end: spec.local.end,
            //     }
            // })
          }
        } else if (t.isExportDefaultSpecifier(spec)) {
          const { name, start, end } = spec.exported
          exports[name] = { start, end }

          if (moduleName) {
            paths.push({
              imported: "default",
              moduleName,
              range: {
                start: spec.exported.start,
                end: spec.exported.end,
              },
            })
          }
        }
      })

      if (t.isVariableDeclaration(declaration)) {
        declaration.declarations.forEach(({ id }) => {
          declaration.declarations.forEach
          findIdentifiers(id).forEach(({ name, start, end }) => {
            exports[name] = { start, end }
          })
        })
      }

      if (
        t.isFunctionDeclaration(declaration) ||
        t.isTypeAlias(declaration) ||
        t.isInterfaceDeclaration(declaration)
      ) {
        const { name, start, end } = declaration.id
        exports[name] = { start, end }
      }

      if (moduleName) {
        paths.push({
          imported: "default",
          moduleName,
          range: {
            start: node.source.start,
            end: node.source.end,
          },
        })
      }
    },
    ExportAllDeclaration({ node }) {
      if (t.isLiteral(node.source)) {
        const moduleName = node.source.value
        paths.push({
          imported: "default",
          moduleName,
          range: {
            start: node.source.start,
            end: node.source.end,
          },
        })
      }
    },
    AssignmentExpression({ node }) {
      if (isModuleDotExports(node.left)) {
        exports.default = {
          start: node.left.start,
          end: node.left.end,
        }
      }
    },
  }

  try {
    const hub = new Hub({
      buildCodeFrameError(node, message, Error) {
        const loc = node && (node.loc || node._loc)

        /* istanbul ignore else */
        if (loc) {
          const err = new Error(
            `${message} (${loc.start.line}:${loc.start.column})`,
          )
          err[parseErrorTag] = true
          return err
        } else {
          // Assume if we don't have a location, then it isn't a problem
          // in the user's code and shouldn't be displayed as a parse
          // error.
          return new Error(message)
        }
      },
    })
    const path = NodePath.get({
      hub: hub,
      parentPath: null,
      parent: ast,
      container: ast,
      key: "program",
    }).setContext()

    // On order to capture duplicate declaration errors I have to build a
    // scope to get access to a "hub" that returns the error I need to catch.
    //
    // https://github.com/babel/babel/issues/4640
    traverse(ast, visitors, path.scope)
  } catch (e) {
    /* istanbul ignore else */
    if (e[parseErrorTag]) {
      return { parseError: e }
    } else {
      /* This should never trigger, it just rethrows unexpected errors */
      throw e
    }
  }

  return {
    scopes,
    externalModules,
    exports,
    paths,
  }
}
<commit_msg>Refs #85 Add dynamicImport to the parser options<commit_after>"use babel"
// @flow
import type { Info } from "../types"

// TimeCop was reporting that it took over 600ms for js-hyperclick to start.
// Converting this `import` to a `require` reduced it to under 250ms Moving it
// to require inside `findIdentifiers` and `parseCode` moved it off the TimeCop
// list (under 5ms)

/*
import { parse, traverse, types as t } from 'babel-core'
*/

const parseErrorTag = Symbol()

const identifierReducer = (tmp, node) => {
  let value = node
  if (node.value) {
    value = node.value
  }
  const { types: t } = require("babel-core")
  let newIdentifiers
  if (t.isIdentifier(value)) {
    newIdentifiers = [value]
  } else if (t.isObjectPattern(value)) {
    newIdentifiers = findIdentifiers(value)
  } else if (t.isArrayPattern(value)) {
    newIdentifiers = findIdentifiers(value)
  }

  /* istanbul ignore next: If this throws, it's a mistake in my code or an
    /* unsupported syntax */
  if (!newIdentifiers) {
    throw new Error("No identifiers found")
  }

  return [...tmp, ...newIdentifiers]
}
function findIdentifiers(node, identifiers = []) {
  const { types: t } = require("babel-core")

  if (t.isObjectPattern(node)) {
    return node.properties.reduce(identifierReducer, identifiers)
  } else if (t.isArrayPattern(node)) {
    return node.elements.reduce(identifierReducer, identifiers)
  } else if (t.isIdentifier(node)) {
    return [node]
  }
  /* istanbul ignore next */
  throw new Error("Unknown node type")
}

export default function parseCode(code: string): Info {
  const { traverse, types: t } = require("babel-core")
  const { Hub, NodePath } = traverse
  const { parse } = require("babylon")
  let ast = undefined

  try {
    ast = parse(code, {
      sourceType: "module",
      plugins: [
        "jsx",
        "flow",
        "doExpressions",
        "objectRestSpread",
        "decorators",
        "classProperties",
        "exportExtensions",
        "asyncGenerators",
        "functionBind",
        "functionSent",
        "dynamicImport",
      ],
    })
  } catch (parseError) {
    /* istanbul ignore next */
    return { parseError }
  }

  // console.log(JSON.stringify(ast, null, 4))

  const scopes = []
  const externalModules = []
  const exports = {}
  const paths = []

  const addModule = (moduleName, identifier, imported = "default") => {
    externalModules.push({
      local: identifier.name,
      start: identifier.start,
      end: identifier.end,
      moduleName,
      imported,
    })
  }
  const addUnboundModule = (
    moduleName,
    identifier,
    imported = identifier.name,
  ) => {
    paths.push({
      imported,
      moduleName,
      range: {
        start: identifier.start,
        end: identifier.end,
      },
    })
  }

  const isModuleDotExports = node =>
    t.isMemberExpression(node) &&
    t.isIdentifier(node.object, { name: "module" }) &&
    t.isIdentifier(node.property, { name: "exports" })

  const visitors = {
    Scope({ scope }) {
      scopes.push(scope)
    },
    CallExpression({ node, parent }) {
      const isRequire = t.isIdentifier(node.callee, { name: "require" })

      const isRequireResolve =
        t.isMemberExpression(node.callee, { computed: false }) &&
        t.isIdentifier(node.callee.object, { name: "require" }) &&
        t.isIdentifier(node.callee.property, { name: "resolve" })

      if (isRequire || isRequireResolve) {
        if (t.isLiteral(node.arguments[0])) {
          let moduleName
          const arg = node.arguments[0]
          if (t.isLiteral(arg)) {
            moduleName = arg.value
          }
          if (
            moduleName == null &&
            t.isTemplateLiteral(arg) &&
            arg.quasis.length === 1
          ) {
            const quasi = arg.quasis[0]
            moduleName = quasi.value.cooked
          }
          const { id } = parent

          if (moduleName != null) {
            if (
              t.isAssignmentExpression(parent) &&
              isModuleDotExports(parent.left)
            ) {
              addUnboundModule(moduleName, parent.left, "default")
            }

            paths.push({
              imported: "default",
              moduleName,
              range: {
                start: node.arguments[0].start,
                end: node.arguments[0].end,
              },
            })

            if (t.isIdentifier(id)) {
              addModule(moduleName, id)
            }
            if (t.isObjectPattern(id) || t.isArrayPattern(id)) {
              findIdentifiers(id).forEach(identifier => {
                addModule(moduleName, identifier)
              })
            }
          }
        }
      }
    },
    ImportDeclaration({ node }) {
      if (t.isLiteral(node.source)) {
        const moduleName = node.source.value
        node.specifiers.forEach(({ local, imported }) => {
          let importedName = "default"
          if (imported != null) {
            addUnboundModule(moduleName, imported)
            importedName = imported.name
          }

          addModule(moduleName, local, importedName)
        })
        paths.push({
          imported: "default",
          moduleName,
          range: {
            start: node.source.start,
            end: node.source.end,
          },
        })
      }
    },
    ExportDefaultDeclaration({ node }) {
      const { declaration } = node

      if (t.isIdentifier(declaration)) {
        exports.default = {
          start: declaration.start,
          end: declaration.end,
        }
        return
      }

      exports.default = {
        start: node.start,
        end: node.end,
      }
    },
    ExportNamedDeclaration({ node }) {
      const { specifiers, declaration } = node

      const moduleName = t.isLiteral(node.source)
        ? node.source.value
        : undefined

      specifiers.forEach(spec => {
        if (t.isExportSpecifier(spec)) {
          const { name, start, end } = spec.exported
          exports[name] = { start, end }

          // export ... from does not create a local binding, so I'm
          // gathering it in the paths. build-suggestion will convert
          // it back to a `from-module`
          if (moduleName && t.isIdentifier(spec.local)) {
            addUnboundModule(moduleName, spec.local)
            // paths.push({
            //     imported: spec.local.name,
            //     moduleName,
            //     range: {
            //         start: spec.local.start,
            //         end: spec.local.end,
            //     }
            // })
          }
        } else if (t.isExportDefaultSpecifier(spec)) {
          const { name, start, end } = spec.exported
          exports[name] = { start, end }

          if (moduleName) {
            paths.push({
              imported: "default",
              moduleName,
              range: {
                start: spec.exported.start,
                end: spec.exported.end,
              },
            })
          }
        }
      })

      if (t.isVariableDeclaration(declaration)) {
        declaration.declarations.forEach(({ id }) => {
          declaration.declarations.forEach
          findIdentifiers(id).forEach(({ name, start, end }) => {
            exports[name] = { start, end }
          })
        })
      }

      if (
        t.isFunctionDeclaration(declaration) ||
        t.isTypeAlias(declaration) ||
        t.isInterfaceDeclaration(declaration)
      ) {
        const { name, start, end } = declaration.id
        exports[name] = { start, end }
      }

      if (moduleName) {
        paths.push({
          imported: "default",
          moduleName,
          range: {
            start: node.source.start,
            end: node.source.end,
          },
        })
      }
    },
    ExportAllDeclaration({ node }) {
      if (t.isLiteral(node.source)) {
        const moduleName = node.source.value
        paths.push({
          imported: "default",
          moduleName,
          range: {
            start: node.source.start,
            end: node.source.end,
          },
        })
      }
    },
    AssignmentExpression({ node }) {
      if (isModuleDotExports(node.left)) {
        exports.default = {
          start: node.left.start,
          end: node.left.end,
        }
      }
    },
  }

  try {
    const hub = new Hub({
      buildCodeFrameError(node, message, Error) {
        const loc = node && (node.loc || node._loc)

        /* istanbul ignore else */
        if (loc) {
          const err = new Error(
            `${message} (${loc.start.line}:${loc.start.column})`,
          )
          err[parseErrorTag] = true
          return err
        } else {
          // Assume if we don't have a location, then it isn't a problem
          // in the user's code and shouldn't be displayed as a parse
          // error.
          return new Error(message)
        }
      },
    })
    const path = NodePath.get({
      hub: hub,
      parentPath: null,
      parent: ast,
      container: ast,
      key: "program",
    }).setContext()

    // On order to capture duplicate declaration errors I have to build a
    // scope to get access to a "hub" that returns the error I need to catch.
    //
    // https://github.com/babel/babel/issues/4640
    traverse(ast, visitors, path.scope)
  } catch (e) {
    /* istanbul ignore else */
    if (e[parseErrorTag]) {
      return { parseError: e }
    } else {
      /* This should never trigger, it just rethrows unexpected errors */
      throw e
    }
  }

  return {
    scopes,
    externalModules,
    exports,
    paths,
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
 * Please see distribution for license.
 */
$.register_module({
    name: 'og.views.config_blocks.Scenario',
    dependencies: ['og.common.util.ui.Form'],
    obj: function () {
        var Block = og.common.util.ui.Block, data, constructor = this;
        var Scenario = function (config) {
            var block = this, id = og.common.id('scenario'), form = config.form,
                index = config.index, extras = {id : id},
                template = '<select class="og-scenario-select" id="'
                + index + '"><option value="">Please select...</option></select>';
            data = config.data;
            form.Block.call(block, {
                extras: extras,
                module: 'og.views.forms.view-definition-scenario_tash',
                children: [
                    new form.Block({content: template})
                ]
            });
            form.on('form:load', function () {
                constructor.content();
            });
        };
        constructor.content = function () {
            og.api.rest.configs.get({type: 'ScenarioDefinition'}).pipe(function (result) {
                $('.og-scenario-select').append('<optgroup label="Scenario Definition"></optgroup>');
                result.data.data.map(function (datum) { // search results
                    var fields = datum.split('|');
                    $('.og-scenario-select optgroup[label="Scenario Definition"]').append(
                        $('<option></option>').val(fields[0]).html(fields[1])
                            .attr('selected', fields[0] === data)
                    );
                });
            });
            og.api.rest.configs.get({type: 'ScenarioDslScript'}).pipe(function (result) {
                $('.og-scenario-select').append('<optgroup label="Scenario DSL Script"></optgroup>');
                result.data.data.map(function (datum) { // search results
                    var fields = datum.split('|');
                    $('.og-scenario-select optgroup[label="Scenario DSL Script"]').append(
                        $('<option></option>').val(fields[0]).html(fields[1])
                            .attr('selected', fields[0] === data)
                    );
                });
            });
        };
        Scenario.prototype = new Block(); // inherit Block prototype
        return Scenario;
    }
});<commit_msg>[GUI-326] reverted back to scenario script only<commit_after>/*
 * Copyright 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
 * Please see distribution for license.
 */
$.register_module({
    name: 'og.views.config_blocks.Scenario',
    dependencies: ['og.common.util.ui.Form'],
    obj: function () {
        var Block = og.common.util.ui.Block;
        var Scenario = function (config) {
            var block = this, id = og.common.id('scenario'), form = config.form, data = config.data,
                index = config.index, extras = {id : id};
            form.Block.call(block, {
                extras: extras,
                module: 'og.views.forms.view-definition-scenario_tash',
                children: [
                    new og.common.util.ui.Dropdown({ form: form, resource: 'configs', index: index,
                        placeholder: 'Please select....',  value: data, fields: [0, 1],
                        rest_options : {type: 'ScenarioDslScript' }
                        })
                ]
            });
        };
        Scenario.prototype = new Block(); // inherit Block prototype
        return Scenario;
    }
});<|endoftext|>


<commit_before>// Load in our dependencies
var assert = require('assert');
var fs = require('fs');
var async = require('async');
var NodeCanvas = require('canvas');
var Image = NodeCanvas.Image;
var engine = {};

// Define our canvas for drawing images on
function Canvas(width, height) {
  var canvas = new NodeCanvas(width, height);
  var ctx = canvas.getContext('2d');
  this.canvas = canvas;
  this.ctx = ctx;
}
Canvas.exportPngCanvas = function (canvas, options) {
  return canvas.createPNGStream();
};
Canvas.exportJpegCanvas = function (canvas, options) {
  return canvas.createJPEGStream();
};
Canvas.formatToCanvasFnMap = {
  png: Canvas.exportPngCanvas,
  'image/png': Canvas.exportPngCanvas,
  jpg: Canvas.exportJpegCanvas,
  jpeg: Canvas.exportJpegCanvas,
  'image/jpg': Canvas.exportJpegCanvas,
  'image/jpeg': Canvas.exportJpegCanvas
};
Canvas.prototype = {
  addImage: function (img, x, y, cb) {
    var ctx = this.ctx;
    ctx.drawImage(img, x, y, img.width, img.height);
  },
  /**
   * @param {Object} options Options for export
   * @param {String} options.format Format to export as
   * @param {Function}
   */
  'export': function (options, cb) {
    // Find the matching canvas method
    var format = options.format || 'png';
    var exportFn = Canvas.formatToCanvasFnMap[format];
    assert(exportFn, '`canvassmith` doesn\'t support exporting "' + format + '". Please use "jpeg" or "png"');

    // Stream out the image to a binary string and callback
    var imgStream = exportFn(this.canvas, options);
    imgStream.on('error', cb);
    imgStream.pipe(concat(function handleBuff (imgBuff) {
      cb(null, imgBuff.toString('binary'));
    });
  }
};

// Expose Canvas to engine
engine.Canvas = Canvas;

// Define a method for creating a canvas
function createCanvas(width, height, cb) {
  var canvas = new Canvas(width, height);
  process.nextTick(function handleNextTick () {
    cb(null, canvas);
  });
}
engine.createCanvas = createCanvas;

// Write out Image as a static property of engine
function createImage(file, cb) {
  async.waterfall([
    function readImageFile (cb) {
      // Read in the file as a buffer
      fs.readFile(file, cb);
    },
    function createImageFn (imgBuffer, cb) {
      // Create an image object with the proper source file
      var img = new Image();
      img.src = imgBuffer;

      // Callback with the image
      cb(null, img);
    }
  ], cb);
}
function createImages(files, cb) {
  async.map(files, createImage, cb);
}
engine.createImage = createImage;
engine.createImages = createImages;

// Export the canvas
module.exports = engine;
<commit_msg>Added missing concat<commit_after>// Load in our dependencies
var assert = require('assert');
var fs = require('fs');
var async = require('async');
var concat = require('concat-stream');
var NodeCanvas = require('canvas');
var Image = NodeCanvas.Image;
var engine = {};

// Define our canvas for drawing images on
function Canvas(width, height) {
  var canvas = new NodeCanvas(width, height);
  var ctx = canvas.getContext('2d');
  this.canvas = canvas;
  this.ctx = ctx;
}
Canvas.exportPngCanvas = function (canvas, options) {
  return canvas.createPNGStream();
};
Canvas.exportJpegCanvas = function (canvas, options) {
  return canvas.createJPEGStream();
};
Canvas.formatToCanvasFnMap = {
  png: Canvas.exportPngCanvas,
  'image/png': Canvas.exportPngCanvas,
  jpg: Canvas.exportJpegCanvas,
  jpeg: Canvas.exportJpegCanvas,
  'image/jpg': Canvas.exportJpegCanvas,
  'image/jpeg': Canvas.exportJpegCanvas
};
Canvas.prototype = {
  addImage: function (img, x, y, cb) {
    var ctx = this.ctx;
    ctx.drawImage(img, x, y, img.width, img.height);
  },
  /**
   * @param {Object} options Options for export
   * @param {String} options.format Format to export as
   * @param {Function}
   */
  'export': function (options, cb) {
    // Find the matching canvas method
    var format = options.format || 'png';
    var exportFn = Canvas.formatToCanvasFnMap[format];
    assert(exportFn, '`canvassmith` doesn\'t support exporting "' + format + '". Please use "jpeg" or "png"');

    // Stream out the image to a binary string and callback
    var imgStream = exportFn(this.canvas, options);
    imgStream.on('error', cb);
    imgStream.pipe(concat(function handleBuff (imgBuff) {
      cb(null, imgBuff.toString('binary'));
    }));
  }
};

// Expose Canvas to engine
engine.Canvas = Canvas;

// Define a method for creating a canvas
function createCanvas(width, height, cb) {
  var canvas = new Canvas(width, height);
  process.nextTick(function handleNextTick () {
    cb(null, canvas);
  });
}
engine.createCanvas = createCanvas;

// Write out Image as a static property of engine
function createImage(file, cb) {
  async.waterfall([
    function readImageFile (cb) {
      // Read in the file as a buffer
      fs.readFile(file, cb);
    },
    function createImageFn (imgBuffer, cb) {
      // Create an image object with the proper source file
      var img = new Image();
      img.src = imgBuffer;

      // Callback with the image
      cb(null, img);
    }
  ], cb);
}
function createImages(files, cb) {
  async.map(files, createImage, cb);
}
engine.createImage = createImage;
engine.createImages = createImages;

// Export the canvas
module.exports = engine;
<|endoftext|>


<commit_before>/**
 * Sitespeed.io - How speedy is your site? (http://www.sitespeed.io)
 * Copyright (c) 2014, Peter Hedenskog, Tobias Lidskog
 * and other contributors
 * Released under the Apache 2.0 License
 */
'use strict';

var spawn = require('cross-spawn'),
  path = require('path'),
  urlParser = require('url'),
  winston = require('winston'),
  EOL = require('os').EOL,
  fs = require('fs'),
  async = require('async');

module.exports.crawl = function(url, config, callback) {
  var pUrl, args = [
    '-Xmx' + config.memory + 'm',
    '-Xms' + config.memory + 'm'
  ];

  var log = winston.loggers.get('sitespeed.io');
  var urlFile = path.join(config.run.absResultDir, 'urls.txt');
  var errorUrlFile = path.join(config.run.absResultDir, 'errorurls.txt');

  if (config.basicAuth) {
    pUrl = urlParser.parse(url);
    var port = pUrl.port || 80;
    if (pUrl.protocol === 'https:') {
      port = 443;
    }
    args.push('-Dcom.soulgalore.crawler.auth=' + pUrl.hostname + ':' + port + ':' + config.basicAuth);
  }
  if (config.proxy) {
    pUrl = urlParser.parse(config.proxy);
    args.push('-Dcom.soulgalore.crawler.proxy=' + pUrl.protocol + pUrl.host);
  }

  var requestHeaders = '';
  // add extra request headers
  if (config.requestHeaders) {
    Object.keys(config.requestHeaders).forEach(function (key) {
      requestHeaders += key + ':' + config.requestHeaders[key] + '@';
    });
  }

  args.push('-cp',
    path.join(__dirname, 'crawler-1.5.14-full.jar'),
    'com.soulgalore.crawler.run.CrawlToFile',
    '-u',
    config.url,
    '-l',
    config.deep,
    '-f',
    urlFile,
    '-ef',
    errorUrlFile,
    '-rh',
    requestHeaders + 'User-Agent:' + config.userAgent);

  if (config.containInPath) {
    args.push('-p', config.containInPath);
  }

  if (config.skip) {
    args.push('-np', config.skip);
  }

  var crawl = spawn('java', args);

  crawl.stdout.on('data', function(data) {
    log.info('Output from the crawl: %s', data.toString());
  });

  crawl.stderr.on('data', function(data) {
    var s = data.toString();
    // JAVA_TOOL_OPTIONS is not an error, but still written to stderr.
    if (s.indexOf('Picked up JAVA_TOOL_OPTIONS:') === 0) {
      return;
    }
    log.error('Error from the crawl: %s', s);
  });

  crawl.on('close', function(code) {
    // the crawler always return code ok today, hmm
    var okUrls = [];
    var errorUrls = {};

    async.parallel([
            function(cb) {
              // Url file might be non-existing, in case of no successful urls
              fs.readFile(urlFile, function(err, data) {
                if (!err) {
                  okUrls = data.toString().split(EOL);
                  okUrls.pop();
                }

                return cb();
              });
            },
          function(cb) {
            // Error file might be non-existing, in case of no errors
            fs.readFile(errorUrlFile, function(err, data) {
              if (!err) {
                data.toString().split(EOL).forEach(function(theUrl) {
                  if (theUrl) {
                    var urlAndReason = theUrl.split(',');
                    errorUrls[urlAndReason[1]] = urlAndReason[0];
                  }
                });
              }

              return cb();
            });
          }
        ],
        function() {
          return callback(okUrls, errorUrls);
        });
  });
  };
<commit_msg>changed cross spawn<commit_after>/**
 * Sitespeed.io - How speedy is your site? (http://www.sitespeed.io)
 * Copyright (c) 2014, Peter Hedenskog, Tobias Lidskog
 * and other contributors
 * Released under the Apache 2.0 License
 */
'use strict';

var spawn = require('cross-spawn-async'),
  path = require('path'),
  urlParser = require('url'),
  winston = require('winston'),
  EOL = require('os').EOL,
  fs = require('fs'),
  async = require('async');

module.exports.crawl = function(url, config, callback) {
  var pUrl, args = [
    '-Xmx' + config.memory + 'm',
    '-Xms' + config.memory + 'm'
  ];

  var log = winston.loggers.get('sitespeed.io');
  var urlFile = path.join(config.run.absResultDir, 'urls.txt');
  var errorUrlFile = path.join(config.run.absResultDir, 'errorurls.txt');

  if (config.basicAuth) {
    pUrl = urlParser.parse(url);
    var port = pUrl.port || 80;
    if (pUrl.protocol === 'https:') {
      port = 443;
    }
    args.push('-Dcom.soulgalore.crawler.auth=' + pUrl.hostname + ':' + port + ':' + config.basicAuth);
  }
  if (config.proxy) {
    pUrl = urlParser.parse(config.proxy);
    args.push('-Dcom.soulgalore.crawler.proxy=' + pUrl.protocol + pUrl.host);
  }

  var requestHeaders = '';
  // add extra request headers
  if (config.requestHeaders) {
    Object.keys(config.requestHeaders).forEach(function (key) {
      requestHeaders += key + ':' + config.requestHeaders[key] + '@';
    });
  }

  args.push('-cp',
    path.join(__dirname, 'crawler-1.5.14-full.jar'),
    'com.soulgalore.crawler.run.CrawlToFile',
    '-u',
    config.url,
    '-l',
    config.deep,
    '-f',
    urlFile,
    '-ef',
    errorUrlFile,
    '-rh',
    requestHeaders + 'User-Agent:' + config.userAgent);

  if (config.containInPath) {
    args.push('-p', config.containInPath);
  }

  if (config.skip) {
    args.push('-np', config.skip);
  }

  var crawl = spawn('java', args);

  crawl.stdout.on('data', function(data) {
    log.info('Output from the crawl: %s', data.toString());
  });

  crawl.stderr.on('data', function(data) {
    var s = data.toString();
    // JAVA_TOOL_OPTIONS is not an error, but still written to stderr.
    if (s.indexOf('Picked up JAVA_TOOL_OPTIONS:') === 0) {
      return;
    }
    log.error('Error from the crawl: %s', s);
  });

  crawl.on('close', function(code) {
    // the crawler always return code ok today, hmm
    var okUrls = [];
    var errorUrls = {};

    async.parallel([
            function(cb) {
              // Url file might be non-existing, in case of no successful urls
              fs.readFile(urlFile, function(err, data) {
                if (!err) {
                  okUrls = data.toString().split(EOL);
                  okUrls.pop();
                }

                return cb();
              });
            },
          function(cb) {
            // Error file might be non-existing, in case of no errors
            fs.readFile(errorUrlFile, function(err, data) {
              if (!err) {
                data.toString().split(EOL).forEach(function(theUrl) {
                  if (theUrl) {
                    var urlAndReason = theUrl.split(',');
                    errorUrls[urlAndReason[1]] = urlAndReason[0];
                  }
                });
              }

              return cb();
            });
          }
        ],
        function() {
          return callback(okUrls, errorUrls);
        });
  });
  };
<|endoftext|>


<commit_before>/* jshints esversion: 5 */
/* globals Map: false, Set: false, module: false, exports: false, Object: false */
(function (root) {
    "use strict";

    var MAP_SUPPORT         = typeof Map !== 'undefined';
    var SET_SUPPORT         = typeof Set !== 'undefined';
    var ARRAYBUFFER_SUPPORT = typeof ArrayBuffer !== 'undefined';
    var DATAVIEW_SUPPORT    = typeof DataView !== 'undefined';
    var NOT_EQUAL           = 0;
    var VALUE               = 1;
    var VALUE_AND_TYPE      = 2;
    var PROPERTIES          = 3;
    var PROPERTIES_AND_TYPE = 4;
    var OBJECT              = 5;
    var FUNCTION            = 6;

    function equal(a, b, options) {
        var aStack = [],                                                // Stack array
            bStack = [];
        options = options || {};                                        // Optional parameter
        return (function check(a, b) {
            var aValue, bValue, aKeys, bKeys, i,                        // Define variables
                aDescriptor, bDescriptor,
                aType = typeof a,                                       // Get value types
                bType = typeof b;
            if (a === b) {                                              // Strict comparison
                if (aType === 'object' && a !== null) {
                    return OBJECT;                                      // Equal object
                } else if (aType === 'function') {
                    return FUNCTION;                                    // Equal function
                }
            return VALUE_AND_TYPE;                                      // Equal value and type
            }
            /* jshint -W116 */
            if (options.nonStrict && a == b) {                          // Non strict comparison (optional)
                return VALUE;                                           // Equal value (different type)
            }
            /* jshint +W116 */
            if (aType === 'undefined' ||                                // undefined and null are always different
                bType === 'undefined' ||
                a === null ||
                b === null)
            {
                return NOT_EQUAL;
            }
            if (aType === 'number' &&                                   // Special case: Not is a Number (NaN !== NaN)
                bType === 'number' &&
                isNaN(a) &&
                isNaN(b))
            {
                return VALUE_AND_TYPE;
            }
            if (typeof a.valueOf === 'function' &&                      // valueOf() is a function in both values
                typeof b.valueOf === 'function')
            {
                aValue = a.valueOf();                                   // Get valueOf()
                bValue = b.valueOf();
                if (aValue !== a || bValue !== b) {                     // The valueOf's return is different that the base value
                    if (aValue === bValue) {                            // The valueOf's return is the same for both values
                        if (a.constructor === b.constructor) {          // It's the same constructor and as result is the same type
                            return VALUE_AND_TYPE;
                        }
                        if (options.nonStrict) {                        // Non strict comparison (optional)
                            return VALUE;                               // Equal value (different type)
                        }
                        return NOT_EQUAL;                               // Strict comparison
                    }
                    /* jshint -W116 */
                    if (options.nonStrict &&                            // Non strict comparison (optional)
                        aValue == bValue)
                    {
                        return VALUE;                                   // Equal value (different type)
                    }
                    /* jshint +W116 */
                    return NOT_EQUAL;                                   // Not equal
                }
            }
            if (aType !== bType) {                                      // Different type is a not equal value from this point
                return NOT_EQUAL;
            }
            if (aType === 'object' ||                                   // Objects
                aType === 'function')                                   // and functions
            {
                if (aStack.indexOf(a) > -1 &&                           // Check if the object has been previously processed
                    bStack.indexOf(b) > -1)
                {
                    return OBJECT;
                }
                aKeys = getProperties(a, options);                      // Get properties with options
                bKeys = getProperties(b, options);
                if (aKeys.length !== bKeys.length) {                    // Check number of properties
                    return NOT_EQUAL;
                }
                if (aKeys.length > 0) {
                    if (aKeys.join('') !== bKeys.join('') &&                // Check name of properties
                        aKeys.sort().join('') !== bKeys.sort().join(''))
                    {
                        return NOT_EQUAL;
                    }
                    aStack.push(a);                                         // Storage objects into stacks for recursive reference
                    bStack.push(b);
                    i = aKeys.length;
                    while (i--) {                                           // Check each property value (recursive call)
                        if (!check(a[aKeys[i]], b[bKeys[i]])) {
                            return NOT_EQUAL;
                        }
                        if (options.checkPropertyDescritors) {              // Check property descriptor (optional)
                            aDescriptor = Object.getOwnPropertyDescriptor(a, aKeys[i]);
                            bDescriptor = Object.getOwnPropertyDescriptor(b, bKeys[i]);
                            if (!aDescriptor && !bDescriptor && options.allProperties) {
                                continue;
                            }
                            if (aDescriptor.enumerable !== bDescriptor.enumerable ||
                                aDescriptor.writable !== bDescriptor.writable ||
                                aDescriptor.configurable !== bDescriptor.configurable) {
                                return NOT_EQUAL;
                            }
                        }
                    }
                }
                if (( a instanceof RegExp && b instanceof RegExp ) ||   // RegExp and Error family objects
                    ( a instanceof Error && b instanceof Error  ))
                {
                    if (a.toString() !== b.toString()) {
                        return NOT_EQUAL;
                    }
                } else if ((MAP_SUPPORT &&                              // Map
                            a instanceof Map && a.keys && a.values &&
                            b instanceof Map &&  b.keys &&  b.values) ||
                           (SET_SUPPORT &&                              // Set
                            a instanceof Set && a.values &&
                            b instanceof Set && b.values))
                {
                    if (a.size !== b.size) {                            // Check size
                        return NOT_EQUAL;
                    }
                    if (a.size > 0) {
                        if (a instanceof Map && b instanceof Map) {
                            aKeys = Array.from(a.keys()).sort();
                            bKeys = Array.from(b.keys()).sort();
                            i = aKeys.length;
                            while (i--) {
                                if (aKeys[i] !== bKeys[i]) {
                                    return NOT_EQUAL;
                                }
                            }
                        }
                        if (check(Array.from(a.entries()).sort(), Array.from(b.entries()).sort())) {
                            return VALUE_AND_TYPE;
                        }
                        return NOT_EQUAL;
                    }
                } else if (ARRAYBUFFER_SUPPORT && DATAVIEW_SUPPORT &&   // ArrayBuffer
                           a instanceof ArrayBuffer && b instanceof ArrayBuffer)
                {
                    aValue = new DataView(a);                           // Get DataView
                    bValue = new DataView(b);
                    if (aValue.byteLength !== bValue.byteLength) {      // Check size
                        return NOT_EQUAL;
                    }
                    i = bValue.byteLength;                              // Check content
                    while (i--) {
                        if (aValue.getInt8(i) !== bValue.getInt8(i)) {  // nonStrict comparison is not supported
                            return NOT_EQUAL;
                        }
                    }
                } else if ((aType === 'function')) {                    // Function type
                    if (options.functionSource && a.toString() === b.toString()) {
                        return FUNCTION;
                    }
                    return NOT_EQUAL;
                }
                if (a.constructor === b.constructor) {                  // It's the same constructor
                    return PROPERTIES_AND_TYPE;                         // and as result is the same type
                }
                if (options.nonStrict) {                                // Non strict comparison (optional)
                    return PROPERTIES;                                  // Equals property and different type
                }
            }
            return NOT_EQUAL;                                           // Not equal
        })(a, b);
    }
    equal.NOT_EQUAL           = NOT_EQUAL           ;
    equal.VALUE               = VALUE               ;
    equal.VALUE_AND_TYPE      = VALUE_AND_TYPE      ;
    equal.PROPERTIES          = PROPERTIES          ;
    equal.PROPERTIES_AND_TYPE = PROPERTIES_AND_TYPE ;
    equal.OBJECT              = OBJECT              ;
    equal.FUNCTION            = FUNCTION            ;

    // get object properties with different scope
    function getProperties(obj, options) {
        var result = [], prop;
        if (!options.nonEnumerableProperties &&                         // General case, own enumerable properties
            !options.allProperties)
        {
            for (prop in obj) {
                if (Object.prototype.hasOwnProperty.call(obj, prop) &&
                    !(prop[0] === '_' && !options.privateProperties))
                {
                    result.push(prop);
                }
            }
            return result;
        }
        return (
            options.allProperties  ?                                    // All properties
                (function getAllProp(obj) {
                    var proto = Object.getPrototypeOf(obj);
                    return (
                        typeof proto === 'object' && proto !== null ?
                            getAllProp(proto) :
                            []
                    ).concat( Object.getOwnPropertyNames(obj) );
                })(obj).sort() :
                Object.getOwnPropertyNames(obj)                         // All own properties (enumerable and nonenumerable)
        ).filter( function(prop, pos, arr) {
            if (prop[0] === '_' && !options.privateProperties) {
                return false;                                           // Filter private properties (_)
            }
            return (!options.allProperties ||                           // Eliminate duplicates
                    pos === 0 || arr[pos - 1] !== prop);
        });
    }

    // Export for node and browser
    if (typeof exports !== 'undefined') {
        if (typeof module !== 'undefined' && module.exports) {
            module.exports = equal;
        }
        exports.equal = equal;
    } else {
        root.equal = equal;
    }

})(this);<commit_msg>More optimization<commit_after>/* jshints esversion: 5 */
/* globals Map: false, Set: false, module: false, exports: false, Object: false */
(function (root) {
    "use strict";

    var MAP_SUPPORT         = typeof Map !== 'undefined';
    var SET_SUPPORT         = typeof Set !== 'undefined';
    var ARRAYBUFFER_SUPPORT = typeof ArrayBuffer !== 'undefined';
    var DATAVIEW_SUPPORT    = typeof DataView !== 'undefined';
    var NOT_EQUAL           = 0;
    var VALUE               = 1;
    var VALUE_AND_TYPE      = 2;
    var PROPERTIES          = 3;
    var PROPERTIES_AND_TYPE = 4;
    var OBJECT              = 5;
    var FUNCTION            = 6;

    function equal(a, b, options) {
        var aStack = [],                                                // Stack array
            bStack = [];
        options = options || {};                                        // Optional parameter
        return (function check(a, b) {
            var aValue, bValue, aKeys, bKeys, key, i,                   // Define variables
                aDescriptor, bDescriptor,
                aType = typeof a,                                       // Get value types
                bType = typeof b;
            if (a === b) {                                              // Strict comparison
                if (aType === 'object' && a !== null) {
                    return OBJECT;                                      // Equal object
                } else if (aType === 'function') {
                    return FUNCTION;                                    // Equal function
                }
            return VALUE_AND_TYPE;                                      // Equal value and type
            }
            /* jshint -W116 */
            if (options.nonStrict && a == b) {                          // Non strict comparison (optional)
                return VALUE;                                           // Equal value (different type)
            }
            /* jshint +W116 */
            if (aType === 'undefined' ||                                // undefined and null are always different
                bType === 'undefined' ||
                a === null ||
                b === null)
            {
                return NOT_EQUAL;
            }
            if (aType === 'number' &&                                   // Special case: Not is a Number (NaN !== NaN)
                bType === 'number' &&
                isNaN(a) &&
                isNaN(b))
            {
                return VALUE_AND_TYPE;
            }
            if (typeof a.valueOf === 'function' &&                      // valueOf() is a function in both values
                typeof b.valueOf === 'function')
            {
                aValue = a.valueOf();                                   // Get valueOf()
                bValue = b.valueOf();
                if (aValue !== a || bValue !== b) {                     // The valueOf's return is different that the base value
                    if (aValue === bValue) {                            // The valueOf's return is the same for both values
                        if (a.constructor === b.constructor) {          // It's the same constructor and as result is the same type
                            return VALUE_AND_TYPE;
                        }
                        if (options.nonStrict) {                        // Non strict comparison (optional)
                            return VALUE;                               // Equal value (different type)
                        }
                        return NOT_EQUAL;                               // Strict comparison
                    }
                    /* jshint -W116 */
                    if (options.nonStrict &&                            // Non strict comparison (optional)
                        aValue == bValue)
                    {
                        return VALUE;                                   // Equal value (different type)
                    }
                    /* jshint +W116 */
                    return NOT_EQUAL;                                   // Not equal
                }
            }
            if (aType !== bType) {                                      // Different type is a not equal value from this point
                return NOT_EQUAL;
            }
            if (aType === 'object' ||                                   // Objects
                aType === 'function')                                   // and functions
            {
                if (aStack.indexOf(a) > -1 &&                           // Check if the object has been previously processed
                    bStack.indexOf(b) > -1)
                {
                    return OBJECT;
                }
                aKeys = getProperties(a, options);                      // Get properties with options
                bKeys = getProperties(b, options);
                if (aKeys.length !== bKeys.length) {                    // Check number of properties
                    return NOT_EQUAL;
                }
                if (aKeys.length > 0) {
                    aStack.push(a);                                         // Storage objects into stacks for recursive reference
                    bStack.push(b);
                    i = aKeys.length;
                    while (i--) {                                           // Check each property value (recursive call)
                        key = aKeys[i];
                        if (!check(a[key], b[key])) {
                            return NOT_EQUAL;
                        }
                        if (options.checkPropertyDescritors) {              // Check property descriptor (optional)
                            aDescriptor = Object.getOwnPropertyDescriptor(a, key);
                            bDescriptor = Object.getOwnPropertyDescriptor(b, key);
                            if (!aDescriptor && !bDescriptor && options.allProperties) {
                                continue;
                            }
                            if (aDescriptor.enumerable !== bDescriptor.enumerable ||
                                aDescriptor.writable !== bDescriptor.writable ||
                                aDescriptor.configurable !== bDescriptor.configurable) {
                                return NOT_EQUAL;
                            }
                        }
                    }
                }
                if (( a instanceof RegExp && b instanceof RegExp ) ||   // RegExp and Error family objects
                    ( a instanceof Error && b instanceof Error  ))
                {
                    if (a.toString() !== b.toString()) {
                        return NOT_EQUAL;
                    }
                } else if ((MAP_SUPPORT &&                              // Map
                            a instanceof Map && a.keys && a.values &&
                            b instanceof Map &&  b.keys &&  b.values) ||
                           (SET_SUPPORT &&                              // Set
                            a instanceof Set && a.values &&
                            b instanceof Set && b.values))
                {
                    if (a.size !== b.size) {                            // Check size
                        return NOT_EQUAL;
                    }
                    i = a.size;
                    if (i > 0) {
                        if (a instanceof Map && b instanceof Map) {
                            aKeys = Array.from(a.keys()).sort();
                            bKeys = Array.from(b.keys()).sort();
                            while (i--) {
                                if (aKeys[i] !== bKeys[i]) {
                                    return NOT_EQUAL;
                                }
                            }
                        }
                        if (check(Array.from(a.entries()).sort(), Array.from(b.entries()).sort())) {
                            return VALUE_AND_TYPE;
                        }
                        return NOT_EQUAL;
                    }
                } else if (ARRAYBUFFER_SUPPORT && DATAVIEW_SUPPORT &&   // ArrayBuffer
                           a instanceof ArrayBuffer && b instanceof ArrayBuffer)
                {
                    aValue = new DataView(a);                           // Get DataView
                    bValue = new DataView(b);
                    if (aValue.byteLength !== bValue.byteLength) {      // Check size
                        return NOT_EQUAL;
                    }
                    i = bValue.byteLength;                              // Check content
                    while (i--) {
                        if (aValue.getInt8(i) !== bValue.getInt8(i)) {  // nonStrict comparison is not supported
                            return NOT_EQUAL;
                        }
                    }
                } else if ((aType === 'function')) {                    // Function type
                    if (options.functionSource && a.toString() === b.toString()) {
                        return FUNCTION;
                    }
                    return NOT_EQUAL;
                }
                if (a.constructor === b.constructor) {                  // It's the same constructor
                    return PROPERTIES_AND_TYPE;                         // and as result is the same type
                }
                if (options.nonStrict) {                                // Non strict comparison (optional)
                    return PROPERTIES;                                  // Equals property and different type
                }
            }
            return NOT_EQUAL;                                           // Not equal
        })(a, b);
    }
    equal.NOT_EQUAL           = NOT_EQUAL           ;
    equal.VALUE               = VALUE               ;
    equal.VALUE_AND_TYPE      = VALUE_AND_TYPE      ;
    equal.PROPERTIES          = PROPERTIES          ;
    equal.PROPERTIES_AND_TYPE = PROPERTIES_AND_TYPE ;
    equal.OBJECT              = OBJECT              ;
    equal.FUNCTION            = FUNCTION            ;

    // get object properties with different scope
    function getProperties(obj, options) {
        var result = [], prop;
        if (!options.nonEnumerableProperties &&                         // General case, own enumerable properties
            !options.allProperties)
        {
            for (prop in obj) {
                if (Object.prototype.hasOwnProperty.call(obj, prop) &&
                    !(prop[0] === '_' && !options.privateProperties))
                {
                    result.push(prop);
                }
            }
            return result;
        }
        return (
            options.allProperties  ?                                    // All properties
                (function getAllProp(obj) {
                    var proto = Object.getPrototypeOf(obj);
                    return (
                        typeof proto === 'object' && proto !== null ?
                            getAllProp(proto) :
                            []
                    ).concat( Object.getOwnPropertyNames(obj) );
                })(obj).sort() :
                Object.getOwnPropertyNames(obj)                         // All own properties (enumerable and nonenumerable)
        ).filter( function(prop, pos, arr) {
            if (prop[0] === '_' && !options.privateProperties) {
                return false;                                           // Filter private properties (_)
            }
            return (!options.allProperties ||                           // Eliminate duplicates
                    pos === 0 || arr[pos - 1] !== prop);
        });
    }

    // Export for node and browser
    if (typeof exports !== 'undefined') {
        if (typeof module !== 'undefined' && module.exports) {
            module.exports = equal;
        }
        exports.equal = equal;
    } else {
        root.equal = equal;
    }

})(this);<|endoftext|>


<commit_before>(function() {
	var ThreeGroupPlugin = E2.plugins.three_group = function(core, node) {
		ThreeObject3DPlugin.apply(this, arguments)

		this.node = node

		this.desc = 'Group several object3ds together so that they can be manipulated as one'

		this.input_slots = [].concat(this.input_slots)

		this.lsg = new AutoSlotGroup(core, node, [], [])
		this.lsg.set_dt(core.datatypes.OBJECT3D)

		var that = this

		this.node.on('slotAdded', function () {
			that.dynInputs = node.getDynamicInputSlots()
			that.updated = true
		})

		this.node.on('slotRemoved', function () {
			that.dynInputs = node.getDynamicInputSlots()
			that.updated = true
		})

		this.object3d = new THREE.Group()
		this.object3d.name = 'group_plugin'
		this.object3d.backReference = this

		this.lastCenter = new THREE.Vector3()
	}

	ThreeGroupPlugin.prototype = Object.create(ThreeObject3DPlugin.prototype)

	ThreeGroupPlugin.prototype.update_input = function(slot, data) {
		if (slot.dynamic) {
			var parent = this.object3d.children[slot.index]

			if (data) {
				if (slot.array) {
					parent.children = data

					for (var i = 0; i < data.length; ++i) {
						if (data[i].parent && data[i].parent !== parent) {
							// the object is in another scene, remove from there
							data[i].parent.remove(data[i])
						}

						data[i].parent = parent
						data[i].dispatchEvent({type: 'added'})
					}
				}
				else {
					if (data.parent && data.parent !== this) {
						// the objects is in another scene, remove from there
						data.parent.remove(data)
					}

					parent.children = [data]

					data.parent = parent
					data.dispatchEvent({type: 'added'})
				}
			}
			else {
				while (parent.children.length > 0) {
					parent.remove(parent.children[0])
				}
			}

			this.pivotNeedsUpdate = true
		}
		else {
			ThreeObject3DPlugin.prototype.update_input.apply(this, arguments)
		}
	}

	ThreeGroupPlugin.prototype.update_state = function() {
		if (this.pivotNeedsUpdate) {
			this.updatePivot()
		}

		ThreeObject3DPlugin.prototype.update_state.apply(this, arguments)
	}

	ThreeGroupPlugin.prototype.connection_changed = function(on, conn, slot) {
		if (on && slot.dynamic) {
			// ensure there is a sufficient amount of slots
			while (this.object3d.children.length < this.dynInputs.length) {
				this.object3d.add(new THREE.Group())
			}
		}

		// disconnect
		if (!on && slot.type === E2.slot_type.input && slot.dynamic) {
			var parent = this.object3d.children[slot.index]

			while (parent.children.length > 0) {
				parent.remove(parent.children[0])
			}
		}

		// connect
		else if (on && slot.type === E2.slot_type.input && slot.dynamic) {
			this.object3d.children[slot.index].children = []
		}

		this.pivotNeedsUpdate = true
	}

	ThreeGroupPlugin.prototype.state_changed = function(ui) {
		if (ui) {
			return
		}

		this.dynInputs = this.node.getDynamicInputSlots()

		if (!this.dynInputs.length) {
			this.node.add_slot(E2.slot_type.input, {
				name: '0',
				dt: E2.dt.OBJECT3D,
				array: false
			})

			this.dynInputs = this.node.getDynamicInputSlots()
		}

		for(var i = 0, len = this.dynInputs.length; i < len; i++) {
			this.lsg.add_dyn_slot(this.dynInputs[i])
			this.object3d.add(new THREE.Group())
		}

		this.lsg.infer_dt()
	}

	ThreeGroupPlugin.prototype.updatePivot = function() {
		var center = new THREE.Vector3()
		var count = 0

		// create a pivot centered around positions of meshes
		// connected to this group node
		for (var j = 0; j < this.object3d.children.length; ++j) {
			var parent = this.object3d.children[j]
			for (var i = 0; i < parent.children.length; ++i) {
				var obj = parent.children[i]

				if (obj.backReference) {
					center.x += obj.position.x
					center.y += obj.position.y
					center.z += obj.position.z
					++count
				}
			}
		}

		if (count > 1) {
			center.divideScalar(count)
		}

		// set state directly, this will be recalculated on demand
		// so no need to create an undo step

		var quat = new THREE.Quaternion(this.object3d.quaternion._x, this.object3d.quaternion._y, this.object3d.quaternion._z, this.object3d.quaternion._w)
		var scale = new THREE.Vector3(this.object3d.scale.x, this.object3d.scale.y, this.object3d.scale.z)

		var m = new THREE.Matrix4().makeRotationFromQuaternion(quat).scale(scale)

		var translation = center.clone().sub(this.lastCenter).applyMatrix4(m)
		this.state.pivot.x += translation.x
		this.state.pivot.y += translation.y
		this.state.pivot.z += translation.z

		for (var i = 0; i < this.object3d.children.length; ++i) {
			var subTree = this.object3d.children[i]

			subTree.position.x = -center.x;
			subTree.position.y = -center.y;
			subTree.position.z = -center.z;
		}

		this.matrixWorldNeedsUpdate = true

		this.lastCenter.copy(center)

		this.pivotNeedsUpdate = false
	}

})()
<commit_msg>calculate gazeClickerCount in object3d group<commit_after>(function() {
	var ThreeGroupPlugin = E2.plugins.three_group = function(core, node) {
		ThreeObject3DPlugin.apply(this, arguments)

		this.node = node

		this.desc = 'Group several object3ds together so that they can be manipulated as one'

		this.input_slots = [].concat(this.input_slots)

		this.lsg = new AutoSlotGroup(core, node, [], [])
		this.lsg.set_dt(core.datatypes.OBJECT3D)

		var that = this

		this.node.on('slotAdded', function () {
			that.dynInputs = node.getDynamicInputSlots()
			that.updated = true
		})

		this.node.on('slotRemoved', function () {
			that.dynInputs = node.getDynamicInputSlots()
			that.updated = true
		})

		this.object3d = new THREE.Group()
		this.object3d.name = 'group_plugin'
		this.object3d.backReference = this

		this.lastCenter = new THREE.Vector3()
	}

	ThreeGroupPlugin.prototype = Object.create(ThreeObject3DPlugin.prototype)

	ThreeGroupPlugin.prototype.update_input = function(slot, data) {
		if (slot.dynamic) {
			var parent = this.object3d.children[slot.index]

			if (data) {
				if (slot.array) {
					parent.children = data

					for (var i = 0; i < data.length; ++i) {
						if (data[i].parent && data[i].parent !== parent) {
							// the object is in another scene, remove from there
							data[i].parent.remove(data[i])
						}

						data[i].parent = parent
						data[i].dispatchEvent({type: 'added'})
					}
				}
				else {
					if (data.parent && data.parent !== this) {
						// the objects is in another scene, remove from there
						data.parent.remove(data)
					}

					parent.children = [data]

					data.parent = parent
					data.dispatchEvent({type: 'added'})
				}
			}
			else {
				while (parent.children.length > 0) {
					parent.remove(parent.children[0])
				}
			}

			this.pivotNeedsUpdate = true
		}
		else {
			ThreeObject3DPlugin.prototype.update_input.apply(this, arguments)
		}
	}

	ThreeGroupPlugin.prototype.update_state = function() {
		if (this.pivotNeedsUpdate) {
			this.updatePivot()
		}

		ThreeObject3DPlugin.prototype.update_state.apply(this, arguments)
	}

	ThreeGroupPlugin.prototype.connection_changed = function(on, conn, slot) {
		if (on && slot.dynamic) {
			// ensure there is a sufficient amount of slots
			while (this.object3d.children.length < this.dynInputs.length) {
				this.object3d.add(new THREE.Group())
			}
		}

		// disconnect
		if (!on && slot.type === E2.slot_type.input && slot.dynamic) {
			var parent = this.object3d.children[slot.index]

			while (parent.children.length > 0) {
				parent.remove(parent.children[0])
			}
		}

		// connect
		else if (on && slot.type === E2.slot_type.input && slot.dynamic) {
			this.object3d.children[slot.index].children = []
		}

		this.pivotNeedsUpdate = true
	}

	ThreeGroupPlugin.prototype.state_changed = function(ui) {
		if (ui) {
			return
		}

		this.dynInputs = this.node.getDynamicInputSlots()

		if (!this.dynInputs.length) {
			this.node.add_slot(E2.slot_type.input, {
				name: '0',
				dt: E2.dt.OBJECT3D,
				array: false
			})

			this.dynInputs = this.node.getDynamicInputSlots()
		}

		for(var i = 0, len = this.dynInputs.length; i < len; i++) {
			this.lsg.add_dyn_slot(this.dynInputs[i])
			this.object3d.add(new THREE.Group())
		}

		this.lsg.infer_dt()
	}

	ThreeGroupPlugin.prototype.updatePivot = function() {
		var center = new THREE.Vector3()
		var count = 0

		// create a pivot centered around positions of meshes
		// connected to this group node
		for (var j = 0; j < this.object3d.children.length; ++j) {
			var parent = this.object3d.children[j]
			for (var i = 0; i < parent.children.length; ++i) {
				var obj = parent.children[i]

				if (obj.backReference) {
					center.x += obj.position.x
					center.y += obj.position.y
					center.z += obj.position.z
					++count
				}
			}
		}

		if (count > 1) {
			center.divideScalar(count)
		}

		// set state directly, this will be recalculated on demand
		// so no need to create an undo step

		var quat = new THREE.Quaternion(this.object3d.quaternion._x, this.object3d.quaternion._y, this.object3d.quaternion._z, this.object3d.quaternion._w)
		var scale = new THREE.Vector3(this.object3d.scale.x, this.object3d.scale.y, this.object3d.scale.z)

		var m = new THREE.Matrix4().makeRotationFromQuaternion(quat).scale(scale)

		var translation = center.clone().sub(this.lastCenter).applyMatrix4(m)
		this.state.pivot.x += translation.x
		this.state.pivot.y += translation.y
		this.state.pivot.z += translation.z

		var gazeClickerCount = 0

		for (var i = 0; i < this.object3d.children.length; ++i) {
			var subTree = this.object3d.children[i]

			subTree.position.x = -center.x
			subTree.position.y = -center.y
			subTree.position.z = -center.z

			if (subTree.gazeClickerCount)
				gazeClickerCount += subTree.gazeClickerCount
		}

		this.object3d.gazeClickerCount = gazeClickerCount

		this.matrixWorldNeedsUpdate = true

		this.lastCenter.copy(center)

		this.pivotNeedsUpdate = false
	}

})()
<|endoftext|>