import React from 'react';
import { Link, IndexLink } from 'react-router';

import AppBar from 'material-ui/AppBar';
import IconButton from 'material-ui/IconButton';
import IconMenu from 'material-ui/IconMenu';
import MenuItem from 'material-ui/MenuItem';
import MoreVertIcon from 'material-ui/svg-icons/navigation/more-vert';
import NavigationClose from 'material-ui/svg-icons/navigation/close';

const Header = () => {
  return (
    <AppBar
    title="Kasih.in"
    iconElementLeft={<IconButton><NavigationClose /></IconButton>}
    iconElementRight={
      <IconMenu
        iconButtonElement={
          <IconButton><MoreVertIcon /></IconButton>
        }
        targetOrigin={{ horizontal: 'right', vertical: 'top' }}
        anchorOrigin={{ horizontal: 'right', vertical: 'top' }}
      >
        <MenuItem primaryText="Refresh" />
        <MenuItem primaryText="Help" />
        <MenuItem primaryText="Sign out" />
      </IconMenu>
    }
    />
  );
};

export default Header;

import React from 'react';
import { Link, IndexLink } from 'react-router';

import AppBar from 'material-ui/AppBar';
import IconButton from 'material-ui/IconButton';
import IconMenu from 'material-ui/IconMenu';
import MenuItem from 'material-ui/MenuItem';
import MoreVertIcon from 'material-ui/svg-icons/navigation/more-vert';
import NavigationClose from 'material-ui/svg-icons/navigation/close';
import { darkWhite } from 'material-ui/styles/colors';
import typography from 'material-ui/styles/typography';

const styles = {
  appBar: {
    position: 'fixed',
    top: 0,
  },
};

const Header = () => (
  <AppBar
    title="Kasih.in"
    style={styles.root}
    iconElementLeft={
    <IconButton
      containerElement={<Link to="/" />}>
      <NavigationClose />
    </IconButton>}
    iconElementRight={
      //TODO: Change the icon once you have
      <IconMenu
        iconButtonElement={
          <IconButton><MoreVertIcon /></IconButton>
        }
        targetOrigin={{ horizontal: 'right', vertical: 'top' }}
        anchorOrigin={{ horizontal: 'right', vertical: 'top' }}
      >
        <MenuItem
          primaryText="About"
          containerElement={<Link to="/about" />}
        />
        <MenuItem primaryText="Sign out" />
      </IconMenu>
    }
    />
);

export default Header;

Add styling and some navigation to header.


/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import {resolve} from 'path';

const TOOL_ROOT = resolve(__dirname, "../");
const FLOW_ROOT = resolve(__dirname, "../../../");
export const defaultTestsDirName = "newtests";

// This is where we look for tests to run and where we put newly converted
// tests
export function getTestsDir(relative_to?: string): string {
  if (relative_to !== undefined) {
    return resolve(relative_to, defaultTestsDirName);
  } else {
    return resolve(FLOW_ROOT, defaultTestsDirName);
  }
}

export const binOptions: Array<string> = [
  resolve(FLOW_ROOT, "bin/flow"), // Open source build
  resolve(FLOW_ROOT, "bin/flow.exe"), // Open source windows build
  resolve(FLOW_ROOT, "../buck-out/gen/flow/flow/flow"), // Buck
];

export const defaultFlowConfigName = "_flowconfig";

/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 * @format
 */

import {dirname, join, resolve} from 'path';

const FLOW_ROOT = resolve(__dirname, '../../../');
export const defaultTestsDirName = 'newtests';

// This is where we look for tests to run and where we put newly converted
// tests
export function getTestsDir(relative_to?: string): string {
  if (relative_to !== undefined) {
    return resolve(relative_to, defaultTestsDirName);
  } else {
    return dirname(require.resolve(join(defaultTestsDirName, 'package.json')));
  }
}

export const binOptions: Array<string> = [
  resolve(FLOW_ROOT, 'bin/flow'), // Open source build
  resolve(FLOW_ROOT, 'bin/flow.exe'), // Open source windows build
  resolve(FLOW_ROOT, '../buck-out/gen/flow/flow/flow'), // Buck
];

export const defaultFlowConfigName = '_flowconfig';

Allow workspaces outside of the workspace root


// 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. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require tether
//= require_tree ./application

// 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. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require_tree ./application

Remove javascript requirement for tether.


'use strict'

const serverlessLog = require('../serverlessLog.js')

module.exports = class InProcessRunner {
  constructor(functionName, handlerPath, handlerName) {
    this._functionName = functionName
    this._handlerName = handlerName
    this._handlerPath = handlerPath
  }

  run(event, context, callback) {
    // TODO error handling? when module and/or function is not found
    // lazy load handler with first usage

    let handler

    try {
      handler = require(this._handlerPath)[this._handlerName] // eslint-disable-line
    } catch (err) {
      if (err.code === 'MODULE_NOT_FOUND') {
        serverlessLog.errorLog(
          `Could not find handler module '${this._handlerPath}' for function '${this._functionName}'.`,
        )
      }

      throw err
    }

    if (typeof handler !== 'function') {
      throw new Error(
        `offline: handler '${this._handlerName}' in ${this._handlerPath} is not a function`,
      )
    }

    return handler(event, context, callback)
  }
}

'use strict'

module.exports = class InProcessRunner {
  constructor(functionName, handlerPath, handlerName) {
    this._functionName = functionName
    this._handlerName = handlerName
    this._handlerPath = handlerPath
  }

  run(event, context, callback) {
    // check if the handler module path exists
    if (!require.resolve(this._handlerPath)) {
      throw new Error(
        `Could not find handler module '${this._handlerPath}' for function '${this._functionName}'.`,
      )
    }

    // lazy load handler with first usage
    const handler = require(this._handlerPath)[this._handlerName] // eslint-disable-line

    if (typeof handler !== 'function') {
      throw new Error(
        `offline: handler '${this._handlerName}' in ${this._handlerPath} is not a function`,
      )
    }

    return handler(event, context, callback)
  }
}

Fix handler module path check, was broken for module not found in handler


/* Check for trailing spaces
 */

module.exports = function (filename, body, config, callback) {
    // Check each line for trailing spaces

    var re = /\s$/,
        lines = body.split('\n'),
        errors = [];

    for (var i = 0; i < lines.length; i += 1) {
        if (re.test(lines[i])) {
            errors.push({
                filename: filename,
                line: i + 1,
                character: lines[i].length,
                message: "Trailing whitespace.",
                context: lines[i]
            });
        }
    }

    return callback(undefined, errors);
};

/* Check for trailing spaces
 */
module.exports = function (filename, body, config, callback) {
    var re = /\s$/,
        lines = body.split('\n'),
        errors = [];

    for (var i = 0; i < lines.length; i += 1) {
        if (re.test(lines[i])) {
            errors.push({
                filename: filename,
                line: i + 1,
                character: lines[i].length,
                message: "Trailing whitespace.",
                context: lines[i]
            });
        }
    }

    return callback(undefined, errors);
};

Clean up code a wee bit.


/*
 * fc-autocomplete
 * https://github.com/djembuka/fc-autocomplete
 *
 * Copyright (c) 2014 Tatiana
 * Licensed under the MIT license.
 */

(function($) {

  // Collection method.
  $.fn.fc_autocomplete = function() {
    return this.each(function(i) {
      // Do something awesome to each selected element.
      $(this).html('awesome' + i);
    });
  };

}(jQuery));

/*
 * fc-autocomplete
 * https://github.com/djembuka/fc-autocomplete
 *
 * Copyright (c) 2014 Tatiana
 * Licensed under the MIT license.
 */

(function($) {

  // Collection method.
  $.fn.fc_autocomplete = function() {
    return this.each(function(i) {
      // Do something awesome to each selected element.
      $(this).html('awesome' + i);
    });
  };

  // Static method.
  $.fc_autocomplete = function(options) {
    // Override default options with passed-in options.
    options = $.extend({}, $.fc_autocomplete.options, options);
    // Return something awesome.
    return 'awesome' + options.punctuation;
  };

  // Static method default options.
  $.fc_autocomplete.options = {
    punctuation: '.'
  };

  // Custom selector.
  $.expr[':'].fc_autocomplete = function(elem) {
    // Is this element awesome?
    return $(elem).text().indexOf('awesome') !== -1;
  };

}(jQuery));

Fix main js file to pass tests


var common     = require('../common');
var connection = common.createConnection();
var assert     = require('assert');

var length = Math.pow(256, 3) / 2; // Half, because of hex encoding
var buffer = new Buffer(length);
var sql    = 'SELECT ? as bigField';

var rows = [];

// Nesting the query inside the connect() method because our buffer to hex shim
// for node v0.4.x takes ~12sec on TravisCI causing a handshake timeout unless
// we do the handshake first before creating the SQL query.
connection.connect(function(err) {
  if (err) throw err;

  connection.query(sql, [buffer], function(err, _rows) {
    if (err) throw err;

    rows = _rows;
  });

  connection.end();
});

process.on('exit', function() {
  assert.equal(rows.length, 1);
  assert.equal(rows[0].bigField.length, length);
});

var common     = require('../common');
var connection = common.createConnection();
var assert     = require('assert');

connection.connect(function(err) {
  if (err) throw err;

  getMaxAllowedPacket();
});

var oldMaxAllowedPacket;
function getMaxAllowedPacket() {
  connection.query('SHOW VARIABLES WHERE Variable_name = ?', ['max_allowed_packet'], function(err, rows) {
    if (err) throw err;

    oldMaxAllowedPacket = Number(rows[0].Value);

    increaseMaxAllowedPacketIfNeeded();
  });
}

function increaseMaxAllowedPacketIfNeeded() {
  // Our test generates a SQL query a few bytes larger than 16 MB, but lets
  // leave a little margin:
  var minMaxAllowedPacket = 20 * 1024 * 1024;

  var newMaxAllowedPacket = (oldMaxAllowedPacket < minMaxAllowedPacket)
    ? minMaxAllowedPacket
    : oldMaxAllowedPacket;

  connection.query('SET GLOBAL max_allowed_packet = ?', [newMaxAllowedPacket], function(err, rows) {
    if (err) throw err;

    triggerLargeQueryAndResponsePackets();
  });
}

var rows = [];
var length = Math.pow(256, 3) / 2; // Half, because of hex encoding
var buffer = new Buffer(length);
var sql    = 'SELECT ? as bigField';

function triggerLargeQueryAndResponsePackets() {
  connection.query(sql, [buffer], function(err, _rows) {
    if (err) throw err;

    rows = _rows;

    resetMaxAllowedPacket();
  });
}

function resetMaxAllowedPacket() {
  connection.query('SET GLOBAL max_allowed_packet = ?', [oldMaxAllowedPacket], function(err, rows) {
    if (err) {
      err.message = 'Could not reset max_allowed_packet size, please check your server settings: ' + err.message;
      throw err;
    }
  });

  connection.end();
}

process.on('exit', function() {
  assert.equal(rows.length, 1);
  assert.equal(rows[0].bigField.length, length);
});

Adjust max_allowed_packet size if needed


/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.
 */

/**
 * @namespace The global safeJSON namespace
 * @type {Object}
 */
var safeJSON = window['safeJSON'];

/**
 * @namespace The global tamings___ namespace
 * @type {Array.<Function>}
 */
