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

  'use strict';

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

  grunt.initConfig({

    pkg: grunt.file.readJSON('package.json'),
    buildVersion: '<%= pkg.name %>_v<%= pkg.version %>_<%= grunt.template.today("yyyymmdd.HHMM") %>',

    exec: {
      bower_install: 'bower cache clean --config.interactive=false && bower install --config.interactive=false'
    },

    wiredep: {
      app: {
        src: ['<%= pkg.appPath %>/index.html'],
        ignorePath:  /\.\.\//,
        exclude: [
          'bower_components/bootstrap/dist/css/bootstrap.css',
          'bower_components/bootstrap/dist/js/bootstrap.js'
        ]
      },
      test: {
        devDependencies: true,
        src: '<%= karma.unit.configFile %>',
        ignorePath:  /(\.\.\/){3}/,
        fileTypes:{
          js: {
            block: /(([\s\t]*)\/{2}\s*?bower:\s*?(\S*))(\n|\r|.)*?(\/{2}\s*endbower)/gi,
            detect: {
              js: /'(.*\.js)'/gi
            },
            replace: {
              js: '\'{{filePath}}\','
            }
          }
        }
      }
    },

    'customize-bootstrap': {
      app: {
        options: {
          bootstrapPath: 'bower_components/bootstrap',
          src: '<%= pkg.appPath %>/assets/less/bootstrap/overrides',
          dest: '<%= pkg.buildPathDev %>/less/bootstrap/custom'
        }
      }
    },

    less: {
      app: {
        files: {
          '<%= pkg.buildPathDev %>/css/app-custom.css': '<%= pkg.appPath %>/assets/less/app-custom.less'
        }
      },
      bootstrap: {
        files: {
          '<%= pkg.buildPathDev %>/css/bootstrap.css': '<%= pkg.buildPathDev %>/less/bootstrap/custom/bootstrap.less'
        }
      }
      // bootstrap_theme: {
      //   files: {
      //     '<%= pkg.buildPathDev %>/css/bootstrap-theme.css': '<%= pkg.appPath %>/assets/less/bootstrap/overrides/theme.less'
      //   }
      // }
    },

    clean: {
      build: {
        src: [
          '<%= pkg.buildPath %>/**'
        ]
      },
      dist: {
        src: [
        '<%= pkg.distPath %>/**/*'
        ]
      }
    },

    jshint: {
      all: {
        // define the files to lint
        src: ['Gruntfile.js', '<%= pkg.appPath %>/app/**/*.js'],
        // configure JSHint (documented at http://www.jshint.com/docs/)
        options: {
          jshintrc: true,
          // more options here if you want to override JSHint defaults
          globals: {
            jQuery: true,
            console: true,
            module: true,
            angular: false
          }
        }
      },
      test: {
        // define the files to lint
        src: ['<%= pkg.appPath %>/app/**/*.spec.js'],
        // configure JSHint (documented at http://www.jshint.com/docs/)
        options: {
          jshintrc: true
        }
      }

    },

    jscs: {
      dev: {
        options: {
          config: '<%= pkg.appPath %>/.jscsrc'
        },
        files: {
          src: ['<%= jshint.all.src %>']
        }
      }
    },

    copy: {
      dev_index: {
        src: '<%= pkg.appPath %>/index.html',
        dest: '<%= pkg.buildPathDev %>/index.html'
      },
      dev_glyphicons: {
        expand: true,
        cwd: 'bower_components/bootstrap',
        src: 'fonts/**',
        dest: '<%= pkg.buildPathDev %>/'
      },
      dev_i18n_js: {
        expand: true,
        cwd: '<%= pkg.appPath %>/assets',
        src: 'js/i18n/**',
        dest: '<%= pkg.buildPathDev %>/'
      },
      dev_images: {
        expand: true,
        cwd: '<%= pkg.appPath %>/assets',
        src: 'images/**',
        dest: '<%= pkg.buildPathDev %>/'
      },
      dist_prepare: {
        expand: true,
        cwd: '<%= pkg.buildPathDev %>',
        src: '**',
        dest: '<%= pkg.buildPathDist %>/'
      },
      dist_update_html: {
        expand: true,
        cwd: '<%= pkg.buildPathDev %>',
        src: 'index.html',
        dest: '<%= pkg.distPath %>/'
      },
      dist_update_fonts: {
        expand: true,
        cwd: '<%= pkg.buildPathDev %>',
        src: 'fonts/**',
        dest: '<%= pkg.distPath %>/'
      },
      dist_update_images: {
        expand: true,
        cwd: '<%= pkg.buildPathDev %>',
        src: 'images/**',
        dest: '<%= pkg.distPath %>/'
      },
      dist_update_fontawesome: {
        expand: true,
        cwd: '<%= pkg.appPath %>/bower_components/fontawesome',
        src: 'fonts/**',
        dest: '<%= pkg.distPath %>/'
      },
      dist_update_i18n: {
        expand: true,
        cwd: '<%= pkg.appPath %>/assets/js',
        src: 'i18n/**',
        dest: '<%= pkg.distPath %>/'
      },
      dist_package_prepare: {
        expand: true,
        cwd: '<%= pkg.distPath %>',
        src: '**/**',
        dest: '<%= pkg.buildPath %>/<%= buildVersion %>'
      }
    },

    ngtemplates: {
      app: {
        cwd: '<%= pkg.appPath %>',
        src: 'app/**/**.html',
        dest: '<%= pkg.buildPathDev %>/js/views.js',
        options: {
          htmlmin: {
            collapseBooleanAttributes: true,
            collapseWhitespace: true,
            removeAttributeQuotes: true,
            removeComments: true,
            removeEmptyAttributes: true,
            removeRedundantAttributes: true,
            removeScriptTypeAttributes: true,
            removeStyleLinkTypeAttributes: true          }
        }
      }
    },

    concat: {
      options: {
        // define a string to put between each file in the concatenated output
        separator: ';'
      },
      dev: {
        // the files to concatenate
        src: [
          'app/**/*.service.js',
          'app/**/*.factory.js',
          'app/**/*.filter.js',
          'app/**/*.directive.js',
          'app/**/*.controller.js',
          'app/**/*.routes.js',
          'app/**/*.module.js',
          '<%= pkg.buildPathDev %>/js/views.js',
          '<%= pkg.buildPathDev %>/js/config.js',
          '<%= ngtemplates.app.dest %>',
          '<%= ngconstant.options.dest %>'
        ],
        // the location of the resulting JS file
        dest: '<%= pkg.buildPathDev %>/js/<%= pkg.appName %>.concat.js'
      },
      dist: {
        // the files to concatenate
        src: [
          'app/**/*.service.js',
          'app/**/*.factory.js',
          'app/**/*.filter.js',
          'app/**/*.directive.js',
          'app/**/*.controller.js',
          'app/**/*.routes.js',
          'app/**/*.module.js',
          '<%= pkg.buildPathDev %>/js/views.js',
          '<%= pkg.buildPathDev %>/js/config.js',
          '<%= ngtemplates.app.dest %>',
          '<%= ngconstant.options.dest %>'
        ],
        // the location of the resulting JS file
        dest: '<%= pkg.buildPathDist %>/js/<%= pkg.appName %>.concat.js'
      }
    },

    ngAnnotate: {
      all: {
        // Target-specific file lists and/or options go here.
        files: {
          '<%= concat.dist.dest %>': ['<%= concat.dist.dest %>']
        }
      }
    },

    watch: {
      bower: {
        files: ['bower.json'],
        tasks: ['wiredep']
      },
      gruntfile: {
        files: ['Gruntfile.js'],
        tasks: ['newer:jscs:dev', 'newer:jshint:all']
      },
      index: {
        files: ['index.html'],
        tasks: ['copy:dev_index'],
        options: {
          livereload: true
        }
      },
      js: {
        files: ['<%= jshint.all.src[1] %>'],
        tasks: ['newer:jscs:dev', 'newer:jshint:all', 'newer:concat:dev', 'newer:jshint:test', 'karma', 'ngdocs'],
        options: {
          livereload: true
        }
      },
      templates: {
        files: ['<%= pkg.appPath %>/app/**/*.template.html'],
        tasks: ['newer:ngtemplates', 'newer:concat:dev', 'karma'],
        options: {
          livereload: true
        }
      },
      lessApp: {
        files: ['<%= pkg.appPath %>/assets/less/*.less'],
        tasks: ['less:app'],
        options: {
          livereload: true
        }
      },
      lessBootstrap: {
        files: ['<%= pkg.appPath %>/assets/less/bootstrap/**/*.less'],
        tasks: ['less'], // my own app-custom.less includes bootstrap variables
        options: {
          livereload: true
        }
      },
      livereload: {
        options: {
          livereload: true
        },
        files: [
          '<%= pkg.appPath %>/assets/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },

    karma: {
      unit: {
        configFile: '<%= pkg.appPath %>/app/shared/config/karma.config.js',
        singleRun: true
      }
    },

    connect: {
      dev: {
        options: {
          port: 9001,
          base: ['<%= pkg.buildPathDev %>', '<%= pkg.appPath %>']
        }
      }
    },

    nggettext_extract: {
      pot: {
        files: {
          '<%= pkg.appPath %>/po/template.pot': [
            '<%= pkg.appPath %>/app/**/**.html',
            '<%= pkg.appPath %>/index.html',
            '<%= jshint.all.src[1] %>'
          ]
        }
      }
    },

    nggettext_compile: {
      all: {
        options: {
          format: 'json'
        },
        files: [
          {
            expand: true,
            dot: true,
            cwd: '<%= pkg.appPath %>/po',
            src: ['*.po'],
            dest: '<%= pkg.appPath %>/assets/js/i18n',
            ext: '.json'
          }
        ]
      }
    },

    ngconstant: {
      options: {
        name: 'app.config',
        dest: '<%= pkg.buildPathDev %>/js/config.js'
      },
      dist: {
        constants: '<%= pkg.appPath %>/app/shared/config/dist.config.json'
      },
      dev: {
        constants: '<%= pkg.appPath %>/app/shared/config/dev.config.json'
      }
    },

    useminPrepare: {
      build: {
        src: ['<%= pkg.buildPathDist %>/index.html'],
        dest: '<%= pkg.buildPathDist %>'
      },
      options: {
        flow: {
          steps: { js: ['concat', 'uglifyjs'], css: ['concat', 'cssmin'] },
          post: {
            css: [{
              name: 'concat',
              createConfig: function(context) {
                var generated = context.options.generated;
                generated.options = {
                  stripBanners: { block: true },
                  separator: '\n'
                };
              }
            }]
          }
        }
      }
    },

    filerev: {
      // waiting to test how to support image references inside compiled angular templates
      // images: {
      //   src: '<%= pkg.buildPathDist %>/images/**/*.{jpg,jpeg,gif,png,webp}',
      //   dest: '<%= pkg.distPath %>/images/'
      // },
      css: {
        src: '<%= pkg.distPath %>/styles/**/*.css'
      },
      js: {
        src: '<%= pkg.distPath %>/scripts/**/*.js'
      }
    },

    usemin: {
      html: ['<%= pkg.distPath %>/index.html']
    },

    compress: {
      dist_package: {
        options: {
          archive: '<%= pkg.buildPath %>/<%= buildVersion %>.tar.gz',
          mode: 'tgz',
          pretty: true
        },
        files: [
          {
            expand: true,
            cwd: '<%= pkg.buildPath %>',
            src: '<%= buildVersion %>/**'
          }
        ]
      }
    },

    ngdocs: {
      options: {
        dest: 'dist/docs',
        scripts: [
          'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js',
          'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular-animate.min.js'
        ],
        title: 'App Documentation',
        html5Mode: false,
        startPage: '/api/app'
      },
      api: {
        src: ['app/**/*.js'],
        title: 'Reference'
      }
    }

  });

  grunt.registerTask('build', [
    'exec',
    'clean:build',
    'wiredep',
    'jscs:dev',
    'jshint',
    'ngtemplates',
    'customize-bootstrap:app',
    'less',
    'nggettext_compile',
    'copy:dev_index',
    'copy:dev_glyphicons',
    'copy:dev_images',
    'copy:dev_i18n_js'
  ]);

  grunt.registerTask('memento_test', function() {
    grunt.log.writeln('\n\tI’m Commander Shepard, and this is my favourite memento on this terminal:'.blue.bold);
    grunt.log.writeln('\n\tRemember to always run a "grunt test" before building a dist!\n'.yellow.bold);
  });

  grunt.registerTask('dist', [
    'clean:dist',
    'build',
    'ngconstant:dist',
    'copy:dist_prepare',
    'concat:dist',
    'ngAnnotate',
    // 'karma',
    'useminPrepare',
    'concat:generated',
    'cssmin:generated',
    'uglify:generated',
    'filerev',
    'copy:dist_update_html',
    'copy:dist_update_fonts',
    'copy:dist_update_fontawesome',
    'copy:dist_update_images',
    'copy:dist_update_i18n',
    'usemin',
    'memento_test'
  ]);

  grunt.registerTask('dist-package', [
    'dist',
    'copy:dist_package_prepare',
    'compress:dist_package'
  ]);

  grunt.registerTask('dev', [
    'build',
    'ngconstant:dev',
    'concat:dev',
    'connect:dev',
    'karma',
    'ngdocs',
    'watch'
  ]);

  grunt.registerTask('test', [
    'jscs:dev',
    'jshint:test',
    'karma'
  ]);

  grunt.registerTask('serve', 'Compile then start a connect web server', function(target) {
    if (target === 'dist') {
      return grunt.log.warn('The `serve:dist` target is currently unavailable.\nUse `grunt dist` to build a new dist into the `dist` folder, then serve it as you prefer.');
      // return grunt.task.run(['build', 'connect:dist:keepalive']);
    }

    grunt.task.run([
      'dev'
    ]);
  });

  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('docs', 'Generate the documentation in dist/docs.', ['ngdocs']);

};
<commit_msg>Tentatively remove unwanted trailing space - part 1<commit_after>module.exports = function(grunt) {

  'use strict';

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

  grunt.initConfig({

    pkg: grunt.file.readJSON('package.json'),
    buildVersion: '<%= pkg.name %>_v<%= pkg.version %>_<%= grunt.template.today("yyyymmdd.HHMM") %>',

    exec: {
      bower_install: 'bower cache clean --config.interactive=false && bower install --config.interactive=false'
    },

    wiredep: {
      app: {
        src: ['<%= pkg.appPath %>/index.html'],
        ignorePath:  /\.\.\//,
        exclude: [
          'bower_components/bootstrap/dist/css/bootstrap.css',
          'bower_components/bootstrap/dist/js/bootstrap.js'
        ]
      },
      test: {
        devDependencies: true,
        src: '<%= karma.unit.configFile %>',
        ignorePath:  /(\.\.\/){3}/,
        fileTypes:{
          js: {
            block: /(([\s\t]*)\/{2}\s*?bower:\s*?(\S*))(\n|\r|.)*?(\/{2}\s*endbower)/gi,
            detect: {
              js: /'(.*\.js)'/gi
            },
            replace: {
              js: '\'{{filePath}}\','
            }
          }
        }
      }
    },

    'customize-bootstrap': {
      app: {
        options: {
          bootstrapPath: 'bower_components/bootstrap',
          src: '<%= pkg.appPath %>/assets/less/bootstrap/overrides',
          dest: '<%= pkg.buildPathDev %>/less/bootstrap/custom'
        }
      }
    },

    less: {
      app: {
        files: {
          '<%= pkg.buildPathDev %>/css/app-custom.css': '<%= pkg.appPath %>/assets/less/app-custom.less'
        }
      },
      bootstrap: {
        files: {
          '<%= pkg.buildPathDev %>/css/bootstrap.css': '<%= pkg.buildPathDev %>/less/bootstrap/custom/bootstrap.less'
        }
      }
      // bootstrap_theme: {
      //   files: {
      //     '<%= pkg.buildPathDev %>/css/bootstrap-theme.css': '<%= pkg.appPath %>/assets/less/bootstrap/overrides/theme.less'
      //   }
      // }
    },

    clean: {
      build: {
        src: [
          '<%= pkg.buildPath %>/**'
        ]
      },
      dist: {
        src: [
        '<%= pkg.distPath %>/**/*'
        ]
      }
    }, // Ugly fix

    jshint: {
      all: {
        // define the files to lint
        src: ['Gruntfile.js', '<%= pkg.appPath %>/app/**/*.js'],
        // configure JSHint (documented at http://www.jshint.com/docs/)
        options: {
          jshintrc: true,
          // more options here if you want to override JSHint defaults
          globals: {
            jQuery: true,
            console: true,
            module: true,
            angular: false
          }
        }
      },
      test: {
        // define the files to lint
        src: ['<%= pkg.appPath %>/app/**/*.spec.js'],
        // configure JSHint (documented at http://www.jshint.com/docs/)
        options: {
          jshintrc: true
        }
      }

    },

    jscs: {
      dev: {
        options: {
          config: '<%= pkg.appPath %>/.jscsrc'
        },
        files: {
          src: ['<%= jshint.all.src %>']
        }
      }
    },

    copy: {
      dev_index: {
        src: '<%= pkg.appPath %>/index.html',
        dest: '<%= pkg.buildPathDev %>/index.html'
      },
      dev_glyphicons: {
        expand: true,
        cwd: 'bower_components/bootstrap',
        src: 'fonts/**',
        dest: '<%= pkg.buildPathDev %>/'
      },
      dev_i18n_js: {
        expand: true,
        cwd: '<%= pkg.appPath %>/assets',
        src: 'js/i18n/**',
        dest: '<%= pkg.buildPathDev %>/'
      },
      dev_images: {
        expand: true,
        cwd: '<%= pkg.appPath %>/assets',
        src: 'images/**',
        dest: '<%= pkg.buildPathDev %>/'
      },
      dist_prepare: {
        expand: true,
        cwd: '<%= pkg.buildPathDev %>',
        src: '**',
        dest: '<%= pkg.buildPathDist %>/'
      },
      dist_update_html: {
        expand: true,
        cwd: '<%= pkg.buildPathDev %>',
        src: 'index.html',
        dest: '<%= pkg.distPath %>/'
      },
      dist_update_fonts: {
        expand: true,
        cwd: '<%= pkg.buildPathDev %>',
        src: 'fonts/**',
        dest: '<%= pkg.distPath %>/'
      },
      dist_update_images: {
        expand: true,
        cwd: '<%= pkg.buildPathDev %>',
        src: 'images/**',
        dest: '<%= pkg.distPath %>/'
      },
      dist_update_fontawesome: {
        expand: true,
        cwd: '<%= pkg.appPath %>/bower_components/fontawesome',
        src: 'fonts/**',
        dest: '<%= pkg.distPath %>/'
      },
      dist_update_i18n: {
        expand: true,
        cwd: '<%= pkg.appPath %>/assets/js',
        src: 'i18n/**',
        dest: '<%= pkg.distPath %>/'
      },
      dist_package_prepare: {
        expand: true,
        cwd: '<%= pkg.distPath %>',
        src: '**/**',
        dest: '<%= pkg.buildPath %>/<%= buildVersion %>'
      }
    },

    ngtemplates: {
      app: {
        cwd: '<%= pkg.appPath %>',
        src: 'app/**/**.html',
        dest: '<%= pkg.buildPathDev %>/js/views.js',
        options: {
          htmlmin: {
            collapseBooleanAttributes: true,
            collapseWhitespace: true,
            removeAttributeQuotes: true,
            removeComments: true,
            removeEmptyAttributes: true,
            removeRedundantAttributes: true,
            removeScriptTypeAttributes: true,
            removeStyleLinkTypeAttributes: true          }
        }
      }
    },

    concat: {
      options: {
        // define a string to put between each file in the concatenated output
        separator: ';'
      },
      dev: {
        // the files to concatenate
        src: [
          'app/**/*.service.js',
          'app/**/*.factory.js',
          'app/**/*.filter.js',
          'app/**/*.directive.js',
          'app/**/*.controller.js',
          'app/**/*.routes.js',
          'app/**/*.module.js',
          '<%= pkg.buildPathDev %>/js/views.js',
          '<%= pkg.buildPathDev %>/js/config.js',
          '<%= ngtemplates.app.dest %>',
          '<%= ngconstant.options.dest %>'
        ],
        // the location of the resulting JS file
        dest: '<%= pkg.buildPathDev %>/js/<%= pkg.appName %>.concat.js'
      },
      dist: {
        // the files to concatenate
        src: [
          'app/**/*.service.js',
          'app/**/*.factory.js',
          'app/**/*.filter.js',
          'app/**/*.directive.js',
          'app/**/*.controller.js',
          'app/**/*.routes.js',
          'app/**/*.module.js',
          '<%= pkg.buildPathDev %>/js/views.js',
          '<%= pkg.buildPathDev %>/js/config.js',
          '<%= ngtemplates.app.dest %>',
          '<%= ngconstant.options.dest %>'
        ],
        // the location of the resulting JS file
        dest: '<%= pkg.buildPathDist %>/js/<%= pkg.appName %>.concat.js'
      }
    },

    ngAnnotate: {
      all: {
        // Target-specific file lists and/or options go here.
        files: {
          '<%= concat.dist.dest %>': ['<%= concat.dist.dest %>']
        }
      }
    },

    watch: {
      bower: {
        files: ['bower.json'],
        tasks: ['wiredep']
      },
      gruntfile: {
        files: ['Gruntfile.js'],
        tasks: ['newer:jscs:dev', 'newer:jshint:all']
      },
      index: {
        files: ['index.html'],
        tasks: ['copy:dev_index'],
        options: {
          livereload: true
        }
      },
      js: {
        files: ['<%= jshint.all.src[1] %>'],
        tasks: ['newer:jscs:dev', 'newer:jshint:all', 'newer:concat:dev', 'newer:jshint:test', 'karma', 'ngdocs'],
        options: {
          livereload: true
        }
      },
      templates: {
        files: ['<%= pkg.appPath %>/app/**/*.template.html'],
        tasks: ['newer:ngtemplates', 'newer:concat:dev', 'karma'],
        options: {
          livereload: true
        }
      },
      lessApp: {
        files: ['<%= pkg.appPath %>/assets/less/*.less'],
        tasks: ['less:app'],
        options: {
          livereload: true
        }
      },
      lessBootstrap: {
        files: ['<%= pkg.appPath %>/assets/less/bootstrap/**/*.less'],
        tasks: ['less'], // my own app-custom.less includes bootstrap variables
        options: {
          livereload: true
        }
      },
      livereload: {
        options: {
          livereload: true
        },
        files: [
          '<%= pkg.appPath %>/assets/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },

    karma: {
      unit: {
        configFile: '<%= pkg.appPath %>/app/shared/config/karma.config.js',
        singleRun: true
      }
    },

    connect: {
      dev: {
        options: {
          port: 9001,
          base: ['<%= pkg.buildPathDev %>', '<%= pkg.appPath %>']
        }
      }
    },

    nggettext_extract: {
      pot: {
        files: {
          '<%= pkg.appPath %>/po/template.pot': [
            '<%= pkg.appPath %>/app/**/**.html',
            '<%= pkg.appPath %>/index.html',
            '<%= jshint.all.src[1] %>'
          ]
        }
      }
    },

    nggettext_compile: {
      all: {
        options: {
          format: 'json'
        },
        files: [
          {
            expand: true,
            dot: true,
            cwd: '<%= pkg.appPath %>/po',
            src: ['*.po'],
            dest: '<%= pkg.appPath %>/assets/js/i18n',
            ext: '.json'
          }
        ]
      }
    },

    ngconstant: {
      options: {
        name: 'app.config',
        dest: '<%= pkg.buildPathDev %>/js/config.js'
      },
      dist: {
        constants: '<%= pkg.appPath %>/app/shared/config/dist.config.json'
      },
      dev: {
        constants: '<%= pkg.appPath %>/app/shared/config/dev.config.json'
      }
    },

    useminPrepare: {
      build: {
        src: ['<%= pkg.buildPathDist %>/index.html'],
        dest: '<%= pkg.buildPathDist %>'
      },
      options: {
        flow: {
          steps: { js: ['concat', 'uglifyjs'], css: ['concat', 'cssmin'] },
          post: {
            css: [{
              name: 'concat',
              createConfig: function(context) {
                var generated = context.options.generated;
                generated.options = {
                  stripBanners: { block: true },
                  separator: '\n'
                };
              }
            }]
          }
        }
      }
    },

    filerev: {
      // waiting to test how to support image references inside compiled angular templates
      // images: {
      //   src: '<%= pkg.buildPathDist %>/images/**/*.{jpg,jpeg,gif,png,webp}',
      //   dest: '<%= pkg.distPath %>/images/'
      // },
      css: {
        src: '<%= pkg.distPath %>/styles/**/*.css'
      },
      js: {
        src: '<%= pkg.distPath %>/scripts/**/*.js'
      }
    },

    usemin: {
      html: ['<%= pkg.distPath %>/index.html']
    },

    compress: {
      dist_package: {
        options: {
          archive: '<%= pkg.buildPath %>/<%= buildVersion %>.tar.gz',
          mode: 'tgz',
          pretty: true
        },
        files: [
          {
            expand: true,
            cwd: '<%= pkg.buildPath %>',
            src: '<%= buildVersion %>/**'
          }
        ]
      }
    },

    ngdocs: {
      options: {
        dest: 'dist/docs',
        scripts: [
          'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js',
          'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular-animate.min.js'
        ],
        title: 'App Documentation',
        html5Mode: false,
        startPage: '/api/app'
      },
      api: {
        src: ['app/**/*.js'],
        title: 'Reference'
      }
    }

  });

  grunt.registerTask('build', [
    'exec',
    'clean:build',
    'wiredep',
    'jscs:dev',
    'jshint',
    'ngtemplates',
    'customize-bootstrap:app',
    'less',
    'nggettext_compile',
    'copy:dev_index',
    'copy:dev_glyphicons',
    'copy:dev_images',
    'copy:dev_i18n_js'
  ]);

  grunt.registerTask('memento_test', function() {
    grunt.log.writeln('\n\tI’m Commander Shepard, and this is my favourite memento on this terminal:'.blue.bold);
    grunt.log.writeln('\n\tRemember to always run a "grunt test" before building a dist!\n'.yellow.bold);
  });

  grunt.registerTask('dist', [
    'clean:dist',
    'build',
    'ngconstant:dist',
    'copy:dist_prepare',
    'concat:dist',
    'ngAnnotate',
    // 'karma',
    'useminPrepare',
    'concat:generated',
    'cssmin:generated',
    'uglify:generated',
    'filerev',
    'copy:dist_update_html',
    'copy:dist_update_fonts',
    'copy:dist_update_fontawesome',
    'copy:dist_update_images',
    'copy:dist_update_i18n',
    'usemin',
    'memento_test'
  ]);

  grunt.registerTask('dist-package', [
    'dist',
    'copy:dist_package_prepare',
    'compress:dist_package'
  ]);

  grunt.registerTask('dev', [
    'build',
    'ngconstant:dev',
    'concat:dev',
    'connect:dev',
    'karma',
    'ngdocs',
    'watch'
  ]);

  grunt.registerTask('test', [
    'jscs:dev',
    'jshint:test',
    'karma'
  ]);

  grunt.registerTask('serve', 'Compile then start a connect web server', function(target) {
    if (target === 'dist') {
      return grunt.log.warn('The `serve:dist` target is currently unavailable.\nUse `grunt dist` to build a new dist into the `dist` folder, then serve it as you prefer.');
      // return grunt.task.run(['build', 'connect:dist:keepalive']);
    }

    grunt.task.run([
      'dev'
    ]);
  });

  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('docs', 'Generate the documentation in dist/docs.', ['ngdocs']);

};
<|endoftext|>


<commit_before>const cheerio = require('cheerio');
const request = require('request');

const delay = 3 * 60 * 1000; // minutes
let bookmakersMatches,
    isStarted,
    urlsToParse;

function parseUrl(index = 0) {
    let url = urlsToParse[index];

    request(url.url, (error, response, body) => {
        console.log('Loading bookmakers matches on ' + url.url);

        if (!error && response.statusCode === 200) {
            const $ = cheerio.load(body);
            let $table = $('table.foot-market');
            if ($table.length === 1) {
                $table.children().each(function(i, elem) {
                    let $item = $(this);
                    let teams = $item.data('eventName');
                    if (!teams) {
                        return true;
                    }
                    let arr = teams.split(' - ');
                    if (arr.length !== 2) {
                        return true;
                    }
                    let homeTeamName = trim(arr[0].toLowerCase());
                    let guestTeamName = trim(arr[1].toLowerCase());
                    $item = $item.children('.event-header').eq(0);
                    if (!$item) {
                        return true;
                    }
                    let date = $item.find('.first.member-area').eq(0).find('.date').eq(0).text();
                    if (!date) {
                        return true;
                    }
                    date = trim(date);
                    $item = $item.find('.main-row-buttons').eq(0);
                    if (!$item) {
                        return true;
                    }

                    let rates = {};
                    for (const prop of ['1', 'x', '2', '1x', '12', 'x2', 'f1', 'f2']) {
                        let $next = $item.next();
                        if (!$next) {
                            return true;
                        }
                        let text = trim($next.text());
                        if (prop === 'f1' || prop === 'f2') {
                            let i = text.indexOf(')');
                            let count = '-', value = '-';
                            if (i !== -1) {
                                count = text.substring(1, i);
                                value = parseFloat(text.substring(i + 1));
                            }
                            rates[prop] = {
                                count,
                                value,
                            };
                        } else {
                            rates[prop] = parseFloat(text);
                        }
                        $item = $next;
                    }

                    console.log({
                        bookmakerId: 2,
                        homeTeamName,
                        guestTeamName,
                        date,
                        rates
                    })

                });
            } else {
                console.log($table.length + ' - skip!');
            }
        } else {
            console.log('Failed download page');
        }

        if (++index === urlsToParse.length) {
            // again
            setTimeout(() => parseUrl(), delay);
        } else {
            let i = index;
            setTimeout(() => parseUrl(i), 2000);
        }
    });
}

function trim(string) {
    return string.replace(/^\s*|\s*$/g, '');
}

module.exports = {
    start(urls, mongoDB) {
        if (isStarted || !urls) {
            return;
        }

        isStarted = true;
        bookmakersMatches = mongoDB.collection('bookmakers_matches');
        urlsToParse = urls;

        parseUrl();
    }
};
<commit_msg>Added writing bookmakers matches to DB<commit_after>const cheerio = require('cheerio');
const request = require('request');

const HOURS_DIFF = 3;
const delay = 3 * 60 * 1000; // minutes
let bookmakersMatchesCollection,
    isStarted,
    urlsToParse;

function parseUrl(index = 0) {
    let url = urlsToParse[index];
    let tournamentId = url.id;

    request(url.url, (error, response, body) => {
        console.log('Loading bookmakers matches on ' + url.url);

        if (!error && response.statusCode === 200) {
            const $ = cheerio.load(body);
            let $table = $('table.foot-market');
            if ($table.length === 1) {
                $table.children().each(function(i, elem) {
                    let $item = $(this);
                    let teams = $item.data('eventName');
                    if (!teams) {
                        return true;
                    }
                    let arr = teams.split(' - ');
                    if (arr.length !== 2) {
                        return true;
                    }
                    let homeTeamName = trim(arr[0].toLowerCase());
                    let guestTeamName = trim(arr[1].toLowerCase());
                    $item = $item.children('.event-header').eq(0);
                    if (!$item) {
                        return true;
                    }
                    let date = $item.find('.first.member-area').eq(0).find('.date').eq(0).text();
                    if (!date) {
                        return true;
                    }

                    // date
                    date = trim(date);
                    let time = '-';
                    let dateParts = date.split(' ');
                    if (dateParts.length === 3) {
                        let year = (new Date()).addHours(HOURS_DIFF).getFullYear();
                        let day = parseInt(dateParts[0]);
                        day = isNaN(day) ? 1 : day;
                        let month = 0;
                        switch (trim(dateParts[1].toLowerCase())) {
                            case 'янв':
                                month = 0;
                                break;
                            case 'фев':
                                month = 1;
                                break;
                            case 'мар':
                                month = 2;
                                break;
                            case 'апр':
                                month = 3;
                                break;
                            case 'мая':
                                month = 4;
                                break;
                            case 'июня':
                                month = 5;
                                break;
                            case 'июля':
                                month = 6;
                                break;
                            case 'авг':
                                month = 7;
                                break;
                            case 'сен':
                                month = 8;
                                break;
                            case 'окт':
                                month = 9;
                                break;
                            case 'ноя':
                                month = 10;
                                break;
                            case 'дек':
                                month = 11;
                                break;
                        }
                        time = dateParts[2];
                        date = new Date(year, month, day);
                    } else {
                        // today
                        time = dateParts[0];
                        date = new Date();
                        date.addHours(HOURS_DIFF);
                    }
                    date.setHours(0, 0, 0);
                    date.setMilliseconds(0);

                    // rates
                    $item = $item.find('.main-row-buttons').eq(0);
                    if (!$item) {
                        return true;
                    }

                    let rates = {};
                    for (const prop of ['1', 'x', '2', '1x', '12', 'x2', 'f1', 'f2']) {
                        let $next = $item.next();
                        if (!$next) {
                            return true;
                        }
                        let text = trim($next.text());
                        if (prop === 'f1' || prop === 'f2') {
                            let i = text.indexOf(')');
                            let count = '-', value = '-';
                            if (i !== -1) {
                                count = parseFloat(text.substring(1, i));
                                if (isNaN(count)) {
                                    count = '-';
                                }
                                value = parseFloat(text.substring(i + 1));
                                if (isNaN(value)) {
                                    value = '-';
                                }
                            }
                            rates[prop] = {
                                count,
                                value,
                            };
                        } else {
                            rates[prop] = parseFloat(text);
                            if (isNaN(rates[prop])) {
                                rates[prop] = '-';
                            }
                        }
                        $item = $next;
                    }

                    // to DB
                    let bookmakerId = 2;
                    let id = `${bookmakerId};${tournamentId};${date.getTime()};${homeTeamName};${guestTeamName};`;

                    bookmakersMatchesCollection.remove({_id: id}).catch(() => { });
                    bookmakersMatchesCollection.insertOne({
                        _id: id,
                        bookmakerId,
                        tournamentId,
                        homeTeamName,
                        guestTeamName,
                        date,
                        time,
                        rates
                    }).catch(() => { });
                });
            } else {
                console.log($table.length + ' - skip!');
            }
        } else {
            console.log('Failed download page');
        }

        if (++index === urlsToParse.length) {
            // again
            setTimeout(() => parseUrl(), delay);
        } else {
            let i = index;
            setTimeout(() => parseUrl(i), 2000);
        }
    });
}

function trim(string) {
    return string.replace(/^\s*|\s*$/g, '');
}

Date.prototype.addHours = function(h) {
    this.setTime(this.getTime() + (h*60*60*1000));
    return this;
}

module.exports = {
    start(urls, mongoDB) {
        if (isStarted || !urls) {
            return;
        }

        isStarted = true;
        bookmakersMatchesCollection = mongoDB.collection('bookmakers_matches');
        urlsToParse = urls;

        parseUrl();
    }
};
<|endoftext|>


<commit_before>describe("template", function() {
  require("./setup")();

  var create = require("../index").create;
  var getTemplateList = require("../index").getTemplateList;
  var async = require("async");

  it("creates a template", function(done) {
    create(this.blog.id, this.fake.random.word(), {}, done);
  });

  it("throws an error if you try to create a template with no name", function(done) {
    expect(function() {
      create(this.blog.id, null, null, function() {});
    }).toThrow();

    done();
  });

  fit("creates a template whose name contains a slash", function(done) {
    var name = this.fake.random.word() + "/" + this.fake.random.word();
    var blog = this.blog;
    create(blog.id, name, {}, function(err) {
      if (err) return done.fail(err);
      getTemplateList(blog.id, function(err, templates) {
        if (err) return done.fail(err);

        expect(templates.filter(function(template){
          return template.name === name;
        }).length).toEqual(1);

        done();
      });
    });
  });

  xit("creates multiple templates in parallel", function(done) {
    var test = this;
    var templateNames = [];

    while (templateNames.length < 1000)
      templateNames.push(test.fake.random.uuid());

    async.map(
      templateNames,
      function(templateName, next) {
        create(test.blog.id, templateName, {}, next);
      },
      function(err, templates) {
        if (err) return done.fail(err);
        templates.forEach(function(template) {
          expect(template.id).toEqual(jasmine.any(String));
          expect(templateNames.indexOf(template.name)).not.toEqual(-1);
        });
        done();
      }
    );
  });

  xit("returns an error if you try to create a template which already exists", function(done) {
    var name = this.fake.random.word();
    var test = this;
    create(this.blog.id, name, {}, function(err) {
      if (err) return done.fail(err);
      create(test.blog.id, name, {}, function(err) {
        expect(err instanceof Error).toEqual(true);
        done();
      });
    });
  });

  xit("creates a template from an existing template", function(done) {
    var test = this;
    var blogID = test.blog.id;
    var original = this.fake.random.word();
    var cloned = this.fake.random.word();
    var description = this.fake.random.word();

    create(blogID, original, { description: description }, function(
      err,
      originalTemplate
    ) {
      if (err) return done.fail(err);

      create(blogID, cloned, { cloneFrom: originalTemplate.id }, function(
        err,
        clonedTemplate
      ) {
        if (err) return done.fail(err);

        expect(originalTemplate.description).toEqual(
          clonedTemplate.description
        );
        done();
      });
    });
  });

  xit("returns an error if you try to clone a template that does not exist", function(done) {
    create(
      this.blog.id,
      this.fake.random.word(),
      { cloneFrom: this.fake.random.word() },
      function(err) {
        expect(err instanceof Error).toBe(true);
        done();
      }
    );
  });
});
<commit_msg>Added spec for creating multiple templates concurrently<commit_after>describe("template", function() {
  require("./setup")();

  var create = require("../index").create;
  var getTemplateList = require("../index").getTemplateList;
  var async = require("async");

  it("creates a template", function(done) {
    create(this.blog.id, this.fake.random.word(), {}, done);
  });

  it("throws an error if you try to create a template with no name", function(done) {
    expect(function() {
      create(this.blog.id, null, null, function() {});
    }).toThrow();

    done();
  });

  it("creates a template whose name contains a slash", function(done) {
    var name = this.fake.random.word() + "/" + this.fake.random.word();
    var blog = this.blog;
    create(blog.id, name, {}, function(err) {
      if (err) return done.fail(err);
      getTemplateList(blog.id, function(err, templates) {
        if (err) return done.fail(err);

        expect(
          templates.filter(function(template) {
            return template.name === name;
          }).length
        ).toEqual(1);

        done();
      });
    });
  });

  it("creates multiple templates in parallel", function(done) {
    var test = this;
    var templateNames = [];

    while (templateNames.length < 1000)
      templateNames.push(test.fake.random.uuid());

    async.map(
      templateNames,
      function(templateName, next) {
        create(test.blog.id, templateName, {}, next);
      },
      function(err) {
        if (err) return done.fail(err);
        getTemplateList(test.blog.id, function(err, templates) {
          if (err) return done.fail(err);

          expect(
            templates.filter(function(template) {
              return templateNames.indexOf(template.name) > -1;
            }).length
          ).toEqual(1000);

          done();
        });
      }
    );
  });

  xit("returns an error if you try to create a template which already exists", function(done) {
    var name = this.fake.random.word();
    var test = this;
    create(this.blog.id, name, {}, function(err) {
      if (err) return done.fail(err);
      create(test.blog.id, name, {}, function(err) {
        expect(err instanceof Error).toEqual(true);
        done();
      });
    });
  });

  xit("creates a template from an existing template", function(done) {
    var test = this;
    var blogID = test.blog.id;
    var original = this.fake.random.word();
    var cloned = this.fake.random.word();
    var description = this.fake.random.word();

    create(blogID, original, { description: description }, function(
      err,
      originalTemplate
    ) {
      if (err) return done.fail(err);

      create(blogID, cloned, { cloneFrom: originalTemplate.id }, function(
        err,
        clonedTemplate
      ) {
        if (err) return done.fail(err);

        expect(originalTemplate.description).toEqual(
          clonedTemplate.description
        );
        done();
      });
    });
  });

  xit("returns an error if you try to clone a template that does not exist", function(done) {
    create(
      this.blog.id,
      this.fake.random.word(),
      { cloneFrom: this.fake.random.word() },
      function(err) {
        expect(err instanceof Error).toBe(true);
        done();
      }
    );
  });
});
<|endoftext|>


<commit_before>'use strict';

const path = require('path');<% if ( bundlingTool === 'rollup' ) { %>
const resolve = require('rollup-plugin-node-resolve');
const commonjs = require('rollup-plugin-commonjs');
const nodeBuiltins = require('rollup-plugin-node-builtins');
const globals = require('rollup-plugin-node-globals');<% if ( transpile ) { %>
const babel = require('rollup-plugin-babel');<% } %><% if ( codeCoverage ) { %>
const istanbul = require('rollup-plugin-istanbul');<% } %>
const rollupConfig = require('./rollup.config');<% } %><% if ( browserTestType === 'headless' ) { %>
const puppeteer = require('puppeteer');

process.env.CHROME_BIN = puppeteer.executablePath();<% } %>

let config;

const local = typeof process.env.CI === 'undefined' || process.env.CI === 'false';
const port = 9001;

if ( local ) {
	config = {
		browsers: <% if ( browserTestType !== 'headless' ) { %>['Chrome']<% } else { %>['ChromeHeadless']<% } %>,
	};
} else {
	config = {<% if ( cloudBrowsers ) { %>
		hostname: 'bs-local.com',
		browserStack: {
			username: process.env.BROWSER_STACK_USERNAME,
			accessKey: process.env.BROWSER_STACK_ACCESS_KEY,
			startTunnel: true,
			project: '<%= moduleName %>',
			name: 'Automated (Karma)',
			build: 'Automated (Karma)'
		},<% } %>
		customLaunchers: {<% if ( cloudBrowsers ) { %>
			'BS-Chrome': {
				base: 'BrowserStack',
				browser: 'Chrome',
				os: 'Windows',
				'os_version': '7',
				project: '<%= moduleName %>',
				build: 'Automated (Karma)',
				name: 'Chrome'
			},
			'BS-Firefox': {
				base: 'BrowserStack',
				browser: 'Firefox',
				os: 'Windows',
				'os_version': '7',
				project: '<%= moduleName %>',
				build: 'Automated (Karma)',
				name: 'Firefox'
			},
			'BS-IE9': {
				base: 'BrowserStack',
				browser: 'IE',
				'browser_version': '9',
				os: 'Windows',
				'os_version': '7',
				project: '<%= moduleName %>',
				build: 'Automated (Karma)',
				name: 'IE9'
			},<% } else { %>
			'Chrome-CI': {
				base: 'Chrome',
				flags: ['--no-sandbox']
			}<% } %>
		},
		browsers: <% if ( cloudBrowsers ) { %>['BS-Chrome', 'BS-Firefox', 'BS-IE9']<% } else { %><% if ( browserTestType !== 'headless' ) { %>[(!local ? 'Chrome-CI' : 'Chrome')]<% } else { %>['ChromeHeadless']<% } %><% } %>
	};
}

module.exports = function ( baseConfig ) {

	baseConfig.set(Object.assign({
		basePath: '',
		frameworks: ['mocha', 'fixture'],
		files: [
			'test/<% if ( manualTests || integrationTests ) { %>automated/<% } %>**/*.html',<% if ( bundlingTool === 'webpack' ) { %>
			'test/<% if ( manualTests || integrationTests ) { %>automated/<% } %>**/.webpack.js'<% } %><% if ( bundlingTool === 'rollup' ) { %>
			{ pattern: 'test/<% if ( manualTests || integrationTests ) { %>automated/<% } %>**/*.js', watched: false }<% } %>
		],
		exclude: [],
		preprocessors: {
			'test/<% if ( manualTests || integrationTests ) { %>automated/<% } %>**/*.html': ['html2js'],<% if ( bundlingTool === 'webpack' ) { %>
			'test/<% if ( manualTests || integrationTests ) { %>automated/<% } %>**/.webpack.js': ['webpack', 'sourcemap']<% } %><% if ( bundlingTool === 'rollup' ) { %>
			'test/<% if ( manualTests || integrationTests ) { %>automated/<% } %>**/*.js': ['rollup', 'sourcemap']<% } %>
		},
		reporters: ['mocha'<% if ( codeCoverage ) { %>, 'coverage-istanbul'<% } %>],
		port: port,
		colors: true,
		logLevel: baseConfig.LOG_INFO,
		autoWatch: false,
		client: {
			captureConsole: true
		},
		browserConsoleLogOptions: {
			level: 'log',
			format: '%b %T: %m',
			terminal: true
		},<% if ( bundlingTool === 'webpack' ) { %>
		webpack: {
			mode: 'none',
			devtool: 'cheap-module-inline-source-map'<% if ( transpile || codeCoverage ) { %>,
			module: {
				rules: [<% if ( transpile ) { %>
					{
						test: /\.js$/,
						exclude: /node_modules/,
						use: [{
							loader: 'babel-loader'
						}]
					}<% } %><% if ( transpile && codeCoverage ) { %>,<% } %><% if ( codeCoverage ) { %>
					{
						test: /\.js$/,
						exclude: /(node_modules|test)/,
						enforce: 'post',
						use: [{
							loader: 'istanbul-instrumenter-loader'<% if ( esModules ) { %>,
							options: {
								esModules: true
							}<% } %>
						}]
					}<% } %>
				]
			}<% } %>
		}<% } %><% if ( bundlingTool === 'rollup' ) { %>
		rollupPreprocessor: {
			plugins: [
				nodeBuiltins()<% if ( transpile ) { %>,
				babel({
					exclude: 'node_modules/**',
					runtimeHelpers: true
				})<% } %>,
				resolve({
					preferBuiltins: true
				}),
				commonjs(),
				globals(),
				...rollupConfig.plugins<% if ( transpile ) { %>.filter(({ name }) => !['babel'].includes(name))<% } %><% if ( codeCoverage ) { %>,
				istanbul({
					exclude: ['test/<% if ( manualTests || integrationTests ) { %>automated/<% } %>**/*.js', 'node_modules/**/*']
				})<% } %>
			],
			output: {
				format: 'iife',
				name: '<%= camelCasedModuleName %>',
				sourcemap: 'inline',
				intro: 'window.TYPED_ARRAY_SUPPORT = false;' // IE9
			}
		}<% } %>,<% if ( codeCoverage ) { %>
		coverageIstanbulReporter: {
			dir: path.join(__dirname, 'coverage/%browser%'),
			fixWebpackSourcePaths: true,
			reports: ['html', 'text'],
			thresholds: {
				global: {
					statements: 80
				}
			}
		},<% } %>
		singleRun: true,
		concurrency: Infinity
	}, config));

};
<commit_msg>Make Rollup work with Karma and Mocha<commit_after>'use strict';

const path = require('path');<% if ( bundlingTool === 'rollup' ) { %>
const fs = require('fs');
const resolve = require('rollup-plugin-node-resolve');
const commonjs = require('rollup-plugin-commonjs');
const nodeBuiltins = require('rollup-plugin-node-builtins');
const globals = require('rollup-plugin-node-globals');<% if ( transpile ) { %>
const babel = require('rollup-plugin-babel');<% } %><% if ( codeCoverage ) { %>
const istanbul = require('rollup-plugin-istanbul');<% } %>
const rollupConfig = require('./rollup.config');<% } %><% if ( browserTestType === 'headless' ) { %>
const puppeteer = require('puppeteer');

process.env.CHROME_BIN = puppeteer.executablePath();<% } %><% if ( bundlingTool === 'rollup' && transpile ) { %>

const babelrc = JSON.parse(fs.readFileSync(path.resolve(__dirname, '.babelrc'), 'utf8'));<% } %>

let config;

const local = typeof process.env.CI === 'undefined' || process.env.CI === 'false';
const port = 9001;

if ( local ) {
	config = {
		browsers: <% if ( browserTestType !== 'headless' ) { %>['Chrome']<% } else { %>['ChromeHeadless']<% } %>,
	};
} else {
	config = {<% if ( cloudBrowsers ) { %>
		hostname: 'bs-local.com',
		browserStack: {
			username: process.env.BROWSER_STACK_USERNAME,
			accessKey: process.env.BROWSER_STACK_ACCESS_KEY,
			startTunnel: true,
			project: '<%= moduleName %>',
			name: 'Automated (Karma)',
			build: 'Automated (Karma)'
		},<% } %>
		customLaunchers: {<% if ( cloudBrowsers ) { %>
			'BS-Chrome': {
				base: 'BrowserStack',
				browser: 'Chrome',
				os: 'Windows',
				'os_version': '7',
				project: '<%= moduleName %>',
				build: 'Automated (Karma)',
				name: 'Chrome'
			},
			'BS-Firefox': {
				base: 'BrowserStack',
				browser: 'Firefox',
				os: 'Windows',
				'os_version': '7',
				project: '<%= moduleName %>',
				build: 'Automated (Karma)',
				name: 'Firefox'
			},
			'BS-IE9': {
				base: 'BrowserStack',
				browser: 'IE',
				'browser_version': '9',
				os: 'Windows',
				'os_version': '7',
				project: '<%= moduleName %>',
				build: 'Automated (Karma)',
				name: 'IE9'
			},<% } else { %>
			'Chrome-CI': {
				base: 'Chrome',
				flags: ['--no-sandbox']
			}<% } %>
		},
		browsers: <% if ( cloudBrowsers ) { %>['BS-Chrome', 'BS-Firefox', 'BS-IE9']<% } else { %><% if ( browserTestType !== 'headless' ) { %>[(!local ? 'Chrome-CI' : 'Chrome')]<% } else { %>['ChromeHeadless']<% } %><% } %>
	};
}

module.exports = function ( baseConfig ) {

	baseConfig.set(Object.assign({
		basePath: '',
		frameworks: ['mocha', 'fixture'],
		files: [
			'test/<% if ( manualTests || integrationTests ) { %>automated/<% } %>**/*.html',<% if ( bundlingTool === 'webpack' ) { %>
			'test/<% if ( manualTests || integrationTests ) { %>automated/<% } %>**/.webpack.js'<% } %><% if ( bundlingTool === 'rollup' ) { %>
			{ pattern: 'test/<% if ( manualTests || integrationTests ) { %>automated/<% } %>**/*.js', watched: false }<% } %>
		],
		exclude: [],
		preprocessors: {
			'test/<% if ( manualTests || integrationTests ) { %>automated/<% } %>**/*.html': ['html2js'],<% if ( bundlingTool === 'webpack' ) { %>
			'test/<% if ( manualTests || integrationTests ) { %>automated/<% } %>**/.webpack.js': ['webpack', 'sourcemap']<% } %><% if ( bundlingTool === 'rollup' ) { %>
			'test/<% if ( manualTests || integrationTests ) { %>automated/<% } %>**/*.js': ['rollup', 'sourcemap']<% } %>
		},
		reporters: ['mocha'<% if ( codeCoverage ) { %>, 'coverage-istanbul'<% } %>],
		port: port,
		colors: true,
		logLevel: baseConfig.LOG_INFO,
		autoWatch: false,
		client: {
			captureConsole: true
		},
		browserConsoleLogOptions: {
			level: 'log',
			format: '%b %T: %m',
			terminal: true
		},<% if ( bundlingTool === 'webpack' ) { %>
		webpack: {
			mode: 'none',
			devtool: 'cheap-module-inline-source-map'<% if ( transpile || codeCoverage ) { %>,
			module: {
				rules: [<% if ( transpile ) { %>
					{
						test: /\.js$/,
						exclude: /node_modules/,
						use: [{
							loader: 'babel-loader'
						}]
					}<% } %><% if ( transpile && codeCoverage ) { %>,<% } %><% if ( codeCoverage ) { %>
					{
						test: /\.js$/,
						exclude: /(node_modules|test)/,
						enforce: 'post',
						use: [{
							loader: 'istanbul-instrumenter-loader'<% if ( esModules ) { %>,
							options: {
								esModules: true
							}<% } %>
						}]
					}<% } %>
				]
			}<% } %>
		}<% } %><% if ( bundlingTool === 'rollup' ) { %>
		rollupPreprocessor: {
			plugins: [
				nodeBuiltins()<% if ( transpile ) { %>,
				babel({
					exclude: 'node_modules/**',
					runtimeHelpers: true
				})<% } %>,
				resolve({
					preferBuiltins: true
				}),
				commonjs(),
				babel(Object.assign({
					include: 'node_modules/{has-flag,supports-color}/**',
					runtimeHelpers: true,
					babelrc: false
				}, babelrc)),
				globals(),
				...rollupConfig.plugins<% if ( transpile ) { %>.filter(({ name }) => !['babel'].includes(name))<% } %><% if ( codeCoverage ) { %>,
				istanbul({
					exclude: ['test/<% if ( manualTests || integrationTests ) { %>automated/<% } %>**/*.js', 'node_modules/**/*']
				})<% } %>
			],
			output: {
				format: 'iife',
				name: '<%= camelCasedModuleName %>',
				sourcemap: 'inline',
				intro: 'window.TYPED_ARRAY_SUPPORT = false;' // IE9
			}
		}<% } %>,<% if ( codeCoverage ) { %>
		coverageIstanbulReporter: {
			dir: path.join(__dirname, 'coverage/%browser%'),
			fixWebpackSourcePaths: true,
			reports: ['html', 'text'],
			thresholds: {
				global: {
					statements: 80
				}
			}
		},<% } %>
		singleRun: true,
		concurrency: Infinity
	}, config));

};
<|endoftext|>


<commit_before>'use strict';

// <%= name %>-model.js - A mongoose model
//
// See http://mongoosejs.com/docs/models.html
// for more of what you can do here.

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const <%= name %>Schema = new Schema({
  <% if(name === 'user') { %>email: {
    type: String,
    required: true,
    unique: true
  }, password: {
    type: String,
    required: true
  }<% } else { %>text: {
    type: String,
    required: true,
    index: true
  }<% } %>
});

const <%= name %>Model = mongoose.model('<%= name %>', <%= name %>Schema);

module.exports = <%= name %>Model;<commit_msg>Also fix Mongoose model<commit_after>'use strict';

// <%= name %>-model.js - A mongoose model
//
// See http://mongoosejs.com/docs/models.html
// for more of what you can do here.

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const <%= name %>Schema = new Schema({
  <% if(name === 'user') { %>email: {
    type: String,
    required: true,
    unique: true
  }, password: {
    type: String,
    required: true
  }<% } else { %>text: {
    type: String,
    required: true
  }<% } %>
});

const <%= name %>Model = mongoose.model('<%= name %>', <%= name %>Schema);

module.exports = <%= name %>Model;<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { storiesOf } from '@kadira/storybook';

import * as animationIcons from '../src/svg-icons/animation';
import * as actionIcons from '../src/svg-icons/action';
import * as alertIcons from '../src/svg-icons/alert';
import * as avIcons from '../src/svg-icons/av';
import * as communicationIcons from '../src/svg-icons/communication';
import * as contentIcons from '../src/svg-icons/content';
import * as deviceIcons from '../src/svg-icons/device';
import * as editorIcons from '../src/svg-icons/editor';
import * as fileIcons from '../src/svg-icons/file';
import * as hardwareIcons from '../src/svg-icons/hardware';
import * as imageIcons from '../src/svg-icons/image';
import * as mapsIcons from '../src/svg-icons/maps';
import * as navigationIcons from '../src/svg-icons/navigation';
import * as notificationIcons from '../src/svg-icons/notification';
import * as placesIcons from '../src/svg-icons/places';
import * as toggleIcons from '../src/svg-icons/toggle';

const iconTypes = {
  animation: animationIcons,
  action: actionIcons,
  alert: alertIcons,
  av: avIcons,
  communication: communicationIcons,
  content: contentIcons,
  device: deviceIcons,
  editor: editorIcons,
  file: fileIcons,
  hardware: hardwareIcons,
  image: imageIcons,
  maps: mapsIcons,
  navigation: navigationIcons,
  notification: notificationIcons,
  places: placesIcons,
  toggle: toggleIcons,
};

Object.keys(iconTypes).forEach((iconType) => {
  const stories = storiesOf(iconType, module);
  Object.keys(iconTypes[iconType]).forEach((iconName) => {
    let Icon = iconTypes[iconType][iconName];
    if (iconName.startsWith('Animation')) {
      class IconContainer extends Component {
        state = {
          show: false,
        }

        render() {
          const IconElement = iconTypes[iconType][iconName];
          const buttonText = this.state.show ? 'Hide' : 'Show';
          return (

              <IconElement
                {...this.props}
                show={this.state.show}
              />

              <button
                onClick={() => {
                  this.setState({ show: !this.state.show });
                }}
              >
                {buttonText}
              </button>

          );
        }
      }

      Icon = IconContainer;
    }

    stories.add(iconName, () => (
      <Icon
        color="#2196F3"
        hoverColor="#1386B5"
        style={{
          width: 54,
          height: 54,
        }}
      />
    ));
  });
});
<commit_msg>Add margin for IconContainer component on storybook<commit_after>import React, { Component } from 'react';
import { storiesOf } from '@kadira/storybook';

import * as animationIcons from '../src/svg-icons/animation';
import * as actionIcons from '../src/svg-icons/action';
import * as alertIcons from '../src/svg-icons/alert';
import * as avIcons from '../src/svg-icons/av';
import * as communicationIcons from '../src/svg-icons/communication';
import * as contentIcons from '../src/svg-icons/content';
import * as deviceIcons from '../src/svg-icons/device';
import * as editorIcons from '../src/svg-icons/editor';
import * as fileIcons from '../src/svg-icons/file';
import * as hardwareIcons from '../src/svg-icons/hardware';
import * as imageIcons from '../src/svg-icons/image';
import * as mapsIcons from '../src/svg-icons/maps';
import * as navigationIcons from '../src/svg-icons/navigation';
import * as notificationIcons from '../src/svg-icons/notification';
import * as placesIcons from '../src/svg-icons/places';
import * as toggleIcons from '../src/svg-icons/toggle';

const iconTypes = {
  animation: animationIcons,
  action: actionIcons,
  alert: alertIcons,
  av: avIcons,
  communication: communicationIcons,
  content: contentIcons,
  device: deviceIcons,
  editor: editorIcons,
  file: fileIcons,
  hardware: hardwareIcons,
  image: imageIcons,
  maps: mapsIcons,
  navigation: navigationIcons,
  notification: notificationIcons,
  places: placesIcons,
  toggle: toggleIcons,
};

Object.keys(iconTypes).forEach((iconType) => {
  const stories = storiesOf(iconType, module);
  Object.keys(iconTypes[iconType]).forEach((iconName) => {
    let Icon = iconTypes[iconType][iconName];
    if (iconName.startsWith('Animation')) {
      class IconContainer extends Component {
        state = {
          show: false,
        }

        render() {
          const IconElement = iconTypes[iconType][iconName];
          const buttonText = this.state.show ? 'Hide' : 'Show';
          return (

              <IconElement
                {...this.props}
                show={this.state.show}
              />

                <button
                  onClick={() => {
                    this.setState({ show: !this.state.show });
                  }}
                >
                  {buttonText}
                </button>

          );
        }
      }

      Icon = IconContainer;
    }

    stories.add(iconName, () => (
      <Icon
        color="#2196F3"
        hoverColor="#1386B5"
        style={{
          width: 54,
          height: 54,
        }}
      />
    ));
  });
});
<|endoftext|>


<commit_before>'use strict';

var chartController = function($scope, $location, searchResults){
  // check if a search has been carried out, else redirect back to search
  console.log('running chartController');

  if (searchResults.getTrials() === null){
    $location.path('/search');
  } else {

    var trials = searchResults.getTrials();
    $scope.tableTrials = [];
    $scope.searchTerm = searchResults.getSearch();
    // set global options for the 2 charts here
    Highcharts.setOptions({
      title: {
        text: 'source: clinicaltrial.gov'
      },
      legend: {
        enabled: false
      }
    });

    $scope.statusChartOptions = {
      chart: {
        type: 'bar',
        renderTo: 'statusChart'
      },
      xAxis: {
        categories: []
      },
      yAxis: {
        title: {
          text: 'Trials'
        }
      },
      series: [{
        name: 'Clinical Trials',
        data: []
      }]
    };
    // populate categories for x-axis
    for (var status in trials){
      $scope.statusChartOptions.xAxis.categories.push(status);
      $scope.statusChartOptions.series[0].data.push({
        y: trials[status].trialcount,
        events:{
          click: function(){ //invokes with an jquery event but we don't need it
            // things to clear the trial table if it's not empty
            $scope.tableTrials = [];
            $scope.selectedCategory = '';
            $scope.selectedStatus = this.category;
            $scope.$apply();

            $scope.buildCategoryChart(this.category);
          }
        }
      });
    }

    $scope.statusChart = new Highcharts.Chart($scope.statusChartOptions);

    $scope.buildCategoryChart = function(status){ // status is a string
      $scope.categoryChartOptions = {
        chart: {
          type: 'bar',
          renderTo: 'categoryChart',
        },
        xAxis: {
          categories: []
        },
        yAxis: {
          title: {
            text: 'Trials'
          }
        },
        series: [{
          name: 'Clinical Trials',
          data: []
        }]
      };

      // count how many categories there are and set height = 100 + #conditions*20
      var conditions = 0;

      for (var category in trials[status].conditions){
        conditions++;
        console.log(category);
        $scope.categoryChartOptions.xAxis.categories.push(category);
        $scope.categoryChartOptions.series[0].data.push({
          y: trials[status].conditions[category].length,
          events: {
            click: function(){
              $scope.selectedCategory = this.category;
              // empty the array
              $scope.tableTrials = [];
              for (var i=0; i<trials[status].conditions[this.category].length; i++){
                $scope.tableTrials = $scope.tableTrials.concat(trials[status].conditions[this.category][i]);
              }
              $scope.$apply();
            }
          }
        });
      }
      $scope.categoryChartOptions.chart.height = Math.max(100 + conditions*20, 200);
      $scope.categoryChart = new Highcharts.Chart($scope.categoryChartOptions);
    };
  }
};

angular.module('clinicaltrialsApp')
  .controller('chartCtrl', ['$scope', '$location','searchResults', chartController]);
<commit_msg>Adds commented dividers<commit_after>'use strict';

var chartController = function($scope, $location, searchResults, ngTableParams){
  // check if a search has been carried out, else redirect back to search
  console.log('running chartController');

  if (searchResults.getTrials() === null){
    $location.path('/search');
  } else {

    var trials = searchResults.getTrials();
    $scope.tableTrials = [];
    $scope.searchTerm = searchResults.getSearch();
// ************************************* set global options for the 2 charts here ************************************* //
    Highcharts.setOptions({
      title: {
        text: 'source: clinicaltrial.gov'
      },
      legend: {
        enabled: false
      }
    });

// ************************************* build StatusChart ************************************* //

    $scope.statusChartOptions = {
      chart: {
        type: 'bar',
        renderTo: 'statusChart'
      },
      xAxis: {
        categories: []
      },
      yAxis: {
        title: {
          text: 'Trials'
        }
      },
      series: [{
        name: 'Clinical Trials',
        data: []
      }]
    };
    // populate categories for x-axis
    for (var status in trials){
      $scope.statusChartOptions.xAxis.categories.push(status);
      $scope.statusChartOptions.series[0].data.push({
        y: trials[status].trialcount,
        events:{
          click: function(){ //invokes with an jquery event but we don't need it
            // things to clear the trial table if it's not empty
            $scope.tableTrials = [];
            $scope.selectedCategory = '';
            $scope.selectedStatus = this.category;
            $scope.$apply();

            $scope.buildCategoryChart(this.category);
          }
        }
      });
    }

    $scope.statusChart = new Highcharts.Chart($scope.statusChartOptions);

// ************************************* build category chart ************************************* //

    $scope.buildCategoryChart = function(status){ // status is a string
      $scope.categoryChartOptions = {
        chart: {
          type: 'bar',
          renderTo: 'categoryChart',
        },
        xAxis: {
          categories: []
        },
        yAxis: {
          title: {
            text: 'Trials'
          }
        },
        series: [{
          name: 'Clinical Trials',
          data: []
        }]
      };

      // count how many categories there are and set height = 100 + #conditions*20
      var conditions = 0;

      for (var category in trials[status].conditions){
        conditions++;
        console.log(category);
        $scope.categoryChartOptions.xAxis.categories.push(category);
        $scope.categoryChartOptions.series[0].data.push({
          y: trials[status].conditions[category].length,
          events: {
            click: function(){
              $scope.selectedCategory = this.category;
              // ******************* trial table stuff ******************* //
              $scope.tableTrials = trials[status].conditions[this.category];
              $scope.$apply();
            }
          }
        });
      }
      $scope.categoryChartOptions.chart.height = Math.max(100 + conditions*20, 200);
      $scope.categoryChart = new Highcharts.Chart($scope.categoryChartOptions);
    };

  } // from else li9
};

angular.module('clinicaltrialsApp')
  .controller('chartCtrl', ['$scope', '$location','searchResults', chartController]);
<|endoftext|>


<commit_before>(function() {
var module = angular.module('fim.base');
module.config(function($routeProvider) {
  $routeProvider
    .when('/goods/:engine/:section/:id_rs?', {
      templateUrl: 'partials/goods.html',
      controller: 'GoodsCtrl'
    })
});

module.controller('GoodsCtrl', function($location, $rootScope, $scope, $http, $routeParams, nxt, plugins,
  shoppingCartService, AllGoodsProvider, PastGoodsProvider, GoodsDetailsProvider, UserGoodsProvider,
  SoldGoodsProvider, DeliveryConfirmedGoodsProvider, Gossip, db) {

  $scope.paramEngine  = $rootScope.paramEngine = $routeParams.engine;
  $scope.paramSection = $routeParams.section;
  $scope.id_rs        = $routeParams.id_rs;

  var api             = $scope.paramEngine == 'fim' ? nxt.fim() : nxt.nxt();
  $scope.symbol       = api.engine.symbol;

  /* @param items Array of CartModel (@see models/cart.js) */
  function setupShoppingCart(items) {
    $scope.$evalAsync(function () {
      $scope.shoppingCart = items||[];
      $scope.shoppingCart.forEach(calculateItemTotal);
      calculateCartTotal();
    });
  }

  shoppingCartService.getAll(api.engine.symbol).then(setupShoppingCart);
  db.cart.addObserver($scope, {
    finally: function () {
      shoppingCartService.getAll(api.engine.symbol).then(setupShoppingCart);
    }
  });

  switch ($scope.paramSection) {
    /* /goods/nxt/listing OR /goods/nxt/listing/NXT-7JDS-CS72-TNGS-BBE8E */
    case 'listing': {
      $scope.provider = new AllGoodsProvider(api, $scope, 10, $scope.id_rs);
      $scope.provider.reload();
      break;
    }
    /* /goods/nxt/tags/some-tag */
    case 'tags': {
      $scope.id_rs = null;
      $scope.provider = new AllGoodsProvider(api, $scope, 10, null, $routeParams.id_rs); /* we use id_rs for the tag parameter */
      $scope.provider.reload();
      break;
    }
    /* /goods/nxt/pastorders/NXT-7JDS-CS72-TNGS-BBE8E */
    case 'pastorders': {
      if ($scope.id_rs) {
        $scope.provider = new PastGoodsProvider(api, $scope, 10, $scope.id_rs);
        $scope.provider.reload();
      }
      else {
        $location.path('/goods/'+$scope.paramEngine+'/listing');
      }
      break;
    }
    /* /goods/nxt/solditems/NXT-7JDS-CS72-TNGS-BBE8E */
    case 'solditems': {
      if ($scope.id_rs) {
        // for pending
        $scope.soldGoods = new SoldGoodsProvider(api, $scope, 10, $scope.id_rs);
        $scope.soldGoods.reload();

        // for Completed
        $scope.deliveryConfirmedGoods = new DeliveryConfirmedGoodsProvider(api, $scope, $scope.id_rs);
        $scope.deliveryConfirmedGoods.reload();
      }
      else {
        $location.path('/goods/'+$scope.paramEngine+'/listing');
      }
      break;
    }
    /* /goods/nxt/cart OR /goods/nxt/cart/NXT-7JDS-CS72-TNGS-BBE8E */
    case 'cart': {
      /* nothing to do here $scope.shoppingCart is setup elsewhere */
      break;
    }
    /* /goods/nxt/142563763572767 */
    default: {
      $scope.provider = new GoodsDetailsProvider(api, $scope, $scope.paramSection);
      $scope.provider.reload();
      $scope.paramSection = 'detail';
    }
  }

  /* @param item CartModel */
  $scope.quantityChanged = function (item) {
    $scope.$evalAsync(function () {
      calculateItemTotal(item);
      calculateCartTotal();
      item.save();
    });
  }

  function calculateCartTotal() {
    var totalNQT = '0';
    $scope.shoppingCart.forEach(function (item) {
      totalNQT = (new BigInteger(totalNQT)).add(
                    new BigInteger(nxt.util.convertToNQT(item.totalNXT))).toString()
    });
    $scope.totalNXT = nxt.util.convertToNXT(totalNQT.toString());
  }

  /* @param item CartModel */
  function calculateItemTotal(item) {
    if (item.count == 0) {
      item.totalNXT = '0';
    }
    else {
      item.totalNXT = nxt.util.convertToNXT((new BigInteger(item.priceNQT)).multiply(new BigInteger(""+item.count)).toString());
    }
  }

  $scope.msg = function(id) {
    plugins.get('transaction').get('sendMessage').execute($scope.id_rs, { recipient: id, editRecipient: false });
  }

  $scope.deleteGood = function(good) {
    plugins.get('transaction').get('dgsDelisting').execute({goods: good.goods});
  }

  $scope.add = function() {
    plugins.get('transaction').get('dgsListing').execute();
  }

  $scope.placeOrder = function() {
    var result = (new BigInteger(nxt.util.convertToNQT($scope.totalNXT))).compareTo(
                    new BigInteger(nxt.util.convertToNQT($rootScope.userData.balanceNXT)));
    if (result <= 0) {
      $scope.balanceError = "You don't have enough balance to place these orders.";
    }
    else {
      $scope.balanceError = ' ';
      var iterator = new Iterator($scope.shoppingCart);
      processCart(iterator);
    }
  }

  function processCart(iterator) {
    if (iterator.hasMore()) {
      var item = iterator.next();
      var order_args = {
        goods: item.goods,
        priceNXT: nxt.util.convertToNXT(item.priceNQT),
        quantity: item.count,
        name: item.name,
        deliveryDeadlineTimestamp: String(nxt.util.convertToEpochTimestamp(Date.now()) + 60 * 60 * 168),
        recipient: item.sellerRS
      }
      plugins.get('transaction').get('dgsPurchase').execute(order_args).then(
        function(data) {
          if(data) {
            if (item.callback) {
              $http({
                url: item.callback,
                data: item,
                method: 'POST'
              }).success(function(data) {
                console.log(data);
              }).error(function(err) {
                console.log(err);
              });
            }
            item.delete().then(
              function () {
                if (iterator.hasMore()) {
                  processCart(iterator);
                }
                else {
                  $scope.$evalAsync(function () {
                    $scope.successful = "Payment Completed";
                  });
                }
              }
            );
          }
        }
      );
    }
  }

  $scope.decrypt = function(encryptedMessage, index) {
    if(encryptedMessage) {
      var publicKey = api.crypto.secretPhraseToPublicKey($rootScope.currentAccount.secretPhrase);
      $scope.textMessage = index;
      $scope.decryptedMessage = Gossip.decryptMessage(publicKey, encryptedMessage.nonce, encryptedMessage.data)
    }
  }

  $scope.rebate = function(rebateOrder) {
    var rebate_args = {
      purchase: rebateOrder.purchase,
      refundNQT: rebateOrder.priceNQT
    }
    plugins.get('transaction').get('dgsRefund').execute(rebate_args);
  }

  $scope.confirmDelivery = function(deliveryItem) {
    var confirmDelivery_args = {
      purchase: deliveryItem.purchase
    }
    plugins.get('transaction').get('dgsDelivery').execute(confirmDelivery_args);
  }

  $scope.addToCart = function(details) {
    shoppingCartService.add($scope.symbol, details, 1).then(
      function () {
        $location.path('/goods/'+$scope.paramEngine+'/cart');
      }
    );
  }

});
})();<commit_msg>goods.js alignment and fields are readonly<commit_after>(function() {
var module = angular.module('fim.base');
module.config(function($routeProvider) {
  $routeProvider
    .when('/goods/:engine/:section/:id_rs?', {
      templateUrl: 'partials/goods.html',
      controller: 'GoodsCtrl'
    })
});

module.controller('GoodsCtrl', function($location, $rootScope, $scope, $http, $routeParams, nxt, plugins,
  shoppingCartService, AllGoodsProvider, PastGoodsProvider, GoodsDetailsProvider, UserGoodsProvider,
  SoldGoodsProvider, DeliveryConfirmedGoodsProvider, Gossip, db) {

  $scope.paramEngine  = $rootScope.paramEngine = $routeParams.engine;
  $scope.paramSection = $routeParams.section;
  $scope.id_rs        = $routeParams.id_rs;

  var api             = $scope.paramEngine == 'fim' ? nxt.fim() : nxt.nxt();
  $scope.symbol       = api.engine.symbol;

  /* @param items Array of CartModel (@see models/cart.js) */
  function setupShoppingCart(items) {
    $scope.$evalAsync(function () {
      $scope.shoppingCart = items||[];
      $scope.shoppingCart.forEach(calculateItemTotal);
      calculateCartTotal();
    });
  }

  shoppingCartService.getAll(api.engine.symbol).then(setupShoppingCart);
  db.cart.addObserver($scope, {
    finally: function () {
      shoppingCartService.getAll(api.engine.symbol).then(setupShoppingCart);
    }
  });

  switch ($scope.paramSection) {
    /* /goods/nxt/listing OR /goods/nxt/listing/NXT-7JDS-CS72-TNGS-BBE8E */
    case 'listing': {
      $scope.provider = new AllGoodsProvider(api, $scope, 10, $scope.id_rs);
      $scope.provider.reload();
      break;
    }
    /* /goods/nxt/tags/some-tag */
    case 'tags': {
      $scope.id_rs = null;
      $scope.provider = new AllGoodsProvider(api, $scope, 10, null, $routeParams.id_rs); /* we use id_rs for the tag parameter */
      $scope.provider.reload();
      break;
    }
    /* /goods/nxt/pastorders/NXT-7JDS-CS72-TNGS-BBE8E */
    case 'pastorders': {
      if ($scope.id_rs) {
        $scope.provider = new PastGoodsProvider(api, $scope, 10, $scope.id_rs);
        $scope.provider.reload();
      }
      else {
        $location.path('/goods/'+$scope.paramEngine+'/listing');
      }
      break;
    }
    /* /goods/nxt/solditems/NXT-7JDS-CS72-TNGS-BBE8E */
    case 'solditems': {
      if ($scope.id_rs) {
        // for pending
        $scope.soldGoods = new SoldGoodsProvider(api, $scope, 10, $scope.id_rs);
        $scope.soldGoods.reload();

        // for Completed
        $scope.deliveryConfirmedGoods = new DeliveryConfirmedGoodsProvider(api, $scope, $scope.id_rs);
        $scope.deliveryConfirmedGoods.reload();
      }
      else {
        $location.path('/goods/'+$scope.paramEngine+'/listing');
      }
      break;
    }
    /* /goods/nxt/cart OR /goods/nxt/cart/NXT-7JDS-CS72-TNGS-BBE8E */
    case 'cart': {
      /* nothing to do here $scope.shoppingCart is setup elsewhere */
      break;
    }
    /* /goods/nxt/142563763572767 */
    default: {
      $scope.provider = new GoodsDetailsProvider(api, $scope, $scope.paramSection);
      $scope.provider.reload();
      $scope.paramSection = 'detail';
    }
  }

  /* @param item CartModel */
  $scope.quantityChanged = function (item) {
    $scope.$evalAsync(function () {
      calculateItemTotal(item);
      calculateCartTotal();
      item.save();
    });
  }

  function calculateCartTotal() {
    var totalNQT = '0';
    $scope.shoppingCart.forEach(function (item) {
      totalNQT = (new BigInteger(totalNQT)).add(
                    new BigInteger(nxt.util.convertToNQT(item.totalNXT))).toString()
    });
    $scope.totalNXT = nxt.util.convertToNXT(totalNQT.toString());
  }

  /* @param item CartModel */
  function calculateItemTotal(item) {
    if (item.count == 0) {
      item.totalNXT = '0';
    }
    else {
      item.totalNXT = nxt.util.convertToNXT((new BigInteger(item.priceNQT)).multiply(new BigInteger(""+item.count)).toString());
    }
  }

  $scope.msg = function(id) {
    plugins.get('transaction').get('sendMessage').execute($scope.id_rs, { recipient: id, editRecipient: false });
  }

  $scope.deleteGood = function(good) {
    plugins.get('transaction').get('dgsDelisting').execute({goods: good.goods});
  }

  $scope.add = function() {
    plugins.get('transaction').get('dgsListing').execute();
  }

  $scope.placeOrder = function() {
    var result = (new BigInteger(nxt.util.convertToNQT($scope.totalNXT))).compareTo(
                    new BigInteger(nxt.util.convertToNQT($rootScope.userData.balanceNXT)));
    if (result <= 0) {
      $scope.balanceError = "You don't have enough balance to place these orders.";
    }
    else {
      $scope.balanceError = ' ';
      var iterator = new Iterator($scope.shoppingCart);
      processCart(iterator);
    }
  }

  function processCart(iterator) {
    if (iterator.hasMore()) {
      var item = iterator.next();
      var order_args = {
        goods: item.goods,
        priceNXT: nxt.util.convertToNXT(item.priceNQT),
        quantity: item.count,
        name: item.name,
        deliveryDeadlineTimestamp: String(nxt.util.convertToEpochTimestamp(Date.now()) + 60 * 60 * 168),
        recipient: item.sellerRS
      }
      plugins.get('transaction').get('dgsPurchase').execute(order_args).then(
        function(data) {
          if(data) {
            if (item.callback) {
              $http({
                url: item.callback,
                data: item,
                method: 'POST'
              }).success(function(data) {
                console.log(data);
              }).error(function(err) {
                console.log(err);
              });
            }
            item.delete().then(
              function () {
                if (iterator.hasMore()) {
                  processCart(iterator);
                }
                else {
                  $scope.$evalAsync(function () {
                    $scope.successful = "Payment Completed";
                  });
                }
              }
            );
          }
    else if ($scope.paramSection == "pastorders") {
        }
      );
    }
  }

  $scope.decrypt = function(encryptedMessage, index) {
    if(encryptedMessage) {
      var publicKey = api.crypto.secretPhraseToPublicKey($rootScope.currentAccount.secretPhrase);
      $scope.textMessage = index;
      $scope.decryptedMessage = Gossip.decryptMessage(publicKey, encryptedMessage.nonce, encryptedMessage.data)
    }
  }

  $scope.rebate = function(rebateOrder) {
    var rebate_args = {
      purchase: rebateOrder.purchase,
      refundNQT: rebateOrder.priceNQT
    }
    plugins.get('transaction').get('dgsRefund').execute(rebate_args);
  }

  $scope.confirmDelivery = function(deliveryItem) {
    var confirmDelivery_args = {
      purchase: deliveryItem.purchase
    }
    plugins.get('transaction').get('dgsDelivery').execute(confirmDelivery_args);
  }
    else {

  $scope.addToCart = function(details) {
    shoppingCartService.add($scope.symbol, details, 1).then(
      function () {
        $location.path('/goods/'+$scope.paramEngine+'/cart');
      }
    );
  }

});
})();<|endoftext|>