<commit_before>// # Gruntfile
// Automation for the project.

'use strict';

var GruntConfig = require('thehelp-project').GruntConfig;
require('thehelp-client-project').mixin(GruntConfig);

var internals = {};

module.exports = function(grunt) {
  var config = new GruntConfig(grunt);

  config.standardSetup();

  internals.setupDist(config, grunt);
  internals.setupClientTest(config, grunt);

  var tasks = config.defaultTasks;
  grunt.registerTask('default', tasks.concat(['dist', 'client-test']));
};

internals.setupDist = function(config, grunt) {
  var options = require('./src/client/thehelp-test/config');
  config.registerOptimizeLibrary({
    source: 'thehelp-test',
    targetPath: 'dist',
    config: options
  });
  config.registerOptimizeLibrary({
    source: 'thehelp-test-coverage',
    targetPath: 'dist',
    empty: ['thehelp-test', 'mocha'],
    config: options
  });

  config.registerCopy({
    files: {
      'dist/mocha.css': 'bower_components/mocha/mocha.css',
      'dist/thehelp-test-harness.js': 'src/client/thehelp-test/harness.js',
      'dist/grunt-mocha-bridge.js':
        'node_modules/thehelp-client-project/node_modules/grunt-mocha/phantomjs/bridge.js'
    }
  });

  // Turns out that r.js optimization has a problem when it puts a number of files into
  // one final file. If it finds an anonymous `define()` (no name specified as the first
  // parameter) it will put the name of the method it used to load that file in that
  // anonymous define. In this case, the combined `blanket` file has its dependency
  // `esprima` at the top, which uses UMD-syntax to define itself. Because it was all
  // loaded as `blanket`, that's what r.js puts there. This results in no define for
  // `blanket` at all.
  grunt.task.registerTask('fix-coverage', 'Removes r.js-generated bugs', function() {
    grunt.file.delete('dist/thehelp-test-coverage.min.js');

    var path = 'dist/thehelp-test-coverage.js';
    var contents = grunt.file.read(path);
    contents = contents.replace(
      'define(\'blanket\',[\'exports\'], factory);',
      'define(\'esprima\',[\'exports\'], factory);'
    );

    contents = contents.replace(
      '})();\n\n// bridge',
      '})();\ndefine(\'blanket\', function() { return window.blanket; })\n// Bridge'
    );

    grunt.file.write(path, contents);
  });

  grunt.registerTask('dist', ['requirejs', 'copy:default', 'fix-coverage']);
};

internals.setupClientTest = function(config, grunt) {
  config.registerMocha({
    urls: [
      'http://localhost:3001/test/integration/dev.html',
      'http://localhost:3001/test/integration/dist.html'
    ]
  });
  grunt.registerTask('client-test', ['connect:test', 'mocha']);
};

<commit_msg>Reorganize gruntfile<commit_after>// # Gruntfile
// Automation for the project.

'use strict';

var GruntConfig = require('thehelp-project').GruntConfig;
require('thehelp-client-project').mixin(GruntConfig);

var internals = {};

module.exports = function(grunt) {
  var config = new GruntConfig(grunt);

  config.standardSetup();

  internals.setupDist(config, grunt);
  internals.setupClientTesting(config, grunt);

  var tasks = config.defaultTasks;
  grunt.registerTask('default', tasks.concat(['dist', 'client-test']));
};

internals.setupDist = function(config, grunt) {
  var options = require('./src/client/thehelp-test/config');

  config.registerOptimizeLibrary({
    source: 'thehelp-test',
    targetPath: 'dist',
    config: options
  });

  config.registerOptimizeLibrary({
    source: 'thehelp-test-coverage',
    targetPath: 'dist',
    empty: ['thehelp-test', 'mocha'],
    config: options
  });

  config.registerCopy({
    files: {
      'dist/mocha.css': 'bower_components/mocha/mocha.css',
      'dist/thehelp-test-harness.js': 'src/client/thehelp-test/harness.js',
      'dist/grunt-mocha-bridge.js':
        'node_modules/thehelp-client-project/node_modules/grunt-mocha/phantomjs/bridge.js'
    }
  });

  config.registerPreambleForDist({
    src: 'dist/**/thehelp-test*.js',
    comments: {
      'thehelp-test\\.': 'Includes mocha, chai and sinon.',
      'thehelp-test-coverage\\.': 'Includes blanket.'
    }
  });

  // Turns out that r.js optimization has a problem when it puts a number of files into
  // one final file. If it finds an anonymous `define()` (no name specified as the first
  // parameter) it will put the name of the method it used to load that file in that
  // anonymous define. In this case, the combined `blanket` file has its dependency
  // `esprima` at the top, which uses UMD-syntax to define itself. Because it was all
  // loaded as `blanket`, that's what r.js puts there. This results in no define for
  // `blanket` at all.
  grunt.task.registerTask('fix-coverage', 'Removes r.js-generated bugs', function() {
    grunt.file.delete('dist/thehelp-test-coverage.min.js');

    var path = 'dist/thehelp-test-coverage.js';
    var contents = grunt.file.read(path);
    contents = contents.replace(
      'define(\'blanket\',[\'exports\'], factory);',
      'define(\'esprima\',[\'exports\'], factory);'
    );

    contents = contents.replace(
      '})();\n\n// bridge',
      '})();\ndefine(\'blanket\', function() { return window.blanket; })\n// Bridge'
    );

    grunt.file.write(path, contents);
  });

  grunt.registerTask('dist', [
    'requirejs', 'copy:default', 'fix-coverage', 'preamble-for-dist'
  ]);
};

internals.setupClientTesting = function(config, grunt) {
  config.registerMocha({
    urls: [
      'http://localhost:3001/test/integration/dev.html',
      'http://localhost:3001/test/integration/dist.html'
    ]
  });
  grunt.registerTask('client-test', ['connect:test', 'mocha']);

  config.registerSauce({
    urls: [
      'http://localhost:3001/test/integration/dist.html'
    ]
  });

  //we run client-test first to ensure we don't sent super-broken tests to Sauce Labs
  grunt.registerTask('cross-browser', ['client-test', 'sauce']);
};

<|endoftext|>


