<commit_before>Cards = [
  //{title: "Donación Topos", description: "Los Topos son una asosiación de rescatistas indepe…tencilios necesarios para el rescate de personas.", type: "Monetaria", location: "Todo el mundo.", link: "https://twitter.com/topos/status/908000616575680512"},
  {title: "Centro Acopio FARQ", description: "Centro de Acopio en La Facultad de Arquitectura UANL", type: "Viveres", location: "Monterrey.", link: "https://twitter.com/qt_ewok/status/910358246657073153"},
  {title: "Centro Acopio FAV", description: "Centro de Acopio en La Facultad de Artes Visuales UANL", type: "Viveres", location: "Monterrey.", link: "https://scontent.fntr3-1.fna.fbcdn.net/v/t1.0-0/s480x480/21616244_1344314475691495_4475004746040701212_n.jpg?oh=d6ed0e1262d913fc70ce69694e190a52&oe=5A48CE3F"},
  {title: "Ayuda Medicinas Monterrey", description: "Ayuda con elementos de curación como alcohol, gasas, cubre bocas, agua oxigenada, solución salina, baterías.", type: "Médicina", location: "Monterrey.", link: "https://twitter.com/vovimayhem/status/910371427248984065"},
  {title: "Ayuda Arquitectos o Ingenieros Virtualmente", description: "Ayuda virtual apra hacer evaluaciones estructurales.", type: "Ayuda/Asesoría", location: "Todo el Mundo.", link: "https://twitter.com/YONOFUI/status/910381253144309761"},
  {title: "Voluntarios y Brigadas Universidad Panamericana", description: "Centro de Acopio en la Universidad Panamericana", type: "Varia", location: "CDMX", link: "https://facebook.com/UPMexico"},
  {title: "Paypal Cruz Roja Mexicana", description: "Pagina oficial para donar a la Cruz Roja Mexicana por medio de Paypal", type: "Monetaria", location: "Todo el Mundo.", link: "https://www.paypal.com/mx/webapps/mpp/donar/institution?name=redCross"},
  {title: "Centros de Acopio Dolores Hidalgo", description: "Centros de acopio en Guanajuato", type: "Varia", location: "Guanajuato", link: "http://comoayudar.mx/img/hidalgo.jpg"},
  {title: "Acopio Medicina Monterrey", description: "Recolección de medicina para médicos que saldrán desde Monterrey", type: "Medicamentos", location: "Monterrey", link: "https://scontent.fntr3-1.fna.fbcdn.net/v/t1.0-9/21686379_10159419122800381_7969880375128985024_n.jpg?oh=85ad72baa5f38b27878e76b884187465&oe=5A3B08F6"},
  {title: "Nuhda Team Donations", description: "NUHDA TEAM will be collecting all in kind donations at NUHDA TI:ME Montecillo Wednesday and Thursday from 12 PM to 6 PM. All items will be delivered in Juarez during the weekend to send to Mexico City.", type: "Viveres", location: "El Paso, Texas", link: "https://www.facebook.com/permalink.php?story_fbid=243962466127294&id=138796859977189"},
  {title: "Centro de Acopio Aztlán Bar", description: "Colecta de víveres para las personas afectadas por el sismo en la CDMX. Horarios de 11 AM a 8 PM", type: "Viveres", location: "CDMX", link: "https://www.facebook.com/aztlanrb/posts/1424117287677919"},
  {title: "Centro de Acopio en Torreón", description: "Centros de Acopio en Torreón Coahuila.", type: "Viveres/Varios", location: "Torreón", link: "https://twitter.com/AnaMaciasAnaya/status/910349434315268096"},
  {title: "Centro de Acopio Parque España", description: "20 de septiembre de 10:00 a 17:00 en la explanada del Parque España de la CDMX.", type: "Viveres/Kit Médico", location: "CDMX", link: "https://www.facebook.com/indiemovradio/photos/pb.1048756795183942.-2207520000.1505889399./1543570285702588/?type=3"},
  {title: "Centro de Acopio Mexicali", description: "Centro de acopio en Méxicalí B.C.", type: "Viveres", location: "Mexicali", link: "https://twitter.com/claumeely/status/910396891640225793"},
  {title: "Acopio Carnicerías Ramos", description: "20 de septiembre a partir de las 8 de la mañana, TODAS las sucursales Ramos funcionarán como centro de acopio. ", type: "Kit Médico", location: "Monterrey", link: "https://www.facebook.com/CarnesRamos/posts/1569495539739254"},
  {title: "Aloja personas damnificadas a través de Airbnb México", description: "Ayuda a los damnificados que necesitan un lugar donde dormir a través de Airbnb México", type: "Alojamiento", location: "CDMX", link: "https://www.airbnb.com/welcome/evacuees/terremotoenmexico"},
];
<commit_msg>Añade centro de acopio y albergues de Coyoacán<commit_after>Cards = [
  //{title: "Donación Topos", description: "Los Topos son una asosiación de rescatistas indepe…tencilios necesarios para el rescate de personas.", type: "Monetaria", location: "Todo el mundo.", link: "https://twitter.com/topos/status/908000616575680512"},
  {title: "Centro Acopio FARQ", description: "Centro de Acopio en La Facultad de Arquitectura UANL", type: "Viveres", location: "Monterrey.", link: "https://twitter.com/qt_ewok/status/910358246657073153"},
  {title: "Centro Acopio FAV", description: "Centro de Acopio en La Facultad de Artes Visuales UANL", type: "Viveres", location: "Monterrey.", link: "https://scontent.fntr3-1.fna.fbcdn.net/v/t1.0-0/s480x480/21616244_1344314475691495_4475004746040701212_n.jpg?oh=d6ed0e1262d913fc70ce69694e190a52&oe=5A48CE3F"},
  {title: "Ayuda Medicinas Monterrey", description: "Ayuda con elementos de curación como alcohol, gasas, cubre bocas, agua oxigenada, solución salina, baterías.", type: "Médicina", location: "Monterrey.", link: "https://twitter.com/vovimayhem/status/910371427248984065"},
  {title: "Ayuda Arquitectos o Ingenieros Virtualmente", description: "Ayuda virtual apra hacer evaluaciones estructurales.", type: "Ayuda/Asesoría", location: "Todo el Mundo.", link: "https://twitter.com/YONOFUI/status/910381253144309761"},
  {title: "Voluntarios y Brigadas Universidad Panamericana", description: "Centro de Acopio en la Universidad Panamericana", type: "Varia", location: "CDMX", link: "https://facebook.com/UPMexico"},
  {title: "Paypal Cruz Roja Mexicana", description: "Pagina oficial para donar a la Cruz Roja Mexicana por medio de Paypal", type: "Monetaria", location: "Todo el Mundo.", link: "https://www.paypal.com/mx/webapps/mpp/donar/institution?name=redCross"},
  {title: "Centros de Acopio Dolores Hidalgo", description: "Centros de acopio en Guanajuato", type: "Varia", location: "Guanajuato", link: "http://comoayudar.mx/img/hidalgo.jpg"},
  {title: "Acopio Medicina Monterrey", description: "Recolección de medicina para médicos que saldrán desde Monterrey", type: "Medicamentos", location: "Monterrey", link: "https://scontent.fntr3-1.fna.fbcdn.net/v/t1.0-9/21686379_10159419122800381_7969880375128985024_n.jpg?oh=85ad72baa5f38b27878e76b884187465&oe=5A3B08F6"},
  {title: "Nuhda Team Donations", description: "NUHDA TEAM will be collecting all in kind donations at NUHDA TI:ME Montecillo Wednesday and Thursday from 12 PM to 6 PM. All items will be delivered in Juarez during the weekend to send to Mexico City.", type: "Viveres", location: "El Paso, Texas", link: "https://www.facebook.com/permalink.php?story_fbid=243962466127294&id=138796859977189"},
  {title: "Centro de Acopio Aztlán Bar", description: "Colecta de víveres para las personas afectadas por el sismo en la CDMX. Horarios de 11 AM a 8 PM", type: "Viveres", location: "CDMX", link: "https://www.facebook.com/aztlanrb/posts/1424117287677919"},
  {title: "Centro de Acopio en Torreón", description: "Centros de Acopio en Torreón Coahuila.", type: "Viveres/Varios", location: "Torreón", link: "https://twitter.com/AnaMaciasAnaya/status/910349434315268096"},
  {title: "Centro de Acopio Parque España", description: "20 de septiembre de 10:00 a 17:00 en la explanada del Parque España de la CDMX.", type: "Viveres/Kit Médico", location: "CDMX", link: "https://www.facebook.com/indiemovradio/photos/pb.1048756795183942.-2207520000.1505889399./1543570285702588/?type=3"},
  {title: "Centro de Acopio Mexicali", description: "Centro de acopio en Méxicalí B.C.", type: "Viveres", location: "Mexicali", link: "https://twitter.com/claumeely/status/910396891640225793"},
  {title: "Acopio Carnicerías Ramos", description: "20 de septiembre a partir de las 8 de la mañana, TODAS las sucursales Ramos funcionarán como centro de acopio. ", type: "Kit Médico", location: "Monterrey", link: "https://www.facebook.com/CarnesRamos/posts/1569495539739254"},
  {title: "Aloja personas damnificadas a través de Airbnb México", description: "Ayuda a los damnificados que necesitan un lugar donde dormir a través de Airbnb México", type: "Alojamiento", location: "CDMX", link: "https://www.airbnb.com/welcome/evacuees/terremotoenmexico"},
  {title: "Donación Altruista de Sangre", description: "Indicaciones del IMSS para poder donar sangre.", type: "Sangre", location: "CDMX, Pue, Mor, Oax, EdoMex y Gro", link: "http://www.imss.gob.mx/salud-en-linea/donacion-sangre"},
  {title: "Centro de acopio Coyoacán", description: "Centro de acopio de Coyoacán en el kiosko de la alameda sur.", type: "Viveres, medicina", location: "CDMX", link: "https://twitter.com/Del_Coyoacan/status/910345167332413443"},
  {title: "Albergues en Coyoacán, CDMX", description: "Existen tres albergues en la delegación Coyoacán: La Casa de las Letras, la Territorial Culhuacanes y el CDC de Bombas.", type: "Albergue", location: "CDMX", link: "https://twitter.com/Del_Coyoacan/status/910346089001299969"},
];
<|endoftext|>


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

