<commit_before>/*
* @Author: gbk <ck0123456@gmail.com>
* @Date:   2016-04-21 17:34:00
* @Last Modified by:   gbk
* @Last Modified time: 2017-05-19 13:22:05
*/

'use strict';

var mkdirp = require('mkdirp');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var Progress = require('progress');
var Balancer = require('load-balancer');
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

var util = require('./util');
var loader = require('./loader');
var pkg = require('../package.json');

// plugin defination
module.exports = {

  description: pkg.description,

  options: [
    [ '-s, --src <dir>', 'source directory, default to `src`', 'src' ],
    [ '-d, --dist <dir>', 'build directory, default to `dist`', 'dist' ],
    [ '-e  --entry <file>', 'app entry, default to `app/app.js`', 'app/app.js' ],
    [ '    --pages [pages]', 'add multi-page entries' ],
    [ '    --buildvars', 'build varibles' ],
    [ '    --vars', 'runtime varibles' ],
    [ '    --externals', 'webpack external varibles' ],
    [ '-o, --loose', 'use babel es2015 loose mode to transform codes' ],
    [ '-c, --keepconsole', 'keep `console.log`' ],
    [ '    --keepcss', 'keep non-extracted css in all builds'],
    [ '    --skipminify', 'skip minify js and css' ],
    [ '-p, --progress', 'show progress' ],
    [ '    --exportcss', 'export css files' ],
    [ '    --multiCompilers', 'generate multi-compilers' ],
    [ '    --minifyExtension <extension>', 'minify file extension' ],
    [ '    --includes', 'loader should include paths' ],
    [ '    --polyfill', 'use core-js to do polyfills' ],
    [ '    --mangle', 'mangle varibles when minify' ],
    [ '    --alias', 'path alias' ],
    [ '    --publicPath <path>', 'set publicPath in webpack'],
    [ '    --analyse [port]', 'analyse bundle size'],
  ],

  action: function(options) {

    // options
    var src = options.src;
    var dist = options.dist;
    var entry = options.entry;
    var pages = options.pages;
    var vars = options.vars || {};
    var buildvars = util.parseBuildVars(vars, options.buildvars || {});
    var externals = options.externals || {
      'react': 'window.React',
      'react-dom': 'window.ReactDOM || window.React'
    };
    var loose = options.loose;
    var keepconsole = options.keepconsole;
    var keepcss = options.keepcss;
    var skipminify = options.skipminify;
    var showProgress = options.progress;
    var exportcss = options.exportcss !== false;
    var multiCompilers = !!options.multiCompilers;
    var minifyExtension = options.minifyExtension || '';
    var includes = options.includes;
    var polyfill = !!options.polyfill;
    var mangle = !!options.mangle;
    var alias = (function(aliasMap) {
      for (var key in aliasMap) {
        aliasMap[key] = util.cwdPath(src, aliasMap[key]);
      }
      return aliasMap;
    })(typeof options.alias === 'object' ? options.alias : {
      i18n: 'i18n'
    });
    var publicPath = options.publicPath || '/';
    var analyse = options.analyse;

    // start time stamp
    var startStamp = Date.now();

    // copy task
    mkdirp.sync(util.cwdPath(dist));
    util.copy([
      util.cwdPath(src, 'lib', '**', '*.*'),
      util.cwdPath('html', '**', '*.*')
    ], util.cwdPath(dist));

    // entries
    var entries = {
      app: util.makeEntry(src, entry)
    };
    if (pages) {
      entries = util.makePageEntries(src, entries, pages);
    }

    // resolve
    var resolveRoot = [
      util.relPath('..', 'node_modules')
    ];
    if (process.cwd() !== util.relPath('..', '..', '..')) {
      resolveRoot.push(util.relPath('..', '..'));
    }
    var resolve = {
      root: resolveRoot,
      alias: alias,
      extensions: ['', '.js', '.jsx']
    };
    var resolveLoader = {
      root: resolveRoot
    };

    // plugins
    var plugins = [
      new webpack.optimize.OccurenceOrderPlugin()
    ];
    if (exportcss) {
      plugins.push(new ExtractTextPlugin('[name].css')); // allChunks 的会带来css的顺序问题
    }
    if (showProgress) {
      var bar = new Progress('webpack compile [:bar]', {
        total: 1,
        width: 20
      });
      var oldPercentage = 0;
      plugins.push(new webpack.ProgressPlugin(function handler(percentage) {
        bar.tick(percentage - oldPercentage);
        oldPercentage = percentage;
      }));
    }
    if (analyse) {
      var analysePort = parseInt(analyse);
      plugins.push(new BundleAnalyzerPlugin({
        analyzerMode: analysePort > 0 ? 'server' : 'static',
        analyzerPort: analysePort || 8888,
        reportFilename: util.cwdPath('webpack-bundle-analyzer-report.html')
      }));
    }

    // split buildvars into a table
    var keysArr = [];
    var valuesArr = [];
    for (var key in buildvars) {
      keysArr.push(key);
      if (Array.isArray(buildvars[key]) && buildvars[key].length) {
        valuesArr.push(buildvars[key]);
      } else {
        console.error(key + ' in buildvars MUST have at least one value!');
        process.exit(0);
      }
    }

    // generate all vars combination
    var combinations = [];
    if (keysArr.length) {
      var findRoute = function(combination) {
        combination = combination || [];
        var values = valuesArr[combination.length];
        if (values) {
          values.forEach(function(value) {
            findRoute(combination.concat([ value ]));
          });
        } else {
          var vars = {};
          keysArr.forEach(function(key, index) {
            vars[key] = combination[index];
          });
          combinations.push(vars);
        }
      }
      findRoute();
    }

    // minify task
    var minify = skipminify ? function() {
      util.finishLog(startStamp);
    } : function(assets) {
      new Balancer.Master().send(util.relPath('minify.js'), {
        keepconsole: keepconsole,
        minifyExtension: minifyExtension,
        mangle: mangle
      }, assets.map(function(a) {
        return util.cwdPath(dist, a.name);
      }), function() {
        util.finishLog(startStamp);
      });
    };

    // run compiler
    if (combinations.length > 1 || multiCompilers) { // multi-compilers

      var compilers = combinations.length > 1 ? combinations.map(function(vars, index) {
        return util.preProcess({
          entry: entries,
          output: {
            path: util.cwdPath(dist),
            filename: '[name]' + util.suffixByVars(vars, buildvars) + '.js',
            publicPath: publicPath
          },
          plugins: plugins.concat([
            new webpack.DefinePlugin(util.parseVars(vars))
          ]),
          resolve: resolve,
          resolveLoader: resolveLoader,
          externals: externals,
          cache: true,
          module: {
            loaders: loader(options,  keepcss || index === 0)
          }
        });
      }) : util.preProcess({
          entry: entries,
          output: {
            path: util.cwdPath(dist),
            filename: '[name].js',
            publicPath: publicPath
          },
          plugins: plugins,
          resolve: resolve,
          resolveLoader: resolveLoader,
          externals: externals,
          cache: true,
          module: {
            loaders: loader(options, true),
          }
        });

      webpack(compilers, function(err, stats) {

        // print wepack compile result
        if (err) {
          return util.buildFail(err.toString());
        }
        console.log('=============');
        var assets = [];
        stats.stats.forEach(function(stat) {
          if (stat.hasErrors()) {
            return util.buildFail(stat.toJson().errors[0].split('\n').slice(0, 2).join('\n'));
          }
          console.log(stat.toString({
            version: false,
            hash: false,
            chunks: false,
            children: false,
            colors: true
          }) + '\n=============');

          // concat assets
          Array.prototype.push.apply(assets, stat.toJson({
            hash: false,
            chunks: false,
            children: false,
            modules: false
          }).assets);
        });

        // minify task
        minify(assets);
      });

    } else { // single-compiler

      // vars defined
      if (combinations.length) {
        plugins.push(new webpack.DefinePlugin(util.parseVars(combinations[0])));
      }

      webpack(util.preProcess({
        entry: entries,
        output: {
          path: util.cwdPath(dist),
          filename: '[name].js',
          publicPath: publicPath
        },
        plugins: plugins,
        resolve: resolve,
        resolveLoader: resolveLoader,
        externals: externals,
        cache: true,
        module: {
          loaders: loader(options, true)
        }
      }), function(err, stats) {

        // print wepack compile result
        if (err) {
          return util.buildFail(err.toString());
        }
        if (stats.hasErrors()) {
          return util.buildFail(stats.toJson().errors[0].split('\n').slice(0, 2).join('\n'));
        }
        console.log('\n' + stats.toString({
          hash: false,
          chunks: false,
          children: false,
          colors: true
        }));

        // minify task
        minify(stats.toJson({
          hash: false,
          chunks: false,
          children: false,
          modules: false
        }).assets);
      });
    }

  }
};

<commit_msg>feat: overwrite vars & buildvars in cli<commit_after>/*
* @Author: gbk <ck0123456@gmail.com>
* @Date:   2016-04-21 17:34:00
* @Last Modified by:   gbk
* @Last Modified time: 2017-05-19 13:22:05
*/

'use strict';

var mkdirp = require('mkdirp');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var Progress = require('progress');
var Balancer = require('load-balancer');
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

var util = require('./util');
var loader = require('./loader');
var pkg = require('../package.json');

var parseJSONString = function(stringOrAny) {
  if (typeof stringOrAny !== 'string') {
    return stringOrAny;
  } else {
    try {
      return JSON.parse(stringOrAny);
    } catch (e) {
      console.error(e);
      return stringOrAny;
    }
  }
};

