var path = require('path');
var HtmlWebpackPlugin = require('../..');
var webpackMajorVersion = require('webpack/package.json').version.split('.')[0];
module.exports = {
  context: __dirname,
  entry: './example.js',
  output: {
    path: path.join(__dirname, 'dist/webpack-' + webpackMajorVersion),
    publicPath: '',
    filename: 'bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin({
      // NOTE if you pass plain object it will be passed as is. no default values there, so be aware!
      // for implementation detail, please see index.js and search for "userOptions" variable
      templateParameters: (compilation, assets, assetTags, options) => {
        return {
          compilation,
          webpackConfig: compilation.options,
          htmlWebpackPlugin: {
            tags: assetTags,
            files: assets,
            options
          },
          'foo': 'bar'
        };
      },
      template: 'index.ejs'
    })
  ]
};

var path = require('path');
var HtmlWebpackPlugin = require('../..');
var webpackMajorVersion = require('webpack/package.json').version.split('.')[0];
module.exports = {
  context: __dirname,
  entry: './example.js',
  output: {
    path: path.join(__dirname, 'dist/webpack-' + webpackMajorVersion),
    publicPath: '',
    filename: 'bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin({
      // If you pass a plain object, it will be merged with the default values
      // (New in version 4)
      templateParameters: {
        'foo': 'bar'
      },
      // Or if you want full control, pass a function
      // templateParameters: (compilation, assets, assetTags, options) => {
      //   return {
      //     compilation,
      //     webpackConfig: compilation.options,
      //     htmlWebpackPlugin: {
      //       tags: assetTags,
      //       files: assets,
      //       options
      //     },
      //     'foo': 'bar'
      //   };
      // },
      template: 'index.ejs'
    })
  ]
};

Update example to account for object merging


(function () {
  'use strict';

  moj.Modules.LabelSelect = {
    el: '.js-LabelSelect',

    init: function () {
      this.cacheEls();
      this.bindEvents();

      // keep current state
      this.$options.each(function () {
        var $el = $(this);
        if($el.is(':checked')){
          $el.parent().addClass('is-selected');
        }
      });
    },

    bindEvents: function () {
      this.$options
        .on('change', function () {
          var $el = $(this),
              $parent = $el.parent('label');

          // clear out all other selections on radio elements
          if ($el.attr('type') === 'radio') {
            $('[name=' + $el.attr('name') + ']').parent('label').removeClass('is-selected');
          }

          // set is-selected state on check
          if($el.is(':checked')){
            $parent.addClass('is-selected');
          } else {
            $parent.removeClass('is-selected');
          }
        });
    },

    cacheEls: function () {
      this.$options = $(this.el).find('input[type=radio], input[type=checkbox]');
    }
  };
}());

(function () {
  'use strict';

  moj.Modules.LabelSelect = {
    el: '.js-LabelSelect',

    init: function () {
      _.bindAll(this, 'render');
      this.cacheEls();
      this.bindEvents();
    },

    bindEvents: function () {
      this.$options
        .on('change', function () {
          var $el = $(this),
              $parent = $el.parent('label');

          // clear out all other selections on radio elements
          if ($el.attr('type') === 'radio') {
            $('[name=' + $el.attr('name') + ']').parent('label').removeClass('is-selected');
          }

          // set is-selected state on check
          if($el.is(':checked')){
            $parent.addClass('is-selected');
          } else {
            $parent.removeClass('is-selected');
          }
        });

      moj.Events.on('render LabelSelect.render', this.render);
    },

    cacheEls: function () {
      this.$options = $(this.el).find('input[type=radio], input[type=checkbox]');
    },

    render: function () {
      // keep current state
      this.$options.each(function () {
        var $el = $(this);
        if($el.is(':checked')){
          $el.parent().addClass('is-selected');
        }
      });
    }
  };
}());

Add render function to label select js module


import appReducer from 'src/shared/reducers/app'
import {
  enablePresentationMode,
  disablePresentationMode,
  // delayEnablePresentationMode,
  setAutoRefresh,
} from 'src/shared/actions/app'

describe('Shared.Reducers.appReducer', () => {
  const initialState = {
    ephemeral: {
      inPresentationMode: false,
    },
    persisted: {
      autoRefresh: 0,
    },
  }

  it('should handle ENABLE_PRESENTATION_MODE', () => {
    const reducedState = appReducer(initialState, enablePresentationMode())

    expect(reducedState.ephemeral.inPresentationMode).to.equal(true)
  })

  it('should handle DISABLE_PRESENTATION_MODE', () => {
    Object.assign(initialState, {ephemeral: {inPresentationMode: true}})

    const reducedState = appReducer(initialState, disablePresentationMode())

    expect(reducedState.ephemeral.inPresentationMode).to.equal(false)
  })

  it('should handle SET_AUTOREFRESH', () => {
    const expectedMs = 15000

    const reducedState = appReducer(initialState, setAutoRefresh(expectedMs))

    expect(reducedState.persisted.autoRefresh).to.equal(expectedMs)
  })
})

import appReducer from 'src/shared/reducers/app'
import {
  enablePresentationMode,
  disablePresentationMode,
  // delayEnablePresentationMode,
  setAutoRefresh,
  tempVarControlsToggled,
} from 'src/shared/actions/app'

describe('Shared.Reducers.appReducer', () => {
  const initialState = {
    ephemeral: {
      inPresentationMode: false,
    },
    persisted: {
      autoRefresh: 0,
      showTempVarControls: false,
    },
  }

  it('should handle ENABLE_PRESENTATION_MODE', () => {
    const reducedState = appReducer(initialState, enablePresentationMode())

    expect(reducedState.ephemeral.inPresentationMode).to.equal(true)
  })

  it('should handle DISABLE_PRESENTATION_MODE', () => {
    Object.assign(initialState, {ephemeral: {inPresentationMode: true}})

    const reducedState = appReducer(initialState, disablePresentationMode())

    expect(reducedState.ephemeral.inPresentationMode).to.equal(false)
  })

  it('should handle SET_AUTOREFRESH', () => {
    const expectedMs = 15000

    const reducedState = appReducer(initialState, setAutoRefresh(expectedMs))

    expect(reducedState.persisted.autoRefresh).to.equal(expectedMs)
  })

  it('should handle TEMP_VAR_CONTROLS_TOGGLED', () => {
    const reducedState = appReducer(initialState, tempVarControlsToggled())

    const expectedTestState = !reducedState.persisted.showTempVarControls

    expect(initialState.persisted.showTempVarControls).to.equal(
      expectedTestState
    )
  })
})

Write test for tempvar controls toggle


import SimpleSchema from 'simpl-schema';

const usersEnrollSchema = new SimpleSchema({
  subject: {
    type: String,
    // suggested maximum length of email subject
    // https://stackoverflow.com/a/1592310/1191545
    max: 78
  },
  message: {
    type: String,
    optional: false
  },
  emailAddresses: {
    type: Array,
    regEx: SimpleSchema.RegEx.Email,
    optional: false
  }
});

export default usersEnrollSchema;

import SimpleSchema from 'simpl-schema';

const usersEnrollSchema = new SimpleSchema({
  subject: {
    type: String,
    // suggested maximum length of email subject
    // https://stackoverflow.com/a/1592310/1191545
    max: 78
  },
  message: {
    type: String,
    optional: false
  },
  emailAddresses: {
    type: Array,
    optional: false
  },
  'emailAddresses.$': {
    type: String,
    regEx: SimpleSchema.RegEx.Email,
  }
});

export default usersEnrollSchema;

Add data type and validation regEx for emailAddresses array item(s)


module.exports =
{
  mutationFunction: function(phenotype)
  {
    // make a random change to phenotype
    return phenotype
  }
}

module.exports =
{
  mutationFunction: function(phenotype)
  {
    // make a random change to phenotype
    var count = phenotype.nmos + phenotype.pmos
    var randNumb = Math.floor(Math.random() * (count + 1))

    if (randNumb < Math.floor(count/2))
      phenotype.nmosTransistors[randNumb].srcLeft = !phenotype.nmosTransistors[randNumb].srcLeft
    else
      phenotype.pmosTransistors[count-randNumb].srcLeft = !phenotype.pmosTransistors[count-randNumb].srcLeft

    return phenotype
  }
}

Implement Mutation Function to Toggle Direction of Transistor


'use strict';

angular.module('<%=angularAppName%>')
    .factory('Password', function ($resource) {
        return $resource('api/account/change_password', {}, {
        });
    });

angular.module('jhipsterApp')
    .factory('PasswordResetInit', function ($resource) {
        return $resource('api/account/reset_password/init', {}, {
        })
    });

angular.module('jhipsterApp')
    .factory('PasswordResetFinish', function ($resource) {
        return $resource('api/account/reset_password/finish', {}, {
        })
    });

'use strict';

angular.module('<%=angularAppName%>')
    .factory('Password', function ($resource) {
        return $resource('api/account/change_password', {}, {
        });
    });

angular.module('<%=angularAppName%>')
    .factory('PasswordResetInit', function ($resource) {
        return $resource('api/account/reset_password/init', {}, {
        })
    });

angular.module('<%=angularAppName%>')
    .factory('PasswordResetFinish', function ($resource) {
        return $resource('api/account/reset_password/finish', {}, {
        })
    });

Correct static angular app name


class Year {
  constructor (annum) {
    this.annum = annum
  }
  isLeap () {
    return (this.isDivisibleBy4ButNotBy100() || this.isDivisibleBy4And100ButNotBy400())
  }
  isDivisibleBy4ButNotBy100 () {
    return (this.isDivisibleBy(4) && this.isNotDivisibleBy(100))
  }
  isDivisibleBy4And100ButNotBy400 () {
    return (this.isDivisibleBy(4) && this.isDivisibleBy(100) && this.isDivisibleBy(400))
  }
  isDivisibleBy (number) {
    return (this.annum % number === 0)
  }
  isNotDivisibleBy (number) {
    return (this.annum % number !== 0)
  }
}

module.exports = Year

class Year {
  constructor (annum) {
    this.annum = annum
  }
  isLeap () {
    return (this.isDivisibleBy(4) && !this.isDivisibleBy(100) || this.isDivisibleBy(400))
  }
  isDivisibleBy (number) {
    return (this.annum % number === 0)
  }
}

module.exports = Year

Refactor solution based on feedback received


var morgan = require('morgan');
var bodyParser = require('body-parser');

// Middleware can be thought of as a magical pipe that water flows through.
// Each drop of water starts at the top opening of the pipe. As it falls through,
// a magic spell is cast on it, and then it is spit out the bottom of the pipe
// where another magical pipe could be waiting for it.

// The water in this example is Express's `request` object, and the magical spell
// is just a function passed to `app.use`. Any function passed into `app.use`
// will get run on every single request that your server receives

// The order of middleware is defined matters quite a bit! Requests flow through
// middleware functions in the order they are defined. This is useful because
// many times  middleware function is responsible for modifying the `request`
// object in some way so that the next middleware function (or route handler)
// has access to whatever the previous one just did.

// Middleware is useful when you want to do something for every request
// that hits your server. Logging and parsing are two operations
// commonly found in a middleware stack.

module.exports = function (app, express) {
  app.use(morgan('dev'));
  app.use(bodyParser.urlencoded({extended: true}));
  app.use(bodyParser.json());
  app.use(express.static(__dirname + '/../../client'));
};

var morgan = require('morgan');
var bodyParser = require('body-parser');

module.exports = function (app, express) {
  app.use(morgan('dev'));
  app.use(bodyParser.urlencoded({extended: true}));
  app.use(bodyParser.json());
  app.use(express.static(__dirname + '/../../client'));
};