module.exports = function(grunt) {

  var async = grunt.util.async;
  var log = grunt.log;

  // Available versions of jQuery on CDN
  var jQVersions = ['1.6.4', '1.7.2', '1.8.3', '1.9.1', '1.10.1', '2.0.3'];
  var cdnHost = 'code.jquery.com';
  var destDir = path.join(__dirname, 'src');

  function fetchjQuery(jQVersion, callback) {

    var name = 'jquery-' + jQVersion + '.js';
    var filePath = path.join(destDir, name);

    // If file already exists, then don't download it again
    if(fs.existsSync(filePath)) {
      log.writeln('\u25e6', name);
      setTimeout(callback, 100);
      return;
    }

    // Stream the response in to files
    var stream = fs.createWriteStream(filePath, {
      'encoding': 'utf8'
    });

    http.request({
      'host': cdnHost,
      'path': '/' + name,
      'headers': {
        'Host': cdnHost
      }
    }, function(response) {
      response.setEncoding('utf8');
      response.on('data', stream.write.bind(stream));
      response.on('end', function() {
        stream.end();
        log.writeln('\u2713', name);
        setTimeout(callback, 100);
      });
      response.on('error', function(e) {
        log.writeln('error', e, name);
      });
    }).end();
  }

  grunt.registerTask('download', 'Download jQuery versions from CDN', function() {
    // This task is async
    var done = this.async();
    async.forEach(jQVersions, fetchjQuery, done);
  });

  // Project configuration.
  grunt.initConfig({
    'pkg': grunt.file.readJSON('package.json'),
    'nodeunit': {
      'files': 'test/index.js'
    },
    'watch': {
      'files': ['test/**/*.js'],
      'tasks': ['nodeunit'],
      'options': {
        'debounceDelay': 250
      }
    },
    'jshint': {
      'files': ['Gruntfile.js', 'lib/**/*.js', 'test/**/*.js'],
      'options': {
        'jshintrc': '.jshintrc'
      }
    }
  });

  // Load grunt plugins
  grunt.loadNpmTasks('grunt-contrib-nodeunit');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-jshint');

  // Register tasks.
  grunt.registerTask('default', ['jshint', 'download', 'nodeunit']);

  // Alias "test" to "nodeunit"
  grunt.registerTask('test', ['nodeunit']);

};
<commit_msg>bump versions in grunt file as well<commit_after>var fs = require('fs');
var path = require('path');
var http = require('http');

module.exports = function(grunt) {

  var async = grunt.util.async;
  var log = grunt.log;

  // Available versions of jQuery on CDN
  var jQVersions = ['1.6.4', '1.7.2', '1.8.3', '1.9.1', '1.10.2', '2.0.3'];
  var cdnHost = 'code.jquery.com';
  var destDir = path.join(__dirname, 'src');

  function fetchjQuery(jQVersion, callback) {

    var name = 'jquery-' + jQVersion + '.js';
    var filePath = path.join(destDir, name);

    // If file already exists, then don't download it again
    if(fs.existsSync(filePath)) {
      log.writeln('\u25e6', name);
      setTimeout(callback, 100);
      return;
    }

    // Stream the response in to files
    var stream = fs.createWriteStream(filePath, {
      'encoding': 'utf8'
    });

    http.request({
      'host': cdnHost,
      'path': '/' + name,
      'headers': {
        'Host': cdnHost
      }
    }, function(response) {
      response.setEncoding('utf8');
      response.on('data', stream.write.bind(stream));
      response.on('end', function() {
        stream.end();
        log.writeln('\u2713', name);
        setTimeout(callback, 100);
      });
      response.on('error', function(e) {
        log.writeln('error', e, name);
      });
    }).end();
  }

  grunt.registerTask('download', 'Download jQuery versions from CDN', function() {
    // This task is async
    var done = this.async();
    async.forEach(jQVersions, fetchjQuery, done);
  });

  // Project configuration.
  grunt.initConfig({
    'pkg': grunt.file.readJSON('package.json'),
    'nodeunit': {
      'files': 'test/index.js'
    },
    'watch': {
      'files': ['test/**/*.js'],
      'tasks': ['nodeunit'],
      'options': {
        'debounceDelay': 250
      }
    },
    'jshint': {
      'files': ['Gruntfile.js', 'lib/**/*.js', 'test/**/*.js'],
      'options': {
        'jshintrc': '.jshintrc'
      }
    }
  });

  // Load grunt plugins
  grunt.loadNpmTasks('grunt-contrib-nodeunit');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-jshint');

  // Register tasks.
  grunt.registerTask('default', ['jshint', 'download', 'nodeunit']);

  // Alias "test" to "nodeunit"
  grunt.registerTask('test', ['nodeunit']);

};
<|endoftext|>


<commit_before>// Credit to Ramda for this idea for creating curried functions that
// properly report their arity via function.length.
// https://github.com/ramda/ramda/blob/master/src/internal/_arity.js
export default function _arity (arity, fn) {
  switch (arity) {
    case 0: return function () { return fn.apply(null, arguments) }
    case 1: return function (a0) { return fn.apply(null, arguments) }
    case 2: return function (a0, a1) { return fn.apply(null, arguments) }
    case 3: return function (a0, a1, a2) { return fn.apply(null, arguments) }
    case 4: return function (a0, a1, a2, a3) { return fn.apply(null, arguments) }
    case 5: return function (a0, a1, a2, a3, a4) { return fn.apply(null, arguments) }
    case 6: return function (a0, a1, a2, a3, a4, a5) { return fn.apply(null, arguments) }
    default: throw new Error('Function arity must be <= 6.')
  }
}
<commit_msg>refactor(_arity): do not proxy wrapped function if length is writable<commit_after>export default function _arity (arity, fn) {
  if (Object.getOwnPropertyDescriptor(fn, 'length').writable) {
    Object.defineProperty(fn, 'length', { value: arity })
    return fn
  }
  // Credit to Ramda for this idea for creating curried functions that
  // properly report their arity via function.length.
  // https://github.com/ramda/ramda/blob/master/src/internal/_arity.js
  switch (arity) {
    case 0: return function () { return fn.apply(null, arguments) }
    case 1: return function (a0) { return fn.apply(null, arguments) }
    case 2: return function (a0, a1) { return fn.apply(null, arguments) }
    case 3: return function (a0, a1, a2) { return fn.apply(null, arguments) }
    case 4: return function (a0, a1, a2, a3) { return fn.apply(null, arguments) }
    case 5: return function (a0, a1, a2, a3, a4) { return fn.apply(null, arguments) }
    case 6: return function (a0, a1, a2, a3, a4, a5) { return fn.apply(null, arguments) }
    default: throw new Error('Function arity must be <= 6.')
  }
}
<|endoftext|>


