<commit_before>/**
 * Build scripts
 *
 * Copyright (c) 2017-2022 Alex Grant (@localnerve), LocalNerve LLC
 * Copyrights licensed under the BSD License. See the accompanying LICENSE file for terms.
 */
/* eslint-disable import/no-unresolved, no-console */

const fs = require('fs');
const path = require('path');
const util = require('util');
const { spawn } = require('child_process');
const gulp = require('gulp');
const webpack = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');
const { getSourceDirs, srcRoot } = require('./src/utils/dirs');

const jsBundle = 'bundle.js';

/**
 * Returns an array of webpack config objects that assume these constraints:
 * 1. Produces one .js only bundle named `jsBundle`.
 * 2. Entry point is index.js
 *
 * @param {String} env - The target env, 'production' for production.
 * @param {Array} dirs - toplevel directories under srcRoot.
 * @returns {Array} Webpack config objects.
 */
function getWebpackConfig (env, dirs) {
  const prod = env === 'production';
  const definitions = {
    DEBUG: !prod,
    'process.env': {
      NODE_ENV: JSON.stringify(env)
    }
  };
  const plugins = [
    new webpack.DefinePlugin(definitions)
  ];
  const optimization = {};

  if (prod) {
    optimization.minimizer = [
      new TerserPlugin({
        terserOptions: {
          compress: {
            warnings: false
          },
          output: {
            comments: false
          }
        }
      })
    ];
  }

  return dirs.map(dir => ({
    mode: prod ? 'production' : 'development',
    entry: `${path.join(dir, 'index.js')}`,
    output: {
      path: path.resolve(dir),
      filename: `${jsBundle}`
    },
    module: {
      rules: [{
        test: /\.js$/,
        exclude: /^\/node_modules/,
        loader: 'babel-loader'
      }]
    },
    plugins,
    optimization
  }));
}

/**
 * Creates js bundles for all top level directories under `srcRoot`.
 *
 * @param {String} env - "production" for production.
 * @returns {Promise} Resolves to undefined on completion.
 */
function createBundle (env) {
  return getSourceDirs()
    .then(getWebpackConfig.bind(null, env))
    .then(webpackConfigs => util.promisify(webpack)(webpackConfigs))
    .then(stats => {
      if (stats.hasErrors()) {
        throw stats.toJson().errors;
      }
    });
}

/**
 * Run `npm install` for any src directory that needs it.
 *
 * @returns {Promise} That resolves if all npm installs succeed, rejects otherwise.
 */
function runPackageInstalls () {
  return getSourceDirs()
    .then(dirs => {
      const pkgDirs = dirs.filter(dir => {
        let exists = false;
        try {
          exists = fs.accessSync(path.join(dir, 'package.json'));
        } catch (e) {
          exists = false;
        }
        return exists;
      });

      return Promise.all(pkgDirs.map(pkgDir => {
        const cp = spawn('npm', ['install'], {
          cwd: pkgDir
        });
        return new Promise((resolve, reject) => {
          cp.on('close', code => {
            if (code !== 0) {
              return reject();
            }
            return resolve();
          });
          cp.on('error', reject);
        });
      }));
    });
}

// Define the build tasks:

gulp.task(
  'copy', () => gulp.src([
    `${srcRoot}/**/*.html`,
    `${srcRoot}/**/*.css`,
    `${srcRoot}/**/*.jpg`,
    `${srcRoot}/**/${jsBundle}`,
    `${srcRoot}/**/*worker.js`,
    `${srcRoot}/**/node_modules/**`,
    `!${srcRoot}/horizontal-pager/node_modules`,
    `!${srcRoot}/horizontal-pager/node_modules/**`,
    `!${srcRoot}/**/test`,
    `!${srcRoot}/**/test/**`,
  ]).pipe(gulp.dest('dist'))
);

gulp.task('webpack', () => createBundle('production'));
gulp.task('webpack-dev', () => createBundle('development'));
gulp.task('installs', runPackageInstalls);
<commit_msg>fix packageInstalls<commit_after>/**
 * Build scripts
 *
 * Copyright (c) 2017-2022 Alex Grant (@localnerve), LocalNerve LLC
 * Copyrights licensed under the BSD License. See the accompanying LICENSE file for terms.
 */
/* eslint-disable import/no-unresolved, no-console */

const fs = require('fs');
const path = require('path');
const util = require('util');
const { spawn } = require('child_process');
const gulp = require('gulp');
const webpack = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');
const { getSourceDirs, srcRoot } = require('./src/utils/dirs');

const jsBundle = 'bundle.js';

/**
 * Returns an array of webpack config objects that assume these constraints:
 * 1. Produces one .js only bundle named `jsBundle`.
 * 2. Entry point is index.js
 *
 * @param {String} env - The target env, 'production' for production.
 * @param {Array} dirs - toplevel directories under srcRoot.
 * @returns {Array} Webpack config objects.
 */
function getWebpackConfig (env, dirs) {
  const prod = env === 'production';
  const definitions = {
    DEBUG: !prod,
    'process.env': {
      NODE_ENV: JSON.stringify(env)
    }
  };
  const plugins = [
    new webpack.DefinePlugin(definitions)
  ];
  const optimization = {};

  if (prod) {
    optimization.minimizer = [
      new TerserPlugin({
        terserOptions: {
          compress: {
            warnings: false
          },
          output: {
            comments: false
          }
        }
      })
    ];
  }

  return dirs.map(dir => ({
    mode: prod ? 'production' : 'development',
    entry: `${path.join(dir, 'index.js')}`,
    output: {
      path: path.resolve(dir),
      filename: `${jsBundle}`
    },
    module: {
      rules: [{
        test: /\.js$/,
        exclude: /^\/node_modules/,
        loader: 'babel-loader'
      }]
    },
    plugins,
    optimization
  }));
}

/**
 * Creates js bundles for all top level directories under `srcRoot`.
 *
 * @param {String} env - "production" for production.
 * @returns {Promise} Resolves to undefined on completion.
 */
function createBundle (env) {
  return getSourceDirs()
    .then(getWebpackConfig.bind(null, env))
    .then(webpackConfigs => util.promisify(webpack)(webpackConfigs))
    .then(stats => {
      if (stats.hasErrors()) {
        throw stats.toJson().errors;
      }
    });
}

/**
 * Run `npm install` for any src directory that needs it.
 *
 * @returns {Promise} That resolves if all npm installs succeed, rejects otherwise.
 */
function runPackageInstalls () {
  return getSourceDirs()
    .then(dirs => {
      const pkgDirs = dirs.filter(dir => {
        let exists = false;
        try {
          fs.accessSync(path.join(dir, 'package.json'));
          exists = true;
        } catch (e) {
          exists = false;
        }
        return exists;
      });

      return Promise.all(pkgDirs.map(pkgDir => {
        const cp = spawn('npm', ['install'], {
          cwd: pkgDir
        });
        return new Promise((resolve, reject) => {
          cp.on('close', code => {
            if (code !== 0) {
              return reject();
            }
            return resolve();
          });
          cp.on('error', reject);
        });
      }));
    });
}

// Define the build tasks:

gulp.task(
  'copy', () => gulp.src([
    `${srcRoot}/**/*.html`,
    `${srcRoot}/**/*.css`,
    `${srcRoot}/**/*.jpg`,
    `${srcRoot}/**/${jsBundle}`,
    `${srcRoot}/**/*worker.js`,
    `${srcRoot}/**/node_modules/**`,
    `!${srcRoot}/horizontal-pager/node_modules`,
    `!${srcRoot}/horizontal-pager/node_modules/**`,
    `!${srcRoot}/**/test`,
    `!${srcRoot}/**/test/**`,
  ]).pipe(gulp.dest('dist'))
);

gulp.task('webpack', () => createBundle('production'));
gulp.task('webpack-dev', () => createBundle('development'));
gulp.task('installs', runPackageInstalls);
<|endoftext|>


<commit_before>import React from 'react'
import { IndexLink, Link } from 'react-router'
import PropTypes from 'prop-types'
import './PageLayout.scss'

export const PageLayout = ({ children }) => (

React Redux Starter Kit

    <IndexLink to='/' activeClassName='page-layout__nav-item--active'>Home</IndexLink>
    {' · '}
    <Link to='/counter' activeClassName='page-layout__nav-item--active'>Counter</Link>
      {' · '}
    <Link to='/email' activeClassName='page-layout__nav-item--active'>Email</Link>

      {children}

)
PageLayout.propTypes = {
  children: PropTypes.node,
}

export default PageLayout
<commit_msg>fixes lint errors<commit_after>import React from 'react'
import { IndexLink, Link } from 'react-router'
import PropTypes from 'prop-types'
import './PageLayout.scss'

export const PageLayout = ({ children }) => (

React Redux Starter Kit

    <IndexLink to='/' activeClassName='page-layout__nav-item--active'>Home</IndexLink>
    {' · '}
    <Link to='/counter' activeClassName='page-layout__nav-item--active'>Counter</Link>
    {' · '}
    <Link to='/email' activeClassName='page-layout__nav-item--active'>Email</Link>

      {children}

)
PageLayout.propTypes = {
  children: PropTypes.node,
}

export default PageLayout
<|endoftext|>


<commit_before>/*!
 * Copyright 2017 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

/**************/
/*  REQUIRES  */
/**************/
var fs = require('fs');
var _ = require('lodash');
var gulp = require('gulp');
var pkg = require('./package.json');

// File I/O
var fs = require('fs');
var ts = require('gulp-typescript');
var del = require('del');
var header = require('gulp-header');
var replace = require('gulp-replace');

/****************/
/*  FILE PATHS  */
/****************/
var paths = {
  src: [
    'src/**/*.ts'
  ],

  databaseSrc: [
    'src/**/*.js'
  ],

  build: 'lib/',
};

// Create a separate project for buildProject that overrides the rootDir
// This ensures that the generated production files are in their own root
// rather than including both src and test in the lib dir.
var buildProject = ts.createProject('tsconfig.json', {rootDir: 'src'});

var banner = `/*! firebase-admin v${pkg.version} */\n`;

/***********/
/*  TASKS  */
/***********/

gulp.task('cleanup', function() {
  return del([
    paths.build,
  ]);
});

gulp.task('compile', function() {
  return gulp.src(paths.src)
    // Compile Typescript into .js and .d.ts files
    .pipe(buildProject())

    // Replace SDK version
    .pipe(replace(/\<XXX_SDK_VERSION_XXX\>/g, pkg.version))

    // Add header
    .pipe(header(banner))

    // Write to build directory
    .pipe(gulp.dest(paths.build))
});

gulp.task('copyDatabase', function() {
  return gulp.src(paths.databaseSrc)
    // Add headers
    .pipe(header(fs.readFileSync('third_party/database-license.txt', 'utf8')))
    .pipe(header(banner))

    // Write to build directory
    .pipe(gulp.dest(paths.build))
});

gulp.task('copyTypings', function() {
  return gulp.src('src/index.d.ts')
    // Add header
    .pipe(header(banner))

    // Write to build directory
    .pipe(gulp.dest(paths.build))
});

// Regenerates js every time a source file changes
gulp.task('watch', function() {
  gulp.watch(paths.src, ['compile']);
});

// Build task
gulp.task('build', gulp.series('cleanup', 'compile', 'copyDatabase', 'copyTypings'));