Remove explanitory comment about middlewear


/*
 * grunt-dox
 * https://github.com/iVantage/grunt-dox
 *
 * Copyright (c) 2014 Evan Sheffield
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  // Please see the Grunt documentation for more information regarding task
  // creation: http://gruntjs.com/creating-tasks

  grunt.registerMultiTask('dox', 'Creates documentation markdown for your source code', function() {
    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({
      punctuation: '.',
      separator: ', '
    });

    // Iterate over all specified file groups.
    this.files.forEach(function(f) {
      // Concat specified files.
      var src = f.src.filter(function(filepath) {
        // Warn on and remove invalid source files (if nonull was set).
        if (!grunt.file.exists(filepath)) {
          grunt.log.warn('Source file "' + filepath + '" not found.');
          return false;
        } else {
          return true;
        }
      }).map(function(filepath) {
        // Read file source.
        return grunt.file.read(filepath);
      }).join(grunt.util.normalizelf(options.separator));

      // Handle options.
      src += options.punctuation;

      // Write the destination file.
      grunt.file.write(f.dest, src);

      // Print a success message.
      grunt.log.writeln('File "' + f.dest + '" created.');
    });
  });

};

/*
 * grunt-dox
 * https://github.com/iVantage/grunt-dox
 *
 * Copyright (c) 2014 Evan Sheffield
 * Licensed under the MIT license.
 */

'use strict';

var dox = require('../node_modules/dox/index.js');

module.exports = function(grunt) {

  grunt.registerMultiTask('dox', 'Creates documentation markdown for your source code', function() {
    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({
          lang: 'js'
        });

    // Iterate over all specified file groups.
    this.files.forEach(function(filePair) {

      filePair.src.forEach(function(src) {
        if(grunt.file.isDir(src)) {
          return;
        }

        var data = grunt.file.read(src)
          , comments = dox.parseComments(data, {language: options.lang})
          , markdown
          , dest = filePair.dest;

        try {
          markdown = dox.api(comments);
        } catch (e) {
          grunt.log.error('Error generating documentation for file ' + src.cyan + ': ' + e);
          return;
        }

        // Write the generated markdown to a file
        grunt.file.write(dest, markdown);
        grunt.log.writeln('Created documentation for ' + src.cyan +'--> ' + dest.cyan + '');
      });
    });
  });

};

Create markdown doc files from source


const getRoomData = require('../db/controllers/getRoomIdsAndUserIdsGivenSelfId.js');
const getBasicInfo = require('../db/controllers/getUserBasicInfoGivenUserId.js');
const helpers = require('../db/controllers/helpers.js');

const getUsersInfoForRoom = (roomObj) =>
  getBasicInfo.bulk(roomObj.users)
  .then(helpers.pluckUsers)
  .then(users => {
    roomObj.users = users;
    return roomObj;
  });

const getUsersInfoForRooms = (roomObjs) =>
  Promise.all(roomObjs.map(roomObj => getUsersInfoForRoom(roomObj)));

module.exports = (req, res, next) => {
  const selfId = req.idioma.profile.id;

  getRoomData(selfId)
  .then(getUsersInfoForRooms)
  .then(modifiedArray => req.idioma.rooms = modifiedArray)
  .then(() => next())
  .catch((error) => {
    res.status(404).send(error);
  });
};

const getRoomData = require('../db/controllers/getRoomIdsAndUserIdsGivenSelfId.js');
const getBasicInfo = require('../db/controllers/getUserBasicInfoGivenUserId.js');
const helpers = require('../db/controllers/helpers.js');

const getUsersInfoForRoom = (roomObj) =>
  getBasicInfo.bulk(roomObj.users)
  .then(helpers.pluckUsers)
  .then(users => {
    roomObj.users = users;
    return roomObj;
  });

const getUsersInfoForRooms = (roomObjs) =>
  Promise.all(roomObjs.map(roomObj => getUsersInfoForRoom(roomObj)));

const addMessagesToRooms = (rooms) =>
  rooms.map(room => {
    room.messages = room.messages || [];
    return room;
  });

module.exports = (req, res, next) => {
  const selfId = req.idioma.profile.id;

  getRoomData(selfId)
  .then(getUsersInfoForRooms)
  .then(addMessagesToRooms)
  .then(modifiedArray => req.idioma.rooms = modifiedArray)
  .then(() => next())
  .catch((error) => {
    res.status(404).send(error);
  });
};

Add messages to rooms objects


(function(){
    var app = angular.module('iccmax-gamut', []);
    app.controller('AppController', [function() {
        this.title = 'GAMUT';

        var renderCanvas = document.getElementById("visualizer-canvas");
        var gl = renderCanvas.getContext("webgl") || renderCanvas.getContext('experimental-webgl');
        if (!gl) {
            console.log("Error: Can't create WebGL context");
        }

        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.enable(gl.DEPTH_TEST);

        gl.viewport(0, 0, renderCanvas.width, renderCanvas.height);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    }]);
})();

(function(){
    var app = angular.module('iccmax-gamut', []);
    app.controller('AppController', [function() {
        this.title = 'GAMUT';

        var renderCanvas = document.getElementById("visualizer-canvas");
        var gl = renderCanvas.getContext("webgl") || renderCanvas.getContext('experimental-webgl');
        if (!gl) {
            console.log("Error: Can't create WebGL context");
        }

        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.enable(gl.DEPTH_TEST);

        gl.viewport(0, 0, renderCanvas.width, renderCanvas.height);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

        var handleDragOver = function(e) {
            if (e.preventDefault) {
                e.preventDefault();
            }

            e.dataTransfer.dropEffect = 'copy';

            return false;
        };

        var handleFileDrop = function(e) {
            if (e.stopPropagation) {
                e.stopPropagation();
            }
            if (e.preventDefault) {
                e.preventDefault();
            }

            var files = e.dataTransfer.files;
            if (files.length > 0) {
                fileReader = new FileReader();
                fileReader.onloadend = function() {
                    console.log("Dropped a file: " + fileReader.result);
                }
                var file = files[0];
                fileReader.readAsBinaryString(file);
            }

            return false;
        };

        var visualizer = document.getElementById("visualizer");
        visualizer.addEventListener('dragover', handleDragOver, false);
        visualizer.addEventListener('drop', handleFileDrop, false);
    }]);
})();

Add file drop to visualizer


const path = require('path');
const config = require('./package.json');

const webpack = require('webpack');
require('dotenv').config();

const PROD = process.env.NODE_ENV === 'production';

// let plugins = [];

// PROD ? [
//   plugins.push(new webpack.optimize.UglifyJsPlugin({
//     compress: { warnings: false }
//   }))
// ] : '';

module.exports = {
  entry: path.resolve(__dirname, config.main),
  output: {
    library: process.env.NAME,
    libraryTarget: process.env.TARGET,
    path: path.resolve(__dirname, "dist"),
    filename: (PROD) ? 'autoscroll.min.js' : 'autoscroll.js'
  },
  // devtool: 'source-map',
  module: {
    rules: [
      {
        test: /\.js?$/,
        exclude: /(node_modules|bower_components)/,
        use: ['babel-loader']
      }
    ],
  }
  // plugins: plugins
};

const path = require('path')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const config = require('./package.json')

const webpack = require('webpack')

// Config object
const library = {
  name: 'VueAutoscroll',
  target: 'umd'
}

const DEV = process.env.NODE_ENV === 'development';

let webpackConfig = {
  entry: path.resolve(__dirname, config.main),
  watch: DEV,
  output: {
    library: library.name,
    libraryTarget: library.target,
    path: path.resolve(__dirname, "dist"),
    filename: (DEV) ? 'autoscroll.js' : 'autoscroll.min.js'
  },
  // devtool: 'source-map',
  module: {
    rules: [
      {
        test: /\.js?$/,
        exclude: /(node_modules|bower_components)/,
        use: ['babel-loader']
      }
    ],
  },
  plugins: []
}

if(!DEV) {
  webpackConfig.plugins.push(new webpack.optimize.UglifyJsPlugin({compress: { warnings: false }}))
}

module.exports = webpackConfig

Remove dotenv execution, create library object that contain library infos. watch if DEV MODE and UGLIFY if PROD MODE


var express = require('express')
var router = express.Router()
const family_file = "family.json"

// define the home page route
router.get('/', function (req, res) {
    res.json(readFamily())
})
// define the about route
router.get('/about', function (req, res) {
  res.send('About Page')
})

function readFamily() {
    fs.readFile(('../data/' + family_file), 'utf8', function readFileCallback(err, data){
        if (err){
            console.log(err)
        } else {
            obj = JSON.parse(data) //now it an object
            return obj
        }
    });
    return null
}

module.exports = router

var express = require('express')
var router = express.Router()
const family_file = "family.json"
const fs = require('fs')

// define the home page route
router.get('/', function (req, res) {
    res.json(readFamily())
})
// define the about route
router.get('/about', function (req, res) {
  res.send('About Page')
})

function readFamily() {
    fs.readFile(('../data/' + family_file), 'utf8', function readFileCallback(err, data){
        if (err){
            console.log(err)
        } else {
            obj = JSON.parse(data) //now it an object
            return obj
        }
    });
    return null
}

module.exports = router

FIX - Express server updates adding json file


define([
    'aux/get-parameter-by-name'
], function (getParameterByName) {
    describe('getParameterByName', function () {
        var url;

        beforeEach(function () {
            url = 'http://www.rockabox.com?param1=value1&param2=value2';
        });

        it('should return the query paramater\'s value', function () {
            expect(getParameterByName(url, 'param1')).toContain('value1');
            expect(getParameterByName(url, 'param2')).toContain('value2');
        });

        it ('should return an empty string when query param doesn\'t exist', function () {
            expect(getParameterByName(url, 'param3')).toBe('');
        });
    });
});

define([
    'aux/get-parameter-by-name'
], function (getParameterByName) {
    describe('getParameterByName', function () {
        var url;

        beforeEach(function () {
            url = 'http://www.rockabox.com?param1=value1&param2=value2#somehashnotomitted';
        });

        it('should return the query paramater\'s value', function () {
            expect(getParameterByName(url, 'param1')).toBe('value1');
            expect(getParameterByName(url, 'param2')).toBe('value2');
        });

        it ('should return an empty string when query param doesn\'t exist', function () {
            expect(getParameterByName(url, 'param3')).toBe('');
        });
    });
});

Enhance the get param by name tests


//This server is here, because we need to go up a directory from the test site for some resources.
var connect = require('connect');
connect.createServer(
    connect.static(__dirname)
).listen(3000);

//This server is here, because we need to go up a directory from the test site for some resources.
var connect = require('connect'), http = require('http');

var app = connect()
    .use(connect.logger('short'))
    .use(connect.static(__dirname));

http.createServer(app).listen(3000);

Add logging to the test server.


'use strict'

class API {
  static createQueryFromRequest (request) {
    let limit = parseInt(request.limit) || 25
    delete request.limit

    let offset = parseInt(request.offset) || 0
    delete request.offset

    let order = parseInt(request.order) || 'createdAt'
    delete request.order
    let direction = request.direction || 'ASC'
    delete request.direction

    if (request.data) {
      let dataQuery = request.data
      delete request.data

      request.data = {
        $contains: JSON.parse(dataQuery)
      }
    }

    let query = {
      where: request,
      limit: limit,
      offset: offset,
      order: [
        [order, direction]
      ]
    }

    return query
  }
}

module.exports = API

'use strict'

