<commit_before>const fs = require('mz/fs');
const got = require('got');
const co = require('co');
const cheerio = require('cheerio');
const nunjucks = require('nunjucks');
// Set template default dir to `views`. To be used in `home` task.
nunjucks.configure('views', {
  noCache: true,
  watch: false,
  autoescape: false
});
// Promisify nunjucks render function.
function render(view, context) {
  return new Promise(function(resolve, reject) {
    nunjucks.render(view, context, function(err, result) {
      if (err) {
        reject(err);
      } else {
        resolve(result);
      }
    });
  });
}

const del = require('del');

const gulp = require('gulp');
const $ = require('gulp-load-plugins')();
const useref = require('gulp-useref');
const wiredep = require('wiredep').stream;

const browserSync = require('browser-sync').create();
const cssnext = require('postcss-cssnext');
const merge = require('merge-stream');
const source = require('vinyl-source-stream');
const lazypipe = require('lazypipe');

const origamiModules = [
  {
    source: 'http://origami-build.ft.com/v2/bundles/js?modules=o-gallery@^1.7.6',
    dest: './app/origami/o-gallery.js'
  },
  {
    source: 'http://origami-build.ft.com/v2/bundles/css?modules=o-gallery@^1.7.6',
    dest: './app/origami/o-gallery.css'
  }
];

// fetch contents from `origamiModules.source` and write to `origamiModules.dest`.
gulp.task('origami', () => {
  return co(function *() {
    const results = yield Promise.all(origamiModules.map(module => {
      console.log(`fetching ${module.source}`);
  // After getting response from url, return a new object consisting of url's content and file name to write.
      return got(module.source)
        .then(response => {
          return {
            dest: module.dest,
            body: response.body
          }
        }, (error) => {
  // return error if network failed.
          return Promise.reject(error);
        });
    }));

    yield Promise.all(results.map(res => {
      return fs.writeFile(res.dest, res.body, 'utf8');
    }));

  })
  .catch((err) => {
  // catch any error if there are.
    console.error(err.stack);
  });
});

// Fetch latest content from home page, and update `app/index.html`
gulp.task('home', () => {
  const timeStamp = new Date().getTime();
  return co(function *() {
    const destDir = 'app';
  // check if `destDir` exitsts
    try {
      yield fs.access(destDir, fs.constants.R_OK | fs.constants.W_OK);
    } catch (err) {
  // If not, create it.
      yield fs.mkdir(destDir);
    }

    console.log(`fetching latest body from home page`);
    const latestBody = yield got(`http://www.ftchinese.com/m/corp/p0.html?${timeStamp}`)
      .then(response => {
  // Use cheerio to parse HTML and extract contents inside `<body>`
        const $ = cheerio.load(response.body, {
          decodeEntities: true
        });
        return $('body').html();
      });

  // Render `views/index.html` using the extracted body contents.
    const html = yield render('index.html', {body: latestBody});
  // Write rendered file to `.tmp/index.html`
    yield fs.writeFile(`${destDir}/index.html`, html, 'utf8');
    console.log(`Updated ${destDir}/index.html`);
  })
  .catch(err => {
    console.error(err.stack);
  });
})

// To access the api you need to send cookie PHPSESSID.
gulp.task('story', () => {
  return co(function *() {
    const date = new Date();
    const timeStamp = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
    // const cookies = yield got('https://backyard.ftchinese.com/falcon.php/cmsusers/login')
    // .then(response => {
    //   const cookies = response.headers['set-cookie'].map(cookie => {
    //      const obj =  Cookie.parse(cookie);
    //      return `${obj.key}=${obj.value}`;
    //   });
    //   return cookies.join(';');
    // });

    const cookie = `PHPSESSID=78f011e58763cbca4400e42b265d4e33; ftcms_uid=13; ftcms_username=oliver.zhang; ftcms_groups=editor`;

    const response = yield got(`https://backyard.ftchinese.com/falcon.php/homepage/getstoryapi/${timeStamp}`, {
      'headers': {
        'user-agent': 'ftc',
        'cookie': cookie
      }
    });

    yield fs.writeFile('stories.json', response.body, 'utf8');
  })
  .catch(err => {
    console.log(err);
  });
});

// Get the nav.json.
gulp.task('nav', () => {
  return got(`http://m.ftchinese.com/eaclient/apijson.php`, {
    method: 'POST',
    body: JSON.stringify({
      head: {
        transactiontype: '11001',
        source: 'web'
      },
      body: {
        ielement: {}
      }
    })
  })
  .then(response => {
    console.log('updated ./app/api/page/nav.json');
    return fs.writeFile('./app/api/page/nav.json', response.body, 'utf8');
  })
  .catch(error => {
    console.error(error.stack);
  });
});

// Compile SCSS
gulp.task('styles', function () {
  const DEST = '.tmp/styles';

  return gulp.src(['app/styles/main*.scss'])
    .pipe($.changed(DEST))
    .pipe($.plumber())
    .pipe($.sourcemaps.init({loadMaps:true}))
    .pipe($.sass({
      outputStyle: 'expanded',
      precision: 10,
      includePaths: ['bower_components']
    }).on('error', $.sass.logError))
    .pipe($.postcss([
      cssnext({
        features: {
          colorRgba: false
        }
      })
    ]))
    .pipe($.sourcemaps.write('./'))
    .pipe(gulp.dest(DEST))
    .pipe(browserSync.stream({once: true}));
});

gulp.task('ad', function () {
  return gulp.src('app/m/marketing/*')
    .pipe(gulp.dest('dist/m/marketing'));
});

gulp.task('jshint', function () {
  return gulp.src('app/scripts/**/*.js')
    .pipe($.jshint())
    .pipe($.jshint.reporter('jshint-stylish'))
    .pipe($.jshint.reporter('fail'));
});

// Build css and js.
gulp.task('html', gulp.series('styles', () => {
  return gulp.src('app/*.html')
    .pipe($.useref({searchPath: ['.tmp', 'app', '.']}))
    .pipe($.if('*.js', $.uglify()))
    .on('error', (err) => {
      if (err instanceof GulpUglifyError) {
        console.log(err.fileName);
        console.log(err.cause);
        console.log(err.line);
      }
    })
    .pipe($.if('*.css', $.cssnano()))
    .pipe($.if('*.html', $.htmlmin({collapseWhitespace: true})))
    .pipe(gulp.dest('dist'));
}));

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

// Launch static server
gulp.task('serve',
  gulp.parallel(
    'styles',

    function serve() {
    browserSync.init({
      server: {
        baseDir: ['app', '.tmp'],
        index: 'index.html',
        routes: {
          '/bower_components': 'bower_components'
        }
      }
    });

    gulp.watch('app/styles/**/*.scss', gulp.parallel('styles'));
    gulp.watch(['app/*.html', 'app/scripts/**/*.js', 'app/images/**/*'], browserSync.reload);
  })
);

// Is this one in use?
gulp.task('wiredep', function () {

  const scss = gulp.src('app/styles/*.scss')
    .pipe(wiredep())
    .pipe(gulp.dest('app/styles'));

  const html = gulp.src('app/*.html')
    .pipe(wiredep())
    .pipe(gulp.dest('app'));

  return merge(scss, html);
});

gulp.task('clean', function() {
  return del(['.tmp/**', 'dist']).then(()=>{
    console.log('dir .tmp and dist deleted');
  });
});

gulp.task('build', gulp.parallel('jshint', 'html', 'images', /*'fonts', 'extras',*/ 'ad'));

// Various copy tasks.
gulp.task('copy:cssjs', () => {
  const staticDest = 'dev_www/frontend/static/n';
  const cssDest = 'dev_www/frontend/tpl/next/styles';
  const jsDest = 'dev_www/frontend/tpl/next/scripts'

  let cssStream = gulp.src(['app/origami/*.css', 'dist/styles/*.css'])
    .pipe(gulp.dest(`../${staticDest}`))
    .pipe(gulp.dest(`../${cssDest}`))
    .pipe(gulp.dest(`../testing/${cssDest}`));

  let partialsCssStream = gulp.src('dist/styles/partials/*.css')
    .pipe(gulp.dest(`../${cssDest}`))
    .pipe(gulp.dest(`../testing/${cssDest}`));

  let jsStream = gulp.src(['app/origami/*.js', 'dist/scripts/*.js'])
    .pipe(gulp.dest(`../${staticDest}`))
    .pipe(gulp.dest(`../${jsDest}`))
    .pipe(gulp.dest(`../testing/${jsDest}`));

  return merge(cssStream, partialsCssStream, jsStream);
});

gulp.task('copy:marketing', () => {
  const dest = 'dev_www/frontend/tpl/marketing';
  return gulp.src('dist/m/marketing/*')
    .pipe(gulp.dest(`../${dest}`))
    .pipe(gulp.dest(`../testing/${dest}`));
});

gulp.task('copy:apipage', () => {
  const dest = 'dev_www/frontend/tpl/next/api/page'
  return gulp.src('app/api/page/*')
    .pipe(gulp.dest(`../${dest}`))
    .pipe(gulp.dest(`../testing/${dest}`));
});

gulp.task('copy:pagemaker', () => {
  const dest = 'dev_cms/pagemaker';
// `api*` use make a `api*` directory under dest.
  return gulp.src(['dist/**/*', 'app/api*/**/*'])
    .pipe(gulp.dest(`../${dest}`))
    .pipe(gulp.dest(`../testing/${dest}`));
});

gulp.task('copy:time', () => {
  const dest = 'dev_www/frontend/tpl/next/timestamp';
  const timeStamp = new Date().getTime();
// Create a virtual vinyl stream
  const stream = source('timestamp.html');
// write date to the stream.
  stream.end(timeStamp.toString());
// Use the steam with gulp.
  return stream
    .pipe(gulp.dest(`../${dest}`))
    .pipe(gulp.dest(`../testing/${dest}`));
});

// NOTE: app/templates/html/manual_email.html cannot be parsed by `html-minifier`. There might be some invalid markups. Ignore its contents for now.
const minifier = lazypipe()
  .pipe($.htmlmin, {
// minify html
    collapseWhitespace: false,
// minify inline css
    minifyCSS: false,
// minify inline js
    minifyJS: false,
// ignore php tags
    ignoreCustomFragments: [ /<%[\s\S]*?%>/, /<\?[\s\S]*?\?>/ ]
  })
// show which files are processed in terminal
  .pipe($.debug);

gulp.task('copy:tpl', () => {
  const dest = 'dev_www/frontend/tpl/next';
  return gulp.src(['app/templates/partials*/**/*.html', 'app/templates/html*/**/*.html'])
    .pipe(minifier())
    .on('error', (err) => {
      console.error(err.stack);
    })
    .pipe(gulp.dest(`../${dest}`))
    .pipe(gulp.dest(`../testing/${dest}`));
});

gulp.task('copy:p0', () => {
  const dest = 'dev_www/frontend/tpl/corp';
  return gulp.src('app/templates/p0.html')
    .pipe(minifier())
    .on('error', (err) => {
      console.error(err.stack);
    })
    .pipe(gulp.dest(`../${dest}`))
    .pipe(gulp.dest(`../testing/${dest}`));
});

gulp.task('copy', gulp.series(
  'clean',
  'build',
  gulp.parallel(
    'copy:cssjs',
    'copy:marketing',
    'copy:apipage',
    'copy:pagemaker',
    'copy:tpl',
    'copy:p0',
    'copy:time'
  )
));<commit_msg>add comma<commit_after>const fs = require('mz/fs');
const got = require('got');
const co = require('co');
const cheerio = require('cheerio');
const nunjucks = require('nunjucks');
// Set template default dir to `views`. To be used in `home` task.
nunjucks.configure('views', {
  noCache: true,
  watch: false,
  autoescape: false
});
// Promisify nunjucks render function.
function render(view, context) {
  return new Promise(function(resolve, reject) {
    nunjucks.render(view, context, function(err, result) {
      if (err) {
        reject(err);
      } else {
        resolve(result);
      }
    });
  });
}

const del = require('del');

const gulp = require('gulp');
const $ = require('gulp-load-plugins')();
const useref = require('gulp-useref');
const wiredep = require('wiredep').stream;

const browserSync = require('browser-sync').create();
const cssnext = require('postcss-cssnext');
const merge = require('merge-stream');
const source = require('vinyl-source-stream');
const lazypipe = require('lazypipe');

const origamiModules = [
  {
    source: 'http://origami-build.ft.com/v2/bundles/js?modules=o-gallery@^1.7.6',
    dest: './app/origami/o-gallery.js'
  },
  {
    source: 'http://origami-build.ft.com/v2/bundles/css?modules=o-gallery@^1.7.6',
    dest: './app/origami/o-gallery.css'
  }
];