// Default task
gulp.task('default', gulp.series('build'));
<commit_msg>Fix 'gulp watch' command and also allow compilation of test files. (#672)<commit_after>/*!
 * Copyright 2017 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

/**************/
/*  REQUIRES  */
/**************/
var fs = require('fs');
var _ = require('lodash');
var gulp = require('gulp');
var pkg = require('./package.json');

// File I/O
var fs = require('fs');
var ts = require('gulp-typescript');
var del = require('del');
var header = require('gulp-header');
var replace = require('gulp-replace');

/****************/
/*  FILE PATHS  */
/****************/
var paths = {
  src: [
    'src/**/*.ts',
  ],

  test: [
    'test/**/*.ts',
    '!test/integration/typescript/src/example*.ts',
  ],

  databaseSrc: [
    'src/**/*.js'
  ],

  build: 'lib/',
};

// Create a separate project for buildProject that overrides the rootDir
// This ensures that the generated production files are in their own root
// rather than including both src and test in the lib dir.
var buildProject = ts.createProject('tsconfig.json', {rootDir: 'src'});

var buildTest = ts.createProject('tsconfig.json');

var banner = `/*! firebase-admin v${pkg.version} */\n`;

/***********/
/*  TASKS  */
/***********/

gulp.task('cleanup', function() {
  return del([
    paths.build,
  ]);
});

gulp.task('compile', function() {
  return gulp.src(paths.src)
    // Compile Typescript into .js and .d.ts files
    .pipe(buildProject())

    // Replace SDK version
    .pipe(replace(/\<XXX_SDK_VERSION_XXX\>/g, pkg.version))

    // Add header
    .pipe(header(banner))

    // Write to build directory
    .pipe(gulp.dest(paths.build))
});

/**
 * Task only used to capture typescript compilation errors in the test suite.
 * Output is discarded.
 */
gulp.task('compile_test', function() {
  return gulp.src(paths.test)
    // Compile Typescript into .js and .d.ts files
    .pipe(buildTest())
});

gulp.task('copyDatabase', function() {
  return gulp.src(paths.databaseSrc)
    // Add headers
    .pipe(header(fs.readFileSync('third_party/database-license.txt', 'utf8')))
    .pipe(header(banner))

    // Write to build directory
    .pipe(gulp.dest(paths.build))
});

gulp.task('copyTypings', function() {
  return gulp.src('src/index.d.ts')
    // Add header
    .pipe(header(banner))

    // Write to build directory
    .pipe(gulp.dest(paths.build))
});

gulp.task('compile_all', gulp.series('compile', 'copyDatabase', 'copyTypings', 'compile_test'));

// Regenerates js every time a source file changes
gulp.task('watch', function() {
  gulp.watch(paths.src.concat(paths.test), {ignoreInitial: false}, gulp.series('compile_all'));
});

// Build task
gulp.task('build', gulp.series('cleanup', 'compile', 'copyDatabase', 'copyTypings'));

// Default task
gulp.task('default', gulp.series('build'));
<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');
var mocha = require('gulp-mocha');
var istanbul = require('gulp-istanbul');
var unused = require('gulp-unused');
var eslint = require('gulp-eslint');

gulp.task('coverage', function() {
  return gulp.src(['generator.js', 'lib/**/*.js'])
    .pipe(istanbul())
    .pipe(istanbul.hookRequire());
});

gulp.task('test', ['coverage'], function() {
  return gulp.src('test/*.js')
    .pipe(mocha({reporter: 'spec'}))
    .pipe(istanbul.writeReports());
});

gulp.task('lint', function() {
  return gulp.src(['*.js', 'test/*.js', 'lib/**/*.js'])
    .pipe(eslint())
    .pipe(eslint.format());
});

gulp.task('unused', function() {
  var keys = Object.keys(require('./lib/utils.js'));
  return gulp.src(['generator.js', 'lib/**/*.js'])
    .pipe(unused({keys: keys}))
});

gulp.task('default', ['test', 'lint']);
<commit_msg>change file patterns<commit_after>'use strict';

var gulp = require('gulp');
var mocha = require('gulp-mocha');
var istanbul = require('gulp-istanbul');
var unused = require('gulp-unused');
var eslint = require('gulp-eslint');

gulp.task('coverage', function() {
  return gulp.src(['index.js', 'lib/**/*.js'])
    .pipe(istanbul())
    .pipe(istanbul.hookRequire());
});

gulp.task('test', ['coverage'], function() {
  return gulp.src('test/*.js')
    .pipe(mocha({reporter: 'spec'}))
    .pipe(istanbul.writeReports());
});

gulp.task('lint', function() {
  return gulp.src(['*.js', 'test/*.js', 'lib/**/*.js'])
    .pipe(eslint())
    .pipe(eslint.format());
});

gulp.task('unused', function() {
  var keys = Object.keys(require('./lib/utils.js'));
  return gulp.src(['index.js', 'lib/**/*.js'])
    .pipe(unused({keys: keys}))
});

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


<commit_before>var debug = require('debug')('iGrowl');
var app = require('./app');

app.set('port', process.env.PORT || 3000);

// gulp modules
var gulp = require('gulp'),
	sass = require('gulp-sass'),
	minifycss = require('gulp-minify-css'),
	rename = require('gulp-rename'),
	concat = require('gulp-concat'),
	uglify = require('gulp-uglify'),
	jade = require('gulp-jade'),
	livereload = require('gulp-livereload');

var css = __dirname + '/public/stylesheets',
	js = __dirname + '/public/javascripts',
	fonts = __dirname + '/public/fonts';

// -------------- development --------------
var dev = {
	scssInit  : css + '/scss/*.scss', 		// initial scss processing
	cssDest   : css, 						// css destination
	scssWatch : css + '/**/*.scss', 		// scss watch
	cssReload : css + '/*.css', 			// live-reload watch
};

// compile
gulp.task('scss', function(){
	gulp.src( dev.scssInit )
		.pipe( sass() )
		.pipe( gulp.dest( dev.cssDest ) );
});

// watch (scss for compile, css for livereload)
gulp.task('watch', function(){
	// watch scss
	gulp.watch( dev.scssWatch, ['scss'] );

	// watch css
	livereload.listen();
	gulp.watch( dev.cssReload ).on('change', livereload.changed);
});

// start express
gulp.task('express', function(){
	var server = app.listen(app.get('port'), function() {
		debug('Express server listening on port ' + server.address().port);
	});
});

gulp.task('dev', ['scss', 'express', 'watch'], function(){
	console.log('gulp successfully started!');
});

// -------------- dist --------------
var dist = {
	dest : __dirname + '/dist/',

	cssInit : css + '/igrowl.css',
	get cssDest (){ return this.dest + '/css'; },

	jsInit : js + '/igrowl.js',
	get jsDest (){ return this.dest + '/js'; },

	fontInit : fonts,
	get fontDest (){ return this.dest + '/fonts'; }
};

// igrowl.css + icon font css
gulp.task('dist-css', function(){
	// igrowl.css
	gulp.src( dist.cssInit )
		.pipe( gulp.dest( dist.cssDest ) )
		.pipe( rename({ suffix: '.min' }) )
		.pipe( minifycss() )
		.pipe( gulp.dest( dist.cssDest ) );

	// icon font css
	gulp.src( css + '/icomoon/*.css' )
		.pipe( gulp.dest( dist.cssDest + '/fonts/' ) );
});

// scripts
gulp.task('dist-scripts', function(){
	gulp.src( dist.jsInit )
		.pipe( gulp.dest( dist.jsDest ) )
		.pipe( rename({ suffix: '.min' }) )
		.pipe( uglify({ preserveComments : 'some' }) )
		.pipe( gulp.dest( dist.jsDest) );
});

// fonts
gulp.task('dist-fonts', function(){
	gulp.src( [ dist.fontInit + '/*/*', '!' + dist.fontInit+ '/interface/**'] )
		.pipe( gulp.dest( dist.fontDest ) );
});

gulp.task('dist', ['scss', 'dist-css', 'dist-scripts', 'dist-fonts'], function(){
	console.log( 'successfully set up dist' );
});

// -------------- github page --------------
var gh = {
	dest : __dirname + '/gh-pages/',

	jadeInit : 'views/index.jade',

	get cssDest (){ return this.dest + '/stylesheets/'; },
	get jsDest (){ return this.dest + '/javascripts/'; },
	get fontDest (){ return this.dest + '/fonts/'; },

};

// jade to index.html
gulp.task('gh-jade', function(){
	gulp.src( gh.jadeInit )
		.pipe( jade() )
		.pipe( gulp.dest( gh.dest ) );
});

// main css files + icon font css
gulp.task('gh-css', function(){
	// main css files
	gulp.src( css + '/*.css' )
		.pipe( concat('style.css') )
		.pipe( minifycss() )
		.pipe( gulp.dest( gh.cssDest ) );

	// icomoon css fonts
	gulp.src( css +  '/icomoon/*.css' )
		.pipe( concat('icons.css') )
		.pipe( minifycss() )
		.pipe( gulp.dest( gh.cssDest + '/icomoon/' ) );
});

// all scripts + animate.json
gulp.task('gh-scripts', function(){
	gulp.src([
			js + '/jquery.js',
			js + '/*.js'
		])
		.pipe( concat('main.js') )
		.pipe( uglify() )
		.pipe( gulp.dest( gh.jsDest ) );

	// for animate.json (list of animations)
	gulp.src( js + '/*.json' )
		.pipe( gulp.dest( gh.jsDest ) );
});

// fonts
gulp.task('gh-fonts', function(){
	return gulp.src( fonts + '/*/*' )
		.pipe( gulp.dest( gh.fontDest ) );
});

gulp.task('gh-page', ['gh-jade', 'scss', 'gh-css', 'gh-scripts', 'gh-fonts'], function(){
	console.log( 'successfully updated github page' );
});

<commit_msg>added scss error handling<commit_after>var debug = require('debug')('iGrowl');
var app = require('./app');

app.set('port', process.env.PORT || 3000);

// gulp modules
var gulp = require('gulp'),
	sass = require('gulp-sass'),
	minifycss = require('gulp-minify-css'),
	rename = require('gulp-rename'),
	concat = require('gulp-concat'),
	uglify = require('gulp-uglify'),
	jade = require('gulp-jade'),
	livereload = require('gulp-livereload');

var css = __dirname + '/public/stylesheets',
	js = __dirname + '/public/javascripts',
	fonts = __dirname + '/public/fonts',
	images = __dirname + '/public/images';

// -------------- development --------------
var dev = {
	scssInit  : css + '/scss/*.scss', 		// initial scss processing
	cssDest   : css, 						// css destination
	scssWatch : css + '/**/*.scss', 		// scss watch
	cssReload : css + '/*.css', 			// live-reload watch
};

// compile
gulp.task('scss', function(){
	gulp.src( dev.scssInit )
		.pipe( sass({errLogToConsole: true}) )
		.pipe( gulp.dest( dev.cssDest ) );
});

// watch (scss for compile, css for livereload)
gulp.task('watch', function(){
	// watch scss
	gulp.watch( dev.scssWatch, ['scss'] );

	// watch css
	livereload.listen();
	gulp.watch( dev.cssReload ).on('change', livereload.changed);
});

// start express
gulp.task('express', function(){
	var server = app.listen(app.get('port'), function() {
		debug('Express server listening on port ' + server.address().port);
	});
});

gulp.task('dev', ['scss', 'express', 'watch'], function(){
	console.log('gulp successfully started!');
});

// -------------- dist --------------
var dist = {
	dest : __dirname + '/dist/',

	cssInit : css + '/igrowl.css',
	get cssDest (){ return this.dest + '/css'; },

	jsInit : js + '/igrowl.js',
	get jsDest (){ return this.dest + '/js'; },

	fontInit : fonts,
	get fontDest (){ return this.dest + '/fonts'; }
};

// igrowl.css + icon font css
gulp.task('dist-css', function(){
	// igrowl.css
	gulp.src( dist.cssInit )
		.pipe( gulp.dest( dist.cssDest ) )
		.pipe( rename({ suffix: '.min' }) )
		.pipe( minifycss() )
		.pipe( gulp.dest( dist.cssDest ) );

	// icon font css
	gulp.src( css + '/icomoon/*.css' )
		.pipe( gulp.dest( dist.cssDest + '/fonts/' ) );
});

// scripts
gulp.task('dist-scripts', function(){
	gulp.src( dist.jsInit )
		.pipe( gulp.dest( dist.jsDest ) )
		.pipe( rename({ suffix: '.min' }) )
		.pipe( uglify({ preserveComments : 'some' }) )
		.pipe( gulp.dest( dist.jsDest) );
});

// fonts
gulp.task('dist-fonts', function(){
	gulp.src( [ dist.fontInit + '/*/*', '!' + dist.fontInit+ '/interface/**'] )
		.pipe( gulp.dest( dist.fontDest ) );
});

gulp.task('dist', ['scss', 'dist-css', 'dist-scripts', 'dist-fonts'], function(){
	console.log( 'successfully set up dist' );
});

// -------------- github page --------------
var gh = {
	dest : __dirname + '/gh-pages/',

	jadeInit : 'views/index.jade',

	get cssDest (){ return this.dest + '/stylesheets/'; },
	get jsDest (){ return this.dest + '/javascripts/'; },
	get fontDest (){ return this.dest + '/fonts/'; },
	get imageDest (){ return this.dest + '/images/'; },
};

// jade to index.html
gulp.task('gh-jade', function(){
	gulp.src( gh.jadeInit )
		.pipe( jade() )
		.pipe( gulp.dest( gh.dest ) );
});

// main css files + icon font css
gulp.task('gh-css', function(){
	// main css files
	gulp.src( css + '/*.css' )
		.pipe( concat('style.css') )
		.pipe( minifycss() )
		.pipe( gulp.dest( gh.cssDest ) );

	// icomoon css fonts
	gulp.src( css +  '/icomoon/*.css' )
		.pipe( concat('icons.css') )
		.pipe( minifycss() )
		.pipe( gulp.dest( gh.cssDest + '/icomoon/' ) );
});

// all scripts + animate.json
gulp.task('gh-scripts', function(){
	gulp.src([
			js + '/jquery.js',
			js + '/*.js'
		])
		.pipe( concat('main.js') )
		.pipe( uglify() )
		.pipe( gulp.dest( gh.jsDest ) );

	// for animate.json (list of animations)
	gulp.src( js + '/*.json' )
		.pipe( gulp.dest( gh.jsDest ) );
});

// fonts + images
gulp.task('gh-other', function(){
	gulp.src( fonts + '/*/*' )
		.pipe( gulp.dest( gh.fontDest ) );

	gulp.src( images + '/*' )
		.pipe( gulp.dest( gh.imageDest ) );
});

gulp.task('gh-page', ['gh-jade', 'scss', 'gh-css', 'gh-scripts', 'gh-fonts'], function(){
	console.log( 'successfully updated github page' );
});

<|endoftext|>


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

const runSequence = require('run-sequence');
const del = require('del');
const quaff = require('quaff');
const wiredep = require('wiredep').stream;

const browserSync = require('browser-sync');
const reload = browserSync.reload;

const config = require('./config');
const handlers = require('./handlers');

const lessPluginGlob = require('less-plugin-glob');
const autoprefixer = require('autoprefixer');
const mqpacker = require('css-mqpacker');

// Cleaning the temporary directory and directory of builds
gulp.task('clean', () => del(['.tmp', 'build'], { dot: true }));

// Synchronize two directories: `app` and `build`
gulp.task('sync', () =>
  gulp.src('')
    .pipe($.directorySync('app', 'build', {
      printSummary: true,
      ignore: handlers.syncIgnore
    }))
);

// Linting JavaScript files
gulp.task('lint', () =>
  gulp.src(['**/*.js', '!{inline,vendor}/**'], { cwd: 'app/scripts' })
    .pipe($.xo().on('error', handlers.xoError))
);

// Transpiles ES2015 code to ES5 and concatenate JavaScript files
gulp.task('scripts:babel', () =>
  gulp.src(['**/*.js', '!{inline,vendor}/**'], { cwd: 'app/scripts' })
    .pipe($.newer('.tmp/scripts'))
    .pipe($.sourcemaps.init())
    .pipe($.babel({
      presets: ['es2015']
    }).on('error', handlers.babelError))
    .pipe(gulp.dest('.tmp/scripts'))
);

gulp.task('scripts', ['scripts:babel'], () =>
  gulp.src('.tmp/scripts/**/*.js')
    .pipe($.sourcemaps.init())
    .pipe($.concat('scripts.bundle.js'))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('build/scripts'))
);

