<commit_before> var _ = require('underscore');
 var timer = require("grunt-timer");
 var jasmineCfg = require('./lib/build/tasks/jasmine.js');
 var duplicatedDependencies = require('./lib/build/tasks/shrinkwrap-duplicated-dependencies.js');

 var REQUIRED_NPM_VERSION = /2.14.[0-9]+/;
 var REQUIRED_NODE_VERSION = /0.10.[0-9]+/;
 var SHRINKWRAP_MODULES_TO_VALIDATE = [
  'backbone',
  'camshaft-reference',
  'carto',
  'cartodb.js',
  'cartocolor',
  'd3',
  'jquery',
  'leaflet',
  'perfect-scrollbar',
  'torque.js',
  'turbo-carto'
];

  /**
   *  CartoDB UI assets generation
   */

  module.exports = function(grunt) {

    if (timer) timer.init(grunt);

    function preFlight(done) {
      function checkVersion(cmd, versionRegExp, name, done) {
        require("child_process").exec(cmd, function (error, stdout, stderr) {
          var err = null;
          if (error) {
            err = 'failed to check version for ' + name;
          } else {
            if (!versionRegExp.test(stdout)) {
              err = 'installed ' + name + ' version does not match with required one ' + versionRegExp.toString() + " installed: " +  stdout;
            }
          }
          if (err) {
            grunt.log.fail(err);
          }
          done && done(err ? new Error(err): null);
        });
      }
      // checkVersion('npm -v', REQUIRED_NPM_VERSION, 'npm', done);
      // checkVersion('node -v', REQUIRED_NODE_VERSION, 'node', done);
    }

    preFlight(function (err) {
      if (err) {
        grunt.log.fail("############### /!\\ CAUTION /!\\ #################");
        grunt.log.fail("PLEASE installed required versions to build CARTO:\n- npm: " + REQUIRED_NPM_VERSION + "\n- node: " + REQUIRED_NODE_VERSION);
        grunt.log.fail("#################################################");
        process.exit(1);
      }
    });

    var duplicatedModules = duplicatedDependencies(require('./npm-shrinkwrap.json'), SHRINKWRAP_MODULES_TO_VALIDATE);
    if (duplicatedModules.length > 0) {
      grunt.log.fail("############### /!\\ CAUTION /!\\ #################");
      grunt.log.fail("Duplicated dependencies found in npm-shrinkwrap.json file.");
      grunt.log.fail(JSON.stringify(duplicatedModules, null, 4));
      grunt.log.fail("#################################################");
      process.exit(1);
    }

    var ROOT_ASSETS_DIR = './public/assets/';
    var ASSETS_DIR = './public/assets/<%= pkg.version %>';

    // use grunt --environment production
    var env = './config/grunt_' + (grunt.option('environment') || 'development') + '.json';
    if (grunt.file.exists(env)) {
      env = grunt.file.readJSON(env)
    } else {
      throw grunt.util.error(env +' file is missing! See '+ env +'.sample for how it should look like');
    }

    var aws = {};
    if (grunt.file.exists('./lib/build/grunt-aws.json')) {
      aws = grunt.file.readJSON('./lib/build/grunt-aws.json');
    }

    // Project configuration.
    grunt.initConfig({
      pkg: grunt.file.readJSON('package.json'),
      aws: aws,
      env: env,

      assets_dir: ASSETS_DIR,
      root_assets_dir: ROOT_ASSETS_DIR,

      // Concat task
      concat: require('./lib/build/tasks/concat').task(),

      // JST generation task
      jst: require('./lib/build/tasks/jst').task(),

      // Compass files generation
      compass: require('./lib/build/tasks/compass').task(),

      // Copy assets (stylesheets, javascripts, images...)
      copy: require('./lib/build/tasks/copy').task(grunt),

      // Watch actions
      watch: require('./lib/build/tasks/watch.js').task(),

      // Clean folders before other tasks
      clean: require('./lib/build/tasks/clean').task(),

      jasmine: jasmineCfg,

      s3: require('./lib/build/tasks/s3.js').task(),

      exorcise: require('./lib/build/tasks/exorcise.js').task(),

      uglify: require('./lib/build/tasks/uglify.js').task(),

      browserify: require('./lib/build/tasks/browserify.js').task(),

      connect: require('./lib/build/tasks/connect.js').task(),

      availabletasks: require('./lib/build/tasks/availabletasks.js').task()
    });

    // $ grunt availabletasks
    grunt.loadNpmTasks('grunt-available-tasks');

    // Load Grunt tasks
    require('load-grunt-tasks')(grunt, {
      pattern: ['grunt-*', '@*/grunt-*', '!grunt-timer']
    });

    require('./lib/build/tasks/manifest').register(grunt, ASSETS_DIR);

    // builds cdb
    grunt.registerTask('cdb', "builds cartodb.js", function() {
      var done = this.async();
      require("child_process").exec('make update_cdb', function (error, stdout, stderr) {
        if (error) {
          grunt.log.fail('cartodb.js not updated (due to '+ stdout +", "+ stderr +")");
        } else {
          grunt.log.ok('cartodb.js updated');
        }
        done();
      });
    });

    grunt.registerTask('invalidate', "invalidate cache", function() {
      var done = this.async();
      var url = require('url');
      var https = require('https');

      var options = url.parse(grunt.template.process('https://api.fastly.com/service/<%= aws.FASTLY_CARTODB_SERVICE %>/purge_all'));
      options['method'] = 'POST';
      options['headers'] = {
        'Fastly-Key': aws.FASTLY_API_KEY,
        'Content-Length': '0' //Disables chunked encoding
      };
      console.log(options);

      https.request(options, function(response) {
        if(response.statusCode == 200) {
          grunt.log.ok('CDN invalidated (fastly)');
        } else {
          grunt.log.error('CDN not invalidated (fastly), code: ' + response.statusCode)
        }
        done();
      }).on('error', function(e) {
        grunt.log.error('CDN not invalidated (fastly)');
        done();
      }).end();
    });

    grunt.registerTask('config', "generates assets config for current configuration", function() {
      // Set assets url for static assets in our app
      var config = grunt.template.process("cdb.config.set('assets_url', '<%= env.http_path_prefix %>/assets/<%= pkg.version %>');");
      config += grunt.template.process("\nconsole.log('cartodbui v<%= pkg.version %>');");
      grunt.file.write("lib/build/app_config.js", config);
    });

    grunt.registerTask('check_release', "checks release can be done", function() {
      if (env === 'development') {
        grunt.log.error("you can't release running development enviorment");
        return false;
      }
      grunt.log.ok("************************************************");
      grunt.log.ok(" you are going to deploy to " + env );
      grunt.log.ok("************************************************");
    });

    grunt.event.on('watch', function(action, filepath) {
      // configure copy vendor to only run on changed file
      var cfg = grunt.config.get('copy.vendor');
      if (filepath.indexOf(cfg.cwd) !== -1) {
        grunt.config('copy.vendor.src', filepath.replace(cfg.cwd, ''));
      } else {
        grunt.config('copy.vendor.src', []);
      }

      var COPY_PATHS = [
        'app',
        'js_core_cartodb',
        'js_client_cartodb',
        'js_core_cartodb3',
        'js_client_cartodb3',
        'js_test_spec_core_cartodb3',
        'js_test_spec_client_cartodb3',
        'js_test_jasmine_core_cartodb3',
        'js_test_jasmine_client_cartodb3'
      ];

      // configure copy paths to only run on changed files
      for (var j = 0, m = COPY_PATHS.length; j < m; ++j) {
        var copy_path = COPY_PATHS[j];
        var files = grunt.config.get('copy.' + copy_path + '.files');
        for (var i = 0, l = files.length; i < l; ++i) {
          var cfg = grunt.config.get('copy.' + copy_path + '.files.' + i);
          if (filepath.indexOf(cfg.cwd) !== -1) {
            grunt.config('copy.' + copy_path + '.files.' + i + '.src', filepath.replace(cfg.cwd, ''));
          } else {
            grunt.config('copy.' + copy_path + '.files.' + i + '.src', []);
          }
        }
      }
    });

    grunt.registerTask('setConfig', 'Set a config property', function(name, val) {
      grunt.config.set(name, val);
    });

    // still have to use this custom task because registerCmdTask outputs tons of warnings like:
    // path/to/some/ignored/files:0:0: File ignored because of your .eslintignore file. Use --no-ignore to override.
    grunt.registerTask('lint', 'lint source files', function () {
      var done = this.async();
      require('child_process').exec('(git diff --name-only --relative; git diff origin/master.. --name-only --relative) | grep \'\\.js\\?$\' | xargs node_modules/.bin/semistandard', function (error, stdout, stderr) {
        if (error) {
          grunt.log.fail(error);

          // Filter out lines that are ignored,
          // e.g. "src/foobar.js:0:0: File ignored because of your .eslintignore file. Use --no-ignore to override."
          grunt.log.fail(stdout.replace(/.+--no-ignore.+(\r?\n|\r)/g, ''));
          grunt.fail.warn('try `node_modules/.bin/semistandard --format src/filename.js` to auto-format code (you might still need to fix some things manually).');
        } else {
          grunt.log.ok('All linted files OK!');
          grunt.log.writelns('>> Note that files listed in .eslintignore are not linted');
        }
        done();
      });
    });

    registerCmdTask('npm-test', {cmd: 'npm', args: ['test']});
    registerCmdTask('npm-test-watch', {cmd: 'npm', args: ['run', 'test-watch']});

    grunt.registerTask('pre_client', [
      'copy:locale_core',
      'copy:locale_client',
      'copy:js_core_cartodb',
      'copy:js_client_cartodb',
      'copy:js_core_cartodb3',
      'copy:js_client_cartodb3',
      'copy:js_test_spec_core_cartodb3',
      'copy:js_test_spec_client_cartodb3',
      'copy:js_test_jasmine_core_cartodb3',
      'copy:js_test_jasmine_client_cartodb3'
    ]);

    grunt.registerTask('js', ['cdb', 'pre_client', 'browserify', 'concat:js', 'jst']);
    grunt.registerTask('pre_default', ['clean', 'config', 'js']);
    grunt.registerTask('test', '(CI env) Re-build JS files and run all tests. For manual testing use `grunt jasmine` directly', [
        'pre_default',
        'npm-test',
        'jasmine',
        'lint'
      ]);
    grunt.registerTask('editor3', [
      'browserify:vendor_editor3',
      'browserify:common_editor3',
      'browserify:editor3',
      'browserify:public_editor3'
    ]);
    grunt.registerTask('css_editor_3', [
      'copy:cartofonts',
      'copy:iconfont',
      'copy:cartoassets',
      'copy:perfect_scrollbar',
      'copy:colorpicker',
      'copy:deep_insights',
      'copy:cartodbjs_v4'
    ]);
    grunt.registerTask('css', ['copy:vendor', 'css_editor_3', 'copy:app', 'compass', 'concat:css']);
    grunt.registerTask('default', ['pre_default', 'css', 'manifest']);
    grunt.registerTask('minimize', ['default', 'copy:js', 'exorcise', 'uglify']);
    grunt.registerTask('release', ['check_release', 'minimize', 's3', 'invalidate']);
    grunt.registerTask('build-jasmine-specrunners', _
      .chain(jasmineCfg)
      .keys()
      .map(function (name) {
        return ['jasmine', name, 'build'].join(':');
      })
      .value());
    grunt.registerTask('dev', 'Typical task for frontend development (watch JS/CSS changes)', [
      'setConfig:env.browserify_watch:true',
      'browserify',
      'build-jasmine-specrunners',
      'connect',
      'watch']);
    grunt.registerTask('sourcemaps',
      'generate sourcemaps, to be used w/ trackjs.com for bughunting', [
        'setConfig:assets_dir:./tmp/sourcemaps',
        'config',
        'js',
        'copy:js',
        'exorcise',
        'uglify'
      ]);

    /**
     * Delegate task to commandline.
     * @param {String} name - If taskname starts with npm it's run a npm script (i.e. `npm run foobar`
     * @param {Object} d - d as in data
     * @param {Array} d.args - arguments to pass to the d.cmd
     * @param {String} [d.cmd = process.execPath]
     * @param {String} [d.desc = ''] - description
     * @param {...string} args space-separated arguments passed to the cmd
     */
    function registerCmdTask (name, opts) {
      opts = _.extend({
        cmd: process.execPath,
        desc: '',
        args: []
      }, opts);
      grunt.registerTask(name, opts.desc, function () {
        // adapted from http://stackoverflow.com/a/24796749
        var done = this.async();
        grunt.util.spawn({
          cmd: opts.cmd,
          args: opts.args,
          opts: { stdio: 'inherit' }
        }, done);
      });
    }
  };