// fetch contents from `origamiModules.source` and write to `origamiModules.dest`.
gulp.task('origami', () => {
  return co(function *() {
    const results = yield Promise.all(origamiModules.map(module => {
      console.log(`fetching ${module.source}`);
  // After getting response from url, return a new object consisting of url's content and file name to write.
      return got(module.source)
        .then(response => {
          return {
            dest: module.dest,
            body: response.body
          }
        }, (error) => {
  // return error if network failed.
          return Promise.reject(error);
        });
    }));

    yield Promise.all(results.map(res => {
      return fs.writeFile(res.dest, res.body, 'utf8');
    }));

  })
  .catch((err) => {
  // catch any error if there are.
    console.error(err.stack);
  });
});

// Fetch latest content from home page, and update `app/index.html`
gulp.task('home', () => {
  const timeStamp = new Date().getTime();
  return co(function *() {
    const destDir = 'app';
  // check if `destDir` exitsts
    try {
      yield fs.access(destDir, fs.constants.R_OK | fs.constants.W_OK);
    } catch (err) {
  // If not, create it.
      yield fs.mkdir(destDir);
    }

    console.log(`fetching latest body from home page`);
    const latestBody = yield got(`http://www.ftchinese.com/m/corp/p0.html?${timeStamp}`)
      .then(response => {
  // Use cheerio to parse HTML and extract contents inside `<body>`
        const $ = cheerio.load(response.body, {
          decodeEntities: true
        });
        return $('body').html();
      });

  // Render `views/index.html` using the extracted body contents.
    const html = yield render('index.html', {body: latestBody});
  // Write rendered file to `.tmp/index.html`
    yield fs.writeFile(`${destDir}/index.html`, html, 'utf8');
    console.log(`Updated ${destDir}/index.html`);
  })
  .catch(err => {
    console.error(err.stack);
  });
})

// To access the api you need to send cookie PHPSESSID.
gulp.task('story', () => {
  return co(function *() {
    const date = new Date();
    const timeStamp = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
    // const cookies = yield got('https://backyard.ftchinese.com/falcon.php/cmsusers/login')
    // .then(response => {
    //   const cookies = response.headers['set-cookie'].map(cookie => {
    //      const obj =  Cookie.parse(cookie);
    //      return `${obj.key}=${obj.value}`;
    //   });
    //   return cookies.join(';');
    // });

    const cookie = `PHPSESSID=78f011e58763cbca4400e42b265d4e33; ftcms_uid=13; ftcms_username=oliver.zhang; ftcms_groups=editor`;

    const response = yield got(`https://backyard.ftchinese.com/falcon.php/homepage/getstoryapi/${timeStamp}`, {
      'headers': {
        'user-agent': 'ftc',
        'cookie': cookie
      }
    });

    yield fs.writeFile('stories.json', response.body, 'utf8');
  })
  .catch(err => {
    console.log(err);
  });
});

// Get the nav.json.
gulp.task('nav', () => {
  return got(`http://m.ftchinese.com/eaclient/apijson.php`, {
    method: 'POST',
    body: JSON.stringify({
      head: {
        transactiontype: '11001',
        source: 'web'
      },
      body: {
        ielement: {}
      }
    })
  })
  .then(response => {
    console.log('updated ./app/api/page/nav.json');
    return fs.writeFile('./app/api/page/nav.json', response.body, 'utf8');
  })
  .catch(error => {
    console.error(error.stack);
  });
});

// Compile SCSS
gulp.task('styles', function () {
  const DEST = '.tmp/styles';

  return gulp.src(['app/styles/main*.scss'])
    .pipe($.changed(DEST))
    .pipe($.plumber())
    .pipe($.sourcemaps.init({loadMaps:true}))
    .pipe($.sass({
      outputStyle: 'expanded',
      precision: 10,
      includePaths: ['bower_components']
    }).on('error', $.sass.logError))
    .pipe($.postcss([
      cssnext({
        features: {
          colorRgba: false
        }
      })
    ]))
    .pipe($.sourcemaps.write('./'))
    .pipe(gulp.dest(DEST))
    .pipe(browserSync.stream({once: true}));
});

gulp.task('ad', function () {
  return gulp.src('app/m/marketing/*')
    .pipe(gulp.dest('dist/m/marketing'));
});

gulp.task('jshint', function () {
  return gulp.src('app/scripts/**/*.js')
    .pipe($.jshint())
    .pipe($.jshint.reporter('jshint-stylish'))
    .pipe($.jshint.reporter('fail'));
});

// Build css and js.
gulp.task('html', gulp.series('styles', () => {
  return gulp.src('app/*.html')
    .pipe($.useref({searchPath: ['.tmp', 'app', '.']}))
    .pipe($.if('*.js', $.uglify()))
    .on('error', (err) => {
      if (err instanceof GulpUglifyError) {
        console.log(err.fileName);
        console.log(err.cause);
        console.log(err.line);
      }
    })
    .pipe($.if('*.css', $.cssnano()))
    .pipe($.if('*.html', $.htmlmin({collapseWhitespace: true})))
    .pipe(gulp.dest('dist'));
}));

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

// Launch static server
gulp.task('serve',
  gulp.parallel(
    'styles',

    function serve() {
    browserSync.init({
      server: {
        baseDir: ['app', '.tmp'],
        index: 'index.html',
        routes: {
          '/bower_components': 'bower_components'
        }
      }
    });

    gulp.watch('app/styles/**/*.scss', gulp.parallel('styles'));
    gulp.watch(['app/*.html', 'app/scripts/**/*.js', 'app/images/**/*'], browserSync.reload);
  })
);

// Is this one in use?
gulp.task('wiredep', function () {

  const scss = gulp.src('app/styles/*.scss')
    .pipe(wiredep())
    .pipe(gulp.dest('app/styles'));

  const html = gulp.src('app/*.html')
    .pipe(wiredep())
    .pipe(gulp.dest('app'));

  return merge(scss, html);
});

gulp.task('clean', function() {
  return del(['.tmp/**', 'dist']).then(()=>{
    console.log('dir .tmp and dist deleted');
  });
});

gulp.task('build', gulp.parallel('jshint', 'html', 'images', /*'fonts', 'extras',*/ 'ad'));

// Various copy tasks.
gulp.task('copy:cssjs', () => {
  const staticDest = 'dev_www/frontend/static/n';
  const cssDest = 'dev_www/frontend/tpl/next/styles';
  const jsDest = 'dev_www/frontend/tpl/next/scripts';

  let cssStream = gulp.src(['app/origami/*.css', 'dist/styles/*.css'])
    .pipe(gulp.dest(`../${staticDest}`))
    .pipe(gulp.dest(`../${cssDest}`))
    .pipe(gulp.dest(`../testing/${cssDest}`));

  let partialsCssStream = gulp.src('dist/styles/partials/*.css')
    .pipe(gulp.dest(`../${cssDest}`))
    .pipe(gulp.dest(`../testing/${cssDest}`));

  let jsStream = gulp.src(['app/origami/*.js', 'dist/scripts/*.js'])
    .pipe(gulp.dest(`../${staticDest}`))
    .pipe(gulp.dest(`../${jsDest}`))
    .pipe(gulp.dest(`../testing/${jsDest}`));

  return merge(cssStream, partialsCssStream, jsStream);
});

gulp.task('copy:marketing', () => {
  const dest = 'dev_www/frontend/tpl/marketing';
  return gulp.src('dist/m/marketing/*')
    .pipe(gulp.dest(`../${dest}`))
    .pipe(gulp.dest(`../testing/${dest}`));
});

gulp.task('copy:apipage', () => {
  const dest = 'dev_www/frontend/tpl/next/api/page'
  return gulp.src('app/api/page/*')
    .pipe(gulp.dest(`../${dest}`))
    .pipe(gulp.dest(`../testing/${dest}`));
});

gulp.task('copy:pagemaker', () => {
  const dest = 'dev_cms/pagemaker';
// `api*` use make a `api*` directory under dest.
  return gulp.src(['dist/**/*', 'app/api*/**/*'])
    .pipe(gulp.dest(`../${dest}`))
    .pipe(gulp.dest(`../testing/${dest}`));
});

gulp.task('copy:time', () => {
  const dest = 'dev_www/frontend/tpl/next/timestamp';
  const timeStamp = new Date().getTime();
// Create a virtual vinyl stream
  const stream = source('timestamp.html');
// write date to the stream.
  stream.end(timeStamp.toString());
// Use the steam with gulp.
  return stream
    .pipe(gulp.dest(`../${dest}`))
    .pipe(gulp.dest(`../testing/${dest}`));
});

// NOTE: app/templates/html/manual_email.html cannot be parsed by `html-minifier`. There might be some invalid markups. Ignore its contents for now.
const minifier = lazypipe()
  .pipe($.htmlmin, {
// minify html
    collapseWhitespace: false,
// minify inline css
    minifyCSS: false,
// minify inline js
    minifyJS: false,
// ignore php tags
    ignoreCustomFragments: [ /<%[\s\S]*?%>/, /<\?[\s\S]*?\?>/ ]
  })
// show which files are processed in terminal
  .pipe($.debug);

gulp.task('copy:tpl', () => {
  const dest = 'dev_www/frontend/tpl/next';
  return gulp.src(['app/templates/partials*/**/*.html', 'app/templates/html*/**/*.html'])
    .pipe(minifier())
    .on('error', (err) => {
      console.error(err.stack);
    })
    .pipe(gulp.dest(`../${dest}`))
    .pipe(gulp.dest(`../testing/${dest}`));
});

gulp.task('copy:p0', () => {
  const dest = 'dev_www/frontend/tpl/corp';
  return gulp.src('app/templates/p0.html')
    .pipe(minifier())
    .on('error', (err) => {
      console.error(err.stack);
    })
    .pipe(gulp.dest(`../${dest}`))
    .pipe(gulp.dest(`../testing/${dest}`));
});

gulp.task('copy', gulp.series(
  'clean',
  'build',
  gulp.parallel(
    'copy:cssjs',
    'copy:marketing',
    'copy:apipage',
    'copy:pagemaker',
    'copy:tpl',
    'copy:p0',
    'copy:time'
  )
));<|endoftext|>


<commit_before>var gulp = require('gulp'),
    rename = require('gulp-rename'),
    jsontransform = require('gulp-json-transform'),
    concatjson = require('gulp-concat-json'),
    clean = require('gulp-clean'),
    run = require('run-sequence'),
    exec = require('gulp-exec'),
    bibtex2json = require('./citation/bibtex2json'),
    fs = require('fs'),
    sh = require('sync-exec');
var startColor = color = 0;

var paths = {
    src: 'app',
    dev: 'www',
    json: 'comparison-elements-json/',
    data: 'app/components/comparison/data/'
};

var files = {
    data: [
        './app/components/comparison/data/*.json',
        './comparison-configuration/*',
        './citation/output/*',
        './favicon.ico'
    ],
    markdown: [
        './comparison-elements/*.md'
    ],
    json: [
        './comparison-elements-json/*.json'
    ]
}

var destfiles = {
    index: './www'
}

// BUILD / UPDATE data files -------------------------------------<
gulp.task('build-data', function (callback) {
    run('versioninfo', 'determinecolors', 'markdown', 'json', 'citation', callback);
})

gulp.task('determinecolors', function() {
    var input = './comparison-configuration/table.json';
    var colorArray = [
        'hsl(000, 100%, 70%)',
        'hsl(15, 100%, 70%)',
        'hsl(30, 100%, 70%)',
        'hsl(45, 100%, 70%)',
        'hsl(60, 100%, 70%)',
        'hsl(75, 100%, 70%)',
        'hsl(90, 100%, 70%)',
        'hsl(105, 100%, 70%)',
        'hsl(120, 100%, 70%)',
        'hsl(135, 100%, 70%)',
        'hsl(150, 100%, 70%)',
        'hsl(165, 100%, 70%)',
        'hsl(180, 100%, 70%)',
        'hsl(195, 100%, 70%)',
        'hsl(210, 100%, 70%)',
        'hsl(225, 100%, 70%)',
        'hsl(240, 100%, 70%)',
        'hsl(255, 100%, 70%)',
        'hsl(270, 100%, 70%)',
        'hsl(285, 100%, 70%)',
        'hsl(300, 100%, 70%)',
        'hsl(315, 100%, 70%)',
        'hsl(330, 100%, 70%)',
        'hsl(345, 100%, 70%)'
    ];
    var color;
    var data = JSON.parse(fs.readFileSync(input, "utf8"));
    var changed = false;
    var count = 0;
    var cCount = 0;
    for (var i = 0; i < data.length; i++) {
        var o = data[i];
        if (o.type.tag === "label" && o.type.values != null) {
            count += o.type.values.length;
            cCount++;
        }
    }
    var delta = Math.floor(colorArray.length / count);
    if (delta < 1) {
        var columnD = Math.floor(colorArray.length / cCount);
    } else {
        var columnD = 0;
    }
    color = Math.floor(Math.random() * colorArray.length);
    for (var i = 0; i < data.length; i++) {
        var o = data[i];
        if (o.type.tag === "label" && o.type.values != null) {
            if (o.type.values[0].weight === undefined) {
                var vals = o.type.values.sort((o1, o2) => o1.name.toString().localeCompare(o2.name.toString()));
            } else {
                var mult = (o.order === undefined || o.order.toLowerCase() === "asc") ? 1 : -1;
                var vals = o.type.values.sort((o1, o2) => mult * (o1.weight - o2.weight));
            }
            for (var j = 0; j < vals.length; j++) {
                var v = vals[j];
                if (!(v.hasOwnProperty("class") || v.hasOwnProperty("color"))) {
                    v.color = colorArray[color];
                    changed = true;
                    color = (color + delta) % colorArray.length;
                }
            }
        }
        color = (color + columnD) % colorArray.length;
    }
    if (changed) {
        fs.writeFileSync(input, JSON.stringify(data, null, 4), "utf8");
    }
    return true;
});