<commit_before>// jshint ignore: start
module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    connect: {
      server: {
        options: {
          port: 9000,
          hostname: '*',
          livereload: true
        }
      }
    },
    open: {
      server: {
        url: 'http://localhost:<%= connect.server.options.port %>/docs/html/'
      }
    },
    react: {
      dynamic_mappings: {
        files: [
          {
            expand: true,
            cwd: 'scripts/',
            src: ['**/*.jsx'],
            dest: 'modules/',
            ext: '.jsx.js'
          }
        ]
      }
    },
    jshint: {
      all: {
        src: ['Gruntfile.js', 'scripts/**/*.jsx', 'scripts/**/*.js'],
        options: {
          jshintrc: '.jshintrc'
        }
      }
    },
    markdown: {
      all: {
        files: [
          {
            expand: true,
            src: 'docs/dist/**/*.md',
            dest: 'docs/html/',
            flatten: true,
            ext: '.html'
          }
        ],
        options: {
          template: 'docs/src/template/template.jst',
          preCompile: function(src, context) {},
          postCompile: function(src, context) {},
          templateContext: {},
          markdownOptions: {
            gfm: true,
            highlight: 'manual',
            codeLines: {
              before: '',
              after: ''
            }
          }
        }
      }
    },
    includereplace: {
      docs: {
        options: {
          includesDir: "examples/"
          // Task-specific options go here.
        },
        // Files to perform replacements and includes with
        src: 'docs/src/**/*.md',
        // Destination directory to copy files to
        dest: 'docs/dist/',
      }
    },
    clean: {
      docs: [ "docs/html"],
      includes: [ "docs/dist"]
    },
    copy: {
      docs: {
        files: [
          { expand: true, cwd: 'docs/old/', src: ['**'], dest: 'docs/html/', flatten: false},
          { expand: true, cwd: 'docs/assets/', src: ['**'], dest: 'docs/html/', flatten: false},
          { expand: true, src: ['examples/assets/scripts/testComponent.js', 'examples/assets/scripts/fakeData.js'], dest: 'docs/html/scripts', flatten: true}
        ]
      }
    },
    webpack: {
      default: {
        entry: {
          Griddle: ['./scripts/griddle.jsx'],
          GriddleWithCallback: './scripts/griddleWithCallback.jsx'},
        output: {
          path: __dirname,
          filename: 'build/[name].js',
          publicPath: '/',
          library: "[name]",
          libraryTarget: "umd"
        },
        resolve: {
          extensions: ['', '.js', '.jsx']
        },
        module: {
          loaders: [
            {test: /\.jsx$/, loader: 'jsx'}
          ]
        },
        externals: {
          "react": "React",
          "underscore": "_"
        }
      },
      docs: {
        entry: {
            Griddle: ['./scripts/griddle.jsx'],
            GriddleWithCallback: './scripts/griddleWithCallback.jsx',
            TestChart: './examples/basic/testChart.jsx'
        },
        output: {
          path: __dirname,
          filename: 'docs/html/scripts/[name].js',
          publicPath: '/',
          library: "[name]",
          libraryTarget: "umd"
        },
        resolve: {
          extensions: ['', '.js', '.jsx']
        },
        module: {
          loaders: [
            {test: /\.jsx$/, loader: 'jsx'}
          ]
        },
        externals: {
          "react": "React",
          "underscore": "_"
        }
      }
    },
    watch: {
      scripts: {
        files: ['**/*.jsx', '**/*.md'],
        tasks: ['build'],
        options: {
          spawn: false,
          interrupt: true,
        },
      },
    },
  });

  grunt.loadNpmTasks('grunt-open');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-react');
  grunt.loadNpmTasks('grunt-jsxhint');
  grunt.loadNpmTasks('grunt-webpack');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-markdown');
  grunt.loadNpmTasks('grunt-include-replace');

  grunt.registerTask('serve', function (target) {
    grunt.task.run([
      'build',
      'connect',
      'open',
      'watch',
    ]);
  });

  grunt.registerTask('build', function(target){
    grunt.task.run([
      'clean',
      'includereplace',
      'markdown',
      'clean:includes',
      'webpack:docs',
      'copy',
    ]);
  })

  // Default task(s).
  grunt.registerTask('default', ['serve']);
};
<commit_msg>Fixes livereload.<commit_after>// jshint ignore: start
module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    connect: {
      server: {
        options: {
          port: 9000,
          hostname: '*',
          livereload: true
        }
      }
    },
    open: {
      server: {
        url: 'http://localhost:<%= connect.server.options.port %>/docs/html/'
      }
    },
    react: {
      dynamic_mappings: {
        files: [
          {
            expand: true,
            cwd: 'scripts/',
            src: ['**/*.jsx'],
            dest: 'modules/',
            ext: '.jsx.js'
          }
        ]
      }
    },
    jshint: {
      all: {
        src: ['Gruntfile.js', 'scripts/**/*.jsx', 'scripts/**/*.js'],
        options: {
          jshintrc: '.jshintrc'
        }
      }
    },
    markdown: {
      all: {
        files: [
          {
            expand: true,
            src: 'docs/dist/**/*.md',
            dest: 'docs/html/',
            flatten: true,
            ext: '.html'
          }
        ],
        options: {
          template: 'docs/src/template/template.jst',
          preCompile: function(src, context) {},
          postCompile: function(src, context) {},
          templateContext: {},
          markdownOptions: {
            gfm: true,
            highlight: 'manual',
            codeLines: {
              before: '',
              after: ''
            }
          }
        }
      }
    },
    includereplace: {
      docs: {
        options: {
          includesDir: "examples/"
          // Task-specific options go here.
        },
        // Files to perform replacements and includes with
        src: 'docs/src/**/*.md',
        // Destination directory to copy files to
        dest: 'docs/dist/',
      }
    },
    clean: {
      docs: [ "docs/html"],
      includes: [ "docs/dist"]
    },
    copy: {
      docs: {
        files: [
          { expand: true, cwd: 'docs/old/', src: ['**'], dest: 'docs/html/', flatten: false},
          { expand: true, cwd: 'docs/assets/', src: ['**'], dest: 'docs/html/', flatten: false},
          { expand: true, src: ['examples/assets/scripts/testComponent.js', 'examples/assets/scripts/fakeData.js'], dest: 'docs/html/scripts', flatten: true}
        ]
      }
    },
    webpack: {
      default: {
        entry: {
          Griddle: ['./scripts/griddle.jsx'],
          GriddleWithCallback: './scripts/griddleWithCallback.jsx'},
        output: {
          path: __dirname,
          filename: 'build/[name].js',
          publicPath: '/',
          library: "[name]",
          libraryTarget: "umd"
        },
        resolve: {
          extensions: ['', '.js', '.jsx']
        },
        module: {
          loaders: [
            {test: /\.jsx$/, loader: 'jsx'}
          ]
        },
        externals: {
          "react": "React",
          "underscore": "_"
        }
      },
      docs: {
        entry: {
            Griddle: ['./scripts/griddle.jsx'],
            GriddleWithCallback: './scripts/griddleWithCallback.jsx',
            TestChart: './examples/basic/testChart.jsx'
        },
        output: {
          path: __dirname,
          filename: 'docs/html/scripts/[name].js',
          publicPath: '/',
          library: "[name]",
          libraryTarget: "umd"
        },
        resolve: {
          extensions: ['', '.js', '.jsx']
        },
        module: {
          loaders: [
            {test: /\.jsx$/, loader: 'jsx'}
          ]
        },
        externals: {
          "react": "React",
          "underscore": "_"
        }
      }
    },
    watch: {
      scripts: {
        files: ['**/*.jsx', '**/*.md'],
        tasks: ['build'],
        options: {
          spawn: false,
          interrupt: true,
          livereload: true
        },
      },
    },
  });

  grunt.loadNpmTasks('grunt-open');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-react');
  grunt.loadNpmTasks('grunt-jsxhint');
  grunt.loadNpmTasks('grunt-webpack');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-markdown');
  grunt.loadNpmTasks('grunt-include-replace');

  grunt.registerTask('serve', function (target) {
    grunt.task.run([
      'build',
      'connect',
      'open',
      'watch',
    ]);
  });

  grunt.registerTask('build', function(target){
    grunt.task.run([
      'clean',
      'includereplace',
      'markdown',
      'clean:includes',
      'webpack:docs',
      'copy',
    ]);
  })

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


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

var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');

var paths = {
  scripts: ['dinosaurs/js/**/*.js'],
};

gulp.task('clean', function(cb) {
  del(['static/js'], cb);
});