<commit_before>// Generated on 2015-03-30 using generator-angular 0.9.8
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {

  // Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);

  // Time how long tasks take. Can help when optimizing build times
  require('time-grunt')(grunt);

  // Support HTML5 mode in development
  var modRewrite = require('connect-modrewrite');

  //Load s3 library
  grunt.loadNpmTasks('grunt-aws-s3');

  // Load less compiller
  grunt.loadNpmTasks('grunt-contrib-less');

  // Configurable paths for the application
  var appConfig = {
    app: require('./bower.json').appPath || 'app',
    dist: 'dist'
  };

  // Define the configuration for all the tasks
  grunt.initConfig({

    // Project settings
    yeoman: appConfig,

    // Watches files for changes and runs tasks based on the changed files
    watch: {
      bower: {
        files: ['bower.json'],
        tasks: ['wiredep']
      },
      js: {
        files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
        tasks: ['newer:jshint:all'],
        options: {
          livereload: '<%= connect.options.livereload %>'
        }
      },
      jsTest: {
        files: ['test/spec/{,*/}*.js'],
        tasks: ['newer:jshint:test', 'karma']
      },
      styles: {
        files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
        tasks: ['newer:copy:styles', 'autoprefixer']
      },
      less: {
        files: ['app/styles/less/*.less'],
        tasks: ['less:development'],
        options: {
          livereload: false
        }
      },
      css: {
        files: ['app/styles/*.css'],
      },
      gruntfile: {
        files: ['Gruntfile.js']
      },
      livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          '<%= yeoman.app %>/{,*/}*.html',
          '.tmp/styles/{,*/}*.css',
          '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },

    // The actual grunt server settings
    connect: {
      options: {
        port: 9000,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: 'localhost',
        livereload: 35729
      },

      livereload: {

        options: {
          open: true,
          middleware: function (connect) {
            return [
              modRewrite(['^[^\\.]*$ /index.html [L]']),
              connect.static('.tmp'),
              connect().use(
                '/bower_components',
                connect.static('./bower_components')
              ),
              connect.static(appConfig.app)
            ];
          }
        }
      },
      test: {
        options: {
          port: 9001,
          middleware: function (connect) {
            return [
              connect.static('.tmp'),
              connect.static('test'),
              connect().use(
                '/bower_components',
                connect.static('./bower_components')
              ),
              connect.static(appConfig.app)
            ];
          }
        }
      },
      dist: {
        options: {
          open: true,
          base: '<%= yeoman.dist %>'
        }
      }
    },

    // Make sure code styles are up to par and there are no obvious mistakes
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: {
        src: [
          'Gruntfile.js',
          '<%= yeoman.app %>/scripts/{,*/}*.js'
        ]
      },
      test: {
        options: {
          jshintrc: 'test/.jshintrc'
        },
        src: ['test/spec/{,*/}*.js']
      }
    },

    // Compile less
    less: {
      development: {
        options: {
          paths: ['assets/css']
        },
        files: {
          'app/styles/style.css': 'app/styles/less/*.less'
        }
      },
      production: {
        options: {
          paths: ['assets/css'],
          cleancss: true,
          modifyVars: {
            imgPath: '"http://mycdn.com/path/to/images"',
            bgColor: 'red'
          }
        },
        files: {
          'app/styles/style.css': 'app/styles/less/*.less'
        }
      }
    },

    // Empties folders to start fresh
    clean: {
      dist: {
        files: [{
          dot: true,
          src: [
            '.tmp',
            '<%= yeoman.dist %>/{,*/}*',
            '!<%= yeoman.dist %>/.git*'
          ]
        }]
      },
      server: '.tmp'
    },

    // Add vendor prefixed styles
    autoprefixer: {
      options: {
        browsers: ['last 1 version']
      },
      dist: {
        files: [{
          expand: true,
          cwd: '.tmp/styles/',
          src: '{,*/}*.css',
          dest: '.tmp/styles/'
        }]
      }
    },

    // Automatically inject Bower components into the app
    wiredep: {
      app: {
        src: ['<%= yeoman.app %>/index.html'],
        ignorePath:  /\.\.\//
      }
    },

    // Renames files for browser caching purposes
    filerev: {
      dist: {
        src: [
          '<%= yeoman.dist %>/scripts/{,*/}*.js',
          '<%= yeoman.dist %>/styles/{,*/}*.css',
          '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
          '<%= yeoman.dist %>/styles/fonts/*'
        ]
      }
    },

    // Reads HTML for usemin blocks to enable smart builds that automatically
    // concat, minify and revision files. Creates configurations in memory so
    // additional tasks can operate on them
    useminPrepare: {
      html: '<%= yeoman.app %>/index.html',
      options: {
        dest: '<%= yeoman.dist %>',
        flow: {
          html: {
            steps: {
              js: ['concat', 'uglifyjs'],
              css: ['cssmin']
            },
            post: {}
          }
        }
      }
    },

    // Performs rewrites based on filerev and the useminPrepare configuration
    usemin: {
      html: ['<%= yeoman.dist %>/{,*/}*.html'],
      css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
      options: {
        assetsDirs: ['<%= yeoman.dist %>','<%= yeoman.dist %>/images']
      }
    },

    // The following *-min tasks will produce minified files in the dist folder
    // By default, your `index.html`'s <!-- Usemin block --> will take care of
    // minification. These next options are pre-configured if you do not wish
    // to use the Usemin blocks.
    // cssmin: {
    //   dist: {
    //     files: {
    //       '<%= yeoman.dist %>/styles/main.css': [
    //         '.tmp/styles/{,*/}*.css'
    //       ]
    //     }
    //   }
    // },
    // uglify: {
    //   dist: {
    //     files: {
    //       '<%= yeoman.dist %>/scripts/scripts.js': [
    //         '<%= yeoman.dist %>/scripts/scripts.js'
    //       ]
    //     }
    //   }
    // },
    // concat: {
    //   dist: {}
    // },

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

    svgmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>/images',
          src: '{,*/}*.svg',
          dest: '<%= yeoman.dist %>/images'
        }]
      }
    },

    htmlmin: {
      dist: {
        options: {
          collapseWhitespace: true,
          conservativeCollapse: true,
          collapseBooleanAttributes: true,
          removeCommentsFromCDATA: true,
          removeOptionalTags: true
        },
        files: [{
          expand: true,
          cwd: '<%= yeoman.dist %>',
          src: ['*.html', 'views/{,*/}*.html'],
          dest: '<%= yeoman.dist %>'
        }]
      }
    },

    // ng-annotate tries to make the code safe for minification automatically
    // by using the Angular long form for dependency injection.
    ngAnnotate: {
      dist: {
        files: [{
          expand: true,
          cwd: '.tmp/concat/scripts',
          src: ['*.js', '!oldieshim.js'],
          dest: '.tmp/concat/scripts'
        }]
      }
    },

    // Replace Google CDN references
    cdnify: {
      dist: {
        html: ['<%= yeoman.dist %>/*.html']
      }
    },

    // Copies remaining files to places other tasks can use
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= yeoman.app %>',
          dest: '<%= yeoman.dist %>',
          src: [
            '*.{ico,png,txt}',
            '.htaccess',
            '*.html',
            'views/{,*/}*.html',
            'images/{,*/}*.{webp}',
            'fonts/*'
          ]
        }, {
          expand: true,
          cwd: '.tmp/images',
          dest: '<%= yeoman.dist %>/images',
          src: ['generated/*']
        }, {
          expand: true,
          cwd: 'bower_components/bootstrap/dist',
          src: 'fonts/*',
          dest: '<%= yeoman.dist %>'
        }]
      },
      styles: {
        expand: true,
        cwd: '<%= yeoman.app %>/styles',
        dest: '.tmp/styles/',
        src: '{,*/}*.css'
      }
    },

    // Run some tasks in parallel to speed up the build process
    concurrent: {
      server: [
        'copy:styles'
      ],
      test: [
        'copy:styles'
      ],
      dist: [
        'copy:styles',
        'imagemin',
        'svgmin'
      ]
    },

    // Test settings
    karma: {
      unit: {
        configFile: 'test/karma.conf.js',
        singleRun: true
      }
    },

    replace: {
      host: {
        src: ['dist/scripts/*.js'],
        overwrite: true,                 // overwrite matched source files
        replacements: [{
          from: 'http://localhost:8003',
          to: 'http://sparkwaves-env-apg22ebmpm.elasticbeanstalk.com'
        }]
      }
    },

    aws: grunt.file.readJSON('aws-keys.json'), // Read the file

    aws_s3: {
      options: {
        accessKeyId: '<%= aws.AWSAccessKeyId %>', // Use the variables
        secretAccessKey: '<%= aws.AWSSecretKey %>', // You can also use env variables
        region: 'us-east-1',
        uploadConcurrency: 1,
        downloadConcurrency: 2
      },

      production: {
        options: {
          bucket: 'www.sparkwaves.com',

        },
        files: [
          {expand: true, cwd: 'dist/', src: ['**'], dest: ''},
        ]
      },
      clean: {
        options: {
          bucket: 'www.sparkwaves.com',
          debug: false // Doesn't actually delete but shows log
        },
        files: [
          {dest: '/', action: 'delete'},
        ]
      },
      download: {
        options: {
          bucket: 'www.sparkwaves.com'
        },
        files: [
          {dest: '', cwd: 'backup/', action: 'download'}, // Downloads the content of app/ to backup/
        ]
      },
    },
  });

  grunt.registerTask('serve', 'Compile then start a connect web server', function (target) {
    if (target === 'dist') {
      return grunt.task.run(['build', 'connect:dist:keepalive']);
    }

    grunt.task.run([
      'clean:server',
      'wiredep',
      'concurrent:server',
      'autoprefixer',
      'connect:livereload',
      'watch'
    ]);
  });

  grunt.registerTask('server', 'DEPRECATED TASK. Use the "serve" task instead', function (target) {
    grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
    grunt.task.run(['serve:' + target]);
  });

  grunt.registerTask('test', [
    'clean:server',
    'concurrent:test',
    'autoprefixer',
    'connect:test',
    'karma'
  ]);

  grunt.registerTask('build', [
    'clean:dist',
    'wiredep',
    'useminPrepare',
    'concurrent:dist',
    'autoprefixer',
    'concat',
    'ngAnnotate',
    'copy:dist',
    'cdnify',
    'cssmin',
    'uglify',
    'filerev',
    'usemin',
    'htmlmin'
  ]);

  grunt.registerTask('deploy', [
    'clean:dist',
    'wiredep',
    'useminPrepare',
    'concurrent:dist',
    'autoprefixer',
    'concat',
    'ngAnnotate',
    'copy:dist',
    'cdnify',
    'cssmin',
    'uglify',
    'filerev',
    'usemin',
    'htmlmin',
    'replace:host',
    'aws_s3:clean',
    'aws_s3:production',
  ]);

  grunt.registerTask('default', [
    'newer:jshint',
    'test',
    'build'
  ]);
};
<commit_msg>updated backend url<commit_after>// Generated on 2015-03-30 using generator-angular 0.9.8
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {

  // Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);

  // Time how long tasks take. Can help when optimizing build times
  require('time-grunt')(grunt);

  // Support HTML5 mode in development
  var modRewrite = require('connect-modrewrite');

  //Load s3 library
  grunt.loadNpmTasks('grunt-aws-s3');

  // Load less compiller
  grunt.loadNpmTasks('grunt-contrib-less');

  // Configurable paths for the application
  var appConfig = {
    app: require('./bower.json').appPath || 'app',
    dist: 'dist'
  };

  // Define the configuration for all the tasks
  grunt.initConfig({

    // Project settings
    yeoman: appConfig,

    // Watches files for changes and runs tasks based on the changed files
    watch: {
      bower: {
        files: ['bower.json'],
        tasks: ['wiredep']
      },
      js: {
        files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
        tasks: ['newer:jshint:all'],
        options: {
          livereload: '<%= connect.options.livereload %>'
        }
      },
      jsTest: {
        files: ['test/spec/{,*/}*.js'],
        tasks: ['newer:jshint:test', 'karma']
      },
      styles: {
        files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
        tasks: ['newer:copy:styles', 'autoprefixer']
      },
      less: {
        files: ['app/styles/less/*.less'],
        tasks: ['less:development'],
        options: {
          livereload: false
        }
      },
      css: {
        files: ['app/styles/*.css'],
      },
      gruntfile: {
        files: ['Gruntfile.js']
      },
      livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          '<%= yeoman.app %>/{,*/}*.html',
          '.tmp/styles/{,*/}*.css',
          '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },

    // The actual grunt server settings
    connect: {
      options: {
        port: 9000,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: 'localhost',
        livereload: 35729
      },

      livereload: {

        options: {
          open: true,
          middleware: function (connect) {
            return [
              modRewrite(['^[^\\.]*$ /index.html [L]']),
              connect.static('.tmp'),
              connect().use(
                '/bower_components',
                connect.static('./bower_components')
              ),
              connect.static(appConfig.app)
            ];
          }
        }
      },
      test: {
        options: {
          port: 9001,
          middleware: function (connect) {
            return [
              connect.static('.tmp'),
              connect.static('test'),
              connect().use(
                '/bower_components',
                connect.static('./bower_components')
              ),
              connect.static(appConfig.app)
            ];
          }
        }
      },
      dist: {
        options: {
          open: true,
          base: '<%= yeoman.dist %>'
        }
      }
    },

    // Make sure code styles are up to par and there are no obvious mistakes
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: {
        src: [
          'Gruntfile.js',
          '<%= yeoman.app %>/scripts/{,*/}*.js'
        ]
      },
      test: {
        options: {
          jshintrc: 'test/.jshintrc'
        },
        src: ['test/spec/{,*/}*.js']
      }
    },

    // Compile less
    less: {
      development: {
        options: {
          paths: ['assets/css']
        },
        files: {
          'app/styles/style.css': 'app/styles/less/*.less'
        }
      },
      production: {
        options: {
          paths: ['assets/css'],
          cleancss: true,
          modifyVars: {
            imgPath: '"http://mycdn.com/path/to/images"',
            bgColor: 'red'
          }
        },
        files: {
          'app/styles/style.css': 'app/styles/less/*.less'
        }
      }
    },

    // Empties folders to start fresh
    clean: {
      dist: {
        files: [{
          dot: true,
          src: [
            '.tmp',
            '<%= yeoman.dist %>/{,*/}*',
            '!<%= yeoman.dist %>/.git*'
          ]
        }]
      },
      server: '.tmp'
    },

    // Add vendor prefixed styles
    autoprefixer: {
      options: {
        browsers: ['last 1 version']
      },
      dist: {
        files: [{
          expand: true,
          cwd: '.tmp/styles/',
          src: '{,*/}*.css',
          dest: '.tmp/styles/'
        }]
      }
    },

    // Automatically inject Bower components into the app
    wiredep: {
      app: {
        src: ['<%= yeoman.app %>/index.html'],
        ignorePath:  /\.\.\//
      }
    },

    // Renames files for browser caching purposes
    filerev: {
      dist: {
        src: [
          '<%= yeoman.dist %>/scripts/{,*/}*.js',
          '<%= yeoman.dist %>/styles/{,*/}*.css',
          '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
          '<%= yeoman.dist %>/styles/fonts/*'
        ]
      }
    },

    // Reads HTML for usemin blocks to enable smart builds that automatically
    // concat, minify and revision files. Creates configurations in memory so
    // additional tasks can operate on them
    useminPrepare: {
      html: '<%= yeoman.app %>/index.html',
      options: {
        dest: '<%= yeoman.dist %>',
        flow: {
          html: {
            steps: {
              js: ['concat', 'uglifyjs'],
              css: ['cssmin']
            },
            post: {}
          }
        }
      }
    },

    // Performs rewrites based on filerev and the useminPrepare configuration
    usemin: {
      html: ['<%= yeoman.dist %>/{,*/}*.html'],
      css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
      options: {
        assetsDirs: ['<%= yeoman.dist %>','<%= yeoman.dist %>/images']
      }
    },

    // The following *-min tasks will produce minified files in the dist folder
    // By default, your `index.html`'s <!-- Usemin block --> will take care of
    // minification. These next options are pre-configured if you do not wish
    // to use the Usemin blocks.
    // cssmin: {
    //   dist: {
    //     files: {
    //       '<%= yeoman.dist %>/styles/main.css': [
    //         '.tmp/styles/{,*/}*.css'
    //       ]
    //     }
    //   }
    // },
    // uglify: {
    //   dist: {
    //     files: {
    //       '<%= yeoman.dist %>/scripts/scripts.js': [
    //         '<%= yeoman.dist %>/scripts/scripts.js'
    //       ]
    //     }
    //   }
    // },
    // concat: {
    //   dist: {}
    // },

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

    svgmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>/images',
          src: '{,*/}*.svg',
          dest: '<%= yeoman.dist %>/images'
        }]
      }
    },

    htmlmin: {
      dist: {
        options: {
          collapseWhitespace: true,
          conservativeCollapse: true,
          collapseBooleanAttributes: true,
          removeCommentsFromCDATA: true,
          removeOptionalTags: true
        },
        files: [{
          expand: true,
          cwd: '<%= yeoman.dist %>',
          src: ['*.html', 'views/{,*/}*.html'],
          dest: '<%= yeoman.dist %>'
        }]
      }
    },

    // ng-annotate tries to make the code safe for minification automatically
    // by using the Angular long form for dependency injection.
    ngAnnotate: {
      dist: {
        files: [{
          expand: true,
          cwd: '.tmp/concat/scripts',
          src: ['*.js', '!oldieshim.js'],
          dest: '.tmp/concat/scripts'
        }]
      }
    },

    // Replace Google CDN references
    cdnify: {
      dist: {
        html: ['<%= yeoman.dist %>/*.html']
      }
    },

    // Copies remaining files to places other tasks can use
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= yeoman.app %>',
          dest: '<%= yeoman.dist %>',
          src: [
            '*.{ico,png,txt}',
            '.htaccess',
            '*.html',
            'views/{,*/}*.html',
            'images/{,*/}*.{webp}',
            'fonts/*'
          ]
        }, {
          expand: true,
          cwd: '.tmp/images',
          dest: '<%= yeoman.dist %>/images',
          src: ['generated/*']
        }, {
          expand: true,
          cwd: 'bower_components/bootstrap/dist',
          src: 'fonts/*',
          dest: '<%= yeoman.dist %>'
        }]
      },
      styles: {
        expand: true,
        cwd: '<%= yeoman.app %>/styles',
        dest: '.tmp/styles/',
        src: '{,*/}*.css'
      }
    },

    // Run some tasks in parallel to speed up the build process
    concurrent: {
      server: [
        'copy:styles'
      ],
      test: [
        'copy:styles'
      ],
      dist: [
        'copy:styles',
        'imagemin',
        'svgmin'
      ]
    },

    // Test settings
    karma: {
      unit: {
        configFile: 'test/karma.conf.js',
        singleRun: true
      }
    },

    replace: {
      host: {
        src: ['dist/scripts/*.js'],
        overwrite: true,                 // overwrite matched source files
        replacements: [{
          from: 'http://localhost:8003',
          to: 'http://sparkwaves-env-q7g3pzats8.elasticbeanstalk.com'
        }]
      }
    },

    aws: grunt.file.readJSON('aws-keys.json'), // Read the file

    aws_s3: {
      options: {
        accessKeyId: '<%= aws.AWSAccessKeyId %>', // Use the variables
        secretAccessKey: '<%= aws.AWSSecretKey %>', // You can also use env variables
        region: 'us-east-1',
        uploadConcurrency: 1,
        downloadConcurrency: 2
      },

      production: {
        options: {
          bucket: 'www.sparkwaves.com',

        },
        files: [
          {expand: true, cwd: 'dist/', src: ['**'], dest: ''},
        ]
      },
      clean: {
        options: {
          bucket: 'www.sparkwaves.com',
          debug: false // Doesn't actually delete but shows log
        },
        files: [
          {dest: '/', action: 'delete'},
        ]
      },
      download: {
        options: {
          bucket: 'www.sparkwaves.com'
        },
        files: [
          {dest: '', cwd: 'backup/', action: 'download'}, // Downloads the content of app/ to backup/
        ]
      },
    },
  });

  grunt.registerTask('serve', 'Compile then start a connect web server', function (target) {
    if (target === 'dist') {
      return grunt.task.run(['build', 'connect:dist:keepalive']);
    }

    grunt.task.run([
      'clean:server',
      'wiredep',
      'concurrent:server',
      'autoprefixer',
      'connect:livereload',
      'watch'
    ]);
  });

  grunt.registerTask('server', 'DEPRECATED TASK. Use the "serve" task instead', function (target) {
    grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
    grunt.task.run(['serve:' + target]);
  });

  grunt.registerTask('test', [
    'clean:server',
    'concurrent:test',
    'autoprefixer',
    'connect:test',
    'karma'
  ]);

  grunt.registerTask('build', [
    'clean:dist',
    'wiredep',
    'useminPrepare',
    'concurrent:dist',
    'autoprefixer',
    'concat',
    'ngAnnotate',
    'copy:dist',
    'cdnify',
    'cssmin',
    'uglify',
    'filerev',
    'usemin',
    'htmlmin'
  ]);

  grunt.registerTask('deploy', [
    'clean:dist',
    'wiredep',
    'useminPrepare',
    'concurrent:dist',
    'autoprefixer',
    'concat',
    'ngAnnotate',
    'copy:dist',
    'cdnify',
    'cssmin',
    'uglify',
    'filerev',
    'usemin',
    'htmlmin',
    'replace:host',
    'aws_s3:clean',
    'aws_s3:production',
  ]);

  grunt.registerTask('default', [
    'newer:jshint',
    'test',
    'build'
  ]);
};
<|endoftext|>