class API {
  static createQueryFromRequest (request) {
    let limit = parseInt(request.limit) || 25
    delete request.limit

    let offset = parseInt(request.offset) || 0
    delete request.offset

    let order = parseInt(request.order) || 'createdAt'
    delete request.order
    let direction = request.direction || 'ASC'
    delete request.direction

    if (request.data) {
      let dataQuery = request.data
      delete request.data

      request.data = {
        $contains: JSON.parse(dataQuery)
      }
    }

    if (query.nicknames) {
      query.nicknames = { $contains: [query.nicknames] }
    }

    let query = {
      where: request,
      limit: limit,
      offset: offset,
      order: [
        [order, direction]
      ]
    }

    return query
  }
}

module.exports = API

Fix nick search missing from new standardised search function


class MCWorkflowFiltersComponentController {
    /*@ngInject*/
    constructor(experimentsAPI, mcStateStore, $stateParams) {
        this.experimentsAPI = experimentsAPI;
        this.mcStateStore = mcStateStore;
        this.projectId = $stateParams.project_id;
        this.experimentId = $stateParams.experiment_id;
        this.showSamplesFilter = false;
        this.showProcessesFilter = true;
    }

    $onInit() {
        this.activateProcessesFilter();
    }

    activateProcessesFilter() {
        let e = this.mcStateStore.getState('experiment');
        this.processes = _.values(e.processes);
        this.showProcessesFilter = true;
        this.showSamplesFilter = false;
        // this.experimentsAPI.getProcessesForExperiment(this.projectId, this.experimentId).then(
        //     (processes) => {
        //         this.showProcessesFilter = true;
        //         this.showSamplesFilter = false;
        //         this.processes = processes;
        //     }
        // );
    }

    activateSamplesFilter() {
        this.experimentsAPI.getSamplesForExperiment(this.projectId, this.experimentId).then(
            (samples) => {
                this.showProcessesFilter = false;
                this.showSamplesFilter = true;
                this.samples = samples;
            }
        );
    }
}

angular.module('materialscommons').component('mcWorkflowFilters', {
    template: require('./mc-workflow-filters.html'),
    controller: MCWorkflowFiltersComponentController
});

class MCWorkflowFiltersComponentController {
    /*@ngInject*/
    constructor(experimentsAPI, mcStateStore, $stateParams) {
        this.experimentsAPI = experimentsAPI;
        this.mcStateStore = mcStateStore;
        this.projectId = $stateParams.project_id;
        this.experimentId = $stateParams.experiment_id;
        this.showSamplesFilter = true;
        this.showProcessesFilter = false;
    }

    $onInit() {
        this.activateSamplesFilter();
    }

    activateProcessesFilter() {
        let e = this.mcStateStore.getState('experiment');
        this.processes = _.values(e.processes);
        this.showProcessesFilter = true;
        this.showSamplesFilter = false;
    }

    activateSamplesFilter() {
        this.experimentsAPI.getSamplesForExperiment(this.projectId, this.experimentId).then(
            (samples) => {
                this.showProcessesFilter = false;
                this.showSamplesFilter = true;
                this.samples = samples;
            }
        );
    }
}

angular.module('materialscommons').component('mcWorkflowFilters', {
    template: require('./mc-workflow-filters.html'),
    controller: MCWorkflowFiltersComponentController
});

Make samples filter the default filter


/** Find the most common entry in an array of numbers
    @function clonecounter
    @param {array} arr Simple array of numbers
    @example clonecounter(arrayName)

    @returns {string} Most common entry
*/

function clonecounter(arr) {
    var mostCommon = 0;
    var count = 0;
    var compObj = {};
        arr.forEach(function(val,idx) {
            if(!compObj[val]) {
                compObj[val] = 1;
            } else {
                compObj[val]+=1;
            };
        });

        Object.keys(compObj).forEach(function(val,idx) {
            if(obj[val] > count) {
                count = compObj[val];
                mostCommon = val;
            }
     });

     return Number(mostCommon);
}

/** Find the most common entry in an array of numbers
    @function clonecounter
    @param {array} arr Simple array of numbers
    @example clonecounter(arrayName)

    @returns {number} Most common entry
*/

function clonecounter(arr) {
    var mostCommon = 0;
    var count = 0;
    var compObj = {};
        arr.forEach(function(val,idx) {
            if(!compObj[val]) {
                compObj[val] = 1;
            } else {
                compObj[val]+=1;
            };
        });

        Object.keys(compObj).forEach(function(val,idx) {
            if(obj[val] > count) {
                count = compObj[val];
                mostCommon = val;
            }
     });

     return Number(mostCommon);
}

Clone Counter - Read an array of numbers, pick out the one that appears most frequently


const {Bookmark} = require('../models')

module.exports = {
  async index (req, res) {
    try {
      const {songId, userId} = req.query

      const bookmark = await Bookmark.findOne({
        where: {
          SongId: songId,
          UserId: userId
        }
      })
      res.send(bookmark)
    } catch (err) {
        res.status(500).send({
        error: 'An error has occured.'
      })
    }
  },

  async post (req, res) {
    try {
      const bookmark = req.body

      await Bookmark.create(bookmark)
      res.send(bookmark)
    } catch (err) {
        res.status(500).send({
        error: 'An error has occured.'
      })
    }
  },

  async delete (req, res) {
    try {
      const {bookmarkId} = req.params

      const bookmark = await Bookmark.findById(bookmarkId)
      await bookmark.destroy()
      res.send(bookmark)
    } catch (err) {
        res.status(500).send({
        error: 'An error has occured.'
      })
    }
  }
}

const {Bookmark} = require('../models')

module.exports = {
  async index (req, res) {
    try {
      const {songId, userId} = req.query

      const bookmark = await Bookmark.findOne({
        where: {
          SongId: songId,
          UserId: userId
        }
      })
      res.send(bookmark)
    } catch (err) {
        return res.status(500).send({
        error: 'An error has occured.'
      })
    }
  },

  async post (req, res) {
    try {
      const {songId, userId} = req.body.params
      const bookmark = await Bookmark.findOne({
        where: {
          SongId: songId,
          UserId: songId
        }
      })
      if (bookmark) {
        return res.status(400).send({
          error: 'You already have this set as a bookmark'
        })
      }

      const newBookmark = await Bookmark.create({
        SongId: songId,
        UserId: userId
      })
      res.status(201).send(newBookmark)
    } catch (err) {
      return res.status(500).send({
        error: 'An internal error has occured.'
      })
    }
  },

  async delete (req, res) {
    try {
      const {bookmarkId} = req.params

      const bookmark = await Bookmark.findById(bookmarkId)
      await bookmark.destroy()
      res.send(bookmark)
    } catch (err) {
        res.status(500).send({
        error: 'An error has occured.'
      })
    }
  }
}

Update add & delete bookmark on backend


exports.init = function () {
    debugger
};

var $ = function (s) {
    return document.querySelector(s);
};

exports.init = function () {
    var content = $("#content");
    this
      .link("clientConnected")
      .send()
      .data(function (err, data) {
         content.value += data + "\n";
       })
      ;
};

Create the link from the client


//var queue = new PowerQueue();
var hn = Meteor.require('hacker-news-api');

Meteor.methods({
  "readHn": function () {
    "use strict";
    hn.getStories(Meteor.bindEnvironment(
      function (error, data) {
        if (error) {
          throw error;
        }
        _(data.hits).forEach(function (item) {
          /*jshint camelcase: false */
          var obj = {
            oldId: parseInt(item.objectID, 10),
            oldPoints: parseInt(item.points, 10),
            createdAt: new Date(item.created_at),
            site: 'hn',
            author: item.author,
            title: item.title,
            url: item.url,
            comments: parseInt(item.num_comments, 10),
          };

          Posts.upsert({
              oldId: obj.oldId
          },{ $set: obj });

        });
      }, function (e) {
        throw e;
      })
    );
  }
});

//var queue = new PowerQueue();
var hn = Meteor.require('hacker-news-api');

var readHn = function () {
  "use strict";
  console.log('Reading last 24 hours of Hacker News');
  var now = Date.now() / 1000;

  var query = 'search?tags=story&numericFilters=created_at_i>' +
  (now - 86400) + ',created_at_i<' +
  now;

  hn.call(query, Meteor.bindEnvironment(
    function (error, data) {
      if (error) {
        throw error;
      }
      _(data.hits).forEach(function (item) {
        /*jshint camelcase: false */
        var obj = {
          oldId: parseInt(item.objectID, 10),
          oldPoints: parseInt(item.points, 10),
          createdAt: new Date(item.created_at),
          site: 'hn',
          author: item.author,
          title: item.title,
          url: item.url,
          comments: parseInt(item.num_comments, 10),
        };

        Posts.upsert({
            oldId: obj.oldId
        },{ $set: obj });

      });
    }, function (e) {
      throw e;
    })
  );
}

// read last 24 hours of hn
readHn();

// reread hn every hour
Meteor.setInterval(readHn, 3600 * 1000)

Add auto-reading from Hacker News


export default class Utils {
  static paddingZero(num) {
    return `0${num}`.slice(-2);
  }

  static toFormatDate(date) {
    const y = date.getFullYear();
    const m = this.paddingZero(date.getMonth() + 1);
    const d = this.paddingZero(date.getDate());
    return `${y}-${m}-${d}`;
  }

  static toDate(formatedDate) {
    const ary = formatedDate.split('-').map(s => parseInt(s, 10));
    return new Date(ary[0], ary[1] - 1, ary[2], 0, 0, 0);
  }

  static getToday() {
    return this.toFormatDate(new Date());
  }

  static getRelativeDate(formatedBaseDate, diff) {
    const bd = this.toDate(formatedBaseDate);
    const rd = new Date(bd.getFullYear(), bd.getMonth(), bd.getDate() + diff);

    return this.toFormatDate(rd);
  }

  static isToday(date) {
    const now = new Date();
    const today = new Date(now.getFullYear(), now.getMonth() + 1, now.getDate(), 0, 0, 0);

    return today.getTime() === this.toDate(date).getTime();
  }
}

export default class Utils {
  static paddingZero(num) {
    return `0${num}`.slice(-2);
  }

  static toFormatDate(date) {
    const y = date.getFullYear();
    const m = this.paddingZero(date.getMonth() + 1);
    const d = this.paddingZero(date.getDate());
    return `${y}-${m}-${d}`;
  }

  static toDate(formatedDate) {
    const ary = formatedDate.split('-').map(s => parseInt(s, 10));
    return new Date(ary[0], ary[1] - 1, ary[2], 0, 0, 0);
  }

  static getToday() {
    return this.toFormatDate(new Date());
  }

  static getRelativeDate(formatedBaseDate, diff) {
    const bd = this.toDate(formatedBaseDate);
    const rd = new Date(bd.getFullYear(), bd.getMonth(), bd.getDate() + diff);

    return this.toFormatDate(rd);
  }

  static isToday(date) {
    const now = new Date();
    const today = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0);

    return today.getTime() === this.toDate(date).getTime();
  }
}

Fix bug in isToday method


import React, { Component } from 'react';
import './App.css';
import { connect } from 'react-redux'
import { Intent, Position, Toaster } from "@blueprintjs/core";

class App extends Component {
  componentWillMount() {
    this.toaster = Toaster.create({
      className: "my-toaster",
      position: Position.TOP_CENTER
    });
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.error.get('message') !== nextProps.error.get('message')) {
      this.toaster.show({
        message: nextProps.error.get('message'),
        intent: Intent.DANGER
      });
    }
  }

  render() {
    return (
      <div className="App">
        {this.props.children}
      </div>
    );
  }
}

const mapStateToProps = state => ({
  error: state.get('error')
});

export default connect(mapStateToProps)(App);