// plugin defination
module.exports = {

  description: pkg.description,

  options: [
    [ '-s, --src <dir>', 'source directory, default to `src`', 'src' ],
    [ '-d, --dist <dir>', 'build directory, default to `dist`', 'dist' ],
    [ '-e  --entry <file>', 'app entry, default to `app/app.js`', 'app/app.js' ],
    [ '    --pages [pages]', 'add multi-page entries' ],
    [ '    --buildvars <json>', 'build varibles' ],
    [ '    --vars <json>', 'runtime varibles' ],
    [ '    --externals', 'webpack external varibles' ],
    [ '-o, --loose', 'use babel es2015 loose mode to transform codes' ],
    [ '-c, --keepconsole', 'keep `console.log`' ],
    [ '    --keepcss', 'keep non-extracted css in all builds'],
    [ '    --skipminify', 'skip minify js and css' ],
    [ '-p, --progress', 'show progress' ],
    [ '    --exportcss', 'export css files' ],
    [ '    --multiCompilers', 'generate multi-compilers' ],
    [ '    --minifyExtension <extension>', 'minify file extension' ],
    [ '    --includes', 'loader should include paths' ],
    [ '    --polyfill', 'use core-js to do polyfills' ],
    [ '    --mangle', 'mangle varibles when minify' ],
    [ '    --alias', 'path alias' ],
    [ '    --publicPath <path>', 'set publicPath in webpack'],
    [ '    --analyse [port]', 'analyse bundle size'],
  ],

  action: function(options) {

    // options
    var src = options.src;
    var dist = options.dist;
    var entry = options.entry;
    var pages = options.pages;
    var vars = parseJSONString(options.vars) || {};
    var buildvars = util.parseBuildVars(vars, parseJSONString(options.buildvars) || {});
    var externals = options.externals || {
      'react': 'window.React',
      'react-dom': 'window.ReactDOM || window.React'
    };
    var loose = options.loose;
    var keepconsole = options.keepconsole;
    var keepcss = options.keepcss;
    var skipminify = options.skipminify;
    var showProgress = options.progress;
    var exportcss = options.exportcss !== false;
    var multiCompilers = !!options.multiCompilers;
    var minifyExtension = options.minifyExtension || '';
    var includes = options.includes;
    var polyfill = !!options.polyfill;
    var mangle = !!options.mangle;
    var alias = (function(aliasMap) {
      for (var key in aliasMap) {
        aliasMap[key] = util.cwdPath(src, aliasMap[key]);
      }
      return aliasMap;
    })(typeof options.alias === 'object' ? options.alias : {
      i18n: 'i18n'
    });
    var publicPath = options.publicPath || '/';
    var analyse = options.analyse;

    // start time stamp
    var startStamp = Date.now();

    // copy task
    mkdirp.sync(util.cwdPath(dist));
    util.copy([
      util.cwdPath(src, 'lib', '**', '*.*'),
      util.cwdPath('html', '**', '*.*')
    ], util.cwdPath(dist));

    // entries
    var entries = {
      app: util.makeEntry(src, entry)
    };
    if (pages) {
      entries = util.makePageEntries(src, entries, pages);
    }

    // resolve
    var resolveRoot = [
      util.relPath('..', 'node_modules')
    ];
    if (process.cwd() !== util.relPath('..', '..', '..')) {
      resolveRoot.push(util.relPath('..', '..'));
    }
    var resolve = {
      root: resolveRoot,
      alias: alias,
      extensions: ['', '.js', '.jsx']
    };
    var resolveLoader = {
      root: resolveRoot
    };

    // plugins
    var plugins = [
      new webpack.optimize.OccurenceOrderPlugin()
    ];
    if (exportcss) {
      plugins.push(new ExtractTextPlugin('[name].css')); // allChunks 的会带来css的顺序问题
    }
    if (showProgress) {
      var bar = new Progress('webpack compile [:bar]', {
        total: 1,
        width: 20
      });
      var oldPercentage = 0;
      plugins.push(new webpack.ProgressPlugin(function handler(percentage) {
        bar.tick(percentage - oldPercentage);
        oldPercentage = percentage;
      }));
    }
    if (analyse) {
      var analysePort = parseInt(analyse);
      plugins.push(new BundleAnalyzerPlugin({
        analyzerMode: analysePort > 0 ? 'server' : 'static',
        analyzerPort: analysePort || 8888,
        reportFilename: util.cwdPath('webpack-bundle-analyzer-report.html')
      }));
    }

    // split buildvars into a table
    var keysArr = [];
    var valuesArr = [];
    for (var key in buildvars) {
      keysArr.push(key);
      if (Array.isArray(buildvars[key]) && buildvars[key].length) {
        valuesArr.push(buildvars[key]);
      } else {
        console.error(key + ' in buildvars MUST have at least one value!');
        process.exit(0);
      }
    }

    // generate all vars combination
    var combinations = [];
    if (keysArr.length) {
      var findRoute = function(combination) {
        combination = combination || [];
        var values = valuesArr[combination.length];
        if (values) {
          values.forEach(function(value) {
            findRoute(combination.concat([ value ]));
          });
        } else {
          var vars = {};
          keysArr.forEach(function(key, index) {
            vars[key] = combination[index];
          });
          combinations.push(vars);
        }
      }
      findRoute();
    }

    // minify task
    var minify = skipminify ? function() {
      util.finishLog(startStamp);
    } : function(assets) {
      new Balancer.Master().send(util.relPath('minify.js'), {
        keepconsole: keepconsole,
        minifyExtension: minifyExtension,
        mangle: mangle
      }, assets.map(function(a) {
        return util.cwdPath(dist, a.name);
      }), function() {
        util.finishLog(startStamp);
      });
    };

    // run compiler
    if (combinations.length > 1 || multiCompilers) { // multi-compilers

      var compilers = combinations.length > 1 ? combinations.map(function(vars, index) {
        return util.preProcess({
          entry: entries,
          output: {
            path: util.cwdPath(dist),
            filename: '[name]' + util.suffixByVars(vars, buildvars) + '.js',
            publicPath: publicPath
          },
          plugins: plugins.concat([
            new webpack.DefinePlugin(util.parseVars(vars))
          ]),
          resolve: resolve,
          resolveLoader: resolveLoader,
          externals: externals,
          cache: true,
          module: {
            loaders: loader(options,  keepcss || index === 0)
          }
        });
      }) : util.preProcess({
          entry: entries,
          output: {
            path: util.cwdPath(dist),
            filename: '[name].js',
            publicPath: publicPath
          },
          plugins: plugins,
          resolve: resolve,
          resolveLoader: resolveLoader,
          externals: externals,
          cache: true,
          module: {
            loaders: loader(options, true),
          }
        });

      webpack(compilers, function(err, stats) {

        // print wepack compile result
        if (err) {
          return util.buildFail(err.toString());
        }
        console.log('=============');
        var assets = [];
        stats.stats.forEach(function(stat) {
          if (stat.hasErrors()) {
            return util.buildFail(stat.toJson().errors[0].split('\n').slice(0, 2).join('\n'));
          }
          console.log(stat.toString({
            version: false,
            hash: false,
            chunks: false,
            children: false,
            colors: true
          }) + '\n=============');

          // concat assets
          Array.prototype.push.apply(assets, stat.toJson({
            hash: false,
            chunks: false,
            children: false,
            modules: false
          }).assets);
        });

        // minify task
        minify(assets);
      });

    } else { // single-compiler

      // vars defined
      if (combinations.length) {
        plugins.push(new webpack.DefinePlugin(util.parseVars(combinations[0])));
      }

      webpack(util.preProcess({
        entry: entries,
        output: {
          path: util.cwdPath(dist),
          filename: '[name].js',
          publicPath: publicPath
        },
        plugins: plugins,
        resolve: resolve,
        resolveLoader: resolveLoader,
        externals: externals,
        cache: true,
        module: {
          loaders: loader(options, true)
        }
      }), function(err, stats) {

        // print wepack compile result
        if (err) {
          return util.buildFail(err.toString());
        }
        if (stats.hasErrors()) {
          return util.buildFail(stats.toJson().errors[0].split('\n').slice(0, 2).join('\n'));
        }
        console.log('\n' + stats.toString({
          hash: false,
          chunks: false,
          children: false,
          colors: true
        }));

        // minify task
        minify(stats.toJson({
          hash: false,
          chunks: false,
          children: false,
          modules: false
        }).assets);
      });
    }

  }
};

<|endoftext|>


<commit_before>'use strict'

const phantomjs = require('phantomjs-prebuilt').path
const spawn = require('cross-spawn')
const tmp = require('tmp')
const async = require('async')
const node_path = require('path')

const fs = require('fs')

const {
  EventEmitter
} = require('events')

STR_RUNNER_JS = 'runner.js'

function runner (options) {
  return new Runner(options)
}

class Runner extends EventEmitter {
  constructor (options) {
    super()
    this._js = []
  }

  js (filename) {
    this._js.push(filename)
    return this
  }

  include_jquery () {
    return this.include_js()
  }

  open (url) {
    this._create_tmp_js((err) => {
      if (err) {
        return this.emit('error', err)
      }

      this._run_phantomjs(url, (err, output) => {
        if (err) {
          return this.emit('error', err)
        }

        this.emit('result', output, url)
      })
    })
  }

  _run_phantomjs (url, callback) {
    let s = spawn(phantomjs.path, [url, this._runner_filename])

    let output = ''

    s.stdout.on('data', (data) => {
      output += data
    })

    s.on('close', (code) => {
      if (code) {
        return callback(new Error('phantomjs exit with code ' + code))
      }

      callback(null, output)
    })
  }

  _create_tmp_js (callback) {
    if (this._tmp_created) {
      return callback(null)
    }

    let template

    try {
      template = require('./runner')
    } catch (e) {
      return callback(e)
    }

    let dir
    let content

    async.parallel([
      (done) => {
        this._read_template((err, c) => {
          content = c
          done(err)
        })
      },

      (done) => {
        this._create_tmp_dir((err, d) => {
          dir = d
          done(err)
        })
      }

    ], (err) => {
      if (err) {
        return callback(err)
      }

      this._runner_filename = filename = node_path.join(dir, STR_RUNNER_JS)
      fs.writeFile(filename, content, (err) => {
        if (err) {
          return callback(err)
        }

        this._tmp_created = true
        callback(null)
      })
    })
  }

  _read_template (callback) {
    fs.readFile(template, (err, content) => {
      if (err) {
        return callback(err)
      }

      let local_js = JSON.stringify(this._js)
      let file_content = eval('`' + content.toString() + '`')

      callback(null, file_content)
    })
  }

  _create_tmp_dir (callback) {
    tmp.dir(callback)
  }
}
<commit_msg>fixes syntax errors<commit_after>'use strict'

const phantomjs = require('phantomjs-prebuilt').path
const spawn = require('cross-spawn')
const tmp = require('tmp')
const async = require('async')

const node_path = require('path')
const fs = require('fs')
const EventEmitter = require('events').EventEmitter

const STR_RUNNER_JS = 'runner.js'

function runner (options) {
  return new Runner(options)
}

class Runner extends EventEmitter {
  constructor (options) {
    super()
    this._js = []
  }

  js (filename) {
    this._js.push(filename)
    return this
  }

  include_jquery () {
    return this.js(require.resolve('jquery'))
  }

  open (url) {
    this._create_tmp_js((err) => {
      if (err) {
        return this.emit('error', err)
      }

      this._run_phantomjs(url, (err, output) => {
        if (err) {
          return this.emit('error', err)
        }

        this.emit('result', output, url)
      })
    })
  }

  // Spawn phantomjs with specific url
  _run_phantomjs (url, callback) {
    let s = spawn(phantomjs.path, [url, this._runner_filename])

    let output = ''

    s.stdout.on('data', (data) => {
      output += data
    })

    s.on('close', (code) => {
      if (code) {
        return callback(new Error('phantomjs exit with code ' + code))
      }

      callback(null, output)
    })
  }

  // Create runner javascript file
  _create_tmp_js (callback) {
    if (this._tmp_created) {
      return callback(null)
    }

    let template

    try {
      template = require('./runner')
    } catch (e) {
      return callback(e)
    }

    let dir
    let content

    async.parallel([
      (done) => {
        this._read_template((err, c) => {
          content = c
          done(err)
        })
      },

      (done) => {
        this._create_tmp_dir((err, d) => {
          dir = d
          done(err)
        })
      }

    ], (err) => {
      if (err) {
        return callback(err)
      }

      this._runner_filename = filename = node_path.join(dir, STR_RUNNER_JS)
      fs.writeFile(filename, content, (err) => {
        if (err) {
          return callback(err)
        }

        this._tmp_created = true
        callback(null)
      })
    })
  }