// Compile Less files, add vendor prefixes to rules and combine media queries
gulp.task('styles', () =>
  gulp.src('app/styles/less/styles.less')
    .pipe($.sourcemaps.init())
    .pipe($.less({
      plugins: [lessPluginGlob]
    }).on('error', handlers.lessError))
    .pipe($.postcss([
      autoprefixer({ browsers: config.autoprefixer }),
      mqpacker
    ]))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('build/styles'))
);

// Compile Jade files, inject Bower components and contents of the inline files
gulp.task('templates', () =>
  gulp.src('app/templates/*.jade')
    .pipe($.clipEmptyFiles())
    .pipe($.data(() => quaff('app/templates/data')))
    .pipe($.jade({
      pretty: true
    }).on('error', handlers.jadeError))
    .pipe(wiredep({
      onError: handlers.wiredepError
    }))
    .pipe(gulp.dest('build'))
);

// Generating SVG sprite
gulp.task('sprites', () =>
  gulp.src('app/images/icons/**/*.svg')
    .pipe($.svgSprite(config.svgSprite).on('error', console.log))
    .pipe(gulp.dest('build'))
);

// Compression built files
gulp.task('compress:scripts', () =>
  gulp.src('build/scripts/scripts.bundle.js')
    .pipe($.uglify())
    .pipe($.rename('scripts.bundle.min.js'))
    .pipe(gulp.dest('build/scripts'))
);

gulp.task('compress:styles', () =>
  gulp.src('build/styles/styles.css')
    .pipe($.minifyCss())
    .pipe($.rename('styles.min.css'))
    .pipe(gulp.dest('build/styles'))
);

gulp.task('compress:images', () =>
  gulp.src(['build/images/**/*'])
    .pipe($.imagemin({
      progressive: true,
      interlaced: true
    }))
    .pipe(gulp.dest('build/images'))
);

gulp.task('compress', [
  'compress:scripts',
  'compress:styles',
  'compress:images'
]);

// Builds the project to develop
gulp.task('build:default', (cb) =>
  runSequence(
    'clean',
    'sprites',
    'lint',
    ['sync', 'templates', 'scripts', 'styles'],
    cb
  )
);

// Builds the project, runs the server and Watch files for changes & reload
gulp.task('serve', () => {
  browserSync({
    online: false,
    notify: false,
    logPrefix: 'Yellfy',
    server: {
      baseDir: ['build'],
      routes: {
        '/bower_components': 'bower_components'
      }
    },
    port: 8000
  });

  // Directory synchronization
  $.watch([
    'app/images/**',
    '!app/images/icons/**',
    'app/scripts/vendor/**',
    'app/styles/vendor/**',
    'app/*'
  ], $.batch((events, done) =>
    gulp.start(runSequence('sync', reload), done)
  ));

  // Scripts
  $.watch([
    'app/scripts/**/*.js',
    '!app/scripts/{vendor,inline}'
  ], $.batch((events, done) =>
    gulp.start(runSequence('lint', 'scripts', reload), done)
  ));

  // Sprites
  $.watch(['app/images/icons/**/*.svg'], $.batch((events, done) =>
    gulp.start(runSequence('sprites', 'styles', reload), done)
  ));

  // Styles
  $.watch(['app/styles/less/**/*.less'], $.batch((events, done) =>
    gulp.start(runSequence('styles', reload), done)
  ));

  // Bower & templates
  $.watch([
    'bower.json',
    'app/templates/**/*'
  ], $.batch((events, done) =>
    gulp.start(runSequence('templates', reload), done)
  ));
});

// Build and runs the server
gulp.task('server', ['build:default'], () =>
  browserSync({
    notify: false,
    logPrefix: 'Yellfy',
    server: {
      baseDir: ['build'],
      routes: {
        '/bower_components': 'bower_components'
      }
    },
    port: 8001
  })
);

// General building tasks
gulp.task('default', (cb) => runSequence('build:default', 'serve', cb));
gulp.task('build', () =>
  runSequence('build:default', 'compress', () => del(['.tmp'], { dot: true })
));
<commit_msg>strict mode and comments<commit_after>'use strict';

const gulp = require('gulp');
const $ = require('gulp-load-plugins')();

const runSequence = require('run-sequence');
const del = require('del');
const quaff = require('quaff');
const wiredep = require('wiredep').stream;

// Browser Sync
const browserSync = require('browser-sync');
const reload = browserSync.reload;

// Yellfy libs
const config = require('./config');
const handlers = require('./handlers');

// Plugins for Less and PostCSS
const lessPluginGlob = require('less-plugin-glob');
const autoprefixer = require('autoprefixer');
const mqpacker = require('css-mqpacker');

// Cleaning the temporary directory and directory of builds
gulp.task('clean', () => del(['.tmp', 'build'], { dot: true }));

// Synchronize two directories: `app` and `build`
gulp.task('sync', () =>
  gulp.src('')
    .pipe($.directorySync('app', 'build', {
      printSummary: true,
      ignore: handlers.syncIgnore
    }))
);

// Linting JavaScript files
gulp.task('lint', () =>
  gulp.src(['**/*.js', '!{inline,vendor}/**'], { cwd: 'app/scripts' })
    .pipe($.xo().on('error', handlers.xoError))
);

// Transpiles ES2015 code to ES5 and concatenate JavaScript files
gulp.task('scripts:babel', () =>
  gulp.src(['**/*.js', '!{inline,vendor}/**'], { cwd: 'app/scripts' })
    .pipe($.newer('.tmp/scripts'))
    .pipe($.sourcemaps.init())
    .pipe($.babel({
      presets: ['es2015']
    }).on('error', handlers.babelError))
    .pipe(gulp.dest('.tmp/scripts'))
);

gulp.task('scripts', ['scripts:babel'], () =>
  gulp.src('.tmp/scripts/**/*.js')
    .pipe($.sourcemaps.init())
    .pipe($.concat('scripts.bundle.js'))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('build/scripts'))
);

// Compile Less files, add vendor prefixes to rules and combine media queries
gulp.task('styles', () =>
  gulp.src('app/styles/less/styles.less')
    .pipe($.sourcemaps.init())
    .pipe($.less({
      plugins: [lessPluginGlob]
    }).on('error', handlers.lessError))
    .pipe($.postcss([
      autoprefixer({ browsers: config.autoprefixer }),
      mqpacker
    ]))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('build/styles'))
);

// Compile Jade files, inject Bower components and contents of the inline files
gulp.task('templates', () =>
  gulp.src('app/templates/*.jade')
    .pipe($.clipEmptyFiles())
    .pipe($.data(() => quaff('app/templates/data')))
    .pipe($.jade({
      pretty: true
    }).on('error', handlers.jadeError))
    .pipe(wiredep({
      onError: handlers.wiredepError
    }))
    .pipe(gulp.dest('build'))
);

// Generating SVG sprite
gulp.task('sprites', () =>
  gulp.src('app/images/icons/**/*.svg')
    .pipe($.svgSprite(config.svgSprite).on('error', console.log))
    .pipe(gulp.dest('build'))
);

// Compression built files
gulp.task('compress:scripts', () =>
  gulp.src('build/scripts/scripts.bundle.js')
    .pipe($.uglify())
    .pipe($.rename('scripts.bundle.min.js'))
    .pipe(gulp.dest('build/scripts'))
);

gulp.task('compress:styles', () =>
  gulp.src('build/styles/styles.css')
    .pipe($.minifyCss())
    .pipe($.rename('styles.min.css'))
    .pipe(gulp.dest('build/styles'))
);

gulp.task('compress:images', () =>
  gulp.src(['build/images/**/*'])
    .pipe($.imagemin({
      progressive: true,
      interlaced: true
    }))
    .pipe(gulp.dest('build/images'))
);

gulp.task('compress', [
  'compress:scripts',
  'compress:styles',
  'compress:images'
]);

// Builds the project to develop
gulp.task('build:default', (cb) =>
  runSequence(
    'clean',
    'sprites',
    'lint',
    ['sync', 'templates', 'scripts', 'styles'],
    cb
  )
);

// Builds the project, runs the server and Watch files for changes & reload
gulp.task('serve', () => {
  browserSync({
    online: false,
    notify: false,
    logPrefix: 'Yellfy',
    server: {
      baseDir: ['build'],
      routes: {
        '/bower_components': 'bower_components'
      }
    },
    port: 8000
  });

  // Directory synchronization
  $.watch([
    'app/images/**',
    '!app/images/icons/**',
    'app/scripts/vendor/**',
    'app/styles/vendor/**',
    'app/*'
  ], $.batch((events, done) =>
    gulp.start(runSequence('sync', reload), done)
  ));

  // Scripts
  $.watch([
    'app/scripts/**/*.js',
    '!app/scripts/{vendor,inline}'
  ], $.batch((events, done) =>
    gulp.start(runSequence('lint', 'scripts', reload), done)
  ));

  // Sprites
  $.watch(['app/images/icons/**/*.svg'], $.batch((events, done) =>
    gulp.start(runSequence('sprites', 'styles', reload), done)
  ));

  // Styles
  $.watch(['app/styles/less/**/*.less'], $.batch((events, done) =>
    gulp.start(runSequence('styles', reload), done)
  ));

  // Bower & templates
  $.watch([
    'bower.json',
    'app/templates/**/*'
  ], $.batch((events, done) =>
    gulp.start(runSequence('templates', reload), done)
  ));
});

