<commit_before>'use strict';

/**
 * Load required plugins
 */
var gulp = require('gulp'),
  $ = require('gulp-load-plugins')(),
  browserSync = require('browser-sync'),
  reload = browserSync.reload,
  runSequence = require('run-sequence'),
  argv = require('yargs').argv,
  rimraf = require('rimraf'),
  assemble = require('fabricator-assemble'),
  yaml = require('js-yaml'),
  fs = require('fs'),
  globby = require('globby'),
  path = require('path'),
  markdown = require('markdown-it')({
    html: true
  });

/**
 * Configuration
 */
var config = {
  dev: $.util.env.dev,
  src: {
    styles: {
      fabricator: 'src/assets/fabricator/styles/fabricator.scss'
    },
    javascript: {
      fabricator: [
        'node_modules/prismjs/prism.js',
        'src/assets/fabricator/scripts/*.js'
      ]
    }
  },
  styleguide: {
    dest: 'styleguide'
  },
  framework: {
    dest: 'build'
  },
  locales: yaml.safeLoad(fs.readFileSync('src/data/locales.yml', 'utf-8')),
  autoprefixer: ['last 2 versions', 'safari 8', 'ie 9', 'ff 28']
};

/**
 * Build vendors dependencies
 */
gulp.task('vendors', function() {

  // CSS VENDORS
  gulp.src([
    'node_modules/Yamm/yamm/yamm.css',
    'node_modules/bootstrap-accessibility-plugin/plugins/css/bootstrap-accessibility.css',
    'node_modules/blueimp-gallery/css/blueimp-gallery.min.css',
    'node_modules/blueimp-bootstrap-image-gallery/css/bootstrap-image-gallery.min.css',
    'node_modules/pikaday/css/pikaday.css'
  ])
    .pipe($.concat('vendors.css'))
    .pipe($.cleanCss())
    .pipe(gulp.dest(config.framework.dest + '/css'));

  // JS VENDORS
  // (with jQuery and Bootstrap dependencies first)
  gulp.src([
    'node_modules/jquery/dist/jquery.js',
    'node_modules/drmonty-chosen/js/chosen.jquery.js',
    'node_modules/typeahead.js/dist/typeahead.bundle.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/affix.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/alert.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/button.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/carousel.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/collapse.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/dropdown.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/modal.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/tooltip.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/popover.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/scrollspy.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/tab.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/transition.js',
    'node_modules/bootstrap-accessibility-plugin/plugins/js/bootstrap-accessibility.js',
    'node_modules/tablesorter/dist/js/jquery.tablesorter.js',
    'node_modules/jquery-drilldown/dist/jquery.drilldown.js',
    'node_modules/Placeholdr/placeholdr.js',
    'node_modules/blueimp-gallery/js/jquery.blueimp-gallery.min.js',
    'node_modules/blueimp-bootstrap-image-gallery/js/bootstrap-image-gallery.min.js',
    'node_modules/moment/moment.js',
    'node_modules/pikaday/pikaday.js',
    'node_modules/twitter-timeline/index.js'
  ])
    .pipe($.concat('vendors.js'))
    .pipe(gulp.dest(config.framework.dest + '/js'))
    .pipe($.concat('vendors.min.js'))
    .pipe($.uglify())
    .pipe(gulp.dest(config.framework.dest + '/js'));

  // FONTS SOURCES
  // Important to add the bootstrap fonts to avoid issues with the fonts include path
  gulp.src([
    'node_modules/bootstrap-sass/assets/fonts/bootstrap/*',
    'assets/fonts/*'
  ])
    .pipe(gulp.dest(config.framework.dest + '/fonts'));
});

/**
 * Build styles from SCSS files
 * With error reporting on compiling (so that there's no crash)
 */
gulp.task('styles', function() {
  if (!argv.dev) { console.log('[styles] Outputting minified styles.' ); }
  else { console.log('[styles] Processing styles for dev env. No minifying here, for sourcemaps!') }

  return gulp.src('src/assets/sass/admin.scss')
    .pipe($.sass().on('error', $.sass.logError))
    .pipe($.if(argv.dev, $.sourcemaps.init()))
    .pipe($.autoprefixer({
      browsers: config.autoprefixer
    }))
    .pipe($.if(argv.dev, $.sourcemaps.write()))
    .pipe($.if(!argv.dev, $.cleanCss()))
    .pipe(gulp.dest(config.framework.dest + '/css'));
});

gulp.task('print', function() {
  return gulp.src('src/assets/sass/print/print.scss')
    .pipe($.sass().on('error', $.sass.logError))
    .pipe($.if(argv.dev, $.sourcemaps.init()))
    .pipe($.autoprefixer({
      browsers: config.autoprefixer
    }))
    .pipe($.if(argv.dev, $.sourcemaps.write()))
    .pipe($.if(!argv.dev, $.cleanCss()))
    .pipe(gulp.dest(config.framework.dest + '/css'));
});

gulp.task('twitter-inject', function() {
  return gulp.src('src/assets/sass/twitter-inject.scss')
    .pipe($.sass().on('error', $.sass.logError))
    .pipe($.if(argv.dev, $.sourcemaps.init()))
    .pipe($.autoprefixer({
      browsers: config.autoprefixer
    }))
    .pipe($.if(argv.dev, $.sourcemaps.write()))
    .pipe($.if(!argv.dev, $.cleanCss()))
    .pipe(gulp.dest(config.framework.dest + '/css'));
});

/**
 * Build JS
 * With error reporting on compiling (so that there's no crash)
 */
gulp.task('scripts', function() {
  return gulp.src(['src/assets/js/*.js'])
    .pipe($.jshint())
    .pipe($.jshint.reporter('jshint-stylish'))
    .pipe($.concat('main.js'))
    .pipe(gulp.dest(config.framework.dest + '/js'))
    .pipe($.rename({ suffix: '.min' }))
    .pipe($.uglify())
    .pipe(gulp.dest(config.framework.dest + '/js'));
});

/**
 * Copy images to build
 */
gulp.task('build-images', function() {
  return gulp.src(['src/assets/img/**', 'node_modules/blueimp-gallery/img/**'])
    .pipe(gulp.dest(config.framework.dest + '/img'));
});

/**
 * Copy fonts to build
 */
gulp.task('build-fonts', function() {
  return gulp.src(['src/assets/fonts/**'])
    .pipe(gulp.dest(config.framework.dest + '/fonts'));
});

/**
 * Compile TWIG example pages
 */
gulp.task('clean-twig', function(cb) {
  rimraf('src/views/pages', cb);
});

gulp.task('twig', ['clean-twig'], function() {
  return gulp.src(['src/example-pages/*.twig', '!src/example-pages/layout.twig'])
    .pipe($.twig())
    .pipe(gulp.dest('src/views/pages'));
});

/**
 * FABRICATOR
 */
// Build the style guide
gulp.task('assemble-everything', function(cb) {
  runSequence('clean', 'assemble', 'copy', 'styles:fabricator', 'scripts:fabricator', cb);
});

gulp.task('assemble', function(done) {
  // Build style guide for every language
  for (var localeCode in config.locales) {
    var locale = config.locales[localeCode];

    // Do not build disabled locales
    if (locale.disabled) continue;

    var dest = config.styleguide.dest + '/' + locale.code,
      data = {
        locale: locale.code,
        version: fs.readFileSync('VERSION', 'utf-8')
      },
      dictionary = {};

    // Get all translation files for the current locale
    var translations = globby.sync('src/locales/' + locale.code + '/*.yml');

    // Build a dictionary using the filename as the main key
    translations.forEach(function(file) {
      var id = path.basename(file, path.extname(file));
      dictionary[id] = yaml.safeLoad(fs.readFileSync(file, 'utf-8'));
    });

    // Assemble the style guide
    assemble({
      dest: dest,
      logErrors: config.dev,
      helpers: {
        // Register the translation helper
        t: function() {
          // Build an array out of fn arguments
          var args = Array.prototype.slice.call(arguments);
          // Remove the last entry which is an object given by Handlebars
          var obj = args.pop();

          // Build a full translation key with all arguments
          args = args.join('.');

          // Remove any digits coming from the component key prefix
          args = args.replace(/(\d+[\-\.]?)/g, '');

          // Look for the translation in the dictionnary
          var value = args.trim().split('.').reduce(function(dict, key){
            if (!dict) {
              return null;
            }
            return dict[key];
          }, dictionary);

          // Parse content for Markdown if required
          if (value && obj.hash && obj.hash.markdown) {
            var value = markdown.render(value);
          }

          return value || '[Missing translation: ' + args + ']';
        },
        // Return true if the language given match with the current locale
        isCurrentLocale: function(lang, options) {
          if (lang === locale.code) {
            return options.fn(this);
          }
          return options.inverse(this);
        },
        // Return the corresponding data value
        data: function(value) {
          return data[value] || '';
        },
        toUpperCase: function(value) {
          return value.toUpperCase();
        },
        renderFile: function(path, file) {
          var fileName = 'src/materials-data/' + path + file,
            exists = fs.existsSync(fileName);

          if (!exists) return '[File "' + fileName + '" doesn’t exist.]';

          return fs.readFileSync(fileName, 'utf-8');
        },
        replace: function(regex, newSubstr, str) {
          return str.replace(new RegExp(regex, 'g'), newSubstr);
        },
        modulo: function(index, divider, block) {
          if ((parseInt(index,10) + 1) % divider === 0) {
            return block.fn(this);
          }
        },
        // Remove number prefixes (01- or 01.02-)
        prefixless: function(value) {
          return value.replace(/(\d+[\-\.]?)+/ig, '');
        }
      }
    })
  }
  done();
});

// Copy all the required files to the styleguide folder
gulp.task('copy', ['copy:framework', 'copy:assets', 'copy:landing', 'copy:files']);

gulp.task('copy:framework', function() {
  return gulp.src([config.framework.dest + '/**/*'])
    .pipe(gulp.dest(config.styleguide.dest));
});

gulp.task('copy:assets', function() {
  return gulp.src(['styleguide-img/**/*'])
    .pipe(gulp.dest(config.styleguide.dest + '/styleguide-img'));
});

gulp.task('copy:landing', function() {
  return gulp.src(['src/index.html'])
    .pipe(gulp.dest(config.styleguide.dest));
});

gulp.task('copy:files', function() {
  return gulp.src(['src/assets/files/*'])
    .pipe(gulp.dest(config.styleguide.dest + '/files'));
});

// Build Fabricator style
gulp.task('styles:fabricator', function() {
  gulp.src(config.src.styles.fabricator)
    .pipe($.sourcemaps.init())
    .pipe($.sass().on('error', $.sass.logError))
    .pipe($.autoprefixer({
      browsers: config.autoprefixer
    }))
    .pipe($.if(!config.dev, $.cleanCss()))
    .pipe($.sourcemaps.write())
    .pipe(gulp.dest(config.styleguide.dest + '/css'))
    .pipe($.if(config.dev, reload({stream:true})));
});

// Build Fabricator scripts
gulp.task('scripts:fabricator', function() {
  return gulp.src(config.src.javascript.fabricator)
    .pipe($.concat('fabricator.min.js'))
    .pipe($.uglify())
    .pipe(gulp.dest(config.styleguide.dest + '/js'));
});

/**
 * Clean output directories
 */
gulp.task('clean', function(cb) {
  rimraf(config.styleguide.dest, cb);
});

/**
 * Serve
 */
gulp.task('serve', ['assemble-everything'], function () {
  browserSync({
    server: {
      baseDir: config.styleguide.dest
    },
    notify: false,
    open: false
  });

  gulp.task('assemble:watch', ['assemble-everything'], reload);
  gulp.watch(['src/**/*.{html,md,json,yml}'], ['assemble:watch']);

  gulp.watch(['src/assets/sass/**/*.scss', 'src/assets/fabricator/styles/**/*.scss'], function() {
    runSequence('styles', 'print', 'twitter-inject', 'assemble:watch');
  });
  gulp.watch(['src/assets/js/*.js', 'src/assets/fabricator/scripts/**/*.js'], function() {
    runSequence('scripts', 'assemble:watch');
  });
  gulp.watch(['src/assets/img/**/*.{jpg,png,gif,svg}'], function() {
    runSequence('build-images', 'assemble:watch');
  });
  gulp.watch(['src/assets/fonts/**/*.{eot,woff,woff2,ttf}'], function() {
    runSequence('build-fonts', 'assemble:watch');
  });
  gulp.watch(['src/example-pages/*.twig'], function() {
    runSequence('twig', 'assemble:watch');
  });
});