<commit_before>PokeyI = function(bot) {

  this.bot = bot;
};

BattleRoles = {

	'sweeperAtk': 0,
	'sweeperSpa': 1,

	'wallDef': 2,
	'wallSpd': 3,

	'pivotOff': 4,
	'pivotDef': 5,

	'wallbreakOff': 6,
	'wallbreakDef': 7
};

PokeyI.prototype.evalDamagingMove = function(move) {

  coef = this.getWeaknesses(this.bot.ennemy[0])[move.baseType]; // Type effectiveness
  for (i = 0; i < this.bot.pokemon.types.length; i++) { // STAB
    if (this.bot.pokemon && this.bot.pokemon.types[i] == move.baseType)
      coef *= 1.5;
  }

  if (move.id == "lowkick") {
    wgt = this.bot.ennemy[0].weightkg;
    if (wgt < 10)
      move.basePower = 20;
    else if (wgt < 25)
      move.basePower = 40;
    else if (wgt < 50)
      move.basePower = 60;
    else if (wgt < 100)
      move.basePower = 80;
    else if (wgt < 200)
      move.basePower = 100;
    else
      move.basePower = 120;
  }

  if (move.accuracy === true)
    move.accuracy = 100;

  volatileEffects = this.getMultiplicator(this.bot.pokemon, (move.category == "physical") ? 'atk' : 'spa');

  return coef * move.basePower * (move.accuracy / 100) * volatileEffects;

};