// Build and runs the server
gulp.task('server', ['build:default'], () =>
  browserSync({
    notify: false,
    logPrefix: 'Yellfy',
    server: {
      baseDir: ['build'],
      routes: {
        '/bower_components': 'bower_components'
      }
    },
    port: 8001
  })
);

// General building tasks
gulp.task('default', (cb) => runSequence('build:default', 'serve', cb));
gulp.task('build', () =>
  runSequence('build:default', 'compress', () => del(['.tmp'], { dot: true })
));
<|endoftext|>


<commit_before>'use-strict';

//////////////////////////////
// Requires
//////////////////////////////
var autoprefixer = require('gulp-autoprefixer');
var browserSync = require('browser-sync').create();
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var plumber = require('gulp-plumber');
var rename = require('gulp-rename');
var replace = require('gulp-replace');
var sass = require('gulp-sass');
var stylish = require('jshint-stylish');
var merge = require('merge-stream');
var lazypipe = require('lazypipe');

//////////////////////////////
// Variables
//////////////////////////////

var dirs = {
  'images': 'dev/images/*.{png,jpg,jpeg}',
  'markdown': 'dev/docs/*.md',
  'sass': {
    'main': 'dev/*.scss',
    'patterns': 'dev/patterns/**/*.scss',
    'lint': [
      'dev/patterns/**/*.scss',
      'dev/dev.scss',
      '!dev/*.css'
    ]
  },
  'js': {
    'lint': [
      'Gulpfile.js',
      '*.json',
      'dev/dev.js',
      'dev/patterns/**/package.json'
    ]
  },
  'html': {
    'reload': [
      'dev/index.html',
      'dev/patterns/**/html/*.html'
    ]
  }
};

var importPath = {
  node_modules: {
    colors: '../node_modules/bluemix-colors/npm-dist/bluemix-colors',
    typography: '../node_modules/bluemix-typography/bluemix-typography'
  },
  bower_components: {
    colors: '../bower_components/bluemix-colors/bower-dist/bluemix-colors',
    typography: '../bower_components/bluemix-typography/bluemix-typography'
  }
};

//////////////////////////////
// BrowserSync
//////////////////////////////

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

//////////////////////////////
// HTML Tasks
//////////////////////////////

gulp.task('html:reload', function() {
  gulp.watch(dirs.html.reload).on('change', browserSync.reload);
});

//////////////////////////////
// JavaScript Tasks
//////////////////////////////

gulp.task('jshint', function() {
  return gulp.src(dirs.js.lint)
    .pipe(plumber())
    .pipe(jshint())
    .pipe(jshint.reporter(stylish));
});

gulp.task('jshint:watch', function() {
  gulp.watch(dirs.js.lint, ['jshint']);
});

gulp.task('js:reload', function() {
  gulp.watch(dirs.js.lint).on('change', browserSync.reload);
});

//////////////////////////////
// Sass Tasks
//////////////////////////////

// Using importPaths here to properly compile dev.css for development
gulp.task('sass', function() {
  return gulp.src(dirs.sass.main)
    .pipe(replace('path_to_colors', importPath.node_modules.colors))
    .pipe(replace('path_to_typography', importPath.node_modules.typography))
    .pipe(sass().on('error', sass.logError))
    .pipe(autoprefixer({
      browsers: ['> 1%', 'last 2 versions']
    }))
    .pipe(gulp.dest('dev'))
    .pipe(browserSync.stream());
});

gulp.task('sass:dist', function() {
  var npmDistMain = gulp.src(dirs.sass.main)
    .pipe(replace('path_to_colors', importPath.node_modules.colors))
    .pipe(replace('path_to_typography', importPath.node_modules.typography))
    .pipe(rename('_pattern-library.scss'))
    .pipe(gulp.dest('npm-dist'));

  var npmDistPatterns = gulp.src(dirs.sass.patterns)
    .pipe(gulp.dest('npm-dist/patterns'));

  var bowerDistMain = gulp.src(dirs.sass.main)
    .pipe(replace('path_to_colors', importPath.bower_components.colors))
    .pipe(replace('path_to_typography', importPath.bower_components.typography))
    .pipe(rename('_pattern-library.scss'))
    .pipe(gulp.dest('bower-dist'));

  var bowerDistPatterns = gulp.src(dirs.sass.patterns)
    .pipe(gulp.dest('bower-dist/patterns'));

  return merge(npmDistMain, npmDistPatterns, bowerDistMain, bowerDistPatterns);
});

gulp.task('sass:watch', function() {
  gulp.watch([dirs.sass.main, dirs.sass.patterns], ['sass', 'sass:dist']);
});

//////////////////////////////
// Image Tasks
//////////////////////////////

gulp.task('image', function() {
  var npmDist = gulp.src(dirs.images)
    .pipe(gulp.dest('npm-dist/images'));

  var bowerDist = gulp.src(dirs.images)
    .pipe(gulp.dest('bower-dist/images'));

  return merge(npmDist, bowerDist);
});

gulp.task('image:watch', function() {
  gulp.watch(dirs.images, ['image']);
});

//////////////////////////////
// Markdown Tasks
//////////////////////////////

gulp.task('markdown', function() {
  var npmDist = gulp.src(dirs.markdown)
    .pipe(gulp.dest('npm-dist/docs'));

  var bowerDist = gulp.src(dirs.markdown)
    .pipe(gulp.dest('bower-dist/docs'));

  return (npmDist, bowerDist);
});

//////////////////////////////
// Running Tasks
//////////////////////////////

gulp.task('build', ['sass', 'image', 'markdown']);

gulp.task('watch', ['sass:watch', 'jshint:watch', 'image:watch', 'html:reload', 'js:reload']);

gulp.task('default', ['browser-sync', 'build', 'watch']);
<commit_msg>Fix path to bower_components<commit_after>'use-strict';

//////////////////////////////
// Requires
//////////////////////////////
var autoprefixer = require('gulp-autoprefixer');
var browserSync = require('browser-sync').create();
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var plumber = require('gulp-plumber');
var rename = require('gulp-rename');
var replace = require('gulp-replace');
var sass = require('gulp-sass');
var stylish = require('jshint-stylish');
var merge = require('merge-stream');
var lazypipe = require('lazypipe');

//////////////////////////////
// Variables
//////////////////////////////

var dirs = {
  'images': 'dev/images/*.{png,jpg,jpeg}',
  'markdown': 'dev/docs/*.md',
  'sass': {
    'main': 'dev/*.scss',
    'patterns': 'dev/patterns/**/*.scss',
    'lint': [
      'dev/patterns/**/*.scss',
      'dev/dev.scss',
      '!dev/*.css'
    ]
  },
  'js': {
    'lint': [
      'Gulpfile.js',
      '*.json',
      'dev/dev.js',
      'dev/patterns/**/package.json'
    ]
  },
  'html': {
    'reload': [
      'dev/index.html',
      'dev/patterns/**/html/*.html'
    ]
  }
};

var importPath = {
  node_modules: {
    colors: '../node_modules/bluemix-colors/npm-dist/bluemix-colors',
    typography: '../node_modules/bluemix-typography/bluemix-typography'
  },
  bower_components: {
    colors: '../bluemix-colors/bower-dist/bluemix-colors',
    typography: '../bluemix-typography/bluemix-typography'
  }
};

//////////////////////////////
// BrowserSync
//////////////////////////////

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

//////////////////////////////
// HTML Tasks
//////////////////////////////

gulp.task('html:reload', function() {
  gulp.watch(dirs.html.reload).on('change', browserSync.reload);
});

//////////////////////////////
// JavaScript Tasks
//////////////////////////////

gulp.task('jshint', function() {
  return gulp.src(dirs.js.lint)
    .pipe(plumber())
    .pipe(jshint())
    .pipe(jshint.reporter(stylish));
});

gulp.task('jshint:watch', function() {
  gulp.watch(dirs.js.lint, ['jshint']);
});

gulp.task('js:reload', function() {
  gulp.watch(dirs.js.lint).on('change', browserSync.reload);
});

//////////////////////////////
// Sass Tasks
//////////////////////////////

// Using importPaths here to properly compile dev.css for development
gulp.task('sass', function() {
  return gulp.src(dirs.sass.main)
    .pipe(replace('path_to_colors', importPath.node_modules.colors))
    .pipe(replace('path_to_typography', importPath.node_modules.typography))
    .pipe(sass().on('error', sass.logError))
    .pipe(autoprefixer({
      browsers: ['> 1%', 'last 2 versions']
    }))
    .pipe(gulp.dest('dev'))
    .pipe(browserSync.stream());
});

gulp.task('sass:dist', function() {
  var npmDistMain = gulp.src(dirs.sass.main)
    .pipe(replace('path_to_colors', importPath.node_modules.colors))
    .pipe(replace('path_to_typography', importPath.node_modules.typography))
    .pipe(rename('_pattern-library.scss'))
    .pipe(gulp.dest('npm-dist'));

  var npmDistPatterns = gulp.src(dirs.sass.patterns)
    .pipe(gulp.dest('npm-dist/patterns'));

  var bowerDistMain = gulp.src(dirs.sass.main)
    .pipe(replace('path_to_colors', importPath.bower_components.colors))
    .pipe(replace('path_to_typography', importPath.bower_components.typography))
    .pipe(rename('_pattern-library.scss'))
    .pipe(gulp.dest('bower-dist'));

  var bowerDistPatterns = gulp.src(dirs.sass.patterns)
    .pipe(gulp.dest('bower-dist/patterns'));

  return merge(npmDistMain, npmDistPatterns, bowerDistMain, bowerDistPatterns);
});

gulp.task('sass:watch', function() {
  gulp.watch([dirs.sass.main, dirs.sass.patterns], ['sass', 'sass:dist']);
});

//////////////////////////////
// Image Tasks
//////////////////////////////

gulp.task('image', function() {
  var npmDist = gulp.src(dirs.images)
    .pipe(gulp.dest('npm-dist/images'));

  var bowerDist = gulp.src(dirs.images)
    .pipe(gulp.dest('bower-dist/images'));

  return merge(npmDist, bowerDist);
});

gulp.task('image:watch', function() {
  gulp.watch(dirs.images, ['image']);
});

//////////////////////////////
// Markdown Tasks
//////////////////////////////

gulp.task('markdown', function() {
  var npmDist = gulp.src(dirs.markdown)
    .pipe(gulp.dest('npm-dist/docs'));

  var bowerDist = gulp.src(dirs.markdown)
    .pipe(gulp.dest('bower-dist/docs'));

  return (npmDist, bowerDist);
});

//////////////////////////////
// Running Tasks
//////////////////////////////

gulp.task('build', ['sass', 'image', 'markdown']);

gulp.task('watch', ['sass:watch', 'jshint:watch', 'image:watch', 'html:reload', 'js:reload']);

gulp.task('default', ['browser-sync', 'build', 'watch']);
<|endoftext|>


<commit_before>const gulp = require("gulp");
require('gulp-release-it')(gulp);

gulp.task("default", function() {
	runSequence(
		"complete-release",
		function(error) {
			if (error) {
				console.log(error.message);
			}
			else {
				console.log('RELEASE FINISHED SUCCESSFULLY');
			}
			callback(error);
		});
});
<commit_msg>fixed gulp task<commit_after>const gulp = require("gulp");
require('gulp-release-it')(gulp);
const runSequence = require('run-sequence');

gulp.task("default", function() {
	runSequence(
		"bump-complete-release"
	);
});
<|endoftext|>


<commit_before>'use strict'

let gulp = require('gulp')
let sass = require('gulp-sass')
let typescript = require('gulp-tsc')
let browserSync = require('browser-sync').create()

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

gulp.task('watch', ['watch.ts', 'watch.sass'])

gulp.task('setup', ['ts', 'sass'], () => {
	gulp.src(['node_modules/angular2/bundles/**/*'])
		.pipe(gulp.dest('public/javascripts/angular2'))
})

gulp.task('ts', () => {
	let tscConfig = require('./client/tsconfig.json')

	var tsResult = gulp
		.src(['client/**/*.ts'])
		.pipe(typescript(tscConfig.compilerOptions));

	return tsResult.pipe(gulp.dest('public/javascripts/'));
})

gulp.task('ts.html', () => {
	gulp.src(['client/**/*.html'])
		.pipe(gulp.dest('public/javascripts/'))
})