/**
 * Deploy to GH pages
 */
gulp.task('deploy', function () {
  if (argv.github) {
    return gulp.src(config.styleguide.dest + '/**/*')
      .pipe($.ghPages());
  }
  else {
    return gulp.src(config.styleguide.dest + '/**/*')
      .pipe($.rsync({
        root: 'styleguide',
        hostname: 'swg',
        destination: '/var/www/swg',
        progress: true,
        recursive: true,
        clean: true
      }));
  }
});

/**
 * Default task build the style guide
 */
gulp.task('default', ['clean'], function(cb) {
  runSequence(
    'vendors',
    'styles',
    'print',
    'twitter-inject',
    'scripts',
    'twig',
    'build-images',
    'build-fonts',
    'styles:fabricator',
    'scripts:fabricator',
    'assemble',
    'copy',
    cb
  );
});
<commit_msg>refactor: improve build<commit_after>'use strict';

/**
 * Load required plugins
 */
var gulp = require('gulp'),
  $ = require('gulp-load-plugins')(),
  autoprefixer = require('gulp-autoprefixer'),
  concat = require('gulp-concat'),
  cleanCss = require('gulp-clean-css'),
  ghPages = require('gulp-gh-pages'),
  jshint = require('gulp-jshint'),
  rename = require('gulp-rename'),
  rsync = require('gulp-rsync'),
  sass = require('gulp-sass'),
  sourcemaps = require('gulp-sourcemaps'),
  twig = require('gulp-twig'),
  uglify = require('gulp-uglify'),

  browserSync = require('browser-sync'),
  reload = browserSync.reload,
  runSequence = require('run-sequence'),
  argv = require('yargs').argv,
  rimraf = require('rimraf'),
  assemble = require('fabricator-assemble'),
  yaml = require('js-yaml'),
  fs = require('fs'),
  globby = require('globby'),
  path = require('path'),
  markdown = require('markdown-it')({
    html: true
  });

/**
 * Configuration
 */
var config = {
  dev: $.util.env.dev,
  src: {
    styles: {
      fabricator: 'src/assets/fabricator/styles/fabricator.scss'
    },
    javascript: {
      fabricator: [
        'node_modules/prismjs/prism.js',
        'src/assets/fabricator/scripts/*.js'
      ]
    }
  },
  styleguide: {
    dest: 'styleguide'
  },
  framework: {
    dest: 'build'
  },
  locales: yaml.safeLoad(fs.readFileSync('src/data/locales.yml', 'utf-8')),
  autoprefixer: ['last 2 versions', 'safari 8', 'ie 9', 'ff 28']
};

/**
 * Build vendors dependencies
 */