var tamings___ = window['tamings___'] || [];

/**
 * @namespace The global bridge___ namespace
 * @type {Object}
 */
var bridge___;

/**
 * @namespace The global caja___ namespace
 * @type {Object}
 */
var caja = window['caja___'];

/**
 * @namespace The global ___ namespace
 * @type {Object}
 */
var ___ = window['___'];

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.
 */

/**
 * @namespace The global safeJSON namespace
 * @type {Object}
 */
var safeJSON = window['safeJSON'];

/**
 * @namespace The global tamings___ namespace
 * @type {Array.<Function>}
 */
var tamings___ = window['tamings___'] || [];

/**
 * @namespace The global bridge___ namespace
 * @type {Object}
 */
var bridge___;

/**
 * @namespace The global caja___ namespace
 * @type {Object}
 */
var caja___ = window['caja___'];

/**
 * @namespace The global ___ namespace
 * @type {Object}
 */
var ___ = window['___'];

Correct caja global var. caja___ is what is used, and not having this declared will cause dynamic JS compilation warnings/errors.


Elm.Native.Trampoline = {};
Elm.Native.Trampoline.make = function(elm) {
    elm.Native = elm.Native || {};
    elm.Native.Trampoline = elm.Native.Trampoline || {};
    if (elm.Native.Trampoline.values) return elm.Native.Trampoline.values;

    // trampoline : Trampoline a -> a
    trampoline = function(t) {
        var tramp = t;
        while(true) {
            switch(tramp.ctor) {
            case "Done":
                return tramp._0;
            case "Continue":
                tramp = tramp._0({ctor: "_Tuple0"});
                continue;
            }
        }
    }

    return elm.Native.Trampoline.values = { trampoline: trampoline };
};

Elm.Native.Trampoline = {};
Elm.Native.Trampoline.make = function(elm) {
    elm.Native = elm.Native || {};
    elm.Native.Trampoline = elm.Native.Trampoline || {};
    if (elm.Native.Trampoline.values) return elm.Native.Trampoline.values;

    // trampoline : Trampoline a -> a
    var trampoline;
    trampoline = function(t) {
        var tramp = t;
        while(true) {
            switch(tramp.ctor) {
            case "Done":
                return tramp._0;
            case "Continue":
                tramp = tramp._0({ctor: "_Tuple0"});
                continue;
            }
        }
    }

    return elm.Native.Trampoline.values = { trampoline: trampoline };
};

Declare the trampoline variable before using it.


/*
 * Export your react-router routes here.
 */

import React from 'react';
import {Route} from 'react-router';

import App from '../views/App';

export default (
  <Route handler={App}>

    <Route
      path="/"
      component={require('../views/Home/Handler').default} />

  </Route>
);

/*
 * Export your react-router routes here.
 */

import React from 'react';
import {Route} from 'react-router';

import App from '../views/App';

export default (
  <Route component={App}>

    <Route
      path="/"
      component={require('../views/Home/Handler').default} />

  </Route>
);

Fix App component not being used due to typo'd prop name


import {BatchedStateMachine} from './batched-state-machine'

export function createBatchedStateMachineCache(stateMachineConfig) {
  const cache = {}

  return {
    get(cacheKey, initialConfig) {
      if (cache[cacheKey]) {
        return cache[cacheKey]
      }

      const stateMachine = new BatchedStateMachine(stateMachineConfig, initialConfig)
      cache[cacheKey] = stateMachine

      return stateMachine
    },
  }
}

import {BatchedStateMachine} from './batched'

export function createBatchedStateMachineCache(stateMachineConfig) {
  const cache = {}

  return {
    get(cacheKey, initialConfig) {
      if (cache[cacheKey]) {
        return cache[cacheKey]
      }

      const stateMachine = new BatchedStateMachine(stateMachineConfig, initialConfig)
      cache[cacheKey] = stateMachine

      return stateMachine
    },
  }
}

Fix broken require in createBatchedCache


var exec    = require('child_process').exec;
var path    = require('path');
var extend  = require('xtend');
var command = require('language-command');

/**
 * Execute a file in a particular programming language.
 *
 * @param {String}   language
 * @param {String}   file
 * @param {String}   args
 * @param {Object}   opts
 * @param {Function} done
 */
module.exports = function (language, file, args, opts, done) {
  // Support for skipping arguments and options.
  if (typeof args === 'function') {
    done = args;
    args = null;
    opts = null;
  }

  // Support for skipping options.
  if (typeof opts === 'function') {
    done = opts;
    opts = null;
  }

  var cmd = command(language, file, args);

  // Pass back the language unsupported error in an async fashion.
  if (cmd == null) {
    return done(new Error('Language not supported'));
  }

  return exec(cmd, extend({
    cwd: path.dirname(file)
  }, opts), done);
};

var exec    = require('child_process').exec;
var path    = require('path');
var extend  = require('xtend');
var command = require('language-command');

/**
 * Execute a file in a particular programming language.
 *
 * @param {String}   language
 * @param {String}   file
 * @param {Array}    args
 * @param {Object}   opts
 * @param {Function} done
 */
module.exports = function (language, file, args, opts, done) {
  // Support for skipping arguments and options.
  if (typeof args === 'function') {
    done = args;
    args = null;
    opts = null;
  }

  // Support for skipping options.
  if (typeof opts === 'function') {
    done = opts;
    opts = null;
  }

  // Reverse options and arguments.
  if (typeof args === 'object' && !Array.isArray(args)) {
    opts = args;
    args = null;
  }

  var cmd = command(language, file, args);

  // Pass back the language unsupported error in an async fashion.
  if (cmd == null) {
    return done(new Error('Language not supported'));
  }

  return exec(cmd, extend({
    cwd: path.dirname(file)
  }, opts), done);
};

Support args in different orders


hljs.initHighlightingOnLoad();

var metrics_url = "http://metrics.bioboxes.org/v1/containers.json"

$.getJSON(metrics_url, function(json) {
  var downloads = _.last(json['total']['value']);
  $('#downloads-count').text(downloads);
});

hljs.initHighlightingOnLoad();

var metrics_url = "http://metrics.bioboxes.org/v1/containers.json";

$.getJSON(metrics_url, function(json) {
  var downloads = _.last(json['total']['value']);
  $('#downloads-count').text(downloads);
});

Add missing semicolon in js


exports.seed = knex =>
  knex.transaction((trx) => {
    knex('role').transacting(trx).insert({
      id: 1,
      name: 'Professor',
    })
    .then(trx.commit)
    .catch(
      (err) => {
        trx.rollback();
        console.error(err);
        process.exit(1);
      }
    );
  });

exports.seed = knex =>
  knex.transaction((trx) => {
    knex('role').transacting(trx).insert({
      id: 1,
      name: 'professor',
    })
    .then(trx.commit)
    .catch(
      (err) => {
        trx.rollback();
        console.error(err);
        process.exit(1);
      }
    );
  });

Update test seed to use 'professor' as role name.


// @flow

const logger = require('../logger');
const R = require('ramda');
const sshpk = require('sshpk');
const bodyParser = require('body-parser');

const toFingerprint = sshKey =>
  sshpk
    .parseKey(sshKey, 'ssh')
    .fingerprint()
    .toString();

const keysRoute = async (req, res) => {
  const { fingerprint } = req.body;
  const cred = req.credentials;

  if (cred.role !== 'admin') {
    throw new Error('Unauthorized');
  }

  if (!fingerprint) {
    return res.status(500).send('Missing parameter "fingerprint"');
  }

  const dao = req.app.get("context").dao;

  logger.debug(`Accessing keys with fingerprint: ${fingerprint}`);

  const context = req.context;

  const sshKeys = await dao.getCustomerSshKeys(cred);

  const fingerprintKeyMap = R.compose(
    R.fromPairs,
    R.map(sshKey => [toFingerprint(sshKey), sshKey]),
  )(sshKeys);

  const result = R.propOr('', fingerprint, fingerprintKeyMap);

  if (!result) {
    logger.debug(`Unknown fingerprint: ${fingerprint}`);
  }

  res.send(result);
};

module.exports = [bodyParser.json(), keysRoute];

// @flow

const logger = require('../logger');
const R = require('ramda');
const sshpk = require('sshpk');
const bodyParser = require('body-parser');

const toFingerprint = sshKey => {
  try {
    return sshpk
      .parseKey(sshKey, 'ssh')
      .fingerprint()
      .toString();
  } catch(e) {
    logger.error(`Invalid ssh key detected: ${sshKey}`);
  }
}

const keysRoute = async (req, res) => {
  const { fingerprint } = req.body;
  const cred = req.credentials;

  if (cred.role !== 'admin') {
    throw new Error('Unauthorized');
  }

  if (!fingerprint) {
    return res.status(500).send('Missing parameter "fingerprint"');
  }

  const dao = req.app.get("context").dao;

  logger.debug(`Accessing keys with fingerprint: ${fingerprint}`);

  const context = req.context;

  const sshKeys = await dao.getCustomerSshKeys(cred);

  const fingerprintKeyMap = R.compose(
    R.fromPairs,
    R.reject(([fingerprint]) => fingerprint === undefined),
    R.map(sshKey => [toFingerprint(sshKey), sshKey]),
  )(sshKeys);

  const result = R.propOr('', fingerprint, fingerprintKeyMap);

  if (!result) {
    logger.debug(`Unknown fingerprint: ${fingerprint}`);
  }

  res.send(result);
};

module.exports = [bodyParser.json(), keysRoute];

Add error recovery for wrongly formatted sshKeys


//= require ./app/init
//= require_tree ./app

$(document).on('turbolinks:load', function() {

  $('.bread_hover').hover(function(e) {
    $('.bread_links a').attr('aria-expanded', true);
    $('.line_browser').velocity("fadeIn", { duration: 50 });
  }, function(e) {
    $('.bread_links a').attr('aria-expanded', false);
    $('.line_browser').velocity("fadeOut", { duration: 50 });
  });

});

Fix year_breadcrumb in Gobierto Indicators


// js/directives/nw-category-item.directive

(function() {
  "use strict";

  angular.module("NoteWrangler")
    .directive("nwCategoryItem", nwCategoryItemDirective);

  //nwCategoryItemDirective.$inject = ["Category"];

  function nwCategoryItemDirective() {
    return {
      replace: true,
      restrict: "E",
      templateUrl: "/templates/directives/nw-category-item.directive.html",
      scope: {
        category: "="
      }
    }
  }
});

// js/directives/nw-category-item.directive

(function() {
  "use strict";

  angular.module("NoteWrangler")
    .directive("nwCategoryItem", nwCategoryItemDirective);

  nwCategoryItemDirective.$inject = ["Category"];

  function nwCategoryItemDirective() {
    return {
      replace: true,
      restrict: "E",
      templateUrl: "../templates/directives/nw-category-item.directive.html",
      scope: {
        category: "="
      },
      require: "^nwCategorySelect",
      link: (scope, element, attrs, nwCategorySelectCtrl) => {
        scope.makeActive = () => {
          nwCategorySelectCtrl.setActiveCategory(scope.category);
        };

        scope.categoryActive = () => {
          return nwCategorySelectCtrl.setActiveCategory(scope.category) === scope.category.name;
        };
      }
    }
  }
})();