gulp.task('versioninfo', function () {
    var versionfile = './app/VersionInformation.ts.example';
    var output = './app/VersionInformation.ts';
    var revision = sh('git rev-parse HEAD');
    var date = sh('git log -1 --format=%cd --date=short');
    return gulp.src(versionfile)
        .pipe(rename(output))
        .pipe(gulp.dest('.'))
        .pipe(exec('sed -i\'.bak\' "s/§§date§§/' + date.stdout.trim() + '/" ' + output))
        .pipe(exec('sed -i\'.bak\' "s/§§commit§§/' + revision.stdout.trim() + '/g" ' + output));
})

gulp.task('update-data', function () {
    gulp.watch(files.markdown, ['build-data']);
})

gulp.task('markdown', function(callback){
    var options = {
      continueOnError: false,
      pipeStdout: true
    }
    return gulp.src(files.markdown)
    .pipe(exec("./gradlew -q -b ./app/java/md-to-json/build.gradle run -PappArgs=\"[$/\n<%= file.contents.toString() %>\n/$, 1, true]\"", options))
    .pipe(rename({extname: ".json"}))
    .pipe(gulp.dest(paths.json));
});

gulp.task('json', function(){
    return gulp.src(files.json)
        .pipe(concatjson("data.json"))
        .pipe(jsontransform(function(data){
            return data;
        }, 2))
        .pipe(gulp.dest(paths.data))
})

gulp.task('citation', function(callback){
    var fileContent = JSON.parse(fs.readFileSync("./citation/config.json", "utf8"));
    bibtex2json.parse('./citation/' + fileContent.bibtex_file, 'utf8', './citation/' + fileContent.bibtex_style, './citation/output', callback);
})
// --------------------------------------------------------------->

// BUILD / UPDATE www folder -------------------------------------<
gulp.task('build-www', ['data'], function () {})

gulp.task('update-www', function () {
    gulp.watch(files.data, ['data']);
})

gulp.task('data', function() {
    return gulp.src(files.data, {base: '.'})
        .pipe(gulp.dest(destfiles.index));
});
// --------------------------------------------------------------->

// DELETE www folder ---------------------------------------------<
gulp.task('delete-www', function() {
    return gulp.src(paths.dev, {read: false})
        .pipe(clean());
});
// --------------------------------------------------------------->

// DEFAULT and DEV tasks -----------------------------------------<
gulp.task('default', function(callback){
    run('build-data', 'delete-www', 'build-www', callback);
});

gulp.task('dev', ['default'], function(callback) {
    run('update-data','update-www', callback);
});
// --------------------------------------------------------------->
<commit_msg>Possible incompatible change: call of gradlew<commit_after>var gulp = require('gulp'),
    rename = require('gulp-rename'),
    jsontransform = require('gulp-json-transform'),
    concatjson = require('gulp-concat-json'),
    clean = require('gulp-clean'),
    run = require('run-sequence'),
    exec = require('gulp-exec'),
    bibtex2json = require('./citation/bibtex2json'),
    fs = require('fs'),
    sh = require('sync-exec');
var startColor = color = 0;

var paths = {
    src: 'app',
    dev: 'www',
    json: 'comparison-elements-json/',
    data: 'app/components/comparison/data/'
};

var files = {
    data: [
        './app/components/comparison/data/*.json',
        './comparison-configuration/*',
        './citation/output/*',
        './favicon.ico'
    ],
    markdown: [
        './comparison-elements/*.md'
    ],
    json: [
        './comparison-elements-json/*.json'
    ]
}

var destfiles = {
    index: './www'
}

// BUILD / UPDATE data files -------------------------------------<
gulp.task('build-data', function (callback) {
    run('versioninfo', 'determinecolors', 'markdown', 'json', 'citation', callback);
})

gulp.task('determinecolors', function() {
    var input = './comparison-configuration/table.json';
    var colorArray = [
        'hsl(000, 100%, 70%)',
        'hsl(15, 100%, 70%)',
        'hsl(30, 100%, 70%)',
        'hsl(45, 100%, 70%)',
        'hsl(60, 100%, 70%)',
        'hsl(75, 100%, 70%)',
        'hsl(90, 100%, 70%)',
        'hsl(105, 100%, 70%)',
        'hsl(120, 100%, 70%)',
        'hsl(135, 100%, 70%)',
        'hsl(150, 100%, 70%)',
        'hsl(165, 100%, 70%)',
        'hsl(180, 100%, 70%)',
        'hsl(195, 100%, 70%)',
        'hsl(210, 100%, 70%)',
        'hsl(225, 100%, 70%)',
        'hsl(240, 100%, 70%)',
        'hsl(255, 100%, 70%)',
        'hsl(270, 100%, 70%)',
        'hsl(285, 100%, 70%)',
        'hsl(300, 100%, 70%)',
        'hsl(315, 100%, 70%)',
        'hsl(330, 100%, 70%)',
        'hsl(345, 100%, 70%)'
    ];
    var color;
    var data = JSON.parse(fs.readFileSync(input, "utf8"));
    var changed = false;
    var count = 0;
    var cCount = 0;
    for (var i = 0; i < data.length; i++) {
        var o = data[i];
        if (o.type.tag === "label" && o.type.values != null) {
            count += o.type.values.length;
            cCount++;
        }
    }
    var delta = Math.floor(colorArray.length / count);
    if (delta < 1) {
        var columnD = Math.floor(colorArray.length / cCount);
    } else {
        var columnD = 0;
    }
    color = Math.floor(Math.random() * colorArray.length);
    for (var i = 0; i < data.length; i++) {
        var o = data[i];
        if (o.type.tag === "label" && o.type.values != null) {
            if (o.type.values[0].weight === undefined) {
                var vals = o.type.values.sort((o1, o2) => o1.name.toString().localeCompare(o2.name.toString()));
            } else {
                var mult = (o.order === undefined || o.order.toLowerCase() === "asc") ? 1 : -1;
                var vals = o.type.values.sort((o1, o2) => mult * (o1.weight - o2.weight));
            }
            for (var j = 0; j < vals.length; j++) {
                var v = vals[j];
                if (!(v.hasOwnProperty("class") || v.hasOwnProperty("color"))) {
                    v.color = colorArray[color];
                    changed = true;
                    color = (color + delta) % colorArray.length;
                }
            }
        }
        color = (color + columnD) % colorArray.length;
    }
    if (changed) {
        fs.writeFileSync(input, JSON.stringify(data, null, 4), "utf8");
    }
    return true;
});

gulp.task('versioninfo', function () {
    var versionfile = './app/VersionInformation.ts.example';
    var output = './app/VersionInformation.ts';
    var revision = sh('git rev-parse HEAD');
    var date = sh('git log -1 --format=%cd --date=short');
    return gulp.src(versionfile)
        .pipe(rename(output))
        .pipe(gulp.dest('.'))
        .pipe(exec('sed -i\'.bak\' "s/§§date§§/' + date.stdout.trim() + '/" ' + output))
        .pipe(exec('sed -i\'.bak\' "s/§§commit§§/' + revision.stdout.trim() + '/g" ' + output));
})

gulp.task('update-data', function () {
    gulp.watch(files.markdown, ['build-data']);
})

gulp.task('markdown', function(callback){
    var options = {
      continueOnError: false,
      pipeStdout: true
    }
    return gulp.src(files.markdown)
    .pipe(exec("gradlew -q -b ./app/java/md-to-json/build.gradle md2json -PappArgs=\"[$/\n<%= file.contents.toString() %>\n/$, 1, true]\"", options))
    .pipe(rename({extname: ".json"}))
    .pipe(gulp.dest(paths.json));
});

gulp.task('json', function(){
    return gulp.src(files.json)
        .pipe(concatjson("data.json"))
        .pipe(jsontransform(function(data){
            return data;
        }, 2))
        .pipe(gulp.dest(paths.data))
})

gulp.task('citation', function(callback){
    var fileContent = JSON.parse(fs.readFileSync("./citation/config.json", "utf8"));
    bibtex2json.parse('./citation/' + fileContent.bibtex_file, 'utf8', './citation/' + fileContent.bibtex_style, './citation/output', callback);
})
// --------------------------------------------------------------->

// BUILD / UPDATE www folder -------------------------------------<
gulp.task('build-www', ['data'], function () {})

gulp.task('update-www', function () {
    gulp.watch(files.data, ['data']);
})

gulp.task('data', function() {
    return gulp.src(files.data, {base: '.'})
        .pipe(gulp.dest(destfiles.index));
});
// --------------------------------------------------------------->

// DELETE www folder ---------------------------------------------<
gulp.task('delete-www', function() {
    return gulp.src(paths.dev, {read: false})
        .pipe(clean());
});
// --------------------------------------------------------------->

// DEFAULT and DEV tasks -----------------------------------------<
gulp.task('default', function(callback){
    run('build-data', 'delete-www', 'build-www', callback);
});

gulp.task('dev', ['default'], function(callback) {
    run('update-data','update-www', callback);
});
// --------------------------------------------------------------->
<|endoftext|>


<commit_before><commit_msg>Update gulpfile<commit_after>var gulp = require('gulp');
var browserify = require('browserify');
<|endoftext|>


<commit_before>var gulp = require('gulp');
var autoprefixer = require('gulp-autoprefixer');
var concatCss = require('gulp-concat-css');
var uglifyjs = require('gulp-uglifyjs');
var rename = require('gulp-rename');
var cssmin = require('gulp-cssmin');
var sass = require('gulp-sass');
var del = require('del');
var browserSync = require('browser-sync').create();
var runSequence = require('run-sequence');

// configuration
var paths = {
    html: 'build/index.html',
    css: 'build/styles/*.css',
    sass: 'build/styles/sass/*.scss',
    scripts: 'build/scripts/*.js'
};

gulp.task('browser-sync', function () {
    browserSync.init({
        server: {
            baseDir: "./app"
        }
    });
});

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

gulp.task('html', function () {
    return gulp.src(paths.html)
        .pipe(gulp.dest('app'))
        .pipe(browserSync.stream());
});

// gulp.task('styles', function() {
//     return gulp.src(paths.css)
//         .pipe(autoprefixer())
//         .pipe(concatCss('style.css'))
//         .pipe(cssmin())
//         .pipe(rename('style.min.css'))
//         .pipe(gulp.dest('app/styles'))
//         .pipe(browserSync.stream());
// });

gulp.task('cssreset', function() {
    return gulp.src(paths.css)
        .pipe(cssmin())
        .pipe(rename('normalize.min.css'))
        .pipe(gulp.dest('app/styles'));
});

gulp.task('sass', function() {
    return gulp.src(paths.sass)
        .pipe(sass().on('error', sass.logError))
        .pipe(concatCss('style.css'))
        .pipe(cssmin())
        .pipe(rename('style.min.css'))
        .pipe(gulp.dest('app/styles'))
        .pipe(browserSync.stream());
});

gulp.task('scripts', function() {
    return gulp.src(paths.scripts)
        .pipe(uglifyjs())
        .pipe(rename('script.min.js'))
        .pipe(gulp.dest('app/scripts'))
        .pipe(browserSync.stream());
});

gulp.task('build', function(callback) {
    runSequence('clean', ['html', 'cssreset', 'sass', 'scripts', 'browser-sync', 'watch'],
        callback
    )
});

gulp.task('watch', function() {
    //gulp.watch(paths.css, ['styles']);
    gulp.watch(paths.sass, ['sass']);
    gulp.watch(paths.scripts, ['scripts']);
    gulp.watch(paths.html, ['html']);
});<commit_msg>add sass to repository<commit_after>var gulp = require('gulp');
var autoprefixer = require('gulp-autoprefixer');
var concatCss = require('gulp-concat-css');
var uglifyjs = require('gulp-uglifyjs');
var rename = require('gulp-rename');
var cssmin = require('gulp-cssmin');
var sass = require('gulp-sass');
var del = require('del');
var browserSync = require('browser-sync').create();
var runSequence = require('run-sequence');

// configuration
var paths = {
    html: 'build/index.html',
    css: 'build/styles/*.css',
    sass: 'build/styles/sass/*.scss',
    scripts: 'build/scripts/*.js'
};