gulp.task('vendors', function() {

  // CSS VENDORS
  gulp.src([
    'node_modules/Yamm/yamm/yamm.css',
    'node_modules/bootstrap-accessibility-plugin/plugins/css/bootstrap-accessibility.css',
    'node_modules/blueimp-gallery/css/blueimp-gallery.min.css',
    'node_modules/blueimp-bootstrap-image-gallery/css/bootstrap-image-gallery.min.css',
    'node_modules/pikaday/css/pikaday.css'
  ])
    .pipe(concat('vendors.css'))
    .pipe(cleanCss())
    .pipe(gulp.dest(config.framework.dest + '/css'));

  // JS VENDORS
  // (with jQuery and Bootstrap dependencies first)
  gulp.src([
    'node_modules/jquery/dist/jquery.js',
    'node_modules/drmonty-chosen/js/chosen.jquery.js',
    'node_modules/typeahead.js/dist/typeahead.bundle.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/affix.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/alert.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/button.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/carousel.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/collapse.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/dropdown.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/modal.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/tooltip.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/popover.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/scrollspy.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/tab.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap/transition.js',
    'node_modules/bootstrap-accessibility-plugin/plugins/js/bootstrap-accessibility.js',
    'node_modules/tablesorter/dist/js/jquery.tablesorter.js',
    'node_modules/jquery-drilldown/dist/jquery.drilldown.js',
    'node_modules/Placeholdr/placeholdr.js',
    'node_modules/blueimp-gallery/js/jquery.blueimp-gallery.min.js',
    'node_modules/blueimp-bootstrap-image-gallery/js/bootstrap-image-gallery.min.js',
    'node_modules/moment/moment.js',
    'node_modules/pikaday/pikaday.js',
    'node_modules/twitter-timeline/index.js'
  ])
    .pipe(concat('vendors.js'))
    .pipe(gulp.dest(config.framework.dest + '/js'))
    .pipe(concat('vendors.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest(config.framework.dest + '/js'));

  // FONTS SOURCES
  // Important to add the bootstrap fonts to avoid issues with the fonts include path
  gulp.src([
    'node_modules/bootstrap-sass/assets/fonts/bootstrap/*',
    'assets/fonts/*'
  ])
    .pipe(gulp.dest(config.framework.dest + '/fonts'));
});

/**
 * Build styles from SCSS files
 * With error reporting on compiling (so that there's no crash)
 */
gulp.task('styles', function() {
  if (!argv.dev) { console.log('[styles] Outputting minified styles.' ); }
  else { console.log('[styles] Processing styles for dev env. No minifying here, for sourcemaps!') }

  return gulp.src('src/assets/sass/admin.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe($.if(argv.dev, sourcemaps.init()))
    .pipe(autoprefixer({
      browsers: config.autoprefixer
    }))
    .pipe($.if(argv.dev, sourcemaps.write()))
    .pipe($.if(!argv.dev, cleanCss()))
    .pipe(gulp.dest(config.framework.dest + '/css'));
});

gulp.task('print', function() {
  return gulp.src('src/assets/sass/print/print.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe($.if(argv.dev, sourcemaps.init()))
    .pipe(autoprefixer({
      browsers: config.autoprefixer
    }))
    .pipe($.if(argv.dev, sourcemaps.write()))
    .pipe($.if(!argv.dev, cleanCss()))
    .pipe(gulp.dest(config.framework.dest + '/css'));
});

gulp.task('twitter-inject', function() {
  return gulp.src('src/assets/sass/twitter-inject.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe($.if(argv.dev, sourcemaps.init()))
    .pipe(autoprefixer({
      browsers: config.autoprefixer
    }))
    .pipe($.if(argv.dev, sourcemaps.write()))
    .pipe($.if(!argv.dev, cleanCss()))
    .pipe(gulp.dest(config.framework.dest + '/css'));
});

/**
 * Build JS
 * With error reporting on compiling (so that there's no crash)
 */
gulp.task('scripts', function() {
  return gulp.src(['src/assets/js/*.js'])
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(concat('main.js'))
    .pipe(gulp.dest(config.framework.dest + '/js'))
    .pipe(rename({ suffix: '.min' }))
    .pipe(uglify())
    .pipe(gulp.dest(config.framework.dest + '/js'));
});

/**
 * Copy images to build
 */
gulp.task('build-images', function() {
  return gulp.src(['src/assets/img/**', 'node_modules/blueimp-gallery/img/**'])
    .pipe(gulp.dest(config.framework.dest + '/img'));
});

/**
 * Copy fonts to build
 */
gulp.task('build-fonts', function() {
  return gulp.src(['src/assets/fonts/**'])
    .pipe(gulp.dest(config.framework.dest + '/fonts'));
});

/**
 * Compile TWIG example pages
 */
gulp.task('clean-twig', function(cb) {
  rimraf('src/views/pages', cb);
});

gulp.task('twig', ['clean-twig'], function() {
  return gulp.src(['src/example-pages/*.twig', '!src/example-pages/layout.twig'])
    .pipe(twig())
    .pipe(gulp.dest('src/views/pages'));
});

/**
 * FABRICATOR
 */
// Build the style guide
gulp.task('assemble-everything', function(cb) {
  runSequence('clean', 'assemble', 'copy', 'styles:fabricator', 'scripts:fabricator', cb);
});

gulp.task('assemble', function(done) {
  // Build style guide for every language
  for (var localeCode in config.locales) {
    if (config.locales.hasOwnProperty(localeCode)) {
      var locale = config.locales[localeCode];

      // Do not build disabled locales
      if (locale.disabled) continue;

      var dest = config.styleguide.dest + '/' + locale.code,
        data = {
          locale: locale.code,
          version: fs.readFileSync('VERSION', 'utf-8')
        },
        dictionary = {};

      // Get all translation files for the current locale
      var translations = globby.sync('src/locales/' + locale.code + '/*.yml');

      // Build a dictionary using the filename as the main key
      translations.forEach(function (file) {
        var id = path.basename(file, path.extname(file));
        dictionary[id] = yaml.safeLoad(fs.readFileSync(file, 'utf-8'));
      });

      // Assemble the style guide
      assemble({
        dest: dest,
        logErrors: config.dev,
        helpers: {
          // Register the translation helper
          t: function () {
            // Build an array out of fn arguments
            var args = Array.prototype.slice.call(arguments);
            // Remove the last entry which is an object given by Handlebars
            var obj = args.pop();

            // Build a full translation key with all arguments
            args = args.join('.');

            // Remove any digits coming from the component key prefix
            args = args.replace(/(\d+[\-\.]?)/g, '');

            // Look for the translation in the dictionnary
            var value = args.trim().split('.').reduce(function (dict, key) {
              if (!dict) {
                return null;
              }
              return dict[key];
            }, dictionary);

            // Parse content for Markdown if required
            if (value && obj.hash && obj.hash.markdown) {
              var value = markdown.render(value);
            }

            return value || '[Missing translation: ' + args + ']';
          },
          // Return true if the language given match with the current locale
          isCurrentLocale: function (lang, options) {
            if (lang === locale.code) {
              return options.fn(this);
            }
            return options.inverse(this);
          },
          // Return the corresponding data value
          data: function (value) {
            return data[value] || '';
          },
          toUpperCase: function (value) {
            return value.toUpperCase();
          },
          renderFile: function (path, file) {
            var fileName = 'src/materials-data/' + path + file,
              exists = fs.existsSync(fileName);

            if (!exists) return '[File "' + fileName + '" doesn’t exist.]';

            return fs.readFileSync(fileName, 'utf-8');
          },
          replace: function (regex, newSubstr, str) {
            return str.replace(new RegExp(regex, 'g'), newSubstr);
          },
          modulo: function (index, divider, block) {
            if ((parseInt(index, 10) + 1) % divider === 0) {
              return block.fn(this);
            }
          },
          // Remove number prefixes (01- or 01.02-)
          prefixless: function (value) {
            return value.replace(/(\d+[\-\.]?)+/ig, '');
          }
        }
      })
    }
  }
  done();
});

// Copy all the required files to the styleguide folder
gulp.task('copy', ['copy:framework', 'copy:assets', 'copy:landing', 'copy:files']);

gulp.task('copy:framework', function() {
  return gulp.src([config.framework.dest + '/**/*'])
    .pipe(gulp.dest(config.styleguide.dest));
});

gulp.task('copy:assets', function() {
  return gulp.src(['styleguide-img/**/*'])
    .pipe(gulp.dest(config.styleguide.dest + '/styleguide-img'));
});

gulp.task('copy:landing', function() {
  return gulp.src(['src/index.html'])
    .pipe(gulp.dest(config.styleguide.dest));
});

gulp.task('copy:files', function() {
  return gulp.src(['src/assets/files/*'])
    .pipe(gulp.dest(config.styleguide.dest + '/files'));
});

// Build Fabricator style
gulp.task('styles:fabricator', function() {
  gulp.src(config.src.styles.fabricator)
    .pipe(sourcemaps.init())
    .pipe(sass().on('error', sass.logError))
    .pipe(autoprefixer({
      browsers: config.autoprefixer
    }))
    .pipe($.if(!config.dev, cleanCss()))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest(config.styleguide.dest + '/css'))
    .pipe($.if(config.dev, reload({stream:true})));
});

// Build Fabricator scripts
gulp.task('scripts:fabricator', function() {
  return gulp.src(config.src.javascript.fabricator)
    .pipe(concat('fabricator.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest(config.styleguide.dest + '/js'));
});

/**
 * Clean output directories
 */
gulp.task('clean', function(cb) {
  rimraf(config.styleguide.dest, cb);
});

/**
 * Serve
 */
gulp.task('serve', ['assemble-everything'], function () {
  browserSync({
    server: {
      baseDir: config.styleguide.dest
    },
    notify: false,
    open: false
  });

  gulp.task('assemble:watch', ['assemble-everything'], reload);
  gulp.watch(['src/**/*.{html,md,json,yml}'], ['assemble:watch']);

  gulp.watch(['src/assets/sass/**/*.scss', 'src/assets/fabricator/styles/**/*.scss'], function() {
    runSequence('styles', 'print', 'twitter-inject', 'assemble:watch');
  });
  gulp.watch(['src/assets/js/*.js', 'src/assets/fabricator/scripts/**/*.js'], function() {
    runSequence('scripts', 'assemble:watch');
  });
  gulp.watch(['src/assets/img/**/*.{jpg,png,gif,svg}'], function() {
    runSequence('build-images', 'assemble:watch');
  });
  gulp.watch(['src/assets/fonts/**/*.{eot,woff,woff2,ttf}'], function() {
    runSequence('build-fonts', 'assemble:watch');
  });
  gulp.watch(['src/example-pages/*.twig'], function() {
    runSequence('twig', 'assemble:watch');
  });
});

/**
 * Deploy to GH pages
 */
gulp.task('deploy', function () {
  if (argv.github) {
    return gulp.src(config.styleguide.dest + '/**/*')
      .pipe(ghPages());
  }
  else {
    return gulp.src(config.styleguide.dest + '/**/*')
      .pipe(rsync({
        root: 'styleguide',
        hostname: 'swg',
        destination: '/var/www/swg',
        progress: true,
        recursive: true,
        clean: true
      }));
  }
});

/**
 * Default task build the style guide
 */
gulp.task('default', ['clean'], function(cb) {
  runSequence(
    'vendors',
    'styles',
    'print',
    'twitter-inject',
    'scripts',
    'twig',
    'build-images',
    'build-fonts',
    'styles:fabricator',
    'scripts:fabricator',
    'assemble',
    'copy',
    cb
  );
});
<|endoftext|>


<commit_before>const gulp = require('gulp');
const eslint = require('gulp-eslint');
const mocha = require('gulp-mocha');
const nodemon = require('gulp-nodemon');

var lintFiles = ['lib/**/*.js', 'models/**/*.js', 'routes/**/*.js', 'test/**/*.js',
                 '_server.js', 'gulpfile.js', 'index.js', 'server.js'];
var testFiles = ['lib/**/*.js', 'models/**/*.js', 'routes/**/*.js', 'test/**/*.js',
                 '_server.js', 'server.js'];

gulp.task('lint', () => {
  return gulp.src(lintFiles)
    .pipe(eslint({
      useEslintrc: true
    }))
    .pipe(eslint.format());
});

gulp.task('test', () => {
  return gulp.src('test/**/*.js')
    .pipe(mocha({
      reporter: 'spec'
    }));
});

gulp.task('develop', () => {
  nodemon({
    script: 'server.js',
    ext: 'js',
    tasks: ['lint', 'test']
  })
  .on('restart', () => {
    process.stdout.write('Server restarted!\n');
  });
});

gulp.task('watch', () => {
  gulp.watch(lintFiles, ['lint']);
  gulp.watch(testFiles, ['test']);
});

gulp.task('default', ['lint', 'test']);
<commit_msg>Adjust gulp-eslint to fail on error<commit_after>const gulp = require('gulp');
const eslint = require('gulp-eslint');
const mocha = require('gulp-mocha');
const nodemon = require('gulp-nodemon');

var lintFiles = ['lib/**/*.js', 'models/**/*.js', 'routes/**/*.js', 'test/**/*.js',
                 '_server.js', 'gulpfile.js', 'index.js', 'server.js'];
var testFiles = ['lib/**/*.js', 'models/**/*.js', 'routes/**/*.js', 'test/**/*.js',
                 '_server.js', 'server.js'];

gulp.task('lint', () => {
  return gulp.src(lintFiles)
    .pipe(eslint({
      useEslintrc: true
    }))
    .pipe(eslint.format())
    .pipe(eslint.failOnError());
});

gulp.task('test', () => {
  return gulp.src('test/**/*.js')
    .pipe(mocha({
      reporter: 'spec'
    }));
});

gulp.task('develop', () => {
  nodemon({
    script: 'server.js',
    ext: 'js',
    tasks: ['lint', 'test']
  })
  .on('restart', () => {
    process.stdout.write('Server restarted!\n');
  });
});

gulp.task('watch', () => {
  gulp.watch(lintFiles, ['lint']);
  gulp.watch(testFiles, ['test']);
});

gulp.task('default', ['lint', 'test']);
<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');
var Handlebars = require('handlebars');
var $ = require('gulp-load-plugins')();
var seq = require('run-sequence');
var through = require('through2');

/*************************************************************************
 * initialize makdoc
 */
var makdoc = require('gulp-makdoc'); // should init before local task
makdoc.init(gulp, Handlebars);

/*************************************************************************
 * tasks
 */

gulp.task('deploy', ['makdoc'], function () {
    var deploy = require('gulp-gh-pages');
    var path = require('path');

    return gulp.src([path.join($.makdoc.vars.DIST(),'**/*'),
                    '!**/*.map'])
        .pipe(deploy({
            remoteUrl: 'git@github.com:pismute/pismute.github.io.git',
            cacheDir: '.gh-pages',
            branch:'master'
        }));
});

// Bower helper
gulp.task('bower', function() {
    var base = 'app/bower_components/';
    var files = [
        'requirejs/require.js',
        'bootstrap/dist/**/*.min.{js,css}',
        'bootstrap-material-design/dist/**/material.min.{js,css}',
        'bootstrap-material-design/dist/**/ripples.min.{js,css}',
        '{d3,jquery,lodash,dashbars}/**/*.min.js',
        'moment/min/{locales,moment}.min.js',
        'handlebars/handlebars/handlebars.min.js'
    ];
    files = files.map(function(file){
        return 'app/bower_components/' + file;
    });

    return gulp.src(files, {base:base})
        .pipe(gulp.dest('dist/bower_components/'));
});

gulp.task('makdoc:init:after', function(done){
    var returns = function(v) {
        return function(){
            return v;
        };
    };

    $.makdoc.vars.BASE_URL = returns('http://pismute.github.io/'),

    done();
});

gulp.task('makdoc:done:after', function(done){
    seq(['bower',
         'lint'],
        done);
});

gulp.task('lint', function(){
    return gulp.src(['gulpfiles.js', './gulp/**/*.js'])
        .pipe($.cached('lint'))
        .pipe($.jshint('.jshintrc'))
        .pipe($.jshint.reporter('default'));
});

/*************************************************************************
 * template data
 */

makdoc.templateData({
    package:require('./package.json')
});

/*************************************************************************
 * override:highlight
 */

var _alias = {
    'js-run': 'js',
    'js-run-d3': 'js'
};

makdoc.util.highlight = function() {
    var _highlight = makdoc.util.highlight_pygment();
    return function(code, lang, done){
        return _highlight(code, _alias[lang] || lang, done);
    }
}

/*************************************************************************
 * helpers
 */

var _ = require('lodash');

var arrayfy = function(value) {
    //value is string or array
    return !value? []:
        Array.isArray(value)? value:value.split(',');
}

Handlebars.registerHelper('_keyword-links', function(tags) {
    return _(arrayfy(tags))
        .map(function(it){
            it = it.trim();
            return '' +
                it + '';
        })
        .value()
            .join(' ');
});

Handlebars.registerHelper('_group-doc', function(models){
    return models.reduce(function(g, m){
        var keywords = m['keywords'];
        if( keywords ) {
            var keywords = _.isString(keywords)? keywords.split(','): keywords;

            keywords.forEach(function(keyword){
                if( (g[keyword]) ) {
                    g[keyword].push(m);
                }else{
                    g[keyword] = [m];
                }
            });
        }

        return g;
    }, {});
});

Handlebars.registerHelper('_summary', function(html) {
    if(html){
        var matched = (/<h[123456].*?>.*<\/h[123456].*?>([\s\S*]*?)<h[123456].*?>.*<\/h[123456].*?>/i).exec(html)

        if( matched ) {
            return matched[1];
        }
    }

    return "empty-summary";
});
<commit_msg>update makdoc<commit_after>'use strict';

var gulp = require('gulp');
var Handlebars = require('handlebars');
var $ = require('gulp-load-plugins')();
var seq = require('run-sequence');
var through = require('through2');

/*************************************************************************
 * initialize makdoc
 */
var makdoc = require('gulp-makdoc')(gulp, Handlebars); // should init before local task

/*************************************************************************
 * tasks
 */

gulp.task('deploy', ['makdoc'], function () {
    var deploy = require('gulp-gh-pages');
    var path = require('path');

    return gulp.src([path.join(makdoc.vars.DIST(),'**/*'),
                    '!**/*.map'])
        .pipe(deploy({
            remoteUrl: 'git@github.com:pismute/pismute.github.io.git',
            cacheDir: '.gh-pages',
            branch:'master'
        }));
});

// Bower helper
gulp.task('bower', function() {
    var base = 'app/bower_components/';
    var files = [
        'requirejs/require.js',
        'bootstrap/dist/**/*.min.{js,css}',
        'bootstrap-material-design/dist/**/material.min.{js,css}',
        'bootstrap-material-design/dist/**/ripples.min.{js,css}',
        '{d3,jquery,lodash,dashbars}/**/*.min.js',
        'moment/min/{locales,moment}.min.js',
        'handlebars/handlebars/handlebars.min.js'
    ];
    files = files.map(function(file){
        return 'app/bower_components/' + file;
    });

    return gulp.src(files, {base:base})
        .pipe(gulp.dest('dist/bower_components/'));
});

gulp.task('makdoc:init:after', function(done){
    var returns = function(v) {
        return function(){
            return v;
        };
    };

    makdoc.vars.BASE_URL = returns('http://pismute.github.io/'),

    done();
});

gulp.task('makdoc:done:after', function(done){
    seq(['bower',
         'lint'],
        done);
});

gulp.task('lint', function(){
    return gulp.src(['gulpfiles.js', './gulp/**/*.js'])
        .pipe($.cached('lint'))
        .pipe($.jshint('.jshintrc'))
        .pipe($.jshint.reporter('default'));
});

/*************************************************************************
 * template data
 */

makdoc.templateData({
    package:require('./package.json')
});

/*************************************************************************
 * override:highlight
 */

var _alias = {
    'js-run': 'js',
    'js-run-d3': 'js'
};

makdoc.util.highlight = function() {
    var _highlight = makdoc.util.highlight_pygment();
    return function(code, lang, done){
        return _highlight(code, _alias[lang] || lang, done);
    }
}

/*************************************************************************
 * helpers
 */

var _ = require('lodash');

var arrayfy = function(value) {
    //value is string or array
    return !value? []:
        Array.isArray(value)? value:value.split(',');
}

Handlebars.registerHelper('_keyword-links', function(tags) {
    return _(arrayfy(tags))
        .map(function(it){
            it = it.trim();
            return '' +
                it + '';
        })
        .value()
            .join(' ');
});

Handlebars.registerHelper('_group-doc', function(models){
    return models.reduce(function(g, m){
        var keywords = m['keywords'];
        if( keywords ) {
            var keywords = _.isString(keywords)? keywords.split(','): keywords;

            keywords.forEach(function(keyword){
                if( (g[keyword]) ) {
                    g[keyword].push(m);
                }else{
                    g[keyword] = [m];
                }
            });
        }

        return g;
    }, {});
});

Handlebars.registerHelper('_summary', function(html) {
    if(html){
        var matched = (/<h[123456].*?>.*<\/h[123456].*?>([\s\S*]*?)<h[123456].*?>.*<\/h[123456].*?>/i).exec(html)

        if( matched ) {
            return matched[1];
        }
    }

    return "empty-summary";
});
<|endoftext|>


<commit_before>
var path = require('path')
var gulp = require('gulp')
var sourcemaps = require('gulp-sourcemaps')
var babel = require('gulp-babel')

var paths = {
  es6: ['**/*.js', '!gulpfile.js', '!build/**/*.*', '!node_modules/**/*.*'],
  es5: 'build',
  // must be absolute or relative to source map
  sourceRoot: path.join(__dirname)
}

gulp.task('babel', function () {
  return gulp.src(paths.es6)
    .pipe(sourcemaps.init())
    .pipe(babel({
      optional: [
        'es7.asyncFunctions',
        'es7.exportExtensions'
      ]
    }))
    .pipe(sourcemaps.write('.', {sourceRoot: paths.sourceRoot}))
    .pipe(gulp.dest(paths.es5))
})

gulp.task('watch', function () {
  gulp.watch(paths.es6, ['babel'])
})

gulp.task('default', ['watch'])
<commit_msg>Update gulpfile to use gulp v4.0<commit_after>
var path = require('path')
var gulp = require('gulp')
var sourcemaps = require('gulp-sourcemaps')
var babel = require('gulp-babel')

var paths = {
  es6: ['**/*.js', '!gulpfile.js', '!build/**/*.*', '!node_modules/**/*.*'],
  es5: 'build',
  // must be absolute or relative to source map
  sourceRoot: path.join(__dirname)
}

gulp.task('babel', function () {
  return gulp.src(paths.es6)
    .pipe(sourcemaps.init())
    .pipe(babel({
      presets: ['es2015', 'stage-0'],
      retainLines: 'true'
    }))
    .pipe(sourcemaps.write('.', {sourceRoot: paths.sourceRoot}))
    .pipe(gulp.dest(paths.es5))
})

gulp.task('build', gulp.series('babel'))

gulp.task('watch', function () {
  gulp.watch(paths.es6, gulp.series('babel'))
})

gulp.task('default', gulp.series('build', 'watch'))
<|endoftext|>


<commit_before>var gulp = require('gulp');
var $ = require('gulp-load-plugins')()

var commonFiles = [
  'app/shared/vendor/async.js',
  'app/shared/vendor/jquery.min.js',
  'app/shared/vendor/angular.min.js',
  'app/shared/vendor/moment.min.js',
  'app/shared/vendor/*.js',
  'app/modules.js',
  'app/shared/**/*.js',
];

gulp.task('js', function () {
  gulp.src(commonFiles.concat([
    '!app/shared/**/*Spec.js',
    'app/pages/**/*.js',
    '!app/pages/guest/*.js',
    '!app/pages/**/*Spec.js'
  ]))
  .pipe($.sourcemaps.init())
  .pipe($.concat('cluster.js'))
  // .pipe($.ngAnnotate())
  // .pipe($.uglify())
  .pipe($.sourcemaps.write())
  .pipe(gulp.dest('app/assets/js'))
})

gulp.task('jspro', function () {
  gulp.src(commonFiles.concat([
    '!app/shared/**/*Spec.js',
    'app/pages/**/*.js',
    '!app/pages/guest/*.js',
    '!app/pages/**/*Spec.js'
  ]))
  .pipe($.sourcemaps.init())
  .pipe($.concat('cluster.js'))
  .pipe($.ngAnnotate())
  .pipe($.uglify())
  .pipe(gulp.dest('app/assets/js'))
})

gulp.task('guestjs', function () {

  gulp.src(commonFiles.concat([
    '!app/shared/routes/*.js',
    '!app/shared/**/*Spec.js',
    'app/pages/**/*.js',
    '!app/pages/logout/*.js',
    '!app/pages/create/*.js',
    '!app/pages/**/*Spec.js'
  ]))
  .pipe($.sourcemaps.init())
  .pipe($.concat('guest.js'))
  // .pipe($.ngAnnotate())
  // .pipe($.uglify())
  .pipe($.sourcemaps.write())
  .pipe(gulp.dest('app/assets/js'))

})
gulp.task('guestjspro', function () {

  gulp.src(commonFiles.concat([
    '!app/shared/routes/*.js',
    '!app/shared/**/*Spec.js',
    'app/pages/**/*.js',
    '!app/pages/logout/*.js',
    '!app/pages/create/*.js',
    '!app/pages/**/*Spec.js'
  ]))
  .pipe($.sourcemaps.init())
  .pipe($.concat('guest.js'))
  .pipe($.ngAnnotate())
  .pipe($.uglify())
  .pipe(gulp.dest('app/assets/js'))

})

gulp.task('sass', function () {
  gulp.src('app/assets/sass/cluster.sass')
  .pipe($.rubySass({style: 'compressed', loadPath: process.cwd() + '/app/assets/sass'}))
  .pipe(gulp.dest('app/assets/css'));
});

gulp.task('dev', ['js', 'guestjs', 'sass'], function () {
  gulp.watch(['app/pages/**/*.js', 'app/shared/**/*.js'], ['js', 'guestjs'])
  gulp.watch('app/assets/sass/**/*.sass', ['sass'])
})

gulp.task('build', ['js'])
gulp.task('heroku', ['jspro', 'guestjspro', 'sass'])
<commit_msg>tiny tweaks<commit_after>var gulp = require('gulp');
var $ = require('gulp-load-plugins')()

var commonFiles = [
  'app/shared/vendor/async.js',
  'app/shared/vendor/jquery.min.js',
  'app/shared/vendor/angular.min.js',
  'app/shared/vendor/moment.min.js',
  'app/shared/vendor/*.js',
  'app/modules.js',
  'app/shared/**/*.js',
];

//TODO: figure out a way to fix duplication in this file
gulp.task('js', function () {
  gulp.src(commonFiles.concat([
    '!app/shared/**/*Spec.js',
    'app/pages/**/*.js',
    '!app/pages/guest/*.js',
    '!app/pages/**/*Spec.js'
  ]))
  .pipe($.sourcemaps.init())
  .pipe($.concat('cluster.js'))
  .pipe($.sourcemaps.write())
  .pipe(gulp.dest('app/assets/js'))
})

gulp.task('jspro', function () {
  gulp.src(commonFiles.concat([
    '!app/shared/**/*Spec.js',
    'app/pages/**/*.js',
    '!app/pages/guest/*.js',
    '!app/pages/**/*Spec.js'
  ]))
  .pipe($.sourcemaps.init())
  .pipe($.concat('cluster.js'))
  .pipe($.ngAnnotate())
  .pipe($.uglify())
  .pipe(gulp.dest('app/assets/js'))
})

gulp.task('guestjs', function () {

  gulp.src(commonFiles.concat([
    '!app/shared/routes/*.js',
    '!app/shared/**/*Spec.js',
    'app/pages/**/*.js',
    '!app/pages/logout/*.js',
    '!app/pages/create/*.js',
    '!app/pages/**/*Spec.js'
  ]))
  .pipe($.sourcemaps.init())
  .pipe($.concat('guest.js'))
  // .pipe($.ngAnnotate())
  // .pipe($.uglify())
  .pipe($.sourcemaps.write())
  .pipe(gulp.dest('app/assets/js'))

})
gulp.task('guestjspro', function () {

  gulp.src(commonFiles.concat([
    '!app/shared/routes/*.js',
    '!app/shared/**/*Spec.js',
    'app/pages/**/*.js',
    '!app/pages/logout/*.js',
    '!app/pages/create/*.js',
    '!app/pages/**/*Spec.js'
  ]))
  .pipe($.sourcemaps.init())
  .pipe($.concat('guest.js'))
  .pipe($.ngAnnotate())
  .pipe($.uglify())
  .pipe(gulp.dest('app/assets/js'))

})

gulp.task('sass', function () {
  gulp.src('app/assets/sass/cluster.sass')
  .pipe($.rubySass({style: 'compressed', loadPath: process.cwd() + '/app/assets/sass'}))
  .pipe(gulp.dest('app/assets/css'));
});

gulp.task('dev', ['js', 'guestjs', 'sass'], function () {
  gulp.watch(['app/pages/**/*.js', 'app/shared/**/*.js'], ['js', 'guestjs'])
  gulp.watch('app/assets/sass/**/*.sass', ['sass'])
})

gulp.task('build', ['js'])
gulp.task('heroku', ['jspro', 'guestjspro', 'sass'])
<|endoftext|>


<commit_before>define([
    "jquery",
    "./depends_parse"
], function($, parser) {
    function DependsHandler($el, expression) {
        var $context = $el.closest("form");
        if (!$context.length)
            $context=$(document);
        this.$el=$el;
        this.$context=$context;
        this.ast=parser.parse(expression);  // TODO: handle parse exceptions here
    }

    DependsHandler.prototype = {
        _findInputs: function(name) {
            var $input = this.$context.find(":input[name='"+name+"']");
            if (!$input.length)
                $input=$("#"+name);
            return $input;
        },

        _getValue: function(name) {
            var $input = this._findInputs(name);
            if (!$input.length)
                return null;

            if ($input.attr("type")==="radio" || $input.attr("type")==="checkbox")
                return $input.filter(":checked").val() || null;
            else
                return $input.val();
        },

        getAllInputs: function() {
            var todo = [this.ast],
                $inputs = $(),
                node;

            while (todo.length) {
                node=todo.shift();
                if (node.input)
                    $inputs=$inputs.add(this._findInputs(node.input));
                if (node.children && node.children.length)
                    todo.push.apply(todo, node.children);
            }
            return $inputs;
        },

        _evaluate: function(node) {
            var value = node.input ? this._getValue(node.input) : null,
                i;

            switch (node.type) {
                case "NOT":
                    return !this._evaluate(node.children[0]);
                case "AND":
                    for (i=0; i<node.children.length; i++)
                        if (!this._evaluate(node.children[i]))
                            return false;
                    return true;
                case "OR":
                    for (i=0; i<node.children.length; i++)
                        if (this._evaluate(node.children[i]))
                            return true;
                    return false;
                case "comparison":
                    switch (node.operator) {
                        case "=":
                            return node.value==value;
                        case "!=":
                            return node.value!=value;
                        case "<=":
                            return value<=node.value;
                        case "<":
                            return value<node.value;
                        case ">":
                            return value>node.value;
                        case ">=":
                            return value>=node.value;
                        case "~=":
                            return value.indexOf(node.value)!=-1;
                    }
                    break;
                case "truthy":
                    return !!value;
            }
        },

        evaluate: function() {
            return this._evaluate(this.ast);
        }
    };

    return DependsHandler;
});

<commit_msg>Depends: fix handling of empty values with ~=<commit_after>define([
    "jquery",
    "./depends_parse"
], function($, parser) {
    function DependsHandler($el, expression) {
        var $context = $el.closest("form");
        if (!$context.length)
            $context=$(document);
        this.$el=$el;
        this.$context=$context;
        this.ast=parser.parse(expression);  // TODO: handle parse exceptions here
    }

    DependsHandler.prototype = {
        _findInputs: function(name) {
            var $input = this.$context.find(":input[name='"+name+"']");
            if (!$input.length)
                $input=$("#"+name);
            return $input;
        },

        _getValue: function(name) {
            var $input = this._findInputs(name);
            if (!$input.length)
                return null;

            if ($input.attr("type")==="radio" || $input.attr("type")==="checkbox")
                return $input.filter(":checked").val() || null;
            else
                return $input.val();
        },

        getAllInputs: function() {
            var todo = [this.ast],
                $inputs = $(),
                node;

            while (todo.length) {
                node=todo.shift();
                if (node.input)
                    $inputs=$inputs.add(this._findInputs(node.input));
                if (node.children && node.children.length)
                    todo.push.apply(todo, node.children);
            }
            return $inputs;
        },

        _evaluate: function(node) {
            var value = node.input ? this._getValue(node.input) : null,
                i;

            switch (node.type) {
                case "NOT":
                    return !this._evaluate(node.children[0]);
                case "AND":
                    for (i=0; i<node.children.length; i++)
                        if (!this._evaluate(node.children[i]))
                            return false;
                    return true;
                case "OR":
                    for (i=0; i<node.children.length; i++)
                        if (this._evaluate(node.children[i]))
                            return true;
                    return false;
                case "comparison":
                    switch (node.operator) {
                        case "=":
                            return node.value==value;
                        case "!=":
                            return node.value!=value;
                        case "<=":
                            return value<=node.value;
                        case "<":
                            return value<node.value;
                        case ">":
                            return value>node.value;
                        case ">=":
                            return value>=node.value;
                        case "~=":
                            if (value===null)
                                return false;
                            return value.indexOf(node.value)!=-1;
                    }
                    break;
                case "truthy":
                    return !!value;
            }
        },

        evaluate: function() {
            return this._evaluate(this.ast);
        }
    };

    return DependsHandler;
});

<|endoftext|>


<commit_before>/* eslint-env node */

const archiver = require('archiver');
const eslint = require('gulp-eslint');
const fs = require('fs');
const gulp = require('gulp');
const gutil = require('gulp-util');
const jest = require('gulp-jest').default;
const jsonTransform = require('gulp-json-transform');
const lodash = require('lodash');
const rimraf = require('rimraf');
const runSequence = require('run-sequence');
const watch = require('gulp-watch');
const webpack = require('webpack');

const packageJson = require('./package.json');
const webpackConfig = require('./webpack.config.js');
const webpackProductionConfig = require('./webpack.production.config.js');

const DIST_DIRECTORY = 'dist';

// Clean all release artifacts
gulp.task('clean', function(done) {
  rimraf(`${__dirname}/${DIST_DIRECTORY}`, done);
});

// Copy any files that don't require pre-processing.
gulp.task('cp', function() {
  const cpApp = gulp.src([
    'app/img/**',
  ], {base: 'app'})
    .pipe(gulp.dest(DIST_DIRECTORY));

  const cpManifest = gulp.src([
    'app/manifest.json',
  ])
    .pipe(gulp.dest(DIST_DIRECTORY));

  const cpRoot = gulp.src([
    'MIT-LICENSE.txt',
    'README.md',
  ], {base: '.'})
    .pipe(gulp.dest(DIST_DIRECTORY));

  return [cpApp, cpManifest, cpRoot];
});

gulp.task('lint', function() {
  return gulp.src(['**/*.js', `!${DIST_DIRECTORY}/**`, '!node_modules/**', '!coverage/**'])
    // eslint() attaches the lint output to the "eslint" property
    // of the file object so it can be used by other modules.
    .pipe(eslint())
    // eslint.format() outputs the lint results to the console.
    // Alternatively use eslint.formatEach() (see Docs).
    .pipe(eslint.format())
    // To have the process exit with an error code (1) on
    // lint error, return the stream and pipe to failAfterError last.
    .pipe(eslint.failAfterError());
});

gulp.task('locales', function() {
  return gulp.src('_locales/**/*.json', {base: '.'})
    .pipe(jsonTransform(function(messages) {
      return Object.keys(messages).reduce(function(result, messageId) {
        // Omit the 'description' because it is only useful during development for translators.
        // Those bytes do not need to be shipped to users.
        result[messageId] = lodash.omit(messages[messageId], 'description');
        return result;
      }, {});
    }))
    .pipe(gulp.dest(DIST_DIRECTORY));
});

gulp.task('test', function () {
  process.env.NODE_ENV = 'test';

  return gulp.src('app/js/__tests__').pipe(jest(Object.assign({}, {
    config: {
      transformIgnorePatterns: [
        '<rootDir>/dist/', '<rootDir>/node_modules/',
      ],
      transform: {
        '^.+\\.jsx?$': 'babel-jest',
      },
      verbose: true,
      automock: false,
    },
  })));
});

function webpackLog(stats) {
  gutil.log('[webpack]', stats.toString({
    chunks: false, // Limit chunk information output; it's slow and not too useful
    colors: true,
    modules: false,
  }));
}

gulp.task('webpack', function(done) {
  return webpack(
    webpackConfig,
    function(err, stats) {
      if (err) throw new gutil.PluginError('webpack', err);
      webpackLog(stats);
      done();
    }
  );
});

gulp.task('webpack:production', function(done) {
  return webpack(
    webpackProductionConfig,
    function(err, stats) {
      if (err) throw new gutil.PluginError('webpack', err);
      webpackLog(stats);
      done();
    }
  );
});

gulp.task('webpack:watch', function(done) {
  let firstRun = true;
  return webpack(Object.assign({}, {watch: true}, webpackConfig), function(err, stats) {
    if (err) throw new gutil.PluginError('webpack', err);
    webpackLog(stats);

    // Call Gulp's `done` callback only once per watch. Calling it more than once is an error.
    if (firstRun) {
      firstRun = false;
      done();
    }
  });
});

// Watch and re-compile / re-lint when in development.
// eslint-disable-next-line no-unused-vars
gulp.task('watch', function(done) {
  watch('_locales/**/*', function() {
    gulp.start('locales');
  });
  watch('app/**/!(*.js)', function() {
    gulp.start('cp');
  });
  watch('app/**/*.js', function() {
    gulp.start('lint');
    gulp.start('test');
  });
  watch('__tests__/**/*.js', function() {
    gulp.start('lint');
    gulp.start('test');
  });
  gulp.start(['cp', 'lint', 'locales', 'test', 'webpack:watch']);
});

gulp.task('archive', function(done) {
  // create a file to stream archive data to.
  const output = fs.createWriteStream(`${__dirname}/tabwrangler-${packageJson.version}.zip`);
  const archive = archiver('zip');

  // listen for all archive data to be written
  output.on('close', function() {
    console.log(`${archive.pointer()} total bytes`);
    console.log('archiver has been finalized and the output file descriptor has closed.');
    done();
  });

  // good practice to catch this error explicitly
  archive.on('error', function(err) {
    throw err;
  });

  // pipe archive data to the file
  archive.pipe(output);

  // append files from a directory
  archive.directory(`${DIST_DIRECTORY}/`);

  // finalize the archive (ie we are done appending files but streams have to finish yet)
  archive.finalize();
});

gulp.task('release', function(done) {
  runSequence(
    'clean',
    'cp',
    'locales',
    'lint',
    'test',
    'webpack:production',
    'archive',
    function() {
      done();
    }
  );
});

gulp.task('default', function(done) {
  runSequence('cp', 'locales', 'lint', 'webpack', done);
});
<commit_msg>Pack files at archive root for Firefox package<commit_after>/* eslint-env node */

const archiver = require('archiver');
const eslint = require('gulp-eslint');
const fs = require('fs');
const gulp = require('gulp');
const gutil = require('gulp-util');
const jest = require('gulp-jest').default;
const jsonTransform = require('gulp-json-transform');
const lodash = require('lodash');
const rimraf = require('rimraf');
const runSequence = require('run-sequence');
const watch = require('gulp-watch');
const webpack = require('webpack');

const packageJson = require('./package.json');
const webpackConfig = require('./webpack.config.js');
const webpackProductionConfig = require('./webpack.production.config.js');

const DIST_DIRECTORY = 'dist';

// Clean all release artifacts
gulp.task('clean', function(done) {
  rimraf(`${__dirname}/${DIST_DIRECTORY}`, done);
});

// Copy any files that don't require pre-processing.
gulp.task('cp', function() {
  const cpApp = gulp.src([
    'app/img/**',
  ], {base: 'app'})
    .pipe(gulp.dest(DIST_DIRECTORY));

  const cpManifest = gulp.src([
    'app/manifest.json',
  ])
    .pipe(gulp.dest(DIST_DIRECTORY));

  const cpRoot = gulp.src([
    'MIT-LICENSE.txt',
    'README.md',
  ], {base: '.'})
    .pipe(gulp.dest(DIST_DIRECTORY));

  return [cpApp, cpManifest, cpRoot];
});

gulp.task('lint', function() {
  return gulp.src(['**/*.js', `!${DIST_DIRECTORY}/**`, '!node_modules/**', '!coverage/**'])
    // eslint() attaches the lint output to the "eslint" property
    // of the file object so it can be used by other modules.
    .pipe(eslint())
    // eslint.format() outputs the lint results to the console.
    // Alternatively use eslint.formatEach() (see Docs).
    .pipe(eslint.format())
    // To have the process exit with an error code (1) on
    // lint error, return the stream and pipe to failAfterError last.
    .pipe(eslint.failAfterError());
});

gulp.task('locales', function() {
  return gulp.src('_locales/**/*.json', {base: '.'})
    .pipe(jsonTransform(function(messages) {
      return Object.keys(messages).reduce(function(result, messageId) {
        // Omit the 'description' because it is only useful during development for translators.
        // Those bytes do not need to be shipped to users.
        result[messageId] = lodash.omit(messages[messageId], 'description');
        return result;
      }, {});
    }))
    .pipe(gulp.dest(DIST_DIRECTORY));
});

gulp.task('test', function () {
  process.env.NODE_ENV = 'test';

  return gulp.src('app/js/__tests__').pipe(jest(Object.assign({}, {
    config: {
      transformIgnorePatterns: [
        '<rootDir>/dist/', '<rootDir>/node_modules/',
      ],
      transform: {
        '^.+\\.jsx?$': 'babel-jest',
      },
      verbose: true,
      automock: false,
    },
  })));
});

function webpackLog(stats) {
  gutil.log('[webpack]', stats.toString({
    chunks: false, // Limit chunk information output; it's slow and not too useful
    colors: true,
    modules: false,
  }));
}

gulp.task('webpack', function(done) {
  return webpack(
    webpackConfig,
    function(err, stats) {
      if (err) throw new gutil.PluginError('webpack', err);
      webpackLog(stats);
      done();
    }
  );
});

gulp.task('webpack:production', function(done) {
  return webpack(
    webpackProductionConfig,
    function(err, stats) {
      if (err) throw new gutil.PluginError('webpack', err);
      webpackLog(stats);
      done();
    }
  );
});

gulp.task('webpack:watch', function(done) {
  let firstRun = true;
  return webpack(Object.assign({}, {watch: true}, webpackConfig), function(err, stats) {
    if (err) throw new gutil.PluginError('webpack', err);
    webpackLog(stats);

    // Call Gulp's `done` callback only once per watch. Calling it more than once is an error.
    if (firstRun) {
      firstRun = false;
      done();
    }
  });
});

// Watch and re-compile / re-lint when in development.
// eslint-disable-next-line no-unused-vars
gulp.task('watch', function(done) {
  watch('_locales/**/*', function() {
    gulp.start('locales');
  });
  watch('app/**/!(*.js)', function() {
    gulp.start('cp');
  });
  watch('app/**/*.js', function() {
    gulp.start('lint');
    gulp.start('test');
  });
  watch('__tests__/**/*.js', function() {
    gulp.start('lint');
    gulp.start('test');
  });
  gulp.start(['cp', 'lint', 'locales', 'test', 'webpack:watch']);
});

gulp.task('archive', function(done) {
  // create a file to stream archive data to.
  const output = fs.createWriteStream(`${__dirname}/tabwrangler-${packageJson.version}.zip`);
  const archive = archiver('zip');

  // listen for all archive data to be written
  output.on('close', function() {
    console.log(`${archive.pointer()} total bytes`);
    console.log('archiver has been finalized and the output file descriptor has closed.');
    done();
  });

  // good practice to catch this error explicitly
  archive.on('error', function(err) {
    throw err;
  });

  // pipe archive data to the file
  archive.pipe(output);

  // append files from the distribution directory, putting files all at the root
  archive.directory(`${DIST_DIRECTORY}/`, false);

  // finalize the archive (ie we are done appending files but streams have to finish yet)
  archive.finalize();
});

gulp.task('release', function(done) {
  runSequence(
    'clean',
    'cp',
    'locales',
    'lint',
    'test',
    'webpack:production',
    'archive',
    function() {
      done();
    }
  );
});

gulp.task('default', function(done) {
  runSequence('cp', 'locales', 'lint', 'webpack', done);
});
<|endoftext|>


<commit_before>var elixir = require('laravel-elixir'),
    build  = require('./gulp.build.json');

require('./tasks/angular.task.js');
require('./tasks/bower.task.js');
require('laravel-elixir-livereload');

/*
 |--------------------------------------------------------------------------
 | Elixir Asset Management
 |--------------------------------------------------------------------------
 |
 | Elixir provides a clean, fluent API for defining some basic Gulp tasks
 | for your Laravel application. By default, we are compiling the Less
 | file for our application, as well as publishing vendor resources.
 |
 */

elixir(function(mix) {
    'use strict';

    if (build.published) {
        build.base_directory = "";
        build.application    = "";

        for (var i = 0; i < build.components.length; i++) {
            build.components[i] = "";
        }
    }

    mix
        .bower()
        .angular([
            './' + build.base_directory + build.application + 'angular/main.js',
            './' + build.base_directory + build.application + 'angular/**/**/**/*.js',
            './' + build.base_directory + build.components[0] + 'angular/**/**/**/*.js',
        ])
        //.sass('./' + build.base_directory + build.sass_directory + 'angular/**/**/**/*.scss', 'public/css')
        .sass([
            './' + build.base_directory + build.application + 'angular/**/**/**/*.scss',
            './' + build.base_directory + build.components[0] + 'angular/**/**/**/*.scss'
        ], 'public/css')
        .copy('./' + build.base_directory + build.application + 'angular/**/**/**/*.html', 'public/views/')
        .copy('./' + build.base_directory + build.components[0] + 'angular/**/**/**/*.html', 'public/views/')
        .livereload([
            'public/js/vendor.js',
            'public/js/app.js',
            'public/css/vendor.css',
            'public/css/app.css',
            'public/views/!**!/!*.html'
        ], { liveCSS: true })
        .phpUnit();
});
<commit_msg>Refactoring # Add app.core.module.js , application.module.js , components.module.js. # Update gulpfile<commit_after>var elixir = require('laravel-elixir'),
    build  = require('./gulp.build.json');

require('./tasks/angular.task.js');
require('./tasks/bower.task.js');
require('laravel-elixir-livereload');

/*
 |--------------------------------------------------------------------------
 | Elixir Asset Management
 |--------------------------------------------------------------------------
 |
 | Elixir provides a clean, fluent API for defining some basic Gulp tasks
 | for your Laravel application. By default, we are compiling the Less
 | file for our application, as well as publishing vendor resources.
 |
 */

elixir(function(mix) {
    'use strict';

    if (build.published) {
        build.base_directory = "";
        build.application    = "";

        for (var i = 0; i < build.components.length; i++) {
            build.components[i] = "";
        }
    }

    mix
        .bower()
        .angular([
            './' + build.base_directory + build.application + 'angular/modules/app.core.module.js',
            './' + build.base_directory + build.application + 'angular/modules/components.module.js',
            './' + build.base_directory + build.application + 'angular/modules/application.module.js',
            './' + build.base_directory + build.application + 'angular/**/**/**/*.js',
            './' + build.base_directory + build.components[0] + 'angular/**/**/**/*.js',
        ])
        //.sass('./' + build.base_directory + build.sass_directory + 'angular/**/**/**/*.scss', 'public/css')
        .sass([
            './' + build.base_directory + build.application + 'angular/**/**/**/*.scss',
            './' + build.base_directory + build.components[0] + 'angular/**/**/**/*.scss'
        ], 'public/css')
        .copy('./' + build.base_directory + build.application + 'angular/**/**/**/*.html', 'public/views/')
        .copy('./' + build.base_directory + build.components[0] + 'angular/**/**/**/*.html', 'public/views/')
        .livereload([
            'public/js/vendor.js',
            'public/js/app.js',
            'public/css/vendor.css',
            'public/css/app.css',
            'public/views/!**!/!*.html'
        ], { liveCSS: true })
        .phpUnit();
});
<|endoftext|>


<commit_before>var browserify  = require('browserify');
var del         = require('del');
var debug       = require('gulp-debug');
var minimist    = require('minimist');
var gulp        = require('gulp');
var coverage    = require('gulp-coverage');
var jshint      = require('gulp-jshint');
var jsxhint     = require('gulp-jsxhint');
var map         = require('map-stream');
var mocha       = require('gulp-spawn-mocha');
var nodemon     = require('gulp-nodemon');
var stylish     = require('jshint-stylish');
var reactify    = require('reactify');
var react       = require('gulp-react');
var runSequence = require('run-sequence');
var uglify      = require('gulp-uglify');
var sass        = require('gulp-sass');
var source      = require('vinyl-source-stream');
var streamify   = require('gulp-streamify');
var watch       = require('gulp-watch');
var watchify    = require('watchify');

var options = minimist(process.argv.slice(2));

/**
 * Runs Mocha tests for the server
 */
gulp.task('test', function () {
  var sources = ['spec/config.js', 'app/**/*.spec.js'];

  options.reporter = 'min';
  options.istanbul = true;
  options.debugBrk = options.debug ? 'debug' : undefined;

  return gulp
    .src(sources)
    .pipe(mocha(options));
});

/**
 * Lints the server
 */
gulp.task('lint-server', function () {
  var sources = ['app/**/*.js', '!app/public/**/*.js'];

  return gulp
    .src(sources)
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'));
});

/**
 * Lints the client
 */
gulp.task('lint-client', function (done) {
  return gulp
    .src(['app/public/**/*.js'])
    .pipe(react())
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish', { verbose: true }))
    .pipe(jshint.reporter('fail'))
    .pipe(done);
});

/**
 * Cleans the dist directory
 */
gulp.task('clean', function (callback) {
  return del(['./dist/**/*'], callback);
});

gulp.task('browserify', function () {
  var bundler = browserify({
    debug:        true,
    transform:    [ reactify ],
    entries:      [ './app/public/app.js' ],
    cache:        {},
    packageCache: {}
  });
  bundler.plugin('minifyify', { map: 'app.js.map', output: __dirname + '/dist/public/app.js.map' });
  return bundler
    .bundle()
    .pipe(source('public/app.js'))
    .pipe(gulp.dest('./dist/'));
});

/**
 * Compiles the client javascript
 */
gulp.task('watchify', function () {
  var bundler = browserify({
    debug:        true,
    transform:    [ reactify ],
    entries:      [ './app/public/app.js' ],
    cache:        {},
    packageCache: {}
  });
  bundler.plugin('minifyify', { map: 'app.js.map', output: __dirname + '/dist/public/app.js.map' });
  var watcher = watchify(bundler);

  return watcher
    .on('error', function (err) {
      console.log(err.message);
    })
    .on('update', function () {
      console.log('updating bundle');
      watcher.bundle()
        .pipe(source('public/app.js'))
        .pipe(gulp.dest('./dist/'));
      console.log('updated bundle!');
    })
    .bundle()
    .pipe(source('public/app.js'))
    .pipe(gulp.dest('./dist/'));
});

/**
 * Copies the server component to the dist directory
 */
gulp.task('copy-server', function () {
  return gulp
    .src(['./app/**/*', '!./app/public/**/*'])
    .pipe(gulp.dest('./dist/'));
});

/**
 * Copies the client component to the dist directory
 */
gulp.task('copy-client', function () {
  return gulp
    .src(['./app/public/index.html'])
    .pipe(gulp.dest('./dist/public/'));
});

/**
 * Compiles the client SASS
 */
gulp.task('sass', function () {
  return gulp
    .src(['./app/public/main.scss'])
    .pipe(sass({
      outputStyle: 'compress',
      errLogToConsole: true
    }))
    .pipe(gulp.dest('./dist/public/'));
});

/**
 * Copies client assets
 */
gulp.task('assets', function () {
  return gulp
    .src(['./app/public/assets/**/*'])
    .pipe(gulp.dest('./dist/public/assets/'));
});

/**
 * Builds the application
 */
gulp.task('build', function (done) {
  return runSequence('clean', 'copy-server', 'browserify', 'copy-client', 'sass', 'assets', done);
});

gulp.task('watch', function (done) {
  return runSequence('clean', 'copy-server', 'watchify', 'copy-client', 'sass', 'assets', done);
});

/**
 * Automatic server reload
 */
gulp.task('nodemon', ['watch'], function (done) {
  var called = false;
  return nodemon({
    script: './dist/index.js',
    ext: 'js',
    ignore: ['dist/**/*', 'app/public/**/*', 'coverage/**/*', 'doc/**/*', 'node_modules/**/*', 'spec/**/*']
  }).on('change', ['lint-server', 'copy-server'])
    .on('start', ['watch']);
});

/**
 * Development task
 */
gulp.task('watch', function () {
  gulp.watch(['app/public/index.html'], ['copy-client']);
  gulp.watch(['app/public/**/*.scss'], ['sass']);
});

/**
 * Default
 */
gulp.task('default', ['nodemon']);<commit_msg>fix watch process<commit_after>var browserify  = require('browserify');
var del         = require('del');
var debug       = require('gulp-debug');
var minimist    = require('minimist');
var gulp        = require('gulp');
var coverage    = require('gulp-coverage');
var jshint      = require('gulp-jshint');
var jsxhint     = require('gulp-jsxhint');
var map         = require('map-stream');
var mocha       = require('gulp-spawn-mocha');
var nodemon     = require('gulp-nodemon');
var stylish     = require('jshint-stylish');
var reactify    = require('reactify');
var react       = require('gulp-react');
var runSequence = require('run-sequence');
var uglify      = require('gulp-uglify');
var sass        = require('gulp-sass');
var source      = require('vinyl-source-stream');
var streamify   = require('gulp-streamify');
var watch       = require('gulp-watch');
var watchify    = require('watchify');

var options = minimist(process.argv.slice(2));

/**
 * Runs Mocha tests for the server
 */
gulp.task('test', function () {
  var sources = ['spec/config.js', 'app/**/*.spec.js'];

  options.reporter = 'min';
  options.istanbul = true;
  options.debugBrk = options.debug ? 'debug' : undefined;

  return gulp
    .src(sources)
    .pipe(mocha(options));
});

/**
 * Lints the server
 */
gulp.task('lint-server', function () {
  var sources = ['app/**/*.js', '!app/public/**/*.js'];

  return gulp
    .src(sources)
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'));
});

/**
 * Lints the client
 */
gulp.task('lint-client', function (done) {
  return gulp
    .src(['app/public/**/*.js'])
    .pipe(react())
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish', { verbose: true }))
    .pipe(jshint.reporter('fail'))
    .pipe(done);
});

/**
 * Cleans the dist directory
 */
gulp.task('clean', function (callback) {
  return del(['./dist/**/*'], callback);
});

gulp.task('browserify', function () {
  var bundler = browserify({
    debug:        true,
    transform:    [ reactify ],
    entries:      [ './app/public/app.js' ],
    cache:        {},
    packageCache: {}
  });
  bundler.plugin('minifyify', { map: 'app.js.map', output: __dirname + '/dist/public/app.js.map' });
  return bundler
    .bundle()
    .pipe(source('public/app.js'))
    .pipe(gulp.dest('./dist/'));
});

/**
 * Compiles the client javascript
 */
gulp.task('watchify', function () {
  var bundler = browserify({
    debug:        true,
    transform:    [ reactify ],
    entries:      [ './app/public/app.js' ],
    cache:        {},
    packageCache: {}
  });
  bundler.plugin('minifyify', { map: 'app.js.map', output: __dirname + '/dist/public/app.js.map' });
  var watcher = watchify(bundler);

  return watcher
    .on('error', function (err) {
      console.log(err.message);
    })
    .on('update', function () {
      console.log('updating bundle');
      watcher.bundle()
        .pipe(source('public/app.js'))
        .pipe(gulp.dest('./dist/'));
      console.log('updated bundle!');
    })
    .bundle()
    .pipe(source('public/app.js'))
    .pipe(gulp.dest('./dist/'));
});

/**
 * Copies the server component to the dist directory
 */
gulp.task('copy-server', function () {
  return gulp
    .src(['./app/**/*', '!./app/public/**/*'])
    .pipe(gulp.dest('./dist/'));
});

/**
 * Copies the client component to the dist directory
 */
gulp.task('copy-client', function () {
  return gulp
    .src(['./app/public/index.html'])
    .pipe(gulp.dest('./dist/public/'));
});

/**
 * Compiles the client SASS
 */
gulp.task('sass', function () {
  return gulp
    .src(['./app/public/main.scss'])
    .pipe(sass({
      outputStyle: 'compress',
      errLogToConsole: true
    }))
    .pipe(gulp.dest('./dist/public/'));
});

/**
 * Copies client assets
 */
gulp.task('assets', function () {
  return gulp
    .src(['./app/public/assets/**/*'])
    .pipe(gulp.dest('./dist/public/assets/'));
});

/**
 * Builds the application
 */
gulp.task('build', function (done) {
  return runSequence('clean', 'copy-server', 'browserify', 'copy-client', 'sass', 'assets', done);
});

gulp.task('watch', function (done) {
  return runSequence('clean', 'copy-server', 'watchify', 'copy-client', 'sass', 'assets', done);
});

/**
 * Automatic server reload
 */
gulp.task('nodemon', ['watch'], function (done) {
  var called = false;
  return nodemon({
    script: './dist/index.js',
    ext: 'js',
    ignore: ['dist/**/*', 'app/public/**/*', 'coverage/**/*', 'doc/**/*', 'node_modules/**/*', 'spec/**/*']
  }).on('change', ['lint-server', 'copy-server'])
    .on('start', ['watch-assets']);
});

/**
 * Development task
 */
gulp.task('watch-assets', function () {
  gulp.watch(['app/public/index.html'], ['copy-client']);
  gulp.watch(['app/public/**/*.scss'], ['sass']);
});

/**
 * Default
 */
gulp.task('default', ['nodemon']);<|endoftext|>


<commit_before>import isArray from '../utils/is-array';
import isUndefined from '../utils/is-undefined';
import compareArrays from '../utils/compare-arrays';
import { deprecateSimple } from '../utils/deprecate';
import { mergeConfigs } from './set';
import { Locale } from './constructor';
import keys from '../utils/keys';

import { baseConfig } from './base-config';

// internal storage for locale config files
var locales = {};
var localeFamilies = {};
var globalLocale;

function normalizeLocale(key) {
    return key ? key.toLowerCase().replace('_', '-') : key;
}

// pick the locale from the array
// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
function chooseLocale(names) {
    var i = 0, j, next, locale, split;

    while (i < names.length) {
        split = normalizeLocale(names[i]).split('-');
        j = split.length;
        next = normalizeLocale(names[i + 1]);
        next = next ? next.split('-') : null;
        while (j > 0) {
            locale = loadLocale(split.slice(0, j).join('-'));
            if (locale) {
                return locale;
            }
            if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
                //the next array item is better than a shallower substring of this one
                break;
            }
            j--;
        }
        i++;
    }
    return globalLocale;
}

function loadLocale(name) {
    var oldLocale = null;
    // TODO: Find a better way to register and load all the locales in Node
    if (locales[name] === undefined && (typeof module !== 'undefined') &&
            module && module.exports) {
        try {
            oldLocale = globalLocale._abbr;
            var aliasedRequire = require;
            aliasedRequire((typeof __dirname !== undefined ? __dirname : '.') + '/locale/' + name);
            getSetGlobalLocale(oldLocale);
        } catch (e) {
            // mark as not found to avoid repeating expensive file require call causing high CPU
            // when trying to find en-US, en_US, en-us for every format call
            locales[name] = null; // null means not found
        }
    }
    return locales[name];
}

// This function will load locale and then set the global locale.  If
// no arguments are passed in, it will simply return the current global
// locale key.
export function getSetGlobalLocale (key, values) {
    var data;
    if (key) {
        if (isUndefined(values)) {
            data = getLocale(key);
        }
        else {
            data = defineLocale(key, values);
        }

        if (data) {
            // moment.duration._locale = moment._locale = data;
            globalLocale = data;
        }
        else {
            if ((typeof console !==  'undefined') && console.warn) {
                //warn user if arguments are passed but the locale could not be set
                console.warn('Locale ' + key +  ' not found. Did you forget to load it?');
            }
        }
    }

    return globalLocale._abbr;
}

export function defineLocale (name, config) {
    if (config !== null) {
        var locale, parentConfig = baseConfig;
        config.abbr = name;
        if (locales[name] != null) {
            deprecateSimple('defineLocaleOverride',
                    'use moment.updateLocale(localeName, config) to change ' +
                    'an existing locale. moment.defineLocale(localeName, ' +
                    'config) should only be used for creating a new locale ' +
                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
            parentConfig = locales[name]._config;
        } else if (config.parentLocale != null) {
            if (locales[config.parentLocale] != null) {
                parentConfig = locales[config.parentLocale]._config;
            } else {
                locale = loadLocale(config.parentLocale);
                if (locale != null) {
                    parentConfig = locale._config;
                } else {
                    if (!localeFamilies[config.parentLocale]) {
                        localeFamilies[config.parentLocale] = [];
                    }
                    localeFamilies[config.parentLocale].push({
                        name: name,
                        config: config
                    });
                    return null;
                }
            }
        }
        locales[name] = new Locale(mergeConfigs(parentConfig, config));

        if (localeFamilies[name]) {
            localeFamilies[name].forEach(function (x) {
                defineLocale(x.name, x.config);
            });
        }

        // backwards compat for now: also set the locale
        // make sure we set the locale AFTER all child locales have been
        // created, so we won't end up with the child locale set.
        getSetGlobalLocale(name);

        return locales[name];
    } else {
        // useful for testing
        delete locales[name];
        return null;
    }
}

export function updateLocale(name, config) {
    if (config != null) {
        var locale, tmpLocale, parentConfig = baseConfig;
        // MERGE
        tmpLocale = loadLocale(name);
        if (tmpLocale != null) {
            parentConfig = tmpLocale._config;
        }
        config = mergeConfigs(parentConfig, config);
        locale = new Locale(config);
        locale.parentLocale = locales[name];
        locales[name] = locale;

        // backwards compat for now: also set the locale
        getSetGlobalLocale(name);
    } else {
        // pass null for config to unupdate, useful for tests
        if (locales[name] != null) {
            if (locales[name].parentLocale != null) {
                locales[name] = locales[name].parentLocale;
                if (name === getSetGlobalLocale()) {
                    getSetGlobalLocale(name);
                }
            } else if (locales[name] != null) {
                delete locales[name];
            }
        }
    }
    return locales[name];
}

// returns locale data
export function getLocale (key) {
    var locale;

    if (key && key._locale && key._locale._abbr) {
        key = key._locale._abbr;
    }

    if (!key) {
        return globalLocale;
    }

    if (!isArray(key)) {
        //short-circuit everything else
        locale = loadLocale(key);
        if (locale) {
            return locale;
        }
        key = [key];
    }

    return chooseLocale(key);
}

export function listLocales() {
    return keys(locales);
}
<commit_msg>[bugfix] Properly fallback to base locales in array getter (#5459)<commit_after>import isArray from '../utils/is-array';
import isUndefined from '../utils/is-undefined';
import { deprecateSimple } from '../utils/deprecate';
import { mergeConfigs } from './set';
import { Locale } from './constructor';
import keys from '../utils/keys';

import { baseConfig } from './base-config';

// internal storage for locale config files
var locales = {};
var localeFamilies = {};
var globalLocale;

function commonPrefix(arr1, arr2) {
    var i, minl = Math.min(arr1.length, arr2.length);
    for (i = 0; i < minl; i += 1) {
        if (arr1[i] !== arr2[i]) {
            return i;
        }
    }
    return minl;
}

function normalizeLocale(key) {
    return key ? key.toLowerCase().replace('_', '-') : key;
}

// pick the locale from the array
// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
function chooseLocale(names) {
    var i = 0, j, next, locale, split;

    while (i < names.length) {
        split = normalizeLocale(names[i]).split('-');
        j = split.length;
        next = normalizeLocale(names[i + 1]);
        next = next ? next.split('-') : null;
        while (j > 0) {
            locale = loadLocale(split.slice(0, j).join('-'));
            if (locale) {
                return locale;
            }
            if (next && next.length >= j && commonPrefix(split, next) >= j - 1) {
                //the next array item is better than a shallower substring of this one
                break;
            }
            j--;
        }
        i++;
    }
    return globalLocale;
}

function loadLocale(name) {
    var oldLocale = null;
    // TODO: Find a better way to register and load all the locales in Node
    if (locales[name] === undefined && (typeof module !== 'undefined') &&
            module && module.exports) {
        try {
            oldLocale = globalLocale._abbr;
            var aliasedRequire = require;
            aliasedRequire((typeof __dirname !== undefined ? __dirname : '.') + '/locale/' + name);
            getSetGlobalLocale(oldLocale);
        } catch (e) {
            // mark as not found to avoid repeating expensive file require call causing high CPU
            // when trying to find en-US, en_US, en-us for every format call
            locales[name] = null; // null means not found
        }
    }
    return locales[name];
}

// This function will load locale and then set the global locale.  If
// no arguments are passed in, it will simply return the current global
// locale key.
export function getSetGlobalLocale (key, values) {
    var data;
    if (key) {
        if (isUndefined(values)) {
            data = getLocale(key);
        }
        else {
            data = defineLocale(key, values);
        }

        if (data) {
            // moment.duration._locale = moment._locale = data;
            globalLocale = data;
        }
        else {
            if ((typeof console !==  'undefined') && console.warn) {
                //warn user if arguments are passed but the locale could not be set
                console.warn('Locale ' + key +  ' not found. Did you forget to load it?');
            }
        }
    }

    return globalLocale._abbr;
}

export function defineLocale (name, config) {
    if (config !== null) {
        var locale, parentConfig = baseConfig;
        config.abbr = name;
        if (locales[name] != null) {
            deprecateSimple('defineLocaleOverride',
                    'use moment.updateLocale(localeName, config) to change ' +
                    'an existing locale. moment.defineLocale(localeName, ' +
                    'config) should only be used for creating a new locale ' +
                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
            parentConfig = locales[name]._config;
        } else if (config.parentLocale != null) {
            if (locales[config.parentLocale] != null) {
                parentConfig = locales[config.parentLocale]._config;
            } else {
                locale = loadLocale(config.parentLocale);
                if (locale != null) {
                    parentConfig = locale._config;
                } else {
                    if (!localeFamilies[config.parentLocale]) {
                        localeFamilies[config.parentLocale] = [];
                    }
                    localeFamilies[config.parentLocale].push({
                        name: name,
                        config: config
                    });
                    return null;
                }
            }
        }
        locales[name] = new Locale(mergeConfigs(parentConfig, config));

        if (localeFamilies[name]) {
            localeFamilies[name].forEach(function (x) {
                defineLocale(x.name, x.config);
            });
        }

        // backwards compat for now: also set the locale
        // make sure we set the locale AFTER all child locales have been
        // created, so we won't end up with the child locale set.
        getSetGlobalLocale(name);

        return locales[name];
    } else {
        // useful for testing
        delete locales[name];
        return null;
    }
}

export function updateLocale(name, config) {
    if (config != null) {
        var locale, tmpLocale, parentConfig = baseConfig;
        // MERGE
        tmpLocale = loadLocale(name);
        if (tmpLocale != null) {
            parentConfig = tmpLocale._config;
        }
        config = mergeConfigs(parentConfig, config);
        locale = new Locale(config);
        locale.parentLocale = locales[name];
        locales[name] = locale;

        // backwards compat for now: also set the locale
        getSetGlobalLocale(name);
    } else {
        // pass null for config to unupdate, useful for tests
        if (locales[name] != null) {
            if (locales[name].parentLocale != null) {
                locales[name] = locales[name].parentLocale;
                if (name === getSetGlobalLocale()) {
                    getSetGlobalLocale(name);
                }
            } else if (locales[name] != null) {
                delete locales[name];
            }
        }
    }
    return locales[name];
}

// returns locale data
export function getLocale (key) {
    var locale;

    if (key && key._locale && key._locale._abbr) {
        key = key._locale._abbr;
    }

    if (!key) {
        return globalLocale;
    }

    if (!isArray(key)) {
        //short-circuit everything else
        locale = loadLocale(key);
        if (locale) {
            return locale;
        }
        key = [key];
    }

    return chooseLocale(key);
}

export function listLocales() {
    return keys(locales);
}
<|endoftext|>


<commit_before>const gulp = require('gulp');
const shell = cmd => require('child_process').execSync(cmd, {stdio:[0,1,2]});
const del = require('del');
const extend = require('extend');
const seq = require('run-sequence');
const $ = require('gulp-load-plugins')({
  //pattern: ['gulp-*', 'gulp.*'],
  //replaceString: /\bgulp[\-.]/
});
const Server = require('karma').Server;

const pkg = require('./package.json');
const karmaconfig = require('./karma.conf.js');
const config = {
  ts: {
    options: extend(require('./tsconfig.json').compilerOptions, {
      typescript: require('typescript')
    }),
    source: {
      src: [
        'typings/*.d.ts',
        '*.ts',
        'src/**/*.ts'
      ],
      dest: 'dist/'
    },
    dist: {
      src: [
        'typings/*.d.ts',
        '*.ts',
        'src/**/*.d.ts',
        'src/**/+([!.]).ts'
      ],
      dest: 'dist/'
    },
    test: {
      src: [
        'typings/*.d.ts',
        'test/**/*.ts'
      ],
      dest: 'test/'
    }
  },
  banner: [
    `/*! ${pkg.name} v${pkg.version} ${pkg.repository.url} | (c) 2016, ${pkg.author} | ${pkg.license.type} License (${pkg.license.url}) */`,
    ''
  ].join('\n'),
  exporter:
`define = typeof define === 'function' && define.amd
  ? define
  : (function () {
    'use strict';
    var name = '${pkg.name}',
        workspace = {};
    return function define(m, rs, f) {
      return !f
        ? void define(name, m, rs)
        : void f.apply(this, rs.map(function (r) {
          switch (r) {
            case 'require': {
              return typeof require === 'function' ? require : void 0;
            }
            case 'exports': {
              return m.indexOf('/') === -1
                ? workspace[m] = typeof exports === 'undefined' ? self[m] = self[m] || {} : exports
                : workspace[m] = workspace.hasOwnProperty(m) ? workspace[m] : {};
            }
            default: {
              return r.slice(-2) === '.d' && {}
                  || workspace.hasOwnProperty(r) && workspace[r]
                  || typeof require === 'function' && require(r)
                  || self[r];
            }
          }
        }));
    };
  })();
`,
  clean: {
    src: 'src/**/*.js',
    dist: 'dist',
    test: 'test/**/*.js',
    bench: 'benchmark/**/*.js',
    cov: 'coverage'
  },
  karma: {
    watch: extend({}, require('./karma.conf.js'), {
      browsers: ['Chrome'],
      preprocessors: {
        'dist/*.js': ['espower'],
        'test/**/*.js': ['espower']
      },
      singleRun: false
    }),
    test: extend({}, require('./karma.conf.js'), {
      browsers: ['Chrome', 'Firefox', 'IE11', 'IE10', 'IE9'],
      reporters: ['dots'],
      preprocessors: {
        'dist/*.js': ['espower'],
        'test/**/*.js': ['espower']
      },
      singleRun: true
    }),
    server: extend({}, require('./karma.conf.js'), {
      browsers: ['Chromium', 'Firefox'],
      reporters: ['dots'],
      preprocessors: {
        'dist/*.js': ['espower'],
        'test/**/*.js': ['espower']
      },
      singleRun: true
    })
  }
};

gulp.task('ts:source', function () {
  return gulp.src(config.ts.source.src)
    .pipe($.typescript(Object.assign({
      outFile: `${pkg.name}.js`
    }, config.ts.options)))
    .pipe($.header(config.exporter))
    .pipe(gulp.dest(config.ts.source.dest));
});

gulp.task('ts:dist', function () {
  return gulp.src(config.ts.dist.src)
    .pipe($.typescript(Object.assign({
      outFile: `${pkg.name}.js`
    }, config.ts.options)))
    .once("error", function () {
      this.once("finish", () => process.exit(1));
    })
    .pipe($.unassert())
    .pipe($.header(config.exporter))
    .pipe($.header(config.banner))
    .pipe(gulp.dest(config.ts.dist.dest))
    .pipe($.uglify({ preserveComments: 'license' }))
    .pipe($.rename({ extname: '.min.js' }))
    .pipe(gulp.dest(config.ts.dist.dest));
});

gulp.task('ts:test', function () {
  return gulp.src(config.ts.test.src)
    .pipe($.typescript(Object.assign({
    }, config.ts.options)))
    .pipe(gulp.dest(config.ts.test.dest));
});

gulp.task('ts:watch', function () {
  gulp.watch(config.ts.source.src, ['ts:source']);
  gulp.watch(config.ts.test.src, ['ts:test']);
});

gulp.task('mocha:watch', function () {
  gulp.watch(config.ts.source.dest + '*.js', ['mocha:test']);
});

gulp.task('mocha:test', function () {
  return gulp.src(config.ts.source.dest + '*.js', { read: false })
    .pipe($.mocha({
      require: ['intelli-espower-loader'],
      reporter: 'dot'
    }));
});

gulp.task('karma:watch', function (done) {
  new Server(config.karma.watch, function(exitCode) {
    console.log('Karma has exited with ' + exitCode);
    done();
  }).start();
});

gulp.task('karma:test', function (done) {
  new Server(config.karma.test, function(exitCode) {
    console.log('Karma has exited with ' + exitCode);
    done();
  }).start();
});

gulp.task('karma:server', function (done) {
  new Server(config.karma.server, function(exitCode) {
    console.log('Karma has exited with ' + exitCode);
    done();
  }).start();
});

gulp.task('clean', function () {
  return del([config.clean.src, config.clean.dist, config.clean.test, config.clean.bench]);
});

gulp.task('install', function () {
  shell('npm i');
  shell('tsd install --save --overwrite');
});

gulp.task('update', function () {
  shell('npm-check-updates -u');
  shell('npm i');
  //shell('tsd update --save --overwrite');
});

gulp.task('build', ['clean'], function (done) {
  seq(
    ['ts:source', 'ts:test'],
    done
  );
});

gulp.task('watch', ['build'], function () {
  seq([
    'ts:watch',
    'karma:watch'
  ]);
});

gulp.task('test', ['build'], function (done) {
  seq(
    'karma:test',
    function () {
      done();
    }
  );
});

gulp.task('dist', ['clean'], function (done) {
  seq(
    'ts:dist',
    done
  );
});

gulp.task('server', function (done) {
  seq(
    'build',
    'karma:server',
    'dist',
    function () {
      done();
    }
  );
});
<commit_msg>chore(config): fix build scripts<commit_after>const gulp = require('gulp');
const shell = cmd => require('child_process').execSync(cmd, {stdio:[0,1,2]});
const del = require('del');
const extend = require('extend');
const seq = require('run-sequence');
const $ = require('gulp-load-plugins')({
  //pattern: ['gulp-*', 'gulp.*'],
  //replaceString: /\bgulp[\-.]/
});
const Server = require('karma').Server;

const pkg = require('./package.json');
const karmaconfig = require('./karma.conf.js');
const config = {
  ts: {
    options: extend(require('./tsconfig.json').compilerOptions, {
      typescript: require('typescript')
    }),
    source: {
      src: [
        'typings/*.d.ts',
        '*.ts',
        'src/**/*.ts'
      ],
      dest: 'dist/'
    },
    dist: {
      src: [
        'typings/*.d.ts',
        '*.ts',
        'src/**/*.d.ts',
        'src/**/+([!.]).ts'
      ],
      dest: 'dist/'
    },
    test: {
      src: [
        'typings/*.d.ts',
        'test/**/*.ts'
      ],
      dest: 'test/'
    }
  },
  banner: [
    `/*! ${pkg.name} v${pkg.version} ${pkg.repository.url} | (c) 2016, ${pkg.author} | ${pkg.license.type} License (${pkg.license.url}) */`,
    ''
  ].join('\n'),
  exporter:
`define = typeof define === 'function' && define.amd
  ? define
  : (function () {
    'use strict';
    var name = '${pkg.name}',
        workspace = {};
    return function define(m, rs, f) {
      return !f
        ? void define(name, m, rs)
        : void f.apply(this, rs.map(function (r) {
          switch (r) {
            case 'require': {
              return typeof require === 'function' ? require : void 0;
            }
            case 'exports': {
              return m.indexOf('/') === -1
                ? workspace[m] = typeof exports === 'undefined' ? self[m] = self[m] || {} : exports
                : workspace[m] = workspace.hasOwnProperty(m) ? workspace[m] : {};
            }
            default: {
              return r.slice(-2) === '.d' && {}
                  || workspace.hasOwnProperty(r) && workspace[r]
                  || typeof require === 'function' && require(r)
                  || self[r];
            }
          }
        }));
    };
  })();
`,
  clean: {
    src: 'src/**/*.js',
    dist: 'dist',
    test: 'test/**/*.js',
    bench: 'benchmark/**/*.js',
    cov: 'coverage'
  },
  karma: {
    watch: extend({}, require('./karma.conf.js'), {
      browsers: ['Chrome'],
      preprocessors: {
        'dist/*.js': ['espower'],
        'test/**/*.js': ['espower']
      },
      singleRun: false
    }),
    test: extend({}, require('./karma.conf.js'), {
      browsers: ['Chrome', 'Firefox', 'IE11', 'IE10', 'IE9'],
      reporters: ['dots'],
      preprocessors: {
        'dist/*.js': ['espower'],
        'test/**/*.js': ['espower']
      },
      singleRun: true
    }),
    server: extend({}, require('./karma.conf.js'), {
      browsers: ['Chromium', 'Firefox'],
      reporters: ['dots'],
      preprocessors: {
        'dist/*.js': ['espower'],
        'test/**/*.js': ['espower']
      },
      singleRun: true
    })
  }
};

gulp.task('ts:source', function () {
  return gulp.src(config.ts.source.src)
    .pipe($.typescript(Object.assign({
      outFile: `${pkg.name}.js`
    }, config.ts.options)))
    .pipe($.header(config.exporter))
    .pipe(gulp.dest(config.ts.source.dest));
});

gulp.task('ts:dist', function () {
  return gulp.src(config.ts.dist.src)
    .pipe($.typescript(Object.assign({
      outFile: `${pkg.name}.js`
    }, config.ts.options)))
    .once("error", function () {
      this.once("finish", () => process.exit(1));
    })
    .pipe($.unassert())
    .pipe($.header(config.exporter))
    .pipe($.header(config.banner))
    .pipe(gulp.dest(config.ts.dist.dest))
    .pipe($.uglify({ preserveComments: 'license' }))
    .pipe($.rename({ extname: '.min.js' }))
    .pipe(gulp.dest(config.ts.dist.dest));
});

gulp.task('ts:test', function () {
  return gulp.src(config.ts.test.src)
    .pipe($.typescript(Object.assign({
    }, config.ts.options)))
    .pipe(gulp.dest(config.ts.test.dest));
});

gulp.task('ts:watch', function () {
  gulp.watch(config.ts.source.src, ['ts:source']);
  gulp.watch(config.ts.test.src, ['ts:test']);
});

gulp.task('mocha:watch', function () {
  gulp.watch(config.ts.source.dest + '*.js', ['mocha:test']);
});

gulp.task('mocha:test', function () {
  return gulp.src(config.ts.source.dest + '*.js', { read: false })
    .pipe($.mocha({
      require: ['intelli-espower-loader'],
      reporter: 'dot'
    }));
});

gulp.task('karma:watch', function (done) {
  new Server(config.karma.watch, done).start();
});

gulp.task('karma:test', function (done) {
  new Server(config.karma.test, done).start();
});

gulp.task('karma:server', function (done) {
  new Server(config.karma.server, done).start();
});

gulp.task('clean', function () {
  return del([config.clean.src, config.clean.dist, config.clean.test, config.clean.bench]);
});

gulp.task('install', function () {
  shell('npm i');
  shell('tsd install --save --overwrite');
});

gulp.task('update', function () {
  shell('npm-check-updates -u');
  shell('npm i');
  //shell('tsd update --save --overwrite');
});

gulp.task('build', ['clean'], function (done) {
  seq(
    ['ts:source', 'ts:test'],
    done
  );
});

gulp.task('watch', ['build'], function () {
  seq([
    'ts:watch',
    'karma:watch'
  ]);
});

gulp.task('test', ['build'], function (done) {
  seq(
    'karma:test',
    function () {
      done();
    }
  );
});

gulp.task('dist', ['clean'], function (done) {
  seq(
    'ts:dist',
    done
  );
});

gulp.task('server', function (done) {
  seq(
    'build',
    'karma:server',
    'dist',
    function () {
      done();
    }
  );
});
<|endoftext|>