gulp.task('watch.ts', ['ts', 'ts.html'], () => {
	gulp.watch('client/**/*', ['ts', 'ts.html'])
		// .pipe(browserSync.stream());
})

gulp.task('sass', () => {
	return gulp.src('./public/sass/main.scss')
		.pipe(sass().on('error', sass.logError))
		.pipe(gulp.dest('./public/stylesheets'))
		.pipe(browserSync.stream({match: '**/*.css'}))
})

gulp.task('watch.sass', ['sass', 'browser-sync'], function () {
	gulp.watch('./public/sass/**/*.scss', ['sass'])
})

gulp.task('browser-sync', function() {
	browserSync.init({
		proxy: "localhost:3000"
	})
})
<commit_msg>Remove html components<commit_after>'use strict'

let gulp = require('gulp')
let sass = require('gulp-sass')
let typescript = require('gulp-tsc')
let browserSync = require('browser-sync').create()

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

gulp.task('watch', ['watch.ts', 'watch.sass'])

gulp.task('setup', ['ts', 'sass'], () => {
	gulp.src(['node_modules/angular2/bundles/**/*'])
		.pipe(gulp.dest('public/javascripts/angular2'))
})

gulp.task('ts', () => {
	let tscConfig = require('./client/tsconfig.json')

	var tsResult = gulp
		.src(['client/**/*.ts'])
		.pipe(typescript(tscConfig.compilerOptions));

	return tsResult.pipe(gulp.dest('public/javascripts/'));
})

gulp.task('watch.ts', ['ts'], () => {
	gulp.watch('client/**/*', ['ts'])
		// .pipe(browserSync.stream());
})

gulp.task('sass', () => {
	return gulp.src('./public/sass/main.scss')
		.pipe(sass().on('error', sass.logError))
		.pipe(gulp.dest('./public/stylesheets'))
		.pipe(browserSync.stream({match: '**/*.css'}))
})

gulp.task('watch.sass', ['sass', 'browser-sync'], function () {
	gulp.watch('./public/sass/**/*.scss', ['sass'])
})

gulp.task('browser-sync', function() {
	browserSync.init({
		proxy: "localhost:3000"
	})
})
<|endoftext|>


<commit_before>/* eslint-env node */

"use strict";

/* *****************
#    DEFINE-VARS
# *************** */
var _ = require("underscore"),
  gulp = require("gulp"),
  CheckCoverage = require("./node_modules/istanbul/lib/command/check-coverage.js"),
  combineCoverage = require("istanbul-combine"),
  eslint = require("gulp-eslint"),
  exec = require("child_process").exec,
  KarmaServer = require("karma").Server;

/* ******************
#    CONCAT-TASKS
# **************** */
gulp.task("default", ["coverage", "lint"]);
gulp.task("test", [
    "test-backbone",
    "test-own"
]);

/* *********
#    TEST
# ******* */
gulp.task("test-backbone", function (cb) {
  new KarmaServer({
    browsers: ["Firefox"],
    coverageReporter: {
      dir: "coverage-backbone",
      subdir: ".",
      type: "json"
    },
    files: [
      "bower_components/underscore/underscore.js",
      "bower_components/jquery/dist/jquery.js",
      "bower_components/backbone/backbone.js",
      "bower_components/autobahn/autobahn.js",
      "backbone.wamp.js",
      "backbone-test/setup/dom-setup.js",
      "backbone-test/setup/environment.js",
      "backbone-test/noconflict.js",
      "backbone-test/events.js",
      "backbone-test/model.js",
      "backbone-test/collection.js",
      "backbone-test/router.js",
      "backbone-test/view.js",
      "backbone-test/sync.js"
    ],
    frameworks: ["qunit"],
    preprocessors: {
      "backbone.wamp.js": "coverage"
    },
    reporters: ["progress", "coverage"],
    singleRun: true
  }, cb).start();
});

gulp.task("test-own", function (cb) {
  var crossbarProcess = exec("crossbar start");
  _.delay(function () {
    new KarmaServer({
      browsers: ["Firefox"],
      coverageReporter: {
        dir: "coverage-own",
        subdir: ".",
        type: "json"
      },
      files: [
        "bower_components/async/lib/async.js",
        "bower_components/autobahn/autobahn.js",
        "bower_components/underscore/underscore.js",
        "bower_components/jquery/dist/jquery.js",
        "bower_components/backbone/backbone.js",
        "bower_components/q/q.js",
        "backbone.wamp.js",
        "bower_components/requirejs/require.js",
        "test/browser.js"
      ],
      frameworks: ["chai", "mocha"],
      preprocessors: {
        "backbone.wamp.js": "coverage"
      },
      reporters: ["progress", "coverage"],
      singleRun: true
    }, function () {
      exec("ps -fe | grep [i]stanbul | awk '{print $2}'", function (err, pid) {
        process.kill(parseInt(pid.trim(), 10), "SIGINT");
        crossbarProcess.kill();
        cb(err);
      });
    }).start();
  }, 10000);
});

/* *************
#    COVERAGE
# *********** */
gulp.task("coverage", ["test"], function (cb) {
  combineCoverage({
    pattern: "coverage-*/coverage*.json",
    reporters: {
      html: {
        dir: "coverage"
      },
      json: {
        dir: "coverage"
      }
    }
  }).then(function () {
    var checker = new CheckCoverage();
    checker.run([
      "--remain", "coverage/coverage-final.json",
      "--statements", "100",
      "--branches", "100",
      "--functions", "100",
      "--lines", "100"
    ], function (err) {
      cb(err);
    });
  });
});

/* ***********
#    LINT
# ********* */
gulp.task("lint", function () {
  return gulp.src(["*.js", "test/*.js"])
    .pipe(eslint())
    .pipe(eslint.format())
    .pipe(eslint.failOnError());
});
<commit_msg>timeout on grep pid exec<commit_after>/* eslint-env node */

"use strict";

/* *****************
#    DEFINE-VARS
# *************** */
var _ = require("underscore"),
  gulp = require("gulp"),
  CheckCoverage = require("./node_modules/istanbul/lib/command/check-coverage.js"),
  combineCoverage = require("istanbul-combine"),
  eslint = require("gulp-eslint"),
  exec = require("child_process").exec,
  KarmaServer = require("karma").Server;

/* ******************
#    CONCAT-TASKS
# **************** */
gulp.task("default", ["coverage", "lint"]);
gulp.task("test", [
    "test-backbone",
    "test-own"
]);

/* *********
#    TEST
# ******* */
gulp.task("test-backbone", function (cb) {
  new KarmaServer({
    browsers: ["Firefox"],
    coverageReporter: {
      dir: "coverage-backbone",
      subdir: ".",
      type: "json"
    },
    files: [
      "bower_components/underscore/underscore.js",
      "bower_components/jquery/dist/jquery.js",
      "bower_components/backbone/backbone.js",
      "bower_components/autobahn/autobahn.js",
      "backbone.wamp.js",
      "backbone-test/setup/dom-setup.js",
      "backbone-test/setup/environment.js",
      "backbone-test/noconflict.js",
      "backbone-test/events.js",
      "backbone-test/model.js",
      "backbone-test/collection.js",
      "backbone-test/router.js",
      "backbone-test/view.js",
      "backbone-test/sync.js"
    ],
    frameworks: ["qunit"],
    preprocessors: {
      "backbone.wamp.js": "coverage"
    },
    reporters: ["progress", "coverage"],
    singleRun: true
  }, cb).start();
});

gulp.task("test-own", function (cb) {
  var crossbarProcess = exec("crossbar start");
  _.delay(function () {
    new KarmaServer({
      browsers: ["Firefox"],
      coverageReporter: {
        dir: "coverage-own",
        subdir: ".",
        type: "json"
      },
      files: [
        "bower_components/async/lib/async.js",
        "bower_components/autobahn/autobahn.js",
        "bower_components/underscore/underscore.js",
        "bower_components/jquery/dist/jquery.js",
        "bower_components/backbone/backbone.js",
        "bower_components/q/q.js",
        "backbone.wamp.js",
        "bower_components/requirejs/require.js",
        "test/browser.js"
      ],
      frameworks: ["chai", "mocha"],
      preprocessors: {
        "backbone.wamp.js": "coverage"
      },
      reporters: ["progress", "coverage"],
      singleRun: true
    }, function () {
      exec("ps -fe | grep [i]stanbul | awk '{print $2}'",
        {timeout: 10000},
        function (err, pid) {
          process.kill(parseInt(pid.trim(), 10), "SIGINT");
          crossbarProcess.kill();
          cb(err);
        });
    }).start();
  }, 10000);
});

/* *************
#    COVERAGE
# *********** */
gulp.task("coverage", ["test"], function (cb) {
  combineCoverage({
    pattern: "coverage-*/coverage*.json",
    reporters: {
      html: {
        dir: "coverage"
      },
      json: {
        dir: "coverage"
      }
    }
  }).then(function () {
    var checker = new CheckCoverage();
    checker.run([
      "--remain", "coverage/coverage-final.json",
      "--statements", "100",
      "--branches", "100",
      "--functions", "100",
      "--lines", "100"
    ], function (err) {
      cb(err);
    });
  });
});

/* ***********
#    LINT
# ********* */
gulp.task("lint", function () {
  return gulp.src(["*.js", "test/*.js"])
    .pipe(eslint())
    .pipe(eslint.format())
    .pipe(eslint.failOnError());
});
<|endoftext|>


<commit_before>let bookList = [
  { numb: 1, title: 'HTML5', author: 'Lee', price: 2000 },
  { numb: 2, title: 'CSS3', author: 'Kim', price: 3000 },
  { numb: 3, title: 'JavaScript', author: 'Park', price: 5000 }
];

/*
  `

    <input type="checkbox" id="${book.numb}">
    ${book.numb}
    ${book.title}
    ${book.author}
    ${book.price}

`
*/

// 1. Delete Book 버튼이 클릭되면 체크된 book 리스트를 삭제
document.getElementById('delete').addEventListener('click', (e) => {
  //chedked id를 배열로 취득
  const checkedIdArr = [...document.querySelectorAll('tbody input[type=checkbox]:checked')].map(el => el.id);
})
// 2. 최상위 체크박스를 클릭하면 전체 체크박스 토글(on/off)
document.getElementById('checkbox').addEventListener('change', (e) => { [...document.querySelectorAll('thead input[type=checkbox]')].map(el => { el.checked = e.target.checked; }); });
// 3. Add Book 버튼이 클릭되면 .add-form를 표시

// 4. Add Book 버튼이 클릭되면 Cancel 버튼 표시
// 5. .add-form이 표시된 상태에서 필수입력 대상인 Title이 입력되었으면 Add Book 버튼이 클릭 시, bookList 객체에 .add-form의 입력값을 추가하고 DOM 갱신
// 6. .add-form이 표시된 상태에서 필수입력 대상인 Title이 입력되지 않았으면 alert으로 입력되지 않았음을 경고
if (!conditions[i].checked) {
  alert('Title을 입력하지 않았습니다.');
}
// 7. Cancel 버튼이 클릭되면 .add-form과 Cancel 버튼 비표시
// (*) 모든 선언문의 전역 선언 금지

<commit_msg>add another way  code and study<commit_after>let bookList = [
  { numb: 1, title: 'HTML5', author: 'Lee', price: 2000 },
  { numb: 2, title: 'CSS3', author: 'Kim', price: 3000 },
  { numb: 3, title: 'JavaScript', author: 'Park', price: 5000 }
];

const book =
/*
  `

    <input type="checkbox" id="${book.numb}">
    ${book.numb}
    ${book.title}
    ${book.author}
    ${book.price}

`
*/

// 1. Delete Book 버튼이 클릭되면 체크된 book 리스트를 삭제
document.getElementById('delete').addEventListener('click', (e) => {
  //chedked id를 배열로 취득
  const checkedIdArr = [...document.querySelectorAll('tbody input[type=checkbox]:checked')].map(el => el.id);
})
// 2. 최상위 체크박스를 클릭하면 전체 체크박스 토글(on/off)
document.getElementById('checkbox').addEventListener('change', (e) => { [...document.querySelectorAll('thead input[type=checkbox]')].map(el => { el.checked = e.target.checked; }); });
// 3. Add Book 버튼이 클릭되면 .add-form를 표시