import React, { Component } from 'react';
import './App.css';
import { connect } from 'react-redux'
import { Intent, Position, Toaster } from "@blueprintjs/core";

class App extends Component {
  componentWillMount() {
    this.toaster = Toaster.create({
      className: "my-toaster",
      position: Position.TOP_CENTER
    });
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.error.get('message')) {
      this.toaster.clear();
      this.toaster.show({
        message: nextProps.error.get('message'),
        intent: Intent.DANGER
      });
    }
  }

  render() {
    return (
      <div className="App">
        {this.props.children}
      </div>
    );
  }
}

const mapStateToProps = state => ({
  error: state.get('error')
});

export default connect(mapStateToProps)(App);

Make sure to change the toaster when new error appears


describe('C&E Generator', function() {
    beforeEach(function beforeEach() {
        browser.get('http://localhost:4000/')
    })

    it('should have a title', function hasTitle() {
        expect(browser.getTitle()).toEqual('C&E Generator')
    })

    it('should display allowed number of participants', function participants() {
        element(by.cssContainingText('option', 'NU')).click()
        element(by.model('ce.participants')).getText().then(function (options) {
            expect(options.trim().split(/\s+/)).toEqual(['8', '16', '32', '64'])
        })
    })

    it('should display allowed number of participants for monotype', function monotypeParticipants() {
        element(by.cssContainingText('option', 'Monotype')).click()
        element(by.cssContainingText('option', 'Dragon')).click()
        element(by.model('ce.participants')).getText().then(function (options) {
            expect(options.trim().split(/\s+/)).toEqual(['8'])
        })
    })
})

describe('C&E Generator', function() {
    beforeEach(function beforeEach() {
        browser.get('http://localhost:4000/')
    })

    it('should have a title', function hasTitle() {
        expect(browser.getTitle()).toEqual('C&E Generator')
    })

    it('should display allowed number of participants', function participants() {
        element(by.cssContainingText('option', 'NU')).click()
        element(by.model('ce.participants')).getText().then(function (options) {
            expect(options.trim().split(/\s+/)).toEqual(['8', '16', '32', '64'])
        })
    })

    it('should display allowed number of participants for monotype', function monotypeParticipants() {
        element(by.cssContainingText('option', 'Monotype')).click()
        element(by.cssContainingText('option', 'Dragon')).click()
        element(by.model('ce.participants')).getText().then(function (options) {
            expect(options.trim().split(/\s+/)).toEqual(['8'])
        })
    })

    it('should not display allowed number of participants for non-mega dragon monotype', function nonMegaDragon() {
        element(by.cssContainingText('option', 'Monotype')).click()
        element(by.cssContainingText('option', 'Dragon')).click()
        element(by.model('ce.megas')).click()
        element(by.model('ce.participants')).getText().then(function (options) {
            expect(options.trim()).toEqual("")
        })
    })
})

Add test for non-mega dragon monotype.


var fs = require('fs');
var parallelStream = require('pelias-parallel-stream');

var maxInFlight = 10;

module.exports.create = function create_json_parse_stream(dataDirectory) {
  return parallelStream(maxInFlight, function(record, enc, next) {
    fs.readFile(dataDirectory + record.path, function(err, data) {
      if (err) {
        console.error('exception reading file ' + record.path);
        next(err);
      } else {
        try {
          var object = JSON.parse(data);
          next(null, object);
        } catch (parse_err) {
          console.error('exception parsing JSON in file %s:', record.path, parse_err);
          console.error('Inability to parse JSON usually means that WOF has been cloned ' +
                        'without using git-lfs, please see instructions here: ' +
                        'https://github.com/whosonfirst/whosonfirst-data#git-and-large-files');
          next(parse_err);
        }
      }
    });
  });
};

var fs = require('fs');
var parallelStream = require('pelias-parallel-stream');

var maxInFlight = 10;

module.exports.create = function create_json_parse_stream(dataDirectory) {
  return parallelStream(maxInFlight, function(record, enc, next) {
    var full_file_path = dataDirectory + record.path;
    fs.readFile(full_file_path, function(err, data) {
      if (err) {
        console.error('exception reading file ' + full_file_path);
        next(err);
      } else {
        try {
          var object = JSON.parse(data);
          next(null, object);
        } catch (parse_err) {
          console.error('exception parsing JSON in file %s:', record.path, parse_err);
          console.error('Inability to parse JSON usually means that WOF has been cloned ' +
                        'without using git-lfs, please see instructions here: ' +
                        'https://github.com/whosonfirst/whosonfirst-data#git-and-large-files');
          next(parse_err);
        }
      }
    });
  });
};

Use full path in file reading error


// import necessary modules
import express from 'express';
import users from '../controllers/users';
import verifyToken from '../controllers/auth/verifyToken';

const router = express.Router();
router.post('/signup', users.createUser);
router.post('/login', users.authenticateUser);

// Endpoint for user to upvote a book
router.post('/:userId/book/:bookId/upvote', verifyToken, users.upVote);
// Endpoint for user to downvote a book
router.post('/:userId/book/:bookId/downvote', verifyToken, users.downVote);
// Endpoint to update a book
router.post('/:userId/fav/:bookId', verifyToken, users.favoriteBook);
// Endpoint for user to review a book
router.post('/:userId/review/:bookId', verifyToken, users.reviewBook);
router.get('/:userId/favbooks', verifyToken, users.getFavoriteBooks);
router.post('/:userId/borrow/:bookId', verifyToken, users.sendBorrowRequest);

export default router;

// import necessary modules
import express from 'express';
import users from '../controllers/users';
import verifyToken from '../controllers/auth/verifyToken';

const router = express.Router();
// Endpoint for user to signup
router.post('/signup', users.createUser);
// Endpoint for user to signin
router.post('/login', users.authenticateUser);
// Endpoint for user to upvote a book
router.post('/:userId/book/:bookId/upvote', verifyToken, users.upVote);
// Endpoint for user to downvote a book
router.post('/:userId/book/:bookId/downvote', verifyToken, users.downVote);
// Endpoint to update a book
router.post('/:userId/fav/:bookId', verifyToken, users.favoriteBook);
// Endpoint for user to review a book
router.post('/:userId/review/:bookId', verifyToken, users.reviewBook);
// Endpoint for user to get favorite books
router.get('/:userId/favbooks', verifyToken, users.getFavoriteBooks);
// Endpoint for user to borrow a book
router.post('/:userId/borrow/:bookId', verifyToken, users.sendBorrowRequest);
// Endpoint for Admin to handle borrow requests
router.put('/:userId/borrow/:bookId', verifyToken, users.handleBorrowRequest);

export default router;

Add route to handle a borrow request


var p = String.prototype;

// Converts spinal-case, snake_case or space case to camelCase
p.toCamelCase = function(pascalCase) {
	var str = this.toLowerCase();

	var arr = str.split(/[\s-_]/);

	for(var i = pascalCase ? 0 : 1; i < arr.length; i++) {
		arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].slice(1);
	}

	return arr.join('');
};

// Converts spinal-case, snake_case or space case to PascalCase
p.toPascalCase = function() {
	return this.toCamelCase(true);
};

// converts camelCase or PascalCase to spinal-case/
p.toSpinalCase = function() {
	return (this.charAt(0).toLowerCase() + this.slice(1)).replace(/([A-Z])/, '-$&').toLowerCase();
};

// converts camelCase or PascalCase to snake_case/
p.toSnakeCase = function() {
	return (this.charAt(0).toLowerCase() + this.slice(1)).replace(/([A-Z])/, '_$&').toLowerCase();
};

var p = String.prototype;

// normalize always returns the string in spinal-case
function normalize(str) {
	var arr = str.split(/[\s-_.]/);

	if(arr.length > 1)
		return arr.map(function(part) { return part.toLowerCase(); }).join('-');
	else
		return (str.charAt(0).toLowerCase() + str.slice(1)).replace(/([A-Z])/, '-$&').toLowerCase();
}

// Converts spinal-case, snake_case or space case to camelCase
p.toCamelCase = function(pascalCase) {
	var str = this.toLowerCase();

	var arr = str.split(/[\s-_]/);

	for(var i = pascalCase ? 0 : 1; i < arr.length; i++) {
		arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].slice(1);
	}

	return arr.join('');
};

// Converts spinal-case, snake_case or space case to PascalCase
p.toPascalCase = function() {
	return normalize(this).toCamelCase(true);
};

// converts camelCase or PascalCase to spinal-case/
p.toSpinalCase = function() {
	return normalize(this);
};

// converts camelCase or PascalCase to snake_case/
p.toSnakeCase = function() {
	return normalize(this).split('-').join('_');
};

p.toSpaceCase = function(capitals) {
	return normalize(this).split('-').map(function(part) {
		return capitals ? part.charAt(0).toUpperCase() + part.slice(1) : part;
	}).join(' ');
};

Normalize all to spinal-case before other convertions. Added toSpaceCase.


/* -*- mode: javascript; c-basic-offset: 4; indent-tabs-mode: nil -*- */

//
// Dalliance Genome Explorer
// (c) Thomas Down 2006-2013
//
// tier-actions.js
//

Browser.prototype.mergeSelectedTiers = function() {
    var sources = [];
    var styles = [];

    for (var sti = 0; sti < this.selectedTiers.length; ++sti) {
        var tier = this.tiers[this.selectedTiers[sti]];
	    sources.push(shallowCopy(tier.dasSource));
        var ss = tier.stylesheet.styles;
        for (var si = 0; si < ss.length; ++si) {
            var sh = ss[si];
            var nsh = shallowCopy(sh);
            nsh.method = tier.dasSource.name.replace(/[()+*?]/g, '\\$&');
            nsh._methodRE = null;
            nsh.style = shallowCopy(sh.style);
            if (nsh.style.ZINDEX === undefined)
                nsh.style.ZINDEX = sti;

            styles.push(nsh);
        }
    }

    this.addTier(
	{name: 'Merged',
	 merge: 'concat',
	 overlay: sources,
	 noDownsample: true,
     style: styles});

    this.setSelectedTier(this.tiers.length - 1);
}

/* -*- mode: javascript; c-basic-offset: 4; indent-tabs-mode: nil -*- */

//
// Dalliance Genome Explorer
// (c) Thomas Down 2006-2013
//
// tier-actions.js
//

Browser.prototype.mergeSelectedTiers = function() {
    var sources = [];
    var styles = [];

    for (var sti = 0; sti < this.selectedTiers.length; ++sti) {
        var tier = this.tiers[this.selectedTiers[sti]];
	    sources.push(shallowCopy(tier.dasSource));
        var ss = tier.stylesheet.styles;
        for (var si = 0; si < ss.length; ++si) {
            var sh = ss[si];
            var nsh = shallowCopy(sh);
            nsh.method = tier.dasSource.name.replace(/[()+*?]/g, '\\$&');
            nsh._methodRE = null;
            nsh.style = shallowCopy(sh.style);
            if (nsh.style.ZINDEX === undefined)
                nsh.style.ZINDEX = sti;

            if (tier.forceMin) {
                nsh.style.MIN = tier.forceMin;
            }
            if (tier.forceMax) {
                nsh.style.MAX = tier.forceMax;
            }

            styles.push(nsh);
        }
    }

    this.addTier(
	{name: 'Merged',
	 merge: 'concat',
	 overlay: sources,
	 noDownsample: true,
     style: styles});

    this.setSelectedTier(this.tiers.length - 1);
}

Write forceMin/forceMax into the synthetic stylesheet of merged tracks.


const parameters = require('./Parameters')
// Show every method for operation with tables like delete, insert, update

exports.check = function (column, operator, value) {

}

exports.deleteTable = function () {

}