gulp.task('browser-sync', function () {
    browserSync.init({
        server: {
            baseDir: "./app"
        }
    });
});

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

gulp.task('html', function () {
    return gulp.src(paths.html)
        .pipe(gulp.dest('app'))
        .pipe(browserSync.stream());
});

// gulp.task('styles', function() {
//     return gulp.src(paths.css)
//         .pipe(autoprefixer())
//         .pipe(concatCss('style.css'))
//         .pipe(cssmin())
//         .pipe(rename('style.min.css'))
//         .pipe(gulp.dest('app/styles'))
//         .pipe(browserSync.stream());
// });

gulp.task('cssreset', function() {
    return gulp.src(paths.css)
        .pipe(cssmin())
        .pipe(rename('normalize.min.css'))
        .pipe(gulp.dest('app/styles'));
});

gulp.task('sass', function() {
    return gulp.src(paths.sass)
        .pipe(sass().on('error', sass.logError))
        .pipe(autoprefixer())
        .pipe(concatCss('style.css'))
        .pipe(cssmin())
        .pipe(rename('style.min.css'))
        .pipe(gulp.dest('app/styles'))
        .pipe(browserSync.stream());
});

gulp.task('scripts', function() {
    return gulp.src(paths.scripts)
        .pipe(uglifyjs())
        .pipe(rename('script.min.js'))
        .pipe(gulp.dest('app/scripts'))
        .pipe(browserSync.stream());
});

gulp.task('build', function(callback) {
    runSequence('clean', ['html', 'cssreset', 'sass', 'scripts', 'browser-sync', 'watch'],
        callback
    )
});

gulp.task('watch', function() {
    //gulp.watch(paths.css, ['styles']);
    gulp.watch(paths.sass, ['sass']);
    gulp.watch(paths.scripts, ['scripts']);
    gulp.watch(paths.html, ['html']);
});<|endoftext|>


<commit_before>const gulp = require('gulp')
const browserSync = require('browser-sync').create()
const sass = require('gulp-sass')
const plumber = require('gulp-plumber')
const gutil = require('gulp-util')
const uncss = require('gulp-uncss')
const fs = require('fs')
const juice = require('juice')
const path = require('path')
const information = require(path.join(__dirname, 'working/information.json'))
const html2txt = require('gulp-html2txt')
const cheerio = require('cheerio')

// Compile sass into CSS & auto-inject into browsers
gulp.task('sass', (done) => {
  return gulp.src('working/scss/*.scss')
    // plumber is used so that the watch task does not break when there is some wrong code
    .pipe(plumber(function (error) {
      gutil.beep()
      console.log(error)
      this.emit('end')
    }))
    .pipe(sass())
    .pipe(gulp.dest('working/css'))
    .pipe(browserSync.stream())
})

// Compile sass into CSS, remove unneeded CSS and dump it into the working folder for use in build process
// it is not neccessary to create a build CSS file just for the purpose of building the final email
gulp.task('css', () => {
  return gulp.src('working/scss/*.scss')
    .pipe(plumber(function (error) {
      gutil.beep()
      console.log(error)
      this.emit('end')
    }))
    .pipe(sass())
    .pipe(uncss({
      html: ['working/index.html']
    }))
    .pipe(gulp.dest('working/css'))
})

/**
* replaces each instance of a replacelist key template in the string for the replacelist value
* @param {string}
* @param {object}
* @return {string}
*/
const replaceLinks = (str, replacelist = {}) => {
  // there has to be a string to pass through even if replacelist is empty
  if (str.length < 1) throw new Error('File is empty')
  // if there is no replacelist or it is empty, pass through the value
  let html = str
  if (Object.keys(replacelist).length !== 0) {
    for (const key of Object.keys(replacelist)) {
      let replacestring = new RegExp(`#{${key}}`, 'g')
      html = html.replace(replacestring, replacelist[key])
    }
    let basicReg = /#{(.*?)}/g
    let els = html.match(basicReg)
    if (els !== null) {
      // find all matches and filter out the fluff
      // TODO think about if a set would be more appropriate as it would only list the unique values
      /*
      let allElements = new Set(els.map(x => x.replace('#{','').replace('}', '')))
      console.log(`Warning: there are still ${allElements.size} elements not replaced: ${[...allElements]}'`)
      */
      let allElements = els.map(x => x.replace('#{', '').replace('}', ''))
      console.log(`Warning: there are still ${allElements.length} instances not replaced: ${allElements}`)
    }
    return html
  } else {
    console.log('Warning: no links are provided, html goes through as is.')
    return str
  }
}

/**
* creates a url parameter string from the links object given
* @param {object}
* @return {string}
*/
const createParameterString = (parameters) => {
  let availableUtmKeys = ['source', 'medium', 'name', 'term', 'content']
  let paramsArr = []

  // check if the parameters exist, otherwise don't bother
  if (parameters.utm || parameters.custom) {
    // loop through all the utm and custom keys
    for (const paramKeys of Object.keys(parameters)) {
      // loop through the inner keys of utm and custom
      for (const key of Object.keys(parameters[paramKeys])) {
        // don't add if it is empty or if it is not a string or number
        if (parameters[paramKeys][key] && (typeof parameters[paramKeys][key] === 'string' || typeof parameters[paramKeys][key] === 'number')) {
          // only add the keys that are valid utm keys, ignore the ones that are not correct
          // IGNORE OR ERROR?
          if (paramKeys === 'utm' && availableUtmKeys.indexOf(key) !== -1) {
            paramsArr.push(`utm_${key}=${parameters[paramKeys][key]}`)
          } else if (paramKeys !== 'utm') { // if the keys are not utm, you are free to add them
            paramsArr.push(`${key}=${parameters[paramKeys][key]}`)
          }
        }
      }
    }
  }
  // joining all parameters in a string
  // if there are no parameters, create an empty string
  let paramsString = paramsArr.length !== 0 ? `?${paramsArr.join('&')}` : ''
  return paramsString
}

/**
* replaces each instance of a href atrribute in the first argument for the values provided in the second argument
* @param {string}
* @param {string}
* @param {function}
* @return {string}
*/
const addParameters = (str, parameters = '', cheerio) => {
  // check if the createParameterString returns a non-empty string
  // to avoid all the work that is not needed
  if (parameters) {
    // load the cheerio instance for appending links
    const $ = cheerio.load(str, { decodeEntities: false })
    // create the parameter string that will be appended to each href

    // add the parameters to each href in the email
    $('a').each(function (i, el) {
      let origHref = $(this).attr('href')
      // if the split method returns an array that is longer than 1 element, it means that there is an existing parameter in it
      // append the parameters only if there is no existing parameters
      if (origHref.split('?').length === 1) {
        $(this).attr('href', origHref + parameters)
      }
    })
    return $.html()
  } else {
    // if there is nothing available, return as is
    return str
  }
}

/**
* replaces each instance of a href atrribute in the first argument for the values provided in the second argument
* @param {string}
* @param {string}
* @return {string}
*/
const createHtml = (html, cssPath, addParameters, createParameterString, cheerio) => {
  return new Promise((resolve, reject) => {
    // replace the file path in the html file so that juice can find it, looking from the root of the project
    let email = html.replace('<link rel="stylesheet" href="css/styles.css">', `<link rel="stylesheet" href="${cssPath}">`)
    juice.juiceResources(email, { preserveMediaQueries: true, applyStyleTags: true }, (err, html) => {
      if (err) reject(err)
      // replace the url placeholder and add url parameters
      resolve(addParameters(replaceLinks(html, information.links), createParameterString(information.parameters), cheerio))
    })
  })
}

gulp.task('premailer', (done) => {
  fs.readFile('working/index.html', 'utf-8', (err, html) => {
    if (err) throw err
    createHtml(html, 'working/css/styles.css', addParameters, createParameterString, cheerio).then(html => {
      fs.writeFile('build/index.html', html, (err) => {
        if (err) throw err
        done()
      })
    }).catch(e => {
      done()
      throw e
    })
  })
})

// convert html to txt
gulp.task('txt', () => {
  return gulp.src('build/index.html')
    .pipe(html2txt())
    .pipe(gulp.dest('build/'))
})

// start up browserSync
gulp.task('browserSync', (done) => {
  browserSync.init({
    server: 'working'
  })
  done()
})

// reload browserSync
gulp.task('reload', (done) => {
  browserSync.reload()
  done()
})

// watch scss and html files for changes
gulp.task('watchSassAndHtml', () => {
  gulp.watch('working/scss/*.scss', gulp.parallel('sass', 'reload'))
  gulp.watch('working/*.html', gulp.series('reload'))
})

gulp.task('build', gulp.series('css', 'premailer', 'txt'))
gulp.task('serve', gulp.series('sass', gulp.parallel('browserSync', 'watchSassAndHtml')))

module.exports = {
  replaceLinks,
  addParameters,
  createParameterString,
  createHtml
}
<commit_msg>add mailgun send email capability<commit_after>const gulp = require('gulp')
const browserSync = require('browser-sync').create()
const sass = require('gulp-sass')
const plumber = require('gulp-plumber')
const gutil = require('gulp-util')
const uncss = require('gulp-uncss')
const fs = require('fs')
const juice = require('juice')
const path = require('path')
const information = require(path.join(__dirname, 'working/information.json'))
const html2txt = require('gulp-html2txt')
const cheerio = require('cheerio')
const mailgun = require('mailgun.js')

// Compile sass into CSS & auto-inject into browsers
gulp.task('sass', (done) => {
  return gulp.src('working/scss/*.scss')
    // plumber is used so that the watch task does not break when there is some wrong code
    .pipe(plumber(function (error) {
      gutil.beep()
      console.log(error)
      this.emit('end')
    }))
    .pipe(sass())
    .pipe(gulp.dest('working/css'))
    .pipe(browserSync.stream())
})

// Compile sass into CSS, remove unneeded CSS and dump it into the working folder for use in build process
// it is not neccessary to create a build CSS file just for the purpose of building the final email
gulp.task('css', () => {
  return gulp.src('working/scss/*.scss')
    .pipe(plumber(function (error) {
      gutil.beep()
      console.log(error)
      this.emit('end')
    }))
    .pipe(sass())
    .pipe(uncss({
      html: ['working/index.html']
    }))
    .pipe(gulp.dest('working/css'))
})

/**
* replaces each instance of a replacelist key template in the string for the replacelist value
* @param {string}
* @param {object}
* @return {string}
*/
const replaceLinks = (str, replacelist = {}) => {
  // there has to be a string to pass through even if replacelist is empty
  if (str.length < 1) throw new Error('File is empty')
  // if there is no replacelist or it is empty, pass through the value
  let html = str
  if (Object.keys(replacelist).length !== 0) {
    for (const key of Object.keys(replacelist)) {
      let replacestring = new RegExp(`#{${key}}`, 'g')
      html = html.replace(replacestring, replacelist[key])
    }
    let basicReg = /#{(.*?)}/g
    let els = html.match(basicReg)
    if (els !== null) {
      // find all matches and filter out the fluff
      // TODO think about if a set would be more appropriate as it would only list the unique values
      /*
      let allElements = new Set(els.map(x => x.replace('#{','').replace('}', '')))
      console.log(`Warning: there are still ${allElements.size} elements not replaced: ${[...allElements]}'`)
      */
      let allElements = els.map(x => x.replace('#{', '').replace('}', ''))
      console.log(`Warning: there are still ${allElements.length} instances not replaced: ${allElements}`)
    }
    return html
  } else {
    console.log('Warning: no links are provided, html goes through as is.')
    return str
  }
}

/**
* creates a url parameter string from the links object given
* @param {object}
* @return {string}
*/
const createParameterString = (parameters) => {
  let availableUtmKeys = ['source', 'medium', 'name', 'term', 'content']
  let paramsArr = []

  // check if the parameters exist, otherwise don't bother
  if (parameters.utm || parameters.custom) {
    // loop through all the utm and custom keys
    for (const paramKeys of Object.keys(parameters)) {
      // loop through the inner keys of utm and custom
      for (const key of Object.keys(parameters[paramKeys])) {
        // don't add if it is empty or if it is not a string or number
        if (parameters[paramKeys][key] && (typeof parameters[paramKeys][key] === 'string' || typeof parameters[paramKeys][key] === 'number')) {
          // only add the keys that are valid utm keys, ignore the ones that are not correct
          // IGNORE OR ERROR?
          if (paramKeys === 'utm' && availableUtmKeys.indexOf(key) !== -1) {
            paramsArr.push(`utm_${key}=${parameters[paramKeys][key]}`)
          } else if (paramKeys !== 'utm') { // if the keys are not utm, you are free to add them
            paramsArr.push(`${key}=${parameters[paramKeys][key]}`)
          }
        }
      }
    }
  }
  // joining all parameters in a string
  // if there are no parameters, create an empty string
  let paramsString = paramsArr.length !== 0 ? `?${paramsArr.join('&')}` : ''
  return paramsString
}