// 4. Add Book 버튼이 클릭되면 Cancel 버튼 표시
// 5. .add-form이 표시된 상태에서 필수입력 대상인 Title이 입력되었으면 Add Book 버튼이 클릭 시, bookList 객체에 .add-form의 입력값을 추가하고 DOM 갱신
// 6. .add-form이 표시된 상태에서 필수입력 대상인 Title이 입력되지 않았으면 alert으로 입력되지 않았음을 경고
if (!conditions[i].checked) {
  alert('Title을 입력하지 않았습니다.');
}
// 7. Cancel 버튼이 클릭되면 .add-form과 Cancel 버튼 비표시
// (*) 모든 선언문의 전역 선언 금지

/*
다른 사람이 작성한 코드

    const BookList = (function () {
      // let bookList = [
      //   { id: 1, title: 'HTML5', author: 'Lee', price: 2000 },
      //   { id: 2, title: 'CSS3', author: 'Kim', price: 3000 },
      //   { id: 3, title: 'JavaScript', author: 'Park', price: 5000 }
      // ];

      let bookList = [];

      // bookList 객체를 DOM에 갱신
      const insertBookListToTable = function () {
        // bookList 객체를 HTML화하고 DOM 갱신
        document.querySelector('#mytable > tbody').innerHTML = bookList.map(({ id, title, author, price }) => `<tr><td><input type="checkbox" id="${id}"></td><th>${id}</th><td>${title}</td><td>${author}</td><td>${price}</td></tr>`).join('');
      };

      const getBook = function (url) {
        // promise 생성과 반환
        return new Promise((resolve, reject) => {
          // XMLHttpRequest 객체의 생성
          var req = new XMLHttpRequest();
          // 비동기 방식으로 Request를 오픈한다
          req.open('GET', url);
          // Request를 전송한다
          req.send();

          // Event Handler
          req.onreadystatechange = function () {
            // 서버 응답 완료 && 정상 응답
            if (req.readyState === XMLHttpRequest.DONE) {
              if (req.status == 200) {
                // resolve 메소드에 전달한 처리 결과는 then 메소드의 첫번째 콜백함수에서 취득 가능
                resolve(req.response);
              } else {
                // 서버의 응답이 정상이 아니면
                // reject 메소드에 전달한 처리 결과는 then 메소드의 두번째 콜백함수에서 취득 가능
                reject(req.statusText);
              }
            }
          };
        });
      };

      // Get bookList form server
      getBook('http://localhost:5000/books')
      .then(books => {
        // resolved!
        bookList = JSON.parse(books);
        // 취득한 bookList 객체를 DOM에 추가
        insertBookListToTable();
      }, (reason) => {
        // rejected!
        console.log(reason);
        throw 'Error:' + reason;
      }).catch(error => console.error(error));

      // bookList 객체의 마지막 id에 1을 더한 값 취득
      const getLastId = function () {
        let lastId = 1;
        bookList.map(({ id }) => id > lastId ? lastId = id : id);
        return lastId + 1;
      };

      // book list 이벤트 처리
      const eventProcess = function() {
        // add book list form 표시 여부
        let isShown = false;
        // add book list form
        const addForm = document.getElementsByClassName('add-form')[0];
        // cancel button
        const cancel = document.getElementById('cancel');

        // add book button event
        document.getElementById('add').addEventListener('click', () => {
          if (isShown) {
            // 이미 입력폼이 보여지고 상황
            const title = document.getElementById('title');
            if (title) {
              // 타이틀 입력폼의 값이 있을 경우
              // Todo: POST to Server

              bookList.push({
                id: getLastId(),
                title,
                author: document.getElementById('author').value,
                price: document.getElementById('price').value
              });

              // bookList 객체를 DOM에 갱신
              insertBookListToTable();

              console.log(bookList);

              addForm.style.display = 'none';
              cancel.style.display = 'none';
            } else {
              alert('title을 입력하세요');
              return;
            }
          } else {
            addForm.style.display = 'block';
            cancel.style.display = 'inline-block';
            document.getElementById('title').value = '';
            document.getElementById('author').value = '';
            document.getElementById('price').value = '';
          }
          isShown = !isShown;
        });

        // cancel button event
        // addEventListener 함수의 콜백 함수를 화살표 함수로 정의하면 this가 상위 컨택스트를 가리킨다.
        cancel.addEventListener('click', function () {
          if (addForm.style.display === 'block') {
            // addForm 비표시
            addForm.style.display = 'none';
            // cancel button 비표시
            this.style.display = 'none';
            isShown = !isShown;
          }
        });
        // checkall checkbox event
        document.getElementById('checkall').addEventListener('change', (e) => {
          // 모든 체크박스를 최상위 체크박스의 상태와 동기화
          [...document.querySelectorAll('tbody input[type=checkbox]')].map(el => {
            el.checked = e.target.checked;
          });
        });

        // delete button event
        document.getElementById('delete').addEventListener('click', (e) => {
          // checked id를 배열로 취득
          const checkedIdArr = [...document.querySelectorAll('tbody input[type=checkbox]:checked')].map(el => el.id);

          // bookList 객체에서 checked id와 id가 같은 리스트를 삭제
          checkedIdArr.map(checkedId => {
            bookList = bookList.filter((book) => book.id !== checkedId * 1);
          });

          // bookList 객체를 DOM에 갱신
          insertBookListToTable();
        });
      };

      return {
        init: eventProcess
      };
    }());

    BookList.init();

  */<|endoftext|>


<commit_before>/*  Utlimate Jay Mega Gulpfile */

(function () {
    "use strict";

    var pkg     = require("./package.json"),
        del     = require("del"),
        yargs   = require("yargs"),
        exec    = require("exec"),
        fs      = require("fs"),
        gulp    = require("gulp"),
        bump    = require("gulp-bump"),
        header  = require("gulp-header"),
        qunit   = require("gulp-qunit"),
        uglify  = require("gulp-uglifyjs"),
        jshint  = require('gulp-jshint'),
        gutil   = require("gulp-util"),
        zip     = require("gulp-zip"),
        replace = require("gulp-replace"),
        gsync   = require("gulp-sync"),
        sync    = gsync(gulp).sync;

    var version = yargs.argv.type || "patch";

    var settings = {
        banner: {
            content: [
                '/*! ----------------------------------------------------------------------------',
                ' *  <%= pkg.description %>',
                ' *  v<%= pkg.version %> released <%= datetime %>',
                ' *  <%= pkg.homepage %>',
                ' *  Copyright (c) 2010-<%= year %>, Jay Salvat',
                ' *  http://jaysalvat.com/',
                ' *  ----------------------------------------------------------------------------',
                ' *  ccv.js and cascade.js',
                ' *  Copyright (c) 2010-<%= year %>, Liu Liu',
                ' *  http://liuliu.me/',
                ' *  ----------------------------------------------------------------------------',
                ' */',
                '',
            ].join("\n"),
            vars: {
                pkg: pkg,
                datetime: gutil.date("yyyy-mm-dd HH:MM"),
                year: gutil.date("yyyy")
            }
        },
        files: {
            in: [
                './src/cascade.js',
                './src/ccv.js',
                './src/jquery.facedetection.js'
            ],
            out: 'jquery.facedetection'
        },
        enclose: {
            '(typeof jQuery !== "function") ? { fn: {} } : jQuery': '$' // jQuery hack for Worker mode
        }
    };

    var getPackageJson = function () {
        return JSON.parse(fs.readFileSync('./package.json'));
    };

    gulp.task("clean", function (cb) {
        return del([ "./dist" ], cb);
    });

    gulp.task("tmp-clean", function (cb) {
        return del([ "./tmp" ], cb);
    });

    gulp.task("tmp-create", function (cb) {
        return exec("mkdir -p ./tmp", cb);
    });

    gulp.task("tmp-copy", [ "tmp-create" ], function () {
        return gulp.src("./dist/*")
            .pipe(gulp.dest("./tmp"));
    });

    gulp.task("zip", [ "tmp-create" ], function () {
        var filename = settings.files.out + ".zip";

        return gulp.src("./dist/*")
            .pipe(zip(filename))
            .pipe(gulp.dest("./tmp"));
    });

    gulp.task("fail-if-dirty", function (cb) {
        return exec('git diff-index HEAD --', function (err, output) { // err, output, code
            if (err) {
                return cb(err);
            }
            if (output) {
                return cb("Repository is dirty");
            }
            return cb();
        });
    });

    gulp.task("fail-if-not-master", function (cb) {
        exec('git symbolic-ref -q HEAD', function (err, output) { // err, output, code
            if (err) {
                return cb(err);
            }
            if (!/refs\/heads\/master/.test(output)) {
                return cb("Branch is not Master");
            }
            return cb();
        });
    });

    gulp.task("git-tag", function (cb) {
        var message = "v" + getPackageJson().version;

        return exec('git tag ' + message, cb);
    });

    gulp.task("git-add", function (cb) {
        return exec('git add -A', cb);
    });

    gulp.task("git-commit", [ "git-add" ], function (cb) {
        var message = "Build v" + getPackageJson().version;

        return exec('git commit -m "' + message + '"', cb);
    });

    gulp.task("git-pull", function (cb) {
        return exec('git pull origin master', function (err, output, code) {
            if (code !== 0) {
                return cb(err + output);
            }
            return cb();
        });
    });

    gulp.task("git-push", [ "git-commit" ], function (cb) {
        return exec('git push origin master --tags', function (err, output, code) {
            if (code !== 0) {
                return cb(err + output);
            }
            return cb();
        });
    });

    gulp.task("meta", [ "tmp-create" ], function (cb) {
        var  metadata = {
                date: gutil.date("yyyy-mm-dd HH:MM"),
                version: "v" + getPackageJson().version
            },
            json = JSON.stringify(metadata, null, 4);

        fs.writeFileSync("tmp/metadata.json", json);
        fs.writeFileSync("tmp/metadata.js", "__metadata(" + json + ");");

        return cb();
    });

    gulp.task("bump", function () {
        return gulp.src([ "package.json", "bower.json", "facedetection.jquery.json" ])
            .pipe(bump({
                type: version
            }))
            .pipe(gulp.dest("."));
    });

    gulp.task("license", function () {
        return gulp.src([ "./LICENSE.md", "./README.md" ])
            .pipe(replace(/( 2010-)(\d{4})/g, "$1" + gutil.date("yyyy")))
            .pipe(gulp.dest("."));
    });

    gulp.task('lint', function() {
        return gulp.src('./src/jquery.facedetection.js')
            .pipe(jshint())
            .pipe(jshint.reporter('default'));
    });

    gulp.task("test-dev", function () {
        return gulp.src("./tests/test-runner.html")
            .pipe(qunit());
    });

    gulp.task("test-dist", function () {
        return gulp.src("./tests/test-runner-dist.html")
            .pipe(qunit());
    });

    gulp.task("uglify", function () {
        settings.banner.vars.pkg = getPackageJson();

        return gulp.src(settings.files.in)
            .pipe(uglify(settings.files.out + '.min.js', {
                enclose: settings.enclose,
                compress: {
                    warnings: false
                },
                mangle: true,
                outSourceMap: true
            }))
            .pipe(gulp.dest('./dist/'));
    });

    gulp.task("beautify", function () {
        return gulp.src(settings.files.in)
            .pipe(uglify(settings.files.out + '.js', {
                enclose: settings.enclose,
                compress: {
                    warnings: false
                },
                output: {
                    beautify: true
                },
                mangle: false
            }))
            .pipe(gulp.dest('./dist/'));
    });

    gulp.task("header", function () {
        settings.banner.vars.pkg = getPackageJson();

        return gulp.src('./dist/*.js')
            .pipe(header(settings.banner.content, settings.banner.vars ))
            .pipe(gulp.dest('./dist/'));
    });

    gulp.task("gh-pages", function (cb) {
        version = getPackageJson().version;

        exec([  'git checkout gh-pages',
                'rm -rf releases/' + version,
                'mkdir -p releases/' + version,
                'cp -r tmp/* releases/' + version,
                'git add -A releases/' + version,
                'rm -rf releases/latest',
                'mkdir -p releases/latest',
                'cp -r tmp/* releases/latest',
                'git add -A releases/latest',
                'git commit -m "Publish release v' + version + '."',
                // 'git push origin gh-pages',
                'git checkout -'
            ].join(" && "),
            function (err, output, code) {
                if (code !== 0) {
                    return cb(err + output);
                }
                return cb();
            }
        );
    });

    gulp.task("test", sync([
        "lint",
        "test-dev"
    ],
    "building"));

    gulp.task("build", sync([
        "lint",
        "test-dev",
        "clean",
        "beautify",
        "uglify",
        "header",
        "test-dist"
    ],
    "building"));

    gulp.task("release", sync([
      [ "fail-if-not-master", "fail-if-dirty" ],
        "git-pull",
        "lint",
        "test-dev",
        "bump",
        "license",
        "clean",
        "beautify",
        "uglify",
        "header",
        "test-dist",
        "git-add",
        "git-commit",
        "git-tag",
        "git-push",
        "publish"
    ],
    "releasing"));

    gulp.task("publish", sync([
      [ "fail-if-not-master", "fail-if-dirty" ],
        "tmp-create",
        "tmp-copy",
        "meta",
        "zip",
        "gh-pages",
        "tmp-clean"
    ],
    "publising"));
})();