PokeyI.prototype.evalStatus = function(move) {
  coef = 1.0;
  if (this.bot.ennemy[0].status != "" ||
    (move.status == "par" && this.hasType(this.bot.ennemy[0], "Electric")) ||
    (move.status == "brn" && this.hasType(this.bot.ennemy[0], "Fire")) ||
    (move.baseType == "Grass" && this.hasType(this.bot.ennemy[0], "Grass")) ||
    (move.status == "tox" && this.hasType(this.bot.ennemy[0], "Poison"))) {
    return 0;
  }

  switch (move.status) {
    case "par":
      coef *= (this.getStat(this.bot.ennemy[0], "spe") / 100);
      break;
    case "brn":
      coef *= (this.getStat(this.bot.ennemy[0], "atk") / 100);
      break;
    case "slp":
      coef *= (this.getDanger(this.bot.ennemy[0]) / 60);
      break;
    case "tox":
      coef *= (this.getBulk(this.bot.ennemy[0]) / 100);
  }

  if (coef < 0.5)
    return 30;
  if (coef < 1)
    return 60;
  if (coef < 1.2)
    return 150;
  return 400;

};

PokeyI.prototype.evalSpin = function(move) {

  if (jQuery.isEmptyObject(this.bot.room.battle.mySide.sideConditions)) {
    console.log("Risibot: evalSpin: There is nothing to spin.");
    return 0;
  }
  return 150;
};

PokeyI.prototype.evalTraps = function(move) {

  if (this.getDanger(this.bot.ennemy[0]) > 100)
    return 0;

  switch (move.id) {
    case "stealthrock":
      if (!this.bot.room.battle.yourSide.sideConditions.stealthrock)
        return 150;
      break;
    case "spikes":
      if (!this.bot.room.battle.yourSide.sideConditions.spikes)
        return 150;
      break;
    case "stickyweb":
      if (!this.bot.room.battle.yourSide.sideConditions.stickyweb)
        return 150;
      break;
  }
  console.log("Risibot: evalTraps: Entry hazards are already set.");
  return 0;
};

PokeyI.prototype.evalHeal = function(move) {

  hp = this.bot.pokemon.hp / this.bot.pokemon.hpmax;
  if (hp < 25)
    return 1500;
  if (hp < 50)
    return 1000;
  if (hp < 60)
    return 500;
  if (hp < 75)
    return 100;
  if (hp < 90)
    return 30;
  return 0;
};

PokeyI.prototype.hasType = function(pokemon, type) {
  for (var i = 0; i < pokemon.types.length; i++) {
    if (pokemon.types[i] == type)
      return true;
  }
  return false;
};

PokeyI.prototype.getStat = function(pokemon, stat) {
	return pokemon.baseStats[stat];
};

PokeyI.prototype.getBulk = function(pokemon) {
  return (this.getStat(pokemon, 'hp') / 2 +
    Math.max(this.getStat(pokemon, 'def'), this.getStat(pokemon, 'spd')) / 2);
};

PokeyI.prototype.getDanger = function(pokemon) {
  return (this.getStat(pokemon, 'spe') / 2 / (pokemon.status == 'par' ? 4 : 1) +
    Math.max(this.getStat(pokemon, 'atk') / (pokemon.status == 'brn' ? 2 : 1), this.getStat(pokemon, 'spa')) / 2);
};

PokeyI.prototype.getMultiplicator = function(pokemon, stat) {
  console.log(pokemon.boosts[stat]);
  if (pokemon.boosts[stat] > 0)
    return 1.0 + 0.5 * pokemon.boosts[stat];
  else if (pokemon.boosts[stat] < 0)
    switch (pokemon.boosts[stat]) {
      case -1:
        return 0.67;
      case -2:
        return 0.5;
      case -3:
        return 0.4;
      case -4:
        return 0.33;
      case -5:
        return 0.29;
      case -6:
        return 0.25;
    }
  return 1.0;
};

PokeyI.prototype.getWeaknesses = function(poke) { //Takes a fullPokemon for argument
  //Returns a dictionnary of the pokemon weaknesses

  var id = poke.speciesid;
  var ab = [""];
  var init = ["Bug", "Dark", "Dragon", "Electric", "Fairy", "Fighting", "Fire", "Flying",
    "Ghost", "Grass", "Ground", "Ice", "Normal", "Poison", "Psychic", "Rock",
    "Steel", "Water", "powder", "par", "psn", "tox", "brn", "trapped"
  ];

  for (var i in exports.BattlePokedex[id].abilities) {
    ab.push(exports.BattlePokedex[id].abilities[i]);
  }

  var weaknesses = {};

  for (var i = 0; i < init.length; i++) {
    weaknesses[init[i]] = 1.0;
  }

  for (var i = 0; i < poke.types.length; i++) {
    t = poke.types[i];
    for (var j in exports.BattleTypeChart[t]['damageTaken']) {
      switch (exports.BattleTypeChart[t]['damageTaken'][j]) {
        case 1:
          weaknesses[j] *= 2.0;
          break;
        case 2:
          weaknesses[j] *= 0.5;
          break;
        case 3:
          weaknesses[j] *= 0.0;
          break;
      }
    }
  }

  for (var i = 0; i < ab.length; i++) {
    if (ab[i] == "Dry Skin") {
      weaknesses["Fire"] *= 1.25;
      weaknesses["Water"] = 0.0;
    } else if (ab[i] == "Filter" || ab[i] == "Solid Rock") {
      for (var j in exports.BattleTypeChart[t]['damageTaken']) {
        if (weaknesses[j] == 2.0 || weaknesses == 4.0) {
          weaknesses[j] *= 0.75;
        }
      }
    } else if (ab[i] == "Flash Fire") {
      weaknesses["Fire"] = 0.0;
    } else if (ab[i] == "HeatProof") {
      weaknesses["Fire"] *= 0.5;
    } else if (ab[i] == "Levitate") {
      weaknesses["Ground"] = 0.0;
    } else if (ab[i] == "Thick Fat") {
      weaknesses["Fire"] *= 0.5;
      weaknesses["Ice"] *= 0.5;
    } else if (ab[i] == "Volt Absorb" || ab[i] == "Lightningrod" || ab[i] == "Motor Drive") {
      weaknesses["Electric"] = 0.0;
      weaknesses["par"] = 0.0;
    } else if (ab[i] == "Water Absorb" || ab[i] == "Storm Drain") {
      weaknesses["Water"] = 0.0;
    } else if (ab[i] == "Wonder Guard") {
      for (var j in exports.BattleTypeChart[t]['damageTaken']) {
        if (weaknesses[j] != 2.0 && weaknesses != 4.0) {
          weaknesses[j] = 0.0;
        }
      }
    } else if (ab[i] == "Sap Sipper") {
      weaknesses["Grass"] = 0.0;
      weaknesses["powder"] = 0.0;
    } else if (ab[i] == "Poison Heal") {
      weaknesses["tox"] = 0.0;
      weaknesses["psn"] = 0.0;
    }
  }

  return weaknesses;
};

PokeyI.prototype.evalSwitch = function(pokemon) {
	var coef = 100.0;
	var weaknesses = this.getWeaknesses(pokemon);
	for (var i = 0; i < this.bot.ennemy[0].types; i++)
		coef *= (1.0 / weaknesses[this.bot.ennemy[0][i]]);
};

PokeyI.prototype.getExpectedRole = function(pokemon) {
	// val in BattleRoles
	potentialRoles = [];

	// Simple cartesian norma
	potentialRoles.push(this.distance(this.getStat(pokemon, 'atk'), this.getStat(pokemon, 'spe'))); //swp a
	potentialRoles.push(this.distance(this.getStat(pokemon, 'spa'), this.getStat(pokemon, 'spe'))); // swp s
	potentialRoles.push(this.distance(this.getStat(pokemon, 'hp'), this.getStat(pokemon, 'def'))); // wall def
	potentialRoles.push(this.distance(this.getStat(pokemon, 'hp'), this.getStat(pokemon, 'spd'))); // wall off
	potentialRoles.push(this.distance(this.getStat(pokemon, 'atk'), this.getStat(pokemon, 'spe'))); // piv off
	potentialRoles.push(this.distance(this.getStat(pokemon, 'def'), this.getStat(pokemon, 'spd'))); // piv def
	potentialRoles.push(this.distance(this.getStat(pokemon, 'atk'), this.getStat(pokemon, 'atk'))); // wb off
	potentialRoles.push(this.distance(this.getStat(pokemon, 'atk'), this.getStat(pokemon, 'def'))); // wb def

	// We apply more coefs
	potentialRoles[BattleRoles.wallDef] *= this.getPotentialWall(pokemon, 'def');
	potentialRoles[BattleRoles.wallSpd] *= this.getPotentialWall(pokemon, 'spd');

	return potentialRoles;
};

PokeyI.prototype.distance = function(a, b) {
	return Math.sqrt(a*a + b*b);
};

PokeyI.prototype.getPotentialWall = function(pokemon, type) { // Can pokemon be a good wall ?
	coef = Math.pow(2, parseFloat(this.getStat(pokemon, type) - 80) / 30);
	if (this.canHeal(pokemon)) // Increases greatly the staying power
		coef *= 1.5;
	else
		coef *= 0.67;
	if (this.canCure(pokemon)) // Not as important, but cool.
		coef *= 1.2;
	return coef * this.passiveHeal(pokemon); // Leech seed / ingrain ... / POISON HEAL !!
};

PokeyI.prototype.canHeal = function(pokemon) { // If pokemon can learn viable heal moves
	var name = pokemon.species.toLowerCase();
	for (var move in BattleLearnsets[name].learnset) {
		switch (move) {
			case 'roost':
			case 'recover':
			case 'slackoff':
			case 'softboiled':
			case 'milkdrink':
			case 'synthesis':
			case 'morningsun':
			case 'moonlight':
			case 'wish':
			case 'healorder':
				return true;
		}
	}
	return false;
};

