<commit_before>/* jshint camelcase:false, node:true */

"use strict";

module.exports = function(grunt) {

    // Force use of Unix newlines
    grunt.util.linefeed = "\n";

    // Project configuration.
    grunt.initConfig({
        // Metadata.
        pkg: grunt.file.readJSON("package.json"),
        banner: {
            compact: "/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - " +
                "<%= grunt.template.today('yyyy-mm-dd') %>\n" +
                "<%= pkg.homepage ? '* ' + pkg.homepage + '\\n' : '' %>" +
                "* Copyright (c) <%= grunt.template.today('yyyy') %> Nicole Sullivan and Nicholas C. Zakas;\n" +
                "* Licensed <%= _.pluck(pkg.licenses, 'type').join(', ') %> <%= _.pluck(pkg.licenses, 'url').join(', ') %> */\n",
            full: "/*!\n" +
                "CSSLint\n" +
                "Copyright (c) <%= grunt.template.today('yyyy') %> Nicole Sullivan and Nicholas C. Zakas. All rights reserved.\n" +
                "\n" +
                "Permission is hereby granted, free of charge, to any person obtaining a copy\n" +
                "of this software and associated documentation files (the 'Software'), to deal\n" +
                "in the Software without restriction, including without limitation the rights\n" +
                "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n" +
                "copies of the Software, and to permit persons to whom the Software is\n" +
                "furnished to do so, subject to the following conditions:\n" +
                "\n" +
                "The above copyright notice and this permission notice shall be included in\n" +
                "all copies or substantial portions of the Software.\n" +
                "\n" +
                "THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n" +
                "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n" +
                "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n" +
                "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n" +
                "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n" +
                "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n" +
                "THE SOFTWARE.\n\n" +
                "*/\n" +
                "/* Build: v<%= pkg.version %> <%= grunt.template.today('dd-mmmm-yyyy hh:MM:ss') %> */"
        },
        build_dir: "dist",
        //Parser lib copy for versions that can't use requirejs
        parserlib: "node_modules/parserlib/lib/node-parserlib.js",
        //clone copy for versions that can't use requirejs
        clone: "node_modules/clone/clone.js",
        //Core CSSLint files used by most versions
        csslint_files: [
            "src/core/CSSLint.js",
            "src/core/*.js",
            "src/rules/*.js",
            "src/formatters/*.js"
        ],
        //Core fileset used by most versions
        core_files: [
            "<%= parserlib %>",
            "<%= clone %>",
            "<%= csslint_files %>"
        ],
        // Task configuration.
        clean: {
            dist: "<%= build_dir %>"
        },
        changelog: {
            dest: "CHANGELOG"
        },
        concat: {
            core: {
                options: {
                    banner: "<%= banner.full %>\n" +
                            //Hack for using the node version of parserlib
                            "var exports = exports || {};\n" +
                            "var CSSLint = (function(){\n",
                    footer: "\nreturn CSSLint;\n})();"
                },
                src: [
                    "<%= core_files %>"
                ],
                dest: "<%= build_dir %>/<%= pkg.name %>.js"
            },//Build environment workers
            rhino: {
                src: [
                    "<%= concat.core.dest %>",
                    "src/cli/common.js",
                    "src/cli/rhino.js"
                ],
                dest: "<%= build_dir %>/<%= pkg.name %>-rhino.js"
            },
            node: {
                options: {
                    banner: "<%= banner.full %>\n" +
                            "var clone = require('clone');\n" +
                            "var parserlib = require('parserlib');\n",
                    footer: "\nexports.CSSLint = CSSLint;"
                },
                files: {
                    "<%= build_dir %>/<%= pkg.name %>-node.js": ["<%= csslint_files %>"]
                }
            },
            node_cli: {
                options: {
                    banner: "#!/usr/bin/env node\n<%= banner.full %>"
                },
                src: [
                    "src/cli/common.js",
                    "src/cli/node.js"
                ],
                dest: "<%= build_dir %>/cli.js"
            },
            tests: {
                src: [
                    "tests/**/*.js",
                    "!tests/all-rules.js"
                ],
                dest: "<%= build_dir %>/<%= pkg.name %>-tests.js"
            },
            worker: {
                options: {
                    banner: "<%= banner.full %>\n" +
                            //Hack for using the node version of parserlib
                            "var exports = exports || {};\n"
                },
                src: [
                    "<%= core_files %>",
                    "src/worker/*.js"
                ],
                dest: "<%= build_dir %>/<%= pkg.name %>-worker.js"
            },
            wsh: {
                src: [
                    "<%= concat.core.dest %>",
                    "src/cli/common.js",
                    "src/cli/wsh.js"
                ],
                dest: "<%= build_dir %>/<%= pkg.name %>-wsh.js"
            }
        },
        includereplace: {
            dist: {
                options: {
                    // Global variables available in all files
                    globals: {
                        VERSION: "<%= pkg.version %>"
                    },
                    prefix: "@",
                    suffix: "@"
                },
                files: [{
                    expand: true,
                    cwd: "<%= build_dir %>/",
                    src: "**/*",
                    dest: "<%= build_dir %>/"
                }]
            }
        },
        jshint: {
            options: {
                jshintrc: ".jshintrc"
            },
            gruntfile: {
                src: ["Gruntfile.js", "tasks/*.js"]
            },
            demo: {
                src: "demos/*.js"
            },
            all: {
                src: "src/**/*.js"
            },
            tests: {
                src: "tests/**/*.js"
            }
        },
        watch: {
            gruntfile: {
                files: "<%= jshint.gruntfile.src %>",
                tasks: ["jshint"]
            },
            src: {
                files: "<%= jshint.all.src %>",
                tasks: ["jshint:all"]
            },
            lib_test: {
                files: "<%= jshint.tests.src %>",
                tasks: ["jshint:tests"]
            }
        },
        yuitest: {
            tests: {
                src: [
                    "tests/**/*.js"
                ]
            }
        },
        test_rhino: {
            tests: {
                src: [
                    "<%= concat.tests.dest %>",
                    "tests/all-rules.js"
                ]
            }
        }
    });

    // Load any grunt plugins found in package.json.
    require("load-grunt-tasks")(grunt, {scope: "devDependencies"});
    require("time-grunt")(grunt);

    // Load custom tasks
    grunt.loadTasks("tasks");

    // Default task.
    grunt.registerTask("default", ["build", "test"]);

    grunt.registerTask("build", ["clean", "concat", "includereplace"]);

    //Alias for
    grunt.registerTask("lint", ["jshint"]);

    // Testing
    grunt.registerTask("test", ["build", "jshint", "yuitest"]);
    grunt.registerTask("rhino", ["build", "jshint", "test_rhino"]);

    grunt.registerTask("release", ["default", "changelog"]);
};
<commit_msg>Get rid of the build date in dist files.<commit_after>/* jshint camelcase:false, node:true */

"use strict";