Edit templateUrl value. Add require, link values. Add nwCategoryItemDirective.


import Immutable from 'seamless-immutable';
import { actionTypes } from '../actions';

const initialState = Immutable({
  show: false,
  message: null,
  explanation: null,
  leftButton: null,
  rightButton: null
});

const defaultRightButton = {
  label: "~BUTTON.OK",
  action: "dismissModalDialog"
};

export default function modalDialog(state = initialState, action) {
  switch (action.type) {
    case actionTypes.MODAL_DIALOG_SHOWN:
      return state.merge({
        show: true,
        message: action.message,
        explanation: action.explanation,
        rightButton: action.rightButton || defaultRightButton,
        leftButton: action.leftButton,
        showAward: action.showAward,
        top: action.top
      });
    case actionTypes.GUIDE_MESSAGE_RECEIVED:
      if (action.data) {
        return state.merge({
          show: true,
          message: "Message from ITS",
          explanation: action.data.message.asString(),
          rightButton: defaultRightButton
        });
      }
      else
        return state;
    case actionTypes.MODAL_DIALOG_DISMISSED:
      return initialState;
    // actions which don't close the dialog, i.e. that can occur
    // while a dialog is being shown
    case actionTypes.BASKET_SELECTION_CHANGED:
    case actionTypes.DRAKE_SELECTION_CHANGED:
      return state;
    // Assume for now that all other actions also close dialog
    default:
      return initialState;
  }
}

import Immutable from 'seamless-immutable';
import { actionTypes } from '../actions';
import urlParams from '../utilities/url-params';

const initialState = Immutable({
  show: false,
  message: null,
  explanation: null,
  leftButton: null,
  rightButton: null
});

const defaultRightButton = {
  label: "~BUTTON.OK",
  action: "dismissModalDialog"
};

export default function modalDialog(state = initialState, action) {
  switch (action.type) {
    case actionTypes.MODAL_DIALOG_SHOWN:
      return state.merge({
        show: true,
        message: action.message,
        explanation: action.explanation,
        rightButton: action.rightButton || defaultRightButton,
        leftButton: action.leftButton,
        showAward: action.showAward,
        top: action.top
      });
    case actionTypes.GUIDE_MESSAGE_RECEIVED:
      if (action.data && urlParams.showITS === "true") {
        return state.merge({
          show: true,
          message: "Message from ITS",
          explanation: action.data.message.asString(),
          rightButton: defaultRightButton
        });
      }
      else
        return state;
    case actionTypes.MODAL_DIALOG_DISMISSED:
      return initialState;
    // actions which don't close the dialog, i.e. that can occur
    // while a dialog is being shown
    case actionTypes.BASKET_SELECTION_CHANGED:
    case actionTypes.DRAKE_SELECTION_CHANGED:
      return state;
    // Assume for now that all other actions also close dialog
    default:
      return initialState;
  }
}

Hide ITS messages for now unless `showITS` url param


import React from "react"

export default class FormErrorList extends React.Component {
  displayName = "Frig.FormErrorList"

  static defaultProps = {
    // This is the property of `errors` where Frig will look for form-level errors.
    // Set to "base" by default, for compatibility with Active Record.
    name: "base",
  }

  static contextTypes = {
    frigForm: React.PropTypes.shape({
      errors: React.PropTypes.object.isRequired,
    }).isRequired,
  }

  _errorsArray() {
    const { errors } = this.context.frigForm
    const { name } = this.props
    return errors.hasOwnProperty(name)
      ? errors.base
      : []
  }

  render() {
    const ThemedErrorList = this.context.frigForm.theme.component("errors")
    return <ThemedErrorList errors={this._errorsArray()} />
  }
}

import React from "react"

export default class FormErrorList extends React.Component {
  displayName = "Frig.FormErrorList"

  static defaultProps = {
    // This is the property of `errors` where Frig will look for form-level errors.
    // Set to "base" by default, for compatibility with Active Record.
    name: "base",
  }

  static contextTypes = {
    frigForm: React.PropTypes.shape({
      errors: React.PropTypes.object.isRequired,
    }).isRequired,
  }

  _errorsArray() {
    const { errors } = this.context.frigForm
    const { name } = this.props
    return errors[name] || []
  }

  render() {
    const ThemedErrorList = this.context.frigForm.theme.component("errors")
    return <ThemedErrorList errors={this._errorsArray()} />
  }
}

Fix <FormErrorList/> always looking at `base` field


import { Controller } from "stimulus";

export default class extends Controller {
  static targets = ["source", "select"];
  static values = { options: Array };

  handleSelectChange() {
    this.populateSelect(parseInt(this.sourceTarget.value));
  }

  populateSelect(sourceId) {
    this.removeCurrentOptions()

    this.dependantOptionsFor(sourceId).forEach((item) => {
      this.addOption(item[0], item[1])
    });
  }

  removeCurrentOptions() {
    this.selectTarget.innerHTML = ""
  }

  addOption(label, value) {
    const newOption = document.createElement("option")
    newOption.innerHTML = label
    newOption.value = value
    this.selectTarget.appendChild(newOption)
  }

  dependantOptionsFor(sourceId) {
    return this.optionsValue.find((option) => option[0] === sourceId)[1]
  }
}

import { Controller } from "stimulus";

export default class extends Controller {
  static targets = ["source", "select"];
  static values = { options: Array };

  handleSelectChange() {
    this.populateSelect(parseInt(this.sourceTarget.value));
  }

  // private

  populateSelect(sourceId) {
    this.removeCurrentOptions()
    this.populateNewOptions(sourceId)
  }

  removeCurrentOptions() {
    this.selectTarget.innerHTML = ""

    this.selectTarget.tomselect?.clear()
    this.selectTarget.tomselect?.clearOptions()
  }

  populateNewOptions(sourceId) {
    const options = this.dependantOptionsFor(sourceId)

    options.forEach((item) => {
      this.addOption(item[0], item[1])
    });

    this.selectTarget.tomselect?.sync()
    this.selectTarget.tomselect?.addItem(options[0]?.[1])
  }

  addOption(label, value) {
    const newOption = document.createElement("option")
    newOption.innerHTML = label
    newOption.value = value
    this.selectTarget.appendChild(newOption)
  }

  dependantOptionsFor(sourceId) {
    return this.optionsValue.find((option) => option[0] === sourceId)[1]
  }
}

Refactor dependant-selector further and (conditionally) update TomSelect if present


var HangarXPLOR = HangarXPLOR || {};

// Pre-process all the items in a document, then load the next page, or render the UI
HangarXPLOR.ProcessPage = function($page, pageNo)
{
  var $items = $('.list-items > li', $page);

  $items.each(HangarXPLOR.ProcessItem);

  if ($items.length < 10)
  {
    HangarXPLOR.DrawUI();
  } else {
    HangarXPLOR.LoadPage(pageNo + 1);
  }
}

var HangarXPLOR = HangarXPLOR || {};

// Pre-process all the items in a document, then load the next page, or render the UI
HangarXPLOR.ProcessPage = function($page, pageNo)
{
  var isEmpty = $('.list-items > li > .empy-list', $page).length > 0;

  var $items = $('.list-items > li', $page);

  $items.each(HangarXPLOR.ProcessItem);

  if (isEmpty || $items.length < 10)
  {
    HangarXPLOR.DrawUI();
  } else {
    HangarXPLOR.LoadPage(pageNo + 1);
  }
}

Add additional check for empty pages


let transitServiceColor = {
  'CORE - METRORAIL': 'red',
  'CORE - METRORAPID': '#f24d6e',
  'CORE - LIMITED': '#649dce',
  'CORE - RADIAL': '#5190c8',
  'CORE - FEEDER': '#3d84c2',
  'CORE - EXPRESS/FLYERS': '#3777ae',
  'CORE - CROSSTOWN': '#77a9d4',
  'SPECIAL - REVERSE COMMUTE': '#6c9452',
  'SPECIAL - RAIL CONNECTORS': '#4b874b',
  'SPECIAL - EBUS': '#42775b',
  'SPECIAL - NIGHT OWLS': '#7ec87e',
  'SPECIAL - SENIOR': '#70b18e',
  'UT - CIRCULATORS': '#ffbb4f',
  'UT - RADIALS': '#af823c'
}

export default function(datum) {
  for (let i = 0; i < datum.length; i++) {
    let data = datum[i];
    let color = 'purple';
    if (transitServiceColor.hasOwnProperty(data.key)) {
      color = transitServiceColor[data.key];
    }
    data.color = color;
  }
  return datum;
}

import transitServiceColors from 'capmetrics-web/utils/service-colors';

export default function(datum) {
  for (let i = 0; i < datum.length; i++) {
    let data = datum[i];
    let color = 'purple';
    if (transitServiceColors.hasOwnProperty(data.key)) {
      color = transitServiceColors[data.key];
    }
    data.color = color;
  }
  return datum;
}

Switch to an import of transit colors from util module.


// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --allow-natives-syntax --turbo-filter=*

function foo() {
  with ({ value:"fooed" }) { return value; }
}

%OptimizeFunctionOnNextCall(foo);
assertEquals("fooed", foo());
assertOptimized(foo);

function bar() {
  with ({ value:"bared" }) { return value; }
}

assertEquals("bared", bar());
%OptimizeFunctionOnNextCall(bar);
assertEquals("bared", bar());
// TODO(mstarzinger): Still not optimized, make sure it is.
// assertOptimized(bar);

// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --allow-natives-syntax --turbo-filter=*

function foo() {
  with ({ value:"fooed" }) { return value; }
}

%OptimizeFunctionOnNextCall(foo);
assertEquals("fooed", foo());
// TODO(mstarzinger): Still not optimized, make sure it is.
// assertOptimized(foo);

function bar() {
  with ({ value:"bared" }) { return value; }
}

assertEquals("bared", bar());
%OptimizeFunctionOnNextCall(bar);
assertEquals("bared", bar());
// TODO(mstarzinger): Still not optimized, make sure it is.
// assertOptimized(bar);

Disable new test failing since 79748e3f7ced.


// Copyright 2014-2015 runtime.js project authors
//
// 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.

'use strict';

/* global isolate, runtime */
console.log = isolate.log;
var resources = require('./resources');
require('./polyfill');

var tty = require('./tty');
var keyboard = require('./keyboard');
var ps2 = require('./ps2');
var pci = require('./pci');
var net = require('./net');
var StdIO = require('./stdio');

function Runtime() {
  this.tty = tty;
  this.keyboard = keyboard;
  this.pci = pci;
  this.ps2 = ps2;
  this.allocator = resources.allocator;
  this.net = net;
  this.bufferAddress = runtime.bufferAddress; // fixme
  this.debug = runtime.debug; // fixme
  this.machine = {
    reboot: resources.natives.reboot,
    shutdown: function() {
      resources.acpi.enterSleepState(5);
    }
  };
  this.stdio = new StdIO();
}

global.runtime = module.exports = new Runtime();

// Copyright 2014-2015 runtime.js project authors
//
// 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.

'use strict';

/* global isolate, runtime */
console.log = isolate.log;
var resources = require('./resources');
require('./polyfill');

var tty = require('./tty');
var keyboard = require('./keyboard');
var ps2 = require('./ps2');
var pci = require('./pci');
var net = require('./net');
var StdIO = require('./stdio');