  _read_template (callback) {
    fs.readFile(template, (err, content) => {
      if (err) {
        return callback(err)
      }

      let local_js = JSON.stringify(this._js)
      let file_content = eval('`' + content.toString() + '`')

      callback(null, file_content)
    })
  }

  _create_tmp_dir (callback) {
    tmp.dir(callback)
  }
}
<|endoftext|>


<commit_before>#!/usr/bin/env node

/*globals require, process, console, setImmediate */

'use strict';

var options, formatter, state,

cli = require('commander'),
fs = require('fs'),
path = require('path'),
js = require('escomplex-js'),
check = require('check-types');

parseCommandLine();

state = {
    starting: true,
    openFileCount: 0,
    source: [],
    tooComplex: false,
    failingModules: []
};

expectFiles(cli.args, cli.help.bind(cli));
readFiles(cli.args);

function parseCommandLine () {
    var config;

    cli.
        usage('[options] <path>').
        option('-c, --config <path>', 'specify path to configuration JSON file').
        option('-o, --output <path>', 'specify an output file for the report').
        option('-f, --format <format>', 'specify the output format of the report').
        option('-a, --allfiles', 'include hidden files in the report').
        option('-p, --filepattern <pattern>', 'specify the files to process using a regular expression to match against file names').
        option('-P, --dirpattern <pattern>', 'specify the directories to process using a regular expression to match against directory names').
        option('-x, --excludepattern <pattern>', 'specify the the directories to exclude using a regular expression to match against directory names').
        option('-e, --ignoreerrors', 'ignore any files that fail to parsed into an AST').
        option('-m, --maxfiles <number>', 'specify the maximum number of files to have open at any point', parseInt).
        option('-F, --maxfod <first-order density>', 'specify the per-project first-order density threshold', parseFloat).
        option('-O, --maxcost <change cost>', 'specify the per-project change cost threshold', parseFloat).
        option('-S, --maxsize <core size>', 'specify the per-project core size threshold', parseFloat).
        option('-M, --minmi <maintainability index>', 'specify the per-module maintainability index threshold', parseFloat).
        option('-C, --maxcyc <cyclomatic complexity>', 'specify the per-function cyclomatic complexity threshold', parseInt).
        option('-Y, --maxcycden <cyclomatic density>', 'specify the per-function cyclomatic complexity density threshold', parseInt).
        option('-D, --maxhd <halstead difficulty>', 'specify the per-function Halstead difficulty threshold', parseFloat).
        option('-V, --maxhv <halstead volume>', 'specify the per-function Halstead volume threshold', parseFloat).
        option('-E, --maxhe <halstead effort>', 'specify the per-function Halstead effort threshold', parseFloat).
        option('-s, --silent', 'don\'t write any output to the console').
        option('-l, --logicalor', 'disregard operator || as source of cyclomatic complexity').
        option('-w, --switchcase', 'disregard switch statements as source of cyclomatic complexity').
        option('-i, --forin', 'treat for...in statements as source of cyclomatic complexity').
        option('-t, --trycatch', 'treat catch clauses as source of cyclomatic complexity').
        option('-n, --newmi', 'use the Microsoft-variant maintainability index (scale of 0 to 100)').
        parse(process.argv);

    config = readConfig(cli.config);

    Object.keys(config).forEach(function (key) {
        if (cli[key] === undefined) {
            cli[key] = config[key];
        }
    });

    options = {
        logicalor: !cli.logicalor,
        switchcase: !cli.switchcase,
        forin: cli.forin || false,
        trycatch: cli.trycatch || false,
        newmi: cli.newmi || false,
        ignoreErrors: cli.ignoreerrors || false
    };

    if (check.unemptyString(cli.format) === false) {
        cli.format = 'plain';
    }

    if (check.unemptyString(cli.filepattern) === false) {
        cli.filepattern = '\\.js$';
    }
    cli.filepattern = new RegExp(cli.filepattern);

    if (check.unemptyString(cli.dirpattern)) {
        cli.dirpattern = new RegExp(cli.dirpattern);
    }

    if (check.unemptyString(cli.excludepattern)) {
        cli.excludepattern = new RegExp(cli.excludepattern);
    }

    if (check.number(cli.maxfiles) === false) {
        cli.maxfiles = 1024;
    }

    try {
        formatter = require('./formats/' + cli.format);
    } catch (err) {
        formatter = require(cli.format);
    }
}

function readConfig (configPath) {
    var configInfo;

    try {
        if (check.not.unemptyString(configPath)) {
            configPath = path.join(process.cwd(), '.complexrc');
        }

        if (fs.existsSync(configPath)) {
            configInfo = fs.statSync(configPath);

            if (configInfo.isFile()) {
                return JSON.parse(fs.readFileSync(configPath), { encoding: 'utf8' });
            }
        }

        return {};
    } catch (err) {
        error('readConfig', err);
    }
}

function expectFiles (paths, noFilesFn) {
    if (paths.length === 0) {
        noFilesFn();
    }
}

function readFiles (paths) {
    paths.forEach(function (p) {
        var stat = fs.statSync(p);

        if (stat.isDirectory()) {
            if ((!cli.dirpattern || cli.dirpattern.test(p)) && (!cli.excludepattern || !cli.excludepattern.test(p))) {
                readDirectory(p);
            }
        } else if (cli.filepattern.test(p)) {
            conditionallyReadFile(p);
        }
    });

    state.starting = false;
}

function readDirectory (directoryPath) {
    readFiles(
        fs.readdirSync(directoryPath).filter(function (p) {
            return path.basename(p).charAt(0) !== '.' || cli.allfiles;
        }).map(function (p) {
            return path.resolve(directoryPath, p);
        })
    );
}

function conditionallyReadFile (filePath) {
    if (isOpenFileLimitReached()) {
        setImmediate(function () {
            conditionallyReadFile(filePath);
        });
    } else {
        readFile(filePath);
    }
}

function readFile (filePath) {
    state.openFileCount += 1;

    fs.readFile(filePath, 'utf8', function (err, source) {
        if (err) {
            error('readFile', err);
        }

        state.openFileCount -= 1;

        if (beginsWithShebang(source)) {
            source = commentFirstLine(source);
        }

        setSource(filePath, source);
    });
}

function isOpenFileLimitReached () {
    return state.openFileCount >= cli.maxfiles;
}

function error (functionName, err) {
    fail('Fatal error [' + functionName + ']: ' + err.message);
    process.exit(1);
}

function fail (message) {
    console.log(message);
}

function beginsWithShebang (source) {
    return source[0] === '#' && source[1] === '!';
}

function commentFirstLine (source) {
    return '//' + source;
}

function setSource (modulePath, source) {
    state.source.push({
        path: modulePath,
        code: source
    });

    if (state.starting === false && state.openFileCount === 0) {
        getReports();
    }
}

function getReports () {
    var result, failingModules;

    try {
        result = js.analyse(state.source, options);

        if (!cli.silent) {
            writeReports(result);
        }

        failingModules = getFailingModules(result.reports);
        if (failingModules.length > 0) {
            return fail('Warning: Complexity threshold breached!\nFailing modules:\n' + failingModules.join('\n'));
        }

        if (isProjectComplexityThresholdSet() && isProjectTooComplex(result)) {
            fail('Warning: Project complexity threshold breached!');
        }
    } catch (err) {
        error('getReports', err);
    }
}

function writeReports (result) {
    var formatted = formatter.format(result);

    if (check.unemptyString(cli.output)) {
        fs.writeFile(cli.output, formatted, 'utf8', function (err) {
            if (err) {
                error('writeReport', err);
            }
        });
    } else {
        console.log(formatted);
    }
}

function getFailingModules (reports) {
    return reports.reduce(function (failingModules, report) {
        if (
            (isModuleComplexityThresholdSet() && isModuleTooComplex(report)) ||
            (isFunctionComplexityThresholdSet() && isFunctionTooComplex(report))
        ) {
            return failingModules.concat(report.path);
        }

        return failingModules;
    }, []);
}

function isModuleComplexityThresholdSet () {
    return check.number(cli.minmi);
}

function isModuleTooComplex (report) {
    if (isThresholdBreached(cli.minmi, report.maintainability, true)) {
        return true;
    }
}

function isThresholdBreached (threshold, metric, inverse) {
    if (!inverse) {
        return check.number(threshold) && metric > threshold;
    }

    return check.number(threshold) && metric < threshold;
}

function isFunctionComplexityThresholdSet () {
    return check.number(cli.maxcyc) || check.number(cli.maxcycden) || check.number(cli.maxhd) || check.number(cli.maxhv) || check.number(cli.maxhe);
}

function isFunctionTooComplex (report) {
    var i;

    for (i = 0; i < report.functions.length; i += 1) {
        if (isThresholdBreached(cli.maxcyc, report.functions[i].cyclomatic)) {
            return true;
        }

        if (isThresholdBreached(cli.maxcycden, report.functions[i].cyclomaticDensity)) {
            return true;
        }

        if (isThresholdBreached(cli.maxhd, report.functions[i].halstead.difficulty)) {
            return true;
        }

        if (isThresholdBreached(cli.maxhv, report.functions[i].halstead.volume)) {
            return true;
        }

        if (isThresholdBreached(cli.maxhe, report.functions[i].halstead.effort)) {
            return true;
        }
    }

    return false;
}

function isProjectComplexityThresholdSet () {
    return check.number(cli.maxfod) || check.number(cli.maxcost) || check.number(cli.maxsize);
}

function isProjectTooComplex (result) {
    if (isThresholdBreached(cli.maxfod, result.firstOrderDensity)) {
        return true;
    }

    if (isThresholdBreached(cli.maxcost, result.changeCost)) {
        return true;
    }

    if (isThresholdBreached(cli.maxsize, result.coreSize)) {
        return true;
    }

    return false;
}

<commit_msg>Tweak help output.<commit_after>#!/usr/bin/env node

/*globals require, process, console, setImmediate */

'use strict';

var options, formatter, state,

cli = require('commander'),
fs = require('fs'),
path = require('path'),
js = require('escomplex-js'),
check = require('check-types');

parseCommandLine();

state = {
    starting: true,
    openFileCount: 0,
    source: [],
    tooComplex: false,
    failingModules: []
};

expectFiles(cli.args, cli.help.bind(cli));
readFiles(cli.args);