/*

NOTES
=====

Gh-pages creation
-----------------

git checkout --orphan gh-pages
git rm -rf .
rm -fr
echo "Welcome" > index.html
git add index.html
git commit -a -m "First commit"
git push origin gh-pages
git checkout -

*/
<commit_msg>Uncomment gh-pages push<commit_after>/*  Utlimate Jay Mega Gulpfile */

(function () {
    "use strict";

    var pkg     = require("./package.json"),
        del     = require("del"),
        yargs   = require("yargs"),
        exec    = require("exec"),
        fs      = require("fs"),
        gulp    = require("gulp"),
        bump    = require("gulp-bump"),
        header  = require("gulp-header"),
        qunit   = require("gulp-qunit"),
        uglify  = require("gulp-uglifyjs"),
        jshint  = require('gulp-jshint'),
        gutil   = require("gulp-util"),
        zip     = require("gulp-zip"),
        replace = require("gulp-replace"),
        gsync   = require("gulp-sync"),
        sync    = gsync(gulp).sync;

    var version = yargs.argv.type || "patch";

    var settings = {
        banner: {
            content: [
                '/*! ----------------------------------------------------------------------------',
                ' *  <%= pkg.description %>',
                ' *  v<%= pkg.version %> released <%= datetime %>',
                ' *  <%= pkg.homepage %>',
                ' *  Copyright (c) 2010-<%= year %>, Jay Salvat',
                ' *  http://jaysalvat.com/',
                ' *  ----------------------------------------------------------------------------',
                ' *  ccv.js and cascade.js',
                ' *  Copyright (c) 2010-<%= year %>, Liu Liu',
                ' *  http://liuliu.me/',
                ' *  ----------------------------------------------------------------------------',
                ' */',
                '',
            ].join("\n"),
            vars: {
                pkg: pkg,
                datetime: gutil.date("yyyy-mm-dd HH:MM"),
                year: gutil.date("yyyy")
            }
        },
        files: {
            in: [
                './src/cascade.js',
                './src/ccv.js',
                './src/jquery.facedetection.js'
            ],
            out: 'jquery.facedetection'
        },
        enclose: {
            '(typeof jQuery !== "function") ? { fn: {} } : jQuery': '$' // jQuery hack for Worker mode
        }
    };

    var getPackageJson = function () {
        return JSON.parse(fs.readFileSync('./package.json'));
    };

    gulp.task("clean", function (cb) {
        return del([ "./dist" ], cb);
    });

    gulp.task("tmp-clean", function (cb) {
        return del([ "./tmp" ], cb);
    });

    gulp.task("tmp-create", function (cb) {
        return exec("mkdir -p ./tmp", cb);
    });

    gulp.task("tmp-copy", [ "tmp-create" ], function () {
        return gulp.src("./dist/*")
            .pipe(gulp.dest("./tmp"));
    });

    gulp.task("zip", [ "tmp-create" ], function () {
        var filename = settings.files.out + ".zip";

        return gulp.src("./dist/*")
            .pipe(zip(filename))
            .pipe(gulp.dest("./tmp"));
    });

    gulp.task("fail-if-dirty", function (cb) {
        return exec('git diff-index HEAD --', function (err, output) { // err, output, code
            if (err) {
                return cb(err);
            }
            if (output) {
                return cb("Repository is dirty");
            }
            return cb();
        });
    });

    gulp.task("fail-if-not-master", function (cb) {
        exec('git symbolic-ref -q HEAD', function (err, output) { // err, output, code
            if (err) {
                return cb(err);
            }
            if (!/refs\/heads\/master/.test(output)) {
                return cb("Branch is not Master");
            }
            return cb();
        });
    });

    gulp.task("git-tag", function (cb) {
        var message = "v" + getPackageJson().version;

        return exec('git tag ' + message, cb);
    });

    gulp.task("git-add", function (cb) {
        return exec('git add -A', cb);
    });

    gulp.task("git-commit", [ "git-add" ], function (cb) {
        var message = "Build v" + getPackageJson().version;

        return exec('git commit -m "' + message + '"', cb);
    });

    gulp.task("git-pull", function (cb) {
        return exec('git pull origin master', function (err, output, code) {
            if (code !== 0) {
                return cb(err + output);
            }
            return cb();
        });
    });

    gulp.task("git-push", [ "git-commit" ], function (cb) {
        return exec('git push origin master --tags', function (err, output, code) {
            if (code !== 0) {
                return cb(err + output);
            }
            return cb();
        });
    });

    gulp.task("meta", [ "tmp-create" ], function (cb) {
        var  metadata = {
                date: gutil.date("yyyy-mm-dd HH:MM"),
                version: "v" + getPackageJson().version
            },
            json = JSON.stringify(metadata, null, 4);

        fs.writeFileSync("tmp/metadata.json", json);
        fs.writeFileSync("tmp/metadata.js", "__metadata(" + json + ");");

        return cb();
    });

    gulp.task("bump", function () {
        return gulp.src([ "package.json", "bower.json", "facedetection.jquery.json" ])
            .pipe(bump({
                type: version
            }))
            .pipe(gulp.dest("."));
    });

    gulp.task("license", function () {
        return gulp.src([ "./LICENSE.md", "./README.md" ])
            .pipe(replace(/( 2010-)(\d{4})/g, "$1" + gutil.date("yyyy")))
            .pipe(gulp.dest("."));
    });

    gulp.task('lint', function() {
        return gulp.src('./src/jquery.facedetection.js')
            .pipe(jshint())
            .pipe(jshint.reporter('default'));
    });

    gulp.task("test-dev", function () {
        return gulp.src("./tests/test-runner.html")
            .pipe(qunit());
    });

    gulp.task("test-dist", function () {
        return gulp.src("./tests/test-runner-dist.html")
            .pipe(qunit());
    });

    gulp.task("uglify", function () {
        settings.banner.vars.pkg = getPackageJson();

        return gulp.src(settings.files.in)
            .pipe(uglify(settings.files.out + '.min.js', {
                enclose: settings.enclose,
                compress: {
                    warnings: false
                },
                mangle: true,
                outSourceMap: true
            }))
            .pipe(gulp.dest('./dist/'));
    });

    gulp.task("beautify", function () {
        return gulp.src(settings.files.in)
            .pipe(uglify(settings.files.out + '.js', {
                enclose: settings.enclose,
                compress: {
                    warnings: false
                },
                output: {
                    beautify: true
                },
                mangle: false
            }))
            .pipe(gulp.dest('./dist/'));
    });

    gulp.task("header", function () {
        settings.banner.vars.pkg = getPackageJson();

        return gulp.src('./dist/*.js')
            .pipe(header(settings.banner.content, settings.banner.vars ))
            .pipe(gulp.dest('./dist/'));
    });

    gulp.task("gh-pages", function (cb) {
        version = getPackageJson().version;

        exec([  'git checkout gh-pages',
                'rm -rf releases/' + version,
                'mkdir -p releases/' + version,
                'cp -r tmp/* releases/' + version,
                'git add -A releases/' + version,
                'rm -rf releases/latest',
                'mkdir -p releases/latest',
                'cp -r tmp/* releases/latest',
                'git add -A releases/latest',
                'git commit -m "Publish release v' + version + '."',
                'git push origin gh-pages',
                'git checkout -'
            ].join(" && "),
            function (err, output, code) {
                if (code !== 0) {
                    return cb(err + output);
                }
                return cb();
            }
        );
    });

    gulp.task("test", sync([
        "lint",
        "test-dev"
    ],
    "building"));

    gulp.task("build", sync([
        "lint",
        "test-dev",
        "clean",
        "beautify",
        "uglify",
        "header",
        "test-dist"
    ],
    "building"));

    gulp.task("release", sync([
      [ "fail-if-not-master", "fail-if-dirty" ],
        "git-pull",
        "lint",
        "test-dev",
        "bump",
        "license",
        "clean",
        "beautify",
        "uglify",
        "header",
        "test-dist",
        "git-add",
        "git-commit",
        "git-tag",
        "git-push",
        "publish"
    ],
    "releasing"));

    gulp.task("publish", sync([
      [ "fail-if-not-master", "fail-if-dirty" ],
        "tmp-create",
        "tmp-copy",
        "meta",
        "zip",
        "gh-pages",
        "tmp-clean"
    ],
    "publising"));
})();

/*

NOTES
=====

Gh-pages creation
-----------------

git checkout --orphan gh-pages
git rm -rf .
rm -fr
echo "Welcome" > index.html
git add index.html
git commit -a -m "First commit"
git push origin gh-pages
git checkout -

*/
<|endoftext|>


<commit_before>import element from 'virtual-element';
import { bindActionCreators } from 'redux';
import shallowEquals  from 'is-equal-shallow';
import isPlainObject from 'is-plain-object';
import invariant from 'invariant';

const defaultMapStateToProps = () => ({});
const defaultMapDispatchToProps = dispatch => ({ dispatch });
const defaultMergeProps =  (stateProps, dispatchProps, parentProps) => ({
    ...parentProps,
    ...stateProps,
    ...dispatchProps
});

const wrapActionCreators = actionCreators => dispatch => bindActionCreators(actionCreators, dispatch);

function connect(mapStateToProps = defaultMapStateToProps, mapDispatchToProps = defaultMapDispatchToProps, mergeProps = defaultMergeProps) {
    if(isPlainObject(mapDispatchToProps)) {
        mapDispatchToProps = wrapActionCreators(mapDispatchToProps);
    }

    const mappedStateUseProps = mapStateToProps.length > 1;
    const mappedDispatchUseProps = mapDispatchToProps.length > 1;

    const computeStateProps = props => {
        const state = props.store.getState();
        const stateProps = mapStateToProps(state, props);

        invariant(isPlainObject(stateProps), '[deku-redux][connect] mapStateToProps must return an object. Instead received %s', stateProps);

        return stateProps;
    };

    const computeDispatchProps = props => {
        const dispatch = props.store.dispatch;
        const dispatchProps = mapDispatchToProps(dispatch, props);

        invariant(isPlainObject(dispatchProps), '[deku-redux][connect] mapDispatchToProps must return an object. Instead received %s', dispatchProps);

        return dispatchProps;
    };

    return function connectWrapper(Component) {
        const connectRegistry = {};
        const getStateProps = id => connectRegistry[id] ? connectRegistry[id].stateProps : null;
        const setStateProps = (id, stateProps) => connectRegistry[id].stateProps = stateProps;
        const getDispatchProps = id => connectRegistry[id] ? connectRegistry[id].dispatchProps : null;
        const setDispatchProps = (id, dispatchProps) => connectRegistry[id].dispatchProps = dispatchProps;

        const ConnectedComponent = {
            propTypes: {
                store: { source: 'store' },
                storeState: { source: 'storeState' }
            },

            beforeMount({ id, props }, elm, setState) {
                invariant(props.store, '[deku-redux][connect] Could not find store. Did you use `storePlugin` on your deku tree?');
                invariant(
                  props.store.getState && props.store.subscribe && props.store.subscribe,
                  '[deku-redux][connect] Could not recognise store. Did you use `storePlugin` with a valid redux store?'
                );

                connectRegistry[id] = {};
                setStateProps(id, computeStateProps(props));
                setDispatchProps(id, computeDispatchProps(props));
            },

            shouldUpdate({ id, props }, nextProps) {
                const storeChanged = nextProps.storeState !== props.storeState;
                const propsChanged = !shallowEquals(nextProps, props);

                const computeNewStateProps = storeChanged || (propsChanged && mappedStateUseProps);
                const computeNewDispatchProps = propsChanged && mappedDispatchUseProps;

                let statePropsChanged = false;
                let dispatchPropsChanged = false;

                if (computeNewStateProps) {
                    const stateProps = computeStateProps(props);
                    statePropsChanged = !shallowEquals(stateProps, getStateProps(id));
                    if (statePropsChanged) {
                        setStateProps(id, stateProps);
                    }
                }

                if (computeNewDispatchProps) {
                    const dispatchProps = computeDispatchProps(props);
                    dispatchPropsChanged = !shallowEquals(dispatchProps, getDispatchProps(id));
                    if (dispatchPropsChanged) {
                        setDispatchProps(id, stateProps);
                    }
                }

                return propsChanged || statePropsChanged || dispatchPropsChanged;
            },

            beforeUnmount({ id }) {
                connectRegistry[id] = undefined;
            },

            render({ id, props }) {
                // TODO: use _.omit or similar
                const parentProps = Object.keys(props)
                    .filter(prop => prop !== 'store' || prop !== 'storeState')
                    .reduce((acc, prop) => {
                        acc[prop] = props[prop];
                        return acc;
                    }, {});

                const componentProps = mergeProps(parentProps, getStateProps(id), getDispatchProps(id));

                invariant(isPlainObject(componentProps), '[deku-redux][connect] `mergeProps` function didn\'t return a plain object.');

                return element(Component, componentProps);
            }
        };

        return ConnectedComponent;
    };
}