/**
* replaces each instance of a href atrribute in the first argument for the values provided in the second argument
* @param {string}
* @param {string}
* @param {function}
* @return {string}
*/
const addParameters = (str, parameters = '', cheerio) => {
  // check if the createParameterString returns a non-empty string
  // to avoid all the work that is not needed
  if (parameters) {
    // load the cheerio instance for appending links
    const $ = cheerio.load(str, { decodeEntities: false })
    // create the parameter string that will be appended to each href

    // add the parameters to each href in the email
    $('a').each(function (i, el) {
      let origHref = $(this).attr('href')
      // if the split method returns an array that is longer than 1 element, it means that there is an existing parameter in it
      // append the parameters only if there is no existing parameters
      if (origHref.split('?').length === 1) {
        $(this).attr('href', origHref + parameters)
      }
    })
    return $.html()
  } else {
    // if there is nothing available, return as is
    return str
  }
}

/**
* replaces each instance of a href atrribute in the first argument for the values provided in the second argument
* @param {string}
* @param {string}
* @return {string}
*/
const createHtml = (html, cssPath, addParameters, createParameterString, cheerio) => {
  return new Promise((resolve, reject) => {
    // replace the file path in the html file so that juice can find it, looking from the root of the project
    let email = html.replace('<link rel="stylesheet" href="css/styles.css">', `<link rel="stylesheet" href="${cssPath}">`)
    juice.juiceResources(email, { preserveMediaQueries: true, applyStyleTags: true }, (err, html) => {
      if (err) reject(err)
      // replace the url placeholder and add url parameters
      resolve(addParameters(replaceLinks(html, information.links), createParameterString(information.parameters), cheerio))
    })
  })
}

gulp.task('premailer', (done) => {
  fs.readFile('working/index.html', 'utf-8', (err, html) => {
    if (err) throw err
    createHtml(html, 'working/css/styles.css', addParameters, createParameterString, cheerio).then(html => {
      fs.writeFile('build/index.html', html, (err) => {
        if (err) throw err
        done()
      })
    }).catch(e => {
      done()
      throw e
    })
  })
})

// convert html to txt
gulp.task('txt', () => {
  return gulp.src('build/index.html')
    .pipe(html2txt())
    .pipe(gulp.dest('build/'))
})

// start up browserSync
gulp.task('browserSync', (done) => {
  browserSync.init({
    server: 'working'
  })
  done()
})

// reload browserSync
gulp.task('reload', (done) => {
  browserSync.reload()
  done()
})

// watch scss and html files for changes
gulp.task('watchSassAndHtml', () => {
  gulp.watch('working/scss/*.scss', gulp.parallel('sass', 'reload'))
  gulp.watch('working/*.html', gulp.series('reload'))
})

gulp.task('build', gulp.series('css', 'premailer', 'txt'))
gulp.task('serve', gulp.series('sass', gulp.parallel('browserSync', 'watchSassAndHtml')))

const sendmail = (done) => {
  const credentials = require('./credentials.json')
  const mg = mailgun.client({ username: 'api', key: process.env.MAILGUN_API_KEY || credentials.mailgun.key })
  const information = require('./working/information.json')
  const html = new Promise((resolve, reject) => {
    fs.readFile('./build/index.html', 'utf-8', (err, data) => {
      if (err) throw Error(err)
      if (data.length > 0) {
        resolve(data)
      } else {
        reject('Empty file')
      }
    })
  })
  const text = new Promise((resolve, reject) => {
    fs.readFile('./build/index.txt', 'utf-8', (err, data) => {
      if (err) throw Error(err)
      if (data.length > 0) {
        resolve(data)
      } else {
        reject('Empty file')
      }
    })
  })

  Promise.all([html, text]).then(emails => {
    mg.messages.create(credentials.mailgun.domain, {
      from: `${information.senderName} ${information.senderEmail}`,
      to: information.recipient,
      subject: information.subject,
      text: emails[1],
      html: emails[0]
    })
      .then(msg => {
        console.log(msg)
        done()
      }
      ) // logs response data
      .catch(err => {
        console.log(err)
        done()
      }) // logs any error
  }).catch(err => {
    console.log(err)
    done()
  })
}

gulp.task('sendmail', gulp.series('css', 'premailer', 'txt', sendmail))

module.exports = {
  replaceLinks,
  addParameters,
  createParameterString,
  createHtml,
  sendmail
}
<|endoftext|>


<commit_before>var gulp = require('gulp');
var sass = require('gulp-sass');
var uglify = require('gulp-uglify');
var concat = require('gulp-concat');
var minifyCSS = require('gulp-minify-css');
var rename = require("gulp-rename");

var files = {
    css: {
        vendor: [
            'bower_components/bootstrap/dist/css/bootstrap.min.css',
            'bower_components/font-awesome/css/font-awesome.min.css',
            'assets/vendor/hljs.css',
            'node_modules/codemirror/lib/codemirror.css',
            'node_modules/codemirror/addon/fold/foldgutter.css',
            'node_modules/codemirror/addon/dialog/dialog.css',
            'node_modules/react-select2-wrapper/css/select2.css'
        ],
        custom: ['assets/css/*.css'],
        sassFile: ['assets/styles/*.scss']
    },
    js: {
        vendor: [
            'bower_components/jquery/dist/jquery.min.js',
            'bower_components/bootstrap/dist/js/bootstrap.min.js',
            'bower_components/lodash/dist/lodash.min.js',
            'bower_components/crypto-js/crypto-js.js',
            'bower_components/lzma/src/lzma.js',
            'bower_components/urlsafe-base64/app.js',
            'bower_components/auth0.js/build/auth0.min.js'
        ],
        custom: [
        ]
    }
};

gulp.task('vendorcss', function() {
    return gulp.src(files.css.vendor)
        .pipe(concat('vendor.min.css'))
        .pipe(gulp.dest('dist/css'));
});

gulp.task('customcss', ['sass'], function() {
    return gulp.src(files.css.custom)
        .pipe(minifyCSS())
        .pipe(concat('style.min.css'))
        .pipe(gulp.dest('dist/css'));
});

gulp.task('vendorjs', function() {
    return gulp.src(files.js.vendor)
        .pipe(concat('vendor.min.js'))
        .pipe(gulp.dest('dist/js'));
});

gulp.task('sass', function() {
    return gulp.src(files.css.sassFile)
        .pipe(sass.sync().on('error', sass.logError))
        .pipe(gulp.dest('assets/css'));
});

gulp.task('moveCss', function() {
    return gulp.src(['bower_components/bootstrap/dist/css/bootstrap.min.css.map'])
        .pipe(gulp.dest('dist/css'));
});

gulp.task('moveFonts', function() {
    return gulp.src(['bower_components/bootstrap/dist/fonts/*',
        'bower_components/font-awesome/fonts/*'
        ])
        .pipe(gulp.dest('dist/fonts'));
});

// Include dependency in dist
gulp.task('move_js_depends', function() {
    return gulp.src(['bower_components/lzma/src/lzma_worker.js',
        'assets/vendor/JSONURL.js'])
        .pipe(gulp.dest('dist/vendor'));
});

// Prepare files for es plugin
gulp.task('build_es_plugin', ['compact'], function() {
    var dirs = [
        'app',
        'assets',
        'dist'
    ];
    dirs.forEach(function(dir) {
        gulp.src([dir+'/**/*']).pipe(gulp.dest('./_site/'+dir+'/'));
    });
    return gulp.src(['index.html']).pipe(gulp.dest('./_site/'));
});

// chrome build
gulp.task('chromePreBuild', ['compact', 'chrome-specific_dir'], function() {
});

gulp.task('chromeBuild', ['chromePreBuild'], function() {
    var dirs = [
        'app',
        'assets',
        'dist'
    ];
    dirs.forEach(function(dir) {
        gulp.src([dir+'/**/*']).pipe(gulp.dest('./gem-unpacked/site/'+dir+'/'));
    });
    return gulp.src(['index.html']).pipe(gulp.dest('./gem-unpacked/site/'));
});

// copy chrome-specific dir
gulp.task('chrome-specific_dir', function() {
    return gulp.src(['chrome-specific/**/*']).pipe(gulp.dest('./gem-unpacked/'));
});

gulp.task('compact', [
    'customcss',
    'vendorcss',
    'vendorjs',
    'moveCss',
    'moveFonts',
    'move_js_depends'
]);

gulp.task('watchfiles', function() {
    gulp.watch(files.css.sassFile, ['customcss']);
});

gulp.task('default', ['compact']);

gulp.task('watch', ['compact', 'watchfiles']);
<commit_msg>Fix gulpfile<commit_after>var gulp = require('gulp');
var sass = require('gulp-sass');
var uglify = require('gulp-uglify');
var concat = require('gulp-concat');
var minifyCSS = require('gulp-minify-css');
var rename = require("gulp-rename");

var files = {
	css: {
		vendor: [
			'bower_components/bootstrap/dist/css/bootstrap.min.css',
			'bower_components/font-awesome/css/font-awesome.min.css',
			'assets/vendor/hljs.css',
			'node_modules/codemirror/lib/codemirror.css',
			'node_modules/codemirror/addon/fold/foldgutter.css',
			'node_modules/codemirror/addon/dialog/dialog.css',
			'node_modules/react-select2-wrapper/css/select2.css'
		],
		custom: ['assets/css/*.css'],
		sassFile: ['assets/styles/*.scss']
	},
	js: {
		vendor: [
			'bower_components/jquery/dist/jquery.min.js',
			'bower_components/bootstrap/dist/js/bootstrap.min.js',
			'bower_components/lodash/dist/lodash.min.js',
			'bower_components/crypto-js/crypto-js.js',
			'bower_components/lzma/src/lzma.js',
			'bower_components/urlsafe-base64/app.js',
			'bower_components/auth0.js/build/auth0.min.js'
		],
		custom: [
		]
	}
};

function bundle_stuff(src, filename, distPath) {
	return gulp.src(src)
		.pipe(concat(filename))
		.pipe(gulp.dest(distPath));
}

gulp.task('vendorcss', function() {
	return bundle_stuff(files.css.vendor, 'vendor.min.css', 'dist/css');
});

gulp.task('customcss', ['sass'], function() {
	return gulp.src(files.css.custom)
		.pipe(minifyCSS())
		.pipe(concat('style.min.css'))
		.pipe(gulp.dest('dist/css'));
});

gulp.task('vendorjs', function() {
	return bundle_stuff(files.js.vendor, 'vendor.min.js', 'dist/js');
});

gulp.task('sass', function() {
	return gulp.src(files.css.sassFile)
		.pipe(sass.sync().on('error', sass.logError))
		.pipe(gulp.dest('assets/css'));
});

gulp.task('moveCss', function() {
	return gulp.src(['bower_components/bootstrap/dist/css/bootstrap.min.css.map'])
		.pipe(gulp.dest('dist/css'));
});

gulp.task('moveFonts', function() {
	return gulp.src(['bower_components/bootstrap/dist/fonts/*',
		'bower_components/font-awesome/fonts/*'
		])
		.pipe(gulp.dest('dist/fonts'));
});

// Include dependency in dist
gulp.task('move_js_depends', function() {
	return gulp.src(['bower_components/lzma/src/lzma_worker.js',
		'assets/vendor/JSONURL.js'])
		.pipe(gulp.dest('dist/vendor'));
});

function move_after_build(path) {
	var dirs = [
		'app',
		'assets',
		'dist'
	];
	dirs.forEach(function(dir) {
		gulp.src([dir+'/**/*']).pipe(gulp.dest(path+dir+'/'));
	});
	return gulp.src(['index.html']).pipe(gulp.dest(path));
}

// Prepare files for es plugin
gulp.task('build_es_plugin', ['compact'], function() {
	return move_after_build('./_site/');
});

// chrome build
gulp.task('chromePreBuild', ['compact', 'chrome-specific_dir'], function() {
});

gulp.task('chromeBuild', ['chromePreBuild'], function() {
	return move_after_build('./gem-unpacked/site/');
});

// copy chrome-specific dir
gulp.task('chrome-specific_dir', function() {
	return gulp.src(['chrome-specific/**/*']).pipe(gulp.dest('./gem-unpacked/'));
});

gulp.task('compact', [
	'customcss',
	'vendorcss',
	'vendorjs',
	'moveCss',
	'moveFonts',
	'move_js_depends'
]);

gulp.task('watchfiles', function() {
	gulp.watch(files.css.sassFile, ['customcss']);
});

gulp.task('default', ['compact']);

gulp.task('watch', ['compact', 'watchfiles']);
<|endoftext|>


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

var browserSync = require('browser-sync');
var gulp = require('gulp');
var plugins = require('gulp-load-plugins')();
var mergeStream = require('merge-stream');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var watchify = require('watchify');
var browserify = require('browserify');
var uglifyify = require('uglifyify');
var to5ify = require("6to5ify");
var runSequence = require('run-sequence');  // Temporary solution until Gulp 4
                                            // https://github.com/gulpjs/gulp/issues/355