exports.deleteAllRecords = function () {

}

exports.createTable = function () {

}

exports.addColumnOnTable = function () {

}

exports.removeColumnFromTable = function () {

}

exports.modifyColumnOnTable = function () {

}

exports.createKey = function () {

}

exports.removeKey = function () {

}

const parameters = require('./Parameters')

exports.check = function (column, operator, value) {

}

exports.deleteTable = function () {

}

exports.deleteAllRecords = function () {

}

exports.createTable = function () {

}

exports.addColumnOnTable = function () {

}

exports.removeColumnFromTable = function () {

}

exports.modifyColumnOnTable = function () {

}

exports.createKey = function () {

}

exports.removeKey = function () {

}

Delete the comment which is not correct


/* @flow */
import test from 'ava'
import useGitHub from 'create-npm/test/helpers/useGitHub'
import useGitHubRepository from 'create-npm/test/helpers/useGitHubRepository'
import { getGitHubRepositoryName } from 'create-npm/src/actions'

useGitHub()
const localPath = useGitHubRepository('test-create-npm/existing-repo')

test('reading the name of a GitHub repository', async t => {
  t.is(
    await getGitHubRepositoryName(localPath),
    'test-create-npm/existing-repo'
  )
})

/* @flow */
import test from 'ava'
import useGitHub from 'create-npm/test/helpers/useGitHub'
import useGitHubRepository from 'create-npm/test/helpers/useGitHubRepository'
import useGitSshKey from 'create-npm/test/helpers/useGitSshKey'
import { getGitHubRepositoryName } from 'create-npm/src/actions'

useGitHub()
useGitSshKey()
const localPath = useGitHubRepository('test-create-npm/existing-repo')

test('reading the name of a GitHub repository', async t => {
  t.is(
    await getGitHubRepositoryName(localPath),
    'test-create-npm/existing-repo'
  )
})

Use git ssh key when cloning


(function () {

	'use strict';

	var parameters = {
		diameter: 10,
	};

	var geometries;

	QUnit.module( "Extras - Helpers - BoxHelper", {

		beforeEach: function() {
			var greenMaterial = new THREE.MeshBasicMaterial( {color: 0x00ff00} );

			// Test with a normal cube and a box helper
			var boxGeometry = new THREE.BoxGeometry( parameters.diameter );
			var box = new THREE.Mesh( boxGeometry, greenMaterial );
			var boxHelper = new THREE.BoxHelper( box );

			// The same should happen with a comparable sphere
			var sphereGeometry = new THREE.SphereGeometry( parameters.diameter / 2 );
			var sphere = new THREE.Mesh( sphereGeometry, greenMaterial );
			var sphereBoxHelper = new THREE.BoxHelper( sphere );

			// Note that unlike what I'd like to, these doesn't check the equivalency of the two generated geometries
			geometries = [ boxHelper.geometry, sphereBoxHelper.geometry ];
		}

	});

	QUnit.test( "standard geometry tests", function( assert ) {
		runStdGeometryTests( assert, geometries );
	});

})();

(function () {

	'use strict';

	var parameters = {
		diameter: 10
	};

	var geometries;

	QUnit.module( "Extras - Helpers - BoxHelper", {

		beforeEach: function() {
			var greenMaterial = new THREE.MeshBasicMaterial( {color: 0x00ff00} );

			// Test with a normal cube and a box helper
			var boxGeometry = new THREE.BoxGeometry( parameters.diameter );
			var box = new THREE.Mesh( boxGeometry, greenMaterial );
			var boxHelper = new THREE.BoxHelper( box );

			// The same should happen with a comparable sphere
			var sphereGeometry = new THREE.SphereGeometry( parameters.diameter / 2 );
			var sphere = new THREE.Mesh( sphereGeometry, greenMaterial );
			var sphereBoxHelper = new THREE.BoxHelper( sphere );

			// Note that unlike what I'd like to, these doesn't check the equivalency of the two generated geometries
			geometries = [ boxHelper.geometry, sphereBoxHelper.geometry ];
		}

	});

	QUnit.test( "standard geometry tests", function( assert ) {
		runStdGeometryTests( assert, geometries );
	});

})();

Remove unneeded comma from BoxHelper test


// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery-ui
//= require jquery_ujs
//= require turbolinks
//= require_tree .

Add jquery to asset pipeline


import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { createUploadLink } from 'apollo-upload-client';
import csrf from '~/lib/utils/csrf';

export default (resolvers = {}) =>
  new ApolloClient({
    link: createUploadLink({
      uri: `${gon.relative_url_root}/api/graphql`,
      headers: {
        [csrf.headerKey]: csrf.token,
      },
    }),
    cache: new InMemoryCache(),
    resolvers,
  });

import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { createUploadLink } from 'apollo-upload-client';
import csrf from '~/lib/utils/csrf';

export default (resolvers = {}, baseUrl = '') => {
  let uri = `${gon.relative_url_root}/api/graphql`;

  if (baseUrl) {
    // Prepend baseUrl and ensure that `///` are replaced with `/`
    uri = `${baseUrl}${uri}`.replace(/\/{3,}/g, '/');
  }

  return new ApolloClient({
    link: createUploadLink({
      uri,
      headers: {
        [csrf.headerKey]: csrf.token,
      },
    }),
    cache: new InMemoryCache(),
    resolvers,
  });
};

Add support for baseUrl in ApolloClient instance


import { app } from 'electron'

/**
 * Show or hide main window
 * @return {BrowserWindow} appWindow
 */
export default (appWindow) => {
  if (appWindow.isVisible()) {
    appWindow.hide()
    app.hide()
  } else {
    appWindow.show()
    appWindow.focus()
  }
}

import { app } from 'electron'

/**
 * Show or hide main window
 * @return {BrowserWindow} appWindow
 */
export default (appWindow) => {
  if (appWindow.isVisible()) {
    appWindow.hide()
    if (process.platform === 'darwin') {
      // Restore focus in previous application
      // MacOS only: https://github.com/electron/electron/blob/master/docs/api/app.md#apphide-macos
      app.hide()
    }
  } else {
    appWindow.show()
    appWindow.focus()
  }
}

Fix no method error for `app.hide()` on Linux and Windows


$(function() {
  var blankByDefault = ($("#artefact_slug").attr('value') != '');
  var generateSlug = function generateSlug() {
    if(blankByDefault) { return }
    var title = $("#artefact_name").val();
    var slug = title.toLowerCase()
      .replace(/[^\w ]+/g, '')
      .replace(/ +/g, '-')
      .replace(/^-+|-+$/, '')
    $("#artefact_slug").val(slug);
  }
  $("#artefact_name").change(generateSlug)
  $("#artefact_name").bind('keyup', generateSlug)

  $('a[rel=external]').attr('target','_blank');

  // $('.related select').chosen({
  //   allow_single_deselect: true,
  //   no_results_text: "No results matched"
  // });

  $('select#artefact_sections').chosen({
    allow_single_deselect: true,
    no_results_text: "Section not found"
  });

  $('.flash-notice').delay(4000).slideUp(300).
    one('click', function () { $(this).slideUp(300); });

  // add sections
  $('#add-section').click(function () {
    $('.remove-section').show();
    var new_select = $('.artefact-section').first().clone(true);
    new_select.find('select option:selected').removeAttr('selected');
    new_select.insertBefore(this);
    return false;
  })

  $('.remove-section').click(function () {
    if ($('.artefact-section').size() >= 2) {
      $(this).parent().remove();
      if ($('.artefact-section').size() == 1) {
        $('.remove-section').hide();
      }
    }
    return false;
  })

});

$(function() {
  var blankByDefault = ($("#artefact_slug").attr('value') != '');
  var generateSlug = function generateSlug() {
    if(blankByDefault) { return }
    var title = $("#artefact_name").val();
    var slug = title.toLowerCase()
      .replace(/[^\w ]+/g, '')
      .replace(/ +/g, '-')
      .replace(/^-+|-+$/, '')
    $("#artefact_slug").val(slug);
  }
  $("#artefact_name").change(generateSlug)
  $("#artefact_name").bind('keyup', generateSlug)

  $('a[rel=external]').attr('target','_blank');

  $('.flash-notice').delay(4000).slideUp(300).
    one('click', function () { $(this).slideUp(300); });

  // add sections
  $('#add-section').click(function () {
    $('.remove-section').show();
    var new_select = $('.artefact-section').first().clone(true);
    new_select.find('select option:selected').removeAttr('selected');
    new_select.insertBefore(this);
    return false;
  })

  $('.remove-section').click(function () {
    if ($('.artefact-section').size() >= 2) {
      $(this).parent().remove();
      if ($('.artefact-section').size() == 1) {
        $('.remove-section').hide();
      }
    }
    return false;
  })

});

Remove dead chosen dropdown code


$(document).ready( function () {
  $('#signup').click(function(event){
    event.preventDefault();
    $('#screen_block').show();
    $('#signup_modal').show();
  });

  $('#screen_block').click(function(event){
    event.preventDefault();

    $('#screen_block').hide();
    $('#login_modal').hide();
    $('#signup_modal').hide();
    $('#new_question_modal').hide();
  });

  $('#login').click(function(event){
    event.preventDefault();
    $('#screen_block').show();
    $('#login_modal').show();
  });

  $('.new_question_button').click(function(event){
    event.preventDefault();
    $('#screen_block').show();
    $('#new_question_modal').show();
  });
  $('form#new_question').submit(function(event){
    event.preventDefault();
    $.ajax({
      url: '/questions',
      type: 'POST',
      data: $('form#new_question').serialize(),
      dataType: 'JSON',
    }).done(function(data){
      $('ol.thumb-grid').load('/ .thumb-grid')
      clear_modals();
    }).fail(function(data){
      console.log(data);
    });
  });
});

function clear_modals(){
  $('#screen_block').hide();
    $('#login_modal').hide();
    $('#signup_modal').hide();
    $('#new_question_modal').hide();
}

$(document).ready( function () {
  $('#signup').click(function(event){
    event.preventDefault();
    $('#screen_block').show();
    $('#signup_modal').show();
  });

  $('#screen_block').click(function(event){
    event.preventDefault();
    clear_modals();
  });

  $('#login').click(function(event){
    event.preventDefault();
    $('#screen_block').show();
    $('#login_modal').show();
  });

  $('.new_question_button').click(function(event){
    event.preventDefault();
    $('#screen_block').show();
    $('#new_question_modal').show();
  });
  $('form#new_question').submit(function(event){
    event.preventDefault();
    $.ajax({
      url: '/questions',
      type: 'POST',
      data: $('form#new_question').serialize(),
      dataType: 'JSON',
    }).done(function(data){
      $('ol.thumb-grid').load('/ .thumb-grid')
      clear_modals();
    }).fail(function(data){
      console.log(data);
    });
  });
});

function clear_modals(){
  $('#screen_block').hide();
    $('#login_modal').hide();
    $('#signup_modal').hide();
    $('#new_question_modal').hide();
}

Refactor JS To have Reusuable Functions


'use strict';

var _ = require('lodash');
var fs = require('fs');
var path = require('path');

function arrayToQueryString(args) {
  var searchString = '?q=' + args._.join('+');
  if (args.user) {
    searchString = searchString.concat('+user:' + args.user);
  }
  if (args.language) {
    searchString = searchString.concat('+language:' + args.language);
  }
  return searchString;
}

function performQuery(config, request, args) {
  var url = config.API_URI + config.SEARCH_URI + arrayToQueryString(args);
  request.get(
    {
      url: url,
      headers: {
        'User-Agent': 'request',
      },
    }, function(error, response, body) {
      var result = JSON.parse(body);
      /* jshint camelcase: false */
      console.log('Found %s repositories that match your search query',
                  result.total_count || 0);
      _.forEach(result.items, function(repo) {
        console.log(repo.full_name);
      });
      /* jshint camelcase: true */
    });
}