function parseCommandLine () {
    var config;

    cli.
        usage('[options] <path>').
        option('-c, --config <path>', 'specify path to configuration JSON file').
        option('-o, --output <path>', 'specify an output file for the report').
        option('-f, --format <format>', 'specify the output format of the report').
        option('-e, --ignoreerrors', 'ignore parser errors').
        option('-a, --allfiles', 'include hidden files in the report').
        option('-p, --filepattern <pattern>', 'specify the files to process using a regular expression to match against file names').
        option('-P, --dirpattern <pattern>', 'specify the directories to process using a regular expression to match against directory names').
        option('-x, --excludepattern <pattern>', 'specify the the directories to exclude using a regular expression to match against directory names').
        option('-m, --maxfiles <number>', 'specify the maximum number of files to have open at any point', parseInt).
        option('-F, --maxfod <first-order density>', 'specify the per-project first-order density threshold', parseFloat).
        option('-O, --maxcost <change cost>', 'specify the per-project change cost threshold', parseFloat).
        option('-S, --maxsize <core size>', 'specify the per-project core size threshold', parseFloat).
        option('-M, --minmi <maintainability index>', 'specify the per-module maintainability index threshold', parseFloat).
        option('-C, --maxcyc <cyclomatic complexity>', 'specify the per-function cyclomatic complexity threshold', parseInt).
        option('-Y, --maxcycden <cyclomatic density>', 'specify the per-function cyclomatic complexity density threshold', parseInt).
        option('-D, --maxhd <halstead difficulty>', 'specify the per-function Halstead difficulty threshold', parseFloat).
        option('-V, --maxhv <halstead volume>', 'specify the per-function Halstead volume threshold', parseFloat).
        option('-E, --maxhe <halstead effort>', 'specify the per-function Halstead effort threshold', parseFloat).
        option('-s, --silent', 'don\'t write any output to the console').
        option('-l, --logicalor', 'disregard operator || as source of cyclomatic complexity').
        option('-w, --switchcase', 'disregard switch statements as source of cyclomatic complexity').
        option('-i, --forin', 'treat for...in statements as source of cyclomatic complexity').
        option('-t, --trycatch', 'treat catch clauses as source of cyclomatic complexity').
        option('-n, --newmi', 'use the Microsoft-variant maintainability index (scale of 0 to 100)').
        parse(process.argv);

    config = readConfig(cli.config);

    Object.keys(config).forEach(function (key) {
        if (cli[key] === undefined) {
            cli[key] = config[key];
        }
    });

    options = {
        logicalor: !cli.logicalor,
        switchcase: !cli.switchcase,
        forin: cli.forin || false,
        trycatch: cli.trycatch || false,
        newmi: cli.newmi || false,
        ignoreErrors: cli.ignoreerrors || false
    };

    if (check.unemptyString(cli.format) === false) {
        cli.format = 'plain';
    }

    if (check.unemptyString(cli.filepattern) === false) {
        cli.filepattern = '\\.js$';
    }
    cli.filepattern = new RegExp(cli.filepattern);

    if (check.unemptyString(cli.dirpattern)) {
        cli.dirpattern = new RegExp(cli.dirpattern);
    }

    if (check.unemptyString(cli.excludepattern)) {
        cli.excludepattern = new RegExp(cli.excludepattern);
    }

    if (check.number(cli.maxfiles) === false) {
        cli.maxfiles = 1024;
    }

    try {
        formatter = require('./formats/' + cli.format);
    } catch (err) {
        formatter = require(cli.format);
    }
}

function readConfig (configPath) {
    var configInfo;

    try {
        if (check.not.unemptyString(configPath)) {
            configPath = path.join(process.cwd(), '.complexrc');
        }

        if (fs.existsSync(configPath)) {
            configInfo = fs.statSync(configPath);

            if (configInfo.isFile()) {
                return JSON.parse(fs.readFileSync(configPath), { encoding: 'utf8' });
            }
        }

        return {};
    } catch (err) {
        error('readConfig', err);
    }
}

function expectFiles (paths, noFilesFn) {
    if (paths.length === 0) {
        noFilesFn();
    }
}

function readFiles (paths) {
    paths.forEach(function (p) {
        var stat = fs.statSync(p);

        if (stat.isDirectory()) {
            if ((!cli.dirpattern || cli.dirpattern.test(p)) && (!cli.excludepattern || !cli.excludepattern.test(p))) {
                readDirectory(p);
            }
        } else if (cli.filepattern.test(p)) {
            conditionallyReadFile(p);
        }
    });

    state.starting = false;
}

function readDirectory (directoryPath) {
    readFiles(
        fs.readdirSync(directoryPath).filter(function (p) {
            return path.basename(p).charAt(0) !== '.' || cli.allfiles;
        }).map(function (p) {
            return path.resolve(directoryPath, p);
        })
    );
}

function conditionallyReadFile (filePath) {
    if (isOpenFileLimitReached()) {
        setImmediate(function () {
            conditionallyReadFile(filePath);
        });
    } else {
        readFile(filePath);
    }
}

function readFile (filePath) {
    state.openFileCount += 1;

    fs.readFile(filePath, 'utf8', function (err, source) {
        if (err) {
            error('readFile', err);
        }

        state.openFileCount -= 1;

        if (beginsWithShebang(source)) {
            source = commentFirstLine(source);
        }

        setSource(filePath, source);
    });
}

function isOpenFileLimitReached () {
    return state.openFileCount >= cli.maxfiles;
}

function error (functionName, err) {
    fail('Fatal error [' + functionName + ']: ' + err.message);
    process.exit(1);
}

function fail (message) {
    console.log(message);
}

function beginsWithShebang (source) {
    return source[0] === '#' && source[1] === '!';
}

function commentFirstLine (source) {
    return '//' + source;
}

function setSource (modulePath, source) {
    state.source.push({
        path: modulePath,
        code: source
    });

    if (state.starting === false && state.openFileCount === 0) {
        getReports();
    }
}

function getReports () {
    var result, failingModules;

    try {
        result = js.analyse(state.source, options);

        if (!cli.silent) {
            writeReports(result);
        }

        failingModules = getFailingModules(result.reports);
        if (failingModules.length > 0) {
            return fail('Warning: Complexity threshold breached!\nFailing modules:\n' + failingModules.join('\n'));
        }

        if (isProjectComplexityThresholdSet() && isProjectTooComplex(result)) {
            fail('Warning: Project complexity threshold breached!');
        }
    } catch (err) {
        error('getReports', err);
    }
}

function writeReports (result) {
    var formatted = formatter.format(result);

    if (check.unemptyString(cli.output)) {
        fs.writeFile(cli.output, formatted, 'utf8', function (err) {
            if (err) {
                error('writeReport', err);
            }
        });
    } else {
        console.log(formatted);
    }
}

function getFailingModules (reports) {
    return reports.reduce(function (failingModules, report) {
        if (
            (isModuleComplexityThresholdSet() && isModuleTooComplex(report)) ||
            (isFunctionComplexityThresholdSet() && isFunctionTooComplex(report))
        ) {
            return failingModules.concat(report.path);
        }

        return failingModules;
    }, []);
}

function isModuleComplexityThresholdSet () {
    return check.number(cli.minmi);
}

function isModuleTooComplex (report) {
    if (isThresholdBreached(cli.minmi, report.maintainability, true)) {
        return true;
    }
}

function isThresholdBreached (threshold, metric, inverse) {
    if (!inverse) {
        return check.number(threshold) && metric > threshold;
    }

    return check.number(threshold) && metric < threshold;
}

function isFunctionComplexityThresholdSet () {
    return check.number(cli.maxcyc) || check.number(cli.maxcycden) || check.number(cli.maxhd) || check.number(cli.maxhv) || check.number(cli.maxhe);
}

function isFunctionTooComplex (report) {
    var i;

    for (i = 0; i < report.functions.length; i += 1) {
        if (isThresholdBreached(cli.maxcyc, report.functions[i].cyclomatic)) {
            return true;
        }

        if (isThresholdBreached(cli.maxcycden, report.functions[i].cyclomaticDensity)) {
            return true;
        }

        if (isThresholdBreached(cli.maxhd, report.functions[i].halstead.difficulty)) {
            return true;
        }

        if (isThresholdBreached(cli.maxhv, report.functions[i].halstead.volume)) {
            return true;
        }

        if (isThresholdBreached(cli.maxhe, report.functions[i].halstead.effort)) {
            return true;
        }
    }

    return false;
}

function isProjectComplexityThresholdSet () {
    return check.number(cli.maxfod) || check.number(cli.maxcost) || check.number(cli.maxsize);
}

function isProjectTooComplex (result) {
    if (isThresholdBreached(cli.maxfod, result.firstOrderDensity)) {
        return true;
    }

    if (isThresholdBreached(cli.maxcost, result.changeCost)) {
        return true;
    }

    if (isThresholdBreached(cli.maxsize, result.coreSize)) {
        return true;
    }

    return false;
}

<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import lifecyclesPoylfill from 'react-lifecycles-compat';

import GifPlayer from './GifPlayer';

const preload = (src, callback) => {
  var img = new Image();
  if (typeof callback === 'function') {
    img.onload = () => callback(img);
    img.setAttribute('crossOrigin', 'anonymous');
  }
  img.src = src;
};

const firstGifFrameUrl = img => {
  const canvas = document.createElement('canvas');
  if (typeof canvas.getContext !== 'function') {
    return null;
  }
  canvas.width = img.width;
  canvas.height = img.height;
  const ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0);
  return canvas.toDataURL();
}

class GifPlayerContainer extends React.Component {
  static getDerivedStateFromProps (nextProps, prevState) {
    const prevGif = prevState.providedGif;
    const nextGif = nextProps.gif;
    const prevStill = prevState.providedStill;
    const nextStill = nextProps.still;
    if (prevGif === nextGif && prevStill === nextStill) {
      return null;
    }

    return {
      playing: nextGif && nextProps.autoplay && prevGif !== nextGif
        ? true
        : prevState.playing,
      providedGif: nextGif,
      providedStill: nextStill,
      actualGif: nextGif,
      actualStill: nextStill || prevGif !== nextGif
        ? nextStill
        : prevState.actualStill
    };
  }

  constructor (props) {
    super(props);
    this.state = {
      playing: Boolean(props.autoplay),
      providedGif: props.gif,
      providedStill: props.still,
      actualGif: props.gif,
      actualStill: props.still
    };
    this.updateId = -1;
  }

  componentDidMount () {
    if (typeof this.props.pauseRef === 'function') {
      this.props.pauseRef(() => this.setState({ playing: false }));
    }
    this.updateImages();
  }

  componentDidUpdate (prevProps, prevState) {
    this.updateImages(prevState);
    const { onTogglePlay=()=>{} } = this.props;
    if (prevState.playing !== this.state.playing) {
      onTogglePlay(this.state.playing);
    }
  }

  updateImages (prevState = {}) {
    const { providedGif, providedStill } = this.state;
    if (
      providedGif &&
      !providedStill &&
      providedGif !== prevState.providedGif
    ) {
      const updateId = ++this.updateId;
      preload(providedGif, img => {
        if (this.updateId === updateId) {
          const actualStill = firstGifFrameUrl(img);
          if (actualStill) {
            this.setState({ actualStill });
          }
        }
      });
    }
  }

  toggle () {
    this.setState({
      playing: !this.state.playing
    });
  }

  render () {
    const { actualGif, actualStill, playing } = this.state;
    return (
      <GifPlayer
        gif={actualGif}
        still={actualStill}
        playing={playing}
        toggle={() => this.toggle()}
      />
    );
  }
}

lifecyclesPoylfill(GifPlayerContainer);