PokeyI.prototype.canCure = function(pokemon) { // If pokemon can learn viable heal moves
	var name = pokemon.species.toLowerCase();
	for (var move in BattleLearnsets[name].learnset) {
		switch (move) {
			case 'healbell':
			case 'aromatherapy':
				return true;
		}
	}
	return false;
};

PokeyI.prototype.passiveHeal = function(pokemon) { // If pokemon can learn viable heal moves
	var coef = 1.0;
	var name = pokemon.species.toLowerCase();
	for (var move in BattleLearnsets[name].learnset) {
		switch (move) {
			case 'aquaring':
			case 'leechseed':
			case 'ingrain':
				coef *= 1.1;
		}
	}
	for (var a in BattlePokedex[name].abilities) {
		switch (BattlePokedex[name].abilities[a]) {
			case 'Poison Heal':
				coef *= 1.5;
		}
	}
	return coef;
};
<commit_msg>Update PokeyI.js<commit_after>PokeyI = function(bot) {

  this.bot = bot;
};

BattleRoles = {

  'sweeperAtk': 0,
  'sweeperSpa': 1,

  'wallDef': 2,
  'wallSpd': 3,

  'pivotOff': 4,
  'pivotDef': 5,

  'wallbreakOff': 6,
  'wallbreakDef': 7
};

PokeyI.prototype.evalDamagingMove = function(move) {

  coef = this.getWeaknesses(this.bot.ennemy[0])[move.baseType]; // Type effectiveness
  for (i = 0; i < this.bot.pokemon.types.length; i++) { // STAB
    if (this.bot.pokemon && this.bot.pokemon.types[i] == move.baseType)
      coef *= 1.5;
  }

  if (move.id == "lowkick") {
    wgt = this.bot.ennemy[0].weightkg;
    if (wgt < 10)
      move.basePower = 20;
    else if (wgt < 25)
      move.basePower = 40;
    else if (wgt < 50)
      move.basePower = 60;
    else if (wgt < 100)
      move.basePower = 80;
    else if (wgt < 200)
      move.basePower = 100;
    else
      move.basePower = 120;
  }

  if (move.accuracy === true)
    move.accuracy = 100;

  volatileEffects = this.getMultiplicator(this.bot.pokemon, (move.category == "physical") ? 'atk' : 'spa');

  return coef * move.basePower * (move.accuracy / 100) * volatileEffects;

};

PokeyI.prototype.evalStatus = function(move) {
  coef = 1.0;
  if (this.bot.ennemy[0].status != "" ||
    (move.status == "par" && this.hasType(this.bot.ennemy[0], "Electric")) ||
    (move.status == "brn" && this.hasType(this.bot.ennemy[0], "Fire")) ||
    (move.baseType == "Grass" && this.hasType(this.bot.ennemy[0], "Grass")) ||
    (move.status == "tox" && this.hasType(this.bot.ennemy[0], "Poison"))) {
    return 0;
  }

  switch (move.status) {
    case "par":
      coef *= (this.getStat(this.bot.ennemy[0], "spe") / 100);
      break;
    case "brn":
      coef *= (this.getStat(this.bot.ennemy[0], "atk") / 100);
      break;
    case "slp":
      coef *= (this.getDanger(this.bot.ennemy[0]));
      break;
    case "tox":
      coef *= (this.getBulk(this.bot.ennemy[0]) / 100);
  }

  if (coef < 0.5)
    return 30;
  if (coef < 1)
    return 60;
  if (coef < 1.2)
    return 150;
  return 400;

};

PokeyI.prototype.evalSpin = function(move) {

  if (jQuery.isEmptyObject(this.bot.room.battle.mySide.sideConditions)) {
    console.log("Risibot: evalSpin: There is nothing to spin.");
    return 0;
  }
  return 150;
};

PokeyI.prototype.evalTraps = function(move) {

  if (this.getDanger(this.bot.ennemy[0]) > 100)
    return 0;

  switch (move.id) {
    case "stealthrock":
      if (!this.bot.room.battle.yourSide.sideConditions.stealthrock)
        return 150;
      break;
    case "spikes":
      if (!this.bot.room.battle.yourSide.sideConditions.spikes)
        return 150;
      break;
    case "stickyweb":
      if (!this.bot.room.battle.yourSide.sideConditions.stickyweb)
        return 150;
      break;
  }
  console.log("Risibot: evalTraps: Entry hazards are already set.");
  return 0;
};

PokeyI.prototype.evalHeal = function(move) {

  hp = this.bot.pokemon.hp / this.bot.pokemon.hpmax;
  if (hp < 25)
    return 1500;
  if (hp < 50)
    return 1000;
  if (hp < 60)
    return 500;
  if (hp < 75)
    return 100;
  if (hp < 90)
    return 30;
  return 0;
};

PokeyI.prototype.evalSeeds = function(move) {

  if (this.bot.ennemy[0].volatiles.leechseed)
    return 0;

  if (this.getDanger(this.bot.pokemon, this.bot.ennemy[0]) < 0.3) // Ennemy could switch
    return 100;
  if (this.getDanger(this.bot.pokemon, this.bot.ennemy[0]) < 0.8) // Ennemy will probably not switch
    return 300;
  if (this.getDanger(this.bot.pokemon, this.bot.ennemy[0]) < 1.5) // It's crucial to survive
    return 399;

};

PokeyI.prototype.hasType = function(pokemon, type) {
  for (var i = 0; i < pokemon.types.length; i++) {
    if (pokemon.types[i] == type)
      return true;
  }
  return false;
};

PokeyI.prototype.getStat = function(pokemon, stat) {
  return pokemon.baseStats[stat];
};

PokeyI.prototype.getBulk = function(pokemon) {
  return (this.getStat(pokemon, 'hp') / 2 +
    Math.max(this.getStat(pokemon, 'def'), this.getStat(pokemon, 'spd')) / 2);
};

PokeyI.prototype.getDanger = function(attacker, defender) {

  var atkType; // We first try to determine what kind of attacker ennemy is.
  (this.getStat(attacker, 'atk') >= this.getStat(attacker, 'spa')) ? atkType = 'atk': atkType = 'spa';

  var potentialO = (this.getStat(attacker, 'spe') / 2 / (attacker.status == 'par' ? 4 : 1) + // We calculate an offensive power
    this.getStat(attacker, atkType) / 2 / ((attacker.status == 'brn' && atkType == 'atk') ? 2 : 1));

  var increased = false;
  for (var i = 0; i < attacker.types.length; i++) { // We calculate the type effectiveness
    w = Math.max(this.getWeaknesses(defender)[attacker.types[i]], 0.5);
    if (w > 1 && !increased) {
      potentialO *= w;
      increased = true;
    }
  }

  var potentialD = (this.getStat(defender, 'hp') / 2 / (attacker.status == 'par' ? 4 : 1) + // We calculate a defensive power
    ((atkType == 'atk') ? this.getStat(defender, 'def') : this.getStat(defender, 'spd')) / 2);

  return potentialO / potentialD;
};

PokeyI.prototype.getMultiplicator = function(pokemon, stat) {
  console.log(pokemon.boosts[stat]);
  if (pokemon.boosts[stat] > 0)
    return 1.0 + 0.5 * pokemon.boosts[stat];
  else if (pokemon.boosts[stat] < 0)
    switch (pokemon.boosts[stat]) {
      case -1:
        return 0.67;
      case -2:
        return 0.5;
      case -3:
        return 0.4;
      case -4:
        return 0.33;
      case -5:
        return 0.29;
      case -6:
        return 0.25;
    }
  return 1.0;
};

PokeyI.prototype.getWeaknesses = function(poke) { //Takes a fullPokemon for argument
  //Returns a dictionnary of the pokemon weaknesses

  var id = poke.speciesid;
  if (!id)
    id = poke.species.toLowerCase();
  var ab = [""];
  var init = ["Bug", "Dark", "Dragon", "Electric", "Fairy", "Fighting", "Fire", "Flying",
    "Ghost", "Grass", "Ground", "Ice", "Normal", "Poison", "Psychic", "Rock",
    "Steel", "Water", "powder", "par", "psn", "tox", "brn", "trapped"
  ];

  for (var i in exports.BattlePokedex[id].abilities) {
    ab.push(exports.BattlePokedex[id].abilities[i]);
  }

  var weaknesses = {};

  for (var i = 0; i < init.length; i++) {
    weaknesses[init[i]] = 1.0;
  }

  for (var i = 0; i < poke.types.length; i++) {
    t = poke.types[i];
    for (var j in exports.BattleTypeChart[t]['damageTaken']) {
      switch (exports.BattleTypeChart[t]['damageTaken'][j]) {
        case 1:
          weaknesses[j] *= 2.0;
          break;
        case 2:
          weaknesses[j] *= 0.5;
          break;
        case 3:
          weaknesses[j] *= 0.0;
          break;
      }
    }
  }

  for (var i = 0; i < ab.length; i++) {
    if (ab[i] == "Dry Skin") {
      weaknesses["Fire"] *= 1.25;
      weaknesses["Water"] = 0.0;
    } else if (ab[i] == "Filter" || ab[i] == "Solid Rock") {
      for (var j in exports.BattleTypeChart[t]['damageTaken']) {
        if (weaknesses[j] == 2.0 || weaknesses == 4.0) {
          weaknesses[j] *= 0.75;
        }
      }
    } else if (ab[i] == "Flash Fire") {
      weaknesses["Fire"] = 0.0;
    } else if (ab[i] == "HeatProof") {
      weaknesses["Fire"] *= 0.5;
    } else if (ab[i] == "Levitate") {
      weaknesses["Ground"] = 0.0;
    } else if (ab[i] == "Thick Fat") {
      weaknesses["Fire"] *= 0.5;
      weaknesses["Ice"] *= 0.5;
    } else if (ab[i] == "Volt Absorb" || ab[i] == "Lightningrod" || ab[i] == "Motor Drive") {
      weaknesses["Electric"] = 0.0;
      weaknesses["par"] = 0.0;
    } else if (ab[i] == "Water Absorb" || ab[i] == "Storm Drain") {
      weaknesses["Water"] = 0.0;
    } else if (ab[i] == "Wonder Guard") {
      for (var j in exports.BattleTypeChart[t]['damageTaken']) {
        if (weaknesses[j] != 2.0 && weaknesses != 4.0) {
          weaknesses[j] = 0.0;
        }
      }
    } else if (ab[i] == "Sap Sipper") {
      weaknesses["Grass"] = 0.0;
      weaknesses["powder"] = 0.0;
    } else if (ab[i] == "Poison Heal") {
      weaknesses["tox"] = 0.0;
      weaknesses["psn"] = 0.0;
    }
  }

  return weaknesses;
};