<commit_msg>Gruntfile.js<commit_after> var _ = require('underscore');
 var timer = require("grunt-timer");
 var jasmineCfg = require('./lib/build/tasks/jasmine.js');
 var duplicatedDependencies = require('./lib/build/tasks/shrinkwrap-duplicated-dependencies.js');

 var REQUIRED_NPM_VERSION = /2.14.[0-9]+/;
 var REQUIRED_NODE_VERSION = /0.10.[0-9]+/;
 var SHRINKWRAP_MODULES_TO_VALIDATE = [
  'backbone',
  'camshaft-reference',
  'carto',
  'cartodb.js',
  'cartocolor',
  'd3',
  'jquery',
  'leaflet',
  'perfect-scrollbar',
  'torque.js',
  'turbo-carto'
];

  /**
   *  CartoDB UI assets generation
   */

  module.exports = function(grunt) {

    if (timer) timer.init(grunt);

    function preFlight(done) {
      function checkVersion(cmd, versionRegExp, name, done) {
        require("child_process").exec(cmd, function (error, stdout, stderr) {
          var err = null;
          if (error) {
            err = 'failed to check version for ' + name;
          } else {
            if (!versionRegExp.test(stdout)) {
              err = 'installed ' + name + ' version does not match with required one ' + versionRegExp.toString() + " installed: " +  stdout;
            }
          }
          if (err) {
            grunt.log.fail(err);
          }
          done && done(err ? new Error(err): null);
        });
      }
      checkVersion('npm -v', REQUIRED_NPM_VERSION, 'npm', done);
      checkVersion('node -v', REQUIRED_NODE_VERSION, 'node', done);
    }

    preFlight(function (err) {
      if (err) {
        grunt.log.fail("############### /!\\ CAUTION /!\\ #################");
        grunt.log.fail("PLEASE installed required versions to build CARTO:\n- npm: " + REQUIRED_NPM_VERSION + "\n- node: " + REQUIRED_NODE_VERSION);
        grunt.log.fail("#################################################");
        process.exit(1);
      }
    });

    var duplicatedModules = duplicatedDependencies(require('./npm-shrinkwrap.json'), SHRINKWRAP_MODULES_TO_VALIDATE);
    if (duplicatedModules.length > 0) {
      grunt.log.fail("############### /!\\ CAUTION /!\\ #################");
      grunt.log.fail("Duplicated dependencies found in npm-shrinkwrap.json file.");
      grunt.log.fail(JSON.stringify(duplicatedModules, null, 4));
      grunt.log.fail("#################################################");
      process.exit(1);
    }

    var ROOT_ASSETS_DIR = './public/assets/';
    var ASSETS_DIR = './public/assets/<%= pkg.version %>';

    // use grunt --environment production
    var env = './config/grunt_' + (grunt.option('environment') || 'development') + '.json';
    if (grunt.file.exists(env)) {
      env = grunt.file.readJSON(env)
    } else {
      throw grunt.util.error(env +' file is missing! See '+ env +'.sample for how it should look like');
    }

    var aws = {};
    if (grunt.file.exists('./lib/build/grunt-aws.json')) {
      aws = grunt.file.readJSON('./lib/build/grunt-aws.json');
    }

    // Project configuration.
    grunt.initConfig({
      pkg: grunt.file.readJSON('package.json'),
      aws: aws,
      env: env,

      assets_dir: ASSETS_DIR,
      root_assets_dir: ROOT_ASSETS_DIR,

      // Concat task
      concat: require('./lib/build/tasks/concat').task(),

      // JST generation task
      jst: require('./lib/build/tasks/jst').task(),

      // Compass files generation
      compass: require('./lib/build/tasks/compass').task(),

      // Copy assets (stylesheets, javascripts, images...)
      copy: require('./lib/build/tasks/copy').task(grunt),

      // Watch actions
      watch: require('./lib/build/tasks/watch.js').task(),

      // Clean folders before other tasks
      clean: require('./lib/build/tasks/clean').task(),

      jasmine: jasmineCfg,

      s3: require('./lib/build/tasks/s3.js').task(),

      exorcise: require('./lib/build/tasks/exorcise.js').task(),

      uglify: require('./lib/build/tasks/uglify.js').task(),

      browserify: require('./lib/build/tasks/browserify.js').task(),

      connect: require('./lib/build/tasks/connect.js').task(),

      availabletasks: require('./lib/build/tasks/availabletasks.js').task()
    });

    // $ grunt availabletasks
    grunt.loadNpmTasks('grunt-available-tasks');

    // Load Grunt tasks
    require('load-grunt-tasks')(grunt, {
      pattern: ['grunt-*', '@*/grunt-*', '!grunt-timer']
    });

    require('./lib/build/tasks/manifest').register(grunt, ASSETS_DIR);

    // builds cdb
    grunt.registerTask('cdb', "builds cartodb.js", function() {
      var done = this.async();
      require("child_process").exec('make update_cdb', function (error, stdout, stderr) {
        if (error) {
          grunt.log.fail('cartodb.js not updated (due to '+ stdout +", "+ stderr +")");
        } else {
          grunt.log.ok('cartodb.js updated');
        }
        done();
      });
    });

    grunt.registerTask('invalidate', "invalidate cache", function() {
      var done = this.async();
      var url = require('url');
      var https = require('https');

      var options = url.parse(grunt.template.process('https://api.fastly.com/service/<%= aws.FASTLY_CARTODB_SERVICE %>/purge_all'));
      options['method'] = 'POST';
      options['headers'] = {
        'Fastly-Key': aws.FASTLY_API_KEY,
        'Content-Length': '0' //Disables chunked encoding
      };
      console.log(options);

      https.request(options, function(response) {
        if(response.statusCode == 200) {
          grunt.log.ok('CDN invalidated (fastly)');
        } else {
          grunt.log.error('CDN not invalidated (fastly), code: ' + response.statusCode)
        }
        done();
      }).on('error', function(e) {
        grunt.log.error('CDN not invalidated (fastly)');
        done();
      }).end();
    });

    grunt.registerTask('config', "generates assets config for current configuration", function() {
      // Set assets url for static assets in our app
      var config = grunt.template.process("cdb.config.set('assets_url', '<%= env.http_path_prefix %>/assets/<%= pkg.version %>');");
      config += grunt.template.process("\nconsole.log('cartodbui v<%= pkg.version %>');");
      grunt.file.write("lib/build/app_config.js", config);
    });

    grunt.registerTask('check_release', "checks release can be done", function() {
      if (env === 'development') {
        grunt.log.error("you can't release running development enviorment");
        return false;
      }
      grunt.log.ok("************************************************");
      grunt.log.ok(" you are going to deploy to " + env );
      grunt.log.ok("************************************************");
    });

    grunt.event.on('watch', function(action, filepath) {
      // configure copy vendor to only run on changed file
      var cfg = grunt.config.get('copy.vendor');
      if (filepath.indexOf(cfg.cwd) !== -1) {
        grunt.config('copy.vendor.src', filepath.replace(cfg.cwd, ''));
      } else {
        grunt.config('copy.vendor.src', []);
      }

      var COPY_PATHS = [
        'app',
        'js_core_cartodb',
        'js_client_cartodb',
        'js_core_cartodb3',
        'js_client_cartodb3',
        'js_test_spec_core_cartodb3',
        'js_test_spec_client_cartodb3',
        'js_test_jasmine_core_cartodb3',
        'js_test_jasmine_client_cartodb3'
      ];

      // configure copy paths to only run on changed files
      for (var j = 0, m = COPY_PATHS.length; j < m; ++j) {
        var copy_path = COPY_PATHS[j];
        var files = grunt.config.get('copy.' + copy_path + '.files');
        for (var i = 0, l = files.length; i < l; ++i) {
          var cfg = grunt.config.get('copy.' + copy_path + '.files.' + i);
          if (filepath.indexOf(cfg.cwd) !== -1) {
            grunt.config('copy.' + copy_path + '.files.' + i + '.src', filepath.replace(cfg.cwd, ''));
          } else {
            grunt.config('copy.' + copy_path + '.files.' + i + '.src', []);
          }
        }
      }
    });

    grunt.registerTask('setConfig', 'Set a config property', function(name, val) {
      grunt.config.set(name, val);
    });

    // still have to use this custom task because registerCmdTask outputs tons of warnings like:
    // path/to/some/ignored/files:0:0: File ignored because of your .eslintignore file. Use --no-ignore to override.
    grunt.registerTask('lint', 'lint source files', function () {
      var done = this.async();
      require('child_process').exec('(git diff --name-only --relative; git diff origin/master.. --name-only --relative) | grep \'\\.js\\?$\' | xargs node_modules/.bin/semistandard', function (error, stdout, stderr) {
        if (error) {
          grunt.log.fail(error);

          // Filter out lines that are ignored,
          // e.g. "src/foobar.js:0:0: File ignored because of your .eslintignore file. Use --no-ignore to override."
          grunt.log.fail(stdout.replace(/.+--no-ignore.+(\r?\n|\r)/g, ''));
          grunt.fail.warn('try `node_modules/.bin/semistandard --format src/filename.js` to auto-format code (you might still need to fix some things manually).');
        } else {
          grunt.log.ok('All linted files OK!');
          grunt.log.writelns('>> Note that files listed in .eslintignore are not linted');
        }
        done();
      });
    });

    registerCmdTask('npm-test', {cmd: 'npm', args: ['test']});
    registerCmdTask('npm-test-watch', {cmd: 'npm', args: ['run', 'test-watch']});

    grunt.registerTask('pre_client', [
      'copy:locale_core',
      'copy:locale_client',
      'copy:js_core_cartodb',
      'copy:js_client_cartodb',
      'copy:js_core_cartodb3',
      'copy:js_client_cartodb3',
      'copy:js_test_spec_core_cartodb3',
      'copy:js_test_spec_client_cartodb3',
      'copy:js_test_jasmine_core_cartodb3',
      'copy:js_test_jasmine_client_cartodb3'
    ]);

    grunt.registerTask('js', ['cdb', 'pre_client', 'browserify', 'concat:js', 'jst']);
    grunt.registerTask('pre_default', ['clean', 'config', 'js']);
    grunt.registerTask('test', '(CI env) Re-build JS files and run all tests. For manual testing use `grunt jasmine` directly', [
        'pre_default',
        'npm-test',
        'jasmine',
        'lint'
      ]);
    grunt.registerTask('editor3', [
      'browserify:vendor_editor3',
      'browserify:common_editor3',
      'browserify:editor3',
      'browserify:public_editor3'
    ]);
    grunt.registerTask('css_editor_3', [
      'copy:cartofonts',
      'copy:iconfont',
      'copy:cartoassets',
      'copy:perfect_scrollbar',
      'copy:colorpicker',
      'copy:deep_insights',
      'copy:cartodbjs_v4'
    ]);
    grunt.registerTask('css', ['copy:vendor', 'css_editor_3', 'copy:app', 'compass', 'concat:css']);
    grunt.registerTask('default', ['pre_default', 'css', 'manifest']);
    grunt.registerTask('minimize', ['default', 'copy:js', 'exorcise', 'uglify']);
    grunt.registerTask('release', ['check_release', 'minimize', 's3', 'invalidate']);
    grunt.registerTask('build-jasmine-specrunners', _
      .chain(jasmineCfg)
      .keys()
      .map(function (name) {
        return ['jasmine', name, 'build'].join(':');
      })
      .value());
    grunt.registerTask('dev', 'Typical task for frontend development (watch JS/CSS changes)', [
      'setConfig:env.browserify_watch:true',
      'browserify',
      'build-jasmine-specrunners',
      'connect',
      'watch']);
    grunt.registerTask('sourcemaps',
      'generate sourcemaps, to be used w/ trackjs.com for bughunting', [
        'setConfig:assets_dir:./tmp/sourcemaps',
        'config',
        'js',
        'copy:js',
        'exorcise',
        'uglify'
      ]);

    /**
     * Delegate task to commandline.
     * @param {String} name - If taskname starts with npm it's run a npm script (i.e. `npm run foobar`
     * @param {Object} d - d as in data
     * @param {Array} d.args - arguments to pass to the d.cmd
     * @param {String} [d.cmd = process.execPath]
     * @param {String} [d.desc = ''] - description
     * @param {...string} args space-separated arguments passed to the cmd
     */
    function registerCmdTask (name, opts) {
      opts = _.extend({
        cmd: process.execPath,
        desc: '',
        args: []
      }, opts);
      grunt.registerTask(name, opts.desc, function () {
        // adapted from http://stackoverflow.com/a/24796749
        var done = this.async();
        grunt.util.spawn({
          cmd: opts.cmd,
          args: opts.args,
          opts: { stdio: 'inherit' }
        }, done);
      });
    }
  };