GifPlayerContainer.propTypes = {
  gif: PropTypes.string,
  still: PropTypes.string,
  autoplay: PropTypes.bool,
  pauseRef: PropTypes.func,
  onTogglePlay: PropTypes.func,
};

module.exports = GifPlayerContainer;
<commit_msg>On toggle prop: add check for function typeof<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import lifecyclesPoylfill from 'react-lifecycles-compat';

import GifPlayer from './GifPlayer';

const preload = (src, callback) => {
  var img = new Image();
  if (typeof callback === 'function') {
    img.onload = () => callback(img);
    img.setAttribute('crossOrigin', 'anonymous');
  }
  img.src = src;
};

const firstGifFrameUrl = img => {
  const canvas = document.createElement('canvas');
  if (typeof canvas.getContext !== 'function') {
    return null;
  }
  canvas.width = img.width;
  canvas.height = img.height;
  const ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0);
  return canvas.toDataURL();
}

class GifPlayerContainer extends React.Component {
  static getDerivedStateFromProps (nextProps, prevState) {
    const prevGif = prevState.providedGif;
    const nextGif = nextProps.gif;
    const prevStill = prevState.providedStill;
    const nextStill = nextProps.still;
    if (prevGif === nextGif && prevStill === nextStill) {
      return null;
    }

    return {
      playing: nextGif && nextProps.autoplay && prevGif !== nextGif
        ? true
        : prevState.playing,
      providedGif: nextGif,
      providedStill: nextStill,
      actualGif: nextGif,
      actualStill: nextStill || prevGif !== nextGif
        ? nextStill
        : prevState.actualStill
    };
  }

  constructor (props) {
    super(props);
    this.state = {
      playing: Boolean(props.autoplay),
      providedGif: props.gif,
      providedStill: props.still,
      actualGif: props.gif,
      actualStill: props.still
    };
    this.updateId = -1;
  }

  componentDidMount () {
    if (typeof this.props.pauseRef === 'function') {
      this.props.pauseRef(() => this.setState({ playing: false }));
    }
    this.updateImages();
  }

  componentDidUpdate (prevProps, prevState) {
    this.updateImages(prevState);
    const { onTogglePlay } = this.props
    if (prevState.playing !== this.state.playing && typeof onTogglePlay === 'function') {
      onTogglePlay(this.state.playing);
    }
  }

  updateImages (prevState = {}) {
    const { providedGif, providedStill } = this.state;
    if (
      providedGif &&
      !providedStill &&
      providedGif !== prevState.providedGif
    ) {
      const updateId = ++this.updateId;
      preload(providedGif, img => {
        if (this.updateId === updateId) {
          const actualStill = firstGifFrameUrl(img);
          if (actualStill) {
            this.setState({ actualStill });
          }
        }
      });
    }
  }

  toggle () {
    this.setState({
      playing: !this.state.playing
    });
  }

  render () {
    const { actualGif, actualStill, playing } = this.state;
    return (
      <GifPlayer
        gif={actualGif}
        still={actualStill}
        playing={playing}
        toggle={() => this.toggle()}
      />
    );
  }
}

lifecyclesPoylfill(GifPlayerContainer);

GifPlayerContainer.propTypes = {
  gif: PropTypes.string,
  still: PropTypes.string,
  autoplay: PropTypes.bool,
  pauseRef: PropTypes.func,
  onTogglePlay: PropTypes.func,
};

module.exports = GifPlayerContainer;
<|endoftext|>


<commit_before>'use strict';

var _cli = require('./utils/cli');

phantom.onError = function(msg, trace) {
    var msgStack = ['PHANTOM ERROR: ' + msg];
    if (trace && trace.length) {
        msgStack.push('TRACE:');
        trace.forEach(function(t) {
            msgStack.push(' -> '
                + (t.file || t.sourceURL)
                + ': '
                + t.line
                + (t.function ? ' (in function ' + t.function + ')' : ''));
        });
    }
    console.error(msgStack.join('\n'));
    phantom.exit(1);
};

if (_cli.version) {
    // if --version is passed, print version and exit
    var json = require('../package.json');
    var version = json.version;

    console.log('Scout v' + version);
    console.log('http://mennovanslooten.github.io/Scout/');

    phantom.exit(0);
} else if (_cli.reformat) {
    // if --reformat is passed, reformat and exit
    require('./logger/logger').reformat();
    phantom.exit(0);
} else {
    // otherwise, kick off the tests
    require('./core/suite_controller').start();
}
<commit_msg>Accidentally commited dev code<commit_after>'use strict';

var _cli = require('./utils/cli');

if (_cli.version) {
    // if --version is passed, print version and exit
    var json = require('../package.json');
    var version = json.version;

    console.log('Scout v' + version);
    console.log('http://mennovanslooten.github.io/Scout/');

    phantom.exit(0);
} else if (_cli.reformat) {
    // if --reformat is passed, reformat and exit
    require('./logger/logger').reformat();
    phantom.exit(0);
} else {
    // otherwise, kick off the tests
    require('./core/suite_controller').start();
}
<|endoftext|>


<commit_before>/* eslint-disable no-console */
import path from 'path'
import fs from 'fs-extra'
import chalk from 'chalk'
import isObject from 'is-plain-object'

function isProbablyFile(filePath) {
  return path.extname(filePath).length > 1
}

function processArrayOfTargets(targets, outputFolder) {
  return targets.map(target => ({
    from: target,
    to: path.join(outputFolder, path.basename(target))
  }))
}

function processObjectOfTargets(targets, outputFolder = '') {
  return Object.entries(targets).map(([from, to]) => {
    const dest = (isProbablyFile(from) && !isProbablyFile(to))
      ? path.join(outputFolder, to, path.basename(from))
      : path.join(outputFolder, to)

    return { from, to: dest }
  })
}

export default function copy(options = { verbose: false }) {
  const { outputFolder, targets, verbose } = options

  return {
    name: 'copy',
    async generateBundle(outputOptions) {
      let processedTargets = []

      if (Array.isArray(targets) && targets.length) {
        const destFolder = outputFolder || outputOptions.dir || path.dirname(outputOptions.file)

        processedTargets = processArrayOfTargets(targets, destFolder)
      }

      if (isObject(targets) && Object.entries(options).length) {
        processedTargets = processObjectOfTargets(targets, outputFolder)
      }

      if (processedTargets.length) {
        if (verbose) {
          console.log('Copied files and folders:')
        }

        await Promise.all(processedTargets.map(async ({ from, to }) => {
          try {
            await fs.copy(from, to)

            if (verbose) {
              console.log(`${chalk.green(`${from} -> ${to}`)}`)
            }
          } catch (e) {
            this.error(e)
          }
        }))
      }
    }
  }
}
<commit_msg>Fix targets as an object length<commit_after>/* eslint-disable no-console */
import path from 'path'
import fs from 'fs-extra'
import chalk from 'chalk'
import isObject from 'is-plain-object'

function isProbablyFile(filePath) {
  return path.extname(filePath).length > 1
}

function processArrayOfTargets(targets, outputFolder) {
  return targets.map(target => ({
    from: target,
    to: path.join(outputFolder, path.basename(target))
  }))
}

function processObjectOfTargets(targets, outputFolder = '') {
  return Object.entries(targets).map(([from, to]) => {
    const dest = (isProbablyFile(from) && !isProbablyFile(to))
      ? path.join(outputFolder, to, path.basename(from))
      : path.join(outputFolder, to)

    return { from, to: dest }
  })
}

export default function copy(options = { verbose: false }) {
  const { outputFolder, targets, verbose } = options

  return {
    name: 'copy',
    async generateBundle(outputOptions) {
      let processedTargets = []

      if (Array.isArray(targets) && targets.length) {
        const destFolder = outputFolder || outputOptions.dir || path.dirname(outputOptions.file)

        processedTargets = processArrayOfTargets(targets, destFolder)
      }

      if (isObject(targets) && Object.entries(targets).length) {
        processedTargets = processObjectOfTargets(targets, outputFolder)
      }

      if (processedTargets.length) {
        if (verbose) {
          console.log('Copied files and folders:')
        }

        await Promise.all(processedTargets.map(async ({ from, to }) => {
          try {
            await fs.copy(from, to)

            if (verbose) {
              console.log(`${chalk.green(`${from} -> ${to}`)}`)
            }
          } catch (e) {
            this.error(e)
          }
        }))
      }
    }
  }
}
<|endoftext|>


<commit_before>var getByPath = require('./getByPath')
var CreateSignalFactory = require('./CreateSignalFactory.js')
var CreateRegisterModules = require('./CreateRegisterModules.js')
var EventEmitter = require('events').EventEmitter
var Computed = require('./Computed')

var Controller = function (Model) {
  var controller = new EventEmitter()
  var model = Model(controller)
  var signals = {}
  var modules = {}
  var services = {}
  var externalContextProviders = {__cerebral_global__: []}

  var signalFactory = CreateSignalFactory(controller, externalContextProviders)
  var signal = function () {
    var signalNamePath = arguments[0].split('.')
    var signalName = signalNamePath.pop()
    var signalMethodPath = signals
    while (signalNamePath.length) {
      var pathName = signalNamePath.shift()
      signalMethodPath = signalMethodPath[pathName] = signalMethodPath[pathName] || {}
    }
    var signal = signalMethodPath[signalName] = signalFactory.apply(null, arguments)
    return signal
  }
  var service = function (name, service) {
    var serviceNamePath = name.split('.')
    var serviceName = serviceNamePath.pop()
    var serviceMethodPath = services
    while (serviceNamePath.length) {
      var pathName = serviceNamePath.shift()
      serviceMethodPath = serviceMethodPath[pathName] = serviceMethodPath[pathName] || {}
    }
    serviceMethodPath[serviceName] = service
    return service
  }

  controller.getSignals = function (path) {
    return path
      ? getByPath(signals, path)
      : signals
  }
  controller.getServices = function (path) {
    return path
      ? getByPath(services, path)
      : services
  }
  controller.getModel = function () {
    return model
  }
  controller.get = function (path) {
    return model.accessors.get(typeof path === 'string' ? path.split('.') : path)
  }
  controller.logModel = function () {
    return model.logModel()
  }
  controller.getModules = function (moduleName) {
    return moduleName
      ? modules[moduleName]
      : modules
  }

  controller.addModules = CreateRegisterModules(controller, model, modules)

  controller.addSignals = function (signals, options) {
    Object.keys(signals).forEach(function (name) {
      if (signals[name].chain) {
        var optionsCopy = Object.keys(options || {}).reduce(function (optionsCopy, key) {
          optionsCopy[key] = options[key]
          return optionsCopy
        }, {})
        var signalOptions = Object.keys(signals[name]).reduce(function (signalOptions, key) {
          if (key !== 'chain') {
            signalOptions[key] = signals[name][key]
          }
          return signalOptions
        }, optionsCopy)
        signal(name, signals[name].chain, signalOptions)
      } else {
        signal(name, signals[name], options)
      }
    })
  }
  controller.addServices = function (newServices) {
    Object.keys(newServices).forEach(function (key) {
      service(key, newServices[key])
    })
    return controller.getServices()
  }
  controller.addContextProvider = function (provider, scope) {
    if (scope) {
      if (!externalContextProviders[scope]) {
        externalContextProviders[scope] = []
      }
      externalContextProviders[scope].push(provider)
    } else {
      externalContextProviders.__cerebral_global__.push(provider)
    }
    externalContextProviders[scope || '__cerebral_global__'].push(provider)
  }

  controller.on('flush', Computed.updateCache)

  return controller
}