var reload = browserSync.reload;

// ---------------------------------------------------------------------
// | Helper tasks                                                      |
// ---------------------------------------------------------------------

gulp.task('clean', function (done) {
  require('del')(['build'], done);
});

var pageData;
gulp.task('get-page-data', function(done) {
  pageData = JSON.parse(fs.readFileSync("./src/config.json"));
  pageData.changelog = JSON.parse(fs.readFileSync("./src/changelog.json"));
  pageData.plugins.forEach(function(plugin) {
    plugin.active = require('svgo/plugins/' + plugin.id).active;
  });
  done();
});

gulp.task('copy', [
  'copy:css',
  'copy:html',
  'copy:js',
  'copy:misc'
]);

gulp.task('copy:css', function () {
  return gulp.src('src/css/*.scss')
    //.pipe(plugins.sourcemaps.init())
    .pipe(plugins.sass({ outputStyle: 'compressed' }))
    //.pipe(plugins.sourcemaps.write('./'))
    .pipe(gulp.dest('build/css'))
    .pipe(plugins.filter('**/*.css'))
    .pipe(reload({stream: true}));
});

gulp.task('copy:html', ['get-page-data', 'copy:css'], function () {
  return gulp.src([
    // Copy all `.html` files
    'src/*.html',
  ])
  .pipe(plugins.swig({
    defaults: { cache: false },
    data: pageData
  }))
  .pipe(plugins.htmlmin({
    // In-depth information about the options:
    // https://github.com/kangax/html-minifier#options-quick-reference
    collapseBooleanAttributes: true,
    collapseWhitespace: true,
    minifyJS: true,
    removeAttributeQuotes: true,
    removeComments: true,
    removeEmptyAttributes: true,
    removeOptionalTags: true,
    removeRedundantAttributes: true,
    // Prevent html-minifier from breaking the SVGs
    // https://github.com/kangax/html-minifier/issues/285
    keepClosingSlash: true,
    caseSensitive: true
  })).pipe(gulp.dest('build'))
    .pipe(reload({stream: true}));
});

gulp.task('copy:misc', function () {
  return gulp.src([
    // Copy all files
    'src/**',
    // Exclude the following files
    // (other tasks will handle the copying of these files)
    '!src/*.html',
    '!src/{css,css/**}',
    '!src/{js,js/**}'
  ]).pipe(gulp.dest('build'));
});

function createBundler(src) {
  var b;

  if (plugins.util.env.production) {
    b = browserify();
  }
  else {
    b = browserify({
      cache: {}, packageCache: {}, fullPaths: true,
      debug: true
    });
  }

  b.transform(to5ify.configure({
    experimental: true
  }));

  if (plugins.util.env.production) {
    b.transform({
      global: true
    }, 'uglifyify');
  }

  b.add(src);
  return b;
}

function bundle(bundler, outputPath) {
  var splitPath = outputPath.split('/');
  var outputFile = splitPath[splitPath.length - 1];
  var outputDir = splitPath.slice(0, -1).join('/');

  return bundler.bundle()
    // log errors if they happen
    .on('error', plugins.util.log.bind(plugins.util, 'Browserify Error'))
    .pipe(source(outputFile))
    .pipe(buffer())
    .pipe(plugins.sourcemaps.init({ loadMaps: true })) // loads map from browserify file
    .pipe(plugins.sourcemaps.write('./')) // writes .map file
    .pipe(plugins.size({ gzip: true, title: outputFile }))
    .pipe(gulp.dest('build/' + outputDir))
    .pipe(reload({ stream: true }));
}

var bundlers = {
  'js/page.js': createBundler('./src/js/page/index.js'),
  'js/svgo-worker.js': createBundler('./src/js/svgo-worker/index.js'),
  'js/gzip-worker.js': createBundler('./src/js/gzip-worker/index.js'),
  'js/prism-worker.js': createBundler('./src/js/prism-worker/index.js'),
  'js/promise-polyfill.js': createBundler('./src/js/promise-polyfill/index.js'),
  'js/fastclick.js': createBundler('./src/js/fastclick/index.js'),
  'sw.js': plugins.util.env['disable-sw'] ? createBundler('./src/js/sw-null/index.js') : createBundler('./src/js/sw/index.js')
};

gulp.task('copy:js', function () {
  return mergeStream.apply(null,
    Object.keys(bundlers).map(function(key) {
      return bundle(bundlers[key], key);
    })
  );
});

gulp.task('browser-sync', function() {
  browserSync({
    notify: false,
    port: 8000,
    server: "build",
    open: false
  });
});

gulp.task('watch', function () {
  gulp.watch(['src/**/*.scss'], ['copy:css']);
  gulp.watch(['src/*.html', 'src/plugin-data.json', 'src/changelog.json'], ['copy:misc', 'copy:html']);

  Object.keys(bundlers).forEach(function(key) {
    var watchifyBundler = watchify(bundlers[key]);
    watchifyBundler.on('update', function() {
      return bundle(watchifyBundler, key);
    });
    bundle(watchifyBundler, key);
  });
});

// ---------------------------------------------------------------------
// | Main tasks                                                        |
// ---------------------------------------------------------------------

gulp.task('build', function (done) {
  runSequence('clean', 'copy', done);
});

gulp.task('default', ['build']);

gulp.task('serve', function (done) {
  runSequence( 'build', ['browser-sync', 'watch'], done);
});
<commit_msg>Disabling removeHiddenElems<commit_after>var fs = require('fs');

var browserSync = require('browser-sync');
var gulp = require('gulp');
var plugins = require('gulp-load-plugins')();
var mergeStream = require('merge-stream');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var watchify = require('watchify');
var browserify = require('browserify');
var uglifyify = require('uglifyify');
var to5ify = require("6to5ify");
var runSequence = require('run-sequence');  // Temporary solution until Gulp 4
                                            // https://github.com/gulpjs/gulp/issues/355

var reload = browserSync.reload;

// ---------------------------------------------------------------------
// | Helper tasks                                                      |
// ---------------------------------------------------------------------

gulp.task('clean', function (done) {
  require('del')(['build'], done);
});

var pageData;
gulp.task('get-page-data', function(done) {
  pageData = JSON.parse(fs.readFileSync("./src/config.json"));
  pageData.changelog = JSON.parse(fs.readFileSync("./src/changelog.json"));
  pageData.plugins.forEach(function(plugin) {
    if (plugin.id === 'removeHiddenElems') {
      // TODO: remove this when fixed
      // This breaks the demo image in 0.5.1
      plugin.active = false;
    }
    else {
      plugin.active = require('svgo/plugins/' + plugin.id).active;
    }
  });
  done();
});

gulp.task('copy', [
  'copy:css',
  'copy:html',
  'copy:js',
  'copy:misc'
]);

gulp.task('copy:css', function () {
  return gulp.src('src/css/*.scss')
    //.pipe(plugins.sourcemaps.init())
    .pipe(plugins.sass({ outputStyle: 'compressed' }))
    //.pipe(plugins.sourcemaps.write('./'))
    .pipe(gulp.dest('build/css'))
    .pipe(plugins.filter('**/*.css'))
    .pipe(reload({stream: true}));
});

gulp.task('copy:html', ['get-page-data', 'copy:css'], function () {
  return gulp.src([
    // Copy all `.html` files
    'src/*.html',
  ])
  .pipe(plugins.swig({
    defaults: { cache: false },
    data: pageData
  }))
  .pipe(plugins.htmlmin({
    // In-depth information about the options:
    // https://github.com/kangax/html-minifier#options-quick-reference
    collapseBooleanAttributes: true,
    collapseWhitespace: true,
    minifyJS: true,
    removeAttributeQuotes: true,
    removeComments: true,
    removeEmptyAttributes: true,
    removeOptionalTags: true,
    removeRedundantAttributes: true,
    // Prevent html-minifier from breaking the SVGs
    // https://github.com/kangax/html-minifier/issues/285
    keepClosingSlash: true,
    caseSensitive: true
  })).pipe(gulp.dest('build'))
    .pipe(reload({stream: true}));
});

gulp.task('copy:misc', function () {
  return gulp.src([
    // Copy all files
    'src/**',
    // Exclude the following files
    // (other tasks will handle the copying of these files)
    '!src/*.html',
    '!src/{css,css/**}',
    '!src/{js,js/**}'
  ]).pipe(gulp.dest('build'));
});

function createBundler(src) {
  var b;

  if (plugins.util.env.production) {
    b = browserify();
  }
  else {
    b = browserify({
      cache: {}, packageCache: {}, fullPaths: true,
      debug: true
    });
  }

  b.transform(to5ify.configure({
    experimental: true
  }));

  if (plugins.util.env.production) {
    b.transform({
      global: true
    }, 'uglifyify');
  }

  b.add(src);
  return b;
}

function bundle(bundler, outputPath) {
  var splitPath = outputPath.split('/');
  var outputFile = splitPath[splitPath.length - 1];
  var outputDir = splitPath.slice(0, -1).join('/');

  return bundler.bundle()
    // log errors if they happen
    .on('error', plugins.util.log.bind(plugins.util, 'Browserify Error'))
    .pipe(source(outputFile))
    .pipe(buffer())
    .pipe(plugins.sourcemaps.init({ loadMaps: true })) // loads map from browserify file
    .pipe(plugins.sourcemaps.write('./')) // writes .map file
    .pipe(plugins.size({ gzip: true, title: outputFile }))
    .pipe(gulp.dest('build/' + outputDir))
    .pipe(reload({ stream: true }));
}

var bundlers = {
  'js/page.js': createBundler('./src/js/page/index.js'),
  'js/svgo-worker.js': createBundler('./src/js/svgo-worker/index.js'),
  'js/gzip-worker.js': createBundler('./src/js/gzip-worker/index.js'),
  'js/prism-worker.js': createBundler('./src/js/prism-worker/index.js'),
  'js/promise-polyfill.js': createBundler('./src/js/promise-polyfill/index.js'),
  'js/fastclick.js': createBundler('./src/js/fastclick/index.js'),
  'sw.js': plugins.util.env['disable-sw'] ? createBundler('./src/js/sw-null/index.js') : createBundler('./src/js/sw/index.js')
};

gulp.task('copy:js', function () {
  return mergeStream.apply(null,
    Object.keys(bundlers).map(function(key) {
      return bundle(bundlers[key], key);
    })
  );
});

gulp.task('browser-sync', function() {
  browserSync({
    notify: false,
    port: 8000,
    server: "build",
    open: false
  });
});

gulp.task('watch', function () {
  gulp.watch(['src/**/*.scss'], ['copy:css']);
  gulp.watch(['src/*.html', 'src/plugin-data.json', 'src/changelog.json'], ['copy:misc', 'copy:html']);

  Object.keys(bundlers).forEach(function(key) {
    var watchifyBundler = watchify(bundlers[key]);
    watchifyBundler.on('update', function() {
      return bundle(watchifyBundler, key);
    });
    bundle(watchifyBundler, key);
  });
});

// ---------------------------------------------------------------------
// | Main tasks                                                        |
// ---------------------------------------------------------------------

gulp.task('build', function (done) {
  runSequence('clean', 'copy', done);
});

gulp.task('default', ['build']);

gulp.task('serve', function (done) {
  runSequence( 'build', ['browser-sync', 'watch'], done);
});
<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');
var babel = require('gulp-babel');
var plumber = require('gulp-plumber');
var sass = require('gulp-sass');
var typescript = require('gulp-typescript');
var watch = require('gulp-watch');

var del = require('del');
var runSequence = require('run-sequence');
var electron = require('electron-connect').server.create();

var tsProject = typescript.createProject('./src/tsconfig.json');
var tsTestProject = typescript.createProject('./test/tsconfig.json');

var appDir = './app';
var distDir = './dist';
var srcDir = './src';
var testDir = './test';

var tsFiles = srcDir + '/**/*.{ts,tsx}';
var ssFiles = srcDir + '/**/*.{sass,scss}';
var rsFiles = srcDir + '/**/*.{png,otf,html,css,json}';
var tsTestFiles = testDir + '/**/*.ts';

// Clean project
gulp.task('clean', function() {
  del(['app', 'dist', 'coverage', 'test/**/*.js']);
});

// Copy to app
gulp.task('copy', function() {
  gulp.src(rsFiles, {base: 'src'})
    .pipe(gulp.dest(appDir));
});

// TypeScript -> ES6 -> ES5
gulp.task('ts:compile', function() {
  return gulp.src(tsFiles)
    .pipe(plumber())
    .pipe(typescript(tsProject))
    .pipe(babel())
    .pipe(gulp.dest(appDir));
});

gulp.task('ts:testCompile', ['clean', 'ts:compile'], function() {
  gulp.src(tsTestFiles)
    .pipe(plumber())
    .pipe(typescript(tsTestProject))
    .pipe(babel())
    .pipe(gulp.dest(testDir));
});