global.stdio = new StdIO();

function Runtime() {
  this.tty = tty;
  this.keyboard = keyboard;
  this.pci = pci;
  this.ps2 = ps2;
  this.allocator = resources.allocator;
  this.net = net;
  this.bufferAddress = runtime.bufferAddress; // fixme
  this.debug = runtime.debug; // fixme
  this.machine = {
    reboot: resources.natives.reboot,
    shutdown: function() {
      resources.acpi.enterSleepState(5);
    }
  };
  this.stdio = global.stdio;
}

global.runtime = module.exports = new Runtime();

Make `stdio` a global, point `runtime.stdio` to it


import React from 'react'

export default function Styleable(Component, defaultStyles) {
  function Styled(props) {
    const {styles, ...rest} = props // eslint-disable-line react/prop-types
    return <Component styles={{...styles, ...defaultStyles}} {...rest} />
  }
  Object.assign(Styled, Component)
  Styled.displayName = `Styleable(${Component.displayName || Component.name})`
  return Styled
}

import React from 'react'

export default function Styleable(Component, defaultStyles) {
  function Styled(props) {
    const {styles, ...rest} = props // eslint-disable-line react/prop-types
    return <Component styles={{...defaultStyles, ...styles}} {...rest} />
  }
  Object.assign(Styled, Component)
  Styled.displayName = `Styleable(${Component.displayName || Component.name})`
  return Styled
}

Fix wrong order of extending defaults


;(function($) {

    /*
        @name : checkRadio
        @function : check or uncheck checkbox & radio inputs
        @params : no params
    */
    function checkRadio() {
        if($('input[type="radio"], input[type="checkbox"]').length) {
            $('input[type="radio"], input[type="checkbox"]').each(function(i,el){
                if($(this).is(':checked'))
                    $(this).parent().addClass('checked'); // add .checked class to <label>
                else
                    $(this).parent().removeClass('checked'); // remove .checked class to <label>
            });
        }
    }

    $(function(){
        /*!
            -- @ CHECK RADIO && CHECKBOX INPUTS @ --
        */
        if($('input[type="radio"], input[type="checkbox"]').length) {
            /* DOM ready : Check radio if already checked */
            checkRadio();

            $('input[type="radio"], input[type="checkbox"]').on('click',function(e){
                checkRadio();
            });
        }

        /*!
            -- @ Close alerts @ --
        */
        $('.alert .close').on('click',function(e){
            e.preventDefault();

            $(this).parent().fadeOut(500,function(){
                $(this).remove();
            });
        });

        /*!
            -- @ Modals @ --
        */
        /* Open modal */
        $('button.modal-open').on('click',function(e){
            e.preventDefault();

            var modal = $(this).data('target');

            if($('#'+modal).length) {
                $('body').addClass('opened-modal');
                $('#'+modal).addClass('active');
            } else {
                alert('ChuckCSS error : modal with attribute id="'+modal+'" is not defined!');
            }
        });
        /* Close modal */
        $('.modal:not([data-disabled-overlay])')
            .find('.modal-overlay')
            .add('.modal .modal-close')
            .on('click',function(e) {

                if($(this).parent().hasClass('active'))
                    $(this).parent().removeClass('active');

                if(!$('.modal.active').length)
                    $('body').removeClass('opened-modal');
            });

    });
})(jQuery);

;(function($) {
    $(function(){

        /*!
            -- @ Close alerts @ --
        */
        $('.alert .close').on('click',function(e){
            e.preventDefault();

            $(this).parent().fadeOut(500,function(){
                $(this).remove();
            });
        });

        /*!
            -- @ Modals @ --
        */
        /* Open modal */
        $('button.modal-open').on('click',function(e){
            e.preventDefault();

            var modal = $(this).data('target');

            if($('#'+modal).length) {
                $('body').addClass('opened-modal');
                $('#'+modal).addClass('active');
            } else {
                alert('ChuckCSS error : modal with attribute id="'+modal+'" is not defined!');
            }
        });
        /* Close modal */
        $('.modal:not([data-disabled-overlay])')
            .find('.modal-overlay')
            .add('.modal .modal-close')
            .on('click',function(e) {

                if($(this).parent().hasClass('active'))
                    $(this).parent().removeClass('active');

                if(!$('.modal.active').length)
                    $('body').removeClass('opened-modal');
            });

    });
})(jQuery);

Add JS for close alerts


import { Controller } from "@hotwired/stimulus";
import { Transition } from "./utils/transition";

export default class ShowHideController extends Controller {
  static targets = ["content", "priceBand"];

  togglePriceBand() {
    this.toggle(this.priceBandTarget)
  }

  toggleContent() {
    this.toggle(this.contentTarget)
  }

  toggle(element) {
    const hide = element.toggleAttribute("data-collapsed");

    // cancel previous animation, if any
    if (this.transition) this.transition.cancel();

    const transition = this.transition = new Transition(element)
      .addCallback("starting", function () {
        element.setAttribute("data-collapsed-transitioning", "true")
      })
      .addCallback("complete", function () {
        element.removeAttribute("data-collapsed-transitioning")
      });
    hide ? transition.collapse() : transition.expand();

    transition.start();
  }
}

import { Controller } from "@hotwired/stimulus";
import { Transition } from "./utils/transition";

export default class ShowHideController extends Controller {
  static targets = ["content"];

  toggleContent() {
    this.toggle(this.contentTarget)
  }

  toggle(element) {
    const hide = element.toggleAttribute("data-collapsed");

    // cancel previous animation, if any
    if (this.transition) this.transition.cancel();

    const transition = this.transition = new Transition(element)
      .addCallback("starting", function () {
        element.setAttribute("data-collapsed-transitioning", "true")
      })
      .addCallback("complete", function () {
        element.removeAttribute("data-collapsed-transitioning")
      });
    hide ? transition.collapse() : transition.expand();

    transition.start();
  }
}

Remove FRG specific functionality from show-hide controller


'use strict';

var request = require( 'request' );

module.exports = {
    baseUrl : 'http://www.hltv.org/?pageid=255&res=5&team=1&term=',
    search : function( searchPhrase, callback ){
        var _this = this,
            rawTeamList = false,
            teamList = [],
            i;

        request( _this.baseUrl + searchPhrase, function( error, response, teams ) {
            rawTeamList = JSON.parse( teams );

            for( i = 0; i < rawTeamList.length; i = i + 1 ){
                teamList.push({
                    name : rawTeamList[ i ].name,
                    id : rawTeamList[ i ].teamid,
                    country : rawTeamList[ i ].country
                });
            }

            callback.call( this, teamList );
        });
    }
};

'use strict';

var request = require( 'request' );

module.exports = {
    baseUrl : 'http://www.hltv.org/?pageid=255&res=5&team=1&term=',
    search : function( searchPhrase, callback ){
        var _this = this,
            rawTeamList = false,
            teamList = [],
            i;

        request( _this.baseUrl + encodeURIComponent( searchPhrase ), function( error, response, teams ) {
            rawTeamList = JSON.parse( teams );

            for( i = 0; i < rawTeamList.length; i = i + 1 ){
                teamList.push({
                    name : rawTeamList[ i ].name,
                    id : rawTeamList[ i ].teamid,
                    country : rawTeamList[ i ].country
                });
            }

            callback.call( this, teamList );
        });
    }
};

Make the HLTV search escape uri fragments


var server = require('../server');

server.listen(3000);
console.log('Listening on port 3000');

Add a message to indicate the server is listening


'use strict'

var isInteger = require('is-integer')

module.exports = function parseIntStrict (int) {
  if (typeof int === 'number') {
    return isInteger(int) ? int : undefined
  }
  if (typeof int === 'string') {
    return /^\d+$/.test(int) ? parseInt(int, 10) : undefined
  }
}

'use strict'

var isInteger = require('is-integer')

module.exports = function parseIntStrict (integer) {
  if (typeof integer === 'number') {
    return isInteger(integer) ? integer : undefined
  }
  if (typeof integer === 'string') {
    return /^\d+$/.test(integer) ? parseInt(integer, 10) : undefined
  }
}

Replace "int" variable name with "integer"


var fs = require('fs');
var path = require('path');
var Stream = require('stream');

function statdir(dir, names, cb) {
  var entries = [];

  names.forEach(function(name) {
    var relName = path.join(dir, name);

    fs.lstat(relName, function(err, stats) {
      entries.push({name: relName, isDir: stats && stats.isDirectory()});
      if (entries.length == names.length) cb(entries);
    });
  });
}

module.exports = function(root) {
  var s = new Stream;
  s.readable = true

  function recurse(dir, done) {
    fs.readdir(dir, function (err, names) {
      // TODO: emit err
      if (!names) {
        done();
        return;
      }

      statdir(dir, names, function(entries) {
        var files = entries.filter(function(entry) {
          return !entry.isDir;
        });
        var subdirs = entries.filter(function(entry) {
          return entry.isDir;
        });

        files.forEach(function(entry) {
          s.emit('data', entry.name);
        });

        if (!subdirs.length) done();

        subdirs.forEach(function(subdir, i) {
          recurse(subdir.name, function() {
            if (i == subdirs.length - 1) done();
          });
        });
      });
    });
  }

  recurse(root, function() {
    s.emit('end');
  });

  return s;
}

var fs = require('fs');
var path = require('path');
var Stream = require('stream');

function statdir(dir, names, cb) {
  var entries = [];

  names.forEach(function(name) {
    var relName = path.join(dir, name);

    fs.lstat(relName, function(err, stats) {
      entries.push({name: relName, isDir: stats && stats.isDirectory()});
      if (entries.length == names.length) cb(entries);
    });
  });
}

module.exports = function(root) {
  var s = new Stream;
  s.readable = true

  function recurse(dir, done) {
    fs.readdir(dir, function (err, names) {
      // TODO: emit err

      statdir(dir, names, function(entries) {
        var files = entries.filter(function(entry) {
          return !entry.isDir;
        });
        var subdirs = entries.filter(function(entry) {
          return entry.isDir;
        });

        files.forEach(function(entry) {
          s.emit('data', entry.name);
        });

        if (!subdirs.length) done();

        subdirs.forEach(function(subdir, i) {
          recurse(subdir.name, function() {
            if (i == subdirs.length - 1) done();
          });
        });
      });
    });
  }

  recurse(root, function() {
    s.emit('end');
  });

  return s;
}

Remove error handling for now.


module.exports = {
	extends: 'airbnb-base',
	plugins: [
		'mocha',
	],
	env: {
		node: true,
		mocha: true,
	},
	rules: {
		strict: [0, 'global'],
		indent: [1, 'tab', { SwitchCase: 1, VariableDeclarator: 1 }],
		'no-tabs': 0,
		'no-plusplus': 0,
		'arrow-body-style': [2, 'as-needed', { requireReturnForObjectLiteral: true }],
		'arrow-parens': [2, 'as-needed', { requireForBlockBody: true }],
		'no-console': [1, { allow: ['warn'] }],
		'max-len': [2, 160, 2, {
			ignoreUrls: true,
			ignoreComments: false,
		}],
		'no-underscore-dangle': ['error', { allow: ['_id'], allowAfterThis: true, allowAfterSuper: true }],
		'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
		'import/named': 2,
		'mocha/no-exclusive-tests': 'error',
		'no-restricted-syntax': [
			'error',
			'ForInStatement',
			'LabeledStatement',
			'WithStatement',
		],
		'no-await-in-loop': 0,
	},
};