PokeyI.prototype.evalSwitch = function(pokemon) {
  var coef = 100.0;
  var weaknesses = this.getWeaknesses(pokemon);
  for (var i = 0; i < this.bot.ennemy[0].types; i++)
    coef *= (1.0 / weaknesses[this.bot.ennemy[0][i]]);
};

PokeyI.prototype.getExpectedRole = function(pokemon) {
  // val in BattleRoles
  potentialRoles = [];

  // Simple cartesian norma
  potentialRoles.push(this.distance(this.getStat(pokemon, 'atk'), this.getStat(pokemon, 'spe'))); //swp a
  potentialRoles.push(this.distance(this.getStat(pokemon, 'spa'), this.getStat(pokemon, 'spe'))); // swp s
  potentialRoles.push(this.distance(this.getStat(pokemon, 'hp'), this.getStat(pokemon, 'def'))); // wall def
  potentialRoles.push(this.distance(this.getStat(pokemon, 'hp'), this.getStat(pokemon, 'spd'))); // wall off
  potentialRoles.push(this.distance(this.getStat(pokemon, 'atk'), this.getStat(pokemon, 'spe'))); // piv off
  potentialRoles.push(this.distance(this.getStat(pokemon, 'def'), this.getStat(pokemon, 'spd'))); // piv def
  potentialRoles.push(this.distance(this.getStat(pokemon, 'atk'), this.getStat(pokemon, 'atk'))); // wb off
  potentialRoles.push(this.distance(this.getStat(pokemon, 'atk'), this.getStat(pokemon, 'def'))); // wb def

  // We apply more coefs
  potentialRoles[BattleRoles.wallDef] *= this.getPotentialWall(pokemon, 'def');
  potentialRoles[BattleRoles.wallSpd] *= this.getPotentialWall(pokemon, 'spd');

  return potentialRoles;
};

PokeyI.prototype.distance = function(a, b) {
  return Math.sqrt(a * a + b * b);
};

PokeyI.prototype.getPotentialWall = function(pokemon, type) { // Can pokemon be a good wall ?
  coef = Math.pow(2, parseFloat(this.getStat(pokemon, type) - 80) / 30);
  if (this.canHeal(pokemon)) // Increases greatly the staying power
    coef *= 1.5;
  else
    coef *= 0.67;
  if (this.canCure(pokemon)) // Not as important, but cool.
    coef *= 1.2;
  return coef * this.passiveHeal(pokemon); // Leech seed / ingrain ... / POISON HEAL !!
};

PokeyI.prototype.canHeal = function(pokemon) { // If pokemon can learn viable heal moves
  var name = pokemon.species.toLowerCase();
  for (var move in BattleLearnsets[name].learnset) {
    switch (move) {
      case 'roost':
      case 'recover':
      case 'slackoff':
      case 'softboiled':
      case 'milkdrink':
      case 'synthesis':
      case 'morningsun':
      case 'moonlight':
      case 'wish':
      case 'healorder':
        return true;
    }
  }
  return false;
};

PokeyI.prototype.canCure = function(pokemon) { // If pokemon can learn viable heal moves
  var name = pokemon.species.toLowerCase();
  for (var move in BattleLearnsets[name].learnset) {
    switch (move) {
      case 'healbell':
      case 'aromatherapy':
        return true;
    }
  }
  return false;
};