gulp.task('minify', ['clean'], function() {
  return gulp.src(paths.scripts)
    .pipe(concat('site.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('static/js'));
});

gulp.task('concat', ['clean'], function() {
  return gulp.src(paths.scripts)
    .pipe(concat('site.js'))
    .pipe(gulp.dest('static/js'));
});

// Rerun the task when a file changes
gulp.task('watch', function() {
  gulp.watch(paths.scripts, ['concat']);
});

// The default task (called when you run `gulp` from cli)
gulp.task('default', ['watch', 'concat']);
<commit_msg>Lets use browserify!<commit_after>var del = require('del');
var gulp = require('gulp');
var watchify = require('watchify');
var concat = require('gulp-concat');
var gutil = require('gulp-util');
var uglify = require('gulp-uglify');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');

var paths = {
  scripts: ['dinosaurs/js/**/*.js'],
};

gulp.task('clean', function(cb) {
  del(['static/js'], cb);
});

gulp.task('build', ['clean'], function() {
  var bundler = watchify(browserify({
      cache: {}, packageCache: {}, fullPaths: true,
      entries: 'dinosaurs/index.js',
    }));

    return bundler.bundle()
    .on('error', gutil.log.bind(gutil, 'Browserify Error'))
    .pipe(source('site.min.js'))
    .pipe(buffer())
    .pipe(uglify())
    .pipe(gulp.dest('./static/js'));
});

gulp.task('develop', ['clean'], function() {
  var bundler = watchify(browserify({
      // Required watchify args
      cache: {}, packageCache: {}, fullPaths: true,
      // Specify the entry point of your app
      entries: 'dinosaurs/index.js',
      // Add file extentions to make optional in your requires
      // Enable source maps!
      debug: true
    }));
  bundler.on('update', rebundle);

  function rebundle() {
    return bundler.bundle()
      // log errors if they happen
      .on('error', gutil.log.bind(gutil, 'Browserify Error'))
      .pipe(source('site.min.js'))
      .pipe(gulp.dest('./static/js'));
  }

  return rebundle();
});

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


<commit_before>import {GLTFParser} from '@loaders.gl/gltf';
import {AnimationLoop, setParameters, clear, GLTFInstantiator, log} from 'luma.gl';
import {Matrix4, radians} from 'math.gl';
import document from 'global/document';

export const GLTF_BASE_URL = "https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/";

const INFO_HTML = `

glTF rendering.

A luma.gl glTF renderer.

  Model
  <select id="modelSelector">
    <option value="DamagedHelmet/glTF-Binary/DamagedHelmet.glb">DamagedHelmet</option>
    <option value="Avocado/glTF-Binary/Avocado.glb">Avocado</option>
    <option value="AnimatedMorphCube/glTF-Binary/AnimatedMorphCube.glb">AnimatedMorphCube</option>
    <option value="TextureCoordinateTest/glTF-Binary/TextureCoordinateTest.glb">TextureCoordinateTest</option>
    <option value="VertexColorTest/glTF-Binary/VertexColorTest.glb">VertexColorTest</option>
    <option value="BoxVertexColors/glTF-Binary/BoxVertexColors.glb">BoxVertexColors</option>
    <option value="Box/glTF-Binary/Box.glb">Box</option>
    <option value="BoxTexturedNonPowerOfTwo/glTF-Binary/BoxTexturedNonPowerOfTwo.glb">BoxTexturedNonPowerOfTwo</option>
    <option value="InterpolationTest/glTF-Binary/InterpolationTest.glb">InterpolationTest</option>
    <option value="BoxInterleaved/glTF-Binary/BoxInterleaved.glb">BoxInterleaved</option>
    <option value="BoomBox/glTF-Binary/BoomBox.glb">BoomBox</option>
    <option value="Buggy/glTF-Binary/Buggy.glb">Buggy</option>
    <option value="CesiumMan/glTF-Binary/CesiumMan.glb">CesiumMan</option>
    <option value="AlphaBlendModeTest/glTF-Binary/AlphaBlendModeTest.glb">AlphaBlendModeTest</option>
    <option value="Duck/glTF-Binary/Duck.glb">Duck</option>
    <option value="MorphPrimitivesTest/glTF-Binary/MorphPrimitivesTest.glb">MorphPrimitivesTest</option>
    <option value="MorphPrimitivesTest/glTF-Draco/MorphPrimitivesTest.glb">MorphPrimitivesTest</option>
    <option value="2CylinderEngine/glTF-Binary/2CylinderEngine.glb">CylinderEngine</option>
    <option value="Lantern/glTF-Binary/Lantern.glb">Lantern</option>
    <option value="MultiUVTest/glTF-Binary/MultiUVTest.glb">MultiUVTest</option>
    <option value="WaterBottle/glTF-Binary/WaterBottle.glb">WaterBottle</option>
    <option value="BrainStem/glTF-Binary/BrainStem.glb">BrainStem</option>
    <option value="BarramundiFish/glTF-Binary/BarramundiFish.glb">BarramundiFish</option>
    <option value="NormalTangentMirrorTest/glTF-Binary/NormalTangentMirrorTest.glb">NormalTangentMirrorTest</option>
    <option value="ReciprocatingSaw/glTF-Binary/ReciprocatingSaw.glb">ReciprocatingSaw</option>
    <option value="UnlitTest/glTF-Binary/UnlitTest.glb">UnlitTest</option>
    <option value="MetalRoughSpheres/glTF-Binary/MetalRoughSpheres.glb">MetalRoughSpheres</option>
    <option value="TextureSettingsTest/glTF-Binary/TextureSettingsTest.glb">TextureSettingsTest</option>
    <option value="BoxAnimated/glTF-Binary/BoxAnimated.glb">BoxAnimated</option>
    <option value="VC/glTF-Binary/VC.glb">VC</option>
    <option value="AntiqueCamera/glTF-Binary/AntiqueCamera.glb">AntiqueCamera</option>
    <option value="OrientationTest/glTF-Binary/OrientationTest.glb">OrientationTest</option>
    <option value="CesiumMilkTruck/glTF-Binary/CesiumMilkTruck.glb">CesiumMilkTruck</option>
    <option value="AnimatedMorphSphere/glTF-Binary/AnimatedMorphSphere.glb">AnimatedMorphSphere</option>
    <option value="RiggedSimple/glTF-Binary/RiggedSimple.glb">RiggedSimple</option>
    <option value="Corset/glTF-Binary/Corset.glb">Corset</option>
    <option value="RiggedFigure/glTF-Binary/RiggedFigure.glb">RiggedFigure</option>
    <option value="GearboxAssy/glTF-Binary/GearboxAssy.glb">GearboxAssy</option>
    <option value="NormalTangentTest/glTF-Binary/NormalTangentTest.glb">NormalTangentTest</option>
    <option value="SpecGlossVsMetalRough/glTF-Binary/SpecGlossVsMetalRough.glb">SpecGlossVsMetalRough</option>
    <option value="Monster/glTF-Binary/Monster.glb">Monster</option>
    <option value="BoxTextured/glTF-Binary/BoxTextured.glb">BoxTextured</option>
  </select>

  Show
  <select id="showSelector">
    <option value="0 0 0 0 0 0 0 0">Final Result</option>

    <option value="0 1 0 0 0 0 0 0">Base Color</option>
    <option value="0 0 1 0 0 0 0 0">Metallic</option>
    <option value="0 0 0 1 0 0 0 0">Roughness</option>
    <option value="1 0 0 0 0 0 0 0">Diffuse</option>

    <option value="0 0 0 0 1 0 0 0">Specular Reflection</option>
    <option value="0 0 0 0 0 1 0 0">Geometric Occlusion</option>
    <option value="0 0 0 0 0 0 1 0">Microfacet Distribution</option>
    <option value="0 0 0 0 0 0 0 1">Specular</option>
  </select>

`;

const DEFAULT_OPTIONS = {
  pbrDebug: true,
  pbrIbl: true
};

function loadGLTF(urlOrPromise, gl, options = DEFAULT_OPTIONS) {
  const promise = urlOrPromise instanceof Promise ? urlOrPromise : window.fetch(urlOrPromise).then(res => res.arrayBuffer());

  return promise.then(data => {
    const gltfParser = new GLTFParser();
    const gltf = gltfParser.parse(data);

    const instantiator = new GLTFInstantiator(gl, options);
    const scenes = instantiator.instantiate(gltf);

    log.info(4, "gltfParser: ", gltfParser)();
    log.info(4, "instantiator.instantiate(): ", scenes)();

    scenes[0].traverse((node, {worldMatrix}) => {
      log.info(4, "Using model: ", node)();
    });

    return scenes;
  });
}

export class DemoApp {
  constructor({modelFile = null, initialZoom = 2} = {}) {
    this.scenes = [];
    this.gl = null;
    this.modelFile = modelFile;

    this.glOptions = {
      // Use to test gltf with webgl 1.0 and 2.0
      webgl2: true
    };

    this.mouse = {
      lastX: 0,
      lastY: 0
    };

    this.translate = initialZoom;
    this.rotation = [0, 0];
    this.rotationStart = [0, 0];

    this.u_ScaleDiffBaseMR = [0, 0, 0, 0];
    this.u_ScaleFGDSpec = [0, 0, 0, 0];

    this.onInitialize = this.onInitialize.bind(this);
    this.onRender = this.onRender.bind(this);
  }

  initalizeEventHandling(canvas) {
    canvas.onwheel = e => {
      this.translate += e.deltaY / 10;
      if (this.translate < 0.5) {
        this.translate = 0.5;
      }
      e.preventDefault();
    };

    canvas.onpointerdown = e => {
      this.mouse.lastX = e.clientX;
      this.mouse.lastY = e.clientY;

      this.rotationStart[0] = this.rotation[0];
      this.rotationStart[1] = this.rotation[1];

      canvas.setPointerCapture(e.pointerId);
      e.preventDefault();
    };

    canvas.onpointermove = e => {
      if (e.buttons) {
        const dX = e.clientX - this.mouse.lastX;
        const dY = e.clientY - this.mouse.lastY;

        this.rotation[0] = this.rotationStart[0] + dY / 100;
        this.rotation[1] = this.rotationStart[1] + dX / 100;
      }
    };

    canvas.ondragover = e => {
      e.dataTransfer.dropEffect = 'link';
      e.preventDefault();
    };

    canvas.ondrop = e => {
      e.preventDefault();
      if (e.dataTransfer.files && e.dataTransfer.files.length === 1) {
        loadGLTF(new Promise(resolve => {
          const reader = new window.FileReader();
          reader.onload = ev => resolve(ev.target.result);
          reader.readAsArrayBuffer(e.dataTransfer.files[0]);
        }), this.gl).then(scenes => (this.scenes = scenes));
      }
    };
  }

  onInitialize({gl, canvas}) {
    setParameters(gl, {
      depthTest: true,
      blend: false,
    });

    this.gl = gl;
    if (this.modelFile) {
      // options for unit testing
      const options = {
        pbrDebug: false,
        pbrIbl: false
      };
      loadGLTF(this.modelFile, this.gl, options).then(scenes => (this.scenes = scenes));
    } else {
      const modelSelector = document.getElementById("modelSelector");
      loadGLTF(GLTF_BASE_URL + modelSelector.value, this.gl).then(scenes => (this.scenes = scenes));

      modelSelector.onchange = event => {
        loadGLTF(GLTF_BASE_URL + modelSelector.value, this.gl).then(scenes => (this.scenes = scenes));
      };
    }

    const showSelector = document.getElementById("showSelector");
    if (showSelector) {
      showSelector.onchange = event => {
        const value = showSelector.value.split(" ").map(x => parseFloat(x));
        this.u_ScaleDiffBaseMR = value.slice(0, 4);
        this.u_ScaleFGDSpec = value.slice(4);
      };
    }

    this.initalizeEventHandling(canvas);
  }

  onRender({gl, tick, width, height, aspect}) {
    gl.viewport(0, 0, width, height);
    clear(gl, {color: [0.2, 0.2, 0.2, 1.0], depth: true});

    const [pitch, roll] = this.rotation;
    const cameraPos = [
      -this.translate * Math.sin(roll) * Math.cos(-pitch),
      -this.translate * Math.sin(-pitch),
      this.translate * Math.cos(roll) * Math.cos(-pitch)
    ];

    const uView = new Matrix4()
      .translate([0, 0, -this.translate])
      .rotateX(pitch)
      .rotateY(roll);

    const uProjection = new Matrix4().perspective({fov: radians(40), aspect, near: 0.1, far: 9000});

    if (!this.scenes.length) return false;

    let success = true;

    this.scenes[0].traverse((model, {worldMatrix}) => {
      // In glTF, meshes and primitives do no have their own matrix.
      const u_MVPMatrix = new Matrix4(uProjection).multiplyRight(uView).multiplyRight(worldMatrix);
      success = success && model.draw({
        uniforms: {
          u_Camera: cameraPos,
          u_MVPMatrix,
          u_ModelMatrix: worldMatrix,
          u_NormalMatrix: new Matrix4(worldMatrix).invert().transpose(),

          u_ScaleDiffBaseMR: this.u_ScaleDiffBaseMR,
          u_ScaleFGDSpec: this.u_ScaleFGDSpec,
        }
      });
    });

    return success;
  }
}

const animationLoop = new AnimationLoop(new DemoApp());

animationLoop.getInfo = () => INFO_HTML;

export default animationLoop;

/* global window */
if (typeof window !== 'undefined' && !window.website) {
  animationLoop.start();

  const infoDiv = document.createElement('div');
  infoDiv.innerHTML = animationLoop.getInfo();
  document.body.appendChild(infoDiv);
}
<commit_msg>glTF demo app: load model index dynamically (#935)<commit_after>import {GLTFParser} from '@loaders.gl/gltf';
import {AnimationLoop, setParameters, clear, GLTFInstantiator, log} from 'luma.gl';
import {Matrix4, radians} from 'math.gl';
import document from 'global/document';

export const GLTF_BASE_URL = "https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/";
const GLTF_MODEL_INDEX = `${GLTF_BASE_URL}model-index.json`;

const INFO_HTML = `

glTF rendering.

A luma.gl glTF renderer.

  Model
  <select id="modelSelector">
    <option value="DamagedHelmet/glTF-Binary/DamagedHelmet.glb">Default</option>
  </select>

  Show
  <select id="showSelector">
    <option value="0 0 0 0 0 0 0 0">Final Result</option>

    <option value="0 1 0 0 0 0 0 0">Base Color</option>
    <option value="0 0 1 0 0 0 0 0">Metallic</option>
    <option value="0 0 0 1 0 0 0 0">Roughness</option>
    <option value="1 0 0 0 0 0 0 0">Diffuse</option>

    <option value="0 0 0 0 1 0 0 0">Specular Reflection</option>
    <option value="0 0 0 0 0 1 0 0">Geometric Occlusion</option>
    <option value="0 0 0 0 0 0 1 0">Microfacet Distribution</option>
    <option value="0 0 0 0 0 0 0 1">Specular</option>
  </select>

`;

const DEFAULT_OPTIONS = {
  pbrDebug: true,
  pbrIbl: true
};

function loadGLTF(urlOrPromise, gl, options = DEFAULT_OPTIONS) {
  const promise = urlOrPromise instanceof Promise ? urlOrPromise : window.fetch(urlOrPromise).then(res => res.arrayBuffer());

  return promise.then(data => {
    const gltfParser = new GLTFParser();
    const gltf = gltfParser.parse(data);

    const instantiator = new GLTFInstantiator(gl, options);
    const scenes = instantiator.instantiate(gltf);

    log.info(4, "gltfParser: ", gltfParser)();
    log.info(4, "instantiator.instantiate(): ", scenes)();

    scenes[0].traverse((node, {worldMatrix}) => {
      log.info(4, "Using model: ", node)();
    });

    return scenes;
  });
}

function loadModelList() {
  return window.fetch(GLTF_MODEL_INDEX).then(res => res.json());
}

function addModelsToDropdown(models, modelDropdown) {
  models.forEach(({name, variants}) => {
    if (variants['glTF-Binary']) {
      const option = document.createElement('option');
      option.text = name;
      option.value = `${name}/glTF-Binary/${variants['glTF-Binary']}`;
      modelDropdown.appendChild(option);
    }
  });
}

export class DemoApp {
  constructor({modelFile = null, initialZoom = 2} = {}) {
    this.scenes = [];
    this.gl = null;
    this.modelFile = modelFile;

    this.glOptions = {
      // Use to test gltf with webgl 1.0 and 2.0
      webgl2: true
    };

    this.mouse = {
      lastX: 0,
      lastY: 0
    };

    this.translate = initialZoom;
    this.rotation = [0, 0];
    this.rotationStart = [0, 0];

    this.u_ScaleDiffBaseMR = [0, 0, 0, 0];
    this.u_ScaleFGDSpec = [0, 0, 0, 0];

    this.onInitialize = this.onInitialize.bind(this);
    this.onRender = this.onRender.bind(this);
  }

  initalizeEventHandling(canvas) {
    canvas.onwheel = e => {
      this.translate += e.deltaY / 10;
      if (this.translate < 0.5) {
        this.translate = 0.5;
      }
      e.preventDefault();
    };

    canvas.onpointerdown = e => {
      this.mouse.lastX = e.clientX;
      this.mouse.lastY = e.clientY;

      this.rotationStart[0] = this.rotation[0];
      this.rotationStart[1] = this.rotation[1];

      canvas.setPointerCapture(e.pointerId);
      e.preventDefault();
    };

    canvas.onpointermove = e => {
      if (e.buttons) {
        const dX = e.clientX - this.mouse.lastX;
        const dY = e.clientY - this.mouse.lastY;

        this.rotation[0] = this.rotationStart[0] + dY / 100;
        this.rotation[1] = this.rotationStart[1] + dX / 100;
      }
    };

    canvas.ondragover = e => {
      e.dataTransfer.dropEffect = 'link';
      e.preventDefault();
    };

    canvas.ondrop = e => {
      e.preventDefault();
      if (e.dataTransfer.files && e.dataTransfer.files.length === 1) {
        loadGLTF(new Promise(resolve => {
          const reader = new window.FileReader();
          reader.onload = ev => resolve(ev.target.result);
          reader.readAsArrayBuffer(e.dataTransfer.files[0]);
        }), this.gl).then(scenes => (this.scenes = scenes));
      }
    };
  }

  onInitialize({gl, canvas}) {
    setParameters(gl, {
      depthTest: true,
      blend: false,
    });

    this.gl = gl;
    if (this.modelFile) {
      // options for unit testing
      const options = {
        pbrDebug: false,
        pbrIbl: false
      };
      loadGLTF(this.modelFile, this.gl, options).then(scenes => (this.scenes = scenes));
    } else {
      const modelSelector = document.getElementById("modelSelector");
      loadGLTF(GLTF_BASE_URL + modelSelector.value, this.gl).then(scenes => (this.scenes = scenes));

      modelSelector.onchange = event => {
        loadGLTF(GLTF_BASE_URL + modelSelector.value, this.gl).then(scenes => (this.scenes = scenes));
      };

      loadModelList().then(models => addModelsToDropdown(models, modelSelector));
    }

    const showSelector = document.getElementById("showSelector");
    if (showSelector) {
      showSelector.onchange = event => {
        const value = showSelector.value.split(" ").map(x => parseFloat(x));
        this.u_ScaleDiffBaseMR = value.slice(0, 4);
        this.u_ScaleFGDSpec = value.slice(4);
      };
    }

    this.initalizeEventHandling(canvas);
  }

  onRender({gl, tick, width, height, aspect}) {
    gl.viewport(0, 0, width, height);
    clear(gl, {color: [0.2, 0.2, 0.2, 1.0], depth: true});

    const [pitch, roll] = this.rotation;
    const cameraPos = [
      -this.translate * Math.sin(roll) * Math.cos(-pitch),
      -this.translate * Math.sin(-pitch),
      this.translate * Math.cos(roll) * Math.cos(-pitch)
    ];

    const uView = new Matrix4()
      .translate([0, 0, -this.translate])
      .rotateX(pitch)
      .rotateY(roll);

    const uProjection = new Matrix4().perspective({fov: radians(40), aspect, near: 0.1, far: 9000});

    if (!this.scenes.length) return false;

    let success = true;

    this.scenes[0].traverse((model, {worldMatrix}) => {
      // In glTF, meshes and primitives do no have their own matrix.
      const u_MVPMatrix = new Matrix4(uProjection).multiplyRight(uView).multiplyRight(worldMatrix);
      success = success && model.draw({
        uniforms: {
          u_Camera: cameraPos,
          u_MVPMatrix,
          u_ModelMatrix: worldMatrix,
          u_NormalMatrix: new Matrix4(worldMatrix).invert().transpose(),

          u_ScaleDiffBaseMR: this.u_ScaleDiffBaseMR,
          u_ScaleFGDSpec: this.u_ScaleFGDSpec,
        }
      });
    });

    return success;
  }
}

const animationLoop = new AnimationLoop(new DemoApp());

animationLoop.getInfo = () => INFO_HTML;

export default animationLoop;

/* global window */
if (typeof window !== 'undefined' && !window.website) {
  animationLoop.start();

  const infoDiv = document.createElement('div');
  infoDiv.innerHTML = animationLoop.getInfo();
  document.body.appendChild(infoDiv);
}
<|endoftext|>


<commit_before>function fetchPreview(url) {

    $('#host').hide("drop", {  }, 150, function() {
        $('#loading').show("drop", { }, 150);

        //$.getJSON(url.url + '.jsonp' + url.parameters + "&callback=?");
        $.ajax({
            url: url.url + '.html' + url.parameters,
            success: function(data) {
                $("#host").html(data);

                $('#loading').hide("drop", { }, 150, function() {
                    $('#host').show("drop", { }, 150);

                });
            },
            error: function(xhr, status, errorThrown) {
                $("#host").html('
Oops!

There was a problem with your request:
' + status + '');

                $('#loading').hide("drop", { }, 150, function() {
                    $('#host').show("drop", { }, 150);

                });
            }
        });
    });
}

function openHelp(helpId) {
    var $dialog = $('

')
    .html(help[helpId].details)
    .dialog({
        autoOpen: false,
        title: help[helpId].title,
        show: 'drop',
        hide: 'drop'
    });
    $dialog.dialog('open');
}

function renderSettings() {
    var style = '';
    if(viewModel.chosenStyle() === 'yes') {
        style="styled"
    } else {
        style='unstyled'
    };
    $('#settings').html('Current Settings: ' + viewModel.chosenLimit().label + ' ' + viewModel.chosenCollection().collectionName + ' in ' + viewModel.chosenFormat() + ' format and ' +  style);
}
/* Clipboard from http://code.google.com/p/zeroclipboard/ */
function initializeClipboard() {
		var clip = null;

		// function $(id) { return document.getElementById(id); }
		//

			clip = new ZeroClipboard.Client();
			clip.setHandCursor( true );

			clip.addEventListener('load', function (client) {
				//alert("Flash movie loaded and ready.");
			});

			clip.addEventListener('mouseOver', function (client) {
				// update the text on mouse over
				clip.setText( $('#embed').val() );
			});

			clip.addEventListener('complete', function (client, text) {
				//alert("Copied text to clipboard: " + text );
				 $('#embed').effect("highlight", {}, 1500);

			});

			clip.glue( 'd_clip_button', 'd_clip_container' );

		// function debugstr(msg) {
		// 	var p = document.createElement('p');
		// 	p.innerHTML = msg;
		// 	$('d_debug').appendChild(p);
		// }

}

// Initialization

$(function() {
    ko.applyBindings(viewModel);

    	viewModel.url = ko.dependentObservable( function() {
	        latestUrl = 'http://localhost:9000/people/smithjm/publications/' + this.chosenLimit().label;
	        latestParams = '?collections='
		        + this.chosenCollection().collectionName
		        + '&formatting=' + this.chosenFormat()
		        + '&style=' + this.chosenStyle();

	        fetchPreview({url: latestUrl, parameters: latestParams});
	        var script = '


<commit_before>/*jslint forin:true sub:true anon:true, sloppy:true, stupid:true nomen:true, node:true continue:true*/

/*
 * Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */

var log4js = require("log4js");
var fs = require("fs");
var path = require("path");
var arrowConfig = require('../../config/config');

/**
 * @constructor
 * @param config
 */
function engineManager(config) {
    this.logger = log4js.getLogger("EngineManager");
    this.config = config || arrowConfig;

}
/**
 * get engine seed fs path
 * @return {*}
 */
engineManager.prototype.getEngineSeed = function () {
    return path.join(this.config['arrowModuleRoot'], "lib/engine/interface/engine-seed.js");
};
/**
 * get engine runner fs path
 * @return {*}
 */
engineManager.prototype.getEngineRunner = function () {
    return path.join(this.config['arrowModuleRoot'], "lib/engine/interface/engine-runner.js");
};
/**
 * get test seed by engine name
 * @param engineName
 * @return {*}
 */
engineManager.prototype.getTestSeed = function (engineName) {
    var self = this,
        engine = engineName || "yui",
        engineFloder,
        seedfile;
    if (engine && engine !== "yui") {
        try {
            engineFloder = path.join(self.config['arrowModuleRoot'], "lib/engine");
            seedfile = path.join(engineFloder, engine, engine + "-seed.js");

            if (!fs.statSync(seedfile).isFile()) {
                throw new Error("test seed not exist");
            }
            return seedfile;
        } catch (e) {
            this.logger.error("Finding engine seed" + engineName + " error , maybe it is not supported yet");
            throw e;
        }
    }
    return self.config['testSeed']; //default seed
};
/**
 * get test runner by engine name
 * @param engineName
 * @return {*}
 */
engineManager.prototype.getTestRunner = function (engineName) {
    // some changes for engine
    var self = this,
        engine = engineName || "yui",
        engineFloder,
        runnerfile;
    if (engine && engine !== "yui") {
        try {
            engineFloder = path.join(self.config['arrowModuleRoot'], "lib/engine");
            runnerfile = path.join(engineFloder, engine, engine + "-runner.js");

            if (!fs.statSync(runnerfile).isFile()) {
                throw new Error("test seed or runner not exist");
            }
            return runnerfile;
        } catch (e) {
            this.logger.error("Finding engine runner" + engineName + " error , maybe it is not supported yet");
            throw e;
        }
    }
    return self.config['testRunner'];  //default runner
};

/**
 * parse to get config as json by given string
 * @param string of config,it could be fs path or just config-string
 * @return {*}
 */
engineManager.prototype.getConfigJason = function (configjson) {

    if (!configjson) return {};
    var config;
    if (typeof configjson === "string") {
        try {// it is a path
            config = fs.readFileSync(path.resolve(configjson), 'utf8');
            try {
                config = JSON.parse(config);
                return config;
            } catch (er) {
                // maybe key-value formart file
                this.logger.debug("Please confirm the config file " + configjson + " exist and is json formart");
                return {};
            }
        } catch (e) {
            // no such file
            try {
                config = JSON.parse(configjson);
                return config;
            } catch (ex) {
                this.logger.debug("Please confirm the config string " + configjson + " exist and is json formart");
                return {};
            }
        }
    } else if (typeof configjson === "object") {
        return configjson;
    } else {
        this.logger.error("Please confirm the config " + configjson + " is object or json formart file/string");
        return {};
    }
};

module.exports = engineManager;<commit_msg>debug -> trace<commit_after>/*jslint forin:true sub:true anon:true, sloppy:true, stupid:true nomen:true, node:true continue:true*/

/*
 * Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */

var log4js = require("log4js");
var fs = require("fs");
var path = require("path");
var arrowConfig = require('../../config/config');

/**
 * @constructor
 * @param config
 */
function engineManager(config) {
    this.logger = log4js.getLogger("EngineManager");
    this.config = config || arrowConfig;

}
/**
 * get engine seed fs path
 * @return {*}
 */
engineManager.prototype.getEngineSeed = function () {
    return path.join(this.config['arrowModuleRoot'], "lib/engine/interface/engine-seed.js");
};
/**
 * get engine runner fs path
 * @return {*}
 */
engineManager.prototype.getEngineRunner = function () {
    return path.join(this.config['arrowModuleRoot'], "lib/engine/interface/engine-runner.js");
};
/**
 * get test seed by engine name
 * @param engineName
 * @return {*}
 */
engineManager.prototype.getTestSeed = function (engineName) {
    var self = this,
        engine = engineName || "yui",
        engineFloder,
        seedfile;
    if (engine && engine !== "yui") {
        try {
            engineFloder = path.join(self.config['arrowModuleRoot'], "lib/engine");
            seedfile = path.join(engineFloder, engine, engine + "-seed.js");

            if (!fs.statSync(seedfile).isFile()) {
                throw new Error("test seed not exist");
            }
            return seedfile;
        } catch (e) {
            this.logger.error("Finding engine seed" + engineName + " error , maybe it is not supported yet");
            throw e;
        }
    }
    return self.config['testSeed']; //default seed
};
/**
 * get test runner by engine name
 * @param engineName
 * @return {*}
 */
engineManager.prototype.getTestRunner = function (engineName) {
    // some changes for engine
    var self = this,
        engine = engineName || "yui",
        engineFloder,
        runnerfile;
    if (engine && engine !== "yui") {
        try {
            engineFloder = path.join(self.config['arrowModuleRoot'], "lib/engine");
            runnerfile = path.join(engineFloder, engine, engine + "-runner.js");

            if (!fs.statSync(runnerfile).isFile()) {
                throw new Error("test seed or runner not exist");
            }
            return runnerfile;
        } catch (e) {
            this.logger.error("Finding engine runner" + engineName + " error , maybe it is not supported yet");
            throw e;
        }
    }
    return self.config['testRunner'];  //default runner
};

/**
 * parse to get config as json by given string
 * @param string of config,it could be fs path or just config-string
 * @return {*}
 */
engineManager.prototype.getConfigJason = function (configjson) {

    if (!configjson) return {};
    var config;
    if (typeof configjson === "string") {
        try {// it is a path
            config = fs.readFileSync(path.resolve(configjson), 'utf8');
            try {
                config = JSON.parse(config);
                return config;
            } catch (er) {
                // maybe key-value formart file
                this.logger.trace("Please confirm the config file " + configjson + " exist and is json formart");
                return {};
            }
        } catch (e) {
            // no such file
            try {
                config = JSON.parse(configjson);
                return config;
            } catch (ex) {
                this.logger.trace("Please confirm the config string " + configjson + " exist and is json formart");
                return {};
            }
        }
    } else if (typeof configjson === "object") {
        return configjson;
    } else {
        this.logger.error("Please confirm the config " + configjson + " is object or json formart file/string");
        return {};
    }
};

module.exports = engineManager;<|endoftext|>


<commit_before>import React from 'react';

import { TimeText } from 'es6!display/time';
import { RandomLoadingMessage } from 'es6!display/loading';
import { BuildWidget } from 'es6!display/builds';
import { Grid } from 'es6!display/grid';
import APINotLoaded from 'es6!display/not_loaded';
import ChangesPage from 'es6!display/page_chrome';
import colors from 'es6!utils/colors';

import * as api from 'es6!server/api';

/**
 * Page that shows the builds associated with a single node, across all projects.
 */
var NodePage = React.createClass({

  getInitialState: function() {
    return {
      nodeJobs: null,
      nodeDetails: null,
    }
  },

  componentDidMount: function() {
    var nodeID = this.props.node_id;

    var detailsEndpoint = `/api/0/nodes/${nodeID}/`;
    var jobsEndpoint = `/api/0/nodes/${nodeID}/jobs/`;
    api.fetch(this, {
      nodeDetails: detailsEndpoint,
      nodeJobs: jobsEndpoint,
    })
  },

  render: function() {
    if (!api.mapIsLoaded(this.state, ['nodeJobs', 'nodeDetails'])) {
      return <APINotLoaded
        stateMap={this.state}
        stateMapKeys={['nodeJobs', 'nodeDetails']}
      />;
    }

    var cellClasses = ['nowrap buildWidgetCell', 'nowrap', 'nowrap', 'wide', 'nowrap'];
    var headers = [ 'Build', 'Phab.', 'Project', 'Name', 'Committed'];

    var grid_data = _.map(this.state.nodeJobs.getReturnedData(), d => {
      var project_href = "/v2/project/" + d.project.slug;
      return [
        <BuildWidget build={d.build}/>,
        d.build.source.id.substr(0, 7),
        {d.project.name},
        d.build.name,
        <TimeText time={d.build.dateCreated} />];
    })

    var nodeDetails = this.state.nodeDetails.getReturnedData();
    var style = {
      padding: 10,
      marginBottom: 20,
      backgroundColor: colors.lightestGray
    };

    return <ChangesPage>

Node ID: {nodeDetails.id}

First Seen: <TimeText time={nodeDetails.dateCreated} />

        <Grid
          colnum={5}
          data={grid_data}
          cellClasses={cellClasses}
          headers={headers}
        />

      </ChangesPage>;
  }
});

export default NodePage;
<commit_msg>Fix compile-static<commit_after>import React from 'react';

import { TimeText } from 'es6!display/time';
import { RandomLoadingMessage } from 'es6!display/loading';
import { BuildWidget } from 'es6!display/changes/builds';
import { Grid } from 'es6!display/grid';
import APINotLoaded from 'es6!display/not_loaded';
import ChangesPage from 'es6!display/page_chrome';
import colors from 'es6!utils/colors';

import * as api from 'es6!server/api';

/**
 * Page that shows the builds associated with a single node, across all projects.
 */
var NodePage = React.createClass({

  getInitialState: function() {
    return {
      nodeJobs: null,
      nodeDetails: null,
    }
  },

  componentDidMount: function() {
    var nodeID = this.props.node_id;

    var detailsEndpoint = `/api/0/nodes/${nodeID}/`;
    var jobsEndpoint = `/api/0/nodes/${nodeID}/jobs/`;
    api.fetch(this, {
      nodeDetails: detailsEndpoint,
      nodeJobs: jobsEndpoint,
    })
  },

  render: function() {
    if (!api.mapIsLoaded(this.state, ['nodeJobs', 'nodeDetails'])) {
      return <APINotLoaded
        stateMap={this.state}
        stateMapKeys={['nodeJobs', 'nodeDetails']}
      />;
    }

    var cellClasses = ['nowrap buildWidgetCell', 'nowrap', 'nowrap', 'wide', 'nowrap'];
    var headers = [ 'Build', 'Phab.', 'Project', 'Name', 'Committed'];

    var grid_data = _.map(this.state.nodeJobs.getReturnedData(), d => {
      var project_href = "/v2/project/" + d.project.slug;
      return [
        <BuildWidget build={d.build}/>,
        d.build.source.id.substr(0, 7),
        {d.project.name},
        d.build.name,
        <TimeText time={d.build.dateCreated} />];
    })

    var nodeDetails = this.state.nodeDetails.getReturnedData();
    var style = {
      padding: 10,
      marginBottom: 20,
      backgroundColor: colors.lightestGray
    };

    return <ChangesPage>

Node ID: {nodeDetails.id}

First Seen: <TimeText time={nodeDetails.dateCreated} />

        <Grid
          colnum={5}
          data={grid_data}
          cellClasses={cellClasses}
          headers={headers}
        />

      </ChangesPage>;
  }
});

export default NodePage;
<|endoftext|>


<commit_before>import React, {Component} from 'react';
import {withRouter, Link} from 'react-router-dom';
import {Nav, Navbar, NavItem} from 'react-bootstrap';

import './App.css';
import Routes from './Routes';
import {CognitoUserPool,} from 'amazon-cognito-identity-js';
import AWS from 'aws-sdk';
import config from './config.js';
import RouteNavItem from './components/RouteNavItem';
import {connect} from "react-redux";
import {bindActionCreators} from "redux";
import PropTypes from 'prop-types';
import * as UserActions from "./actions/UserActions";

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            userToken: null,
            isLoadingUserToken: true,
        };
    }

    handleLogout = (event) => {
        const currentUser = this.getCurrentUser();

        if (currentUser !== null) {
            currentUser.signOut();
        }
        if (AWS.config.credentials) {
            AWS.config.credentials.clearCachedId();
        }
        this.updateUserToken(null);
        this.props.history.push('/login');
    };

    updateUserToken = (userToken) => {
        this.setState({
            userToken: userToken
        });
        this.props.executeUpdateUserToken(userToken);
    };

    handleNavLink = (event) => {
        event.preventDefault();
        this.props.history.push(event.currentTarget.getAttribute('href'));
    };

    getCurrentUser() {
        this.props.executeFetchCurrentUser();

        const userPool = new CognitoUserPool({
            UserPoolId: config.cognito.USER_POOL_ID,
            ClientId: config.cognito.APP_CLIENT_ID
        });
        return userPool.getCurrentUser();
    }

    getUserToken(currentUser) {
        return new Promise((resolve, reject) => {
            currentUser.getSession(function (err, session) {
                if (err) {
                    reject(err);
                    return;
                }
                resolve(session.getIdToken().getJwtToken());
            });
        });
    }

    async componentDidMount() {
        const currentUser = this.getCurrentUser();

        if (currentUser === null) {
            this.setState({isLoadingUserToken: false});
            return;
        }

        try {
            const userToken = await this.getUserToken(currentUser);
            this.updateUserToken(userToken);
        }
        catch (e) {
            alert(e);
        }

        this.setState({isLoadingUserToken: false});
    }

    render() {
        const childProps = {
            userToken: this.state.userToken,
            updateUserToken: this.updateUserToken,
        };

        if (this.props.isLoadingUserToken) {
            return false;
        }

        return (

                <Navbar fluid collapseOnSelect>
                    <Navbar.Header>
                        <Navbar.Brand>
                            <Link to="/">Exercises</Link>
                        </Navbar.Brand>
                        <Navbar.Toggle/>
                    </Navbar.Header>
                    <Navbar.Collapse>

                            {this.state.userToken
                                ? <NavItem onClick={this.handleLogout}>Logout</NavItem>
                                : [<RouteNavItem key={1} onClick={this.handleNavLink}
                                                 href="/signup">Signup</RouteNavItem>,
                                    <RouteNavItem key={2} onClick={this.handleNavLink}
                                                  href="/login">Login</RouteNavItem>]}

                    </Navbar.Collapse>
                </Navbar>
                <Routes childProps={childProps}/>

        );
    }
}

App.propTypes = {
    isLoadingUserToken: PropTypes.bool,
    userToken: PropTypes.string,
    currentUser: PropTypes.object,
    executeFetchCurrentUser: PropTypes.func,
    executeUpdateUserToken: PropTypes.func
};

function mapDispatchToProps(dispatch) {
    return bindActionCreators({
        executeFetchCurrentUser: UserActions.fetchCurrentUser,
        executeUpdateUserToken: UserActions.updateUserToken
    }, dispatch);
}

function mapStateToProps(state) {
    return {
        isLoadingUserToken: state.user.isLoadingUserToken,
        userToken: state.user.userToken,
        currentUser: state.user.currentUser
    }
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App));<commit_msg>nochmal zu lokalem State zurueck, da Komponente nicht angezeigt wird, wenn der User vorher ausgeloggt hat<commit_after>import React, {Component} from 'react';
import {withRouter, Link} from 'react-router-dom';
import {Nav, Navbar, NavItem} from 'react-bootstrap';

import './App.css';
import Routes from './Routes';
import {CognitoUserPool,} from 'amazon-cognito-identity-js';
import AWS from 'aws-sdk';
import config from './config.js';
import RouteNavItem from './components/RouteNavItem';
import {connect} from "react-redux";
import {bindActionCreators} from "redux";
import PropTypes from 'prop-types';
import * as UserActions from "./actions/UserActions";

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            userToken: null,
            isLoadingUserToken: true,
        };
    }

    handleLogout = (event) => {
        const currentUser = this.getCurrentUser();

        if (currentUser !== null) {
            currentUser.signOut();
        }
        if (AWS.config.credentials) {
            AWS.config.credentials.clearCachedId();
        }
        this.updateUserToken(null);
        this.props.history.push('/login');
    };

    updateUserToken = (userToken) => {
        this.setState({
            userToken: userToken
        });
        this.props.executeUpdateUserToken(userToken);
    };

    handleNavLink = (event) => {
        event.preventDefault();
        this.props.history.push(event.currentTarget.getAttribute('href'));
    };

    getCurrentUser() {
        this.props.executeFetchCurrentUser();

        const userPool = new CognitoUserPool({
            UserPoolId: config.cognito.USER_POOL_ID,
            ClientId: config.cognito.APP_CLIENT_ID
        });
        return userPool.getCurrentUser();
    }

    getUserToken(currentUser) {
        return new Promise((resolve, reject) => {
            currentUser.getSession(function (err, session) {
                if (err) {
                    reject(err);
                    return;
                }
                resolve(session.getIdToken().getJwtToken());
            });
        });
    }

    async componentDidMount() {
        const currentUser = this.getCurrentUser();

        if (currentUser === null) {
            this.setState({isLoadingUserToken: false});
            return;
        }

        try {
            const userToken = await this.getUserToken(currentUser);
            this.updateUserToken(userToken);
        }
        catch (e) {
            alert(e);
        }

        this.setState({isLoadingUserToken: false});
    }

    render() {
        const childProps = {
            userToken: this.state.userToken,
            updateUserToken: this.updateUserToken,
        };

        if (this.state.isLoadingUserToken) {
            return false;
        }

        return (

                <Navbar fluid collapseOnSelect>
                    <Navbar.Header>
                        <Navbar.Brand>
                            <Link to="/">Exercises</Link>
                        </Navbar.Brand>
                        <Navbar.Toggle/>
                    </Navbar.Header>
                    <Navbar.Collapse>

                            {this.state.userToken
                                ? <NavItem onClick={this.handleLogout}>Logout</NavItem>
                                : [<RouteNavItem key={1} onClick={this.handleNavLink}
                                                 href="/signup">Signup</RouteNavItem>,
                                    <RouteNavItem key={2} onClick={this.handleNavLink}
                                                  href="/login">Login</RouteNavItem>]}

                    </Navbar.Collapse>
                </Navbar>
                <Routes childProps={childProps}/>

        );
    }
}

App.propTypes = {
    isLoadingUserToken: PropTypes.bool,
    userToken: PropTypes.string,
    currentUser: PropTypes.object,
    executeFetchCurrentUser: PropTypes.func,
    executeUpdateUserToken: PropTypes.func
};

function mapDispatchToProps(dispatch) {
    return bindActionCreators({
        executeFetchCurrentUser: UserActions.fetchCurrentUser,
        executeUpdateUserToken: UserActions.updateUserToken
    }, dispatch);
}

function mapStateToProps(state) {
    return {
        isLoadingUserToken: state.user.isLoadingUserToken,
        userToken: state.user.userToken,
        currentUser: state.user.currentUser
    }
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App));<|endoftext|>


<commit_before>/**
 * npm pre-install script.
 *
 * This script checks if the installed npm-version matches the required engine
 * defined in the package.json.
 */

var exec = require('child_process').exec;
var project = require('./../package.json');

// Validate npm version before installing Sails.
if (project.engines && project.engines.npm) exec('npm -v', validateNpmVersion);

/**
 * Callback for the 'npm -v' execution.
 * @param  err    Possible command execution error.
 * @param  stdout Command execution result.
 */
function validateNpmVersion(err, stdout) {

  // Throw-up process errors.
  if (err) return exitWithMessage(err);

  // Parse Semver for current and required.
  var semver = getSemver(stdout);
  var requiredNpmSemver = getSemver(project.engines.npm, true);

  // Get only the release numbering.
  var version = semver && semver[1];
  var requiredNpmVersion = requiredNpmSemver && requiredNpmSemver[1];

  // If no version is identified, stop install.
  if (!version) exitWithMessage([
    'Unable to check your npm-version',
    '',
    'Please reinstall npm to use Sails.js'
  ]);

  // Handle old npm installations.
  if (!satisfiesVersion(version, requiredNpmVersion)) exitWithMessage([
    'Your current npm version (' + version + ') is not supported:',
    'Sails requires at least version ' + project.engines.npm,
    '',
    'Try uploading npm before installing Sails.'
  ]);

  console.log('Sails.js Installation: Checking npm-version successful');

  // Exit process with success.
  process.exit(0);
}

/**
 * Exit proccess with a given error beautifully.
 */
function exitWithMessage(err, code) {

  // Exit error header.
  console.log('\033[31mSails.js Installation - Error');
  console.log('--------------------------------------------------------\033[00m');

  // Exit (possibly multiple) error lines.
  (typeof err === 'string' ? [err] : err).forEach(function (err) {
    console.log(err);
  });

  // Exit error footer.
  console.log('\033[31m--------------------------------------------------------');

  // Exit processing with a 1 (error) default code.
  process.exit(code === undefined ? 1 : code);
}

/**
 * Parse version string into semver array.
 * @param {string} version
 * @param {boolean} range If version is a range, make sure to consider up-front
 *                        specification.
 * @return {Array}  An array with the version's parts or null if not valid.
 */
function getSemver(version, range) {

  // Fulfil possibly missing zeros, if range is allowed.
  if (range) {
    version = version.split('.');
    var missing = 3 - version.length;

    for(;missing > 0; missing--) {
      version.push(0);
    }

    version = version.join('.');
  }

  var versionRegex = '(([0-9]{1,})\.([0-9]{1,})\.([0-9]{1,}))(?:-?(.*))';
  var regex = new RegExp('^' + (range ? '(?:.*)' : '') + versionRegex + '$');

  return version.replace(/\s+/g, '').match(regex);
}

/**
 * Makes a simple '>=' version comparison.
 * @param  {string} version
 * @param  {string} compare
 * @return {boolean}
 */
function satisfiesVersion(version, compare) {
  var version = version.split('.');
  var compare = compare.split('.');
  var satisfied;

  return compare.every(function (value, i) {
    if (satisfied !== undefined) return satisfied;
    if (version[i] > value) return satisfied = true;
    if (version[i] < value) return satisfied = false;

    return true;
  }) && satisfied !== false;
}
<commit_msg>Fix regex escaping<commit_after>/**
 * npm pre-install script.
 *
 * This script checks if the installed npm-version matches the required engine
 * defined in the package.json.
 */

var exec = require('child_process').exec;
var project = require('./../package.json');

// Validate npm version before installing Sails.
if (project.engines && project.engines.npm) exec('npm -v', validateNpmVersion);

/**
 * Callback for the 'npm -v' execution.
 * @param  err    Possible command execution error.
 * @param  stdout Command execution result.
 */
function validateNpmVersion(err, stdout) {

  // Throw-up process errors.
  if (err) return exitWithMessage(err);

  // Parse Semver for current and required.
  var semver = getSemver(stdout);
  var requiredNpmSemver = getSemver(project.engines.npm, true);

  // Get only the release numbering.
  var version = semver && semver[1];
  var requiredNpmVersion = requiredNpmSemver && requiredNpmSemver[1];

  // If no version is identified, stop install.
  if (!version) exitWithMessage([
    'Unable to check your npm-version',
    '',
    'Please reinstall npm to use Sails.js'
  ]);

  // Handle old npm installations.
  if (!satisfiesVersion(version, requiredNpmVersion)) exitWithMessage([
    'Your current npm version (' + version + ') is not supported:',
    'Sails requires at least version ' + project.engines.npm,
    '',
    'Try uploading npm before installing Sails.'
  ]);

  console.log('Sails.js Installation: Checking npm-version successful');

  // Exit process with success.
  process.exit(0);
}

/**
 * Exit proccess with a given error beautifully.
 */
function exitWithMessage(err, code) {

  // Exit error header.
  console.log('\033[31mSails.js Installation - Error');
  console.log('--------------------------------------------------------\033[00m');

  // Exit (possibly multiple) error lines.
  (typeof err === 'string' ? [err] : err).forEach(function (err) {
    console.log(err);
  });

  // Exit error footer.
  console.log('\033[31m--------------------------------------------------------');

  // Exit processing with a 1 (error) default code.
  process.exit(code === undefined ? 1 : code);
}

/**
 * Parse version string into semver array.
 * @param {string} version
 * @param {boolean} range If version is a range, make sure to consider up-front
 *                        specification.
 * @return {Array}  An array with the version's parts or null if not valid.
 */
function getSemver(version, range) {

  // Fulfil possibly missing zeros, if range is allowed.
  if (range) {
    version = version.split('.');
    var missing = 3 - version.length;

    for(;missing > 0; missing--) {
      version.push(0);
    }

    version = version.join('.');
  }

  var versionRegex = '(([0-9]{1,})\\.([0-9]{1,})\\.([0-9]{1,}))(?:-?(.*))';
  var regex = new RegExp('^' + (range ? '(?:.*)' : '') + versionRegex + '$');

  return version.replace(/\s+/g, '').match(regex);
}

/**
 * Makes a simple '>=' version comparison.
 * @param  {string} version
 * @param  {string} compare
 * @return {boolean}
 */
function satisfiesVersion(version, compare) {
  var version = version.split('.');
  var compare = compare.split('.');
  var satisfied;

  return compare.every(function (value, i) {
    if (satisfied !== undefined) return satisfied;
    if (version[i] > value) return satisfied = true;
    if (version[i] < value) return satisfied = false;

    return true;
  }) && satisfied !== false;
}
<|endoftext|>


<commit_before>const _ = require('lodash');

const selection = [
    {
        title: 'Ad | Play-Doh Modeling Compound',
        link: 'https://amzn.to/2lWpeo5',
        content: ' 10 cans of creative fun kids can get creative with just the right colors They need in this Play Doh 10 pack of 2 ounce cans',
        contentSnippet: '10 cans of creative fun kids can get creative with just the right colors They need in this Play Doh 10 pack of 2 ounce cans',
        publishedDate: '2019-09-11T12:00:00.000Z',
        categories: [],
        author: 'Play-Doh'
    },
    {
        title: 'Ad | All-new Echo (3rd Gen) - Smart speaker with Alexa - Twilight Blue',
        link: 'https://amzn.to/2ntWMu4',
        content: ' Meet Echo - Echo (3rd Gen) has new premium speakers powered by Dolby to play 360° audio with crisp vocals and dynamic bass response.',
        contentSnippet: 'Meet Echo - Echo (3rd Gen) has new premium speakers powered by Dolby to play 360° audio with crisp vocals and dynamic bass response.',
        publishedDate: '2019-09-11T12:00:00.000Z',
        categories: [],
        author: 'Amazon'
    }
];

const showAdThreshold = 1000;
let requestsSinceLastAd = 0;

const getAd = function () {
    return _.sample(selection);
};

const shouldShowAd = function (req) {
    if (req.query.support) {
        requestsSinceLastAd += 1;

        if (requestsSinceLastAd >= showAdThreshold) {
            requestsSinceLastAd = 0;
            return true;
        }
    }

    return false;
};

const addAds = function (req, response) {
    if (shouldShowAd(req)) {
        if (req.query.callback) {
            // eslint-disable-next-line no-param-reassign
            response = response.match(new RegExp(`${req.query.callback}\\((.*)\\)`))[1];
        }

        const data = JSON.parse(response);

        data.responseData.feed.entries.pop();
        data.responseData.feed.entries.unshift(getAd());
        // eslint-disable-next-line no-param-reassign
        response = JSON.stringify(data);

        if (req.query.callback) {
            // eslint-disable-next-line no-param-reassign
            response = `${req.query.callback}(${response});`;
        }
    }

    return response;
};

module.exports = {
    getAd, shouldShowAd, addAds
};
<commit_msg>Log the rendered ad<commit_after>const _ = require('lodash');

const selection = [
    {
        title: 'Ad | Play-Doh Modeling Compound',
        link: 'https://amzn.to/2lWpeo5',
        content: ' 10 cans of creative fun kids can get creative with just the right colors They need in this Play Doh 10 pack of 2 ounce cans',
        contentSnippet: '10 cans of creative fun kids can get creative with just the right colors They need in this Play Doh 10 pack of 2 ounce cans',
        publishedDate: '2019-09-11T12:00:00.000Z',
        categories: [],
        author: 'Play-Doh'
    },
    {
        title: 'Ad | All-new Echo (3rd Gen) - Smart speaker with Alexa - Twilight Blue',
        link: 'https://amzn.to/2ntWMu4',
        content: ' Meet Echo - Echo (3rd Gen) has new premium speakers powered by Dolby to play 360° audio with crisp vocals and dynamic bass response.',
        contentSnippet: 'Meet Echo - Echo (3rd Gen) has new premium speakers powered by Dolby to play 360° audio with crisp vocals and dynamic bass response.',
        publishedDate: '2019-09-11T12:00:00.000Z',
        categories: [],
        author: 'Amazon'
    }
];

const showAdThreshold = 1000;
let requestsSinceLastAd = 0;

const getAd = function () {
    return _.sample(selection);
};

const shouldShowAd = function (req) {
    if (req.query.support) {
        requestsSinceLastAd += 1;

        if (requestsSinceLastAd >= showAdThreshold) {
            requestsSinceLastAd = 0;
            return true;
        }
    }

    return false;
};

const addAds = function (req, response) {
    if (shouldShowAd(req)) {
        if (req.query.callback) {
            // eslint-disable-next-line no-param-reassign
            response = response.match(new RegExp(`${req.query.callback}\\((.*)\\)`))[1];
        }

        const data = JSON.parse(response);
        const ad = getAd();

        data.responseData.feed.entries.pop();
        data.responseData.feed.entries.unshift(ad);
        // eslint-disable-next-line no-param-reassign
        response = JSON.stringify(data);

        if (req.query.callback) {
            // eslint-disable-next-line no-param-reassign
            response = `${req.query.callback}(${response});`;
        }

        console.log(`Embedded ad: ${JSON.stringify(ad)}`);
    }

    return response;
};

module.exports = {
    getAd, shouldShowAd, addAds
};
<|endoftext|>