module.exports = {
	extends: 'airbnb-base',
	plugins: [
		'mocha',
	],
	env: {
		node: true,
		mocha: true,
	},
	rules: {
		strict: [0, 'global'],
		indent: [1, 'tab', { SwitchCase: 1, VariableDeclarator: 1 }],
		'no-tabs': 0,
		'no-plusplus': 0,
		'arrow-body-style': [2, 'as-needed', { requireReturnForObjectLiteral: true }],
		'arrow-parens': [2, 'as-needed', { requireForBlockBody: true }],
		'no-console': [1, { allow: ['warn'] }],
		'max-len': [2, 160, 2, {
			ignoreUrls: true,
			ignoreComments: false,
		}],
		'no-underscore-dangle': ['error', { allow: [
			'_id',
			'_index',
			'_score',
			'_shards',
			'_source',
			'_type',
		], allowAfterThis: true, allowAfterSuper: true }],
		'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
		'import/named': 2,
		'mocha/no-exclusive-tests': 'error',
		'no-restricted-syntax': [
			'error',
			'ForInStatement',
			'LabeledStatement',
			'WithStatement',
		],
		'no-await-in-loop': 0,
	},
};

Add dangling underscore exceptions for elasticsearch results


"use strict";

var Hapi = require("hapi");
var halacious = require("halacious");
var fs = require("fs");
var MongoDbConnection = require("./lib/services/mongoDb");

const config = require("./etc/conf.json");

var server = new Hapi.Server();

server.connection(config.connection);

server.register(halacious, function registerHalacious(error) {
  if (error) {
    return console.log(error);
  }

  var ns = server.plugins.halacious.namespaces.add({
    name: "undefined",
    description: "Hackathon",
    prefix: "hack"
  });

  ns.rel({ name: "qaid", description: "A collection of questions" });
  ns.rel({ name: "question", description: "A question" });
  ns.rel({ name: "answer", description: "An answer" });
});

fs.readdir("./lib/resources/", function getFiles(error, files) {
  if (error) {
    throw error;
  }

  files.forEach(function getFile(file) {
    if (file.includes(".js") < 0) {
      return;
    }

    server.route(require("./lib/resources/" + file));
  });
});

MongoDbConnection.connect((error) => {
  if (error) {
    process.exit(2);
  }

  // Start the Server
  server.start(() => console.log("Server running at:", server.info.uri));
});

"use strict";

var Hapi = require("hapi");
var halacious = require("halacious");
var fs = require("fs");
var MongoDbConnection = require("./lib/services/mongoDb");

const config = require("./etc/conf.json");

var server = new Hapi.Server();

server.connection(config.connection);

server.register(halacious, function registerHalacious(error) {
  if (error) {
    return console.log(error);
  }

  var ns = server.plugins.halacious.namespaces.add({
    name: "Coolblue",
    description: "Hackathon",
    prefix: "hack"
  });

  ns.rel({ name: "qaid", description: "A collection of questions" });
  ns.rel({ name: "question", description: "A question" });
  ns.rel({ name: "answer", description: "An answer" });
});

fs.readdir("./lib/resources/", function getFiles(error, files) {
  if (error) {
    throw error;
  }

  files.forEach(function getFile(file) {
    if (file.includes(".js") < 0) {
      return;
    }

    server.route(require("./lib/resources/" + file));
  });
});

MongoDbConnection.connect((error) => {
  if (error) {
    process.exit(2);
  }

  // Start the Server
  server.start(() => console.log("Server running at:", server.info.uri));
});

Change namespace name to Coolblue


module.exports = function(source) {
  this.cacheable();

  if (this.resource.split('/').indexOf('views') < 0) {
    return source;
  }

  var viewName = this.resource.split('/')
                              .slice(-3)
                              .slice(0, 2)
                              .join('/');

  var before = 'body[data-view-name="' + viewName + '"] {';
  var after = '}';

  return [].concat(before, source, after).join('\n');
};

module.exports = function(source) {
  this.cacheable();

  if (this.resource.split('/').indexOf('views') < 0) {
    return source;
  }

  var viewName = this.resource.split('/')
                              .slice(-3)
                              .slice(0, 2)
                              .join('/');

  var before = '[data-view-name="' + viewName + '"] {';
  var after = '}';

  return [].concat(before, source, after).join('\n');
};

Remove body on injected style so html tag can be used


function r() {
	var strings = arguments[0];
	var values = Array.prototype.slice.call(arguments, 1);

	// concentrate strings and interpolations
	var str = strings.raw.reduce(function(prev, cur, idx) {
		return prev + values[idx-1] + cur;
	})
	.replace(/\r\n/g, '\n');

	var newlineAndTabs = str.match(/^\n[\t]*/);

	if( newlineAndTabs != null ) {
		var matched = newlineAndTabs[0];

		str = str.replace(new RegExp(matched, 'g'), '\n').substr(1);
	}

	else {
		var matched = str.match(/^[\t]*/)[0];

		str = str.substr(matched.length).replace(new RegExp('\n'+matched, 'g'), '\n');
	}

	return str;
}

module.exports = r;

function r() {
	var strings = arguments[0];									// template strings
	var values = Array.prototype.slice.call(arguments, 1);	// interpolation values

	// concentrate strings and interpolations
	var str = strings.raw.reduce(function(prev, cur, idx) {
		return prev + values[idx-1] + cur;
	})
	.replace(/\r\n/g, '\n'); // replace for window newline \r\n

	// check top-tagged applied
	var newlineAndTabs = str.match(/^\n[\t]*/);

	if( newlineAndTabs != null ) {
		var matched = newlineAndTabs[0];

		str = str.replace(new RegExp(matched, 'g'), '\n')
				.substr(1);
	}

	else {
		var matched = str.match(/^[\t]*/)[0];

		str = str.substr(matched.length)
				.replace(new RegExp('\n'+matched, 'g'), '\n');
	}

	return str;
}

module.exports = r;

Add comments for dev and clear codes.


'use strict';

module.exports = {
  name: 'ilios-common',

  included: function() {
    this._super.included.apply(this, arguments);
  },
};

'use strict';

module.exports = {
  name: 'ilios-common',

  included: function() {
    this._super.included.apply(this, arguments);
  },

  contentFor(type, config) {
    let emberGoogleFonts = this.addons.find((a) => a.name === 'ember-cli-google-fonts');
    return emberGoogleFonts.contentFor(type, config);
  }
};

Call contentFor when we are nested


var ai = ai || {};  //!< @namespace ai

ai.init = function(){
  setInterval("ai._mainLoop();", 1000 / 120);
  setInterval("api.keepPlay();", 1000 / 60);
  ai.speedDroping = false;
}

ai._mainLoop = function(){
  obs = api.getObstacles();
  if (obs.length != 0){
    var bound = 280 * (api.getCurrentSpeed() / Runner.config.MAX_SPEED);
    var distance = (obs[0].xPos + obs[0].width) - api.getPlayer().xPos;
    var player = api.getPlayer();
    if (0 < distance && distance < bound && obs[0].yPos != 50 && obs[0].yPos != 75 && player.status != 'JUMPING'){
      api.duckStop();
      api.jump();
    }
    else if (player.status == 'JUMPING'){
      if (player.xPos > obs[0].xPos + obs[0].width && !this.speedDroping){
        api.speedDrop();
        this.speedDroping = true;
      }
    }
    else{
      this.speedDroping = false;
      api.duck();
    }
  }
}

var ai = ai || {};  //!< @namespace ai

ai.init = function(){
  setInterval("ai._mainLoop();", 1000 / 120);
  setInterval("api.keepPlay();", 1000 / 60);
  ai.speedDroping = false;
}

ai._mainLoop = function(){
  obs = api.getObstacles();
  if (obs.length != 0){
    var bound = 350 * (api.getCurrentSpeed() / Runner.config.MAX_SPEED);
    var distance = (obs[0].xPos + obs[0].width) - api.getPlayer().xPos;
    var next = 0;
    if (distance < 0)
      next = 1;
    distance = (obs[next].xPos + obs[next].width) - api.getPlayer().xPos;
    var player = api.getPlayer();
    if (0 < distance && distance < bound && obs[next].yPos != 50 && obs[next].yPos != 75 && player.status != 'JUMPING'){
      api.duckStop();
      api.jump();
    }
    else if (player.status == 'JUMPING'){
      if (player.xPos > obs[0].xPos + obs[0].width / 2 && !this.speedDroping){
        api.speedDrop();
        this.speedDroping = true;
      }
    }
    else{
      this.speedDroping = false;
      api.duck();
    }
  }
}

Fix bug: dont use obs[0] as first obstacle


goog.provide('go_map_directive');

goog.require('go');

goModule.directive('goMap',
    /**
     * @return {angular.Directive} The directive specs.
     */
    function() {
      return {
        restrict: 'E',
        template: '

',
        scope: {
          'm': '=goMapMap'
        },
        link:
            /**
             * @param {angular.Scope} scope Scope.
             * @param {angular.JQLite} element Element.
             * @param {angular.Attributes} attrs Attributes.
             */
            function(scope, element, attrs) {
              /** @type {ol.Map} */
              var map = scope['m'];
              goog.asserts.assertInstanceof(map, ol.Map);

              map.setTarget(element.children()[0]);
            }
      };
    });

goog.provide('go_map_directive');

goog.require('go');

goModule.directive('goMap', ['goDefaultMap',
  /**
   * @param {string} goDefaultMap Default map constant.
   * @return {angular.Directive} The directive specs.
   */
  function(goDefaultMap) {
    return {
      restrict: 'A',
      link:
          /**
           * @param {angular.Scope} scope Scope.
           * @param {angular.JQLite} element Element.
           * @param {angular.Attributes} attrs Attributes.
           */
          function(scope, element, attrs) {
            var attr = 'goMap';
            var prop = attrs[attr] || goDefaultMap;

            /** @type {ol.Map} */
            var map = scope[prop];
            goog.asserts.assertInstanceof(map, ol.Map);

            map.setTarget(element[0]);
          }
    };
  }]);

Make goMap a directive of type A


const service = require('feathers-mongoose');
const Pseudonym = require('./model');
const hooks = require('./hooks');

module.exports = function () {
	const app = this;
	const options = {
		Model: Pseudonym,
		paginate: {
			default: 1000,
			max: 1000,
		},
	};

	app.use('/pseudonym', service(options));

	const pseudonymService = app.service('/pseudonym');
	pseudonymService.hooks(hooks);
};

const service = require('feathers-mongoose');
const Pseudonym = require('./model');
const hooks = require('./hooks');

module.exports = function () {
	const app = this;
	const options = {
		Model: Pseudonym,
		paginate: {
			default: 1000,
			max: 1000,
		},
		lean: false,
	};

	app.use('/pseudonym', service(options));

	const pseudonymService = app.service('/pseudonym');
	pseudonymService.hooks(hooks);
};

Make pseudonym service not lean


"use strict";

var m      = require("mithril"),

    id    = require("./id"),
    hide  = require("./hide"),
    label = require("./label"),

    css = require("./types.css");