function help() {
  console.log(fs.readFileSync(
    path.resolve(__dirname, '../templates/help-search.txt'), 'utf8'));
}

module.exports = function(config, request, args) {
  if (args.help) {
    help();
  }  else {
    performQuery(config, request, args);
  }
};

'use strict';

var _ = require('lodash');
var fs = require('fs');
var path = require('path');

function arrayToQueryString(args) {
  var searchString = '?q=' + args._.join('+');
  if (args.user) {
    searchString = searchString.concat('+user:' + args.user);
  }
  if (args.language) {
    searchString = searchString.concat('+language:' + args.language);
  }
  return searchString;
}

function performQuery(config, request, args) {
  var url = config.API_URI + config.SEARCH_URI + arrayToQueryString(args);
  request.get(
    {
      url: url,
      headers: {
        'User-Agent': 'request',
      },
    }, function(error, response, body) {
      var result = JSON.parse(body);
      /* jshint camelcase: false */
      var res = result.total_count || 0;
      console.log('Showing %d out of %d repositories ' +
                  'that match your search query',
                  Math.min(res, 30), res);
      _.forEach(result.items, function(repo) {
        console.log(repo.full_name);
      });
      /* jshint camelcase: true */
    });
}

function help() {
  console.log(fs.readFileSync(
    path.resolve(__dirname, '../templates/help-search.txt'), 'utf8'));
}

module.exports = function(config, request, args) {
  if (args.help) {
    help();
  }  else {
    performQuery(config, request, args);
  }
};

Clarify result message to show that only 30 repos are showing.


import { ATTR_KEY } from '../constants';
import { toLowerCase } from '../util';
import { ensureNodeData, getRawNodeAttributes, removeNode } from './index';

/** DOM node pool, keyed on nodeName. */

const nodes = {};

export function collectNode(node) {
	removeNode(node);

	if (node instanceof Element) {
		if (node[ATTR_KEY]) {
			ensureNodeData(node, getRawNodeAttributes(node));
		}
		node._component = node._componentConstructor = null;

		let name = node.normalizedNodeName || toLowerCase(node.nodeName);
		(nodes[name] || (nodes[name] = [])).push(node);
	}
}

export function createNode(nodeName, isSvg) {
	let name = toLowerCase(nodeName),
		node = nodes[name] && nodes[name].pop() || (isSvg ? document.createElementNS('http://www.w3.org/2000/svg', nodeName) : document.createElement(nodeName));
	ensureNodeData(node);
	node.normalizedNodeName = name;
	return node;
}

import { ATTR_KEY } from '../constants';
import { toLowerCase } from '../util';
import { ensureNodeData, getRawNodeAttributes, removeNode } from './index';

/** DOM node pool, keyed on nodeName. */

const nodes = {};

export function collectNode(node) {
	removeNode(node);

	if (node instanceof Element) {
		if (!(ATTR_KEY in node)) {
			ensureNodeData(node, getRawNodeAttributes(node));
		}
		node._component = node._componentConstructor = null;

		let name = node.normalizedNodeName || toLowerCase(node.nodeName);
		(nodes[name] || (nodes[name] = [])).push(node);
	}
}

export function createNode(nodeName, isSvg) {
	let name = toLowerCase(nodeName),
		node = nodes[name] && nodes[name].pop() || (isSvg ? document.createElementNS('http://www.w3.org/2000/svg', nodeName) : document.createElement(nodeName));
	ensureNodeData(node);
	node.normalizedNodeName = name;
	return node;
}

Fix prop cache reset triggering in the wrong case (affected performance)


/**
 * Hellosleep
 */

// Load .env for development environments
(process.env.NODE_ENV !== 'production') && require('dotenv').load();

const keystone = require('keystone');

keystone.init({

  'name': '睡吧',
  'brand': '睡吧',

  'less': 'public',
  'static': 'public',

  'views': 'templates/views',
  'view engine': 'jade',

  'port': process.env.PORT || 3000,

  'session': true,
  'auth': true,
  'user model': 'User',
  'cookie secret': '--- insomnia ---',

  'mongo': process.env.MONGO_URI || 'mongodb://localhost/hellosleep',

  'auto update': true,

//  'session store': 'mongo',

  // editor configuration
  'wysiwyg additional buttons': 'styleselect',

  'basedir': __dirname
});

keystone.import('models');

keystone.set('routes', require('./routes'));

keystone.set('locals', {
  ga: {
    property: process.env.GA_SITE_PROPERTY,
    domain: process.env.GA_SITE_DOMAIN
  },
  env: process.env.NODE_ENV || "development"
});

keystone.start();

/**
 * Hellosleep
 */

// Load .env for development environments
(process.env.NODE_ENV !== 'production') && require('dotenv').load();

const keystone = require('keystone');

keystone.init({

  'name': '睡吧',
  'brand': '睡吧',

  'less': 'public',
  'static': 'public',

  'views': 'templates/views',
  'view engine': 'jade',

  'port': process.env.PORT || 3000,

  'session': true,
  'auth': true,
  'user model': 'User',
  'cookie secret': '--- insomnia ---',

  'mongo': process.env.MONGO_URI || 'mongodb://localhost/hellosleep',

  'auto update': true,

  'session store': 'mongo',

  // editor configuration
  'wysiwyg additional buttons': 'styleselect',

  'basedir': __dirname
});

keystone.import('models');

keystone.set('routes', require('./routes'));

keystone.set('locals', {
  ga: {
    property: process.env.GA_SITE_PROPERTY,
    domain: process.env.GA_SITE_DOMAIN
  },
  env: process.env.NODE_ENV || "development"
});

keystone.start();

Use mongodb as production session store


define([
    'amber/devel',
    './deploy',
    // --- packages used only during development begin here ---
    '{%= namespace %}/{%= name %}-Tests',
    'amber-attic/IDE'
    // --- packages used only during development end here ---
], function (amber) {
    return amber;
});

define([
    'amber/devel',
    './deploy',
    // --- packages used only during development begin here ---
    '{%= namespace %}/{%= name %}-Tests',
    'amber-attic/Benchfib',
    'amber-attic/Examples',
    'amber-attic/IDE'
    // --- packages used only during development end here ---
], function (amber) {
    return amber;
});

Load Benchfib and Examples from attic as well


import Ember from 'ember';

export default Ember.Mixin.create({
  page: 0,
  size: 25,
  filter: ''
});

import Ember from 'ember';

export default Ember.Mixin.create({
  page: 0,
  size: 10,
  filter: ''
});

Set default page size to 10


function RetryOperation(timeouts) {
  this._timeouts = timeouts;
  this._fn = null;
  this._errors = [];
}
module.exports = RetryOperation;

RetryOperation.prototype.retry = function(err) {
  if (!err) {
    return false;
  }

  this._errors.push(err);

  var timeout = this._timeouts.shift();
  if (timeout === undefined) {
    return false;
  }

  setTimeout(function() {
    this._fn();
  }.bind(this), timeout);

  return true;
};

RetryOperation.prototype.try = function(fn) {
  this._fn = fn;
  this._fn();
};

RetryOperation.prototype.errors = function() {
  return this._errors;
};

RetryOperation.prototype.mainError = function() {
  if (this._errors.length === 0) {
    return null;
  }

  var counts = {};
  var mainError = null;
  var mainErrorCount = 0;

  for (var i = 0; i < this._errors.length; i++) {
    var error = this._errors[i];
    var message = error.message;
    var count = (counts[message] || 0) + 1;

    counts[message] = count;

    if (count >= mainErrorCount) {
      mainError = error;
      mainErrorCount = count;
    }
  }

  return mainError;
};

function RetryOperation(timeouts) {
  this._timeouts = timeouts;
  this._fn = null;
  this._errors = [];
}
module.exports = RetryOperation;

RetryOperation.prototype.retry = function(err) {
  if (!err) {
    return false;
  }

  this._errors.push(err);

  var timeout = this._timeouts.shift();
  if (timeout === undefined) {
    return false;
  }

  setTimeout(this._fn.bind(this), timeout);

  return true;
};

RetryOperation.prototype.try = function(fn) {
  this._fn = fn;
  this._fn();
};

RetryOperation.prototype.errors = function() {
  return this._errors;
};

RetryOperation.prototype.mainError = function() {
  if (this._errors.length === 0) {
    return null;
  }

  var counts = {};
  var mainError = null;
  var mainErrorCount = 0;

  for (var i = 0; i < this._errors.length; i++) {
    var error = this._errors[i];
    var message = error.message;
    var count = (counts[message] || 0) + 1;

    counts[message] = count;

    if (count >= mainErrorCount) {
      mainError = error;
      mainErrorCount = count;
    }
  }

  return mainError;
};

Simplify setTimeout using bind() in a useful way


function exports(sequelize, DataTypes) {
  const Response = sequelize.define('Response', {
    GuestId: DataTypes.UUID,
  }, {
    classMethods: {
      associate(models) {
        // associations can be defined here

        models.Response.belongsTo(models.Guest, { as: 'Response', foreignKey: 'GuestId' });
        models.Response.belongsTo(models.Question, { as: 'Response', foreignKey: 'QuestionId' });
        models.Response.belongsTo(models.Choice, { as: 'Response', foreignKey: 'ChoiceId' });
      },
    },
  });
  return Response;
}

module.exports = exports;

function exports(sequelize, DataTypes) {
  const Response = sequelize.define('Response', {
    GuestId: DataTypes.UUID,
  }, {
    classMethods: {
      associate(models) {
        // associations can be defined here

        models.Response.belongsTo(models.Guest);
        models.Response.belongsTo(models.Question);
        models.Response.belongsTo(models.Choice);
      },
    },
  });
  return Response;
}

module.exports = exports;

Remove explicit foreign key declarations.


// Program that identifies common element(s) that exist within both two arrays

function intersection(firstArray, secondArray) {
	var hashMap = {};
	var commonElements = [];

}

// Program that identifies common element(s) that exist within both two arrays

function intersection(firstArray, secondArray) {
	var hashMap = {};
	var commonElements = [];

	// create hashmap with elements of first array as keys
	arrOne.forEach(function(element) {
		hashMap[element] = 1;
	})
}

Create hashmap with elements of first array as keys


import React from 'react';

import { Button, ButtonGroup } from 'react-bootstrap';

const User = ({user, onEdit, onDelete}) => {

  const edit = (event) => {
    event.preventDefault();
    onEdit(event, user)
  }

  const deleteItem = () => {
    onDelete(user.id)
  }

  return (

{user.username}

{user.role} | {user.email}

      <ButtonGroup>
        <Button bsStyle="primary" onClick={edit}>Edit</Button>
        <Button bsStyle="danger" onClick={deleteItem}>Delete</Button>
      </ButtonGroup>

  )
}

export default User;

Rename driver-card to user-card for styles


/*
HTTP Strict Transport Security (HSTS)

http://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec-04

*/

module.exports = function (maxAge, includeSubdomains) {
    if (!maxAge) maxAge = '15768000'; // Approximately 6 months
    var header = "maxAge=" + maxAge;

    if (includeSubdomains) header += '; includeSubdomains';

    return function (req, res, next)  {
        if (req.connection.encrypted) {
            res.header('Strict-Transport-Security', header);
        }
        next();
    };
};

/*
HTTP Strict Transport Security (HSTS)

http://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec-04

*/