// SASS -> CSS
gulp.task('sass:compile', function() {
  gulp.src(ssFiles)
    .pipe(plumber())
    .pipe(sass())
    .pipe(gulp.dest(appDir));
});

// Auto compile
gulp.task('watch', function() {
  // *.ts, *.tsx(TypeScript React) -> compile
  watch(tsFiles, function() {
    gulp.run('ts:compile');
  });

  // *.sass, *.scss -> compile
  watch(ssFiles, function() {
    gulp.run('sass:compile');
  });

  // *.html, *.css -> copy
  watch(rsFiles, function() {
    gulp.start(['copy']);
  });
});

// Build
gulp.task('build', function(callback) {
  return runSequence(
    'clean',
    'ts:compile',
    'sass:compile',
    'copy',
    callback
  );
});

gulp.task('serve', function () {
  // http://qiita.com/Quramy/items/90d61ff37ca1b95a7f6d#livereload
  electron.start();

  // BrowserProcess(MainProcess)が読み込むリソースが変更されたら, Electron自体を再起動
  watch(['./app/main.js', './app/browser/*.js'], function() {
    // 再起動せずに増える
    // electron.restart();
  });

  // RendererProcessが読み込むリソースが変更されたら, RendererProcessにreloadさせる
  watch(['./app/renderer/**/*.css', './app/renderer/**/*.js', './app/**/*.html', './app/**/*.png', './app/**/*.otf', './app/**/*.json'], electron.reload);
});

gulp.task('default', function(callback) {
  return runSequence(
    'clean',
    'ts:compile',
    'sass:compile',
    'copy',
    'watch',
    'serve',
    callback
  );
});<commit_msg>Fix gulpfile. When file saved, more than once reload electron on Windows.<commit_after>'use strict';

var gulp = require('gulp');
var babel = require('gulp-babel');
var plumber = require('gulp-plumber');
var sass = require('gulp-sass');
var typescript = require('gulp-typescript');
var watch = require('gulp-watch');

var del = require('del');
var runSequence = require('run-sequence');
var electron = require('electron-connect').server.create();

var tsProject = typescript.createProject('./src/tsconfig.json');
var tsTestProject = typescript.createProject('./test/tsconfig.json');

var appDir = './app';
var distDir = './dist';
var srcDir = './src';
var testDir = './test';

var tsFiles = srcDir + '/**/*.{ts,tsx}';
var ssFiles = srcDir + '/**/*.{sass,scss}';
var rsFiles = srcDir + '/**/*.{png,otf,html,css,json}';
var cpFiles = appDir + '/renderer/**/*.{js,css}';
var crFiles = appDir + '/**/*.{png,otf,html,json}';
var tsTestFiles = testDir + '/**/*.ts';

var served = false;

// Clean project
gulp.task('clean', function() {
  del(['app', 'dist', 'coverage', 'test/**/*.js']);
});

// Copy to app
gulp.task('copy', function() {
  gulp.src(rsFiles, {base: 'src'})
    .pipe(gulp.dest(appDir));
});

// TypeScript -> ES6 -> ES5
gulp.task('ts:compile', function() {
  return gulp.src(tsFiles)
    .pipe(plumber())
    .pipe(typescript(tsProject))
    .pipe(babel())
    .pipe(gulp.dest(appDir));
});

gulp.task('ts:testCompile', ['clean', 'ts:compile'], function() {
  gulp.src(tsTestFiles)
    .pipe(plumber())
    .pipe(typescript(tsTestProject))
    .pipe(babel())
    .pipe(gulp.dest(testDir));
});

// SASS -> CSS
gulp.task('sass:compile', function() {
  gulp.src(ssFiles)
    .pipe(plumber())
    .pipe(sass())
    .pipe(gulp.dest(appDir));
});

// Auto compile
gulp.task('watch', function() {
  // *.ts, *.tsx(TypeScript React) -> compile
  watch(tsFiles, function() {
    return runSequence(
      'ts:compile',
      'serve:reload'
    );
  });

  // *.sass, *.scss -> compile
  watch(ssFiles, function() {
    return runSequence(
      'sass:compile',
      'serve:reload'
    );
  });

  // *.html, *.css -> copy
  watch(rsFiles, function() {
    gulp.start(['copy']);
  });
});

// Build
gulp.task('build', function(callback) {
  return runSequence(
    'clean',
    'ts:compile',
    'sass:compile',
    'copy',
    callback
  );
});

gulp.task('serve', function () {
  // http://qiita.com/Quramy/items/90d61ff37ca1b95a7f6d#livereload
  electron.start();
  served = true;
});

gulp.task('serve:reload', function() {
  if(served) {
    electron.reload();
  }
});

gulp.task('default', function(callback) {
  return runSequence(
    'clean',
    'ts:compile',
    'sass:compile',
    'copy',
    'watch',
    'serve',
    callback
  );
});<|endoftext|>


<commit_before>var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require('vinyl-source-stream');

gulp.task('build', function() {
    return browserify({
        entries: './src/components/app.jsx',
        transform: [[babelify, {presets: ['es2015', 'react']}]],
        extensions: ['.jsx'],
        debug: true
    })
    // .transform('babelify', {presets: ['es2015', 'react']})
    .bundle()
    .pipe(source('bundle.js'))
    .pipe(gulp.dest('./src/dist'));
});

gulp.task('watch', ['build'], function() {
    gulp.watch('*.jsx', ['build']);
});

gulp.task('default', ['watch']);
<commit_msg>Moved gulpfile to the server<commit_after><|endoftext|>


<commit_before>var gulp = require('gulp');
var browserSync = require('browser-sync').create();
var sass = require('gulp-sass');
var rsync = require('rsync-slim');
var concat = require('gulp-concat');
var imagemin = require('gulp-imagemin');
var uglify = require('gulp-uglify');
var critical = require('critical');
var postcss = require('gulp-postcss');
var htmlmin = require('gulp-htmlmin');

var env_prod = true;
var src = 'src';
var dist = 'dist';
var bower = 'bower_components';
var distAssets = dist + '/assets';

var srcSass = src + '/assets/sass';
var srcSassFile = src + '/assets/sass/main.sass';
var distCss = dist + '/assets/css';

var srcJs = src + '/assets/js';
var srcJsFiles = [
  "bower_components/scrollmagic/scrollmagic/minified/ScrollMagic.min.js",
  srcJs + '/ui-scroll.js',
  srcJs + '/ui-core.js',
];
var distJs = dist + '/assets/js';
var distJsFile = 'ui-core.min.js';

var srcImgs = src + '/assets/img';

gulp.task('sass', function() {
  return gulp.src(srcSassFile)
    .pipe(sass({
        includePaths: ['bower_components']
      })
      .on('error', sass.logError))
    .pipe(gulp.dest(distCss))
    .pipe(browserSync.stream());
});

gulp.task('css', ['sass'], function() {
  if (!env_prod) {
    return;
  } else {
    var autoprefixer = require('autoprefixer');
    var cssnano = require('cssnano');
    var mqpacker = require('css-mqpacker');

    return gulp.src(distCss + '/*.css')
      .pipe(postcss([
        mqpacker({
          sort: true
        }),
        autoprefixer(),
        cssnano()
      ]))
      .pipe(gulp.dest(distCss));
  }
});

gulp.task('css:watch', function() {
  gulp.watch(srcSass + '**/*.sass', ['css']);
});

gulp.task('js', function(cb) {
  if (env_prod) {
    return gulp.src(srcJsFiles)
      .pipe(concat(distJsFile))
      .pipe(uglify({
        mangle: true,
        compress: {
          sequences: true,
          dead_code: true,
          conditionals: true,
          booleans: true,
          unused: true,
          if_return: true,
          join_vars: true,
        }
      }))
      .pipe(gulp.dest(distJs));
  } else {
    return gulp.src(srcJsFiles)
      .pipe(concat(distJsFile))
      .pipe(gulp.dest(distJs));
  }
});

gulp.task('js:watch', function() {
  gulp.watch(srcJs + '**/*.js', ['js']);
});

gulp.task('browser-sync', function() {
  browserSync.init({
    ghostMode: false,
    online: false,
    notify: false,
    server: {
      baseDir: dist
    }
  });
  gulp.watch([
      dist + '**/*.html',
      distJs + '**/*.js'
    ])
    .on('change', browserSync.reload);
});

gulp.task('jekyll', function(gulpCallBack) {
  var spawn = require('child_process').spawn;
  var jekyll = spawn('jekyll', ['build'], {
    stdio: 'inherit'
  });

  jekyll.on('exit', function(code) {
    gulpCallBack(code === 0 ? null : 'ERROR: Jekyll process exited with code: ' + code);
  });
});

gulp.task('html:watch', function() {
  gulp.watch([
    src + '/**/*.md',
    src + '/**/*.html'
  ], ['html']);
});

gulp.task('html', ['jekyll'], function() {
  if (!env_prod) {
    return;
  } else {
    return gulp.src(dist + '/**/*.html')
      .pipe(htmlmin({
        collapseWhitespace: true,
        preserveLineBreaks: true,
        removeComments: false,
        minifyCSS: true,
        minifyJS: true
      }))
      .pipe(gulp.dest(dist));
  }
});

gulp.task('images', function() {
  return gulp.src(srcImgs + '/**/*')
    .pipe(imagemin({
      progressive: true
    }))
    .pipe(gulp.dest(distAssets + '/img'));
});

gulp.task('deploy', function() {
  rsync({
    src: 'dist/',
    dest: 'stgsear1@akascia.com:~/www/stickypixel/',
    // options: '--archive --delete --progress --compress --human-readable --exclude .DS_Store --dry-run'
    options: '--archive --delete --progress --compress --human-readable --exclude .DS_Store'
  });
});

gulp.task('default', function() {
  console.log('No task defined as default');
});

gulp.task('env_dev', function() {
  env_prod = false;
});

gulp.task('env_prod', function() {
  env_prod = true;
});

gulp.task('critical', ['build'], function(cb) {
  critical.generate({
    inline: true,
    base: dist + '/',
    src: 'index.html',
    dest: dist + '/index.html',
    minify: true,
    width: 1440,
    height: 900
  });
});

gulp.task('build', ['html', 'html:watch', 'css', 'css:watch', 'js', 'js:watch', 'browser-sync']);
gulp.task('dev', ['env_dev', 'build']);
gulp.task('prod', ['env_prod', 'critical']);
<commit_msg>Update<commit_after>var gulp = require('gulp');
var browserSync = require('browser-sync').create();
var sass = require('gulp-sass');
var rsync = require('rsync-slim');
var concat = require('gulp-concat');
var imagemin = require('gulp-imagemin');
var uglify = require('gulp-uglify');
var critical = require('critical');
var postcss = require('gulp-postcss');
var htmlmin = require('gulp-htmlmin');

var env_prod = true;
var src = 'src';
var dist = 'dist';
var distAssets = dist + '/assets';

var srcSass = src + '/assets/sass';
var srcSassFile = src + '/assets/sass/main.sass';
var distCss = dist + '/assets/css';

var srcJs = src + '/assets/js';
var srcJsFiles = [
  'bower_components/scrollmagic/scrollmagic/minified/ScrollMagic.min.js',
  srcJs + '/ui-scroll.js',
  srcJs + '/ui-core.js'
];
var distJs = dist + '/assets/js';
var distJsFile = 'ui-core.min.js';

var srcImgs = src + '/assets/img';

gulp.task('sass', function() {
  return gulp.src(srcSassFile)
    .pipe(sass({
        includePaths: ['bower_components']
      })
      .on('error', sass.logError))
    .pipe(gulp.dest(distCss))
    .pipe(browserSync.stream());
});

gulp.task('css', ['sass'], function() {
  var autoprefixer, cssnano, mqpacker;
  if (!env_prod) {
    return;
  } else {
    autoprefixer = require('autoprefixer');
    cssnano = require('cssnano');
    mqpacker = require('css-mqpacker');

    return gulp.src(distCss + '/*.css')
      .pipe(postcss([
        mqpacker({
          sort: true
        }),
        autoprefixer(),
        cssnano()
      ]))
      .pipe(gulp.dest(distCss));
  }
});

gulp.task('css:watch', function() {
  gulp.watch(srcSass + '**/*.sass', ['css']);
});

gulp.task('js', function(cb) {
  if (env_prod) {
    return gulp.src(srcJsFiles)
      .pipe(concat(distJsFile))
      .pipe(uglify({
        mangle: true,
        compress: {
          sequences: true,
          dead_code: true,
          conditionals: true,
          booleans: true,
          unused: true,
          if_return: true,
          join_vars: true
        }
      }))
      .pipe(gulp.dest(distJs));
  } else {
    return gulp.src(srcJsFiles)
      .pipe(concat(distJsFile))
      .pipe(gulp.dest(distJs));
  }
});

gulp.task('js:watch', function() {
  gulp.watch(srcJs + '**/*.js', ['js']);
});