module.exports = function(args, view) {
    return {
        controller : function(options) {
            var ctrl = this;

            ctrl.id = id(options);

            // Decorate children w/ their selection status
            ctrl.selected = function(opts) {
                var details = opts.details,
                    values  = opts.data,
                    matches;

                if(!values) {
                    return;
                }

                matches = details.children.filter(function(opt) {
                    if(!args.multiple) {
                        return opt.value === values;
                    }

                    return values[opt.key] === opt.value;
                });

                if(!args.multiple && matches.length) {
                    matches.length = 1;
                }

                details.children = details.children.map(function(opt) {
                    opt.selected = matches.indexOf(opt) > -1;

                    return opt;
                });
            };

            ctrl.value = function(opts, key, value) {
                return opts.update(
                    args.multiple ? opts.path.concat(key) : opts.path,
                    value
                );
            };
        },

        view : function(ctrl, options) {
            var hidden  = hide(options);

            if(hidden) {
                return hidden;
            }

            ctrl.selected(options);

            return m("div", { class : options.class },
                label(ctrl, options),
                view(ctrl, options)
            );
        }
    };
};

"use strict";

var m      = require("mithril"),

    id    = require("./id"),
    hide  = require("./hide"),
    label = require("./label"),

    css = require("./types.css");

module.exports = function(args, view) {
    return {
        controller : function(options) {
            var ctrl = this;

            ctrl.id = id(options);

            // Decorate children w/ their selection status
            ctrl.selected = function(opts) {
                var field  = opts.field,
                    values = opts.data,
                    matches;

                if(!values) {
                    return;
                }

                matches = field.children.filter(function(opt) {
                    if(!args.multiple) {
                        return opt.value === values;
                    }

                    return values[opt.key] === opt.value;
                });

                if(!args.multiple && matches.length) {
                    matches.length = 1;
                }

                field.children = field.children.map(function(opt) {
                    opt.selected = matches.indexOf(opt) > -1;

                    return opt;
                });
            };

            ctrl.value = function(opts, key, value) {
                return opts.update(
                    args.multiple ? opts.path.concat(key) : opts.path,
                    value
                );
            };
        },

        view : function(ctrl, options) {
            var hidden  = hide(options);

            if(hidden) {
                return hidden;
            }

            ctrl.selected(options);

            return m("div", { class : options.class },
                label(ctrl, options),
                view(ctrl, options)
            );
        }
    };
};

Fix a missed details -> field switchover


enyo.kind({
	name: "enyo.sample.PlatformSample",
	kind: "FittableRows",
	classes: "enyo-fit platform-sample",
	components: [
		{classes: "platform-sample-divider", content: "Enyo Platform Detection"},
		{kind: "onyx.Groupbox", components: [
			{kind: "onyx.GroupboxHeader", content: "User-Agent String"},
			{name: "uaString", content: "", style: "padding: 8px;"}
		]},
		{tag: "br"},
		{kind: "onyx.Groupbox", components: [
			{kind: "onyx.GroupboxHeader", content: "enyo.platform"},
			{name: "enyoPlatformJSON", content: "", style: "padding: 8px;"}
		]}
	],
	create: function() {
		this.inherited(arguments);
		this.$.uaString.setContent(navigator.userAgent);
		this.$.enyoPlatformJSON.setContent(JSON.stringify(enyo.platform));
	}
});

enyo.kind({
	name: "enyo.sample.PlatformSample",
	kind: "FittableRows",
	classes: "enyo-fit platform-sample",
	components: [
		{classes: "platform-sample-divider", content: "Enyo Platform Detection"},
		{kind: "onyx.Groupbox", components: [
			{kind: "onyx.GroupboxHeader", content: "User-Agent String"},
			{name: "uaString", content: "", style: "padding: 8px;"}
		]},
		{tag: "br"},
		{kind: "onyx.Groupbox", components: [
			{kind: "onyx.GroupboxHeader", content: "Window"},
			{name: "windowAttr", content: "", style: "padding: 8px;"}
		]},
		{tag: "br"},
		{kind: "onyx.Groupbox", components: [
			{kind: "onyx.GroupboxHeader", content: "enyo.platform"},
			{name: "enyoPlatformJSON", content: "", style: "padding: 8px;"}
		]}
	],
	create: function() {
		this.inherited(arguments);
		this.$.uaString.setContent(navigator.userAgent);
		this.$.windowAttr.setContent("size: " + window.innerWidth + "x" + window.innerHeight +
			", devicePixelRatio: " + window.devicePixelRatio);
		this.$.enyoPlatformJSON.setContent(JSON.stringify(enyo.platform));
	}
});

Add window size and devicePixelRatio to platform sample output


const _ = require('lodash');

module.exports = function parseSectionName(sectionName, name = '') {
  const ret = sectionName + name;

  // Root exception (/)
  return ret.length > 1 ? _.trimStart(ret, '/') : ret;
};

const _ = require('lodash');

module.exports = function parseSectionName(sectionName, name = '') {
  // Root (/) exception
  if (sectionName === '/' && !name) {
    return sectionName;
  }

  const ret = sectionName + '/' + name;
  const trimmed = _.trim(ret, '/');

  return trimmed.length ? trimmed : ret;
};

Allow section name to be separated easier


export default function normalizeTabControllerClick() {
	const hashLinks = document.querySelectorAll(".js-tabs-control a[href^='#']");
	const firstLink = document.querySelector('.js-tabs-control > a');

	function setActiveLink(event) {
		Array.prototype.forEach.call(hashLinks, (link) => {
			link.classList.remove('active');
		});
		event.target.classList.add('active');
	}

	Array.prototype.forEach.call(hashLinks, (link) => {
		link.addEventListener('click', (event) => {
			event.preventDefault();
			setActiveLink(event);
			window.history.pushState({}, '', link.href);

			// Update the URL again with the same hash, then go back
			window.history.pushState({}, '', link.href);
			window.history.back();
		});
	});

	if (window.location.hash) return;
	if (firstLink) firstLink.click();
}

export default function normalizeTabControllerClick() {
	const hashLinks = document.querySelectorAll(".js-tabs-control a[href^='#']");
	const firstLink = document.querySelector('.js-tabs-control > a');

	function setActiveLink(event) {
		Array.prototype.forEach.call(hashLinks, (link) => {
			link.classList.remove('active');
		});
		event.target.classList.add('active');
	}

	Array.prototype.forEach.call(hashLinks, (link) => {
		link.addEventListener('click', (event) => {
			event.preventDefault();
			setActiveLink(event);
			window.history.pushState({}, '', link.href);

			// Update the URL again with the same hash, then go back
			window.history.pushState({}, '', link.href);
			window.history.back();
		});
	});

	if (window.location.hash) return;
	if (firstLink) firstLink.click();
	if (firstLink) firstLink.classList.add('active');
}

Add class active to first tabs link


// Adds toggle for custom theme to Page Action.
//
// This file *only* controls that toggle,
// the logic behind enabling/disabling the theme is found in
// core/js/customThemeHandler.js

var customThemeToggle = (function(){
  var optionsLink = document.getElementById("options-link");
  var enableTheme = document.getElementById("enable-theme");

  chrome.storage.local.get("cmCustomThemeEnabled", function(response){
    var themeIsEnabled = !!response.cmCustomThemeEnabled;
    enableTheme.checked = themeIsEnabled;
    setEventListeners();
  });

  function setEventListeners() {
    optionsLink.addEventListener("click", function(e){

      // needed to prevent the click from propagating to the checkbox
      e.preventDefault();

      //http://stackoverflow.com/a/16130739
      var optionsUrl = chrome.extension.getURL('core/html/ces_options.html');
      chrome.tabs.query({url: optionsUrl}, function(tabs) {
        if (tabs.length) {
          chrome.tabs.update(tabs[0].id, {active: true});
        } else {
          chrome.tabs.create({url: optionsUrl});
        }
      });
    });

    enableTheme.addEventListener("click", function(){
      chrome.storage.local.set({"cmCustomThemeEnabled":enableTheme.checked}, function(){
        sendToActiveTab({method:"enable-custom-theme", data:enableTheme.checked});
      });
    });
  }
})();

// Adds toggle for custom theme to Page Action.
//
// This file *only* controls that toggle,
// the logic behind enabling/disabling the theme is found in
// core/js/customThemeHandler.js

var customThemeToggle = (function(){
  var optionsLink = document.getElementById("options-link");
  var enableTheme = document.getElementById("enable-theme");

  chrome.storage.local.get("cmCustomThemeEnabled", function(response){
    enableTheme.checked = !!response.cmCustomThemeEnabled;
    setEventListeners();
  });

  function setEventListeners() {

    // Need to manually add link functionality to the options page link.
    // Alternatively, could just dynamically add the URL-- I'm not sure it matters much though.
    optionsLink.addEventListener("click", function(e){

      // needed to prevent the click from propagating to the checkbox
      e.preventDefault();

      //http://stackoverflow.com/a/16130739
      var optionsUrl = chrome.extension.getURL('core/html/ces_options.html');
      chrome.tabs.query({url: optionsUrl}, function(tabs) {
        if (tabs.length) {
          chrome.tabs.update(tabs[0].id, {active: true});
        } else {
          chrome.tabs.create({url: optionsUrl});
        }
      });
    });

    enableTheme.addEventListener("click", function(){
      chrome.storage.local.set({"cmCustomThemeEnabled":enableTheme.checked}, function(){
        sendToActiveTab({method:"enable-custom-theme", data:enableTheme.checked});
      });
    });
  }
})();

Remove superfluous variable, improve documentation


const jstPlugin = require('rollup-plugin-jst');
const jst = jstPlugin();

module.exports = {
  process(data, id) {
    return jst.transform(data, id).replace('export default', 'module.exports =');
  }
};

const jstPlugin = require('rollup-plugin-jst');
const jst = jstPlugin();

module.exports = {
  process(data, id) {
    return jst.transform(data, id).replace('export default', 'var I18n = require("i18n-js").default; module.exports =');
  }
};

Allow accessing I18n in jst files during test


import styles from './styles/PaneItem.css'
import listStyles from './styles/ListView.css'
import PropTypes from 'prop-types'
import React from 'react'
import Ink from 'react-ink'
import {StateLink} from 'part:@sanity/base/router'
import {Item as GridListItem} from 'part:@sanity/components/lists/grid'

export default function PaneItemWrapper(props) {
  const {useGrid, linkState, layout, isSelected} = props
  const link = (
    <StateLink state={linkState} className={isSelected ? styles.linkIsSelected : styles.link}>
      {props.children}
      <Ink duration={1000} opacity={0.1} radius={200} />
    </StateLink>
  )

  return useGrid ? (
    <GridListItem className={listStyles[`${layout}ListItem`]}>{link}</GridListItem>
  ) : (

{link}

  )
}

PaneItemWrapper.propTypes = {
  layout: PropTypes.string,
  useGrid: PropTypes.bool,
  isSelected: PropTypes.bool,
  linkState: PropTypes.object,
  children: PropTypes.node
}

import styles from './styles/PaneItem.css'
import listStyles from './styles/ListView.css'
import PropTypes from 'prop-types'
import React from 'react'
// import Ink from 'react-ink'
import {StateLink} from 'part:@sanity/base/router'
import {Item as GridListItem} from 'part:@sanity/components/lists/grid'