module.exports = function(grunt) {

    // Force use of Unix newlines
    grunt.util.linefeed = "\n";

    // Project configuration.
    grunt.initConfig({
        // Metadata.
        pkg: grunt.file.readJSON("package.json"),
        banner: "/*!\n" +
                "CSSLint v<%= pkg.version %>\n" +
                "Copyright (c) <%= grunt.template.today('yyyy') %> Nicole Sullivan and Nicholas C. Zakas. All rights reserved.\n" +
                "\n" +
                "Permission is hereby granted, free of charge, to any person obtaining a copy\n" +
                "of this software and associated documentation files (the 'Software'), to deal\n" +
                "in the Software without restriction, including without limitation the rights\n" +
                "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n" +
                "copies of the Software, and to permit persons to whom the Software is\n" +
                "furnished to do so, subject to the following conditions:\n" +
                "\n" +
                "The above copyright notice and this permission notice shall be included in\n" +
                "all copies or substantial portions of the Software.\n" +
                "\n" +
                "THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n" +
                "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n" +
                "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n" +
                "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n" +
                "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n" +
                "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n" +
                "THE SOFTWARE.\n\n" +
                "*/\n",
        build_dir: "dist",
        //Parser lib copy for versions that can't use requirejs
        parserlib: "node_modules/parserlib/lib/node-parserlib.js",
        //clone copy for versions that can't use requirejs
        clone: "node_modules/clone/clone.js",
        //Core CSSLint files used by most versions
        csslint_files: [
            "src/core/CSSLint.js",
            "src/core/*.js",
            "src/rules/*.js",
            "src/formatters/*.js"
        ],
        //Core fileset used by most versions
        core_files: [
            "<%= parserlib %>",
            "<%= clone %>",
            "<%= csslint_files %>"
        ],
        // Task configuration.
        clean: {
            dist: "<%= build_dir %>"
        },
        changelog: {
            dest: "CHANGELOG"
        },
        concat: {
            core: {
                options: {
                    banner: "<%= banner %>" +
                            //Hack for using the node version of parserlib
                            "var exports = exports || {};\n" +
                            "var CSSLint = (function(){\n",
                    footer: "\nreturn CSSLint;\n})();"
                },
                src: [
                    "<%= core_files %>"
                ],
                dest: "<%= build_dir %>/<%= pkg.name %>.js"
            },//Build environment workers
            rhino: {
                src: [
                    "<%= concat.core.dest %>",
                    "src/cli/common.js",
                    "src/cli/rhino.js"
                ],
                dest: "<%= build_dir %>/<%= pkg.name %>-rhino.js"
            },
            node: {
                options: {
                    banner: "<%= banner %>" +
                            "var clone = require('clone');\n" +
                            "var parserlib = require('parserlib');\n",
                    footer: "\nexports.CSSLint = CSSLint;"
                },
                files: {
                    "<%= build_dir %>/<%= pkg.name %>-node.js": ["<%= csslint_files %>"]
                }
            },
            node_cli: {
                options: {
                    banner: "#!/usr/bin/env node\n<%= banner %>"
                },
                src: [
                    "src/cli/common.js",
                    "src/cli/node.js"
                ],
                dest: "<%= build_dir %>/cli.js"
            },
            tests: {
                src: [
                    "tests/**/*.js",
                    "!tests/all-rules.js"
                ],
                dest: "<%= build_dir %>/<%= pkg.name %>-tests.js"
            },
            worker: {
                options: {
                    banner: "<%= banner %>" +
                            //Hack for using the node version of parserlib
                            "var exports = exports || {};\n"
                },
                src: [
                    "<%= core_files %>",
                    "src/worker/*.js"
                ],
                dest: "<%= build_dir %>/<%= pkg.name %>-worker.js"
            },
            wsh: {
                src: [
                    "<%= concat.core.dest %>",
                    "src/cli/common.js",
                    "src/cli/wsh.js"
                ],
                dest: "<%= build_dir %>/<%= pkg.name %>-wsh.js"
            }
        },
        includereplace: {
            dist: {
                options: {
                    // Global variables available in all files
                    globals: {
                        VERSION: "<%= pkg.version %>"
                    },
                    prefix: "@",
                    suffix: "@"
                },
                files: [{
                    expand: true,
                    cwd: "<%= build_dir %>/",
                    src: "**/*",
                    dest: "<%= build_dir %>/"
                }]
            }
        },
        jshint: {
            options: {
                jshintrc: ".jshintrc"
            },
            gruntfile: {
                src: ["Gruntfile.js", "tasks/*.js"]
            },
            demo: {
                src: "demos/*.js"
            },
            all: {
                src: "src/**/*.js"
            },
            tests: {
                src: "tests/**/*.js"
            }
        },
        watch: {
            gruntfile: {
                files: "<%= jshint.gruntfile.src %>",
                tasks: ["jshint"]
            },
            src: {
                files: "<%= jshint.all.src %>",
                tasks: ["jshint:all"]
            },
            lib_test: {
                files: "<%= jshint.tests.src %>",
                tasks: ["jshint:tests"]
            }
        },
        yuitest: {
            tests: {
                src: [
                    "tests/**/*.js"
                ]
            }
        },
        test_rhino: {
            tests: {
                src: [
                    "<%= concat.tests.dest %>",
                    "tests/all-rules.js"
                ]
            }
        }
    });

    // Load any grunt plugins found in package.json.
    require("load-grunt-tasks")(grunt, {scope: "devDependencies"});
    require("time-grunt")(grunt);

    // Load custom tasks
    grunt.loadTasks("tasks");

    // Default task.
    grunt.registerTask("default", ["build", "test"]);

    grunt.registerTask("build", ["clean", "concat", "includereplace"]);

    //Alias for
    grunt.registerTask("lint", ["jshint"]);

    // Testing
    grunt.registerTask("test", ["build", "jshint", "yuitest"]);
    grunt.registerTask("rhino", ["build", "jshint", "test_rhino"]);

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


<commit_before>/* global module:false */
module.exports = function(grunt) {

   var dep = grunt.file.readJSON('dep.json');
   var dep_files = dep.map(function(el) {
      return '<%= target %>/' + el.file;
   });

   var git_cached = [];

   // Project configuration.
   grunt.initConfig({
      app: grunt.file.readJSON('package.json'),
      meta: {
         banner: grunt.file.read('banner.js')
      },
      target: 'dev',
      jshint: {
         options: {
            jshintrc: '.jshintrc'
         },
         gruntfile: {
            src: 'Gruntfile.js'
         },
         files: ['src/jsxc.lib.*.js']
      },
      copy: {
         main: {
            files: [{
               expand: true,
               src: ['lib/i18next/release/i18next-latest.min.js', 'lib/magnific-popup/dist/*.js', 'lib/favico.js/favico.js', 'lib/emojione/lib/js/*.js', 'lib/emojione/assets/svg/*.svg', 'lib/strophe.js/strophe.js', 'lib/strophe.x/*.js', 'lib/strophe.bookmarks/*.js', 'lib/strophe.vcard/*.js', 'lib/strophe.jinglejs/*-bundle.js', 'lib/otr/build/**', 'lib/otr/lib/dsa-webworker.js', 'lib/otr/lib/sm-webworker.js', 'lib/otr/lib/const.js', 'lib/otr/lib/helpers.js', 'lib/otr/lib/dsa.js', 'lib/otr/vendor/*.js', 'lib/*.js', 'LICENSE', 'img/**', 'sound/**'],
               dest: '<%= target %>/'
            }, {
               expand: true,
               cwd: 'lib/',
               src: ['*.css'],
               dest: '<%= target %>/css/'
            }, {
               expand: true,
               cwd: 'lib/magnific-popup/dist/',
               src: ['*.css'],
               dest: '<%= target %>/css/'
            }]
         }
      },
      clean: ['<%= target %>/'],
      usebanner: {
         dist: {
            options: {
               position: 'top',
               banner: '<%= meta.banner %>'
            },
            files: {
               src: ['<%= target %>/*.js']
            }
         }
      },
      replace: {
         version: {
            src: ['<%= target %>/jsxc.js'],
            overwrite: true,
            replacements: [{
               from: '< $ app.version $ >',
               to: "<%= app.version %>"
            }]
         },
         libraries: {
            src: ['<%= target %>/jsxc.js'],
            overwrite: true,
            replacements: [{
               from: '<$ dep.libraries $>',
               to: function() {
                  var i, d, libraries = '';

                  for (i = 0; i < dep.length; i++) {
                     d = dep[i];
                     if (typeof d.name === 'string') {
                        libraries += '' + d.name + ' (' + d.license + '), ';
                     }
                  }

                  return libraries.replace(/, $/, '');
               }
            }]
         },
         locales: {
            src: ['<%= target %>/lib/translation.js'],
            overwrite: true,
            replacements: [{
               from: /^{/g,
               to: 'var I18next = {'
            }, {
               from: /}$/g,
               to: '};'
            }]
         },
         template: {
            src: ['tmp/template.js'],
            overwrite: true,
            replacements: [{
               from: 'var jsxc.gui.template = {};',
               to: ''
            }]
         },
         imageUrl: {
            src: ['<%= target %>/css/*.css'],
            overwrite: true,
            replacements: [{
               from: /image-url\(["'](.+)["']\)/g,
               to: 'url(\'../img/$1\')'
            }]
         },
         // IE 10 does not like comments starting with @
         todo: {
            src: ['build/jsxc.js'],
            overwrite: true,
            replacements: [{
               from: /\/\/@(.*)/g,
               to: '//$1'
            }]
         }
      },
      merge_data: {
         target: {
            src: ['locales/*.{json,y{,a}ml}'],
            dest: '<%= target %>/lib/translation.js'
         }
      },
      concat: {
         dep: {
            options: {
               banner: '/*!\n' +
                  ' * <%= app.name %> v<%= app.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' +
                  ' * \n' +
                  ' * This file concatenates all dependencies of <%= app.name %>.\n' +
                  ' * \n' +
                  ' */\n\n',
               process: function(src, filepath) {
                  filepath = filepath.replace(/^[a-z]+\//i, '');

                  if (filepath === 'lib/otr/build/dep/crypto.js') {
                     src += ';';
                  }

                  var data = dep[dep_files.indexOf('<%= target %>/' + filepath)];

                  if (data) {
                     return '\n/*!\n * Source: ' + filepath + ', license: ' + data.license + ', url: ' + data.url + '\n */\n' + src;
                  } else {
                     return src;
                  }
               }
            },
            src: dep_files,
            dest: '<%= target %>/lib/jsxc.dep.js'
         },
         jsxc: {
            options: {
               banner: '/*! This file is concatenated for the browser. */\n\n'
            },
            src: ['src/jsxc.intro.js', 'src/jsxc.lib.js', 'src/jsxc.lib.xmpp.js', 'src/jsxc.lib.*.js', 'tmp/template.js', 'src/jsxc.outro.js'],
            dest: '<%= target %>/jsxc.js'
         }
      },
      uglify: {
         jsxc: {
            options: {
               mangle: false,
               sourceMap: true,
               preserveComments: 'some'
            },
            files: {
               '<%= target %>/lib/jsxc.dep.min.js': ['<%= target %>/lib/jsxc.dep.js'],
               '<%= target %>/jsxc.min.js': ['<%= target %>/jsxc.js']
            }
         }
      },
      search: {
         console: {
            files: {
               src: ['src/*.js']
            },
            options: {
               searchString: /console\.log\((?!'[<>]|msg)/g,
               logFormat: 'console',
               failOnMatch: true
            }
         },
         changelog: {
            files: {
               src: ['CHANGELOG.md']
            },
            options: {
               searchString: "<%= app.version %>",
               logFormat: 'console',
               onComplete: function(m) {
                  if (m.numMatches === 0) {
                     grunt.fail.fatal("No entry in CHANGELOG.md for current version found.");
                  }
               }
            }
         }
      },
      compress: {
         main: {
            options: {
               archive: "archives/jsxc-<%= app.version %>.zip"
            },
            files: [{
               src: ['**'],
               expand: true,
               dest: 'jsxc/',
               cwd: 'build/'
            }]
         }
      },
      dataUri: {
        dist: {
            src: '<%= target %>/css/*.css',
            dest: '<%= target %>/css/',
            options: {
               target: ['<%= target %>/img/*.*', '<%= target %>/img/**/*.*'],
               fixDirLevel: false
            }
         }
      },
      qunit: {
        all: {
          options: {
            timeout: 10000,
            urls: [
              'http://localhost:3000/test/bower/bower_spec.html',
              'http://localhost:3000/test/jsxc/jsxc_spec.html'
            ]
          }
        }
      },
      connect: {
        server: {
          options: {
            port: 3000,
            base: '.'
          }
        }
      },
      jsdoc: {
         dist: {
            src: ['src/jsxc.lib.*'],
            dest: 'doc'
         }
      },
      autoprefixer: {
         no_dest: {
            src: '<%= target %>/css/*.css'
         }
      },
      csslint: {
         strict: {
            options: {
               import: 2
            },
            src: ['<%= target %>/css/*.css']
         },
      },
      sass: {
         dist: {
            files: {
               '<%= target %>/css/jsxc.css': 'scss/jsxc.scss',
               '<%= target %>/css/jsxc.webrtc.css': 'scss/jsxc.webrtc.scss'
            }
         }
      },
      watch: {
         locales: {
            files: ['locales/*'],
            tasks: ['merge_data', 'replace:locales', 'concat:dep']
         },
         css: {
            files: ['scss/*'],
            tasks: ['sass', 'autoprefixer', 'replace:imageUrl']
         },
         js: {
            files: ['src/jsxc.lib.*'],
            tasks: ['concat:jsxc']
         },
         template: {
            files: ['template/*.html'],
            tasks: ['htmlConvert', 'replace:template', 'concat:jsxc']
         }
      },
      jsbeautifier: {
         files: ['Gruntfile.js', 'src/jsxc.lib.*', 'template/*.html', 'example/*.html', 'example/js/dev.js', 'example/js/example.js', 'example/css/example.css'],
         options: {
            config: '.jsbeautifyrc'
         }
      },
      prettysass: {
         options: {
            alphabetize: false,
            indent: 4
         },
         jsxc: {
            src: ['scss/*.scss']
         }
      },
      htmlConvert: {
         options: {
            target: 'js',
            rename: function(name) {
               return name.match(/([-_0-9a-z]+)\.html$/i)[1];
            },
            quoteChar: '\'',
            indentString: '',
            indentGlobal: ''
         },
         'jsxc.gui.template': {
            src: 'template/*.html',
            dest: 'tmp/template.js'
         }
      },
      shell: {
         'precommit-before': {
            command: 'git diff --cached --name-only',
            options: {
               callback: function(err, stdout, stderr, cb) {
                  git_cached = stdout.trim().split(/\n/);

                  cb();
               }
            }
         },
         'precommit-after': {
            command: 'git diff --name-only',
            options: {
               callback: function(err, stdout, stderr, cb) {
                  var git_diff = stdout.trim().split(/\n/);
                  var intersection = [];
                  var i;

                  for (i = 0; i < git_diff.length; i++) {
                     if (git_cached.indexOf(git_diff[i]) >= 0) {
                        intersection.push(git_diff[i]);
                     }
                  }

                  if (intersection.length > 0) {
                     grunt.log.writeln();

                     for (i = 0; i < intersection.length; i++) {
                        grunt.log.writeln('> ' + intersection[i]);
                     }

                     grunt.fail.warn('Some files changed during pre-commit hook!');
                  }

                  cb();
               }
            }
         }
      }
   });

   // These plugins provide necessary tasks.
   grunt.loadNpmTasks('grunt-contrib-jshint');
   grunt.loadNpmTasks('grunt-contrib-copy');
   grunt.loadNpmTasks('grunt-contrib-clean');
   grunt.loadNpmTasks('grunt-contrib-concat');
   grunt.loadNpmTasks('grunt-contrib-uglify');
   grunt.loadNpmTasks('grunt-banner');
   grunt.loadNpmTasks('grunt-text-replace');
   grunt.loadNpmTasks('grunt-search');
   grunt.loadNpmTasks('grunt-contrib-compress');
   grunt.loadNpmTasks('grunt-jsdoc');
   grunt.loadNpmTasks('grunt-data-uri');
   grunt.loadNpmTasks('grunt-contrib-qunit');
   grunt.loadNpmTasks('grunt-contrib-connect');
   grunt.loadNpmTasks('grunt-merge-data');
   grunt.loadNpmTasks('grunt-contrib-csslint');
   grunt.loadNpmTasks('grunt-sass');
   grunt.loadNpmTasks('grunt-autoprefixer');
   grunt.loadNpmTasks('grunt-contrib-watch');
   grunt.loadNpmTasks('grunt-jsbeautifier');
   grunt.loadNpmTasks('grunt-prettysass');
   grunt.loadNpmTasks('grunt-html-convert');
   grunt.loadNpmTasks('grunt-shell');

   //Default task
   grunt.registerTask('default', ['build', 'watch']);

   grunt.registerTask('build', ['jshint', 'clean', 'sass', 'replace:imageUrl', 'autoprefixer', 'copy', 'merge_data', 'replace:locales', 'htmlConvert', 'replace:template', 'concat']);

   grunt.registerTask('build:prerelease', 'Build a new pre-release', function() {
      grunt.config.set('target', 'build');

      grunt.task.run(['search:console', 'build', 'usebanner', 'replace:version', 'replace:libraries', 'replace:todo', 'uglify', 'compress']);
   });

   grunt.registerTask('build:release', 'Build a new release', function() {
      grunt.config.set('target', 'build');

      grunt.task.run(['search:changelog', 'build:prerelease', 'jsdoc']);
   });

   // Create alpha/beta build @deprecated
   grunt.registerTask('pre', ['build:prerelease']);

   // before commit
   grunt.registerTask('commit', ['shell:precommit-before', 'search:console', 'jsbeautifier', 'prettysass', 'jshint', 'shell:precommit-after']);
};
<commit_msg>Fix jshint path-no-string-error with v0.9.2<commit_after>/* global module:false */
module.exports = function(grunt) {

   var dep = grunt.file.readJSON('dep.json');
   var dep_files = dep.map(function(el) {
      return '<%= target %>/' + el.file;
   });

   var git_cached = [];

   // Project configuration.
   grunt.initConfig({
      app: grunt.file.readJSON('package.json'),
      meta: {
         banner: grunt.file.read('banner.js')
      },
      target: 'dev',
      jshint: {
         options: {
            reporterOutput: "",
            jshintrc: '.jshintrc'
         },
         gruntfile: {
            src: 'Gruntfile.js'
         },
         files: ['src/jsxc.lib.*.js']
      },
      copy: {
         main: {
            files: [{
               expand: true,
               src: ['lib/i18next/release/i18next-latest.min.js', 'lib/magnific-popup/dist/*.js', 'lib/favico.js/favico.js', 'lib/emojione/lib/js/*.js', 'lib/emojione/assets/svg/*.svg', 'lib/strophe.js/strophe.js', 'lib/strophe.x/*.js', 'lib/strophe.bookmarks/*.js', 'lib/strophe.vcard/*.js', 'lib/strophe.jinglejs/*-bundle.js', 'lib/otr/build/**', 'lib/otr/lib/dsa-webworker.js', 'lib/otr/lib/sm-webworker.js', 'lib/otr/lib/const.js', 'lib/otr/lib/helpers.js', 'lib/otr/lib/dsa.js', 'lib/otr/vendor/*.js', 'lib/*.js', 'LICENSE', 'img/**', 'sound/**'],
               dest: '<%= target %>/'
            }, {
               expand: true,
               cwd: 'lib/',
               src: ['*.css'],
               dest: '<%= target %>/css/'
            }, {
               expand: true,
               cwd: 'lib/magnific-popup/dist/',
               src: ['*.css'],
               dest: '<%= target %>/css/'
            }]
         }
      },
      clean: ['<%= target %>/'],
      usebanner: {
         dist: {
            options: {
               position: 'top',
               banner: '<%= meta.banner %>'
            },
            files: {
               src: ['<%= target %>/*.js']
            }
         }
      },
      replace: {
         version: {
            src: ['<%= target %>/jsxc.js'],
            overwrite: true,
            replacements: [{
               from: '< $ app.version $ >',
               to: "<%= app.version %>"
            }]
         },
         libraries: {
            src: ['<%= target %>/jsxc.js'],
            overwrite: true,
            replacements: [{
               from: '<$ dep.libraries $>',
               to: function() {
                  var i, d, libraries = '';

                  for (i = 0; i < dep.length; i++) {
                     d = dep[i];
                     if (typeof d.name === 'string') {
                        libraries += '' + d.name + ' (' + d.license + '), ';
                     }
                  }

                  return libraries.replace(/, $/, '');
               }
            }]
         },
         locales: {
            src: ['<%= target %>/lib/translation.js'],
            overwrite: true,
            replacements: [{
               from: /^{/g,
               to: 'var I18next = {'
            }, {
               from: /}$/g,
               to: '};'
            }]
         },
         template: {
            src: ['tmp/template.js'],
            overwrite: true,
            replacements: [{
               from: 'var jsxc.gui.template = {};',
               to: ''
            }]
         },
         imageUrl: {
            src: ['<%= target %>/css/*.css'],
            overwrite: true,
            replacements: [{
               from: /image-url\(["'](.+)["']\)/g,
               to: 'url(\'../img/$1\')'
            }]
         },
         // IE 10 does not like comments starting with @
         todo: {
            src: ['build/jsxc.js'],
            overwrite: true,
            replacements: [{
               from: /\/\/@(.*)/g,
               to: '//$1'
            }]
         }
      },
      merge_data: {
         target: {
            src: ['locales/*.{json,y{,a}ml}'],
            dest: '<%= target %>/lib/translation.js'
         }
      },
      concat: {
         dep: {
            options: {
               banner: '/*!\n' +
                  ' * <%= app.name %> v<%= app.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' +
                  ' * \n' +
                  ' * This file concatenates all dependencies of <%= app.name %>.\n' +
                  ' * \n' +
                  ' */\n\n',
               process: function(src, filepath) {
                  filepath = filepath.replace(/^[a-z]+\//i, '');

                  if (filepath === 'lib/otr/build/dep/crypto.js') {
                     src += ';';
                  }

                  var data = dep[dep_files.indexOf('<%= target %>/' + filepath)];

                  if (data) {
                     return '\n/*!\n * Source: ' + filepath + ', license: ' + data.license + ', url: ' + data.url + '\n */\n' + src;
                  } else {
                     return src;
                  }
               }
            },
            src: dep_files,
            dest: '<%= target %>/lib/jsxc.dep.js'
         },
         jsxc: {
            options: {
               banner: '/*! This file is concatenated for the browser. */\n\n'
            },
            src: ['src/jsxc.intro.js', 'src/jsxc.lib.js', 'src/jsxc.lib.xmpp.js', 'src/jsxc.lib.*.js', 'tmp/template.js', 'src/jsxc.outro.js'],
            dest: '<%= target %>/jsxc.js'
         }
      },
      uglify: {
         jsxc: {
            options: {
               mangle: false,
               sourceMap: true,
               preserveComments: 'some'
            },
            files: {
               '<%= target %>/lib/jsxc.dep.min.js': ['<%= target %>/lib/jsxc.dep.js'],
               '<%= target %>/jsxc.min.js': ['<%= target %>/jsxc.js']
            }
         }
      },
      search: {
         console: {
            files: {
               src: ['src/*.js']
            },
            options: {
               searchString: /console\.log\((?!'[<>]|msg)/g,
               logFormat: 'console',
               failOnMatch: true
            }
         },
         changelog: {
            files: {
               src: ['CHANGELOG.md']
            },
            options: {
               searchString: "<%= app.version %>",
               logFormat: 'console',
               onComplete: function(m) {
                  if (m.numMatches === 0) {
                     grunt.fail.fatal("No entry in CHANGELOG.md for current version found.");
                  }
               }
            }
         }
      },
      compress: {
         main: {
            options: {
               archive: "archives/jsxc-<%= app.version %>.zip"
            },
            files: [{
               src: ['**'],
               expand: true,
               dest: 'jsxc/',
               cwd: 'build/'
            }]
         }
      },
      dataUri: {
        dist: {
            src: '<%= target %>/css/*.css',
            dest: '<%= target %>/css/',
            options: {
               target: ['<%= target %>/img/*.*', '<%= target %>/img/**/*.*'],
               fixDirLevel: false
            }
         }
      },
      qunit: {
        all: {
          options: {
            timeout: 10000,
            urls: [
              'http://localhost:3000/test/bower/bower_spec.html',
              'http://localhost:3000/test/jsxc/jsxc_spec.html'
            ]
          }
        }
      },
      connect: {
        server: {
          options: {
            port: 3000,
            base: '.'
          }
        }
      },
      jsdoc: {
         dist: {
            src: ['src/jsxc.lib.*'],
            dest: 'doc'
         }
      },
      autoprefixer: {
         no_dest: {
            src: '<%= target %>/css/*.css'
         }
      },
      csslint: {
         strict: {
            options: {
               import: 2
            },
            src: ['<%= target %>/css/*.css']
         },
      },
      sass: {
         dist: {
            files: {
               '<%= target %>/css/jsxc.css': 'scss/jsxc.scss',
               '<%= target %>/css/jsxc.webrtc.css': 'scss/jsxc.webrtc.scss'
            }
         }
      },
      watch: {
         locales: {
            files: ['locales/*'],
            tasks: ['merge_data', 'replace:locales', 'concat:dep']
         },
         css: {
            files: ['scss/*'],
            tasks: ['sass', 'autoprefixer', 'replace:imageUrl']
         },
         js: {
            files: ['src/jsxc.lib.*'],
            tasks: ['concat:jsxc']
         },
         template: {
            files: ['template/*.html'],
            tasks: ['htmlConvert', 'replace:template', 'concat:jsxc']
         }
      },
      jsbeautifier: {
         files: ['Gruntfile.js', 'src/jsxc.lib.*', 'template/*.html', 'example/*.html', 'example/js/dev.js', 'example/js/example.js', 'example/css/example.css'],
         options: {
            config: '.jsbeautifyrc'
         }
      },
      prettysass: {
         options: {
            alphabetize: false,
            indent: 4
         },
         jsxc: {
            src: ['scss/*.scss']
         }
      },
      htmlConvert: {
         options: {
            target: 'js',
            rename: function(name) {
               return name.match(/([-_0-9a-z]+)\.html$/i)[1];
            },
            quoteChar: '\'',
            indentString: '',
            indentGlobal: ''
         },
         'jsxc.gui.template': {
            src: 'template/*.html',
            dest: 'tmp/template.js'
         }
      },
      shell: {
         'precommit-before': {
            command: 'git diff --cached --name-only',
            options: {
               callback: function(err, stdout, stderr, cb) {
                  git_cached = stdout.trim().split(/\n/);

                  cb();
               }
            }
         },
         'precommit-after': {
            command: 'git diff --name-only',
            options: {
               callback: function(err, stdout, stderr, cb) {
                  var git_diff = stdout.trim().split(/\n/);
                  var intersection = [];
                  var i;

                  for (i = 0; i < git_diff.length; i++) {
                     if (git_cached.indexOf(git_diff[i]) >= 0) {
                        intersection.push(git_diff[i]);
                     }
                  }

                  if (intersection.length > 0) {
                     grunt.log.writeln();

                     for (i = 0; i < intersection.length; i++) {
                        grunt.log.writeln('> ' + intersection[i]);
                     }

                     grunt.fail.warn('Some files changed during pre-commit hook!');
                  }

                  cb();
               }
            }
         }
      }
   });

   // These plugins provide necessary tasks.
   grunt.loadNpmTasks('grunt-contrib-jshint');
   grunt.loadNpmTasks('grunt-contrib-copy');
   grunt.loadNpmTasks('grunt-contrib-clean');
   grunt.loadNpmTasks('grunt-contrib-concat');
   grunt.loadNpmTasks('grunt-contrib-uglify');
   grunt.loadNpmTasks('grunt-banner');
   grunt.loadNpmTasks('grunt-text-replace');
   grunt.loadNpmTasks('grunt-search');
   grunt.loadNpmTasks('grunt-contrib-compress');
   grunt.loadNpmTasks('grunt-jsdoc');
   grunt.loadNpmTasks('grunt-data-uri');
   grunt.loadNpmTasks('grunt-contrib-qunit');
   grunt.loadNpmTasks('grunt-contrib-connect');
   grunt.loadNpmTasks('grunt-merge-data');
   grunt.loadNpmTasks('grunt-contrib-csslint');
   grunt.loadNpmTasks('grunt-sass');
   grunt.loadNpmTasks('grunt-autoprefixer');
   grunt.loadNpmTasks('grunt-contrib-watch');
   grunt.loadNpmTasks('grunt-jsbeautifier');
   grunt.loadNpmTasks('grunt-prettysass');
   grunt.loadNpmTasks('grunt-html-convert');
   grunt.loadNpmTasks('grunt-shell');

   //Default task
   grunt.registerTask('default', ['build', 'watch']);

   grunt.registerTask('build', ['jshint', 'clean', 'sass', 'replace:imageUrl', 'autoprefixer', 'copy', 'merge_data', 'replace:locales', 'htmlConvert', 'replace:template', 'concat']);

   grunt.registerTask('build:prerelease', 'Build a new pre-release', function() {
      grunt.config.set('target', 'build');

      grunt.task.run(['search:console', 'build', 'usebanner', 'replace:version', 'replace:libraries', 'replace:todo', 'uglify', 'compress']);
   });

   grunt.registerTask('build:release', 'Build a new release', function() {
      grunt.config.set('target', 'build');

      grunt.task.run(['search:changelog', 'build:prerelease', 'jsdoc']);
   });

   // Create alpha/beta build @deprecated
   grunt.registerTask('pre', ['build:prerelease']);

   // before commit
   grunt.registerTask('commit', ['shell:precommit-before', 'search:console', 'jsbeautifier', 'prettysass', 'jshint', 'shell:precommit-after']);
};
<|endoftext|>


<commit_before>'use strict';

require('../scss/main.scss');
require('whatwg-fetch');

const {firstscan, apiurl} = require('./config'),
      DateRangePicker = require('react-dates').DateRangePicker,
      LineTooltip = require('react-d3-tooltip').LineTooltip,
      React = require('react'),
      ReactDOM = require('react-dom'),
      moment = require('moment');

(() => {
  const tomorrow = moment().add(1, 'day').endOf('day'),
        firstScan = moment(firstscan).startOf('day');

  class Content extends React.Component{
    constructor() {
      super();
      const today = moment().startOf('day'),
            tomorrow = moment(today).add(1, 'day');
      this.state = {
        startDate: today,
        endDate: tomorrow,
        range: 'day',
        focusedInput: null,
        chartData:  [{}]
      };
      this.fetchData(today, tomorrow);
      this.fetchData = this.fetchData.bind(this);
      this.previous = this.previous.bind(this);
      this.next = this.next.bind(this);
      this.timespan = this.timespan.bind(this);
      this.onDatesChange = this.onDatesChange.bind(this);
      this.onFocusChange = this.onFocusChange.bind(this);
      this.isOutsideRange = this.isOutsideRange.bind(this);
      this.initialVisibleMonth = this.initialVisibleMonth.bind(this);
    }
    // Called to get data from the API to update the chart
    fetchData(sentStart, sentEnd) {
      const start = sentStart.format('YYYYMMDD'),
            end = sentEnd.format('YYYYMMDD');
      fetch(`http://${apiurl}/api/range/${start}/${end}`)
        .then((res) => res.json())
        .then((json) => {
          this.setState({
            chartData: json
          });
        }).catch((err) => {
          throw err;
        })
    }
    // Called to decrement the start and end dates by the current range
    previous() {
      const start = moment(this.state.startDate).subtract(1, this.state.range),
            end = moment(this.state.startDate);
      this.setState({
        startDate: start,
        endDate: end
      }, this.fetchData(start, end));
    }
    // Called to increment the start and end dates by the current range
    next() {
      const start = moment(this.state.startDate).add(1, this.state.range),
            end = moment(this.state.startDate).add(2, this.state.range);
      this.setState({
        startDate: start,
        endDate: end,
      }, this.fetchData(start, end));
    }
    // Called to change the current range (day, week, month, year)
    timespan(e) {
      const range = e.target.value,
            end = moment(this.state.startDate).add(1, range);
      this.setState({
        range: range,
        endDate: end
      }, this.fetchData(this.state.startDate, end));
    }
    // Called by date picker upon changing dates to set dates in state
    onDatesChange(datesObj) {
      if (datesObj.startDate) {
        this.setState({
          startDate: datesObj.startDate
        });
      }
      if (datesObj.endDate) {
        this.setState({
          endDate: datesObj.endDate.startOf('day')
        });
      }
      if (datesObj.startDate && datesObj.endDate) {
        const start = datesObj.startDate,
              end = datesObj.endDate.startOf('day');
        this.setState({
          startDate: start,
          endDate: end
        }, this.fetchData(start, end));
      }
    }
    // Called by date picker when focus changes to/from inputs
    onFocusChange(focused) {
      this.setState({
        focusedInput: focused
      })
    }
    // Disables dates in the callendar that fall in the future
    // or before data collection started
    isOutsideRange(date) {
      return (date.isAfter(tomorrow) || date.isBefore(firstScan));
    }
    // Sets the start month to the previous month
    initialVisibleMonth() {
      return moment().subtract(1, 'month');
    }
    render() {
      // React D3 configuration settings
      const margins = {
              top: 20,
              right: 50,
              bottom: 20,
              left: 50
            },
            chartSeries = [
              {
                field: 'ping',
                name: 'Ping (ms)',
                color: 'orange'
              },
              {
                field: 'upload',
                name: 'Upload (Mbit/s)',
                color: 'green'
              },
              {
                field: 'download',
                name: 'Download (Mbit/s)',
                color: 'red'
              }
            ],
            height = window.innerHeight - 160,
            width = window.innerWidth - 10,
            x = data => moment(data.scantime).toDate(),
            xScale = 'time';
      return(

          <Controls
            startDate={this.state.startDate}
            endDate={this.state.endDate}
            range={this.state.range}
            focusedInput={this.state.focusedInput}
            timespan={this.timespan}
            previous={this.previous}
            next={this.next}
            onFocusChange={this.onFocusChange}
            onDatesChange={this.onDatesChange}
            isOutsideRange={this.isOutsideRange}
            initialVisibleMonth={this.initialVisibleMonth}
          />

            <LineTooltip
              margins={margins}
              data={this.state.chartData}
              width={width}
              height={height}
              chartSeries={chartSeries}
              x={x}
              xScale={xScale}
            />

            Ryan Tanay {moment().format('YYYY')} - source

      )
    }
  };

  const Controls = ({
    startDate,
    endDate,
    range,
    focusedInput,
    timespan,
    previous,
    next,
    onFocusChange,
    onDatesChange,
    isOutsideRange,
    initialVisibleMonth
  }) => {
    const spans = ['Day', 'Week', 'Month', 'Year'],
          spanButtons = spans.map(name =>
            <SpanButton key={name}
                        name={name}
                        range={range}
                        timespan={timespan} />
          );
    return(

        <button
          className={'nav-button'}
          disabled={startDate.isSameOrBefore(firstScan, 'day')}
          onClick={() => previous()}
        >«</button>

            {spanButtons}

            <DateRangePicker
              startDate={startDate}
              endDate={endDate}
              focusedInput={focusedInput}
              onFocusChange={onFocusChange}
              onDatesChange={onDatesChange}
              isOutsideRange={isOutsideRange}
              initialVisibleMonth={initialVisibleMonth}
            />

        <button
          className={'nav-button'}
          disabled={endDate.isSameOrAfter(tomorrow, 'day')}
          onClick={() => next()}
        >»</button>

    )
  }

  const SpanButton = ({name, range, timespan}) => {
    const active = name.toLowerCase() == range;
    return(
      <button
        className={`range-button ${active ? 'active' : ''}`}
        disabled={active}
        onClick={e => timespan(e)}
        value={name.toLowerCase()}
      >{name}</button>
    )
  }

  ReactDOM.render(<Content />, document.getElementById('app'));
})()
<commit_msg>Formatting components<commit_after>'use strict';

require('../scss/main.scss');
require('whatwg-fetch');

const {firstscan, apiurl} = require('./config'),
      DateRangePicker = require('react-dates').DateRangePicker,
      LineTooltip = require('react-d3-tooltip').LineTooltip,
      React = require('react'),
      ReactDOM = require('react-dom'),
      moment = require('moment');

(() => {
  const tomorrow = moment().add(1, 'day').endOf('day'),
        firstScan = moment(firstscan).startOf('day');

  class Content extends React.Component{
    constructor() {
      super();
      const today = moment().startOf('day'),
            tomorrow = moment(today).add(1, 'day');
      this.state = {
        startDate: today,
        endDate: tomorrow,
        range: 'day',
        focusedInput: null,
        chartData:  [{}]
      };
      this.fetchData(today, tomorrow);
      this.fetchData = this.fetchData.bind(this);
      this.previous = this.previous.bind(this);
      this.next = this.next.bind(this);
      this.timespan = this.timespan.bind(this);
      this.onDatesChange = this.onDatesChange.bind(this);
      this.onFocusChange = this.onFocusChange.bind(this);
      this.isOutsideRange = this.isOutsideRange.bind(this);
      this.initialVisibleMonth = this.initialVisibleMonth.bind(this);
    }
    // Called to get data from the API to update the chart
    fetchData(sentStart, sentEnd) {
      const start = sentStart.format('YYYYMMDD'),
            end = sentEnd.format('YYYYMMDD');
      fetch(`http://${apiurl}/api/range/${start}/${end}`)
        .then((res) => res.json())
        .then((json) => {
          this.setState({
            chartData: json
          });
        }).catch((err) => {
          throw err;
        })
    }
    // Called to decrement the start and end dates by the current range
    previous() {
      const start = moment(this.state.startDate).subtract(1, this.state.range),
            end = moment(this.state.startDate);
      this.setState({
        startDate: start,
        endDate: end
      }, this.fetchData(start, end));
    }
    // Called to increment the start and end dates by the current range
    next() {
      const start = moment(this.state.startDate).add(1, this.state.range),
            end = moment(this.state.startDate).add(2, this.state.range);
      this.setState({
        startDate: start,
        endDate: end,
      }, this.fetchData(start, end));
    }
    // Called to change the current range (day, week, month, year)
    timespan(e) {
      const range = e.target.value,
            end = moment(this.state.startDate).add(1, range);
      this.setState({
        range: range,
        endDate: end
      }, this.fetchData(this.state.startDate, end));
    }
    // Called by date picker upon changing dates to set dates in state
    onDatesChange(datesObj) {
      if (datesObj.startDate) {
        this.setState({
          startDate: datesObj.startDate
        });
      }
      if (datesObj.endDate) {
        this.setState({
          endDate: datesObj.endDate.startOf('day')
        });
      }
      if (datesObj.startDate && datesObj.endDate) {
        const start = datesObj.startDate,
              end = datesObj.endDate.startOf('day');
        this.setState({
          startDate: start,
          endDate: end
        }, this.fetchData(start, end));
      }
    }
    // Called by date picker when focus changes to/from inputs
    onFocusChange(focused) {
      this.setState({
        focusedInput: focused
      })
    }
    // Disables dates in the callendar that fall in the future
    // or before data collection started
    isOutsideRange(date) {
      return (date.isAfter(tomorrow) || date.isBefore(firstScan));
    }
    // Sets the start month to the previous month
    initialVisibleMonth() {
      return moment().subtract(1, 'month');
    }
    render() {
      // React D3 configuration settings
      const margins = {
              top: 20,
              right: 50,
              bottom: 20,
              left: 50
            },
            chartSeries = [
              {
                field: 'ping',
                name: 'Ping (ms)',
                color: 'orange'
              },
              {
                field: 'upload',
                name: 'Upload (Mbit/s)',
                color: 'green'
              },
              {
                field: 'download',
                name: 'Download (Mbit/s)',
                color: 'red'
              }
            ],
            height = window.innerHeight - 160,
            width = window.innerWidth - 10,
            x = data => moment(data.scantime).toDate(),
            xScale = 'time';
      return(

          <Controls startDate={this.state.startDate}
                    endDate={this.state.endDate}
                    range={this.state.range}
                    focusedInput={this.state.focusedInput}
                    timespan={this.timespan}
                    previous={this.previous}
                    next={this.next}
                    onFocusChange={this.onFocusChange}
                    onDatesChange={this.onDatesChange}
                    isOutsideRange={this.isOutsideRange}
                    initialVisibleMonth={this.initialVisibleMonth} />

            <LineTooltip margins={margins}
                         data={this.state.chartData}
                         width={width}
                         height={height}
                         chartSeries={chartSeries}
                         x={x}
                         xScale={xScale} />

            Ryan Tanay {moment().format('YYYY')} - source

      )
    }
  };

  const Controls = ({
    startDate,
    endDate,
    range,
    focusedInput,
    timespan,
    previous,
    next,
    onFocusChange,
    onDatesChange,
    isOutsideRange,
    initialVisibleMonth
  }) => {
    const spans = ['Day', 'Week', 'Month', 'Year'],
          spanButtons = spans.map(name =>
            <SpanButton key={name}
                        name={name}
                        range={range}
                        timespan={timespan} />
          );
    return(

        <button className={'nav-button'}
                disabled={startDate.isSameOrBefore(firstScan, 'day')}
                onClick={() => previous()}>«</button>

            {spanButtons}

            <DateRangePicker startDate={startDate}
                             endDate={endDate}
                             focusedInput={focusedInput}
                             onFocusChange={onFocusChange}
                             onDatesChange={onDatesChange}
                             isOutsideRange={isOutsideRange}
                             initialVisibleMonth={initialVisibleMonth} />

        <button className={'nav-button'}
                disabled={endDate.isSameOrAfter(tomorrow, 'day')}
                onClick={() => next()}>»</button>

    )
  }

  const SpanButton = ({name, range, timespan}) => {
    const active = name.toLowerCase() == range;
    return(
      <button className={`range-button ${active ? 'active' : ''}`}
              disabled={active}
              onClick={e => timespan(e)}
              value={name.toLowerCase()}>{name}</button>
    )
  }

  ReactDOM.render(<Content />, document.getElementById('app'));
})()
<|endoftext|>


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

        concat: {
            dist: {
                src: [
                    'vendor/jquery-1.11.0.min.js',
                    'vendor/jquery.color.js',
                    'vendor/leaflet.js',
                    'js/maps.js',
                    'js/djangopeople.js',
                ],
                dest: 'djangopeople/djangopeople/static/djangopeople/js/djangopeople.js',
            },
        },

        uglify: {
            build: {
                src: 'djangopeople/djangopeople/static/djangopeople/js/djangopeople.js',
                dest: 'djangopeople/djangopeople/static/djangopeople/js/djangopeople.min.js',
            },
        },

        watch: {
            scripts: {
                files: [
                    'Gruntfile.js',
                    'js/**/*.js',
                ],
                tasks: ['concat'],
                options: {
                    spawn: false,
                },
            },
        },
    });

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

    grunt.registerTask('default', ['concat', 'uglify']);
};
<commit_msg>Add missing vendor dir<commit_after>module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        concat: {
            dist: {
                src: [
                    'vendor/jquery-1.11.0.min.js',
                    'vendor/jquery.color.js',
                    'vendor/leaflet.js',
                    'js/maps.js',
                    'js/djangopeople.js',
                ],
                dest: 'djangopeople/djangopeople/static/djangopeople/js/djangopeople.js',
            },
        },

        uglify: {
            build: {
                src: 'djangopeople/djangopeople/static/djangopeople/js/djangopeople.js',
                dest: 'djangopeople/djangopeople/static/djangopeople/js/djangopeople.min.js',
            },
        },

        watch: {
            scripts: {
                files: [
                    'Gruntfile.js',
                    'js/**/*.js',
                    'vendor/**/*.js',
                ],
                tasks: ['concat'],
                options: {
                    spawn: false,
                },
            },
        },
    });

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

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


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

  var helpers = require('./.grunt/helpers')(grunt);
  var clone = grunt.util._.clone;

  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-coffee');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.loadNpmTasks('grunt-mocha');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-hull-dox');
  grunt.loadNpmTasks('grunt-hull-widgets');
  grunt.loadNpmTasks('grunt-s3');
  grunt.loadNpmTasks('grunt-git-describe');
  grunt.loadNpmTasks('grunt-coverjs');
  grunt.loadNpmTasks('grunt-plato');
  grunt.loadNpmTasks('grunt-wrap');

  var pkg = grunt.file.readJSON('bower.json');
  var clientConfig = grunt.file.readJSON('.grunt/client.json');
  var remoteConfig = grunt.file.readJSON('.grunt/remote.json');
  var apiConfig = grunt.file.readJSON('.grunt/api.json');

  var port = 3001;

  // ==========================================================================
  // Project configuration
  // ==========================================================================

  // Lookup of the available libs and injects them for the build
  // in the requirejs conf
  var clientLibs = helpers.getBuiltFilenames('src/client/**/*.coffee');
  var remoteLibs = helpers.getBuiltFilenames('src/remote/**/*.coffee');

  // Lookup of the Aura Extensions and injects them in the requirejs build
  var auraExtensions = grunt.file.glob
    .sync('aura-extensions/**/*.js')
    .map(function (extension) {
      return extension.replace('.js', '');
    });

  //Augment the require.js configuation with some computed elements
  var apiRJSConfig = (function () {
    var _c = apiConfig.requireJS;
    _c.optimize = grunt.option('dev') ? "none" : "uglify";
    return _c;
  })();
  var clientRJSConfig = (function () {
    var _c = clientConfig.requireJS;
    _c.include = _c.include.concat(auraExtensions).concat(clientLibs);
    _c.optimize = grunt.option('dev') ? "none" : "uglify";
    return _c;
  })();

  var remoteRJSConfig = (function () {
    var _c = remoteConfig.requireJS;
    _c.include = _c.include.concat(remoteLibs);
    _c.optimize = grunt.option('dev') ? "none" : "uglify";
    return _c;
  })();

  var gruntConfig = {
    PKG_VERSION: pkg.version,
    clean: {
      client: {
        src: 'lib/client/**/*'
      },
      remote: {
        src: 'lib/remote/**/*'
      },
      reset: {
        src: ['build', 'lib', 'tmp', 'dist', 'components', 'node_modules']
      }
    },
    dox: {
      files: {
        baseDir: 'widgets',
        src: 'widgets/**/main.js',
        dest: 'dist/<%= PKG_VERSION %>/docs'
      }
    },
    coffee: {
      compile: {
        options: {
          header: true
        }
      },
      remote: {
        files: grunt.file.expandMapping(remoteConfig.srcFiles, 'lib/', {
          rename: function (destBase, destPath) {
            return destBase + destPath.replace(/\.coffee$/, '.js').replace(/^src\//, "");
          }
        })
      },
      client: {
        files: grunt.file.expandMapping(clientConfig.srcFiles, 'lib/', {
          rename: function (destBase, destPath) {
            return destBase + destPath.replace(/\.coffee$/, '.js').replace(/^src\//, "");
          }
        })
      },
      api: {
        files: grunt.file.expandMapping(apiConfig.srcFiles, 'lib/', {
          rename: function (destBase, destPath) {
            return destBase + destPath.replace(/\.coffee$/, '.js').replace(/^src\//, "");
          }
        })
      }
    },
    connect: {
      server: {
        options: {
          port: port
        }
      }
    },
    requirejs: {
      "client-no-backbone": {
        options: (function (c) {
          c.paths.underscore = 'empty:';
          c.paths.backbone = 'empty:';
          c.out = c.out.replace('hull.js', 'hull.no-backbone.js');
          c.wrap.start = c.wrap.start + ";root._ = window._;";
          c.wrap.start = c.wrap.start + ";root.Backbone = window.Backbone;";
          return c;
        })(clone(clientRJSConfig, true))
      },
      "client-no-underscore": {
        options: (function (c) {
          c.paths.underscore = 'empty:';
          c.out = c.out.replace('hull.js', 'hull.no-underscore.js');
          c.wrap.start = c.wrap.start + ";root._ = window._;";
          return c;
        })(clone(clientRJSConfig, true))
      },
      api: {
        options: clone(apiRJSConfig, true)
      },
      client: {
        options: clone(clientRJSConfig, true)
      },
      remote: {
        options: clone(remoteRJSConfig, true)
      },
      upload: {
        options: {
          namespace: 'Hull',
          paths: {
            jquery: "empty:",
            "jquery.ui.widget" : 'components/jquery-file-upload/js/vendor/jquery.ui.widget',
            "jquery.fileupload" : 'components/jquery-file-upload/js/jquery.fileupload'
          },
          include: [
            'jquery.fileupload'
          ],
          out: 'tmp/widgets/upload/deps/jquery.fileupload.js'
        }
      },
      registration: {
        options: {
          namespace: 'Hull',
          paths: { h5f: 'widgets/registration/h5f' },
          shim: { h5f: { exports: 'H5F' } },
          include: ['h5f'],
          out: 'tmp/widgets/registration/deps.js'
        }
      },
      dox: {
        options: {
          namespace: 'Hull',
          paths: { prism: 'widgets/dox/dox/prism' },
          shim: { prism: { exports: 'Prism' } },
          include: ['prism'],
          out: 'tmp/widgets/dox/dox/deps.js'
        }
      }
    },
    mocha: {
      hull: {
        src: ["spec/index.html"]
      }
    },
    watch: {
      widgets: {
        files: ['widgets/**/*'],
        tasks: ['hull_widgets']
      },
      remote: {
        files: remoteConfig.srcFiles,
        tasks: ['dist:remote', 'do_test']
      },
      api: {
        files: apiConfig.srcFiles,
        tasks: ['dist:api', 'do_test']
      },
      client: {
        files: clientConfig.srcFiles,
        tasks: ['dist:client', 'do_test']
      },
      spec: {
        files: ['spec/**/*.js'],
        tasks: ['mocha']
      }
    },
    version: {
      template: "define(function () { return '<%= PKG_VERSION %>';});",
      dest: 'lib/utils/version.js'
    },
    hull_widgets: {
      hull: {
        src: 'widgets',
        before: ['requirejs:upload', 'requirejs:registration', 'requirejs:dox'],
        dest: 'dist/<%= PKG_VERSION%>',
        optimize: !grunt.option('dev')
      }
    },
    describe: {
      out: 'dist/<%= PKG_VERSION%>/REVISION'
    },
    wrap: {
      Handlebars: {
        src: 'node_modules/grunt-contrib-handlebars/node_modules/handlebars/dist/handlebars.js',
        dest: 'lib/shims',
        wrapper: [
          '(function () {', ';define("handlebars", function () {return Handlebars;});})()'
        ]
      },
      easyXDM: {
        src: 'components/easyXDM/easyXDM.js',
        dest: 'lib/shims',
        wrapper: [
          '', ';var _available = window.easyXDM;define("easyXDM", function () {return window.easyXDM.noConflict();});if(!_available){delete window.easyXDM;};'
        ]
      }
    },
    cover: {
      compile: {
        files: {
          'build/instrumented/*.js' : ['lib/**/*.js']
        },
        options: {
          basePath: 'lib'
        }
      }
    },
    plato: {
      develop: {
        files: {
          'build/report': ['lib/**/*.js']
        }
      }
    },
    dist: {
      "remote": ['clean:remote', 'coffee:remote', 'wrap', 'version', 'requirejs:remote'],
      "client": ['clean:client', 'coffee:client', 'wrap', 'version', 'requirejs:client'],
      "api": ['clean:client', 'coffee:api', 'version', 'requirejs:api'],
      "client-no-underscore": ['clean:client', 'coffee:client', 'wrap', 'version', 'requirejs:client-no-underscore'],
      "client-no-backbone": ['clean:client', 'coffee:client', 'wrap', 'version', 'requirejs:client-no-backbone'],
      "widgets": ["hull_widgets"],
      "docs": ['dox']
    }
  };

  helpers.appendAWSConfig(gruntConfig);
  grunt.initConfig(gruntConfig);

  grunt.registerTask('do_test', ['cover', 'plato', 'mocha']);
  grunt.registerTask('test', ['dist:api', 'dist:client', 'dist:remote', 'do_test']);
  grunt.registerTask('default', ['connect', 'test', 'dist:widgets', 'watch']);
  grunt.registerTask('reset', ['clean:reset']);

  grunt.registerTask('deploy', ['dist', 'describe', 's3:prod']);

  var git = require('git-rev');

  grunt.registerTask('staging', 'Put files in Staging', function(){
    var done = this.async();
    git.branch(function(branch){
      gruntConfig.GIT_BRANCH = branch;
      grunt.initConfig(gruntConfig);
      grunt.task.run('dist', 'describe', 's3:staging');
      done();
    });
  })

  require('./.grunt/customTasks')(grunt);

};
<commit_msg>Staging task<commit_after>module.exports = function (grunt) {
  'use strict';

  var helpers = require('./.grunt/helpers')(grunt);
  var clone = grunt.util._.clone;

  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-coffee');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.loadNpmTasks('grunt-mocha');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-hull-dox');
  grunt.loadNpmTasks('grunt-hull-widgets');
  grunt.loadNpmTasks('grunt-s3');
  grunt.loadNpmTasks('grunt-git-describe');
  grunt.loadNpmTasks('grunt-coverjs');
  grunt.loadNpmTasks('grunt-plato');
  grunt.loadNpmTasks('grunt-wrap');

  var pkg = grunt.file.readJSON('bower.json');
  var clientConfig = grunt.file.readJSON('.grunt/client.json');
  var remoteConfig = grunt.file.readJSON('.grunt/remote.json');
  var apiConfig = grunt.file.readJSON('.grunt/api.json');

  var port = 3001;

  // ==========================================================================
  // Project configuration
  // ==========================================================================

  // Lookup of the available libs and injects them for the build
  // in the requirejs conf
  var clientLibs = helpers.getBuiltFilenames('src/client/**/*.coffee');
  var remoteLibs = helpers.getBuiltFilenames('src/remote/**/*.coffee');

  // Lookup of the Aura Extensions and injects them in the requirejs build
  var auraExtensions = grunt.file.glob
    .sync('aura-extensions/**/*.js')
    .map(function (extension) {
      return extension.replace('.js', '');
    });

  //Augment the require.js configuation with some computed elements
  var apiRJSConfig = (function () {
    var _c = apiConfig.requireJS;
    _c.optimize = grunt.option('dev') ? "none" : "uglify";
    return _c;
  })();
  var clientRJSConfig = (function () {
    var _c = clientConfig.requireJS;
    _c.include = _c.include.concat(auraExtensions).concat(clientLibs);
    _c.optimize = grunt.option('dev') ? "none" : "uglify";
    return _c;
  })();

  var remoteRJSConfig = (function () {
    var _c = remoteConfig.requireJS;
    _c.include = _c.include.concat(remoteLibs);
    _c.optimize = grunt.option('dev') ? "none" : "uglify";
    return _c;
  })();

  var gruntConfig = {
    PKG_VERSION: pkg.version,
    clean: {
      client: {
        src: 'lib/client/**/*'
      },
      remote: {
        src: 'lib/remote/**/*'
      },
      reset: {
        src: ['build', 'lib', 'tmp', 'dist', 'components', 'node_modules']
      }
    },
    dox: {
      files: {
        baseDir: 'widgets',
        src: 'widgets/**/main.js',
        dest: 'dist/<%= PKG_VERSION %>/docs'
      }
    },
    coffee: {
      compile: {
        options: {
          header: true
        }
      },
      remote: {
        files: grunt.file.expandMapping(remoteConfig.srcFiles, 'lib/', {
          rename: function (destBase, destPath) {
            return destBase + destPath.replace(/\.coffee$/, '.js').replace(/^src\//, "");
          }
        })
      },
      client: {
        files: grunt.file.expandMapping(clientConfig.srcFiles, 'lib/', {
          rename: function (destBase, destPath) {
            return destBase + destPath.replace(/\.coffee$/, '.js').replace(/^src\//, "");
          }
        })
      },
      api: {
        files: grunt.file.expandMapping(apiConfig.srcFiles, 'lib/', {
          rename: function (destBase, destPath) {
            return destBase + destPath.replace(/\.coffee$/, '.js').replace(/^src\//, "");
          }
        })
      }
    },
    connect: {
      server: {
        options: {
          port: port
        }
      }
    },
    requirejs: {
      "client-no-backbone": {
        options: (function (c) {
          c.paths.underscore = 'empty:';
          c.paths.backbone = 'empty:';
          c.out = c.out.replace('hull.js', 'hull.no-backbone.js');
          c.wrap.start = c.wrap.start + ";root._ = window._;";
          c.wrap.start = c.wrap.start + ";root.Backbone = window.Backbone;";
          return c;
        })(clone(clientRJSConfig, true))
      },
      "client-no-underscore": {
        options: (function (c) {
          c.paths.underscore = 'empty:';
          c.out = c.out.replace('hull.js', 'hull.no-underscore.js');
          c.wrap.start = c.wrap.start + ";root._ = window._;";
          return c;
        })(clone(clientRJSConfig, true))
      },
      api: {
        options: clone(apiRJSConfig, true)
      },
      client: {
        options: clone(clientRJSConfig, true)
      },
      remote: {
        options: clone(remoteRJSConfig, true)
      },
      upload: {
        options: {
          namespace: 'Hull',
          paths: {
            jquery: "empty:",
            "jquery.ui.widget" : 'components/jquery-file-upload/js/vendor/jquery.ui.widget',
            "jquery.fileupload" : 'components/jquery-file-upload/js/jquery.fileupload'
          },
          include: [
            'jquery.fileupload'
          ],
          out: 'tmp/widgets/upload/deps/jquery.fileupload.js'
        }
      },
      registration: {
        options: {
          namespace: 'Hull',
          paths: { h5f: 'widgets/registration/h5f' },
          shim: { h5f: { exports: 'H5F' } },
          include: ['h5f'],
          out: 'tmp/widgets/registration/deps.js'
        }
      },
      dox: {
        options: {
          namespace: 'Hull',
          paths: { prism: 'widgets/dox/dox/prism' },
          shim: { prism: { exports: 'Prism' } },
          include: ['prism'],
          out: 'tmp/widgets/dox/dox/deps.js'
        }
      }
    },
    mocha: {
      hull: {
        src: ["spec/index.html"]
      }
    },
    watch: {
      widgets: {
        files: ['widgets/**/*'],
        tasks: ['hull_widgets']
      },
      remote: {
        files: remoteConfig.srcFiles,
        tasks: ['dist:remote', 'do_test']
      },
      api: {
        files: apiConfig.srcFiles,
        tasks: ['dist:api', 'do_test']
      },
      client: {
        files: clientConfig.srcFiles,
        tasks: ['dist:client', 'do_test']
      },
      spec: {
        files: ['spec/**/*.js'],
        tasks: ['mocha']
      }
    },
    version: {
      template: "define(function () { return '<%= PKG_VERSION %>';});",
      dest: 'lib/utils/version.js'
    },
    hull_widgets: {
      hull: {
        src: 'widgets',
        before: ['requirejs:upload', 'requirejs:registration', 'requirejs:dox'],
        dest: 'dist/<%= PKG_VERSION%>',
        optimize: !grunt.option('dev')
      }
    },
    describe: {
      out: 'dist/<%= PKG_VERSION%>/REVISION'
    },
    wrap: {
      Handlebars: {
        src: 'node_modules/grunt-contrib-handlebars/node_modules/handlebars/dist/handlebars.js',
        dest: 'lib/shims',
        wrapper: [
          '(function () {', ';define("handlebars", function () {return Handlebars;});})()'
        ]
      },
      easyXDM: {
        src: 'components/easyXDM/easyXDM.js',
        dest: 'lib/shims',
        wrapper: [
          '', ';var _available = window.easyXDM;define("easyXDM", function () {return window.easyXDM.noConflict();});if(!_available){delete window.easyXDM;};'
        ]
      }
    },
    cover: {
      compile: {
        files: {
          'build/instrumented/*.js' : ['lib/**/*.js']
        },
        options: {
          basePath: 'lib'
        }
      }
    },
    plato: {
      develop: {
        files: {
          'build/report': ['lib/**/*.js']
        }
      }
    },
    dist: {
      "remote": ['clean:remote', 'coffee:remote', 'wrap', 'version', 'requirejs:remote'],
      "client": ['clean:client', 'coffee:client', 'wrap', 'version', 'requirejs:client'],
      "api": ['clean:client', 'coffee:api', 'version', 'requirejs:api'],
      "client-no-underscore": ['clean:client', 'coffee:client', 'wrap', 'version', 'requirejs:client-no-underscore'],
      "client-no-backbone": ['clean:client', 'coffee:client', 'wrap', 'version', 'requirejs:client-no-backbone'],
      "widgets": ["hull_widgets"],
      "docs": ['dox']
    }
  };

  helpers.appendAWSConfig(gruntConfig);
  grunt.initConfig(gruntConfig);

  grunt.registerTask('target','Set current target', function(){
    var done = this.async();
    git.branch(function(branch){
      grunt.config.set("PKG_VERSION",branch);
      grunt.config.set("GIT_BRANCH",branch);
      done();
    });

  });
  grunt.registerTask('do_test', ['cover', 'plato', 'mocha']);
  grunt.registerTask('test', ['dist:api', 'dist:client', 'dist:remote', 'do_test']);
  grunt.registerTask('default', ['connect', 'test', 'dist:widgets', 'watch']);
  grunt.registerTask('reset', ['clean:reset']);

  grunt.registerTask('deploy', ['dist', 'describe', 's3:prod']);

  grunt.registerTask('staging', ['target','dist', 'describe', 's3:staging']);

  var git = require('git-rev');

  require('./.grunt/customTasks')(grunt);

};
<|endoftext|>