module.exports.getByPath = getByPath
module.exports.Controller = Controller
module.exports.Computed = Computed
module.exports.ServerController = function (state) {
  var model = {
    accessors: {
      get: function (path) {
        path = typeof path === 'string' ? path.split('.') : path
        return path.reduce(function (currentState, key) {
          return currentState[key]
        }, state)
      }
    }
  }

  return {
    isServer: true,
    get: function (path) {
      return model.accessors.get(path)
    }
  }
}
<commit_msg>feat(signals): expose immediate factory to create immediate signals (#302)<commit_after>var getByPath = require('./getByPath')
var CreateSignalFactory = require('./CreateSignalFactory.js')
var CreateRegisterModules = require('./CreateRegisterModules.js')
var EventEmitter = require('events').EventEmitter
var Computed = require('./Computed')

var Controller = function (Model) {
  var controller = new EventEmitter()
  var model = Model(controller)
  var signals = {}
  var modules = {}
  var services = {}
  var externalContextProviders = {__cerebral_global__: []}

  var signalFactory = CreateSignalFactory(controller, externalContextProviders)
  var signal = function () {
    var signalNamePath = arguments[0].split('.')
    var signalName = signalNamePath.pop()
    var signalMethodPath = signals
    while (signalNamePath.length) {
      var pathName = signalNamePath.shift()
      signalMethodPath = signalMethodPath[pathName] = signalMethodPath[pathName] || {}
    }
    var signal = signalMethodPath[signalName] = signalFactory.apply(null, arguments)
    return signal
  }
  var service = function (name, service) {
    var serviceNamePath = name.split('.')
    var serviceName = serviceNamePath.pop()
    var serviceMethodPath = services
    while (serviceNamePath.length) {
      var pathName = serviceNamePath.shift()
      serviceMethodPath = serviceMethodPath[pathName] = serviceMethodPath[pathName] || {}
    }
    serviceMethodPath[serviceName] = service
    return service
  }

  controller.getSignals = function (path) {
    return path
      ? getByPath(signals, path)
      : signals
  }
  controller.getServices = function (path) {
    return path
      ? getByPath(services, path)
      : services
  }
  controller.getModel = function () {
    return model
  }
  controller.get = function (path) {
    return model.accessors.get(typeof path === 'string' ? path.split('.') : path)
  }
  controller.logModel = function () {
    return model.logModel()
  }
  controller.getModules = function (moduleName) {
    return moduleName
      ? modules[moduleName]
      : modules
  }

  controller.addModules = CreateRegisterModules(controller, model, modules)

  controller.addSignals = function (signals, options) {
    Object.keys(signals).forEach(function (name) {
      if (signals[name].chain) {
        var optionsCopy = Object.keys(options || {}).reduce(function (optionsCopy, key) {
          optionsCopy[key] = options[key]
          return optionsCopy
        }, {})
        var signalOptions = Object.keys(signals[name]).reduce(function (signalOptions, key) {
          if (key !== 'chain') {
            signalOptions[key] = signals[name][key]
          }
          return signalOptions
        }, optionsCopy)
        signal(name, signals[name].chain, signalOptions)
      } else {
        signal(name, signals[name], options)
      }
    })
  }
  controller.addServices = function (newServices) {
    Object.keys(newServices).forEach(function (key) {
      service(key, newServices[key])
    })
    return controller.getServices()
  }
  controller.addContextProvider = function (provider, scope) {
    if (scope) {
      if (!externalContextProviders[scope]) {
        externalContextProviders[scope] = []
      }
      externalContextProviders[scope].push(provider)
    } else {
      externalContextProviders.__cerebral_global__.push(provider)
    }
    externalContextProviders[scope || '__cerebral_global__'].push(provider)
  }

  controller.on('flush', Computed.updateCache)

  return controller
}

module.exports.getByPath = getByPath
module.exports.Controller = Controller
module.exports.Computed = Computed
module.exports.immediate = function (chain) {
  return {
    chain: chain,
    immediate: true
  }
}
module.exports.ServerController = function (state) {
  var model = {
    accessors: {
      get: function (path) {
        path = typeof path === 'string' ? path.split('.') : path
        return path.reduce(function (currentState, key) {
          return currentState[key]
        }, state)
      }
    }
  }

  return {
    isServer: true,
    get: function (path) {
      return model.accessors.get(path)
    }
  }
}
<|endoftext|>


<commit_before>import _          from 'lodash';
import {resolve}  from 'path';
import isThere    from 'is-there';
import sass       from 'node-sass';

export default function(url, prev) {
  if (!/\.json$/.test(url)) {
    return sass.NULL;
  }

  let includePaths = this.options.includePaths ? this.options.includePaths.split(':') : [];
  let paths = []
    .concat(prev.slice(0, prev.lastIndexOf('/')))
    .concat(includePaths);

  let files = paths
    .map(path => resolve(path, url))
    .filter(isThere);

  if (files.length === 0) {
    return new Error(`Unable to find "${url}" from the following path(s): ${paths.join(', ')}. Check includePaths.`);
  }

  return {
    contents: parseJSON(require(files[0]))
  };
}

function parseJSON(json) {
  return Object.keys(json)
    .map(key => `$${key}: ${parseValue(json[key])};`)
    .join('\n');
}

function parseValue(value) {
  if (_.isArray(value)) {
    return parseList(value);
  } else if (_.isPlainObject(value)) {
    return parseMap(value);
  } else {
    return value;
  }
}

function parseList(list) {
  return `(${list
    .map(value => parseValue(value))
    .join(',')})`;
}

function parseMap(map) {
  return `(${Object.keys(map)
    .map(key => `${key}: ${parseValue(map[key])}`)
    .join(',')})`;
}
<commit_msg>Hotfix to invalidate cache on every load<commit_after>import _          from 'lodash';
import {resolve}  from 'path';
import isThere    from 'is-there';
import sass       from 'node-sass';

export default function(url, prev) {
  if (!/\.json$/.test(url)) {
    return sass.NULL;
  }

  let includePaths = this.options.includePaths ? this.options.includePaths.split(':') : [];
  let paths = []
    .concat(prev.slice(0, prev.lastIndexOf('/')))
    .concat(includePaths);

  let files = paths
    .map(path => resolve(path, url))
    .filter(isThere);

  if (files.length === 0) {
    return new Error(`Unable to find "${url}" from the following path(s): ${paths.join(', ')}. Check includePaths.`);
  }

  delete require.cache[require.resolve(files[0])];

  return {
    contents: parseJSON(require(files[0]))
  };
}

function parseJSON(json) {
  return Object.keys(json)
    .map(key => `$${key}: ${parseValue(json[key])};`)
    .join('\n');
}

function parseValue(value) {
  if (_.isArray(value)) {
    return parseList(value);
  } else if (_.isPlainObject(value)) {
    return parseMap(value);
  } else {
    return value;
  }
}

function parseList(list) {
  return `(${list
    .map(value => parseValue(value))
    .join(',')})`;
}

function parseMap(map) {
  return `(${Object.keys(map)
    .map(key => `${key}: ${parseValue(map[key])}`)
    .join(',')})`;
}
<|endoftext|>


<commit_before>/**
Copyright 2016 Autodesk,Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/
import React from 'react';
import ReactDOM from 'react-dom';
import { Button, GlobalNav } from './react-hig';

import 'hig.web/dist/hig.css';
import './index.css';

import logo from './bim-logo.png';

const SideNav = GlobalNav.SideNav;
const SectionList = GlobalNav.SideNav.SectionList;
const Section = GlobalNav.SideNav.SectionList.Item;
const Group = GlobalNav.SideNav.SectionList.Item.Group;
const Item = GlobalNav.SideNav.SectionList.Item.Group.Item;
const Container = GlobalNav.Container;
const TopNav = GlobalNav.Container.TopNav;
const SubNav = GlobalNav.Container.SubNav;
const Tabs = GlobalNav.Container.SubNav.Tabs;
const Tab = GlobalNav.Container.SubNav.Tabs.Tab;
const Slot = GlobalNav.Container.Slot;

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      buttonLabel: 'Toggle HIG Menu',
      fn: false,
      group1: true,
      group3: true,
      open: false,
      activeTab: 0,
      tabs: [
        { label: "One", id: 0 },
        { label: "Two", id: 1 }
      ]
    };
  }

  handleChange = event => {
    const buttonLabel = event.target.value;
    this.setState(() => {
      return { buttonLabel };
    });
  };

  handleClick = event => {
    this.setState({ open: !this.state.open });
  };

  fn1 = () => this.setState({ fn: true });

  fn2 = () => this.setState({ fn: false });
  toggleGroup1 = () => this.setState({ group1: !this.state.group1 });

  toggleGroup3 = () => this.setState({ group3: !this.state.group3 });

  addTabBefore = () => {
    const nextLabel = Math.floor((Math.random() * 100000), 5);
    const nextTabs = Array.from(this.state.tabs);
    nextTabs.unshift({ label: nextLabel, id: nextLabel });
    this.setState({ tabs: nextTabs })
  }

  addTabAfter = () => {
    const nextLabel = Math.floor((Math.random() * 100000), 5);
    const nextTabs = Array.from(this.state.tabs);
    nextTabs.push({ label: nextLabel, id: nextLabel });
    this.setState({ tabs: nextTabs })
  }

  removeTab = () => {
    const nextTabs = Array.from(this.state.tabs);
    nextTabs.pop();
    this.setState({ tabs: nextTabs })
  }

  setActiveTab = (activeTabIndex) => {
    this.setState({ activeTab: activeTabIndex });
  }

  render() {
    return (

        <GlobalNav sideNavOpen={this.state.open}>
          <SideNav>
            <SectionList>

                <Group>
                  {this.state.group1 &&
                    <Item
                      icon="project-management"
                      title="Item 1"
                      link="#"
                      onClick={() => alert('item 1 clicked')}
                    />}
                  <Item icon="project-management" title="Item 2" link="#" />

                  {this.state.group1 &&
                    <Item icon="project-management" title="Item 3" link="#" />}
                </Group>

                <Group>
                  <Item
                    icon="project-management"
                    title={this.state.buttonLabel}
                    link="#"
                  />
                </Group>

                <Group>
                  <Item
                    icon="project-management"
                    title="Toggle Group 1"
                    onClick={this.toggleGroup1}
                  />
                  <Item icon="project-management" title="Item 2" link="#" />
                </Group>

            </SectionList>
          </SideNav>
          <Container>
            <TopNav
              logo={logo}
              logoLink="http://autodesk.com"
              onHamburgerClick={this.handleClick}
            />
            <SubNav
              moduleIndicatorName="Documents Library"
              moduleIndicatorIcon="hamburger"
            >
              <Tabs>
                {this.state.tabs.map((tab, i) => {
                  return <Tab key={tab.id} label={tab.label} active={this.state.activeTab === tab.id} onClick={this.setActiveTab.bind(this, tab.id)} />
                })}
              </Tabs>
            </SubNav>

            <Slot>

              <input
                type="text"
                value={this.state.buttonLabel}
                onChange={this.handleChange}
              />

              <Button
                title="Add tab before"
                onClick={this.addTabBefore}
              />
              <Button
                title="Add tab after"
                onClick={this.addTabAfter}
              />
              <Button
                title="Remove tab"
                onClick={this.removeTab}
              />

              Raw denim flexitarian green juice kinfolk. Umami hammock trust fund everyday carry, woke wolf viral sriracha austin. Fingerstache affogato messenger bag salvia, cray iPhone bushwick blue bottle marfa gentrify dreamcatcher pop-up. Slow-carb etsy enamel pin cronut, raclette post-ironic hashtag. Hoodie dreamcatcher enamel pin lumbersexual before they sold out, authentic selvage tumblr vinyl. Hot chicken chillwave coloring book fixie vice venmo echo park portland. Tote bag master cleanse cronut banjo banh mi pitchfork, celiac photo booth.

              Next level deep v roof party, jianbing pok pok pug butcher vape farm-to-table kombucha. Yr snackwave VHS, wolf poutine actually woke poke flexitarian paleo food truck DIY kale chips viral yuccie. Cornhole tattooed vaporware affogato, gentrify mlkshk portland organic. Swag try-hard cronut hashtag, etsy bespoke chia banjo messenger bag. Mustache umami godard man braid cronut yuccie. YOLO vaporware franzen, gochujang typewriter mixtape brunch salvia paleo lyft. Four dollar toast tumblr mustache thundercats single-origin coffee, freegan flexitarian cold-pressed beard roof party VHS venmo af ugh bushwick.

              Ethical man bun shoreditch chambray farm-to-table. Celiac readymade tote bag shabby chic chia, franzen poke meggings pop-up williamsburg VHS. Flexitarian cardigan blog yuccie activated charcoal farm-to-table. Iceland activated charcoal aesthetic, chambray offal snackwave austin four loko stumptown roof party humblebrag. Food truck selfies vexillologist, subway tile direct trade fingerstache tofu biodiesel four dollar toast. Literally squid tattooed jean shorts, raw denim echo park blog mustache skateboard seitan XOXO lo-fi cray hammock shabby chic. Live-edge sustainable pug, pinterest celiac kinfolk wayfarers narwhal art party vegan +1.

              Helvetica DIY portland, sriracha selvage wolf beard plaid quinoa vegan flexitarian poke. Semiotics fam scenester, plaid synth listicle flexitarian subway tile. Cred everyday carry pop-up, forage viral tbh tilde mustache roof party leggings gastropub unicorn synth. Brunch hoodie williamsburg, selfies plaid jianbing deep v lomo truffaut meggings dreamcatcher kitsch. Mustache deep v fap hashtag, freegan quinoa blue bottle green juice helvetica pickled cronut. Photo booth 90's microdosing vexillologist roof party stumptown. Viral hella pitchfork, aesthetic intelligentsia godard hoodie plaid migas iPhone mlkshk tumeric keffiyeh.

              Banh mi pug fanny pack heirloom portland. Humblebrag selvage forage vape organic beard bicycle rights, fam gentrify live-edge. Vape artisan truffaut, celiac prism XOXO drinking vinegar pour-over vinyl chambray lyft venmo. Tattooed edison bulb air plant hot chicken meggings cold-pressed gastropub, tbh tilde hoodie photo booth leggings. Etsy post-ironic fap you probably haven't heard of them, helvetica synth kinfolk listicle mixtape keytar cold-pressed. 90's put a bird on it yr godard prism kogi, live-edge enamel pin hell of photo booth. Raclette portland humblebrag synth af, fashion axe fingerstache ethical snackwave post-ironic cray.

              Messenger bag listicle skateboard normcore. Roof party food truck authentic dreamcatcher lumbersexual ramps. Man bun drinking vinegar mixtape, disrupt sartorial cray lumbersexual bicycle rights fam brunch celiac lyft. Hella edison bulb poke thundercats taxidermy twee. Lomo biodiesel la croix, pitchfork normcore prism godard coloring book cornhole locavore helvetica. Everyday carry distillery tousled, bespoke irony chartreuse lumbersexual fixie. Unicorn asymmetrical tacos poke, tote bag disrupt sriracha coloring book.

              Humblebrag narwhal hammock, cornhole biodiesel lomo vegan twee migas enamel pin iPhone vaporware chicharrones vape wolf. Godard XOXO deep v tbh irony, church-key seitan fixie post-ironic asymmetrical literally put a bird on it. Hell of helvetica cornhole lomo forage. Affogato activated charcoal ugh, +1 vape poutine poke artisan listicle before they sold out brunch prism VHS cronut. Craft beer PBR&B vice, synth XOXO green juice bitters narwhal chicharrones pinterest microdosing intelligentsia wayfarers scenester schlitz. Stumptown synth bicycle rights ugh poke, photo booth quinoa cronut pickled meggings tumeric. Yr wayfarers mustache pitchfork, art party bitters craft beer single-origin coffee.

              Helvetica keytar leggings beard single-origin coffee, mustache organic pabst lumbersexual chartreuse art party waistcoat wolf mixtape 8-bit. Craft beer meggings subway tile hashtag, put a bird on it portland 8-bit cardigan knausgaard. Snackwave try-hard dreamcatcher, XOXO freegan iceland kinfolk readymade microdosing typewriter vegan vinyl live-edge hella direct trade. Heirloom flexitarian brunch, subway tile beard leggings hella echo park kinfolk poutine mustache cold-pressed. Copper mug marfa crucifix, kale chips bitters XOXO disrupt four dollar toast gluten-free scenester farm-to-table. 8-bit YOLO pickled photo booth biodiesel bushwick, gentrify ennui hoodie bespoke poutine twee tumblr cornhole tilde. Hammock authentic cold-pressed, chartreuse messenger bag blue bottle four dollar toast DIY raw denim cray squid poke biodiesel lo-fi taxidermy.

              Messenger bag cardigan schlitz meggings pinterest, ramps whatever keytar taxidermy four loko PBR&B XOXO vaporware DIY direct trade. Occupy banjo succulents tacos, cred raw denim neutra chicharrones actually kickstarter food truck artisan paleo tumblr. Vinyl synth migas shabby chic, whatever shoreditch brooklyn deep v. 90's gochujang retro shoreditch, leggings banh mi dreamcatcher freegan four dollar toast unicorn kogi. Locavore scenester leggings cronut. Forage irony slow-carb plaid fap af. Art party asymmetrical typewriter trust fund, lyft skateboard gastropub small batch artisan squid iceland vegan disrupt master cleanse.

              Scenester fingerstache kitsch post-ironic snackwave, plaid microdosing gastropub whatever. Next level truffaut swag, offal health goth franzen craft beer tousled 90's retro cardigan man bun keffiyeh ugh. Vegan offal tumblr, distillery prism venmo iPhone 90's vaporware 8-bit cronut semiotics. Prism distillery leggings austin selvage mustache. Venmo gentrify schlitz, ennui cred master cleanse umami sustainable freegan. Chartreuse yuccie freegan, poke four dollar toast echo park messenger bag shabby chic bespoke waistcoat glossier. Offal intelligentsia keffiyeh, XOXO waistcoat neutra squid brunch pug tumeric man braid knausgaard.
            </Slot>
          </Container>
        </GlobalNav>

    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
<commit_msg>Satisfy linter<commit_after>/**
Copyright 2016 Autodesk,Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/
import React from 'react';
import ReactDOM from 'react-dom';
import { Button, GlobalNav } from './react-hig';

import 'hig.web/dist/hig.css';
import './index.css';

import logo from './bim-logo.png';

const SideNav = GlobalNav.SideNav;
const SectionList = GlobalNav.SideNav.SectionList;
const Section = GlobalNav.SideNav.SectionList.Item;
const Group = GlobalNav.SideNav.SectionList.Item.Group;
const Item = GlobalNav.SideNav.SectionList.Item.Group.Item;
const Container = GlobalNav.Container;
const TopNav = GlobalNav.Container.TopNav;
const SubNav = GlobalNav.Container.SubNav;
const Tabs = GlobalNav.Container.SubNav.Tabs;
const Tab = GlobalNav.Container.SubNav.Tabs.Tab;
const Slot = GlobalNav.Container.Slot;

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      buttonLabel: 'Toggle HIG Menu',
      fn: false,
      group1: true,
      group3: true,
      open: false,
      activeTab: 0,
      tabs: [{ label: 'One', id: 0 }, { label: 'Two', id: 1 }]
    };
  }

  handleChange = event => {
    const buttonLabel = event.target.value;
    this.setState(() => {
      return { buttonLabel };
    });
  };

  handleClick = event => {
    this.setState({ open: !this.state.open });
  };

  fn1 = () => this.setState({ fn: true });

  fn2 = () => this.setState({ fn: false });
  toggleGroup1 = () => this.setState({ group1: !this.state.group1 });

  toggleGroup3 = () => this.setState({ group3: !this.state.group3 });

  addTabBefore = () => {
    const nextLabel = Math.floor(Math.random() * 100000, 5);
    const nextTabs = Array.from(this.state.tabs);
    nextTabs.unshift({ label: nextLabel, id: nextLabel });
    this.setState({ tabs: nextTabs });
  };

  addTabAfter = () => {
    const nextLabel = Math.floor(Math.random() * 100000, 5);
    const nextTabs = Array.from(this.state.tabs);
    nextTabs.push({ label: nextLabel, id: nextLabel });
    this.setState({ tabs: nextTabs });
  };

  removeTab = () => {
    const nextTabs = Array.from(this.state.tabs);
    nextTabs.pop();
    this.setState({ tabs: nextTabs });
  };

  setActiveTab = activeTabIndex => {
    this.setState({ activeTab: activeTabIndex });
  };

  render() {
    return (

        <GlobalNav sideNavOpen={this.state.open}>
          <SideNav>
            <SectionList>

                <Group>
                  {this.state.group1 &&
                    <Item
                      icon="project-management"
                      title="Item 1"
                      link="#"
                      onClick={() => alert('item 1 clicked')}
                    />}
                  <Item icon="project-management" title="Item 2" link="#" />

                  {this.state.group1 &&
                    <Item icon="project-management" title="Item 3" link="#" />}
                </Group>

                <Group>
                  <Item
                    icon="project-management"
                    title={this.state.buttonLabel}
                    link="#"
                  />
                </Group>

                <Group>
                  <Item
                    icon="project-management"
                    title="Toggle Group 1"
                    onClick={this.toggleGroup1}
                  />
                  <Item icon="project-management" title="Item 2" link="#" />
                </Group>

            </SectionList>
          </SideNav>
          <Container>
            <TopNav
              logo={logo}
              logoLink="http://autodesk.com"
              onHamburgerClick={this.handleClick}
            />
            <SubNav
              moduleIndicatorName="Documents Library"
              moduleIndicatorIcon="hamburger"
            >
              <Tabs>
                {this.state.tabs.map((tab, i) => {
                  return (
                    <Tab
                      key={tab.id}
                      label={tab.label}
                      active={this.state.activeTab === tab.id}
                      onClick={this.setActiveTab.bind(this, tab.id)}
                    />
                  );
                })}
              </Tabs>
            </SubNav>

            <Slot>

              <input
                type="text"
                value={this.state.buttonLabel}
                onChange={this.handleChange}
              />

              <Button title="Add tab before" onClick={this.addTabBefore} />
              <Button title="Add tab after" onClick={this.addTabAfter} />
              <Button title="Remove tab" onClick={this.removeTab} />

              Raw denim flexitarian green juice kinfolk. Umami hammock trust fund everyday carry, woke wolf viral sriracha austin. Fingerstache affogato messenger bag salvia, cray iPhone bushwick blue bottle marfa gentrify dreamcatcher pop-up. Slow-carb etsy enamel pin cronut, raclette post-ironic hashtag. Hoodie dreamcatcher enamel pin lumbersexual before they sold out, authentic selvage tumblr vinyl. Hot chicken chillwave coloring book fixie vice venmo echo park portland. Tote bag master cleanse cronut banjo banh mi pitchfork, celiac photo booth.

              Next level deep v roof party, jianbing pok pok pug butcher vape farm-to-table kombucha. Yr snackwave VHS, wolf poutine actually woke poke flexitarian paleo food truck DIY kale chips viral yuccie. Cornhole tattooed vaporware affogato, gentrify mlkshk portland organic. Swag try-hard cronut hashtag, etsy bespoke chia banjo messenger bag. Mustache umami godard man braid cronut yuccie. YOLO vaporware franzen, gochujang typewriter mixtape brunch salvia paleo lyft. Four dollar toast tumblr mustache thundercats single-origin coffee, freegan flexitarian cold-pressed beard roof party VHS venmo af ugh bushwick.

              Ethical man bun shoreditch chambray farm-to-table. Celiac readymade tote bag shabby chic chia, franzen poke meggings pop-up williamsburg VHS. Flexitarian cardigan blog yuccie activated charcoal farm-to-table. Iceland activated charcoal aesthetic, chambray offal snackwave austin four loko stumptown roof party humblebrag. Food truck selfies vexillologist, subway tile direct trade fingerstache tofu biodiesel four dollar toast. Literally squid tattooed jean shorts, raw denim echo park blog mustache skateboard seitan XOXO lo-fi cray hammock shabby chic. Live-edge sustainable pug, pinterest celiac kinfolk wayfarers narwhal art party vegan +1.

              Helvetica DIY portland, sriracha selvage wolf beard plaid quinoa vegan flexitarian poke. Semiotics fam scenester, plaid synth listicle flexitarian subway tile. Cred everyday carry pop-up, forage viral tbh tilde mustache roof party leggings gastropub unicorn synth. Brunch hoodie williamsburg, selfies plaid jianbing deep v lomo truffaut meggings dreamcatcher kitsch. Mustache deep v fap hashtag, freegan quinoa blue bottle green juice helvetica pickled cronut. Photo booth 90's microdosing vexillologist roof party stumptown. Viral hella pitchfork, aesthetic intelligentsia godard hoodie plaid migas iPhone mlkshk tumeric keffiyeh.

              Banh mi pug fanny pack heirloom portland. Humblebrag selvage forage vape organic beard bicycle rights, fam gentrify live-edge. Vape artisan truffaut, celiac prism XOXO drinking vinegar pour-over vinyl chambray lyft venmo. Tattooed edison bulb air plant hot chicken meggings cold-pressed gastropub, tbh tilde hoodie photo booth leggings. Etsy post-ironic fap you probably haven't heard of them, helvetica synth kinfolk listicle mixtape keytar cold-pressed. 90's put a bird on it yr godard prism kogi, live-edge enamel pin hell of photo booth. Raclette portland humblebrag synth af, fashion axe fingerstache ethical snackwave post-ironic cray.

              Messenger bag listicle skateboard normcore. Roof party food truck authentic dreamcatcher lumbersexual ramps. Man bun drinking vinegar mixtape, disrupt sartorial cray lumbersexual bicycle rights fam brunch celiac lyft. Hella edison bulb poke thundercats taxidermy twee. Lomo biodiesel la croix, pitchfork normcore prism godard coloring book cornhole locavore helvetica. Everyday carry distillery tousled, bespoke irony chartreuse lumbersexual fixie. Unicorn asymmetrical tacos poke, tote bag disrupt sriracha coloring book.

              Humblebrag narwhal hammock, cornhole biodiesel lomo vegan twee migas enamel pin iPhone vaporware chicharrones vape wolf. Godard XOXO deep v tbh irony, church-key seitan fixie post-ironic asymmetrical literally put a bird on it. Hell of helvetica cornhole lomo forage. Affogato activated charcoal ugh, +1 vape poutine poke artisan listicle before they sold out brunch prism VHS cronut. Craft beer PBR&B vice, synth XOXO green juice bitters narwhal chicharrones pinterest microdosing intelligentsia wayfarers scenester schlitz. Stumptown synth bicycle rights ugh poke, photo booth quinoa cronut pickled meggings tumeric. Yr wayfarers mustache pitchfork, art party bitters craft beer single-origin coffee.

              Helvetica keytar leggings beard single-origin coffee, mustache organic pabst lumbersexual chartreuse art party waistcoat wolf mixtape 8-bit. Craft beer meggings subway tile hashtag, put a bird on it portland 8-bit cardigan knausgaard. Snackwave try-hard dreamcatcher, XOXO freegan iceland kinfolk readymade microdosing typewriter vegan vinyl live-edge hella direct trade. Heirloom flexitarian brunch, subway tile beard leggings hella echo park kinfolk poutine mustache cold-pressed. Copper mug marfa crucifix, kale chips bitters XOXO disrupt four dollar toast gluten-free scenester farm-to-table. 8-bit YOLO pickled photo booth biodiesel bushwick, gentrify ennui hoodie bespoke poutine twee tumblr cornhole tilde. Hammock authentic cold-pressed, chartreuse messenger bag blue bottle four dollar toast DIY raw denim cray squid poke biodiesel lo-fi taxidermy.

              Messenger bag cardigan schlitz meggings pinterest, ramps whatever keytar taxidermy four loko PBR&B XOXO vaporware DIY direct trade. Occupy banjo succulents tacos, cred raw denim neutra chicharrones actually kickstarter food truck artisan paleo tumblr. Vinyl synth migas shabby chic, whatever shoreditch brooklyn deep v. 90's gochujang retro shoreditch, leggings banh mi dreamcatcher freegan four dollar toast unicorn kogi. Locavore scenester leggings cronut. Forage irony slow-carb plaid fap af. Art party asymmetrical typewriter trust fund, lyft skateboard gastropub small batch artisan squid iceland vegan disrupt master cleanse.

              Scenester fingerstache kitsch post-ironic snackwave, plaid microdosing gastropub whatever. Next level truffaut swag, offal health goth franzen craft beer tousled 90's retro cardigan man bun keffiyeh ugh. Vegan offal tumblr, distillery prism venmo iPhone 90's vaporware 8-bit cronut semiotics. Prism distillery leggings austin selvage mustache. Venmo gentrify schlitz, ennui cred master cleanse umami sustainable freegan. Chartreuse yuccie freegan, poke four dollar toast echo park messenger bag shabby chic bespoke waistcoat glossier. Offal intelligentsia keffiyeh, XOXO waistcoat neutra squid brunch pug tumeric man braid knausgaard.
            </Slot>
          </Container>
        </GlobalNav>

    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
<|endoftext|>


<commit_before>import middleware from './internal/middleware'
export default middleware

import _SagaCancellationException from './internal/SagaCancellationException'
export const SagaCancellationException = _SagaCancellationException

export { runSaga, storeIO } from './internal/runSaga'

export { takeEvery, takeLatest } from './internal/sagaHelpers'
<commit_msg>add effects/utils in order to attach to umd global object<commit_after>import middleware from './internal/middleware'
export default middleware

import _SagaCancellationException from './internal/SagaCancellationException'
export const SagaCancellationException = _SagaCancellationException

export { runSaga, storeIO } from './internal/runSaga'

export { takeEvery, takeLatest } from './internal/sagaHelpers'

import * as effects from './effects'
import * as utils from './utils'

export {
  effects,
  utils
}
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import { ActionCreators } from 'redux-undo'
import Footer from '../components/Footer'
import DefaultQuestion from '../components/questions/DefaultQuestion'
import TableQuestion from '../components/questions/TableQuestion'
import { findQuestions, findCustomPage } from '../../utils'

export default class Page extends Component {
  makeQuestions() {
    const { page, actions, state } = this.props;
    return findQuestions(state, page.id).map((q) => {
      let component;
      switch (q.questionType) {
        case 'default':
          component = DefaultQuestion;
          break;
        case 'table':
          component = TableQuestion;
          break;
        default:
          throw 'invalid component';
      }
      return React.createElement(component, {
        state: state,
        question: q,
        key: q.id,
        valueChange: actions.valueChange
      });
    });
  }
  renderDefaultPage() {
    return this.makeQuestions();
  }
  renderCustomPage() {
    const { page, state } = this.props;
    const customPage = findCustomPage(state, page.customPageId);
    return

  }
  render() {
    const { page, actions, state } = this.props;
    return (

{page.pageTitle}

        { page.pageType === 'custom' ? this.renderCustomPage() : this.renderDefaultPage() }
        {this.makeQuestions()}

    );
  }
}

Page.propTypes = {
  page: PropTypes.object.isRequired
};
<commit_msg>Questionが2回表示されてしまう不具合を修正<commit_after>import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import { ActionCreators } from 'redux-undo'
import Footer from '../components/Footer'
import DefaultQuestion from '../components/questions/DefaultQuestion'
import TableQuestion from '../components/questions/TableQuestion'
import { findQuestions, findCustomPage } from '../../utils'

export default class Page extends Component {
  makeQuestions() {
    const { page, actions, state } = this.props;
    return findQuestions(state, page.id).map((q) => {
      let component;
      switch (q.questionType) {
        case 'default':
          component = DefaultQuestion;
          break;
        case 'table':
          component = TableQuestion;
          break;
        default:
          throw 'invalid component';
      }
      return React.createElement(component, {
        state: state,
        question: q,
        key: q.id,
        valueChange: actions.valueChange
      });
    });
  }
  renderDefaultPage() {
    return this.makeQuestions();
  }
  renderCustomPage() {
    const { page, state } = this.props;
    const customPage = findCustomPage(state, page.customPageId);
    return

  }
  render() {
    const { page, actions, state } = this.props;
    return (

{page.pageTitle}

        { page.pageType === 'custom' ? this.renderCustomPage() : this.renderDefaultPage() }

    );
  }
}

Page.propTypes = {
  page: PropTypes.object.isRequired
};
<|endoftext|>