export default function PaneItemWrapper(props) {
  const {useGrid, linkState, layout, isSelected} = props
  const link = (
    <StateLink state={linkState} className={isSelected ? styles.linkIsSelected : styles.link}>
      {props.children}
      {/* <Ink duration={1000} opacity={0.1} radius={200} /> */}
    </StateLink>
  )

  return useGrid ? (
    <GridListItem className={listStyles[`${layout}ListItem`]}>{link}</GridListItem>
  ) : (

{link}

  )
}

PaneItemWrapper.propTypes = {
  layout: PropTypes.string,
  useGrid: PropTypes.bool,
  isSelected: PropTypes.bool,
  linkState: PropTypes.object,
  children: PropTypes.node
}

Remove Ink on Pane items


import React from 'react';

import StatusIcon from '@ichef/gypcrete/src/StatusIcon';
import DebugBox from 'utils/DebugBox';

export default {
    title: '@ichef/gypcrete|StatusIcon',
    component: StatusIcon,
};

export function BasicStatusIcon() {
    return (

            <StatusIcon status="loading" />
            <StatusIcon status="success" autohide={false} />
            <StatusIcon status="error" />

    );
}

export function StatusIconInCorner() {
    return (

            <DebugBox width={32} height={32}>
                <StatusIcon status="loading" position="corner" />
            </DebugBox>
            <DebugBox width={32} height={32}>
                <StatusIcon status="success" position="corner" autohide={false} />
            </DebugBox>
            <DebugBox width={32} height={32}>
                <StatusIcon status="error" position="corner" />
            </DebugBox>

    );
}

import React, { useState } from 'react';

import StatusIcon from '@ichef/gypcrete/src/StatusIcon';

import Button from '@ichef/gypcrete/src/Button';
import DebugBox from 'utils/DebugBox';
import FlexRow from 'utils/FlexRow';

export default {
    title: '@ichef/gypcrete|StatusIcon',
    component: StatusIcon,
};

export function BasicStatusIcon() {
    return (

            <StatusIcon status="loading" />
            <StatusIcon status="success" autohide={false} />
            <StatusIcon status="error" />

    );
}

export function StatusIconInCorner() {
    return (

            <DebugBox width={32} height={32}>
                <StatusIcon status="loading" position="corner" />
            </DebugBox>
            <DebugBox width={32} height={32}>
                <StatusIcon status="success" position="corner" autohide={false} />
            </DebugBox>
            <DebugBox width={32} height={32}>
                <StatusIcon status="error" position="corner" />
            </DebugBox>

    );
}

export function AutoHideSuccessIcon() {
    const [status, setStatus] = useState('error');
    return (
        <FlexRow>
            <StatusIcon status={status} />
            <Button
                color="blue"
                solid
                style={{ display: 'inline-block' }}
                onClick={() => setStatus('success')}
            >
                Make it success
            </Button>
            <Button
                color="red"
                solid
                style={{ display: 'inline-block' }}
                onClick={() => setStatus('error')}
            >
                Make it error
            </Button>
        </FlexRow>
    );
}
AutoHideSuccessIcon.story = {
    parameters: {
        docs: {
            // eslint-disable-next-line no-multi-str
            storyDescription: 'In this example, prop `autohide` is `true`, initially <StatusIcon> is loading; \
            When make it success, after a while(~2s) it will hide; \
            Then if you make it error it shows again.',
        }
    }
};

Add autohide example for StatusIcon


/*$(document).ready(function() {
    /!*$("ul#tabs li").click(function(e){
        if (!$(this).hasClass("active")) {
            var tabNum = $(this).index();
            var nthChild = tabNum+1;
            $("ul#tabs li.active").removeClass("active");
            $(this).addClass("active");
            $("ul#tab li.active").removeClass("active");
            $("ul#tab li:nth-child("+nthChild+")").addClass("active");
        }
    });*!/
});*/

 //function for clone input fields for standard query creation
$(document).ready(function() {

    // add multiple select / deselect functionality
    $("#selectAll").click(function () {
          $('.case').prop('checked', this.checked);
    });
    // if all checkbox are selected, check the selectall checkbox
    // and viceversa
    $(".case").click(function(){
        if($(".case").length == $(".case:checked").length) {
            $("#selectAll").prop("checked", "checked");
        } else {
            $("#selectAll").removeProp("checked");
        }
    });

    //if operator selector changed
    $("#standard_builder").change(function(){
        //find option selected
        var type = $(this).find("option:selected").val();
        //if not undefines
        if(type != undefined){
            //clone keyword box and place after last operator selector
            $("#standard_keywords").clone().insertAfter('#standard_builder:last-child').val('');
            //clone operator box and place after new keyword box, true passes on action listener to new child
            $($(this)).clone(true).insertAfter('#standard_keywords:last-child');
            //disable action listener for current operator selector
            $(this).off();
        }
    });

    //delete table row if deletebutton with id containing deleteQuery
    $("[id*='deleteQuery']").click(function(){
        //var of delete buttons td parent
        var td=$(this).parent();
         //var of td tr parent
        var tr=td.parent();

        //fade and remove row
        tr.fadeOut(400, function(){
            tr.remove()
        })
    });

    $('textarea').numberedtextarea({
        // if true Tab key creates indentation
        allowTabChar: true
    });

});

Check all checkboxes working in pools


import React from 'react';
import {connect} from 'react-redux';
import {pushState} from 'redux-router';

export function requireAuthentication(Component) {

    class AuthenticatedComponent extends React.Component {

        componentWillMount () {
            this.checkAuth();
        }

        componentWillReceiveProps (nextProps) {
            this.checkAuth();
        }

        checkAuth () {
            if (!this.props.isAuthenticated) {
                let redirectAfterLogin = this.props.location.pathname;
                this.props
                    .dispatch(pushState(null, `/login?next=${redirectAfterLogin}`));
            }
        }

        render () {
            return (
                <div>
                    {this.props.isAuthenticated === true
                        ? <Component {...this.props}/>
                        : null
                    }
                </div>
            )

        }
    }

    const mapStateToProps = (state) => ({
        token: state.auth.token,
        userName: state.auth.userName,
        isAuthenticated: state.auth.isAuthenticated
    });

    return connect(mapStateToProps)(AuthenticatedComponent);

}

import React from 'react';
import {connect} from 'react-redux';
import {pushState} from 'redux-router';

export function requireAuthentication(Component) {

    class AuthenticatedComponent extends React.Component {

        componentWillMount () {
            this.checkAuth(this.props.isAuthenticated);
        }

        componentWillReceiveProps (nextProps) {
            this.checkAuth(nextProps.isAuthenticated);
        }

        checkAuth (isAuthenticated) {
            if (!isAuthenticated) {
                let redirectAfterLogin = this.props.location.pathname;
                this.props
                    .dispatch(pushState(null, `/login?next=${redirectAfterLogin}`));
            }
        }

        render () {
            return (
                <div>
                    {this.props.isAuthenticated === true
                        ? <Component {...this.props}/>
                        : null
                    }
                </div>
            )

        }
    }

    const mapStateToProps = (state) => ({
        token: state.auth.token,
        userName: state.auth.userName,
        isAuthenticated: state.auth.isAuthenticated
    });

    return connect(mapStateToProps)(AuthenticatedComponent);

}

Fix checkAuth to make it work with componentWillReceiveProps


var express = require('express');
var kue = require('kue');
var Bot = require('../models/bot');

var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index');
});

router.post('/destroy_jobs', function(req, res, next) {
  kue.Job.rangeByState('delayed', 0, 10000, 'asc', function( err, jobs ) {
    jobs.forEach(function(job) {
      job.remove(function() {});
    });
    res.send();
  });
});

router.post('/destroy_all_the_things', function(req, res, next) {
  ['Queued', 'Active', 'Failed', 'Complete', 'Delayed'].forEach(function(state) {
    kue.Job.rangeByState(state, 0, 999999, 'asc', function( err, jobs ) {
      jobs.forEach(function(job) {
        job.remove(function(err) {
          if (err) console.log(err);
        });
      });
    });
  });

  Bot.remove({})
  .then(function(result) {
  })
  .catch(function(err) {
    res.status(500).send(err);
  });
  res.send();
});

module.exports = router;

var express = require('express');
var kue = require('kue');
var Bot = require('../models/bot');

var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index');
});

router.post('/destroy_all_the_things', function(req, res, next) {
  ['queued', 'active', 'failed', 'complete', 'delayed'].forEach(function(state) {
    kue.Job.rangeByState(state, 0, 10000, 'asc', function(err, jobs) {
      jobs.forEach(function(job) {
        job.remove(function(err) {
          if (err) console.log(err);
        });
      });
    });
  });

  Bot.remove({})
  .then(function(result) {
  })
  .catch(function(err) {
    res.status(500).send(err);
  });
  res.send();
});

module.exports = router;

Fix /destroy_all_the_things endpoint, state are lower case


module.exports = function(grunt) {

	// 1. All configuration goes here
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),

		less: {
			development: {
				options: {
					compress: false,
					yuicompress: false,
					optimization: 2
				},
				files: {
					// target.css file: source.less file
					'assets/css/css-bootstrap.css': 'assets/css/css-bootstrap.less'
				}
			}
		},

		watch: {
			options : {
				livereload: true,
			},
			styles: {
				// Which files to watch (all .less files recursively in the less directory)
				files: ['assets/css/**/*.less'],
				tasks: ['less'],
				options: {
					nospawn: true
				}
			}
		}
	});

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

	// 4. Where we tell Grunt what to do when we type "grunt" into the terminal.
	grunt.registerTask('default',
		[
			'less',
			'watch'
		]
	);

};

module.exports = function(grunt) {

	// 1. All configuration goes here
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),

		less: {
			development: {
				options: {
					compress: false,
					yuicompress: false,
					optimization: 2
				},
				files: {
					// target.css file: source.less file
					'assets/css/css-bootstrap.css': 'assets/css/css-bootstrap.less'
				}
			}
		},

		watch: {
			options : {
				livereload: true,
			},
			styles: {
				// Which files to watch (all .less files recursively in the less directory)
				files: ['assets/css/**/*.less'],
				tasks: ['less'],
				options: {
					nospawn: true
				}
			}
		}
	});

	grunt.loadNpmTasks('grunt-contrib-less');
	grunt.loadNpmTasks('grunt-contrib-watch');

	// 4. Where we tell Grunt what to do when we type "grunt" into the terminal.
	grunt.registerTask('default',
		[
			'less',
			'watch'
		]
	);

};

Remove grunt concat, not used by default, causes errors


// a helper to render a date in milliseconds since epoch as something a normal
// human can understand

var Handlebars = require('handlebars');
var moment = require('moment');

/**
 * Parameters: the date in milliseconds since epoch
 * whether to include the time, or just the date (default: include time)
 */
Handlebars.registerHelper(
  'dateRender',
  function(date, includeTime) {
    if (date === 0 || date === null)
      return '-';

    var m = moment(date);

    // TODO: time zone?
    return new Handlebars.SafeString(
      '<span>' +
      Handlebars.escapeExpression(m.format(window.Messages('app.date_format'))) + ' (' +
      Handlebars.escapeExpression(m.fromNow()) +
      ')</span>');
  }
);

// a helper to render a date in milliseconds since epoch as something a normal
// human can understand