module.exports = function (maxAge, includeSubdomains) {
    if (!maxAge) maxAge = '15768000'; // Approximately 6 months
    var header = "maxAge=" + maxAge;

    if (includeSubdomains) header += '; includeSubdomains';

    return function (req, res, next)  {
        if (typeof req.secure !== "undefined" ? req.secure : req.connection.encrypted) {
            res.header('Strict-Transport-Security', header);
        }
        next();
    };
};

Use req.secure if it is set


var IPHistory = (function() {
    'use strict';

    var no_messages_error = "Your account has no Login/Logout activity.";

    function updateTable(batch) {
        IPHistoryUI.updateTable(batch);
        if (batch.length) {
            return;
        }
        $('#login-history-table tbody')
            .append($('<tr/>', {class: 'flex-tr'})
                .append($('<td/>', {colspan: 6})
                    .append($('<p/>', {
                        class: 'notice-msg center-text',
                        text: text.localize(no_messages_error)
                      })
                    )
                )
            );
    }

    function handler(response) {
        if (response.error && response.error.message) {
            document.getElementById('err').textContent = response.error.message;
            return;
        }
        updateTable(response.login_history);
    }

    // localize, title, create tables
    // register the callback on IPHistoryQueue
    function init() {
        var titleElement = document.getElementById('login_history-title').firstElementChild;
        titleElement.textContent = text.localize(titleElement.textContent);
        IPHistoryUI.createEmptyTable().appendTo('#login_history-ws-container');
        IPHistoryQueue.register(handler);
        IPHistoryQueue.fetchNext({limit: 50});
    }

    function clean() {
        $('#login_history-ws-container .error-msg').text('');
        IPHistoryUI.clearTableContent();
        IPHistoryQueue.clear();
    }

    return {
        init: init,
        clean: clean,
    };
})();

var IPHistory = (function() {
    'use strict';

    var no_messages_error = "Your account has no Login/Logout activity.";

    function updateTable(batch) {
        IPHistoryUI.updateTable(batch);
        if (batch.length) {
            return;
        }
        $('#login-history-table tbody')
            .append($('<tr/>', {class: 'flex-tr'})
                .append($('<td/>', {colspan: 6})
                    .append($('<p/>', {
                        class: 'notice-msg center-text',
                        text: text.localize(no_messages_error)
                      })
                    )
                )
            );
    }

    function handler(response) {
        if (response.error && response.error.message) {
            $('#err').text(response.error.message);
            return;
        }
        updateTable(response.login_history);
    }

    // localize, title, create tables
    // register the callback on IPHistoryQueue
    function init() {
        var $title = $('#login_history-title').children().first();
        $title.text(text.localize($title.text()));
        IPHistoryUI.createEmptyTable().appendTo('#login_history-ws-container');
        IPHistoryQueue.register(handler);
        IPHistoryQueue.fetchNext({limit: 50});
    }

    function clean() {
        $('#login_history-ws-container .error-msg').text('');
        IPHistoryUI.clearTableContent();
        IPHistoryQueue.clear();
    }

    return {
        init: init,
        clean: clean,
    };
})();

Use jQuery for misc. UI code


// audio.js
//
// data object representing an audio
//
// Copyright 2011, StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var DatabankObject = require('databank').DatabankObject;

var Audio = DatabankObject.subClass('audio');

exports.Audio = Audio;

// audio.js
//
// data object representing an audio
//
// Copyright 2011, StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var DatabankObject = require('databank').DatabankObject;

var Audio = DatabankObject.subClass('audio');

Audio.schema = {
    'pkey': 'id',
    'fields': ['author',
               'displayName',
               'embedCode',
               'published',
               'stream',
               'summary',
               'updated']
};

exports.Audio = Audio;

Add a schema to Audio


import _ from 'lodash';
import fs from 'fs';
import path from 'path';
const logger = require('../util/logger')(__filename);

const DATA_DIR = path.join(__dirname, '../../data');
const content = fs.readFileSync(path.join(DATA_DIR, 'events.json'), {encoding: 'utf8'});
let events;
try {
  events = JSON.parse(content);
} catch (e) {
  logger.error('Error when parsing events.json!');
  logger.error(content);
  throw e;
}

function getEvents() {
  return events;
}

function setAttendingCount(facebookEventId, attendingCount) {
  const event = _.find(events, { facebookId: facebookEventId });
  if (!event) {
    return;
  }

  event.attendingCount = attendingCount;
}

export {
  getEvents,
  setAttendingCount
};

import moment from 'moment';
import _ from 'lodash';
import fs from 'fs';
import path from 'path';
const logger = require('../util/logger')(__filename);

const DATA_DIR = path.join(__dirname, '../../data');
const content = fs.readFileSync(path.join(DATA_DIR, 'events.json'), {encoding: 'utf8'});
let events;
try {
  events = JSON.parse(content);
} catch (e) {
  logger.error('Error when parsing events.json!');
  logger.error(content);
  throw e;
}

function getEvents() {
  return _.filter(events, event => {
    return moment(event.endTime).diff(moment(), 'hours') > -5;
  });
}

function setAttendingCount(facebookEventId, attendingCount) {
  const event = _.find(events, { facebookId: facebookEventId });
  if (!event) {
    return;
  }

  event.attendingCount = attendingCount;
}

export {
  getEvents,
  setAttendingCount
};

Return only relevant events from api


ui.CharacterStatusDialog = function(template, _data) {
  ui.Dialog.call(this, template);

  this.name = ui.label(this, '.label.name');
  this.hp = ui.progressbar(this, '.progressbar.health');
  this.mp = ui.progressbar(this, '.progressbar.mana');
  this.xp = ui.progressbar(this, '.progressbar.exp');
  this._data = _data;
  this._update();
}

ui.CharacterStatusDialog.prototype = Object.create(ui.Dialog.prototype);

ui.CharacterStatusDialog.prototype._update = function() {
  this.name.text(this._data.name);

  this.hp.max(this._data.stats.getMaxHp());
  this.hp.value(this._data.hp);

  this.mp.max(this._data.stats.getMaxMp());
  this.mp.value(this._data.mp);

  this.xp.max(1000); // TODO: Real max xp
  this.xp.value(this._data.xp);
};

ui.characterStatusDialog = function(_data) {
  return new ui.CharacterStatusDialog('#dlgCharacterStatus', _data);
};

ui.CharacterStatusDialog = function(template, _data) {
  ui.Dialog.call(this, template);

  this.name = ui.label(this, '.label.name');
  this.hp = ui.progressbar(this, '.progressbar.health');
  this.mp = ui.progressbar(this, '.progressbar.mana');
  this.xp = ui.progressbar(this, '.progressbar.exp');
  this._data = _data;
  this._update();
}

ui.CharacterStatusDialog.prototype = Object.create(ui.Dialog.prototype);

ui.CharacterStatusDialog.prototype._update = function() {
  this.name.text(this._data.name);

  this.hp.max(this._data.stats.getMaxHp());
  this.hp.value(this._data.hp);

  this.mp.max(this._data.stats.getMaxMp());
  this.mp.value(this._data.mp);

  this.xp.max(this._data.stats.getNeedRawExp());
  this.xp.value(this._data.xp);
};

ui.characterStatusDialog = function(_data) {
  return new ui.CharacterStatusDialog('#dlgCharacterStatus', _data);
};

Use the real max xp in character status dialog


(function ($) {
    'use strict';

    setNextActivities();
    function setNextActivities() {

        $.ajax({
            url: "/next_activities"
        }).done(function (data) {
            var count = 0;
            var str = '';
            $.each(data, function (index, activity) {

                if(new Date(activity.field_date_1)>new Date() && count <=10) {
                    str += '
';
                    str += '' + activity.field_date + '	';
                    if (activity.field_lien && activity.field_lien != '') {
                        str += '' + activity.title + '	';
                    } else {
                        str += '' + activity.title + '	';
                    }
                    str += '' + activity.field_room + '	';
                    str += '
';
                    count ++;
                }
            });
            $('.tournaments-home-next table').html(str);
            setTimeout(setNextActivities, 10 * 60 * 1000); //each 10 min
        });

    }
})(jQuery);

(function ($) {
    'use strict';

    setNextActivities();
    function setNextActivities() {

        $.ajax({
            url: "/next_activities"
        }).done(function (data) {
            var count = 0;
            var str = '';
            $.each(data, function (index, activity) {

                if(new Date(activity.field_date_1)>new Date() && count <10) {
                    str += '
';
                    str += '' + activity.field_date + '	';
                    if (activity.field_lien && activity.field_lien != '') {
                        str += '' + activity.title + '	';
                    } else {
                        str += '' + activity.title + '	';
                    }
                    str += '' + activity.field_room + '	';
                    str += '
';
                    count ++;
                }
            });
            $('.tournaments-home-next table').html(str);
            setTimeout(setNextActivities, 10 * 60 * 1000); //each 10 min
        });

    }
})(jQuery);

Fix next activities bug (date filter D8 not operational)


var dbm = require('db-migrate');
var type = dbm.dataType;

exports.up = function(db, callback) {
  db.addColumn('external_transactions', 'to_account_id', {
    type: 'int'
  }, callback);
};

exports.down = function(db, callback) {
  db.addColumn('external_transactions', 'from_account_id', {
    type: 'int'
  }, callback);
};

var dbm = require('db-migrate');
var type = dbm.dataType;

exports.up = function(db, callback) {
  db.addColumn('external_transactions', 'to_account_id', {
    type: 'int'
  }, callback);
};

exports.down = function(db, callback) {
  db.removeColumn('external_transactions', 'to_account_id', callback);
};

Correct the down methods for rollback


var pmongo = require('promised-mongo');

module.exports = function(config) {

    var coll = pmongo(config.get('connexionURI')).collection(config.get('collectionName'));

	return function(req,res){

        console.info("Recherche ...");

		var xmlid = req.params.xmlid ? ("#entry-" + req.params.xmlid) : null;

		console.info("Recherche en cours sur l'id : " , xmlid , " , patientez ...");

        coll.find({})
        .toArray()
        .then(function(docs) {
            console.info("oe : " , docs.length);
        });

		/* Get mongodb files wich contain scores
        coll
        .find({ $text : { $search : xmlid } })
        .toArray()
        .then(function (docs) {
            console.info("nb docs : " , docs.length);
        	// docs.forEach(function (entity, index) { // Foreach of all docs : entity  = document
        	// 	console.log("Le mot est présent dans le doc  : " , entity.basename)
        	// });

        });*/

	};
};

var mongo = require("mongodb").MongoClient;

module.exports = function(config) {

    console.info("collection : " , config.get('connexionURI') , " / " , config.get('collectionName'));

	return function(req,res){

		var xmlid = req.params.xmlid ? ("\"#entry-" + req.params.xmlid + "\"") : null;

		console.info("Recherche sur l'id : " , xmlid , " , patientez ...");

        mongo.connect(config.get('connexionURI'), function(err, db) {
            //console.log("Connected correctly to server");
            db.collection(config.get('collectionName'))
            .find({ $text : { $search : xmlid } } , {basename : 1 , text : 1} )
            .each(function(err, item){
                if(!err && item){
                    console.info("item : ", item.basename)
                }
                else{
                    console.info("err : " , err);
                }
            })
        });

	};
};

Correct Search with phras ein mongo + use mongodb without promise


isAdmin = function (user) {
  user = (typeof user === 'undefined') ? Meteor.user() : user;
  return !!user && !!user.profile && user.profile.admin === true;
};

isAdminById = function (userId) {
  var user = Meteor.users.findOne(userId);
  return isAdmin(user);
};

isVerified = function(user) {
  return !!user && !!user.profile && user.profile.verified === true;
};