gulp.task('browser-sync', function() {
  browserSync.init({
    ghostMode: false,
    online: false,
    notify: false,
    server: {
      baseDir: dist
    }
  });
  gulp.watch([
      dist + '**/*.html',
      distJs + '**/*.js'
    ])
    .on('change', browserSync.reload);
});

gulp.task('jekyll', function(gulpCallBack) {
  var spawn = require('child_process').spawn;
  var jekyll = spawn('jekyll', ['build'], {
    stdio: 'inherit'
  });

  jekyll.on('exit', function(code) {
    gulpCallBack(code === 0 ? null : 'ERROR: Jekyll process exited with code: ' + code);
  });
});

gulp.task('html:watch', function() {
  gulp.watch([
    src + '/**/*.md',
    src + '/**/*.html'
  ], ['html']);
});

gulp.task('html', ['jekyll'], function() {
  if (!env_prod) {
    return;
  } else {
    return gulp.src(dist + '/**/*.html')
      .pipe(htmlmin({
        collapseWhitespace: true,
        preserveLineBreaks: true,
        removeComments: false,
        minifyCSS: true,
        minifyJS: true
      }))
      .pipe(gulp.dest(dist));
  }
});

gulp.task('images', function() {
  return gulp.src(srcImgs + '/**/*')
    .pipe(imagemin({
      progressive: true
    }))
    .pipe(gulp.dest(distAssets + '/img'));
});

gulp.task('deploy', function() {
  rsync({
    src: 'dist/',
    dest: 'stgsear1@akascia.com:~/www/stickypixel/',
    // options: '--archive --delete --progress --compress --human-readable --exclude .DS_Store --dry-run'
    options: '--archive --delete --progress --compress --human-readable --exclude .DS_Store'
  });
});

gulp.task('default', function() {
  console.log('No task defined as default');
});

gulp.task('env_dev', function() {
  env_prod = false;
});

gulp.task('env_prod', function() {
  env_prod = true;
});

gulp.task('critical', ['build'], function(cb) {
  critical.generate({
    inline: true,
    base: dist + '/',
    src: 'index.html',
    dest: dist + '/index.html',
    minify: true,
    width: 1440,
    height: 900
  });
});

gulp.task('build', ['html', 'html:watch', 'css', 'css:watch', 'js', 'js:watch', 'browser-sync']);
gulp.task('dev', ['env_dev', 'build']);
gulp.task('prod', ['env_prod', 'critical']);
<|endoftext|>


<commit_before>// dna.js
// gulp configuration and tasks

// Imports
const babel =         require('gulp-babel');
const del =           require('del');
const fileInclude =   require('gulp-file-include');
const gap =           require('gulp-append-prepend');
const gulp =          require('gulp');
const header =        require('gulp-header');
const htmlHint =      require('gulp-htmlhint');
const htmlValidator = require('gulp-w3c-html-validator');
const mergeStream =   require('merge-stream');
const rename =        require('gulp-rename');
const replace =       require('gulp-replace');
const size =          require('gulp-size');

// Setup
const pkg = require('./package.json');
const released = process.env.dnaReleasedVersion;
const minorVersion = pkg.version.split('.').slice(0,2).join('.');
const linkInfo = {
   youTube: {
      intro:    'jMOZOI-UkNI',
      tutorial: 'juIru5qHZFM'
      },
   jsFiddle: {
      addABook:       'Lspfc8t5',
      bookFinder:     'zxb2x6dv',
      dataClick:      '5dsbvacd',
      liveModel:      'y24pshbn',
      panelsClick:    'uzm44vrf',
      panelsDropDown: 'qt95wt46',
      photoUpload:    'ac0d784e/3',
      smartUpdates:   '4a0tpmxp',
      toDo:           'wo6og0z8'
      }
   };
const webContext = {
   pkg:          pkg,
   released:     released,
   minorVersion: minorVersion,
   gzipSize:     '7 kb gzip',
   title:        pkg.description,  //default page title
   youTube:      linkInfo.youTube,
   jsFiddle:     linkInfo.jsFiddle
   };
const banner =              'dna.js v' + pkg.version + ' ~~ dnajs.org ~~ MIT License';
const websiteTargetFolder = 'website-target';
const htmlHintConfig =      { 'attr-value-double-quotes': false };
const headerComments =      { css: /^[/][*].*[*][/]$/gm, js: /^[/][/].*\n/gm };
const transpileES6 =        ['@babel/env', { modules: false }];
const babelMinifyJs =       { presets: [transpileES6, 'minify'], comments: false };
const newLine =             '\n';

// Tasks
const task = {
   buildDistribution: () => {
      const buildCss = () =>
         gulp.src('dna.css')
            .pipe(replace(headerComments.css, ''))
            .pipe(header('/*! ' + banner + ' */'))
            .pipe(size({ showFiles: true }))
            .pipe(gulp.dest('dist'));
      const buildJs = () =>
         gulp.src('dna.js')
            .pipe(replace(headerComments.js, ''))
            .pipe(header('//! ' + banner + newLine))
            .pipe(replace('[VERSION]', pkg.version))
            .pipe(size({ showFiles: true }))
            .pipe(gulp.dest('dist'))
            .pipe(babel(babelMinifyJs))
            .pipe(rename({ extname: '.min.js' }))
            .pipe(header('//! ' + banner + newLine))
            .pipe(gap.appendText(newLine))
            .pipe(size({ showFiles: true }))
            .pipe(gulp.dest('dist'));
      return mergeStream(buildCss(), buildJs());
      },
   reportSize: () => {
      return gulp.src('dist/dna.*')
         .pipe(size({ showFiles: true, gzip: true }));
      },
   cleanWebsite: () => {
      return del(websiteTargetFolder);
      },
   buildWebsite: () => {
      return mergeStream(
         gulp.src(['website/static/**', '!website/static/**/*.html'])
            .pipe(gulp.dest(websiteTargetFolder)),
         gulp.src(['website/static/**/*.html', 'website/root/**/*.html'])
            .pipe(fileInclude({ basepath: '@root', indent: true, context: webContext }))
            .pipe(htmlHint(htmlHintConfig))
            .pipe(htmlHint.reporter())
            .pipe(htmlValidator())
            .pipe(htmlValidator.reporter())
            .pipe(gulp.dest(websiteTargetFolder))
            .pipe(size({ showFiles: true }))
         );
      },
   otherStuff: () => {
      const findToDoLine =  /.*To-Do Application.*/;
      const findIntroLine = /.*Introduction to dna.js.*/;
      const newToDoLine =
         '* [Sample To-Do Application](https://jsfiddle.net/' + linkInfo.jsFiddle.toDo + '/) (jsfiddle)';
      const newIntroLine =
         '* [Introduction to dna.js](https://youtu.be/' + linkInfo.youTube.intro + ') (YouTube)';
      return mergeStream(
         gulp.src('README.md')
            .pipe(replace(findToDoLine,  newToDoLine))
            .pipe(replace(findIntroLine, newIntroLine))
            .pipe(size({ showFiles: true }))
            .pipe(gulp.dest('.')),
         gulp.src(['spec/visual.html', 'spec/simple.html'])
            .pipe(htmlHint(htmlHintConfig))
            .pipe(htmlHint.reporter())
            .pipe(htmlValidator())
            .pipe(htmlValidator.reporter())
            .pipe(size({ showFiles: true }))
         );
      }
   };

// Gulp
gulp.task('build-dist',  task.buildDistribution);
gulp.task('report-size', task.reportSize);
gulp.task('clean-web',   task.cleanWebsite);
gulp.task('build-web',   task.buildWebsite);
gulp.task('other-stuff', task.otherStuff);
<commit_msg>Named functions for merging tasks<commit_after>// dna.js ~~ MIT License
// Gulp configuration and tasks

// Imports
const babel =         require('gulp-babel');
const del =           require('del');
const fileInclude =   require('gulp-file-include');
const gap =           require('gulp-append-prepend');
const gulp =          require('gulp');
const header =        require('gulp-header');
const htmlHint =      require('gulp-htmlhint');
const htmlValidator = require('gulp-w3c-html-validator');
const mergeStream =   require('merge-stream');
const rename =        require('gulp-rename');
const replace =       require('gulp-replace');
const size =          require('gulp-size');

// Link information
const linkInfo = {
   youTube: {
      intro:    'jMOZOI-UkNI',
      tutorial: 'juIru5qHZFM'
      },
   jsFiddle: {
      addABook:       'Lspfc8t5',
      bookFinder:     'zxb2x6dv',
      dataClick:      '5dsbvacd',
      liveModel:      'y24pshbn',
      panelsClick:    'uzm44vrf',
      panelsDropDown: 'qt95wt46',
      photoUpload:    'ac0d784e/3',
      smartUpdates:   '4a0tpmxp',
      toDo:           'wo6og0z8'
      }
   };

// Setup
const pkg =            require('./package.json');
const released =       process.env.dnaReleasedVersion;
const minorVersion =   pkg.version.split('.').slice(0,2).join('.');
const banner =         'dna.js v' + pkg.version + ' ~~ dnajs.org ~~ MIT License';
const websiteTarget =  'website-target';
const htmlHintConfig = { 'attr-value-double-quotes': false };
const headerComments = { css: /^[/][*].*[*][/]$/gm, js: /^[/][/].*\n/gm };
const transpileES6 =   ['@babel/env', { modules: false }];
const babelMinifyJs =  { presets: [transpileES6, 'minify'], comments: false };
const newLine =        '\n';
const webContext = {
   pkg:          pkg,
   released:     released,
   minorVersion: minorVersion,
   gzipSize:     '7 kb gzip',
   title:        pkg.description,  //default page title
   youTube:      linkInfo.youTube,
   jsFiddle:     linkInfo.jsFiddle
   };

// Tasks
const task = {
   buildDistribution: () => {
      const buildCss = () =>
         gulp.src('dna.css')
            .pipe(replace(headerComments.css, ''))
            .pipe(header('/*! ' + banner + ' */'))
            .pipe(size({ showFiles: true }))
            .pipe(gulp.dest('dist'));
      const buildJs = () =>
         gulp.src('dna.js')
            .pipe(replace(headerComments.js, ''))
            .pipe(header('//! ' + banner + newLine))
            .pipe(replace('[VERSION]', pkg.version))
            .pipe(size({ showFiles: true }))
            .pipe(gulp.dest('dist'))
            .pipe(babel(babelMinifyJs))
            .pipe(rename({ extname: '.min.js' }))
            .pipe(header('//! ' + banner + newLine))
            .pipe(gap.appendText(newLine))
            .pipe(size({ showFiles: true }))
            .pipe(gulp.dest('dist'));
      return mergeStream(buildCss(), buildJs());
      },
   reportSize: () => {
      return gulp.src('dist/dna.*')
         .pipe(size({ showFiles: true, gzip: true }));
      },
   cleanWebsite: () => {
      return del(websiteTarget);
      },
   buildWebsite: () => {
      const copyStaticFiles = () =>
         gulp.src(['website/static/**', '!website/static/**/*.html'])
            .pipe(gulp.dest(websiteTarget));
      const buildHtml = () =>
         gulp.src(['website/static/**/*.html', 'website/root/**/*.html'])
            .pipe(fileInclude({ basepath: '@root', indent: true, context: webContext }))
            .pipe(htmlHint(htmlHintConfig))
            .pipe(htmlHint.reporter())
            .pipe(htmlValidator())
            .pipe(htmlValidator.reporter())
            .pipe(gulp.dest(websiteTarget))
            .pipe(size({ showFiles: true }));
      return mergeStream(copyStaticFiles(), buildHtml());
      },
   otherStuff: () => {
      const line = {
         findToDo:  /.*To-Do Application.*/,
         findIntro: /.*Introduction to dna.js.*/,
         newToDo:   '* [Sample To-Do Application](https://jsfiddle.net/' + linkInfo.jsFiddle.toDo + '/) (jsfiddle)',
         newIntro:  '* [Introduction to dna.js](https://youtu.be/' + linkInfo.youTube.intro + ') (YouTube)'
         };
      const updateReadMe = () =>
         gulp.src('README.md')
            .pipe(replace(line.findToDo,  line.newToDo))
            .pipe(replace(line.findIntro, line.newIntro))
            .pipe(size({ showFiles: true }))
            .pipe(gulp.dest('.'));
      const validateHtml = () =>
         gulp.src(['spec/visual.html', 'spec/simple.html'])
            .pipe(htmlHint(htmlHintConfig))
            .pipe(htmlHint.reporter())
            .pipe(htmlValidator())
            .pipe(htmlValidator.reporter())
            .pipe(size({ showFiles: true }));
      return mergeStream(updateReadMe(), validateHtml());
      }
   };

// Gulp
gulp.task('build-dist',  task.buildDistribution);
gulp.task('report-size', task.reportSize);
gulp.task('clean-web',   task.cleanWebsite);
gulp.task('build-web',   task.buildWebsite);
gulp.task('other-stuff', task.otherStuff);
<|endoftext|>