var Handlebars = require('handlebars');
var moment = require('moment');

/**
 * Parameters: the date in milliseconds since epoch
 * whether to include the time, or just the date (default: include time)
 */
Handlebars.registerHelper(
  'dateRender',
  function(date, includeTime) {
    if (date === 0 || date === null)
      return '-';

    var m = moment.utc(date);

    return new Handlebars.SafeString(
      '<span>' +
      Handlebars.escapeExpression(m.format(window.Messages('app.date_format'))) + ' (' +
      Handlebars.escapeExpression(m.fromNow()) +
      ')</span>');
  }
);

Use UTC time in date-helper


import Ember from 'ember';
import layout from '../../templates/components/bricks-grid/item';

const { Component, on } = Ember;

export default Component.extend({
  layout,

  sendRepackOnInit: on('didInsertElement', function() {
    const img = this.$('img');

    img.on('load', () => {
      if (!this.get('isDestroyed')) {
        this.sendAction('repack');
      }
    });

    this.sendAction('repack');
  }),
});

import Ember from 'ember';
import Item from './item';

const { on } = Ember;

export default Item.extend({
  sendRepackOnInit: on('didInsertElement', function() {
    const img = this.$('img');

    img.on('load', () => {
      if (!this.get('isDestroyed')) {
        this.sendAction('repack');
      }
    });

    this.sendAction('repack');
  }),
});

Add Inherit Image type element from item


import Ember from 'ember';
import fetch from "ember-network/fetch";
import ENV from '../config/environment'

export default Ember.Component.extend({
  classNames: ['noise-query-and-results'],
  results: null,
  // Store the query that was set by the tutorial. If that query changes,
  // by going to another tutorial step, then empty the results.
  tutorialQuery: null,

  actions: {
    doQuery() {
      const query = this.$('textarea').val();
      fetch(ENV.noiseUrl, {
        method: "POST",
        body: query
      }).then(data => {
        return data.json();
      }).then(json => {
        this.set('results', json);
      });
    }
  },

  didUpdateAttrs() {
    // Empty the results only if the query changed to due to the tutorial,
    // don't empty them when the user does some input.
    if (this.get('tutorialQuery') != this.get('attrs').query.value) {
      this.set('results', null);
      this.set('tutorialQuery', this.get('attrs').query.value);
    }
  },
});

import Ember from 'ember';
import ENV from '../config/environment'

export default Ember.Component.extend({
  classNames: ['noise-query-and-results'],
  results: null,
  // Store the query that was set by the tutorial. If that query changes,
  // by going to another tutorial step, then empty the results.
  tutorialQuery: null,

  actions: {
    doQuery() {
      const query = this.$('textarea').val();
      Ember.$.post(ENV.noiseUrl, query, data => {
        this.set('results', data);
      });
    }
  },

  didUpdateAttrs() {
    // Empty the results only if the query changed to due to the tutorial,
    // don't empty them when the user does some input.
    if (this.get('tutorialQuery') != this.get('attrs').query.value) {
      this.set('results', null);
      this.set('tutorialQuery', this.get('attrs').query.value);
    }
  },
});

Use jQuery ajax request instead of fetch


'use strict';

var bpack = require('browser-pack');
var fs = require('fs');
var path = require('path');
var xtend = require('xtend');

var preludePath = path.join(__dirname, 'prelude.js');
var prelude = fs.readFileSync(preludePath, 'utf8');

// This plugin replaces the prelude and adds a transform
var plugin = exports.plugin = function (bfy, opts) {
  function replacePrelude() {
    var packOpts = {
      raw         : true, // Added in regular Browserifiy as well
      preludePath : preludePath,
      prelude     : prelude
    };

    // browserify sets "hasExports" directly on bfy._bpack
    bfy._bpack = bpack(xtend(bfy._options, packOpts, {hasExports: bfy._bpack.hasExports}));
    // Replace the 'pack' pipeline step with the new browser-pack instance
    bfy.pipeline.splice('pack', 1, bfy._bpack);
  }

  bfy.transform(require('./transform'));
  bfy.on('reset', replacePrelude);

  replacePrelude();
};

// Maintain support for the old interface
exports.browserify = function (files) {
  console.error('You are setting up proxyquireify via the old API which will be deprecated in future versions.');
  console.error('It is recommended to use it as a browserify-plugin instead - see the example in the README.');
  return require('browserify')(files).plugin(plugin);
};

'use strict';

var bpack = require('browser-pack');
var fs = require('fs');
var path = require('path');
var xtend = require('xtend');

var preludePath = path.join(__dirname, 'prelude.js');
var prelude = fs.readFileSync(preludePath, 'utf8');

// This plugin replaces the prelude and adds a transform
var plugin = exports.plugin = function (bfy, opts) {
  function replacePrelude() {
    var packOpts = {
      raw         : true, // Added in regular Browserifiy as well
      preludePath : preludePath,
      prelude     : prelude
    };

    // browserify sets "hasExports" directly on bfy._bpack
    bfy._bpack = bpack(xtend(bfy._options, packOpts, {hasExports: bfy._bpack.hasExports}));
    // Replace the 'pack' sub-pipeline with the new browser-pack instance
    bfy.pipeline.get('pack').splice(0, 1, bfy._bpack);
  }

  bfy.transform(require('./transform'));
  bfy.on('reset', replacePrelude);

  replacePrelude();
};

// Maintain support for the old interface
exports.browserify = function (files) {
  console.error('You are setting up proxyquireify via the old API which will be deprecated in future versions.');
  console.error('It is recommended to use it as a browserify-plugin instead - see the example in the README.');
  return require('browserify')(files).plugin(plugin);
};

Fix browserify 'pack' pipeline replacement


'use strict';

if (!config.tasks.fonts) {
	return false;
}

let paths = {
	src: path.join(config.root.base, config.root.src, config.tasks.fonts.src, '/**', getExtensions(config.tasks.fonts.extensions)),
	dest: path.join(config.root.base, config.root.dest, config.tasks.fonts.dest)
};

function fonts() {
	return gulp.src(paths.src, {since: cache.lastMtime('fonts')})
		.pipe(plumber(handleErrors))
		.pipe(cache('fonts'))
		.pipe(changed(paths.dest)) // Ignore unchanged files
		.pipe(flatten())
		.pipe(chmod(config.chmod))
		.pipe(gulp.dest(paths.dest))
		.pipe(size({
			title: 'Fonts:',
			showFiles: false
		})
	);
}

module.exports = fonts;

'use strict';

if (!config.tasks.fonts) {
	return false;
}

let paths = {
	src: path.join(config.root.base, config.root.src, config.tasks.fonts.src, '/**', getExtensions(config.tasks.fonts.extensions)),
	dest: path.join(config.root.base, config.root.dest, config.tasks.fonts.dest)
};

function fonts() {
	return gulp.src(paths.src, {since: cache.lastMtime('fonts')})
		.pipe(plumber(handleErrors))
		.pipe(cache('fonts'))
		.pipe(changed(paths.dest)) // Ignore unchanged files
		.pipe(chmod(config.chmod))
		.pipe(gulp.dest(paths.dest))
		.pipe(size({
			title: 'Fonts:',
			showFiles: false
		})
	);
}

module.exports = fonts;

Remove flattern of font task


var express = require('express');
var app = express();

// Serve assets in /public
var path = require('path');
app.use(express.static(path.join(__dirname, '../client')));

// Body parsing for JSON POST payloads
var bodyParser = require('body-parser');
app.use(bodyParser.json());

// Middlewares
app.use(require('./middlewares/cross_origin_requests'));
app.use(require('./middlewares/http_verbs'));
app.use(require('./middlewares/add_user_to_request'));

// Mount controller files
app.use('/notes', require('./routes/notes'));
app.use('/users', require('./routes/users'));
app.use('/session', require('./routes/session'));

// Start server
var server = app.listen(3000, function() {
  console.log('Listening on http://localhost:3000');
});

var express = require('express');
var app = express();

// Serve assets in /public
var path = require('path');
app.use(express.static(path.join(__dirname, '../client')));

// Body parsing for JSON POST payloads
var bodyParser = require('body-parser');
app.use(bodyParser.json());

// Middlewares
app.use(require('./middlewares/cross_origin_requests'));
app.use(require('./middlewares/http_verbs'));
app.use(require('./middlewares/add_user_to_request'));

// Mount controller files
app.use('/notes', require('./routes/notes'));
app.use('/users', require('./routes/users'));
app.use('/session', require('./routes/session'));

// Start server
app.set('port', (process.env.PORT || 5000));
app.listen(app.get('port'), function() {
  console.log('Listening on http://localhost:', app.get('port'));
});

Use process.env.PORT if it exists.


function WmataApiError(msg, statusCode){
    this.name = 'WmataApiError';
    this.msg = msg || '';
    this.statusCode = statusCode;
}

WmataApiError.prototype = Error.prototype;

WmataApiError.prototype.setMessage = function(msg){
    this.msg = msg;
}

module.exports = WmataApiError;

function WmataApiError(msg, statusCode, url){
    this.name = 'WmataApiError';
    this.message = msg || '';
    this.statusCode = statusCode;
    this.url = url;
}

WmataApiError.prototype = Error.prototype;

WmataApiError.prototype.setMessage = function(msg){
    this.msg = msg;
}

module.exports = WmataApiError;

Include requested URL as part of error object.


#!/usr/bin/env node

var readline = require('readline');
var bcv_parser = require('bible-passage-reference-parser/js/tr_bcv_parser').bcv_parser;
var bcv = new bcv_parser();
var formatter = require('bible-reference-formatter/es6/tr');

bcv.set_options({
  'sequence_combination_strategy': 'separate'
});
bcv.include_apocrypha(true);

var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

var references = [];

function extract_references (data) {
  var res = bcv.parse(data).osis_and_indices();
  res.forEach(function(match) {
    var ref = {};
    ref.original = data.slice(match.indices[0], match.indices[1]);
    ref.osis = match.osis;
    ref.reformat = formatter('yc-long', match.osis);
    references.push(ref);
  });
}

function output_references () {
  var output = JSON.stringify(references, null, '  ');
  process.stdout.write(output);
}

rl.on('line', extract_references);
rl.on('close', output_references);

#!/usr/bin/env node

var readline = require('readline');
var bcv_parser = require('bible-passage-reference-parser/js/tr_bcv_parser').bcv_parser;
var bcv = new bcv_parser();
var formatter = require('bible-reference-formatter/es6/tr');

bcv.set_options({
  'sequence_combination_strategy': 'separate'
});
bcv.include_apocrypha(true);

var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

var references = [];

function extract_references (data) {
  var res = bcv.parse(data).parsed_entities();
  res.forEach(function(match) {
    var ref = {};
    ref.original = data.slice(match.indices[0], match.indices[1]);
    ref.osis = match.osis;
    ref.seq = bcv.translations.default.order[match.start.b] * 1000000 + match.start.c * 1000 + match.start.v;
    ref.reformat = formatter('yc-long', match.osis);
    references.push(ref);
  });
}

function output_references () {
  var output = JSON.stringify(references, null, '  ');
  process.stdout.write(output);
}

rl.on('line', extract_references);
rl.on('close', output_references);

Add sequence key to make sorting easier (w/ thanks to @curiousdannii)