isSuperAdmin = function(user) {
  return !!user && !!user.profile && user.profile.superadmin === true;
};

isAdmin = function (user) {
  user = (typeof user === 'undefined') ? Meteor.user() : user;
  return !!user && !!user.profile && user.profile.admin === true;
};

isAdminById = function (userId) {
  var user = Meteor.users.findOne(userId);
  return isAdmin(user);
};

isVerified = function(user) {
  return !!user && !!user.profile && user.profile.verified === true;
};

isSuperAdmin = function(user) {
  user = (typeof user === 'undefined') ? Meteor.user() : user;
  return !!user && !!user.profile && user.profile.superadmin === true;
};

Check for the current user if none is passed to the function


(function(root) {

  var SessionTimeoutWarning = function () {}

  SessionTimeoutWarning.prototype.count = function () {
    root.setTimeout(this.show, 780000);  // count up to 13 minutes
  };

  SessionTimeoutWarning.prototype.show = function () {
    $('#renew-session').slideDown();
  };

  root.SessionTimeoutWarning = SessionTimeoutWarning;

})(window)

$(function() {

  if ($('body').hasClass('educator-signed-in')) {
    (new SessionTimeoutWarning).count();
  }

  $("#renew-sesion-link").click(function () {
    $.ajax({
      url: '/educators/reset',
      success: function () {
        $('#renew-session').slideUp();
      }
    });
  });
});

(function(root) {

  var SessionTimeoutWarning = function () {}

  SessionTimeoutWarning.prototype.count = function () {
    root.setTimeout(this.show, 780000);  // count up to 13 minutes
  };

  SessionTimeoutWarning.prototype.show = function () {
    $('#renew-session').slideDown();
  };

  root.SessionTimeoutWarning = SessionTimeoutWarning;

})(window)

$(function() {

  if ($('body').hasClass('educator-signed-in')) {
    var warning = new SessionTimeoutWarning;
    warning.count();
  }

  $("#renew-sesion-link").click(function () {
    $.ajax({
      url: '/educators/reset',
      success: function () {
        $('#renew-session').slideUp();
        warning.count();   // Resent timeout count
      }
    });
  });
});

Reset timeout warning count each time user renews session


app.controller("RecommendationsController", function(
    $scope, $location, $timeout, cardService, recommendationService) {
  var deckUrl = $location.search().q;
  $scope.loading = true;

  recommendationService.getRecommendations(deckUrl)
      .then(function(recommendations) {
        $scope.loading = false;
        $scope.deckUrl = deckUrl;
        $scope.recommendations = recommendations;

        // Don't run Masonry until the next digest cycle so that the
        // sections have had a chance to render.
        $timeout(function() {
          var moreRecommendations = $("#moreRecommendations #adds");
          moreRecommendations.masonry({
            itemSelector: "more-recommendations"
          });
        }, 1000);
      }).catch(function(errorMessage) {
        $scope.loading = false;
        $scope.error = errorMessage;
      });

  $scope.getCardUrl = function(name) {
    return cardService.getCardUrl(name);
  };

  $scope.getCardImage = function(name) {
    return cardService.getCardImage(name);
  };
});

app.controller("RecommendationsController", function(
    $scope, $location, $timeout, cardService, recommendationService) {
  var deckUrl = $location.search().q;
  $scope.loading = true;

  recommendationService.getRecommendations(deckUrl)
      .then(function(recommendations) {
        if (deckUrl.indexOf("http") < 0) {
          deckUrl = "http://" + deckUrl;
        }

        $scope.loading = false;
        $scope.deckUrl = deckUrl;
        $scope.recommendations = recommendations;

        // Don't run Masonry until the next digest cycle so that the
        // sections have had a chance to render.
        $timeout(function() {
          var moreRecommendations = $("#moreRecommendations #adds");
          moreRecommendations.masonry({
            itemSelector: "more-recommendations"
          });
        }, 1000);
      }).catch(function(errorMessage) {
        $scope.loading = false;
        $scope.error = errorMessage;
      });

  $scope.getCardUrl = function(name) {
    return cardService.getCardUrl(name);
  };

  $scope.getCardImage = function(name) {
    return cardService.getCardImage(name);
  };
});

Fix "your deck" link when user omits protocol


describe('validateInput', function() {
  it("is true if the input yields a valid integer when parsed", function() {
    expect(validateInput('100')).to.equal(true);
    expect(validateInput('37')).to.equal(true);
  });
});

describe('pingPongOutput', function() {
  it("is the number for most input numbers", function() {
    expect(pingPongOutput(2)).to.equal(2);
    expect(pingPongOutput(28)).to.equal(28);
  });

  it("is 'ping' for numbers divisible by 3", function() {
    expect(pingPongOutput(6)).to.equal("ping");
    expect(pingPongOutput(27)).to.equal("ping");
  });

  it("is 'pong' for numbers divisible by 5", function() {
    expect(pingPongOutput(5)).to.equal("pong");
    expect(pingPongOutput(20)).to.equal("pong");
  });

  it("is 'pingpong' for numbers divisible by 3 and 5", function() {
    expect(pingPongOutput(15)).to.equal("pingpong");
    expect(pingPongOutput(45)).to.equal("pingpong");
  });
});

describe('validateInput', function() {
  it("is true if the input yields a valid integer when parsed", function() {
    expect(validateInput('100')).to.equal(true);
    expect(validateInput('37')).to.equal(true);
  });

  it("is false if the input yields a negative number when parsed", function() {
    expect(validateInput(-33)).to.equal(false);
    expect(validateInput('-100')).to.equal(false);
  });
});

describe('pingPongOutput', function() {
  it("is the number for most input numbers", function() {
    expect(pingPongOutput(2)).to.equal(2);
    expect(pingPongOutput(28)).to.equal(28);
  });

  it("is 'ping' for numbers divisible by 3", function() {
    expect(pingPongOutput(6)).to.equal("ping");
    expect(pingPongOutput(27)).to.equal("ping");
  });

  it("is 'pong' for numbers divisible by 5", function() {
    expect(pingPongOutput(5)).to.equal("pong");
    expect(pingPongOutput(20)).to.equal("pong");
  });

  it("is 'pingpong' for numbers divisible by 3 and 5", function() {
    expect(pingPongOutput(15)).to.equal("pingpong");
    expect(pingPongOutput(45)).to.equal("pingpong");
  });
});

Add spec for negative input values


const defaultConfig = require('./default-config')
const generateLabel = require('./generate-label')

/**
 * Returns the regex, labels and config object used in every handler
 * @param {object} context - Probot context object
 * @returns {object}
 */
module.exports = async context => {
  const config = await context.config('config.yml')
  const cfg = config && config.todo ? Object.assign({}, defaultConfig, config.todo) : defaultConfig
  const labels = await generateLabel(context, cfg)
  const keywords = Array.isArray(cfg.keyword) ? cfg.keyword : [cfg.keyword]
  const reg = new RegExp(`^diff --git a\\/.+ b\\/(.+)[\\s\\S]+?^@{2}.+\\+(\\d+).+@{2}([\\s\\S]+?(^(\\+).*(${keywords.join('|')})(?:[:-\\s]+)?\\s(.*))[\\s\\S]+)`, 'gm')

  return {
    config: cfg,
    regex: reg,
    labels
  }
}

const defaultConfig = require('./default-config')
const generateLabel = require('./generate-label')

/**
 * Returns the regex, labels and config object used in every handler
 * @param {object} context - Probot context object
 * @returns {object}
 */
module.exports = async context => {
  const config = await context.config('config.yml')
  const cfg = config && config.todo ? Object.assign({}, defaultConfig, config.todo) : defaultConfig
  const labels = await generateLabel(context, cfg)
  const keywords = Array.isArray(config.keyword) ? config.keyword : [config.keyword]

  return {
    config: cfg,
    regex: new RegExp(`.+()\\s(?<keyword>${keywords.join('|')})\\s(?<title>.*)`),
    labels
  }
}

Include title regex in handler setup


var _ = require('underscore');
var OnboardingView = require('../layer-onboarding-view');
var AnalysesService = require('../../../../editor/layers/layer-content-views/analyses/analyses-service');
var template = require('./analysis-onboarding.tpl');

module.exports = OnboardingView.extend({
  events: OnboardingView.extendEvents({
    'click .js-add-analysis': '_onAddAnalysisClicked'
  }),

  initialize: function (opts) {
    OnboardingView.prototype.initialize.call(this, _.extend(opts, {
      template: template,
      numberOfSteps: 1,
      modifier: '--analysis'
    }));
  },

  _onAddAnalysisClicked: function () {
    this.clean();
    AnalysesService.addAnalysis();
  }
});

var _ = require('underscore');
var OnboardingView = require('../layer-onboarding-view');
var AnalysesService = require('../../../../editor/layers/layer-content-views/analyses/analyses-service');
var template = require('./analysis-onboarding.tpl');

module.exports = OnboardingView.extend({
  events: OnboardingView.extendEvents({
    'click .js-add-analysis': '_onAddAnalysisClicked'
  }),

  initialize: function (opts) {
    OnboardingView.prototype.initialize.call(this, _.extend(opts, {
      template: template,
      numberOfSteps: 1,
      modifier: '--analysis'
    }));
  },

  _onAddAnalysisClicked: function () {
    this._checkForgetStatus();
    this.clean();
    AnalysesService.addAnalysis();
  }
});

Check status before closing the modal


/**
 * Created by dungvn3000 on 2/11/14.
 */

Ext.define('sunerp.store.BaseStore', {
    extend: 'Ext.data.Store',
    requires: [
        'sunerp.store.Restx'
    ],
    autoLoad: false,
    remoteSort: true,
    remoteFilter: true,
    pageSize: 50,
    constructor: function () {
        this.callParent(arguments);
        this.on('metachange', function (store, meta) {
            var model = store.getNewRecords()[0];
            model.set('id', meta.id);
            model.setDirty(false);
        });
    }
});

/**
 * Created by dungvn3000 on 2/11/14.
 */

Ext.define('sunerp.store.BaseStore', {
    extend: 'Ext.data.Store',
    requires: [
        'sunerp.store.Restx'
    ],
    autoLoad: false,
    remoteSort: true,
    remoteFilter: true,
    pageSize: 100,
    constructor: function () {
        this.callParent(arguments);
        this.on('metachange', function (store, meta) {
            var model = store.getNewRecords()[0];
            model.set('id', meta.id);
            model.setDirty(false);
        });
    }
});

Set default pageSize 50 to 100.


'use strict';
// Handles params concerning configuration files in the $routeProvider phase
angular.module('arethusa.core').factory('confUrl', [
  '$route',
  function ($route) {
    return function (useDefault) {
      var params = $route.current.params;
      var confPath = './static/configs/';
      // Fall back to default and wrong paths to conf files
      // need to be handled separately eventually
      if (params.conf) {
        return confPath + params.conf + '.json';
      } else if (params.conf_file) {
        return params.conf_file;
      } else {
        if (useDefault) {
          return confPath + 'default.json';
        }
      }
    };
  }
]);

'use strict';
// Handles params concerning configuration files in the $routeProvider phase
angular.module('arethusa.core').factory('confUrl', [
  '$route',
  function ($route) {
    return function (useDefault) {
      var params = $route.current.params;
      var confPath = '../dist/configs/';
      // Fall back to default and wrong paths to conf files
      // need to be handled separately eventually
      if (params.conf) {
        return confPath + params.conf + '.json';
      } else if (params.conf_file) {
        return params.conf_file;
      } else {
        if (useDefault) {
          return confPath + 'default.json';
        }
      }
    };
  }
]);

Change path of config files