<|endoftext|>


<commit_before>module.exports = function(grunt) {
  "use strict";

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    jshint: {
      all: [
        'public/*.js',
        'public/js/*.js',
        'server/*.js',
        'Gruntfile.js'
      ],
      options: {
        jshintrc: true
      }
    },
    watch: {
      files: ['public/**/*', 'server/**/*', '!**/node_modules/**'],
      tasks: ['default', 'express'],
      options: {
        spawn: false
      }
    },
    express: {
      web: {
        options: {
          script: 'server/index.js',
          port: 8443
        }
      }
    }
  });

  // Load NPM Tasks
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-express-server');

  // Register task(s).
  grunt.registerTask('default', ['jshint']);
  grunt.registerTask('serve', ['default', 'express', 'watch']);
};
<commit_msg>Don't restart server everytime database changes<commit_after>module.exports = function(grunt) {
  "use strict";

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    jshint: {
      all: [
        'public/*.js',
        'public/js/*.js',
        'server/*.js',
        'Gruntfile.js'
      ],
      options: {
        jshintrc: true
      }
    },
    watch: {
      files: ['public/**/*', 'server/**/*', '!server/db.json', '!**/node_modules/**'],
      tasks: ['default', 'express'],
      options: {
        spawn: false
      }
    },
    express: {
      web: {
        options: {
          script: 'server/index.js',
          port: 8443
        }
      }
    }
  });

  // Load NPM Tasks
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-express-server');

  // Register task(s).
  grunt.registerTask('default', ['jshint']);
  grunt.registerTask('serve', ['default', 'express', 'watch']);
};
<|endoftext|>