export default connect;
<commit_msg>Remove dependency on virtual-element<commit_after>import { bindActionCreators } from 'redux';
import shallowEquals  from 'is-equal-shallow';
import isPlainObject from 'is-plain-object';
import invariant from 'invariant';

const defaultMapStateToProps = () => ({});
const defaultMapDispatchToProps = dispatch => ({ dispatch });
const defaultMergeProps =  (stateProps, dispatchProps, parentProps) => ({
    ...parentProps,
    ...stateProps,
    ...dispatchProps
});

const wrapActionCreators = actionCreators => dispatch => bindActionCreators(actionCreators, dispatch);

function connect(mapStateToProps = defaultMapStateToProps, mapDispatchToProps = defaultMapDispatchToProps, mergeProps = defaultMergeProps) {
    if(isPlainObject(mapDispatchToProps)) {
        mapDispatchToProps = wrapActionCreators(mapDispatchToProps);
    }

    const mappedStateUseProps = mapStateToProps.length > 1;
    const mappedDispatchUseProps = mapDispatchToProps.length > 1;

    const computeStateProps = props => {
        const state = props.store.getState();
        const stateProps = mapStateToProps(state, props);

        invariant(isPlainObject(stateProps), '[deku-redux][connect] mapStateToProps must return an object. Instead received %s', stateProps);

        return stateProps;
    };

    const computeDispatchProps = props => {
        const dispatch = props.store.dispatch;
        const dispatchProps = mapDispatchToProps(dispatch, props);

        invariant(isPlainObject(dispatchProps), '[deku-redux][connect] mapDispatchToProps must return an object. Instead received %s', dispatchProps);

        return dispatchProps;
    };

    return function connectWrapper(Component) {
        const connectRegistry = {};
        const getStateProps = id => connectRegistry[id] ? connectRegistry[id].stateProps : null;
        const setStateProps = (id, stateProps) => connectRegistry[id].stateProps = stateProps;
        const getDispatchProps = id => connectRegistry[id] ? connectRegistry[id].dispatchProps : null;
        const setDispatchProps = (id, dispatchProps) => connectRegistry[id].dispatchProps = dispatchProps;

        const ConnectedComponent = {
            propTypes: {
                store: { source: 'store' },
                storeState: { source: 'storeState' }
            },

            beforeMount({ id, props }, elm, setState) {
                invariant(props.store, '[deku-redux][connect] Could not find store. Did you use `storePlugin` on your deku tree?');
                invariant(
                  props.store.getState && props.store.subscribe && props.store.subscribe,
                  '[deku-redux][connect] Could not recognise store. Did you use `storePlugin` with a valid redux store?'
                );

                connectRegistry[id] = {};
                setStateProps(id, computeStateProps(props));
                setDispatchProps(id, computeDispatchProps(props));
            },

            shouldUpdate({ id, props }, nextProps) {
                const storeChanged = nextProps.storeState !== props.storeState;
                const propsChanged = !shallowEquals(nextProps, props);

                const computeNewStateProps = storeChanged || (propsChanged && mappedStateUseProps);
                const computeNewDispatchProps = propsChanged && mappedDispatchUseProps;

                let statePropsChanged = false;
                let dispatchPropsChanged = false;

                if (computeNewStateProps) {
                    const stateProps = computeStateProps(props);
                    statePropsChanged = !shallowEquals(stateProps, getStateProps(id));
                    if (statePropsChanged) {
                        setStateProps(id, stateProps);
                    }
                }

                if (computeNewDispatchProps) {
                    const dispatchProps = computeDispatchProps(props);
                    dispatchPropsChanged = !shallowEquals(dispatchProps, getDispatchProps(id));
                    if (dispatchPropsChanged) {
                        setDispatchProps(id, stateProps);
                    }
                }

                return propsChanged || statePropsChanged || dispatchPropsChanged;
            },

            beforeUnmount({ id }) {
                connectRegistry[id] = undefined;
            },

            render({ id, props }) {
                // TODO: use _.omit or similar
                const parentProps = Object.keys(props)
                    .filter(prop => prop !== 'store' || prop !== 'storeState')
                    .reduce((acc, prop) => {
                        acc[prop] = props[prop];
                        return acc;
                    }, {});

                const componentProps = mergeProps(parentProps, getStateProps(id), getDispatchProps(id));

                invariant(isPlainObject(componentProps), '[deku-redux][connect] `mergeProps` function didn\'t return a plain object.');

                // <Component {...componentProps} />
                return { type: Component, children: componentProps.children, attributes: componentProps };
            }
        };

        return ConnectedComponent;
    };
}

export default connect;
<|endoftext|>


<commit_before>Rat = function(context){
    this.context = context;
};
Rat.prototype = {
    path : function(opt, style){ return new Rat.Path(opt, style, this); },
    image : function(opt, style){ return new Rat.Image(opt, style, this); },
    text : function(opt, style){ return new Rat.Text(opt, style, this); },

    clear: function(){
        var cnv = this.context.canvas;
        this.context.clearRect(0, 0, cnv.width, cnv.height);
    },
    draw: function(elements){
        var ctx = this.context;
        elements.forEach(function(element){
            element.draw(ctx);
        });
    }
};
Rat.Path = function(opt, style, context){
    Rat.init(this, arguments);
};
Rat.Path.prototype = {
    draw: function(ctx){
        this.process(function(ctx){
            if(this.style.fillStyle)
                ctx.fill();
            if(this.style.strokeStyle)
                ctx.stroke();
        }, ctx);
    },
    isPointIn: function(x,y, ctx){
        return this.process(function(ctx){ return ctx.isPointInPath(x, y) }, ctx);
    },
    process: function(callback, ctx){
        ctx = ctx || this.context.context;
        Rat.style(ctx, this.style);
        ctx.beginPath();
        this.opt.forEach(function(func){
            ctx[func[0]].apply(ctx, func.slice(1));
        });
        var result = callback.call(this, ctx);
        ctx.restore();
        return result;
    }
};

Rat.Image = function(opt, style, context){
    Rat.init(this, arguments);
};
Rat.Image.prototype.draw = function(ctx){
    Rat.style(ctx, this.style);
    if(this.style.crop)
        ctx.drawImage.apply(ctx, [this.opt, 0, 0].concat(this.style.crop));
    else
        ctx.drawImage(this.opt, 0, 0, this.style.width || this.opt.width, this.style.height || this.opt.height);
    ctx.restore();
};
Rat.Text = function(){
    Rat.init(this, arguments);
};
Rat.Text.prototype.draw = function(ctx){
    Rat.style(ctx, this.style);
    if(this.style.fillStyle)
        ctx.fillText(this.opt, 0, 0, this.style.maxWidth || 999999999999999);
    if(this.style.strokeStyle)
        ctx.strokeText(this.opt, 0, 0, this.style.maxWidth || 9999999999999999);
    ctx.restore();
};
Rat.Text.prototype.measure = function(){
    var ctx = this.context.context;
    Rat.style(ctx, this.style);
    var w = ctx.measureText(this.opt).width;
    ctx.restore();
    return w;
};

Rat.notStyle = "translate0rotate0transform0scale".split(0);
Rat.style = function(ctx, style){
    ctx.save();
    style.origin && ctx.translate.apply(ctx, style.origin);
    style.rotate && ctx.rotate(style.rotate);
    style.scale && ctx.scale.apply(ctx, style.scale);
    style.origin && ctx.translate(-style.origin[0], -style.origin[1]);
    style.translate && ctx.translate.apply(ctx, style.translate); // must it be before or after origin?
    style.transform && ctx.transform.apply(ctx, style.transform);
    Object.keys(style).forEach(function(key){
        if(!~Rat.notStyle.indexOf(key))
            ctx[key] = style[key];
    });
};
Rat.init = function(cls, arg){
    cls.opt = arg[0];
    cls.style = arg[1] || {};
    cls.context = arg[2];
    cls.draw(arg[2].context);
};
<commit_msg>Apply is bad<commit_after>Rat = function(context){
    this.context = context;
};
Rat.prototype = {
    path : function(opt, style){ return new Rat.Path(opt, style, this); },
    image : function(opt, style){ return new Rat.Image(opt, style, this); },
    text : function(opt, style){ return new Rat.Text(opt, style, this); },

    clear: function(){
        var cnv = this.context.canvas;
        this.context.clearRect(0, 0, cnv.width, cnv.height);
    },
    draw: function(elements){
        var ctx = this.context;
        elements.forEach(function(element){
            element.draw(ctx);
        });
    }
};
Rat.Path = function(opt, style, context){
    Rat.init(this, arguments);
};
Rat.Path.prototype = {
    draw: function(ctx){
        this.process(function(ctx){
            if(this.style.fillStyle)
                ctx.fill();
            if(this.style.strokeStyle)
                ctx.stroke();
        }, ctx);
    },
    isPointIn: function(x,y, ctx){
        return this.process(function(ctx){ return ctx.isPointInPath(x, y) }, ctx);
    },
    process: function(callback, ctx){
        ctx = ctx || this.context.context;
        Rat.style(ctx, this.style);
        ctx.beginPath();
        this.opt.forEach(function(func){
            ctx[func[0]].apply(ctx, func.slice(1));
        });
        var result = callback.call(this, ctx);
        ctx.restore();
        return result;
    }
};

Rat.Image = function(opt, style, context){
    Rat.init(this, arguments);
};
Rat.Image.prototype.draw = function(ctx){
    Rat.style(ctx, this.style);
    if(this.style.crop)
        ctx.drawImage.apply(ctx, [this.opt, 0, 0].concat(this.style.crop));
    else
        ctx.drawImage(this.opt, 0, 0, this.style.width || this.opt.width, this.style.height || this.opt.height);
    ctx.restore();
};
Rat.Text = function(){
    Rat.init(this, arguments);
};
Rat.Text.prototype.draw = function(ctx){
    Rat.style(ctx, this.style);
    if(this.style.fillStyle)
        ctx.fillText(this.opt, 0, 0, this.style.maxWidth || 999999999999999);
    if(this.style.strokeStyle)
        ctx.strokeText(this.opt, 0, 0, this.style.maxWidth || 9999999999999999);
    ctx.restore();
};
Rat.Text.prototype.measure = function(){
    var ctx = this.context.context;
    Rat.style(ctx, this.style);
    var w = ctx.measureText(this.opt).width;
    ctx.restore();
    return w;
};

Rat.notStyle = "translate0rotate0transform0scale".split(0);
Rat.style = function(ctx, style){
    ctx.save();
    style.origin && ctx.translate(style.origin[0], style.origin[1]);
    style.rotate && ctx.rotate(style.rotate);
    style.scale && ctx.scale.apply(ctx, style.scale);
    style.origin && ctx.translate(-style.origin[0], -style.origin[1]);
    style.translate && ctx.translate.apply(ctx, style.translate); // must it be before or after origin?
    style.transform && ctx.transform.apply(ctx, style.transform);
    Object.keys(style).forEach(function(key){
        if(!~Rat.notStyle.indexOf(key))
            ctx[key] = style[key];
    });
};
Rat.init = function(cls, arg){
    cls.opt = arg[0];
    cls.style = arg[1] || {};
    cls.context = arg[2];
    cls.draw(arg[2].context);
};
<|endoftext|>