PokeyI.prototype.passiveHeal = function(pokemon) { // If pokemon can learn viable heal moves
  var coef = 1.0;
  var name = pokemon.species.toLowerCase();
  for (var move in BattleLearnsets[name].learnset) {
    switch (move) {
      case 'aquaring':
      case 'leechseed':
      case 'ingrain':
        coef *= 1.1;
    }
  }
  for (var a in BattlePokedex[name].abilities) {
    switch (BattlePokedex[name].abilities[a]) {
      case 'Poison Heal':
        coef *= 1.5;
    }
  }
  return coef;
};
<|endoftext|>


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

  //Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
      options: {
        separator: ''
      },
      dist: {
        src: [
          'src/core.js',
          'src/modules/area.js',
          'src/modules/dendrogram.js',
          'src/modules/heatmap.js',
          'src/modules/histogram.js',
          'src/modules/horizon.js',
          'src/modules/line.js',
          'src/modules/map.js',
          'src/modules/pie.js',
          'src/modules/scatterplot.js',
          'src/modules/sparkline.js',
          'src/modules/spider.js',
          'src/modules/sunburst.js',
          'src/modules/sortedTable.js',
          'src/modules/treemap.js',
        ],
        dest: 'kd3.js'
      }
    },
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
          '<%= grunt.template.today("yyyy-mm-dd") %> */'
      },
      js: {
        files: {
          'kd3.min.js': ['kd3.js']
        }
      }
    },
    jshint: {
      foo: {
        src: "src/**/*.js"
      },
      options: {
        jshintrc: '.jshintrc'
      }
    },
    watch: {
      js: {
        files: ["src/**/*.js"],
        tasks: ['concat']
      }
    },
    copy: {
      css: {
        files: [
          { src: 'style/kd3.css', dest: 'kd3.css' }
        ]
      }
    },
    cssmin: {
      dist: {
        files: {
          'kd3.min.css' : ['kd3.css']
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-cssmin');

  grunt.registerTask('default', ['concat', 'copy']);
  grunt.registerTask('production', ['concat', 'uglify', 'copy', 'cssmin']);
  grunt.registerTask('release', ['production']);
  grunt.registerTask('lint', ['jshint']);
};
<commit_msg>more with grunt<commit_after>module.exports = function(grunt) {

  //Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
      options: {
        separator: ''
      },
      dist: {
        src: [
          'src/core.js',
          'src/modules/area.js',
          'src/modules/dendrogram.js',
          'src/modules/heatmap.js',
          'src/modules/histogram.js',
          'src/modules/horizon.js',
          'src/modules/line.js',
          'src/modules/map.js',
          'src/modules/pie.js',
          'src/modules/scatterplot.js',
          'src/modules/sparkline.js',
          'src/modules/spider.js',
          'src/modules/sunburst.js',
          'src/modules/sortedTable.js',
          'src/modules/treemap.js',
        ],
        dest: 'kd3.js'
      }
    },
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
          '<%= grunt.template.today("yyyy-mm-dd") %> */'
      },
      js: {
        files: {
          'kd3.min.js': ['kd3.js']
        }
      }
    },
    jshint: {
      foo: {
        src: "src/**/*.js"
      },
      options: {
        jshintrc: '.jshintrc'
      }
    },
    watch: {
      js: {
        files: ["src/**/*.js"],
        tasks: ['concat']
      }
    },
    copy: {
      css: {
        files: [
          { src: 'style/kd3.css', dest: 'kd3.css' }
        ]
      }
    },
    cssmin: {
      dist: {
        files: {
          'kd3.min.css' : ['kd3.css']
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-cssmin');

  grunt.registerTask('default', ['concat', 'copy', 'watch']);
  grunt.registerTask('production', ['concat', 'uglify', 'copy', 'cssmin']);
  grunt.registerTask('release', ['production']);
  grunt.registerTask('lint', ['jshint']);
};
<|endoftext|>


<commit_before>module.exports = function (grunt) {
    require('load-grunt-tasks')(grunt);

    var jsFiles = 'src/app/**/*.js';
    var otherFiles = [
        'src/app/**/*.html',
        'src/app/**/*.css',
        'src/index.html',
        'src/ChangeLog.html'
    ];
    var gruntFile = 'GruntFile.js';
    var jshintFiles = [jsFiles, gruntFile, 'profiles/*.js'];
    var bumpFiles = [
        'package.json',
        'bower.json',
        'src/app/package.json',
        'src/app/config.js'
    ];

  // Project configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        bump: {
            options: {
                files: bumpFiles,
                commitFiles: bumpFiles.concat(['src/ChangeLog.html']),
                push: false
            }
        },
        clean: {
      // vendor/*.* and package.json break the build
            build: ['dist'],
            deploy: ['deploy']
        },
        connect: {
            uses_defaults: {}
        },
        copy: {
            main: {
                files: [
                    {
                        expand: true,
                        cwd: 'src/',
                        src: ['*.html'],
                        dest: 'dist/'
                    }
                ]
            }
        },
        dojo: {
            prod: {
                options: {
          // You can also specify options to be used in all your tasks
                    profiles: [
                        'profiles/prod.build.profile.js',
                        'profiles/build.profile.js'
                    ] // Profile for build
                }
            },
            stage: {
                options: {
          // You can also specify options to be used in all your tasks
                    profiles: [
                        'profiles/stage.build.profile.js',
                        'profiles/build.profile.js'
                    ] // Profile for build
                }
            },
            options: {
        // You can also specify options to be used in all your tasks
                dojo: 'src/dojo/dojo.js', // Path to dojo.js file in dojo source
                load: 'build', // Optional: Utility to bootstrap (Default: 'build')
                releaseDir: '../dist',
                require: 'src/app/run.js', // Optional: Module to require for the build (Default: nothing)
                basePath: './src'
            }
        },
        imagemin: {
            main: {
                options: {
                    optimizationLevel: 3
                },
                files: [
                    {
                        expand: true,
                        cwd: 'src/',
            // exclude tests because some images in dojox throw errors
                        src: ['**/*.{png,jpg,gif}', '!**/tests/**/*.*'],
                        dest: 'src/'
                    }
                ]
            }
        },
        jasmine: {
            main: {
                src: ['src/app/run.js'],
                options: {
                    specs: ['src/app/**/Spec*.js'],
                    vendor: [
                        'src/jasmine-favicon-reporter/vendor/favico.js',
                        'src/jasmine-favicon-reporter/jasmine-favicon-reporter.js',
                        'src/jasmine-jsreporter/jasmine-jsreporter.js',
                        'src/app/tests/jasmineTestBootstrap.js',
                        'src/dojo/dojo.js',
                        'src/app/tests/jsReporterSanitizer.js',
                        'src/app/tests/jasmineAMDErrorChecking.js'
                    ],
                    host: 'http://localhost:8000'
                }
            }
        },
        eslint: {
            options: {
                configFile: '.eslintrc',
                fix: true
            },
            main: {
                src: jshintFiles
            }
        },
        processhtml: {
            options: {},
            main: {
                files: {
                    'dist/index.html': ['src/index.html']
                }
            }
        },
        uglify: {
            options: {
                preserveComments: false,
                sourceMap: true,
                compress: {
                    drop_console: true, // eslint-disable-line camelcase
                    passes: 2,
                    dead_code: true // eslint-disable-line camelcase
                }
            },
            stage: {
                options: {
                    compress: {
                        drop_console: false // eslint-disable-line camelcase
                    }
                },
                src: ['dist/dojo/dojo.js'],
                dest: 'dist/dojo/dojo.js'
            },
            prod: {
                files: [
                    {
                        expand: true,
                        cwd: 'dist',
                        src: '**/*.js',
                        dest: 'dist'
                    }
                ]
            }
        },
        watch: {
            eslint: {
                files: jshintFiles,
                tasks: ['eslint:main', 'jasmine:main:build']
            },
            src: {
                files: jshintFiles.concat(otherFiles),
                options: {
                    livereload: true
                }
            }
        }
    });

  // Default task.
    grunt.registerTask('default', [
        'jasmine:main:build',
        'eslint:main',
        'connect',
        'watch'
    ]);
    grunt.registerTask('build-prod', [
        'clean:build',
        'newer:imagemin:main',
        'dojo:prod',
        'uglify:prod',
        'copy:main',
        'processhtml:main'
    ]);
    grunt.registerTask('build-stage', [
        'clean:build',
        'newer:imagemin:main',
        'dojo:stage',
        'uglify:stage',
        'copy:main',
        'processhtml:main'
    ]);
};
<commit_msg>chore: clean up<commit_after>module.exports = function (grunt) {
    require('load-grunt-tasks')(grunt);

    var jsFiles = 'src/app/**/*.js';
    var otherFiles = [
        'src/app/**/*.html',
        'src/app/**/*.css',
        'src/index.html',
        'src/ChangeLog.html'
    ];
    var gruntFile = 'GruntFile.js';
    var jshintFiles = [jsFiles, gruntFile, 'profiles/*.js'];
    var bumpFiles = [
        'package.json',
        'bower.json',
        'src/app/package.json',
        'src/app/config.js'
    ];

    // Project configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        bump: {
            options: {
                files: bumpFiles,
                commitFiles: bumpFiles.concat(['src/ChangeLog.html']),
                push: false
            }
        },
        clean: {
            // vendor/*.* and package.json break the build
            build: ['dist'],
            deploy: ['deploy']
        },
        connect: {
            uses_defaults: {}
        },
        copy: {
            main: {
                files: [
                    {
                        expand: true,
                        cwd: 'src/',
                        src: ['*.html'],
                        dest: 'dist/'
                    }
                ]
            }
        },
        dojo: {
            prod: {
                options: {
                    profiles: [
                        'profiles/prod.build.profile.js',
                        'profiles/build.profile.js'
                    ]
                }
            },
            stage: {
                options: {
                    profiles: [
                        'profiles/stage.build.profile.js',
                        'profiles/build.profile.js'
                    ]
                }
            },
            options: {
                dojo: 'src/dojo/dojo.js',
                load: 'build',
                releaseDir: '../dist',
                require: 'src/app/run.js',
                basePath: './src'
            }
        },
        imagemin: {
            main: {
                options: {
                    optimizationLevel: 3
                },
                files: [
                    {
                        expand: true,
                        cwd: 'src/',
                        // exclude tests because some images in dojox throw errors
                        src: ['**/*.{png,jpg,gif}', '!**/tests/**/*.*'],
                        dest: 'src/'
                    }
                ]
            }
        },
        jasmine: {
            main: {
                src: ['src/app/run.js'],
                options: {
                    specs: ['src/app/**/Spec*.js'],
                    vendor: [
                        'src/jasmine-favicon-reporter/vendor/favico.js',
                        'src/jasmine-favicon-reporter/jasmine-favicon-reporter.js',
                        'src/jasmine-jsreporter/jasmine-jsreporter.js',
                        'src/app/tests/jasmineTestBootstrap.js',
                        'src/dojo/dojo.js',
                        'src/app/tests/jsReporterSanitizer.js',
                        'src/app/tests/jasmineAMDErrorChecking.js'
                    ],
                    host: 'http://localhost:8000'
                }
            }
        },
        eslint: {
            options: {
                configFile: '.eslintrc',
                fix: true
            },
            main: {
                src: jshintFiles
            }
        },
        processhtml: {
            options: {},
            main: {
                files: {
                    'dist/index.html': ['src/index.html']
                }
            }
        },
        uglify: {
            options: {
                preserveComments: false,
                sourceMap: true,
                compress: {
                    drop_console: true, // eslint-disable-line camelcase
                    passes: 2,
                    dead_code: true // eslint-disable-line camelcase
                }
            },
            stage: {
                options: {
                    compress: {
                        drop_console: false // eslint-disable-line camelcase
                    }
                },
                src: ['dist/dojo/dojo.js'],
                dest: 'dist/dojo/dojo.js'
            },
            prod: {
                files: [
                    {
                        expand: true,
                        cwd: 'dist',
                        src: '**/*.js',
                        dest: 'dist'
                    }
                ]
            }
        },
        watch: {
            eslint: {
                files: jshintFiles,
                tasks: ['eslint:main', 'jasmine:main:build']
            },
            src: {
                files: jshintFiles.concat(otherFiles),
                options: {
                    livereload: true
                }
            }
        }
    });

    grunt.registerTask('default', [
        'jasmine:main:build',
        'eslint:main',
        'connect',
        'watch'
    ]);
    grunt.registerTask('build-prod', [
        'clean:build',
        'newer:imagemin:main',
        'dojo:prod',
        'uglify:prod',
        'copy:main',
        'processhtml:main'
    ]);
    grunt.registerTask('build-stage', [
        'clean:build',
        'newer:imagemin:main',
        'dojo:stage',
        'uglify:stage',
        'copy:main',
        'processhtml:main'
    ]);
};
<|endoftext|>


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

    var testServerUrl = 'http://localhost:9999',
        seleniumPort = 4723,
        path = require('path');

    require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

    grunt.initConfig({

        pkg: grunt.file.readJSON('package.json'),

        shell: {
            options: {
                stdout: true
            },
            protractor_install: {
                command: 'node ./node_modules/protractor/bin/webdriver-manager update'
            },
            appium_start: {
                command: 'node ./node_modules/appium/bin/appium',
                options: {
                    async: true
                }
            },
            ios_build: {
                command: [
                    'cd build',
                    '../node_modules/ionic/bin/ionic platform ios',
                    '../node_modules/ionic/bin/ionic build ios'
                ].join('&&')
            },
            ios_start: {
                command: [
                    'cd build',
                    '../node_modules/ionic/bin/ionic emulate ios'
                ].join('&&')
            }
        },

        clean: {
            build: 'build',
            temp: 'temp',
            instrumentscli: 'instrumentscli*/',
            phantomjslog: 'phantomjsdriver.log'
        },

        copy: {
            cordova_hidden: {
                expand: true,
                cwd: 'cordova/.cordova/',
                src: '**',
                dest: 'build/.cordova/'
            },
            cordova: {
                expand: true,
                cwd: 'cordova/',
                src: '**',
                dest: 'build/',
                options: {
                    mode: true
                }
            },
            lib: {
                expand: true,
                cwd: 'app/lib/',
                src: '**',
                dest: 'build/www/lib/'
            },
            img: {
                expand: true,
                cwd: 'app/src/',
                src: ['img/**', 'index.html'],
                dest: 'build/www/'
            }
        },

        ngtemplates: {
            nxtr: {
                cwd: 'app/src/js/',
                src: '**/*.tpl.html',
                dest: 'temp/templates.js'
            }
        },

        concat_sourcemap: {
            js: {
                src: [
                    'app/src/js/**/*Module.js',
                    'app/src/js/**/*.js',
                    'temp/templates.js',
                    '!app/src/js/**/*.spec.js'
                ],
                dest: 'build/www/app.js'
            },
            css: {
                src: 'app/src/css/**/*.css',
                dest: 'build/www/app.css'
            }
        },

        connect: {
            options: {
                base: 'build/www'
            },
            devserver: {
                options: {
                    port: 7777,
                    livereload: true,
                    open: true
                }
            },
            webserver: {
                options: {
                    port: 8888,
                    keepalive: true,
                    open: true
                }
            },
            testserver: {
                options: {
                    port: 9999
                }
            }
        },

        protractor: {
            options: {
                configFile: "./app/test/e2e/protractor.conf.js"
            },
            ios_safari: {
                options: {
                    args: {
                        baseUrl: testServerUrl,
                        seleniumPort: seleniumPort,
                        capabilities: {
                            browserName: '',
                            device: 'iphone',
                            app: 'safari'
                        }
                    }
                }
            },
            ios_app: {
                options: {
                    args: {
                        baseUrl: '',
                        seleniumPort: seleniumPort,
                        capabilities: {
                            browserName: '',
                            device: 'iphone',
                            app: path.resolve('build/platforms/ios/build/emulator/NxtrApp.app')
                        }
                    }
                }
            },
            chrome: {
                options: {
                    args: {
                        baseUrl: testServerUrl,
                        capabilities: {
                            'browserName': 'chrome'
                        }
                    }
                }
            },
            headless: {
                options: {
                    args: {
                        baseUrl: testServerUrl,
                        capabilities: {
                            'browserName': 'phantomjs'
                        }
                    }
                }
            },
            autowatch: {
                keepAlive: true,
                options: {
                    args: {
                        baseUrl: testServerUrl,
                        capabilities: {
                            'browserName': 'chrome'
                        }
                    }
                }
            }
        },

        watch: {
            options: {
                livereload: true
            },
            app: {
                files: ['app/src/**', 'app/test/**'],
                tasks: ['build', 'karma:chrome']
            }
        },

        karma: {
            options: {
                configFile: './app/test/unit/karma.conf.js',
                autoWatch: false,
                singleRun: true
            },
            chrome: {
                browsers: ['Chrome']
            },
            headless: {
                browsers: ['PhantomJS']
            }
        }

    });

    // Install tasks
    grunt.registerTask('install', ['shell:protractor_install']);

    // Build tasks
    grunt.registerTask('build', ['copy', 'ngtemplates', 'concat_sourcemap']);

    // Test tasks
    grunt.registerTask('test:unit', ['karma:chrome']);
    grunt.registerTask('test:e2e', ['connect:testserver', 'protractor:chrome']);
    grunt.registerTask('test:e2e_headless', ['connect:testserver', 'protractor:headless']);
    grunt.registerTask('test:e2e_ios_safari', ['connect:testserver', 'shell:appium_start', 'protractor:ios_safari', 'shell:appium_start:kill']);
    grunt.registerTask('test:e2e_ios_app', ['shell:ios_build', 'shell:appium_start', 'protractor:ios_app', 'shell:appium_start:kill']);
    grunt.registerTask('test', ['test:unit', 'test:e2e']);
    grunt.registerTask('test:headless', ['karma:headless', 'test:e2e_headless']);

    // Task to support the 'dev flow' that builds the web application, starts a web server with 'livereload' and
    // watches the source files to reload the application when changes are saved
    grunt.registerTask('dev', ['clean', 'build', 'connect:devserver', 'watch']);

    // Builds and opens the web application in the default browser
    grunt.registerTask('serve', ['clean', 'build', 'connect:webserver']);

    // Builds and opens the Cordova application in the iOS emulator (requires a Mac computer with XCode)
    grunt.registerTask('ios', ['clean', 'build', 'shell:ios_build', 'shell:ios_start']);

    // Builds the web application and performs a test run (both unit and e2e)
    grunt.registerTask('default', ['clean', 'build', 'test']);

    // Builds the web application and performs a test run with a headless browser
    grunt.registerTask('ci', ['clean', 'build', 'test:headless']);

};
<commit_msg>switch to firefox as browser for testing<commit_after>module.exports = function (grunt) {

    var testServerUrl = 'http://localhost:9999',
        seleniumPort = 4723,
        path = require('path');

    require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

    grunt.initConfig({

        pkg: grunt.file.readJSON('package.json'),

        shell: {
            options: {
                stdout: true
            },
            protractor_install: {
                command: 'node ./node_modules/protractor/bin/webdriver-manager update'
            },
            appium_start: {
                command: 'node ./node_modules/appium/bin/appium',
                options: {
                    async: true
                }
            },
            ios_build: {
                command: [
                    'cd build',
                    '../node_modules/ionic/bin/ionic platform ios',
                    '../node_modules/ionic/bin/ionic build ios'
                ].join('&&')
            },
            ios_start: {
                command: [
                    'cd build',
                    '../node_modules/ionic/bin/ionic emulate ios'
                ].join('&&')
            }
        },

        clean: {
            build: 'build',
            temp: 'temp',
            instrumentscli: 'instrumentscli*/',
            phantomjslog: 'phantomjsdriver.log'
        },

        copy: {
            cordova_hidden: {
                expand: true,
                cwd: 'cordova/.cordova/',
                src: '**',
                dest: 'build/.cordova/'
            },
            cordova: {
                expand: true,
                cwd: 'cordova/',
                src: '**',
                dest: 'build/',
                options: {
                    mode: true
                }
            },
            lib: {
                expand: true,
                cwd: 'app/lib/',
                src: '**',
                dest: 'build/www/lib/'
            },
            img: {
                expand: true,
                cwd: 'app/src/',
                src: ['img/**', 'index.html'],
                dest: 'build/www/'
            }
        },

        ngtemplates: {
            nxtr: {
                cwd: 'app/src/js/',
                src: '**/*.tpl.html',
                dest: 'temp/templates.js'
            }
        },

        concat_sourcemap: {
            js: {
                src: [
                    'app/src/js/**/*Module.js',
                    'app/src/js/**/*.js',
                    'temp/templates.js',
                    '!app/src/js/**/*.spec.js'
                ],
                dest: 'build/www/app.js'
            },
            css: {
                src: 'app/src/css/**/*.css',
                dest: 'build/www/app.css'
            }
        },

        connect: {
            options: {
                base: 'build/www'
            },
            devserver: {
                options: {
                    port: 7777,
                    livereload: true,
                    open: true
                }
            },
            webserver: {
                options: {
                    port: 8888,
                    keepalive: true,
                    open: true
                }
            },
            testserver: {
                options: {
                    port: 9999
                }
            }
        },

        protractor: {
            options: {
                configFile: "./app/test/e2e/protractor.conf.js"
            },
            ios_safari: {
                options: {
                    args: {
                        baseUrl: testServerUrl,
                        seleniumPort: seleniumPort,
                        capabilities: {
                            browserName: '',
                            device: 'iphone',
                            app: 'safari'
                        }
                    }
                }
            },
            ios_app: {
                options: {
                    args: {
                        baseUrl: '',
                        seleniumPort: seleniumPort,
                        capabilities: {
                            browserName: '',
                            device: 'iphone',
                            app: path.resolve('build/platforms/ios/build/emulator/NxtrApp.app')
                        }
                    }
                }
            },
            chrome: {
                options: {
                    args: {
                        baseUrl: testServerUrl,
                        capabilities: {
                            'browserName': 'chrome'
                        }
                    }
                }
            },
            firefox: {
                options: {
                    args: {
                        baseUrl: testServerUrl,
                        capabilities: {
                            'browserName': 'firefox'
                        }
                    }
                }
            },
            headless: {
                options: {
                    args: {
                        baseUrl: testServerUrl,
                        capabilities: {
                            'browserName': 'phantomjs'
                        }
                    }
                }
            },
            autowatch: {
                keepAlive: true,
                options: {
                    args: {
                        baseUrl: testServerUrl,
                        capabilities: {
                            'browserName': 'firefox'
                        }
                    }
                }
            }
        },

        watch: {
            options: {
                livereload: true
            },
            app: {
                files: ['app/src/**', 'app/test/**'],
                tasks: ['build', 'karma:firefox']
            }
        },

        karma: {
            options: {
                configFile: './app/test/unit/karma.conf.js',
                autoWatch: false,
                singleRun: true
            },
            chrome: {
              browsers: ['chrome']
            },
            firefox: {
              browsers: ['Firefox']
            },
            headless: {
                browsers: ['PhantomJS']
            }
        }

    });

    // Install tasks
    grunt.registerTask('install', ['shell:protractor_install']);

    // Build tasks
    grunt.registerTask('build', ['copy', 'ngtemplates', 'concat_sourcemap']);

    // Test tasks
    grunt.registerTask('test:unit', ['karma:firefox']);
    grunt.registerTask('test:e2e', ['connect:testserver', 'protractor:firefox']);
    grunt.registerTask('test:e2e_headless', ['connect:testserver', 'protractor:headless']);
    grunt.registerTask('test:e2e_ios_safari', ['connect:testserver', 'shell:appium_start', 'protractor:ios_safari', 'shell:appium_start:kill']);
    grunt.registerTask('test:e2e_ios_app', ['shell:ios_build', 'shell:appium_start', 'protractor:ios_app', 'shell:appium_start:kill']);
    grunt.registerTask('test', ['test:unit', 'test:e2e']);
    grunt.registerTask('test:headless', ['karma:headless', 'test:e2e_headless']);

    // Task to support the 'dev flow' that builds the web application, starts a web server with 'livereload' and
    // watches the source files to reload the application when changes are saved
    grunt.registerTask('dev', ['clean', 'build', 'connect:devserver', 'watch']);

    // Builds and opens the web application in the default browser
    grunt.registerTask('serve', ['clean', 'build', 'connect:webserver']);

    // Builds and opens the Cordova application in the iOS emulator (requires a Mac computer with XCode)
    grunt.registerTask('ios', ['clean', 'build', 'shell:ios_build', 'shell:ios_start']);

    // Builds the web application and performs a test run (both unit and e2e)
    grunt.registerTask('default', ['clean', 'build', 'test']);

    // Builds the web application and performs a test run with a headless browser
    grunt.registerTask('ci', ['clean', 'build', 'test:headless']);

};
<|endoftext|>