<commit_before>module.exports = grunt => {
    const JS_INCLUDE = [ '**/*.js', '!node_modules/**', '!test/**/*.spec.js', '!public/js/*-bundle.js', '!public/js/*.min.js' ];
    const pkg = grunt.file.readJSON( 'package.json' );
    const path = require( 'path' );
    const nodeSass = require( 'node-sass' );

    require( 'time-grunt' )( grunt );
    require( 'load-grunt-tasks' )( grunt );

    grunt.config.init( {
        concurrent: {
            develop: {
                tasks: [ 'nodemon', 'watch' ],
                options: {
                    logConcurrentOutput: true
                }
            }
        },
        nodemon: {
            dev: {
                script: 'app.js',
                options: {
                    watch: [ 'app', 'config' ],
                    //nodeArgs: [ '--debug' ],
                    env: {
                        NODE_ENV: 'development',
                        DEBUG: '*, -express:*, -send, -compression, -body-parser:*, -puppeteer:*'
                    }
                }
            }
        },
        sass: {
            options: {
                implementation: nodeSass,
                functions: {
                    'base64-url($mimeType, $data)': function( mimeType, data ) {
                        const base64 = new Buffer( data.getValue() ).toString( 'base64' );
                        const urlString = `url("data:${mimeType.getValue()};base64,${base64}")`;
                        return nodeSass.types.String( urlString );
                    }
                }
            },
            compile: {
                cwd: 'app/views/styles',
                dest: 'public/css',
                expand: true,
                outputStyle: 'compressed',
                src: '**/*.scss',
                ext: '.css',
                flatten: true,
                extDot: 'last'
            }
        },
        watch: {
            config: {
                files: [ 'config/*.json' ],
                tasks: [ 'client-config-file:create' ]
            },
            sass: {
                files: [ 'app/views/styles/**/*.scss', 'widget/**/*.scss', '!app/views/styles/component/_system_variables.scss' ],
                tasks: [ 'sass' ],
                options: {
                    spawn: false,
                    livereload: true
                }
            },
            jade: {
                files: [ 'app/views/**/*.pug' ],
                options: {
                    spawn: false,
                    livereload: true
                }
            },
            language: {
                files: [ 'app/views/**/*.pug', 'app/controllers/**/*.js', 'app/models/**/*.js', 'public/js/src/**/*.js' ],
                tasks: [ 'shell:translation', 'i18next' ]
            },
            js: {
                files: [ 'public/js/src/**/*.js', 'widget/**/*.js' ],
                tasks: [ 'js-dev' ],
                options: {
                    spawn: false,
                    livereload: true
                }
            }
        },
        shell: {
            translation: {
                command: [
                    'cd locales',
                    'gulp',
                    'cd ..'
                ].join( '&&' )
            },
            ie11polyfill: {
                command: 'curl "https://cdn.polyfill.io/v2/polyfill.min.js?ua=ie%2F11.0.0&features=es2015%2Ces2016%2Ces2017%2Ces2018%2Cdefault-3.6" -o "public/js/ie11-polyfill.min.js"',
            }
        },
        jsbeautifier: {
            test: {
                src: JS_INCLUDE,
                options: {
                    config: './.jsbeautifyrc',
                    mode: 'VERIFY_ONLY'
                }
            },
            fix: {
                src: JS_INCLUDE,
                options: {
                    config: './.jsbeautifyrc'
                }
            }
        },
        eslint: {
            all: JS_INCLUDE,
        },
        // test server JS
        mochaTest: {
            all: {
                options: {
                    reporter: 'dot'
                },
                src: [ 'test/server/**/*.spec.js' ]
            },
            account: {
                src: [ 'test/server/account-*.spec.js' ]
            }
        },
        // test client JS
        karma: {
            options: {
                singleRun: true,
                reporters: [ 'dots' ],
                configFile: 'test/client/config/karma.conf.js'
            },
            headless: {
                browsers: [ 'ChromeHeadless' ]
            },
            browsers: {
                browsers: [ 'Chrome', 'ChromeCanary', 'Firefox', 'Opera' /*,'Safari'*/ ],
            }
        },
        browserify: {
            development: {
                files: {
                    'public/js/enketo-webform-dev-bundle.js': [ 'public/js/src/main-webform.js' ],
                    'public/js/enketo-webform-edit-dev-bundle.js': [ 'public/js/src/main-webform-edit.js' ],
                    'public/js/enketo-webform-view-dev-bundle.js': [ 'public/js/src/main-webform-view.js' ],
                    'public/js/enketo-offline-fallback-dev-bundle.js': [ 'public/js/src/main-offline-fallback.js' ]
                },
                options: {
                    browserifyOptions: {
                        debug: true
                    }
                },
            },
            production: {
                files: {
                    'public/js/enketo-webform-bundle.js': [ 'public/js/src/main-webform.js' ],
                    'public/js/enketo-webform-edit-bundle.js': [ 'public/js/src/main-webform-edit.js' ],
                    'public/js/enketo-webform-view-bundle.js': [ 'public/js/src/main-webform-view.js' ],
                    'public/js/enketo-offline-fallback-bundle.js': [ 'public/js/src/main-offline-fallback.js' ]
                },
            },
            options: {
                // ensure that several placeholder modules in **enketo-core** are overridden
                transform: [
                    [ 'aliasify', {
                        aliases: pkg.aliasify.aliases,
                        global: true
                    } ]
                ]
            },
        },
        uglify: {
            all: {
                files: {
                    'public/js/enketo-webform-bundle.min.js': [ 'public/js/enketo-webform-bundle.js' ],
                    'public/js/enketo-webform-edit-bundle.min.js': [ 'public/js/enketo-webform-edit-bundle.js' ],
                    'public/js/enketo-webform-view-bundle.min.js': [ 'public/js/enketo-webform-view-bundle.js' ],
                    'public/js/enketo-offline-fallback-bundle.min.js': [ 'public/js/enketo-offline-fallback-bundle.js' ],
                },
            },
        },
        env: {
            develop: {
                NODE_ENV: 'develop'
            },
            test: {
                NODE_ENV: 'test'
            },
            production: {
                NODE_ENV: 'production'
            }
        },
        i18next: {
            locales: {
                cwd: 'locales/',
                expand: true,
                src: [ '*/' ],
                include: [ '**/translation.json', '**/translation-additions.json' ],
                rename( dest, src ) {
                    return `${dest + src}translation-combined.json`;
                },
                dest: 'locales/'
            }
        }
    } );

    grunt.registerTask( 'client-config-file', 'Temporary client-config file', task => {
        const CLIENT_CONFIG_PATH = 'public/temp-client-config.json';
        if ( task === 'create' ) {
            const config = require( './app/models/config-model' );
            grunt.file.write( CLIENT_CONFIG_PATH, JSON.stringify( config.client ) );
            grunt.log.writeln( `File ${CLIENT_CONFIG_PATH} created` );
        } else if ( task === 'remove' ) {
            grunt.file.delete( CLIENT_CONFIG_PATH );
            grunt.log.writeln( `File ${CLIENT_CONFIG_PATH} removed` );
        }
    } );

    grunt.registerTask( 'system-sass-variables', 'Creating _system_variables.scss', () => {
        const SYSTEM_SASS_VARIABLES_PATH = 'app/views/styles/component/_system_variables.scss';
        const config = require( './app/models/config-model' );
        grunt.file.write( SYSTEM_SASS_VARIABLES_PATH, `$base-path: "${config.server[ 'base path' ]}";` );
        grunt.log.writeln( `File ${SYSTEM_SASS_VARIABLES_PATH} created` );
    } );

    grunt.registerTask( 'widgets', 'generate widget reference files', () => {
        const WIDGETS_JS_LOC = 'public/js/';
        const WIDGETS_JS = `${WIDGETS_JS_LOC}widgets.js`;
        const WIDGETS_SASS_LOC = 'app/views/styles/component/';
        const WIDGETS_SASS = `${WIDGETS_SASS_LOC}_widgets.scss`;
        const PRE = '// This file is automatically generated with `grunt widgets`\n';
        const widgets = require( './app/models/config-model' ).server.widgets;
        const coreWidgets = require( './public/js/src/module/core-widgets' );
        const paths = Object.keys( widgets ).map( key => coreWidgets[ widgets[ key ] ] || widgets[ key ] );
        let content = `${PRE}'use strict';\n\nmodule.exports = [\n    ${paths.map( p => grunt.file.exists( WIDGETS_JS_LOC, `${p}.js` ) ? `require( '${p}' )` : `//${p} not found` ).join( ',\n    ' )}\n];\n`;
        grunt.file.write( WIDGETS_JS, content );
        grunt.log.writeln( `File ${WIDGETS_JS} created` );
        content = `${PRE +
    paths.map( p => {
        p = path.join( '../../', p );
        return grunt.file.exists( WIDGETS_SASS_LOC, `${p}.scss` ) ? `@import "${p}"` : `//${p} not found`;
    } ).join( ';\n' )};`;
        grunt.file.write( WIDGETS_SASS, content );
        grunt.log.writeln( `File ${WIDGETS_SASS} created` );
    } );

    grunt.registerTask( 'default', [ 'shell:ie11polyfill', 'i18next', 'widgets', 'css', 'js', 'uglify' ] );
    grunt.registerTask( 'js', [ 'client-config-file:create', 'widgets', 'browserify:production' ] );
    grunt.registerTask( 'js-dev', [ 'client-config-file:create', 'widgets', 'browserify:development' ] );
    grunt.registerTask( 'css', [ 'system-sass-variables:create', 'sass' ] );
    grunt.registerTask( 'test', [ 'env:test', 'js', 'css', 'mochaTest:all', 'karma:headless', 'jsbeautifier:test', 'eslint' ] );
    grunt.registerTask( 'test-browser', [ 'env:test', 'css', 'client-config-file:create', 'karma:browsers' ] );
    grunt.registerTask( 'develop', [ 'env:develop', 'shell:ie11polyfill', 'i18next', 'js-dev', 'css', 'concurrent:develop' ] );
    grunt.registerTask( 'test-and-build', [ 'env:test', 'mochaTest:all', 'karma:headless', 'env:production', 'default' ] );
};
<commit_msg>changed: clean css folder before compiling css,<commit_after>module.exports = grunt => {
    const JS_INCLUDE = [ '**/*.js', '!node_modules/**', '!test/**/*.spec.js', '!public/js/*-bundle.js', '!public/js/*.min.js' ];
    const pkg = grunt.file.readJSON( 'package.json' );
    const path = require( 'path' );
    const nodeSass = require( 'node-sass' );

    require( 'time-grunt' )( grunt );
    require( 'load-grunt-tasks' )( grunt );

    grunt.config.init( {
        concurrent: {
            develop: {
                tasks: [ 'nodemon', 'watch' ],
                options: {
                    logConcurrentOutput: true
                }
            }
        },
        nodemon: {
            dev: {
                script: 'app.js',
                options: {
                    watch: [ 'app', 'config' ],
                    //nodeArgs: [ '--debug' ],
                    env: {
                        NODE_ENV: 'development',
                        DEBUG: '*, -express:*, -send, -compression, -body-parser:*, -puppeteer:*'
                    }
                }
            }
        },
        sass: {
            options: {
                implementation: nodeSass,
                functions: {
                    'base64-url($mimeType, $data)': function( mimeType, data ) {
                        const base64 = new Buffer( data.getValue() ).toString( 'base64' );
                        const urlString = `url("data:${mimeType.getValue()};base64,${base64}")`;
                        return nodeSass.types.String( urlString );
                    }
                }
            },
            compile: {
                cwd: 'app/views/styles',
                dest: 'public/css',
                expand: true,
                outputStyle: 'compressed',
                src: '**/*.scss',
                ext: '.css',
                flatten: true,
                extDot: 'last'
            }
        },
        watch: {
            config: {
                files: [ 'config/*.json' ],
                tasks: [ 'client-config-file:create' ]
            },
            sass: {
                files: [ 'app/views/styles/**/*.scss', 'widget/**/*.scss', '!app/views/styles/component/_system_variables.scss' ],
                tasks: [ 'sass' ],
                options: {
                    spawn: false,
                    livereload: true
                }
            },
            jade: {
                files: [ 'app/views/**/*.pug' ],
                options: {
                    spawn: false,
                    livereload: true
                }
            },
            language: {
                files: [ 'app/views/**/*.pug', 'app/controllers/**/*.js', 'app/models/**/*.js', 'public/js/src/**/*.js' ],
                tasks: [ 'shell:translation', 'i18next' ]
            },
            js: {
                files: [ 'public/js/src/**/*.js', 'widget/**/*.js' ],
                tasks: [ 'js-dev' ],
                options: {
                    spawn: false,
                    livereload: true
                }
            }
        },
        shell: {
            translation: {
                command: [
                    'cd locales',
                    'gulp',
                    'cd ..'
                ].join( '&&' )
            },
            ie11polyfill: {
                command: 'curl "https://cdn.polyfill.io/v2/polyfill.min.js?ua=ie%2F11.0.0&features=es2015%2Ces2016%2Ces2017%2Ces2018%2Cdefault-3.6" -o "public/js/ie11-polyfill.min.js"',
            },
            'clean-css': {
                command: 'rm -f public/css/*'
            }
        },
        jsbeautifier: {
            test: {
                src: JS_INCLUDE,
                options: {
                    config: './.jsbeautifyrc',
                    mode: 'VERIFY_ONLY'
                }
            },
            fix: {
                src: JS_INCLUDE,
                options: {
                    config: './.jsbeautifyrc'
                }
            }
        },
        eslint: {
            all: JS_INCLUDE,
        },
        // test server JS
        mochaTest: {
            all: {
                options: {
                    reporter: 'dot'
                },
                src: [ 'test/server/**/*.spec.js' ]
            },
            account: {
                src: [ 'test/server/account-*.spec.js' ]
            }
        },
        // test client JS
        karma: {
            options: {
                singleRun: true,
                reporters: [ 'dots' ],
                configFile: 'test/client/config/karma.conf.js'
            },
            headless: {
                browsers: [ 'ChromeHeadless' ]
            },
            browsers: {
                browsers: [ 'Chrome', 'ChromeCanary', 'Firefox', 'Opera' /*,'Safari'*/ ],
            }
        },
        browserify: {
            development: {
                files: {
                    'public/js/enketo-webform-dev-bundle.js': [ 'public/js/src/main-webform.js' ],
                    'public/js/enketo-webform-edit-dev-bundle.js': [ 'public/js/src/main-webform-edit.js' ],
                    'public/js/enketo-webform-view-dev-bundle.js': [ 'public/js/src/main-webform-view.js' ],
                    'public/js/enketo-offline-fallback-dev-bundle.js': [ 'public/js/src/main-offline-fallback.js' ]
                },
                options: {
                    browserifyOptions: {
                        debug: true
                    }
                },
            },
            production: {
                files: {
                    'public/js/enketo-webform-bundle.js': [ 'public/js/src/main-webform.js' ],
                    'public/js/enketo-webform-edit-bundle.js': [ 'public/js/src/main-webform-edit.js' ],
                    'public/js/enketo-webform-view-bundle.js': [ 'public/js/src/main-webform-view.js' ],
                    'public/js/enketo-offline-fallback-bundle.js': [ 'public/js/src/main-offline-fallback.js' ]
                },
            },
            options: {
                // ensure that several placeholder modules in **enketo-core** are overridden
                transform: [
                    [ 'aliasify', {
                        aliases: pkg.aliasify.aliases,
                        global: true
                    } ]
                ]
            },
        },
        uglify: {
            all: {
                files: {
                    'public/js/enketo-webform-bundle.min.js': [ 'public/js/enketo-webform-bundle.js' ],
                    'public/js/enketo-webform-edit-bundle.min.js': [ 'public/js/enketo-webform-edit-bundle.js' ],
                    'public/js/enketo-webform-view-bundle.min.js': [ 'public/js/enketo-webform-view-bundle.js' ],
                    'public/js/enketo-offline-fallback-bundle.min.js': [ 'public/js/enketo-offline-fallback-bundle.js' ],
                },
            },
        },
        env: {
            develop: {
                NODE_ENV: 'develop'
            },
            test: {
                NODE_ENV: 'test'
            },
            production: {
                NODE_ENV: 'production'
            }
        },
        i18next: {
            locales: {
                cwd: 'locales/',
                expand: true,
                src: [ '*/' ],
                include: [ '**/translation.json', '**/translation-additions.json' ],
                rename( dest, src ) {
                    return `${dest + src}translation-combined.json`;
                },
                dest: 'locales/'
            }
        }
    } );

    grunt.registerTask( 'client-config-file', 'Temporary client-config file', task => {
        const CLIENT_CONFIG_PATH = 'public/temp-client-config.json';
        if ( task === 'create' ) {
            const config = require( './app/models/config-model' );
            grunt.file.write( CLIENT_CONFIG_PATH, JSON.stringify( config.client ) );
            grunt.log.writeln( `File ${CLIENT_CONFIG_PATH} created` );
        } else if ( task === 'remove' ) {
            grunt.file.delete( CLIENT_CONFIG_PATH );
            grunt.log.writeln( `File ${CLIENT_CONFIG_PATH} removed` );
        }
    } );

    grunt.registerTask( 'system-sass-variables', 'Creating _system_variables.scss', () => {
        const SYSTEM_SASS_VARIABLES_PATH = 'app/views/styles/component/_system_variables.scss';
        const config = require( './app/models/config-model' );
        grunt.file.write( SYSTEM_SASS_VARIABLES_PATH, `$base-path: "${config.server[ 'base path' ]}";` );
        grunt.log.writeln( `File ${SYSTEM_SASS_VARIABLES_PATH} created` );
    } );

    grunt.registerTask( 'widgets', 'generate widget reference files', () => {
        const WIDGETS_JS_LOC = 'public/js/';
        const WIDGETS_JS = `${WIDGETS_JS_LOC}widgets.js`;
        const WIDGETS_SASS_LOC = 'app/views/styles/component/';
        const WIDGETS_SASS = `${WIDGETS_SASS_LOC}_widgets.scss`;
        const PRE = '// This file is automatically generated with `grunt widgets`\n';
        const widgets = require( './app/models/config-model' ).server.widgets;
        const coreWidgets = require( './public/js/src/module/core-widgets' );
        const paths = Object.keys( widgets ).map( key => coreWidgets[ widgets[ key ] ] || widgets[ key ] );
        let content = `${PRE}'use strict';\n\nmodule.exports = [\n    ${paths.map( p => grunt.file.exists( WIDGETS_JS_LOC, `${p}.js` ) ? `require( '${p}' )` : `//${p} not found` ).join( ',\n    ' )}\n];\n`;
        grunt.file.write( WIDGETS_JS, content );
        grunt.log.writeln( `File ${WIDGETS_JS} created` );
        content = `${PRE +
    paths.map( p => {
        p = path.join( '../../', p );
        return grunt.file.exists( WIDGETS_SASS_LOC, `${p}.scss` ) ? `@import "${p}"` : `//${p} not found`;
    } ).join( ';\n' )};`;
        grunt.file.write( WIDGETS_SASS, content );
        grunt.log.writeln( `File ${WIDGETS_SASS} created` );
    } );

    grunt.registerTask( 'default', [ 'shell:ie11polyfill', 'i18next', 'widgets', 'css', 'js', 'uglify' ] );
    grunt.registerTask( 'js', [ 'client-config-file:create', 'widgets', 'browserify:production' ] );
    grunt.registerTask( 'js-dev', [ 'client-config-file:create', 'widgets', 'browserify:development' ] );
    grunt.registerTask( 'css', [ 'shell:clean-css', 'system-sass-variables:create', 'sass' ] );
    grunt.registerTask( 'test', [ 'env:test', 'js', 'css', 'mochaTest:all', 'karma:headless', 'jsbeautifier:test', 'eslint' ] );
    grunt.registerTask( 'test-browser', [ 'env:test', 'css', 'client-config-file:create', 'karma:browsers' ] );
    grunt.registerTask( 'develop', [ 'env:develop', 'shell:ie11polyfill', 'i18next', 'js-dev', 'css', 'concurrent:develop' ] );
    grunt.registerTask( 'test-and-build', [ 'env:test', 'mochaTest:all', 'karma:headless', 'env:production', 'default' ] );
};
<|endoftext|>


<commit_before>'use strict';

module.exports = function (grunt) {
  // load all grunt tasks
  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

  // configurable paths
  var uikitConfig = {
    dist: 'dist',
    fileName: 'uikit'
  };

  grunt.initConfig({
    uikit: uikitConfig,
    regarde: {
      all: {
        files: [
          'src/**/*.js',
          'src/**/*.html'
        ],
        tasks: ['process']
      }
    },
    jshint: {
      options: {
        jshintrc: '.jshintrc'
      },
      all: [
        'Gruntfile.js',
        'src/**/*.js'
      ]
    },
    concat: {
      dist: {
        src: [
          'src/mwUI.js',
          'src/**/*.js',
          '.tmp/templates.js',
          'libs/angular-sanitize/angular-sanitize.js',
          'libs/showdown/dist/showdown.js',
          'libs/jquery-ui/ui/jquery.ui.widget.js',
          'libs/blueimp-file-upload/js/jquery.fileupload.js',
          'libs/blueimp-file-upload/js/jquery.iframe-transport.js',
          'libs/bootstrap-sass-datepicker/js/bootstrap-sass-datepicker.js',
          'libs/bootstrap-sass-datepicker/js/locales/bootstrap-datepicker.de.js'
        ],
        dest: '<%= uikit.dist %>/<%= uikit.fileName %>.js'
      }
    },
    uglify: {
      js: {
        files: {
          '<%= uikit.dist %>/<%= uikit.fileName %>.min.js': ['<%= uikit.dist %>/<%= uikit.fileName %>.js']
        }
      }
    },
    ngAnnotate: {
      options: {
        singleQuotes: true
      },
      dist: {
        files: [
          {
            '<%= uikit.dist %>/<%= uikit.fileName %>.js': ['<%= uikit.dist %>/<%= uikit.fileName %>.js']
          }
        ]
      }
    },
    ngtemplates: {
      all: {
        src: [
          'src/templates/**/*.html'
        ],
        dest: '.tmp/templates.js',
        options: {
          url: function (url) {
            return 'uikit/' + url.replace('src/', '');
          },
          bootstrap: function (module, script) {
            return 'angular.module("mwUI").run(["$templateCache", function($templateCache) {' + script + '}]);';
          },
          htmlmin: {collapseWhitespace: true, collapseBooleanAttributes: true}
        }
      }
    },
    karma: {
      unit: {
        configFile: 'karma.conf.js'
      }
    },
    clean: ['.tmp']
  });

  grunt.registerTask('watch', ['process', 'regarde']);
  grunt.registerTask('process', ['ngtemplates:all', 'concat', 'ngAnnotate:dist']);
  grunt.registerTask('build', ['jshint', 'test', 'process', 'uglify', 'clean']);
  grunt.registerTask('test', ['karma']);
};
<commit_msg>fixes gruntfile<commit_after>'use strict';

module.exports = function (grunt) {
  // load all grunt tasks
  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

  // configurable paths
  var uikitConfig = {
    dist: 'dist',
    fileName: 'uikit'
  };

  grunt.initConfig({
    uikit: uikitConfig,
    regarde: {
      all: {
        files: [
          'src/**/*.js',
          'src/**/*.html'
        ],
        tasks: ['process']
      }
    },
    jshint: {
      options: {
        jshintrc: '.jshintrc'
      },
      all: [
        'Gruntfile.js',
        'src/**/*.js'
      ]
    },
    preprocess: {
      js : {
        src : 'src/mw_ui.js',
        dest : '<%= uikit.dist %>/<%= uikit.fileName %>.js'
      }
    },
    concat: {
      dist: {
        src: [
          'src-old/mwUI.js',
          'src-old/**/*.js',
          '.tmp/templates.js',
          'libs/angular-sanitize/angular-sanitize.js',
          'libs/showdown/dist/showdown.js',
          'libs/jquery-ui/ui/jquery.ui.widget.js',
          'libs/blueimp-file-upload/js/jquery.fileupload.js',
          'libs/blueimp-file-upload/js/jquery.iframe-transport.js',
          'libs/bootstrap-sass-datepicker/js/bootstrap-sass-datepicker.js',
          'libs/bootstrap-sass-datepicker/js/locales/bootstrap-datepicker.de.js'
        ],
        dest: '<%= uikit.dist %>/<%= uikit.fileName %>-old.js'
      }
    },
    copy: {
      distToSamplePortal:{
        files: [
          {
            expand: true,
            dot: true,
            cwd: '<%= uikit.dist %>',
            dest: 'sample_portal/app/components/mw-ui',
            src: [
              '<%= uikit.fileName %>.js'
            ]
          }
        ]
      }
    },
    uglify: {
      js: {
        files: {
          '<%= uikit.dist %>/<%= uikit.fileName %>.min.js': ['<%= uikit.dist %>/<%= uikit.fileName %>.js']
        }
      }
    },
    ngAnnotate: {
      options: {
        singleQuotes: true
      },
      dist: {
        files: [
          {
            '<%= uikit.dist %>/<%= uikit.fileName %>.js': ['<%= uikit.dist %>/<%= uikit.fileName %>.js']
          }
        ]
      }
    },
    ngtemplates: {
      old: {
        src: [
          'src-old/templates/**/*.html'
        ],
        dest: '.tmp/templates.js',
        options: {
          url: function (url) {
            return 'uikit/' + url.replace('src-old/', '');
          },
          bootstrap: function (module, script) {
            return 'angular.module("mwUI").run(["$templateCache", function($templateCache) {' + script + '}]);';
          },
          htmlmin: {collapseWhitespace: true, collapseBooleanAttributes: true}
        }
      },
      new: {
        src: [
          'src/**/templates/**/*.html'
        ],
        dest: '.tmp/templates.js',
        options: {
          url: function (url) {
            return 'uikit/' + url.replace('src/', '');
          },
          bootstrap: function (module, script) {
            return 'angular.module("mwUI").run(["$templateCache", function($templateCache) {' + script + '}]);';
          },
          htmlmin: {collapseWhitespace: true, collapseBooleanAttributes: true}
        }
      }
    },
    karma: {
      unit: {
        configFile: 'karma.conf.js'
      }
    },
    clean: ['.tmp']
  });

  grunt.registerTask('watch', ['process', 'regarde']);
  grunt.registerTask('process', ['ngtemplates:new', 'preprocess:js', 'ngAnnotate:dist','copy:distToSamplePortal']);
  grunt.registerTask('process-old', ['ngtemplates:old', 'concat', 'ngAnnotate:dist','copy:distToSamplePortal']);
  grunt.registerTask('build', ['jshint', 'test', 'process', 'process-old', 'uglify', 'clean']);
  grunt.registerTask('test', ['karma']);
};
<|endoftext|>


<commit_before>    //Gruntfile
    module.exports = function(grunt) {

    //Initializing the configuration object
      grunt.initConfig({
        // Task configuration
        // clean all previously built files
        clean: ['dist/', 'out'],
        copy: {
          img: {
            //copy images to /dist folder for deployment
            files: [
              {
                expand: true, src: ['site/img/**'], dest: 'dist/img/',
                filter: 'isFile'
              }
            ]
          },
          fonts: {
            files: [
              {
                expand: true, flatten: true, src: ['site/fonts/**'], dest: 'dist/fonts/',
                filter: 'isFile'
              }
            ]
          }
        },
        jslint: {

          // lint your project's client code
          client: {
            src: [
              'site/js/*.js',
              'site/*.js'
            ],
            directives: {
              browser: true,
              predef: [
                'jQuery'
              ]
            },
            options: {
              junit: 'out/client-junit.xml'
            }
          }
        },
        build_html: {
          main: {
            options: {
              templates: 'site/parts/**/*.html'
            },
            expand: true,
            cwd: 'site/',
            src: ['*.html'],
            dest: 'dist/',
            ext: '.html'
          }
        },
        concat: {
              options: {
                separator: ';',
              },
              js_main: {
                  // concat js files for main page/info part
                src: [
                  './bower_components/jquery/jquery.js',
                  './bower_components/bootstrap/dist/js/bootstrap.js',
                  './site/js/main.js'
                ],
                dest: './dist/assets/js/main.js',
              },
              js_landing: {
                  /* concat javascript files for the landing page – atm only
                   * jQuery and Bootstrap and should use main.js instead.
                  */
                src: [
                  './bower_components/jquery/jquery.js',
                  './bower_components/bootstrap/dist/js/bootstrap.js',
                ],
                dest: './dist/assets/js/landing.js',
              },
        },
        less: {
            development: {
                options: {
                  compress: true,  //minifying the result
                },
                files: {
                  //compiling frontend.less into frontend.css
                  "./dist/assets/stylesheets/landing.css":
                   "./site/stylesheets/landing.less",
                }
            }
        },
        uglify: {
          options: {
            mangle: false  // Keep function names etc. unchanged
          },
          frontend: {
            files: {
              './site/js/main.js':
                './site/js/main.js',
            }
          },
          backend: {
            files: {
              './site/js/landing.js':
                './site/js/landing.js',
            }
          },
        },

      });

    // Plugin loading
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-jslint');
    grunt.loadNpmTasks('grunt-build-html');

    // Task definition
      grunt.registerTask('default', ['clean', 'jslint', 'build_html', 'copy', 'less',
        'concat', 'uglify']);

  };
<commit_msg>just some bug…<commit_after>    //Gruntfile
    module.exports = function(grunt) {

    //Initializing the configuration object
      grunt.initConfig({
        // Task configuration
        // clean all previously built files
        clean: ['dist/', 'out'],
        copy: {
          img: {
            //copy images to /dist folder for deployment
            files: [
              {
                expand: true, cwd: 'site/img', src: ['./**'], dest: 'dist/img/',
                filter: 'isFile'
              }
            ]
          },
          fonts: {
            files: [
              {
                expand: true, flatten: true, src: ['site/fonts/**'], dest: 'dist/fonts/',
                filter: 'isFile'
              }
            ]
          }
        },
        jslint: {

          // lint your project's client code
          client: {
            src: [
              'site/js/*.js',
              'site/*.js'
            ],
            directives: {
              browser: true,
              predef: [
                'jQuery'
              ]
            },
            options: {
              junit: 'out/client-junit.xml'
            }
          }
        },
        build_html: {
          main: {
            options: {
              templates: 'site/parts/**/*.html'
            },
            expand: true,
            cwd: 'site/',
            src: ['*.html'],
            dest: 'dist/',
            ext: '.html'
          }
        },
        concat: {
              options: {
                separator: ';',
              },
              js_main: {
                  // concat js files for main page/info part
                src: [
                  './bower_components/jquery/jquery.js',
                  './bower_components/bootstrap/dist/js/bootstrap.js',
                  './site/js/main.js'
                ],
                dest: './dist/assets/js/main.js',
              },
              js_landing: {
                  /* concat javascript files for the landing page – atm only
                   * jQuery and Bootstrap and should use main.js instead.
                  */
                src: [
                  './bower_components/jquery/jquery.js',
                  './bower_components/bootstrap/dist/js/bootstrap.js',
                ],
                dest: './dist/assets/js/landing.js',
              },
        },
        less: {
            development: {
                options: {
                  compress: true,  //minifying the result
                },
                files: {
                  //compiling frontend.less into frontend.css
                  "./dist/css/style.css":
                   "./site/stylesheets/main.less",
                }
            }
        },
        uglify: {
          options: {
            mangle: false  // Keep function names etc. unchanged
          },
          frontend: {
            files: {
              './site/js/main.js':
                './site/js/main.js',
            }
          },
          backend: {
            files: {
              './site/js/landing.js':
                './site/js/landing.js',
            }
          },
        },

      });

    // Plugin loading
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-jslint');
    grunt.loadNpmTasks('grunt-build-html');

    // Task definition
      grunt.registerTask('default', ['clean', 'jslint', 'build_html', 'copy', 'less',
        'concat', 'uglify']);

  };
<|endoftext|>


<commit_before>module.exports = function(grunt) {

	//prepare frontend boilerplate
	var
		less = {}, concat = {}, watch = {},
		sizes = ['xsmall','small','medium','large','xlarge','xxlarge','xxxlarge','xxxxlarge'],
		basename = sizes[0],
		components_css_dir = "build/components/**/css",
		global_css_dir = "build/global/css",
		dist_dir = 'css/dist';

	for (var i = 0; i < sizes.length; i++) {

		var size = sizes[i], lessfiles = {};
		lessfiles['css/build/'+size+'.min.css'] = [
			global_css_dir+'/elements/**/*.'+size+'.less',
			components_css_dir+'/*.'+size+'.less'
		];
		lessfiles['css/build/'+size+'.retina.min.css'] = [components_css_dir+'/*.'+size+'.retina.less'];
		less[size] = {
			options: {
				paths: ['less'],
				compress: true
			},
			files: lessfiles
		};
		concat["css_"+size] = {
			src: [
				global_css_dir+'/helpers/queries.'+size+'.css',
				'css/build/'+size+'.min.css',
				global_css_dir+'/helpers/queries.close.css',
				global_css_dir+'/helpers/queries.'+size+'.retina.css',
				'css/build/'+size+'.retina.min.css',
				global_css_dir+'/queries.close2.css'
			],
			dest: 'css/dist/'+size+'.min.css',
			seperator: '\n'
		};
		watch["css_"+size] = {
			files: [
				global_css_dir+'/elements/**/*.'+size+'.less',
				global_css_dir+'/elements/**/*.'+size+'.retina.less',
				components_css_dir+'/*.'+size+'.less',
				components_css_dir+'/*.'+size+'.retina.less',
				global_css_dir+'/mixins/*.css',
				global_css_dir+'/helpers/*.css'
			],
			tasks: [
				'less:'+size,
				'concat:css_'+size,
				'concat:css_production'
			]
		};

	};
	//add in specific locations

	less[basename].files['css/build/'+basename+'.min.css'].unshift(global_css_dir+'/utility.less');
	less[basename].files['css/build/'+basename+'.min.css'].unshift(global_css_dir+'/reset.less');

	less['print'] = {
		options: {
			paths: ['less'],
			compress: true
		},
		files: {
			'css/dist/print.css': [
				global_css_dir+'/print.less'
			],
		}
	};

	concat['css_production'] = {
		src: [
			'<banner>',
			'css/dist/xsmall.min.css',
			'css/dist/small.min.css',
			'css/dist/medium.min.css',
			'css/dist/large.min.css',
			'css/dist/xlarge.min.css',
			'css/dist/xxlarge.min.css',
			'css/dist/xxxlarge.min.css',
			'css/dist/xxxxlarge.min.css',
			'css/dist/print.css'
		],
		dest: 'css/dist/production.min.css',
		seperator: '\n'
	};
	concat['js'] = {
		src: [

		],
		dest: 'js/dist/site.src.js',
		seperator: '\n'
	};
	//additional watch print, and watch js
	watch['css_print'] = {
		files: [
			'build/print.less',
		],
		tasks: [
			'less:print',
			'concat:css_production'
		]
	};
	watch['js'] = {
		files: [
			'build/components/**/js/vendor/*.js',
			'build/components/**/js/*.js',
		],
		tasks: [
			'concat:js'
		]
	};

	//do grunt configuration
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		meta: {
			banner: '/*! DNA Designed Communications Limited | Copyright 2012 */'
		},
		imageoptim: {
			// these paths should match directories
			files: ['images'],
			options: {
				quitAfter: true
			}
		},
		less: less,
		concat: concat,
		watch: watch
	});

	grunt.loadNpmTasks('grunt-css');
	grunt.loadNpmTasks('grunt-contrib-less');
	grunt.loadNpmTasks('grunt-contrib-concat');
	grunt.loadNpmTasks('grunt-contrib-watch');
	grunt.loadNpmTasks('grunt-contrib-jshint');
	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-imageoptim');

	grunt.registerTask('default', ['less', 'concat', 'watch']);
};
<commit_msg>Added some notes about default breakpoints<commit_after>module.exports = function(grunt) {

	//prepare frontend boilerplate
	var
		less = {}, concat = {}, watch = {},
		sizes = [ //defaults in comments
			'xsmall', //this always shows
			'small', //30em
			'medium', //46.875em
			'large', //56em
			'xlarge', //62em
			'xxlarge', //70em
			'xxxlarge', //80em
			'xxxxlarge' //100em
		],
		basename = sizes[0],
		components_css_dir = "build/components/**/css",
		global_css_dir = "build/global/css",
		dist_dir = 'css/dist';

	for (var i = 0; i < sizes.length; i++) {

		var size = sizes[i], lessfiles = {};
		lessfiles['css/build/'+size+'.min.css'] = [
			global_css_dir+'/elements/**/*.'+size+'.less',
			components_css_dir+'/*.'+size+'.less'
		];
		lessfiles['css/build/'+size+'.retina.min.css'] = [components_css_dir+'/*.'+size+'.retina.less'];
		less[size] = {
			options: {
				paths: ['less'],
				compress: true
			},
			files: lessfiles
		};
		concat["css_"+size] = {
			src: [
				global_css_dir+'/helpers/queries.'+size+'.css',
				'css/build/'+size+'.min.css',
				global_css_dir+'/helpers/queries.close.css',
				global_css_dir+'/helpers/queries.'+size+'.retina.css',
				'css/build/'+size+'.retina.min.css',
				global_css_dir+'/queries.close2.css'
			],
			dest: 'css/dist/'+size+'.min.css',
			seperator: '\n'
		};
		watch["css_"+size] = {
			files: [
				global_css_dir+'/elements/**/*.'+size+'.less',
				global_css_dir+'/elements/**/*.'+size+'.retina.less',
				components_css_dir+'/*.'+size+'.less',
				components_css_dir+'/*.'+size+'.retina.less',
				global_css_dir+'/mixins/*.css',
				global_css_dir+'/helpers/*.css'
			],
			tasks: [
				'less:'+size,
				'concat:css_'+size,
				'concat:css_production'
			]
		};

	};
	//add in specific locations

	less[basename].files['css/build/'+basename+'.min.css'].unshift(global_css_dir+'/utility.less');
	less[basename].files['css/build/'+basename+'.min.css'].unshift(global_css_dir+'/reset.less');

	less['print'] = {
		options: {
			paths: ['less'],
			compress: true
		},
		files: {
			'css/dist/print.css': [
				global_css_dir+'/print.less'
			],
		}
	};

	concat['css_production'] = {
		src: [
			'<banner>',
			'css/dist/xsmall.min.css',
			'css/dist/small.min.css',
			'css/dist/medium.min.css',
			'css/dist/large.min.css',
			'css/dist/xlarge.min.css',
			'css/dist/xxlarge.min.css',
			'css/dist/xxxlarge.min.css',
			'css/dist/xxxxlarge.min.css',
			'css/dist/print.css'
		],
		dest: 'css/dist/production.min.css',
		seperator: '\n'
	};
	concat['js'] = {
		src: [

		],
		dest: 'js/dist/site.src.js',
		seperator: '\n'
	};
	//additional watch print, and watch js
	watch['css_print'] = {
		files: [
			'build/print.less',
		],
		tasks: [
			'less:print',
			'concat:css_production'
		]
	};
	watch['js'] = {
		files: [
			'build/components/**/js/vendor/*.js',
			'build/components/**/js/*.js',
		],
		tasks: [
			'concat:js'
		]
	};

	//do grunt configuration
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		meta: {
			banner: '/*! DNA Designed Communications Limited | Copyright 2012 */'
		},
		imageoptim: {
			// these paths should match directories
			files: ['images'],
			options: {
				quitAfter: true
			}
		},
		less: less,
		concat: concat,
		watch: watch
	});

	grunt.loadNpmTasks('grunt-css');
	grunt.loadNpmTasks('grunt-contrib-less');
	grunt.loadNpmTasks('grunt-contrib-concat');
	grunt.loadNpmTasks('grunt-contrib-watch');
	grunt.loadNpmTasks('grunt-contrib-jshint');
	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-imageoptim');

	grunt.registerTask('default', ['less', 'concat', 'watch']);
};
<|endoftext|>


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

module.exports = function(grunt) {
  grunt.initConfig({
    bump: {
      options: {
        files: [
          'package.json',
          'bower.json'
        ],
        pushTo: 'origin'
      }
    }
  });
  grunt.loadNpmTasks('grunt-bump');
};

<commit_msg>commit bower.json too when you bump please<commit_after>var fs = require('fs');

module.exports = function(grunt) {
  grunt.initConfig({
    bump: {
      options: {
        files: [
          'package.json',
          'bower.json'
        ],
        commitFiles: '-a',
        pushTo: 'origin'
      }
    }
  });
  grunt.loadNpmTasks('grunt-bump');
};

<|endoftext|>


<commit_before>'use strict';

module.exports = function(grunt) {

  require('load-grunt-tasks')(grunt);
  require('time-grunt')(grunt);

  grunt.initConfig({

    root: {
      app: 'web/app',
      tmp: 'web/.tmp',
      test: 'web/test',
      dist: 'web/dist'
    },

    clean: {
      dist: {
        files: [{
          dot: true,
          src: [
            '<%= root.tmp %>',
            '<%= root.dist %>/*',
            '!<%= root.dist %>/.git*'
          ]
        }]
      },
      server: '<%= root.tmp %>'
    },

    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= root.app %>',
          dest: '<%= root.dist %>',
          src: [
            '*.{ico,png,txt}'
          ]
        }]
      }
    },

    compass: {
      options: {
        sassDir: '<%= root.app %>/styles',
        cssDir: '<%= root.tmp %>/styles',
        generatedImagesDir: '<%= root.tmp %>/images/sprite',
        imagesDir: '<%= root.app %>/images',
        javascriptsDir: '<%= root.app %>/scripts',
        fontsDir: '<%= root.app %>/styles/fonts',
        importPath: '<%= root.app %>/vendor',
        relativeAssets: false,
        assetCacheBuster: false
      },
      dist: {
        options: {
          httpImagesPath: '/nyc-cityhall.vizzuality.com/images',
          httpGeneratedImagesPath: '/nyc-cityhall.vizzuality.com/images/sprite',
          httpFontsPath: '/nyc-cityhall.vizzuality.com/fonts'
        }
      },
      app: {
        options: {
          debugInfo: true,
          relativeAssets: true
        }
      }
    },

    cssmin: {
      dist: {
        files: {
          '<%= root.dist %>/styles/main.css': [
            '<%= root.app %>/vendor/normalize-css/normalize.css',
            '<%= root.tmp %>/styles/{,*/}*.css'
          ]
        }
      }
    },

    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: [
        'Gruntfile.js',
        '<%= root.app %>/scripts/{,*/}{,*/}*.js',
        '<%= root.test %>/specs/{,*/}{,*/}*.js',
        '<%= root.test %>/runner.js'
      ]
    },

    mocha_phantomjs: {
      all: ['<%= root.test %>/index.html']
    },

    requirejs: {
      options: {
        optimize: 'uglify',
        preserveLicenseComments: false,
        useStrict: true,
        wrap: false
      },
      dist: {
        options: {
          baseUrl: '<%= root.app %>/scripts',
          include: 'main',
          out: '<%= root.dist %>/scripts/main.js',
          mainConfigFile: '<%= root.app %>/scripts/main.js',
        }
      }
    },

    uglify: {
      options: {
        mangle: false
      },
      dist: {
        files: {
          '<%= root.dist %>/vendor/requirejs/require.js': ['<%= root.app %>/vendor/requirejs/require.js']
        }
      }
    },

    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= root.app %>/images',
          src: '{,*/}*.{png,jpg,jpeg,gif}',
          dest: '<%= root.dist %>/images'
        }]
      }
    },

    watch: {
      options: {
        nospawn: true
      },
      compass: {
        files: [
          '<%= root.app %>/styles/{,*/}*{,*/}*.{scss,sass}'
        ],
        tasks: ['compass:app']
      },
      test: {
        files: [
          '<%= root.app %>/scripts/{,*/}{,*/}*.js',
          '<%= root.test %>/specs/{,*/}{,*/}*.js',
          '<%= root.test %>/specRunner.js',
          'Gruntfile.js'
        ],
        tasks: ['test']
      }
    }

  });

  grunt.registerTask('test', [
    'jshint',
    'mocha_phantomjs'
  ]);

  grunt.registerTask('build', [
    'test',
    'clean:dist',
    'requirejs',
    'copy:dist',
    'uglify',
    'compass:dist',
    'cssmin',
    'imagemin'
  ]);

  grunt.registerTask('default', [
    'clean:server',
    'test',
    'compass:server'
  ]);

};
<commit_msg>grunt<commit_after>'use strict';

module.exports = function(grunt) {

  require('load-grunt-tasks')(grunt);
  require('time-grunt')(grunt);

  grunt.initConfig({

    root: {
      app: 'web/app',
      tmp: 'web/.tmp',
      test: 'web/test',
      dist: 'web/dist'
    },

    clean: {
      dist: {
        files: [{
          dot: true,
          src: [
            '<%= root.tmp %>',
            '<%= root.dist %>/*',
            '!<%= root.dist %>/.git*'
          ]
        }]
      },
      server: '<%= root.tmp %>'
    },

    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= root.app %>',
          dest: '<%= root.dist %>',
          src: [
            '*.{ico,png,txt}'
          ]
        }]
      }
    },

    compass: {
      options: {
        sassDir: '<%= root.app %>/styles',
        cssDir: '<%= root.tmp %>/styles',
        generatedImagesDir: '<%= root.tmp %>/images/sprite',
        imagesDir: '<%= root.app %>/images',
        javascriptsDir: '<%= root.app %>/scripts',
        fontsDir: '<%= root.app %>/styles/fonts',
        importPath: '<%= root.app %>/vendor',
        relativeAssets: false,
        assetCacheBuster: false
      },
      dist: {
        options: {
          httpImagesPath: '/nyc-cityhall.vizzuality.com/images',
          httpGeneratedImagesPath: '/nyc-cityhall.vizzuality.com/images/sprite',
          httpFontsPath: '/nyc-cityhall.vizzuality.com/fonts'
        }
      },
      app: {
        options: {
          debugInfo: true,
          relativeAssets: true
        }
      }
    },

    cssmin: {
      dist: {
        files: {
          '<%= root.dist %>/styles/main.css': [
            '<%= root.app %>/vendor/normalize-css/normalize.css',
            '<%= root.tmp %>/styles/{,*/}*.css'
          ]
        }
      }
    },

    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: [
        'Gruntfile.js',
        '<%= root.app %>/scripts/{,*/}{,*/}*.js',
        '<%= root.test %>/specs/{,*/}{,*/}*.js',
        '<%= root.test %>/runner.js'
      ]
    },

    mocha_phantomjs: {
      all: ['<%= root.test %>/index.html']
    },

    requirejs: {
      options: {
        optimize: 'uglify',
        preserveLicenseComments: false,
        useStrict: true,
        wrap: false
      },
      dist: {
        options: {
          baseUrl: '<%= root.app %>/scripts',
          include: 'main',
          out: '<%= root.dist %>/scripts/main.js',
          mainConfigFile: '<%= root.app %>/scripts/main.js',
        }
      }
    },

    uglify: {
      options: {
        mangle: false
      },
      dist: {
        files: {
          '<%= root.dist %>/vendor/requirejs/require.js': ['<%= root.app %>/vendor/requirejs/require.js']
        }
      }
    },

    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= root.app %>/images',
          src: '{,*/}*.{png,jpg,jpeg,gif}',
          dest: '<%= root.dist %>/images'
        }]
      }
    },

    watch: {
      options: {
        nospawn: true
      },
      compass: {
        files: [
          '<%= root.app %>/styles/{,*/}*{,*/}*.{scss,sass}'
        ],
        tasks: ['compass:app']
      },
      test: {
        files: [
          '<%= root.app %>/scripts/{,*/}{,*/}*.js',
          '<%= root.test %>/specs/{,*/}{,*/}*.js',
          '<%= root.test %>/specRunner.js',
          'Gruntfile.js'
        ],
        tasks: ['test']
      }
    }

  });

  grunt.registerTask('test', [
    'jshint',
    'mocha_phantomjs'
  ]);

  grunt.registerTask('build', [
    'test',
    'clean:dist',
    'requirejs',
    'copy:dist',
    'uglify',
    'compass:dist',
    'cssmin',
    'imagemin'
  ]);

  grunt.registerTask('default', [
    'clean:server',
    'test',
    'compass:app'
  ]);

};
<|endoftext|>


<commit_before>module.exports = function(grunt) {

	'use strict';

	/**
	* Project configuration
	*/
	grunt.initConfig({

		pkg: require('./package'), // <%=pkg.name%> grunt.file.readJSON('package.json'),

		/**
		* Config - Edit this section
		* ==========================
		* Choose javascript dist filename
		* Choose javascript dist location
		* Choose javascript files to be uglified
		* Choose css dist filename
		* Choose css dist location
		* Choose scss files to be compiled
		*/
		config : {

			js : {
				// <%=config.js.distDir%>
				distDir : 'web/js/',

				// <%=config.js.distFile%>
				distFile : 'app.min.js',

				// <%=config.js.fileList%>
				fileList : [
					'web/bower_components/foundation/js/foundation.min.js',
					//'web/bower_components/foundation/js/foundation.js',
					//'web/bower_components/foundation/js/foundation/*.js',
					'web/bower_components/jquery-ias/src/jquery-ias.js',
					'web/bower_components/jquery-ias/src/callbacks.js',
					'web/bower_components/jquery-ias/src/extension/spinner.js',
					'web/bower_components/jquery-ias/src/extension/noneleft.js',
					'web/js/onDomReady.js'
				]
			}
		},

		/**
		* Watch
		* https://github.com/gruntjs/grunt-contrib-watch
		* Watches your scss, js etc for changes and compiles them
		*/
		watch: {

			grunt: {
				files: ['Gruntfile.js']
			},

			scss: {
				files: ['web/scss/**/*.scss'],
				tasks: ['sass:dist', 'autoprefixer:dist']
			},

			js: {
				files: ['<%=config.js.fileList%>', 'Gruntfile.js'],
				tasks: ['uglify']
			}
		},

		/**
		* Sass compilation
		* https://github.com/gruntjs/grunt-contrib-sass
		* Includes kickoff.scss and kickoff-old-ie.scss by default
		* Also creates source maps
		*/
		sass: {

			dist: {

				options: {
					loadPath: ['web/bower_components/foundation/scss'],
					unixNewlines: true,
					style: 'expanded', //compressed - expanded
					lineNumbers: false,
					debugInfo : false,
					precision : 8,
					sourcemap: false
				},

				files: {
					'web/css/app.css' : 'web/scss/app.scss',
					'web/css/legacy.css': 'web/scss/legacy.scss'
				}
			}
		},

		/**
		* Autoprefixer
		* https://github.com/nDmitry/grunt-autoprefixer
		* https://github.com/ai/autoprefixer
		* Auto prefixes your CSS using caniuse data
		*/
		autoprefixer: {

			dist: {

				options: {
					// Task-specific options go here - we are supporting
					// the last 2 browsers, any browsers with >1% market share,
					// and ensuring we support IE7 + 8 with prefixes
					browsers: ['> 5%', 'last 4 versions', 'firefox > 3.6', 'ie > 6'],
					map: true
				},

				files: {
					'web/css/app.css' : 'web/css/app.css',
					'web/css/legacy.css': 'web/css/legacy.css'
				}
			}
		},

		/**
		* Uglify
		* https://github.com/gruntjs/grunt-contrib-uglify
		* Minifies and concatinates your JS
		* Also creates source maps
		*/
		uglify: {

			options: {
				mangle: true, // mangle: Turn on or off mangling
				beautify: false, // beautify: beautify your code for debugging/troubleshooting purposes
				compress: false,
				// report: 'gzip', // report: Show file size report
				sourceMap: '<%=config.js.distDir%><%=config.js.distFile%>.map',
				sourceMappingURL: '/<%=config.js.distFile%>.map'
			},

			js: {
				src: '<%=config.js.fileList%>',
				dest: '<%=config.js.distDir%><%=config.js.distFile%>'
			}
		},

		/**
		* CSSO
		* https://github.com/t32k/grunt-csso
		* Minify CSS files with CSSO
		*/
		csso: {

			dist: {

				files: {
					'web/css/app.css' : 'web/css/app.css',
					'web/css/legacy.css': 'web/css/legacy.css'
				}
			}
		},

		/**
		* JSHint
		* https://github.com/gruntjs/grunt-contrib-jshint
		* Manage the options inside .jshintrc file
		*/
		jshint: {

			all: '<%=config.js.fileList%>',

			options: {
				jshintrc: '.jshintrc'
			}
		},

		/**
		* JSCS
		* https://github.com/dsheiko/grunt-jscs
		* Manage the options inside .jscs.json file
		*/
		jscs: {

			src: '<%=config.js.fileList%>',

			options: {
				config: ".jscs.json"
			}
		},

		/**
		* Bower install
		* https://github.com/yatskevich/grunt-bower-task
		* Install bower dependencies
		*/
		bower: {

			install: {

				options: {
					targetDir: "./web/bower_components",
					install: true
				}
			}
		},

		/**
		* Symfony2 Console
		* https://www.npmjs.org/package/grunt-symfony2
		* Grunt plugin for running Symfony2 commands
		*/
		'sf2-console': {

			options: {
				bin: 'app/console'
			},

			cache_clear_prod: {
				cmd: 'cache:clear',
				args: {
					env: 'prod'
				}
			},

			cache_clear_dev: {
				cmd: 'cache:clear',
				args: {
					env: 'dev'
				}
			},

			cache_warmup_prod: {
				cmd: 'cache:warmup',
				args: {
					env: 'prod'
				}
			},

			cache_warmup_dev: {
				cmd: 'cache:warmup',
				args: {
					env: 'dev'
				}
			},

			doctrine_schema_drop: {
				cmd: 'doctrine:schema:drop',
				args: {
					env: 'dev',
					force: true
				}
			},

			doctrine_schema_create: {
				cmd: 'doctrine:schema:create',
				args: {
					env: 'dev'
				}
			},

			doctrine_fixtures_load: {
				cmd: 'doctrine:fixtures:load',
				args: {
					env: 'dev',
					append: true
				}
			},

			doctrine_schema_update: {
				cmd: 'doctrine:schema:update',
				args: {
					force: true
				}
			},

			doctrine_schema_validate: {
				cmd: 'doctrine:schema:validate',
				args: {
				}
			},

			sonata_media_sync_default: {
				cmd: 'sonata:media:sync sonata.media.provider.image default'
			},

			sonata_media_sync_intro: {
				cmd: 'sonata:media:sync sonata.media.provider.image intro'
			},

			sonata_media_sync_bgimage: {
				cmd: 'sonata:media:sync sonata.media.provider.image bgimage'
			},

			sonata_media_sync_icon: {
				cmd: 'sonata:media:sync sonata.media.provider.image icon'
			},

			assetic_dump_dev: {
				cmd: 'assetic:dump',
				args: {
					env: 'dev'
				}
			},

			assetic_dump_prod: {
				cmd: 'assetic:dump',
				args: {
					env: 'prod'
				}
			},

			twig_lint: {
				cmd: 'twig:lint',
				args: {
				}
			}
		}

	});

	// Load all the grunt tasks
	require('load-grunt-tasks')(grunt);

   /* ==========================================================================
	Available tasks:
	* grunt : run jshint, uglify and sass
	* grunt watch : run sass, uglify
	* grunt dev : run jshint, uglify and sass
	* grunt deploy : run jshint, uglify, sass and csso
	* grunt first_deployment :
	* grunt deployment_prod :
	* grunt deployment_prod :
	* grunt availabletasks : view all available tasks
	========================================================================== */

	/**
	* GRUNT * Default task
	* run jshint, uglify and sass
	*/
	// Default task
	grunt.registerTask('default', [
		//'jshint',
		'uglify',
		'sass:dist',
		'autoprefixer:dist',
		'sf2-console:assetic_dump_dev'
	]);

	// Deployment to Dev task
	grunt.registerTask('first_deployment', [
		'sf2-console:cache_clear_dev',
		'sf2-console:cache_clear_prod',
		'sf2-console:cache_warmup_dev',
		'sf2-console:cache_warmup_prod',
		'sf2-console:doctrine_schema_drop',
		'sf2-console:doctrine_schema_create',
		'sf2-console:doctrine_fixtures_load',
		'sf2-console:sonata_media_sync_default',
		'sf2-console:sonata_media_sync_intro',
		'sf2-console:sonata_media_sync_bgimage',
		'sf2-console:sonata_media_sync_icon',
		'bower:install',
		'uglify',
		'sass:dist',
		'autoprefixer:dist',
		'csso:dist',
		'sf2-console:assetic_dump_dev',
		'sf2-console:assetic_dump_prod'
	]);

	// Deployment to Prod task
	grunt.registerTask('deployment_prod', [
		'sf2-console:cache_clear_prod',
		'sf2-console:cache_warmup_prod',
		'uglify',
		'sass:dist',
		'autoprefixer:dist',
		'csso:dist',
		'sf2-console:assetic_dump_prod'
	]);

	/**
	* GRUNT DEV * A task for development
	* run jshint, uglify and sass
	*/
	grunt.registerTask('dev', [
		//'jshint',
		'uglify',
		'sass:dist',
		'autoprefixer:dist',
		'sf2-console:assetic_dump_dev'
	]);

	/**
	* GRUNT DEPLOY * A task for your production environment
	* run jshint, uglify and sass:production
	*/
	grunt.registerTask('deploy', [
		'uglify',
		'sass:dist',
		'autoprefixer:dist',
		'csso:dist',
		'sf2-console:assetic_dump_dev',
		'sf2-console:assetic_dump_prod'
	]);

	//Travis CI to test build
	grunt.registerTask('travis', [
		'sf2-console:cache_clear_dev',
		'sf2-console:cache_clear_prod',
		'sf2-console:cache_warmup_dev',
		'sf2-console:cache_warmup_prod',
		'sf2-console:doctrine_schema_drop',
		'sf2-console:doctrine_schema_create',
		'sf2-console:doctrine_fixtures_load',
		'sf2-console:sonata_media_sync_default',
		'sf2-console:sonata_media_sync_intro',
		'sf2-console:sonata_media_sync_bgimage',
		'sf2-console:sonata_media_sync_icon',
		'bower:install',
		//'jshint',
		'uglify',
		'sass:dist',
		'autoprefixer:dist',
		'csso:dist',
		'sf2-console:assetic_dump_dev',
		'sf2-console:assetic_dump_prod'
	]);
};<commit_msg>changing the travis ci grunt tasks<commit_after>module.exports = function(grunt) {

	'use strict';

	/**
	* Project configuration
	*/
	grunt.initConfig({

		pkg: require('./package'), // <%=pkg.name%> grunt.file.readJSON('package.json'),

		/**
		* Config - Edit this section
		* ==========================
		* Choose javascript dist filename
		* Choose javascript dist location
		* Choose javascript files to be uglified
		* Choose css dist filename
		* Choose css dist location
		* Choose scss files to be compiled
		*/
		config : {

			js : {
				// <%=config.js.distDir%>
				distDir : 'web/js/',

				// <%=config.js.distFile%>
				distFile : 'app.min.js',

				// <%=config.js.fileList%>
				fileList : [
					'web/bower_components/foundation/js/foundation.min.js',
					//'web/bower_components/foundation/js/foundation.js',
					//'web/bower_components/foundation/js/foundation/*.js',
					'web/bower_components/jquery-ias/src/jquery-ias.js',
					'web/bower_components/jquery-ias/src/callbacks.js',
					'web/bower_components/jquery-ias/src/extension/spinner.js',
					'web/bower_components/jquery-ias/src/extension/noneleft.js',
					'web/js/onDomReady.js'
				]
			}
		},

		/**
		* Watch
		* https://github.com/gruntjs/grunt-contrib-watch
		* Watches your scss, js etc for changes and compiles them
		*/
		watch: {

			grunt: {
				files: ['Gruntfile.js']
			},

			scss: {
				files: ['web/scss/**/*.scss'],
				tasks: ['sass:dist', 'autoprefixer:dist']
			},

			js: {
				files: ['<%=config.js.fileList%>', 'Gruntfile.js'],
				tasks: ['uglify']
			}
		},

		/**
		* Sass compilation
		* https://github.com/gruntjs/grunt-contrib-sass
		* Includes kickoff.scss and kickoff-old-ie.scss by default
		* Also creates source maps
		*/
		sass: {

			dist: {

				options: {
					loadPath: ['web/bower_components/foundation/scss'],
					unixNewlines: true,
					style: 'expanded', //compressed - expanded
					lineNumbers: false,
					debugInfo : false,
					precision : 8,
					sourcemap: false
				},

				files: {
					'web/css/app.css' : 'web/scss/app.scss',
					'web/css/legacy.css': 'web/scss/legacy.scss'
				}
			}
		},

		/**
		* Autoprefixer
		* https://github.com/nDmitry/grunt-autoprefixer
		* https://github.com/ai/autoprefixer
		* Auto prefixes your CSS using caniuse data
		*/
		autoprefixer: {

			dist: {

				options: {
					// Task-specific options go here - we are supporting
					// the last 2 browsers, any browsers with >1% market share,
					// and ensuring we support IE7 + 8 with prefixes
					browsers: ['> 5%', 'last 4 versions', 'firefox > 3.6', 'ie > 6'],
					map: true
				},

				files: {
					'web/css/app.css' : 'web/css/app.css',
					'web/css/legacy.css': 'web/css/legacy.css'
				}
			}
		},

		/**
		* Uglify
		* https://github.com/gruntjs/grunt-contrib-uglify
		* Minifies and concatinates your JS
		* Also creates source maps
		*/
		uglify: {

			options: {
				mangle: true, // mangle: Turn on or off mangling
				beautify: false, // beautify: beautify your code for debugging/troubleshooting purposes
				compress: false,
				// report: 'gzip', // report: Show file size report
				sourceMap: '<%=config.js.distDir%><%=config.js.distFile%>.map',
				sourceMappingURL: '/<%=config.js.distFile%>.map'
			},

			js: {
				src: '<%=config.js.fileList%>',
				dest: '<%=config.js.distDir%><%=config.js.distFile%>'
			}
		},

		/**
		* CSSO
		* https://github.com/t32k/grunt-csso
		* Minify CSS files with CSSO
		*/
		csso: {

			dist: {

				files: {
					'web/css/app.css' : 'web/css/app.css',
					'web/css/legacy.css': 'web/css/legacy.css'
				}
			}
		},

		/**
		* JSHint
		* https://github.com/gruntjs/grunt-contrib-jshint
		* Manage the options inside .jshintrc file
		*/
		jshint: {

			all: '<%=config.js.fileList%>',

			options: {
				jshintrc: '.jshintrc'
			}
		},

		/**
		* JSCS
		* https://github.com/dsheiko/grunt-jscs
		* Manage the options inside .jscs.json file
		*/
		jscs: {

			src: '<%=config.js.fileList%>',

			options: {
				config: ".jscs.json"
			}
		},

		/**
		* Bower install
		* https://github.com/yatskevich/grunt-bower-task
		* Install bower dependencies
		*/
		bower: {

			install: {

				options: {
					targetDir: "./web/bower_components",
					install: true
				}
			}
		},

		/**
		* Symfony2 Console
		* https://www.npmjs.org/package/grunt-symfony2
		* Grunt plugin for running Symfony2 commands
		*/
		'sf2-console': {

			options: {
				bin: 'app/console'
			},

			cache_clear_prod: {
				cmd: 'cache:clear',
				args: {
					env: 'prod'
				}
			},

			cache_clear_dev: {
				cmd: 'cache:clear',
				args: {
					env: 'dev'
				}
			},

			cache_warmup_prod: {
				cmd: 'cache:warmup',
				args: {
					env: 'prod'
				}
			},

			cache_warmup_dev: {
				cmd: 'cache:warmup',
				args: {
					env: 'dev'
				}
			},

			doctrine_schema_drop: {
				cmd: 'doctrine:schema:drop',
				args: {
					env: 'dev',
					force: true
				}
			},

			doctrine_schema_create: {
				cmd: 'doctrine:schema:create',
				args: {
					env: 'dev'
				}
			},

			doctrine_fixtures_load: {
				cmd: 'doctrine:fixtures:load',
				args: {
					env: 'dev',
					append: true
				}
			},

			doctrine_schema_update: {
				cmd: 'doctrine:schema:update',
				args: {
					force: true
				}
			},

			doctrine_schema_validate: {
				cmd: 'doctrine:schema:validate',
				args: {
				}
			},

			sonata_media_sync_default: {
				cmd: 'sonata:media:sync sonata.media.provider.image default'
			},

			sonata_media_sync_intro: {
				cmd: 'sonata:media:sync sonata.media.provider.image intro'
			},

			sonata_media_sync_bgimage: {
				cmd: 'sonata:media:sync sonata.media.provider.image bgimage'
			},

			sonata_media_sync_icon: {
				cmd: 'sonata:media:sync sonata.media.provider.image icon'
			},

			assetic_dump_dev: {
				cmd: 'assetic:dump',
				args: {
					env: 'dev'
				}
			},

			assetic_dump_prod: {
				cmd: 'assetic:dump',
				args: {
					env: 'prod'
				}
			},

			twig_lint: {
				cmd: 'twig:lint',
				args: {
				}
			}
		}

	});

	// Load all the grunt tasks
	require('load-grunt-tasks')(grunt);

   /* ==========================================================================
	Available tasks:
	* grunt : run jshint, uglify and sass
	* grunt watch : run sass, uglify
	* grunt dev : run jshint, uglify and sass
	* grunt deploy : run jshint, uglify, sass and csso
	* grunt first_deployment :
	* grunt deployment_prod :
	* grunt deployment_prod :
	* grunt availabletasks : view all available tasks
	========================================================================== */

	/**
	* GRUNT * Default task
	* run jshint, uglify and sass
	*/
	// Default task
	grunt.registerTask('default', [
		//'jshint',
		'uglify',
		'sass:dist',
		'autoprefixer:dist',
		'sf2-console:assetic_dump_dev'
	]);

	// First Deployment task
	grunt.registerTask('first_deployment', [
		'sf2-console:cache_clear_dev',
		'sf2-console:cache_clear_prod',
		'sf2-console:cache_warmup_dev',
		'sf2-console:cache_warmup_prod',
		'sf2-console:doctrine_schema_drop',
		'sf2-console:doctrine_schema_create',
		'sf2-console:doctrine_fixtures_load',
		'sf2-console:sonata_media_sync_default',
		'sf2-console:sonata_media_sync_intro',
		'sf2-console:sonata_media_sync_bgimage',
		'sf2-console:sonata_media_sync_icon',
		'bower:install',
		'uglify',
		'sass:dist',
		'autoprefixer:dist',
		'csso:dist',
		'sf2-console:assetic_dump_dev',
		'sf2-console:assetic_dump_prod'
	]);

	// Deployment to Prod task
	grunt.registerTask('deployment_prod', [
		'sf2-console:cache_clear_prod',
		'sf2-console:cache_warmup_prod',
		'uglify',
		'sass:dist',
		'autoprefixer:dist',
		'csso:dist',
		'sf2-console:assetic_dump_prod'
	]);

	/**
	* GRUNT DEV * A task for development
	* run jshint, uglify and sass
	*/
	grunt.registerTask('dev', [
		//'jshint',
		'uglify',
		'sass:dist',
		'autoprefixer:dist',
		'sf2-console:assetic_dump_dev'
	]);

	/**
	* GRUNT DEPLOY * A task for your production environment
	* run jshint, uglify and sass:production
	*/
	grunt.registerTask('deploy', [
		'uglify',
		'sass:dist',
		'autoprefixer:dist',
		'csso:dist',
		'sf2-console:assetic_dump_dev',
		'sf2-console:assetic_dump_prod'
	]);

	/**
	* GRUNT Travis * A task for Travis CI to test build
	*/
	grunt.registerTask('travis', [
		'sf2-console:cache_clear_dev',
		'sf2-console:cache_clear_prod',
		'sf2-console:cache_warmup_dev',
		'sf2-console:cache_warmup_prod',
		'sf2-console:doctrine_schema_drop',
		'sf2-console:doctrine_schema_create',
		'sf2-console:doctrine_fixtures_load',
		'sf2-console:sonata_media_sync_default',
		'sf2-console:sonata_media_sync_intro',
		'sf2-console:sonata_media_sync_bgimage',
		'sf2-console:sonata_media_sync_icon',
		'bower:install',
		'uglify',
		'sass:dist',
		'autoprefixer:dist',
		'csso:dist',
		'sf2-console:assetic_dump_dev',
		'sf2-console:assetic_dump_prod'
	]);
};<|endoftext|>


<commit_before>module.exports = function( grunt ) {
  grunt.initConfig({
    pkg: grunt.file.readJSON( "package.json" ),

    recess: {
      dist: {
        options: {
          noIDs: false,
          noOverqualifying: false,
          noUniversalSelectors: false,
          strictPropertyOrder: false
        },
        src: [
          "public/css/style.less",
          "public/css/make-details.less"
        ]
      }
    },
    jshint: {
      files: [
        "Gruntfile.js",
        "app.js",
        "lib/**/*.js",
        "package.json",
        "public/js/**/*.js",
        "routes/**/*.js"
      ]
    }
  });

  grunt.loadNpmTasks( "grunt-recess" );
  grunt.loadNpmTasks( "grunt-contrib-jshint" );

  grunt.registerTask( "default", [ "recess", "jshint" ]);
};
<commit_msg>Fix bug 899993: Ignore public/js/ext in grunt<commit_after>module.exports = function( grunt ) {
  grunt.initConfig({
    pkg: grunt.file.readJSON( "package.json" ),

    recess: {
      dist: {
        options: {
          noIDs: false,
          noOverqualifying: false,
          noUniversalSelectors: false,
          strictPropertyOrder: false
        },
        src: [
          "public/css/style.less",
          "public/css/make-details.less"
        ]
      }
    },
    jshint: {
      files: [
        "Gruntfile.js",
        "app.js",
        "lib/**/*.js",
        "package.json",
        "public/js/**/*.js",
        "!public/js/lib/**",
        "routes/**/*.js"
      ]
    }
  });

  grunt.loadNpmTasks( "grunt-recess" );
  grunt.loadNpmTasks( "grunt-contrib-jshint" );

  grunt.registerTask( "default", [ "recess", "jshint" ]);
};
<|endoftext|>