'use strict';

const path = require('path');
const fs = require('fs');

const noop = () => {};

before('initialization', function () {
	// Load and override configuration before starting the server
	let config;
	try {
		require.resolve('../config/config');
	} catch (err) {
		if (err.code !== 'MODULE_NOT_FOUND' && err.code !== 'ENOENT') throw err; // Should never happen

		console.log("config.js doesn't exist - creating one with default settings...");
		fs.writeFileSync(path.resolve(__dirname, '../config/config.js'),
			fs.readFileSync(path.resolve(__dirname, '../config/config-example.js'))
		);
	} finally {
		config = require('../config/config');
	}
	require('./../lib/process-manager').disabled = true;

	// Actually crash if we crash
	config.crashguard = false;
	// Don't allow config to be overridden while test is running
	config.watchconfig = false;
	// Don't try to write to file system
	config.nofswriting = true;

	// Don't create a REPL
	require('../lib/repl').start = noop;

	// Start the server.
	require('../app');

	LoginServer.disabled = true;
});

'use strict';

const path = require('path');
const fs = require('fs');

const noop = () => {};

before('initialization', function () {
	process.on('unhandledRejection', err => {
		// I'd throw the err, but we have a heisenbug on our hands and I'd
		// rather not have it screw with Travis in the interim
		console.log(err);
	});

	// Load and override configuration before starting the server
	let config;
	try {
		require.resolve('../config/config');
	} catch (err) {
		if (err.code !== 'MODULE_NOT_FOUND' && err.code !== 'ENOENT') throw err; // Should never happen

		console.log("config.js doesn't exist - creating one with default settings...");
		fs.writeFileSync(path.resolve(__dirname, '../config/config.js'),
			fs.readFileSync(path.resolve(__dirname, '../config/config-example.js'))
		);
	} finally {
		config = require('../config/config');
	}
	require('./../lib/process-manager').disabled = true;

	// Actually crash if we crash
	config.crashguard = false;
	// Don't allow config to be overridden while test is running
	config.watchconfig = false;
	// Don't try to write to file system
	config.nofswriting = true;

	// Don't create a REPL
	require('../lib/repl').start = noop;

	// Start the server.
	require('../app');

	LoginServer.disabled = true;
});

Improve error message for Promise rejections


import chai, { expect } from 'chai';
import sinon            from 'sinon';
import sinonChai        from 'sinon-chai';

chai.use(sinonChai);

import ResourceTestHelper from './ResourceTestHelper';

import DtmfResource from '../lib/DtmfResource';
import HttpClient from '../lib/HttpClient';
import Credentials from '../lib/Credentials';

var creds = Credentials.parse({
  applicationId: 'some-id',
  privateKey: __dirname + '/private-test.key'
});
var emptyCallback = () => {};

describe('DtmfResource', () => {

  var httpClientStub = null;
  var dtmf = null;

  beforeEach(() => {
    httpClientStub = sinon.createStubInstance(HttpClient);
    var options = {
      httpClient: httpClientStub
    };
    dtmf = new DtmfResource(creds, options);
  })

  it('should be able to send DTMF to a call', () => {
    const callId = '2342342-lkjhlkjh-32423';
    var params = [1,2,3,4];
    dtmf.send(callId, params, emptyCallback);

    var expectedRequestArgs = ResourceTestHelper.requestArgsMatch(params, {
      path: DtmfResource.PATH.replace('{call_uuid}', callId),
      method: 'PUT'
    });
    expect(httpClientStub.request)
      .to.have.been.calledWith(
        sinon.match(expectedRequestArgs),
        emptyCallback
      );
  });

});

import chai, { expect } from 'chai';
import sinon            from 'sinon';
import sinonChai        from 'sinon-chai';

chai.use(sinonChai);

import ResourceTestHelper from './ResourceTestHelper';

import DtmfResource from '../lib/DtmfResource';
import HttpClient from '../lib/HttpClient';
import Credentials from '../lib/Credentials';

var creds = Credentials.parse({
  applicationId: 'some-id',
  privateKey: __dirname + '/private-test.key'
});
var emptyCallback = () => {};

describe('DtmfResource', () => {

  var httpClientStub = null;
  var dtmf = null;

  beforeEach(() => {
    httpClientStub = sinon.createStubInstance(HttpClient);
    var options = {
      httpClient: httpClientStub
    };
    dtmf = new DtmfResource(creds, options);
  })

  it('should be able to send DTMF to a call', () => {
    const callId = '2342342-lkjhlkjh-32423';
    var params = {digits: [1,2,3,4]};
    dtmf.send(callId, params, emptyCallback);

    var expectedRequestArgs = ResourceTestHelper.requestArgsMatch(params, {
      path: DtmfResource.PATH.replace('{call_uuid}', callId),
      method: 'PUT'
    });
    expect(httpClientStub.request)
      .to.have.been.calledWith(
        sinon.match(expectedRequestArgs),
        emptyCallback
      );
  });

});

Update params to send object literal with `digits` property


/* global afterEach, beforeEach, describe, it */

import assert from 'assert'
import fs from 'fs'
import rimraf from 'rimraf'
import build from '../../src/build'
import hooks from '../../src/hooks'

describe('build', () => {
  const output = './test/integration/output'

  beforeEach(done => {
    fs.mkdirSync(output)
    build(output)

    done()
  })

  afterEach(done => {
    rimraf(output, err => {
      if (err) throw new Error(err)

      done()
    })
  })

  it('successfully creates the hook scripts', done => {
    const files = fs.readdirSync(output)

    assert.strictEqual(hooks.length, files.length)

    done()
  })
})

/* global afterEach, beforeEach, describe, it */

import assert from 'assert'
import fs from 'fs'
import rimraf from 'rimraf'
import build from '../../src/build'
import hooks from '../../src/hooks'

describe('build', () => {
  const output = './test/integration/output'

  beforeEach(done => {
    fs.mkdirSync(output)
    build(output)

    done()
  })

  afterEach(done => {
    rimraf(output, err => {
      if (err) throw new Error(err)

      done()
    })
  })

  it('successfully creates the hook scripts', done => {
    const files = fs.readdirSync(output)

    assert.strictEqual(hooks.length, files.length)

    files.forEach(hook => {
      fs.readFile(hook, (err, data) => {
        if (err) throw new Error(err)

        assert(data.match('#!/usr/bin/env node'))
        assert(data.match("var Runner = require('hook-script-runner')"))
        assert(data.match("new Runner('${hook}').run()"))
      })
    })

    done()
  })
})

Add additional coverage for hook script contents


var WebSocket = require('ws');
var debug = require('debug')('signalk:ws');

function connectDelta(hostname, callback) {
  var url = "ws://" + hostname + "/signalk/stream?stream=delta&context=self";
  if (typeof Primus != 'undefined') {
    var signalKStream = Primus.connect(url, {
      reconnect: {
        maxDelay: 15000,
        minDelay: 500,
        retries: Infinity
      }
    });
    signalKStream.on('data', callback);
  } else {
    connection = new WebSocket(url);
    connection.onopen = function(msg) {
      debug("open");
    };

    connection.onerror = function(error) {
      debug("error:" + error);
    };
    connection.onmessage = function(msg) {
      callback(JSON.parse(msg.data));
    };
  }
}

module.exports = {
  connectDelta: connectDelta
}

var WebSocket = require('ws');
var debug = require('debug')('signalk:ws');

function connectDelta(hostname, callback, onConnect, onDisconnect) {
  debug("Connecting to " + hostname);
  var url = "ws://" + hostname + "/signalk/stream?stream=delta&context=self";
  if (typeof Primus != 'undefined') {
    debug("Using Primus");
    var signalKStream = Primus.connect(url, {
      reconnect: {
        maxDelay: 15000,
        minDelay: 500,
        retries: Infinity
      }
    });
    signalKStream.on('data', callback);
    return {
      disconnect: function() {
        signalKStream.destroy();
        debug('Disconnected');
      }
    }
  } else {
    debug("Using ws");
    var connection = new WebSocket(url);
    connection.onopen = function(msg) {
      debug("open");
      onConnect();
    };

    connection.onerror = function(error) {
      debug("error:" + error);
    };
    connection.onmessage = function(msg) {
      callback(JSON.parse(msg.data));
    };
    return {
      disconnect: function() {
        connection.close();
        debug('Disconnected');
      }
    }
  }
}

module.exports = {
  connectDelta: connectDelta
}

Add onConnect and onDisconnect callbacks and return 'connection' object with disconnect option


windmill.jsTest.require('shared.js');

// Namespace obj to contain our tests
windmillMain.test_waitForXHR = new function () {
  // Make the async XHR call
  this.test_xhrCall = function () {
    // Callback function -- sets temp flag to 'returned'
    var success = function () {
      windmillMain.tempData = 'returned';
    };
    fleegix.xhr.get(success, '/test.txt');
  };
  this.test_wait = windmillMain.shared.util.waitForTempData;
  this.test_afterWait = function () {
    jum.assertEquals('returned', windmillMain.tempData);
  };
  // Remove the node so we can run the test again
  this.teardown = function () {
    windmillMain.tempData = null;
  }
};

windmill.jsTest.require('shared.js');

// Namespace obj to contain our tests
windmillMain.test_waitForXHR = new function () {
  // Make the async XHR call
  this.test_xhrCall = function () {
    // Callback function -- sets temp flag to 'returned'
    var success = function () {
      windmillMain.tempData = 'returned';
    };
    fleegix.xhr.get(success, '/windmill-serv/jstest/data.json');
  };
  this.test_wait = windmillMain.shared.util.waitForTempData;
  this.test_afterWait = function () {
    jum.assertEquals('returned', windmillMain.tempData);
  };
  // Remove the node so we can run the test again
  this.teardown = function () {
    windmillMain.tempData = null;
  }
};

Load a file that actually exists on the filesystem.


module.exports = function(file, plugins) {
  if (plugins.globby.sync('./config/' + file).length) {
    return require('../config/' + file);
  }
  else {
    plugins.util.log(
      plugins.util.colors.red('\n========================================= \n')
      + plugins.util.colors.yellow('You have to create ')
      + plugins.util.colors.blue('config/' + file)
      + plugins.util.colors.red('\n=========================================')
    );
    throw new plugins.util.PluginError({
      plugin: 'config',
      message: 'You have to create config/' + file
    });
  }
}

module.exports = function(file, plugins) {
  if (plugins.globby.sync('../../../dev/tools/frontools/configs/' + file).length) {
    return require('../../../../dev/tools/frontools/configs/' + file);
  } else if (plugins.globby.sync('./config/' + file).length) {
    return require('../config/' + file);
  } else {
    plugins.util.log(
      plugins.util.colors.red('\n========================================= \n')
      + plugins.util.colors.yellow('You have to create ')
      + plugins.util.colors.blue('config/' + file)
      + plugins.util.colors.red('\n=========================================')
    );
    throw new plugins.util.PluginError({
      plugin: 'config',
      message: 'You have to create config/' + file
    });
  }
}

Allow for config outside of vendor directory


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

var Router = Ember.Router.extend({
  location: config.locationType
});

Router.map(function() {
  this.route('index', { path: '/index' });
});

export default Router;

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

var Router = Ember.Router.extend({
  location: config.locationType
});

Router.map(function() {
  this.route('index', { path: '/' });
});

export default Router;

Set demo route to root


import { createUIStore } from 'redux-webext';
import addEventListeners from './event-listeners';
import { populateTabList } from './dom-utils';

// Initialize tabs
createUIStore()
  .then(populateTabList)
  .then(addEventListeners)
  .catch((e) => {
    console.error(e);
    throw new Error(e);
  });

/* Popup initialization */
import { createUIStore } from 'redux-webext';
import addEventListeners from './event-listeners';
import { populateTabList } from './dom-utils';

// Add a key containing adding the current windowId to the popup.
const windowIdPromise = browser.windows.getCurrent()
  .then(({ id }) => ({ windowId: id }));
// Adds a key 'windowId' to the store object.
// Store object is now -> { dispatch, getState, subscribe, windowId }
const mergeStoreWithWindowId = promiseArray =>
  promiseArray.reduce((acc, obj) => Object.assign({}, acc, obj));

Promise.all([createUIStore(), windowIdPromise])
  .then(mergeStoreWithWindowId)
  .then(populateTabList)
  .then(addEventListeners)
  .catch((e) => {
    console.error(e);
    throw new Error('Ran into a problem initializing popup window.');
  });

Add windowId to store object on popup init


import translations from './translations/accessibility-cloud.js-widget/translations';

function findLocaleWithCountry(localeWithoutCountry) {
  const regexp = new RegExp(`^${localeWithoutCountry}_`);
  return Object.keys(translations).find(locale => locale.match(regexp));
}

function translate(string, locale) {
  const localeWithoutCountry = locale.replace(/_[A-Z][A-Z]$/);
  const localeHasCountry = locale !== localeWithoutCountry;
  const localeWithDefaultCountry = localeHasCountry ? locale : findLocaleWithCountry(locale);
  const defaultLocale = 'en_US';

  const translation = translations[locale] || {};
  const translationWithoutCountry = translations[localeWithoutCountry] || {};
  const translationWithDefaultCountry = translations[localeWithDefaultCountry] || {};
  const translationWithDefaultLocale = translations[defaultLocale] || {};

  return translation[string] ||
    translationWithoutCountry[string] ||
    translationWithDefaultCountry[string] ||
    translationWithDefaultLocale ||
    string;
}

// Note that we don't support template strings for now.

// eslint-disable-next-line import/prefer-default-export
export function t(arg) {
  // eslint-disable-next-line no-undef
  return translate(arg, AccessibilityCloud.locale);
}

import translations from './translations/accessibility-cloud.js-widget/translations';

function findLocaleWithCountry(localeWithoutCountry) {
  const regexp = new RegExp(`^${localeWithoutCountry}_`);
  return Object.keys(translations).find(locale => locale.match(regexp));
}

function translate(string, locale) {
  const localeWithoutCountry = locale.replace(/_[A-Z][A-Z]$/);
  const localeHasCountry = locale !== localeWithoutCountry;
  const localeWithDefaultCountry = localeHasCountry ? locale : findLocaleWithCountry(locale);
  const defaultLocale = 'en_US';

  const translation = translations[locale] || {};
  const translationWithoutCountry = translations[localeWithoutCountry] || {};
  const translationWithDefaultCountry = translations[localeWithDefaultCountry] || {};
  const translationWithDefaultLocale = translations[defaultLocale] || {};

  const result = translation[string] ||
    translationWithoutCountry[string] ||
    translationWithDefaultCountry[string] ||
    translationWithDefaultLocale[string] ||
    string;

  return result;
}

// Note that we don't support template strings for now.

// eslint-disable-next-line import/prefer-default-export
export function t(arg) {
  // eslint-disable-next-line no-undef
  return translate(arg, AccessibilityCloud.locale);
}

Fix a translation bug for en -> en_US fallback


var replace = require("../str-replace");
var expect = require("expect.js");

describe("Replace first", function() {

  it("should replace first occurrences", function() {
    expect(replace("a").from("aa").with("e")).to.be("ea");
  });

  it("should replace first occurrences ignoring the case", function() {
    expect(replace("a").ignoringCase().from("AA").with("e")).to.be("eA");
  });

});

describe("Replace all", function() {

  it("should replace all occurrences", function() {
    expect(replace.all("/").from("/home/dir").with("\\")).to.be("\\home\\dir");
  });

  it("should replace all occurrences ignoring the case", function() {
    var replaceAllHouseIgnoringCase = replace.all("house").ignoringCase();
    expect(replaceAllHouseIgnoringCase.from("Many Houses").with("Horse")).to.be("Many Horses");
    expect(replace.all("house").from("Many Houses").with("Horse")).to.be("Many Houses");
  });

});

Remove useless spacing in the tests


import "../cases/date/compare";
import "../cases/date/format";
import "../cases/dom/manipulate/remove";
import "../cases/dom/traverse/children";
import "../cases/dom/traverse/filter";
import "../cases/dom/traverse/find";
import "../cases/dom/traverse/next";
import "../cases/dom/traverse/nextAll";
import "../cases/dom/traverse/not";
import "../cases/dom/traverse/prev";
import "../cases/dom/traverse/prevAll";
import "../cases/dom/traverse/siblings";

QUnit.config.testTimeout = 1000;

Define test timeout for async tests


/* Tests for themes generation
 */

describe('Themes', function () {

  var async = function(arr, delay, done) {
    var j = 0;

    var runner = function() {
      setTimeout(function() {
        if(j === arr.length) {
          return done();
        }

        console.log('async ', arr.length - j);

        arr[j]();
        j++;
        runner();
      }, delay)
    }

    runner();
  };

  var downloadPicture = function(elem) {

    return function() {

      elem.getAttribute('href')
      .then(function(href) {
        console.log('Downloading ', href);
      });

      elem
      .click()
      .then(element(by.css('#js-download-button')).click)
      .then(element(by.css('#drop-downloads a[ng-click*="DownloadPicture()"]')).click)

    }

  };

  it('should open the page', function () {

    browser.get('#/');

    expect(true).toBe(true);

  });

  it('should download a picture of each theme', function (done) {

    var downloads = [];

    element.all(by.css('.themes-row a'))
    .each(function(elem) {
      downloads.push(downloadPicture(elem));
    })
    .then(function() {

      async(downloads, 1500, function() {
        expect(true).toBe(true);
        done();
      });

    })

  });

})

/* Tests for themes generation
 */

describe('Themes', function () {

  var async = function(arr, delay, done) {
    var j = 0;

    var runner = function() {
      setTimeout(function() {
        if(j === arr.length) {
          return done();
        }

        console.log('async ', arr.length - j);

        arr[j]();
        j++;
        runner();
      }, delay)
    }

    runner();
  };

  var downloadPicture = function(elem) {

    return function() {

      elem.getAttribute('href')
      .then(function(href) {
        console.log('Downloading ', href);
      });

      elem
      .click()
      .then(element(by.css('#js-download-button')).click)
      .then(element(by.css('#drop-downloads a[ng-click*="DownloadPicture()"]')).click)

    }

  };

  it('should open the page', function () {

    browser.get('#/');

    expect(true).toBe(true);

  });

  it('should download a picture of each theme', function (done) {

    var downloads = [];

    // hide the affiliate modal
    browser.executeScript('window.localStorage.setItem("bizcardmaker-affiliate-modal", "true");');

    element.all(by.css('.themes-row a'))
    .each(function(elem) {
      downloads.push(downloadPicture(elem));
    })
    .then(function() {

      async(downloads, 1500, function() {
        expect(true).toBe(true);
        done();
      });

    })

  });

})

Hide the affiliate modal in the e2e theme download tests.


$(document).ready(function(){
    var div = d3.select("body").append("div")
            .attr("class", "tooltip")
            .style("opacity", 0);

    var interactiveBrowse_ecology = d3.select("#interactiveBrowse_ecology");

    var habitat = interactiveBrowse_ecology.append("rect")
            .attr("x", 370)
            .attr("y", 260)
            .attr("width", 120)
            .attr("height", 50)
            .attr("id", "habitat")
            .style("opacity", 0.01)
            .style("fill", "#fff")
            .style("cursor", "pointer")
            .on("click", function(){
                displayPage(d3.select(this).attr("id"));
            });

    function displayPage(traitId){
        var resultPage =  WebRoot+"/trait/details/byId"+traitId;
        window.location.href = resultPage;
    }
});

$(document).ready(function(){
    var div = d3.select("body").append("div")
            .attr("class", "tooltip")
            .style("opacity", 0);

    var interactiveBrowse_ecology = d3.select("#interactiveBrowse_ecology");

    var habitat = interactiveBrowse_ecology.append("rect")
            .attr("x", 370)
            .attr("y", 260)
            .attr("width", 120)
            .attr("height", 50)
            .attr("id", "habitat")
            .attr("type_cvterm_id", "27")
            .style("opacity", 0.01)
            .style("fill", "#fff")
            .style("cursor", "pointer")
            .on("click", function(){
                displayPage(d3.select(this).attr("type_cvterm_id"));
            });

    function displayPage(traitId){
        var resultPage =  WebRoot+"/trait/details/byCvTermId/"+traitId;
        window.location.href = resultPage;
    }
});

Add click function in order to display a trait type by id


'use strict';

/* Constants */

<%= angularAppName %>.constant('USER_ROLES', {
        all: '*',
        admin: 'ROLE_ADMIN',
        user: 'ROLE_USER'
    });

/*
Languages codes are ISO_639-1 codes, see http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
They are written in English to avoid character encoding issues (not a perfect solution)
*/
<%= angularAppName %>.constant('LANGUAGES', {
        ca: 'Catalan',
        da: 'Danish',
        en: 'English',
        es: 'Spanish',
        fr: 'French',
        de: 'German',
        kr: 'Korean',
        pl: 'Polish',
        pt: 'Portuguese',
        ru: 'Russian',
        tr: 'Turkish'
    });

Fix indentation and remove trailing whitespaces


import React, { Component } from 'react';
import AgileTextField from '../AgileTextField';
import numberValidator from '../Utils/Validators/number';

const styles = {
};

class NumberField extends Component {
  render() {
    const {...passThroughProps} = this.props;
    return (
      <AgileTextField
        type="text"
        validateInput={true}
        {...passThroughProps}
      />
    );
  }
};
NumberField.propTypes = {
  name: React.PropTypes.string,
  label: React.PropTypes.string.isRequired,
  hintText: React.PropTypes.string,
  onStateChange: React.PropTypes.func,
  onValueChange: React.PropTypes.func,
  feedbackElement: React.PropTypes.func,
  style: React.PropTypes.object,
  disabled: React.PropTypes.bool,
};
// Specifies the default values for props:
NumberField.defaultProps = {
  name: 'number',
  validator: numberValidator,
  style: styles,
};
export default NumberField;

import React, { Component } from 'react';
import AgileTextField from '../AgileTextField';
import numberValidator from '../Utils/Validators/number';

const styles = {
};

class NumberField extends Component {
  render() {
    const {minValue, maxValue, ...passThroughProps} = this.props;
    return (
      <AgileTextField
        type="text"
        validateInput={true}
        validator={numberValidator(minValue, maxValue)}
        {...passThroughProps}
      />
    );
  }
};
NumberField.propTypes = {
  name: React.PropTypes.string,
  label: React.PropTypes.string.isRequired,
  hintText: React.PropTypes.string,
  onStateChange: React.PropTypes.func,
  onValueChange: React.PropTypes.func,
  feedbackElement: React.PropTypes.func,
  style: React.PropTypes.object,
  disabled: React.PropTypes.bool,
  minValue: React.PropTypes.number,
  maxValue: React.PropTypes.number
};
// Specifies the default values for props:
NumberField.defaultProps = {
  name: 'number',
  style: styles,
  minValue: -Infinity,
  maxValue: Infinity
};
export default NumberField;

Add min and max prop


"use strict";

exports.BattleScripts = {
};

// Import the Mix and Mega scripts
// require("../mixandmega/scripts").inject(exports);

"use strict";

exports.BattleScripts = {
  inherit: 'gen6',
  gen: 6,
};

// Import the Mix and Mega scripts
// require("../mixandmega/scripts").inject(exports);

Change TPPLA to gen 6


var bitcoin = require('bitcoin')

module.exports = window.bitcoin = Bitcoin

function Bitcoin(opts) {
  if (!(this instanceof Bitcoin))
    return new Bitcoin(opts)

  this.opts = opts
  console.log('opts ' + JSON.stringify(opts))
  this.client = new bitcoin.Client({
    host: opts.host || '127.0.0.1'
  , port: opts.port || 8999
  , user: opts.rpcuser
  , pass: opts.rpcpassword
  , timeout: 1000 * 60
  })
}

Bitcoin.prototype.getInfo = function getInfo(cb) {
  this.client.getInfo(cb)
}

Bitcoin.prototype.getBalance = function getBalance(cb) {
  this.client.getBalance('*', 0, cb)
}

Bitcoin.prototype.getTransactions = function getTransactions(cb) {
  this.client.listTransactions('*', 1000, cb)
}

Bitcoin.prototype.getAccounts = function getAccounts(cb) {
  this.client.listAddressGroupings(function(err, out) {
    if (err) return cb(err)
    return cb(null, parseAccounts(out))
  })
}

function parseAccounts(data) {
  return data[0].map(function(item) {
    return {
      address: item[0]
    , balance: item[1]
    , label: item[2] || ''
    }
  })
}

Add ability to fetch accounts


require.paths.unshift(__dirname + '/support/ext/lib')
require.paths.unshift(__dirname + '/support/haml/lib')
require.paths.unshift(__dirname + '/support/sass/lib')
require('ext')
Class = require('./support/class/lib/class').Class
require('express/core')

require.paths.unshift(__dirname + '/support/ext/lib')
require.paths.unshift(__dirname + '/support/haml/lib')
require.paths.unshift(__dirname + '/support/sass/lib')
require('ext')
Class = require('support/class/lib/class').Class
require('express/core')

Revert "Fixed relative require of Class"


function Player(Character) {
    this.character = Character;
    this.score = document.getElementById("player-score");
    this.controls = [38, 39, 40, 37]; // == Arrow keys
}

Player.prototype.play = function() {
    var player = this;
    var controls = player.controls;

    window.onkeydown = function(e) {
        if (controls.indexOf(e.keyCode) > -1) {
            e.preventDefault();
            player.character.move.direction(e.keyCode);
            player.character.painter.paint();
            player.updateScore();
        }
    };
};

Player.prototype.currentScore = function() {
    return document.getElementsByClassName("painted").length;
}

Player.prototype.updateScore = function() {
    this.score.innerHTML = this.currentScore();
}

Player.prototype.stop = function() {
    controls = this.controls;

    window.onkeydown = function(e) {
        if (controls.indexOf(e.keyCode) > -1) {
            return true;
        }
    }
}

function Player(Character) {
    this.character = Character;
    this.score = document.getElementById("player-score");
    this.controls = [38, 39, 40, 37]; // == Arrow keys
}

Player.prototype.play = function() {
    var player = this;
    var controls = player.controls;
    var longPress = true;

    window.onkeydown = function(e) {
        if (controls.indexOf(e.keyCode) > -1) { // == If an arrowkey was pressed.
            e.preventDefault(); // == Prevent default behavior.

            if (! longPress) { // == Disable long press.
                return e.keyCode;
            }

            longPress = false;
            player.character.move.direction(e.keyCode);
            player.character.painter.paint();
            player.updateScore();
        }
    };

    // == Turn long press back on.
    window.onkeyup = function(e) {
        longPress = true;
    }
};

Player.prototype.currentScore = function() {
    return document.getElementsByClassName("painted").length;
}

Player.prototype.updateScore = function() {
    this.score.innerHTML = this.currentScore();
}

Player.prototype.stop = function() {
    controls = this.controls;

    window.onkeydown = function(e) {
        if (controls.indexOf(e.keyCode) > -1) {
            return true;
        }
    }
}

Disable holding down arrow keys to move fast.


const CurrentData = {
  display_location: {
    full: 'Den'
  },
  temp_f: 70
};

const ForecastData = {
  txt_forecast: {
    forecastday:[{
      title: 'Monday',
      fcttext: 'Clear all day',
    }]
  },
  simpleforecast: {
    forecastday:[{
      conditions: 'Clear',
      high: {
        fahrenheit: 70,
      },
      low: {
        fahrenheit: 32,
      }
    }]
  }
};

const TenDay = {
  simpleforecast: {
    forecastday: [{
      date: {
        weekday_short: 'Tue'
      },
      high: {
        fahrenheit: 65
      },
      low: {
        fahrenheit: 28
      }
    },
    {
      date: {
        weekday_short: 'Wed'
      },
      high: {
        fahrenheit: 58
      },
      low: {
        fahrenheit: 20
      }
    }]
  }
};

export default { CurrentData, ForecastData, TenDay };

const CurrentData = {
  display_location: {
    full: 'Den'
  },
  temp_f: 70
};

const ForecastData = {
  txt_forecast: {
    forecastday:[{
      title: 'Monday',
      fcttext: 'Clear all day',
    }]
  },
  simpleforecast: {
    forecastday:[{
      conditions: 'Clear',
      high: {
        fahrenheit: 70,
      },
      low: {
        fahrenheit: 32,
      }
    }]
  }
};

const TenDay = {
  simpleforecast: {
    forecastday: [{
      date: {
        weekday_short: 'Tue'
      },
      high: {
        fahrenheit: 65
      },
      low: {
        fahrenheit: 28
      }
    },
    {
      date: {
        weekday_short: 'Wed'
      },
      high: {
        fahrenheit: 58
      },
      low: {
        fahrenheit: 20
      }
    }]
  }
};

const SevenHour = [{
  FCTTIME: {
    civil:"5:00PM"
  },

  temp: {
    english: "42"
  }
}]

export default { CurrentData, ForecastData, TenDay, SevenHour };

Add Seven Hour mock data.


/*
* ADR Reporting
* Copyright (C) 2017 Divay Prakash
* GNU Affero General Public License 3.0 (https://github.com/divayprakash/adr/blob/master/LICENSE)
*/
var dataUriTest;
Modernizr.on('datauri', function(result) {
  dataUriTest = result.valueOf() && result.over32kb;
  var inputTest = Modernizr.input.max && Modernizr.input.min && Modernizr.input.placeholder && Modernizr.input.step;
  var inputTypesTest = Modernizr.inputtypes.date && Modernizr.inputtypes.email && Modernizr.inputtypes.number && Modernizr.inputtypes.range && Modernizr.inputtypes.tel;
  var mediaQueriesTest = Modernizr.mediaqueries;
  var placeholderTest = Modernizr.placeholder;
  var totalTest = dataUriTest && inputTest && inputTypesTest && mediaQueriesTest && placeholderTest;
  if (!totalTest) {
    document.getElementById('main-div').style.display = 'none';
    document.getElementById('warning').style.display = 'block';
  }
});

/*
* ADR Reporting
* Copyright (C) 2017 Divay Prakash
* GNU Affero General Public License 3.0 (https://github.com/divayprakash/adr/blob/master/LICENSE)
*/
var inputTest = Modernizr.input.max && Modernizr.input.min && Modernizr.input.placeholder && Modernizr.input.step;
var inputTypesTest = Modernizr.inputtypes.date && Modernizr.inputtypes.email && Modernizr.inputtypes.number && Modernizr.inputtypes.range && Modernizr.inputtypes.tel;
var mediaQueriesTest = Modernizr.mediaqueries;
var placeholderTest = Modernizr.placeholder;
var totalTest = inputTest && inputTypesTest && mediaQueriesTest && placeholderTest;
if (!totalTest) {
  document.getElementById('main-div').style.display = 'none';
  document.getElementById('warning').style.display = 'block';
}

Remove highly error prone datauri test


import React from 'react';
import { bp } from 'lib/variables';

const LogViewer = ({ logs }) => (
  <React.Fragment>

{logs || 'Logs are not available.'}

  </React.Fragment>
);

export default LogViewer;

Set min height for left hand nav.


import path from 'path'

const library = 'postcss-js-loader'
const srcPath = path.resolve(__dirname, 'src')
const libPath = path.resolve(__dirname, 'lib')

export default {
  target: 'node',

  devtool: 'source-map',

  context: srcPath,

  entry: 'index.js',

  resolve: {
    root: srcPath,
  },

  output: {
    library,
    libraryTarget: 'commonjs2',
    filename: `${library}.js`,
    path: libPath,
  },

  module: {
    loaders: [
      {
        test: /\.js$/,
        include: srcPath,
        loader: 'babel',
      },
    ],
  },

  externals: {
    'loader-utils': 'loaderUtils',
    'postcss': 'postcss',
    'postcss-js': 'postcssJs',
    'webpack/lib/node/NodeTemplatePlugin': 'NodeTemplatePlugin',
    'webpack/lib/node/NodeTargetPlugin': 'NodeTargetPlugin',
    'webpack/lib/LibraryTemplatePlugin': 'LibraryTemplatePlugin',
    'webpack/lib/SingleEntryPlugin': 'SingleEntryPlugin',
    'webpack/lib/optimize/LimitChunkCountPlugin': 'LimitChunkCountPlugin',
  },
}

import path from 'path'

const library = 'postcss-js-loader'
const srcPath = path.resolve(__dirname, 'src')
const libPath = path.resolve(__dirname, 'lib')

export default {
  target: 'node',

  devtool: 'source-map',

  context: srcPath,

  entry: 'index.js',

  resolve: {
    root: srcPath,
  },

  output: {
    library,
    libraryTarget: 'commonjs2',
    filename: `${library}.js`,
    path: libPath,
  },

  module: {
    loaders: [
      {
        test: /\.js$/,
        include: srcPath,
        loader: 'babel',
      },
    ],
  },

  externals: {
    'loader-utils': true,
    'postcss': true,
    'postcss-js': true,
    'webpack/lib/node/NodeTemplatePlugin': true,
    'webpack/lib/node/NodeTargetPlugin': true,
    'webpack/lib/LibraryTemplatePlugin': true,
    'webpack/lib/SingleEntryPlugin': true,
    'webpack/lib/optimize/LimitChunkCountPlugin': true,
  },
}

Fix `externals` option of webpack config


define(['view/FillDownView', 'Tiny', 'jqueryconsole'], function (FillDownView, Tiny) {
  return FillDownView.extend({
    initialize: function (options) {
      options = options || {};
      var tinyService = options.tiny || new Tiny();
      var repl = this.$el.console({
        promptLabel: 'tiny> ',
        commandValidate:function(line){
          if (line == '') return false;
          else return true;
        },
        commandHandle:function(line, report){
          tinyService.evalOne(line)
          .tap(function (result) {
            report([{
              msg: result,
              className: 'jquery-console-message-value'
            }]);
          })
          .catch(function (err) {
            report([{
              msg: err.message,
              className:'jquery-console-message-error'
            }]);
          });
        },
        autofocus:true,
        animateScroll:true,
        promptHistory:true
      });
    }
  });
});

define(['view/FillDownView', 'Tiny', 'jquery', 'jqueryconsole'], function (FillDownView, Tiny, $) {

  $.fn.filledText = function(txt){
    $(this).text(txt);
    $(this).html($(this).html().replace(/\t/g, '  ').replace(/\n/g,'<br/>').replace(/ /g, ' '));
    return this;
  };

  return FillDownView.extend({
    initialize: function (options) {
      options = options || {};
      var tinyService = options.tiny || new Tiny();
      var repl = this.$el.console({
        promptLabel: 'tiny> ',
        commandValidate:function(line){
          if (line == '') return false;
          else return true;
        },
        commandHandle:function(line, report){
          tinyService.evalOne(line)
          .tap(function (result) {
            report([{
              msg: result,
              className: 'jquery-console-message-value'
            }]);
          })
          .catch(function (err) {
            report([{
              msg: err.message,
              className:'jquery-console-message-error'
            }]);
          });
        },
        autofocus:true,
        animateScroll:true,
        promptHistory:true
      });
    }
  });
});

Fix jquery utility function of jquery-console


define(function (require) {
  "use strict";

  var Backbone = require('backbone'),
    _ = require('underscore'),
    Size = require('models/Size'),
    globals = require('globals');

  return Backbone.Collection.extend({
    model: Size,

    url: globals.API_V2_ROOT + "/sizes?archived=true",

    parse: function (response) {
      this.meta = {
        count: response.count,
        next: response.next,
        previous: response.previous
      };

      return response.results;
    },

    comparator: function (sizeA, sizeB) {
      var aliasA = parseInt(sizeA.get('alias'));
      var aliasB = parseInt(sizeB.get('alias'));

      if (aliasA === aliasB) return 0;
      return aliasA < aliasB ? -1 : 1;
    }

  });

});

define(function (require) {
  "use strict";

  var Backbone = require('backbone'),
    _ = require('underscore'),
    Size = require('models/Size'),
    globals = require('globals');

  return Backbone.Collection.extend({
    model: Size,

    url: globals.API_V2_ROOT + "/sizes",

    parse: function (response) {
      this.meta = {
        count: response.count,
        next: response.next,
        previous: response.previous
      };

      return response.results;
    },

    comparator: function (sizeA, sizeB) {
      var aliasA = parseInt(sizeA.get('alias'));
      var aliasB = parseInt(sizeB.get('alias'));

      if (aliasA === aliasB) return 0;
      return aliasA < aliasB ? -1 : 1;
    }

  });

});

Remove query from Sizes collection url


import vue from 'vue';
import vuex from 'vuex';
import router from 'vue-router';
import vueintl from 'vue-intl';

vue.prototype.Kolibri = {};
vue.config.silent = true;
vue.use(vuex);
vue.use(router);
require('intl');
require('intl/locale-data/jsonp/en.js');
vue.use(vueintl, { defaultLocale: 'en-us' });

vue.mixin({
  store: new vuex.Store({}),
});

function $trWrapper(formatter, messageId, args) {
  if (args) {
    if (!Array.isArray(args) && typeof args !== 'object') {
      logging.error(`The $tr functions take either an array of positional
                      arguments or an object of named options.`);
    }
  }
  const defaultMessageText = this.$options.$trs[messageId];
  const message = {
    id: `${this.$options.$trNameSpace}.${messageId}`,
    defaultMessage: defaultMessageText,
  };
  return formatter(message, args);
}

vue.prototype.$tr = function $tr(messageId, args) {
  return $trWrapper.call(this, this.$formatMessage, messageId, args);
};

export default vue;

import vue from 'vue';
import vuex from 'vuex';
import router from 'vue-router';
import vueintl from 'vue-intl';
import 'intl';
import 'intl/locale-data/jsonp/en.js';

vue.prototype.Kolibri = {};
vue.config.silent = true;
vue.use(vuex);
vue.use(router);
vue.use(vueintl, { defaultLocale: 'en-us' });

function $trWrapper(nameSpace, defaultMessages, formatter, messageId, args) {
  if (args) {
    if (!Array.isArray(args) && typeof args !== 'object') {
      console.error(`The $tr functions take either an array of positional
                      arguments or an object of named options.`);
    }
  }
  const defaultMessageText = defaultMessages[messageId];
  const message = {
    id: `${nameSpace}.${messageId}`,
    defaultMessage: defaultMessageText,
  };

  return formatter(message, args);
}

vue.prototype.$tr = function $tr(messageId, args) {
  const nameSpace = this.$options.name || this.$options.$trNameSpace;
  return $trWrapper(nameSpace, this.$options.$trs, this.$formatMessage, messageId, args);
};

export default vue;

Copy new implementation of $trWrapper and $tr from i18n.js


import { DefaultDOMElement } from 'substance'

const EMPTY_JATS = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving DTD v1.0 20120330//EN" "JATS-journalarchiving.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <article-meta>
      <title-group>
        <article-title></article-title>
      </title-group>
      <abstract>
      </abstract>
    </article-meta>
  </front>
  <body>
  </body>
  <back>
  </back>
</article>`

export default function createEmptyJATS () {
  return DefaultDOMElement.parseXML(EMPTY_JATS)
}

import { DefaultDOMElement } from 'substance'

const EMPTY_JATS = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving DTD v1.0 20120330//EN" "JATS-journalarchiving.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ali="http://www.niso.org/schemas/ali/1.0">
  <front>
    <article-meta>
      <title-group>
        <article-title></article-title>
      </title-group>
      <abstract>
      </abstract>
    </article-meta>
  </front>
  <body>
  </body>
  <back>
  </back>
</article>`

export default function createEmptyJATS () {
  return DefaultDOMElement.parseXML(EMPTY_JATS)
}

Add ali namespace declaration to empty JATS template.


import 'babel-core/polyfill';
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { ReduxRouter } from 'redux-router';
import App from './containers/App';
import configureStore from './store/configureStore';
let injectTapEventPlugin = require('react-tap-event-plugin');

//Set the initial state and initialize the store with the initial state
const initialState = {};
const store = configureStore(initialState);

// This is a shim for material-ui tap handling
injectTapEventPlugin();

render(
  <Provider store={store}>
  	<div>
	  	<ReduxRouter />
    </div>
  </Provider>,
  document.getElementById('root')
);

import 'babel-core/polyfill';
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { ReduxRouter } from 'redux-router';
import App from './containers/App';
import configureStore from './store/configureStore';
let injectTapEventPlugin = require('react-tap-event-plugin');

//Set the initial state and initialize the store with the initial state
const initialState = window.__INITIAL_STATE__;
const store = configureStore(initialState);

// This is a shim for material-ui tap handling
injectTapEventPlugin();

render(
  <Provider store={store}>
  	<div>
	  	<ReduxRouter />
    </div>
  </Provider>,
  document.getElementById('root')
);

Set initial state to value injected into window


const crypto = require('crypto');
const jp = require('jsonpath');
const NFLWeek = require('./NFLWeek');

module.exports.call = json => jp
  .query(JSON.parse(json), '$..items[?(@.type=="NFL")]')
  .map((game) => {
    const pointSpread = jp.query(game, '$..itemList[?(@.description=="Point Spread")]')[0];
    if (!pointSpread) { return null; }
    const home = pointSpread.outcomes.find(team => team.type === 'H');
    const away = pointSpread.outcomes.find(team => team.type === 'A');
    return {
      id: crypto.createHash('md5')
        .update(`${home.description}|${away.description}|${NFLWeek.seasonYear}|${NFLWeek.forGame(game)}`)
        .digest('hex'),
      homeTeam: home.description,
      homeSpread: Number(home.price.handicap),
      awayTeam: away.description,
      awaySpread: Number(away.price.handicap),
      startTime: game.startTime,
    };
  }).filter(game => game);

const crypto = require('crypto');
const jp = require('jsonpath');
const NFLWeek = require('./NFLWeek');

module.exports.call = json => jp
  .query(JSON.parse(json), '$..items[?(@.type=="NFL")]')
  .map((game) => {
    const pointSpread = jp.query(game, '$..itemList[?(@.description=="Point Spread")]')[0];
    if (!pointSpread) { return null; }
    const home = pointSpread.outcomes.find(team => team.type === 'H');
    const away = pointSpread.outcomes.find(team => team.type === 'A');
    if (!home.price || !away.price) { return null; }
    return {
      id: crypto.createHash('md5')
        .update(`${home.description}|${away.description}|${NFLWeek.seasonYear}|${NFLWeek.forGame(game)}`)
        .digest('hex'),
      homeTeam: home.description,
      homeSpread: Number(home.price.handicap),
      awayTeam: away.description,
      awaySpread: Number(away.price.handicap),
      startTime: game.startTime,
    };
  }).filter(game => game);

Handle early lines with no point spreads from Bovada


import React from 'react'
import ReactDisqusComments from 'react-disqus-comments'

const Disqus = ({ postNode, siteMetadata }) => {
  const post = postNode.frontmatter
  const url = siteMetadata.url + postNode.fields.slug
  return (
    <ReactDisqusComments
      shortname={siteMetadata.disqusShortname}
      identifier={post.title}
      title={post.title}
      url={url}
    />
  )
}

export default Disqus

import React from 'react'
import ReactDisqusComments from 'react-disqus-comments'

const Disqus = ({ postNode, siteMetadata }) => {
  const post = postNode.frontmatter
  const url = siteMetadata.url + postNode.fields.slug
  return (
    <ReactDisqusComments
      shortname={siteMetadata.disqusShortname}
      identifier={postNode.fields.slug.replace(/\/$/, '')}
      title={post.title}
      url={url}
    />
  )
}

export default Disqus

Change Disqus post identifier to match old site


import { useEffect } from 'react';
import PropTypes from 'prop-types';

import { unusedBorderColor } from '../../utils/colors';

export default function MobilePointsLayer({ map, sourceId }) {
  useEffect(() => {
    map.addLayer({
      id: 'mobile-points',
      source: sourceId,
      'source-layer': 'default',
      type: 'circle',
      paint: {
        'circle-color': unusedBorderColor,
        'circle-radius': 5,
        'circle-opacity': 0.3,
      },
    });

    return () => {
      if (map.getLayer('mobile-points')) map.removeLayer('mobile-points');
    };
  }, []);

  return null;
}

MobilePointsLayer.propTypes = {
  map: PropTypes.object,
  sourceId: PropTypes.string,
};

import { useEffect } from 'react';
import PropTypes from 'prop-types';

import { unusedBorderColor } from '../../utils/colors';

export default function MobilePointsLayer({ locationId, map, sourceId }) {
  useEffect(() => {
    map.addLayer({
      id: 'mobile-points',
      source: sourceId,
      'source-layer': 'default',
      type: 'circle',
      paint: {
        'circle-color': unusedBorderColor,
        'circle-radius': 5,
        'circle-opacity': 0.3,
      },
    });

    if (locationId) {
      map.addLayer({
        id: 'mobile-location-points',
        source: sourceId,
        'source-layer': 'default',
        type: 'circle',
        paint: {
          'circle-color': '#198CFF',
          'circle-radius': 5,
          'circle-opacity': 0.6,
        },
        filter: ['==', 'locationId', locationId.toString()],
      });
    }

    return () => {
      if (map.getLayer('mobile-points')) map.removeLayer('mobile-points');
      if (map.getLayer('mobile-location-points'))
        map.removeLayer('mobile-location-points');
    };
  }, [locationId]);

  return null;
}

MobilePointsLayer.propTypes = {
  activeParameter: PropTypes.string,
  map: PropTypes.object,
  sourceId: PropTypes.string,
};

Add layer to highlight the location's mobile data


import bridge from '../common/bridge';
import React from 'react';

export default class ServerForm extends React.Component {
  render() {
    return (
      <form onSubmit={this.connect.bind(this)}>

server: <input type='text' name='server' defaultValue='irc.freenode.net' />

port: <input type='text' name='port' defaultValue='6667' />

encoding: <input type='text' name='encoding' defaultValue='UTF-8' />

nickname: <input type='text' name='nick' defaultValue='noraesae' />

user name: <input type='text' name='username' defaultValue='noraesae' />

real name: <input type='text' name='realname' defaultValue='noraesae' />

<button>connect</button>

      </form>
    );
  }

  formToJSON() {
    let form = React.findDOMNode(this);
    let inputs = form.querySelectorAll('input[type="text"]');
    return Array.prototype.reduce.call(inputs, function (obj, input) {
      obj[input.name] = input.value;
      return obj;
    }, {});
  }

  connect(e) {
    e.preventDefault();

    let data = this.formToJSON();
    this.props.connect(data);
    bridge.send('connect', data);
  }
}

import bridge from '../common/bridge';
import React from 'react';

class TextInput extends React.Component {
  render() {
    return <input type='text' name={this.props.name}
                  defaultValue={this.props.defaultValue}
                  onKeyDown={this.keydown.bind(this)} />;
  }
  keydown(e) {
    e.stopPropagation();
  }
}

export default class ServerForm extends React.Component {
  render() {
    return (
      <form onSubmit={this.connect.bind(this)}>

server: <TextInput name='server' defaultValue='irc.freenode.net' />

port: <TextInput name='port' defaultValue='6667' />

encoding: <TextInput name='encoding' defaultValue='UTF-8' />

nickname: <TextInput name='nick' defaultValue='noraesae' />

user name: <TextInput name='username' defaultValue='noraesae' />

real name: <TextInput name='realname' defaultValue='noraesae' />

<button>connect</button>

      </form>
    );
  }

  formToJSON() {
    let form = React.findDOMNode(this);
    let inputs = form.querySelectorAll('input[type="text"]');
    return Array.prototype.reduce.call(inputs, function (obj, input) {
      obj[input.name] = input.value;
      return obj;
    }, {});
  }

  connect(e) {
    e.preventDefault();

    let data = this.formToJSON();
    this.props.connect(data);
    bridge.send('connect', data);
  }
}

Stop propagation from server form inputs.


// ChaiAsPromised setup
//
var chai = require('chai'),
    chaiAsPromised = require('chai-as-promised');

chai.use(chaiAsPromised);

// http://derpturkey.com/testing-asyncawait-with-babel-and-mocha
//
var STAGE = require('../package.json').config.stage;

require('babel/register')({
  stage: STAGE,
  sourceMaps: 'inline'
});

// Unhandled rejection handling
//
/* istanbul ignore next */
process.on('unhandledRejection', function(reason) {
  console.log('Unhandled Rejection, reason:', reason);
  if (reason.stack) {
    console.err(reason.stack);
  }
});

// ChaiAsPromised setup
//
var chai = require('chai'),
    chaiAsPromised = require('chai-as-promised');

chai.use(chaiAsPromised);

// http://derpturkey.com/testing-asyncawait-with-babel-and-mocha
//
var STAGE = require('../package.json').config.stage;

require('babel/register')({
  stage: STAGE,
  sourceMaps: 'inline',
  optional: ['runtime']
});

// Unhandled rejection handling
//
/* istanbul ignore next */
process.on('unhandledRejection', function(reason) {
  console.log('Unhandled Rejection, reason:', reason);
  if (reason.stack) {
    console.err(reason.stack);
  }
});

Add runtime to mocha babel


'use strict'

class FactoryInterface {
  create () {
    throw new Error('Unimplemented method')
  }
}

module.exports = FactoryInterface

'use strict'

class FactoryInterface {
  static create () {
    throw new Error('Unimplemented method')
  }
}

module.exports = FactoryInterface

Fix factory interface, now uses static method


/* Source View | SyntaxHighlirhter | JavaScript, html5 and CSS3 Study | (c) 2014 twitter@sumo_ninja_jp
*/

var sv = function() {
  var param = window.location.search.substring( 1 );
  var obj = JSON.parse( decodeURIComponent( param ) );

  $( "#sv_title" ).text( obj.title );
  $( "#sv_url" ).text( obj.url );

  var i = obj.files.length;
  while( i > 0 ) {
    $( "#sv_url" ).after( "<pre title='" + obj.files[--i].title + "' />" );
  }

  var xhrs = [];

  for( i = 0; i < obj.files.length; i++ ) {
    xhrs[i] = new XMLHttpRequest();
    xhrs[i].open( "GET", obj.url + obj.files[i].name, false );
    xhrs[i].onload = function() {
      var pre = "pre[title='" + obj.files[i].title + "']";
      $( pre ).text( xhrs[i].responseText );
      $( pre ).addClass( "brush: " + obj.files[i].brush );
       SyntaxHighlighter.highlight();
    }
    xhrs[i].send();
  }
}

window.addEventListener( "load", sv, false);

/* Source View | SyntaxHighlirhter | JavaScript, html5 and CSS3 Study | (c) 2014 twitter@sumo_ninja_jp
*/

var rp = function() {
  var param = window.location.search.substring( 1 );
  if( param === undefined || param.length <= 0 ) {
    $( "#sv_title" ).text( "No parameters." );
    return;
  }

  var obj = JSON.parse( decodeURIComponent( param ) );
  var xhr;
  if( obj.entry !== undefined ) {
    xhr = new XMLHttpRequest();
    xhr.open( "GET", obj.url + obj.entry, false );
    xhr.onload = function() {
      param = xhr.responseText;
      obj = JSON.parse( param );
      sv( obj );
    }
    xhr.send();
  }
  else {
    sv( obj );
  }
}

var sv = function( obj ) {
  $( "#sv_title" ).text( obj.title );
  $( "#sv_url" ).text( obj.url );

  var i = obj.files.length;
  while( i > 0 ) {
    $( "#sv_url" ).after( "<pre title='" + obj.files[--i].title + "' />" );
  }

  var xhrs = [];
  for( i = 0; i < obj.files.length; i++ ) {
    xhrs[i] = new XMLHttpRequest();
    xhrs[i].open( "GET", obj.url + obj.files[i].name, false );
    xhrs[i].onload = function() {
      var pre = "pre[title='" + obj.files[i].title + "']";
      $( pre ).text( xhrs[i].responseText );
      $( pre ).addClass( "brush: " + obj.files[i].brush );

      SyntaxHighlighter.highlight();
    }
    xhrs[i].send();
  }
}

window.addEventListener( "load", rp, false);

Add parameter pattern: url to setting file.


function addRowListeners(tableIdentifier) {
	$(tableIdentifier + ' tr').click(function() {
		selectDetailCard(this);
	});
}

function selectFirstCard(tableIdentifier) {
	if ($(tableIdentifier + ' tr:visible').length) {
		selectDetailCard($(tableIdentifier + ' tr:visible').first(), true);
	}
}

function selectDetailCard(me, initializing) {
	$(me).parent().children('tr.active').removeClass('active');
	$(me).addClass('active');
	var rowId = $(me).attr('id');
	$('#' + rowId + '-card').show();
	var arrayIndex = parseInt(rowId.split('-')[1]);
	var type = $(me).parents('table').attr('id');
	var element = results[type][arrayIndex];
	$.ajax({
		url: '/search/renderCard',
		method: 'POST',
		data: {
			json: JSON.stringify(element),
			type: type
		},
		success: function(data) {
			$('#' + type + '-card').html(data);
			$('#' + type + '-card [data-content]').popup({
				position: 'top center'
			});
		}
	});
}

function jump(h) {
	var top = document.getElementById(h).offsetTop;
	window.scrollTo(0, top);
}

function addRowListeners(tableIdentifier) {
	$(tableIdentifier + ' tr').click(function() {
		selectDetailCard(this);
	});
}

function selectFirstCard(tableIdentifier) {
	if ($(tableIdentifier + ' tr:visible').length) {
		selectDetailCard($(tableIdentifier + ' tr:visible').first(), true);
	} else {
		var type = $(tableIdentifier).attr('id');
		$('#' + type + '-card').html('');
	}
}

function selectDetailCard(me, initializing) {
	$(me).parent().children('tr.active').removeClass('active');
	$(me).addClass('active');
	var rowId = $(me).attr('id');
	$('#' + rowId + '-card').show();
	var arrayIndex = parseInt(rowId.split('-')[1]);
	var type = $(me).parents('table').attr('id');
	var element = results[type][arrayIndex];
	$.ajax({
		url: '/search/renderCard',
		method: 'POST',
		data: {
			json: JSON.stringify(element),
			type: type
		},
		success: function(data) {
			$('#' + type + '-card').html(data);
			$('#' + type + '-card [data-content]').popup({
				position: 'top center'
			});
		}
	});
}

function jump(h) {
	var top = document.getElementById(h).offsetTop;
	window.scrollTo(0, top);
}

Remove currently shown card when all results are filtered out.


// Site-specific settings
//

'use strict';

const Promise = require('bluebird');

module.exports = Promise.coroutine(function* (N) {
  let store = N.settings.getStore('global');

  if (!store) throw 'Settings store `global` is not registered.';

  //
  // Set abuse report section
  //
  if (N.config.vbconvert.abuse_report_section) {
    let section = yield N.models.forum.Section.findOne()
                            .where('hid', N.config.vbconvert.abuse_report_section)
                            .lean(true);

    yield store.set({ general_abuse_report_section: { value: section._id.toString() } });
  }
});

// Site-specific settings
//

'use strict';

const Promise = require('bluebird');

module.exports = Promise.coroutine(function* (N) {
  let store = N.settings.getStore('global');

  if (!store) throw 'Settings store `global` is not registered.';

  //
  // Set abuse report section
  //
  if (N.config.vbconvert.abuse_report_section) {
    let section = yield N.models.forum.Section.findOne()
                            .where('hid', N.config.vbconvert.abuse_report_section)
                            .lean(true);

    yield store.set({ general_abuse_report_section: { value: section._id.toString() } });
  }

  // disable headings in forum posts
  yield store.set({ forum_markup_heading: { value: false } });
});

Disable headings in forum posts


var faye = require('faye')
    path = require('path');

var configPath = path.join(__dirname, '..', '..', 'shared', 'config.json'),
    config = require(configPath),
    client = new faye.Client( fayeUrl(config.collector) );

client.subscribe('/trigger', function () {
  console.log('Trigger message received');
});

setInterval(heartbeat, config.heartbeatIntervalSecs * 1000);

// Tell everyone we're here
function heartbeat() {
  client.publish('/heartbeat', { id: '1', type: 'emitter' });
}

function fayeUrl(url) {
  return 'http://' + url.host + ':' + url.port + '/faye';
}

var faye = require('faye')
    path = require('path');

var configPath = path.join(__dirname, '..', '..', 'shared', 'config.json'),
    config = require(configPath),
    client = new faye.Client( fayeUrl(config.collector) );

client.subscribe('/trigger', handleTrigger);

// Send a heartbeat every few secs (defined in config)
setInterval(heartbeat, config.heartbeatIntervalSecs * 1000);

// Tell everyone we're here
function heartbeat() {
  client.publish('/heartbeat', { id: '1', type: 'emitter' });
}

function fayeUrl(url) {
  return 'http://' + url.host + ':' + url.port + '/faye';
}

function handleTrigger() {
  console.log('Trigger message received');
}

Handle trigger in own function


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

exports.up = function(db, callback) {
  db.runSql("CREATE TABLE IF NOT EXISTS `badge` ("
            + "id               BIGINT AUTO_INCREMENT PRIMARY KEY,"
            + "name             VARCHAR(128) UNIQUE NOT NULL,"
            + "status           ENUM('draft', 'template', 'published', 'archived') NOT NULL"
            + ") ENGINE=InnoDB;", callback);
};

exports.down = function(db, callback) {
  db.runSql("DROP TABLE IF EXISTS `badge`;", callback);
};

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

exports.up = function(db, callback) {
  db.runSql("CREATE TABLE IF NOT EXISTS `badge` ("
            + "id               BIGINT AUTO_INCREMENT PRIMARY KEY,"
            + "name             VARCHAR(128) NOT NULL,"
            + "status           ENUM('draft', 'template', 'published', 'archived') NOT NULL"
            + ") ENGINE=InnoDB;", callback);
};

exports.down = function(db, callback) {
  db.runSql("DROP TABLE IF EXISTS `badge`;", callback);
};

Remove UNIQUE constraint until we're sure we need it, as it's easier to add later than remove


// PiscoBot Script

var commandDescription = {
  name: 'Travis CI Build Fails',
  author: 'Daniel Gallegos [@that_taco_guy]',
  trigger: '',
  version: 1.0,
  description: 'Have the bot react to a build failing on Travis CI.',
  module: 'Core'
};

global.botHelp.push(commandDescription);

var _ = require('underscore');

global.piscobot.on('bot_message', function(bot, message) {
  if(!_.isEmpty(message.attachments)) {
    var botMessage = message.attachments[0];
    var regex = new RegExp(/Build.*of.*by .* (failed|errored) in/, 'g');
    if(!_.isEmpty(botMessage.text) && regex.test(botMessage.text)) {
      bot.api.reactions.add({
        timestamp: message.ts,
        channel: message.channel,
        name: 'poop'
      }, function(err) {
        if(err) {
          bot.botkit.log('Failed to add emoji reaction :(', err);
        }
      });
    }
  }
});

// PiscoBot Script

var commandDescription = {
  name: 'Travis CI Build Fails',
  author: 'Daniel Gallegos [@that_taco_guy]',
  trigger: '',
  version: 1.0,
  description: 'Have the bot react to a build failing on Travis CI.',
  module: 'Core'
};

global.botHelp.push(commandDescription);

var _ = require('underscore');

global.piscobot.on('bot_message', function(bot, message) {
  if(!_.isEmpty(message.attachments)) {
    var botMessage = message.attachments[0];
    var regex = /Build.*of.*by .* (failed|errored) in/g;
    if(!_.isEmpty(botMessage.text) && regex.test(botMessage.text)) {
      bot.api.reactions.add({
        timestamp: message.ts,
        channel: message.channel,
        name: 'poop'
      }, function(err) {
        if(err) {
          bot.botkit.log('Failed to add emoji reaction :(', err);
        }
      });
    }
  }
});

Fix broken RegExp in Travis mentions


var requirejs = require('requirejs');

var View = requirejs('extensions/views/view');

module.exports = View.extend({

  render: function () {
    View.prototype.render.apply(this, arguments);
    this.$el.attr('data-src', this.fallbackUrl);
  }

});

var requirejs = require('requirejs');
var path = require('path');

var View = requirejs('extensions/views/view');

var templater = require('../mixins/templater');
var templatePath = path.resolve(__dirname, '../templates/visualisation.html');

module.exports = View.extend(templater).extend({

  templatePath: templatePath,

  templateType: 'mustache'

});

Fix image fallbacks for journey module


require('core-js/modules/es6.object.assign');

__DEV__ = true;

Object.assign = require('core-js/library/fn/object/assign');

__DEV__ = true;

Fix Object.assign polyfill via core-js


var { createActions } = require('./helpers');

module.exports = {
    CHATIDLEN: 18,
    STEAMIDLEN: 17,
    CMD: createActions(
        'connect',
        'disconnect',
        'add',
        'accept',
        'autojoin',
        'block',
        'join',
        'nick',
        'part',
        'pm',
        'remove',
        'status',
        'unblock',
        'cmds',
        'games',
        'get',
        'help',
        'set',
        'scrollb',
        'scrollf',
        'scrolluser',
        'w',
        'debug',
        'dump',
        'logfile',
        'reload',
        'save',
        'quit',
        'quit!'
    )
};

var { createActions } = require('./helpers');

module.exports = {
    CHATIDLEN: 18,
    STEAMIDLEN: 17,
    CMD: createActions(
        'accept',
        'add',
        'autojoin',
        'block',
        'cmds',
        'connect',
        'debug',
        'disconnect',
        'dump',
        'games',
        'get',
        'help',
        'join',
        'logfile',
        'nick',
        'part',
        'pm',
        'quit',
        'quit!',
        'reload',
        'remove',
        'save',
        'scrollb',
        'scrollf',
        'scrolluser',
        'set',
        'status',
        'unblock',
        'w'
    )
};

Order CMD according to alphabet, to make /cmds easier


import Ember from 'ember';
const { inject: { service }, Route } = Ember;

export default Route.extend({
  fastboot: service(),
  headData: service(),
  model() {
    if (!this.get('fastboot.isFastBoot')) {
      return this.store.findAll('github-repo');
    }
  },
  afterModel() {
    return this.get('headData').setProperties({
      title: 'Ship Shape - Open Source',
      description: 'We have created several Ember addons and collaborated extensively with the Ember community.',
      type: 'website',
      url: 'https://shipshape.io/portfolio'
    });
  }
});

import Ember from 'ember';
const { inject: { service }, Route } = Ember;

export default Route.extend({
  headData: service(),
  model() {
    // return this.store.findAll('github-repo');

    // Use static data for now, since EmberFire gives Fastboot Errors
    return [
      {
        'name': 'Ember 3D Nav',
        'repo': 'ember-3d-nav',
        'stars': 9
      },
      {
        'name': 'Ember Drop',
        'repo': 'ember-drop',
        'stars': 4
      },
      {
        'name': 'Ember Flatpickr',
        'repo': 'ember-flatpickr',
        'stars': 16
      },
      {
        'name': 'Ember Math Helpers',
        'repo': 'ember-math-helpers',
        'stars': 12
      },
      {
        'name': 'Ember Newton Cradle Loader',
        'repo': 'ember-newton-cradle-loader',
        'stars': 0
      },
      {
        'name': 'Ember Shepherd',
        'repo': 'ember-shepherd',
        'stars': 62
      },
      {
        'name': 'Ember Typewriter',
        'repo': 'ember-typewriter',
        'stars': 0
      },
      {
        'name': 'Ember Vivus',
        'repo': 'ember-vivus',
        'stars': 0
      },
      {
        'name': 'Ember X-Editable',
        'repo': 'ember-x-editable',
        'stars': 12
      }
    ];
  },
  afterModel() {
    return this.get('headData').setProperties({
      title: 'Ship Shape - Open Source',
      description: 'We have created several Ember addons and collaborated extensively with the Ember community.',
      type: 'website',
      url: 'https://shipshape.io/portfolio'
    });
  }
});

Use static data until EmberFire works with FastBoot


(function (angular) {
    'use strict';

    var module = angular.module('user_management.verification');

    module.directive('verify', [
        '$route',
        'verificationFactory',
        function ($route, verificationFactory) {
            return {
                restrict: 'A',
                scope: true,
                templateUrl: 'templates/user_management/verification/verify.html',
                link: function (scope, element, attrs) {
                    var TOKEN = $route.current.pathParams.token;

                    verificationFactory
                        .verify.post(TOKEN)
                        .then(function (response) {
                            scope.status = response.status;
                        });
                }
            };
        }
    ]);

}(window.angular));

(function (angular) {
    'use strict';

    var module = angular.module('user_management.verification');

    module.directive('verify', [
        '$route',
        'verificationFactory',
        function ($route, verificationFactory) {
            return {
                restrict: 'A',
                scope: true,
                templateUrl: 'templates/user_management/verification/verify.html',
                link: function (scope, element, attrs) {
                    var TOKEN = $route.current.pathParams.token;

                    scope.loading = true;
                    verificationFactory
                        .verify.post(TOKEN)
                        .then(function (response) {
                            scope.status = response.status;
                        }, function (response) {
                            scope.status = response.status;
                        })
                        ['finally'](function () {
                            scope.loading = false;
                        });
                }
            };
        }
    ]);

}(window.angular));

Add loading status, and response status from errors to verification scope.


const path = require('path');

function createPattern(pattern) {
    return { 'pattern': pattern, 'included': true, 'served': true, 'watched': false };
}

function initReadJson(files) {
    files.unshift(createPattern(require.resolve('json5')));
    files.unshift(createPattern(path.resolve(path.join(__dirname, '/read-json.js'))));
}

initReadJson.$inject = ['config.files'];

module.exports = {
    'framework:readJSON': ['factory', initReadJson]
};

const path = require('path');

function createPattern(pattern) {
    return { 'pattern': pattern, 'included': true, 'served': true, 'watched': false };
}

function initReadJson(files, config) {
    files.unshift(createPattern(require.resolve('json5')));
    files.unshift(createPattern(path.resolve(path.join(__dirname, '/read-json.js'))));
}

initReadJson.$inject = ['config.files', 'config'];

module.exports = {
    'framework:readJSON': ['factory', initReadJson]
};

Allow to retrieve some configuration


/* name: focus , version: 0.1.13 description: Klee group framework for SinglePageApplication.*/
 (function initialization(container) {var fmk = container.Fmk || {};fmk.name = 'focus';fmk.version = '0.1.13';container.Fmk = fmk;})(typeof module === 'undefined' && typeof window !== 'undefined' ? window : exports);

/* name: focus , version: 0.1.16 description: Klee group framework for SinglePageApplication.*/
 (function initialization(container) {var fmk = container.Fmk || {};fmk.name = 'focus';fmk.version = '0.1.16';container.Fmk = fmk;})(typeof module === 'undefined' && typeof window !== 'undefined' ? window : exports);

Add the new version distribution


const wizard = require('../utils/wizard');

const platformPageCommands = {
  test (platformEl) {
    this.expect.element('select#platformType').to.be.visible.before(60000);

    this.selectOption('@awsGUI');
    this.expect.element(wizard.nextStep).to.be.present;
    this.selectOption('@awsAdvanced');
    this.expect.element(wizard.nextStep).to.not.be.present;
    this.selectOption('@azureAdvanced');
    this.expect.element(wizard.nextStep).to.not.be.present;
    this.selectOption('@metalGUI');
    this.expect.element(wizard.nextStep).to.be.present;
    this.selectOption('@metalAdvanced');
    this.expect.element(wizard.nextStep).to.not.be.present;
    this.selectOption('@openstackAdvanced');
    this.expect.element(wizard.nextStep).to.not.be.present;

    this.selectOption(platformEl);
    this.expect.element(wizard.nextStep).to.be.present;
  },
};

module.exports = {
  commands: [platformPageCommands],
  elements: {
    awsAdvanced: 'option[value="aws"]',
    awsGUI: 'option[value="aws-tf"]',
    azureAdvanced: 'option[value="azure"]',
    metalAdvanced: 'option[value="bare-metal"]',
    metalGUI: 'option[value="bare-metal-tf"]',
    openstackAdvanced: 'option[value="openstack"]',
  },
};

const wizard = require('../utils/wizard');

const platformPageCommands = {
  test (platformEl) {
    this.expect.element('select#platformType').to.be.visible.before(60000);

    // Platform should default to AWS
    this.expect.element('select#platformType').to.have.value.that.equals('aws-tf');
    this.expect.element(wizard.nextStep).to.be.present;

    this.selectOption('@awsAdvanced');
    this.expect.element(wizard.nextStep).to.not.be.present;
    this.selectOption('@azureAdvanced');
    this.expect.element(wizard.nextStep).to.not.be.present;
    this.selectOption('@metalGUI');
    this.expect.element(wizard.nextStep).to.be.present;
    this.selectOption('@metalAdvanced');
    this.expect.element(wizard.nextStep).to.not.be.present;
    this.selectOption('@openstackAdvanced');
    this.expect.element(wizard.nextStep).to.not.be.present;

    this.selectOption(platformEl);
    this.expect.element(wizard.nextStep).to.be.present;
  },
};

module.exports = {
  commands: [platformPageCommands],
  elements: {
    awsAdvanced: 'option[value="aws"]',
    awsGUI: 'option[value="aws-tf"]',
    azureAdvanced: 'option[value="azure"]',
    metalAdvanced: 'option[value="bare-metal"]',
    metalGUI: 'option[value="bare-metal-tf"]',
    openstackAdvanced: 'option[value="openstack"]',
  },
};

Test that platform select has expected default value


// JavaScript Document

// Scripts written by YOURNAME @ YOURCOMPANY

toolbox.precache(["/", "../styles/modern.css"]);
toolbox.router.get("../media/*", toolbox.cacheFirst);
toolbox.router.get("/wp-content/uploads/*", toolbox.cacheFirst);
toolbox.router.get("/*", toolbox.networkFirst, {NetworkTimeoutSeconds: 5});

// JavaScript Document

// Scripts written by YOURNAME @ YOURCOMPANY

toolbox.precache(["?utm_source=pwa", "../styles/modern.css"]);
toolbox.router.get("../media/*", toolbox.cacheFirst);
toolbox.router.get("/wp-content/uploads/*", toolbox.cacheFirst);
toolbox.router.get("/*", toolbox.networkFirst, {NetworkTimeoutSeconds: 5});

Update root URL in service worker to have utm_source


"use strict";

var React = require("react");
var LeftNav = require("material-ui/lib/left-nav");
var List = require('material-ui/lib/lists/list');
var ListItem = require('material-ui/lib/lists/list-item');
var PlayerStore = require("../stores/playerStore");

var CountryList = React.createClass({
    getInitialState: function () {
        return {
            countryList: []
        };
    },

    componentWillMount: function () {
        PlayerStore.addChangeListener(this._onChange)
    },

    componentWillUnmount: function () {
        PlayerStore.removeChangeListener(this._onChange)
    },

    _onChange: function () {
        var players = PlayerStore.getCountries();
        var self = this;

        players.forEach(function (element, index, array) {
            var imgStyle = {
                verticalAlign: "middle"
            };

            self.state.countryList.push(
                <ListItem key={index}>

                     {element.name}
                </ListItem>
            )
        });

        this.setState({countryList: this.state.countryList});
    },

    _toggleNav: function () {
        this.refs.leftNav.toggle();
    },

    render: function () {
        return (

                <LeftNav ref="leftNav" docked={false}>
                    {this.state.countryList}
                </LeftNav>

        )
    }
});

module.exports = CountryList;

"use strict";

var React = require("react");
var LeftNav = require("material-ui/lib/left-nav");
var List = require('material-ui/lib/lists/list');
var ListItem = require('material-ui/lib/lists/list-item');
var PlayerStore = require("../stores/playerStore");

var CountryList = React.createClass({
    getInitialState: function () {
        return {
            countryList: []
        };
    },

    componentWillMount: function () {
        PlayerStore.addChangeListener(this._onChange)
    },

    componentWillUnmount: function () {
        PlayerStore.removeChangeListener(this._onChange)
    },

    _onChange: function () {
        var players = PlayerStore.getCountries();
        var self = this;

        players.forEach(function (element, index, array) {
            var imgStyle = {
                verticalAlign: "middle"
            };

            self.state.countryList.push(
                <ListItem key={index}>

                     {element.name}
                </ListItem>
            )
        });

        this.setState({countryList: this.state.countryList});
    },

    _toggleNav: function () {
        this.refs.leftNav.toggle();
    },

    render: function () {
        var listStyle = {
            maxHeight: 800,
            overflowY: "auto"
        };

        return (

                <LeftNav ref="leftNav" docked={false}>
                    <List style={listStyle}>
                        {this.state.countryList}
                    </List>
                </LeftNav>

        )
    }
});

module.exports = CountryList;

Add vertical scroll for the left navigation menu


export default [
  {
    type: 'number',
    label: 'Number of Rows',
    key: 'numRows',
    input: true,
    weight: 0,
    placeholder: 'Number of Rows',
    tooltip: 'Enter the number or rows that should be displayed by this table.'
  },
  {
    type: 'number',
    label: 'Number of Columns',
    key: 'numCols',
    input: true,
    weight: 1,
    placeholder: 'Number of Columns',
    tooltip: 'Enter the number or columns that should be displayed by this table.'
  },
  {
    type: 'checkbox',
    label: 'Striped',
    key: 'striped',
    tooltip: 'This will stripe the table if checked.',
    input: true,
    weight: 701
  },
  {
    type: 'checkbox',
    label: 'Bordered',
    key: 'bordered',
    input: true,
    tooltip: 'This will border the table if checked.',
    weight: 702
  },
  {
    type: 'checkbox',
    label: 'Hover',
    key: 'hover',
    input: true,
    tooltip: 'Highlight a row on hover.',
    weight: 703
  },
  {
    type: 'checkbox',
    label: 'Condensed',
    key: 'condensed',
    input: true,
    tooltip: 'Condense the size of the table.',
    weight: 704
  }
];

export default [
  {
    key: 'label',
    ignore: true
  },
  {
    type: 'number',
    label: 'Number of Rows',
    key: 'numRows',
    input: true,
    weight: 1,
    placeholder: 'Number of Rows',
    tooltip: 'Enter the number or rows that should be displayed by this table.'
  },
  {
    type: 'number',
    label: 'Number of Columns',
    key: 'numCols',
    input: true,
    weight: 2,
    placeholder: 'Number of Columns',
    tooltip: 'Enter the number or columns that should be displayed by this table.'
  },
  {
    type: 'checkbox',
    label: 'Striped',
    key: 'striped',
    tooltip: 'This will stripe the table if checked.',
    input: true,
    weight: 701
  },
  {
    type: 'checkbox',
    label: 'Bordered',
    key: 'bordered',
    input: true,
    tooltip: 'This will border the table if checked.',
    weight: 702
  },
  {
    type: 'checkbox',
    label: 'Hover',
    key: 'hover',
    input: true,
    tooltip: 'Highlight a row on hover.',
    weight: 703
  },
  {
    type: 'checkbox',
    label: 'Condensed',
    key: 'condensed',
    input: true,
    tooltip: 'Condense the size of the table.',
    weight: 704
  }
];

Hide the label component for table editing.


#!/usr/bin/env node

process.title = 'timeline_serve';

var _ = require('underscore')._;
var express = require('express');
var socket = require('socket.io');
var fs = require('fs');

var app = express();
app.configure(function () {
    app.use(express.static(__dirname + '/../public'));
});
var server = app.listen(8888);

function readData () {
    var fileNames = fs.readdirSync('./');
    return _.reduce(fileNames, function (memo, filename) {
        var stat = fs.statSync(filename);
        if (stat.isFile()) {
            memo[filename] = fs.readFileSync(filename, 'utf8');
        }
        return memo;
    }, {});
}

var io = socket.listen(server);
io.configure(function () {
    io.set("log level", 1);
});
io.sockets.on('connection', function (socket) {
    socket.emit('data', readData());
});

var watch = require('node-watch');
watch(__dirname + '/../public', function () {
    io.sockets.emit('reload');
});
watch('./', function () {
    io.sockets.emit('data', readData());
});

console.log('Timeline server started.');
console.log('Reading timeline files from ' + fs.realpathSync('./'));
console.log('Point your browser to http://localhost:8888/');

Add some potentially helpful startup console output


module.exports = function(grunt) {
    grunt.initConfig({
    jshint: {
        all: [
            'VotingApplication/VotingApplication.Web/Scripts/Controllers/**/*.js',
            'VotingApplication/VotingApplication.Web/Scripts/Directives/**/*.js',
            'VotingApplication/VotingApplication.Web/Scripts/Modules/**/*.js',
            'VotingApplication/VotingApplication.Web/Scripts/Services/**/*.js'
        ],
        options: {
            jshintrc: true
        }
    }
});

grunt.loadNpmTasks('grunt-contrib-jshint');

grunt.registerTask('default', ['jshint']);

};

module.exports = function(grunt) {
    grunt.initConfig({
    jshint: {
        all: [
            'VotingApplication/VotingApplication.Web/Scripts/Controllers/**/*.js',
            'VotingApplication/VotingApplication.Web/Scripts/Directives/**/*.js',
            'VotingApplication/VotingApplication.Web/Scripts/Modules/**/*.js',
            'VotingApplication/VotingApplication.Web/Scripts/Services/**/*.js'
        ],
        options: {
            jshintrc: true,
            force: true
        }
    }
});

grunt.loadNpmTasks('grunt-contrib-jshint');

grunt.registerTask('default', ['jshint']);

};

Allow jshint process to run without failing the tests


const eris = justcord.eris;
const config = justcord.config;
const chat = justcord.chat;

eris.on("messageCreate", (message) => {
    chat.broadcast(message.content);
});

const eris = justcord.eris;
const config = justcord.config;
const chat = justcord.chat;

eris.on("messageCreate", (message) => {
    if (message.channel.id == config.eris.id) {
        chat.broadcast(`${message.member.nick}: ${message.content}`);
        console.log(`Discord: ${message.member.nick}: ${message.content}`);
    }
});

Format and log messages to console


// If you want to enhance the Jasmine execution context, just add into this file.

require("UnderscoreMatchersForJasmine");

_ = require("underscore");

// Common code for routing promises into the "done" callback model.
module.exports = {
  promiseDone: function(testBodyCb) {
    return function(done) {
      done = _.once(done);
      return testBodyCb().catch(done).finally(function() { done(); });
    };
  }
};

Add a helper for mapping done callbacks to Promises


import styled from 'styled-components';
import icons, { map } from './helpers/icons';

const Icon = styled.i.withConfig({ displayName: 'Icon' })`
  font-family: 'Bandwidth';
  font-size: ${({ theme, size }) => `${size}px` || theme.icon.fontSize};
  color: inherit;
  font-style: normal;
  display: inline-block;
  &::before {
    content: "${({ name, iconsHelper }) => iconsHelper(name)}";
    display: block;
    color: inherit;
  }
`;

Icon.defaultProps = {
  theme: {
    icon: { fontSize: '16px', fg: 'inherit' },
  },

  name: 'attention',
  iconsHelper: icons,

  size: 16,
};

Icon.usage = `
# Icon

Icons let you easily render some of our icons. Pass in the \`name\` prop to specify which one.

\`\`\`
<Icon name="checkmark" />
\`\`\`

## Icons

The icon definition file is in \`components/helpers/icons.js\`

${Object.keys(map).map((name) => `* ${name}`).join('\n')}
`;

export default Icon;

import styled from 'styled-components';
import icons, { map } from './helpers/icons';

const Icon = styled.i.withConfig({ displayName: 'Icon' })`
  font-family: 'Bandwidth';
  font-size: ${({ theme, size }) => `${size}px` || theme.icon.fontSize};
  color: inherit;
  font-style: normal;
  display: inline-block;
  &::before {
    content: "${({ name, iconsHelper }) => iconsHelper(name) || iconsHelper('help_2')}";
    display: block;
    color: inherit;
  }
`;

Icon.defaultProps = {
  theme: {
    icon: { fontSize: '16px', fg: 'inherit' },
  },

  name: 'attention',
  iconsHelper: icons,

  size: 16,
};

Icon.usage = `
# Icon

Icons let you easily render some of our icons. Pass in the \`name\` prop to specify which one.

\`\`\`
<Icon name="checkmark" />
\`\`\`

## Icons

The icon definition file is in \`components/helpers/icons.js\`

${Object.keys(map).map((name) => `* ${name}`).join('\n')}
`;

export default Icon;

Make icon easier to debug


#!/usr/bin/env node

const UI = require('console-ui');
const cli = require('cli');

const Project = require('../models/project');
const CommandFactory = require('../commands/command-factory');

const discovery = require('../tasks/discover');

let options = cli.parse({
  environment: [ 'e', 'A configured deployment environment, i.e. "staging", "production".', 'environment', 'production'],
  verbose: ['v', 'Toggle verbosity', 'bool', false],
  revision: ['r', '("activate" only) revision to activate', 'string', false],
  activate: ['a', '("deploy" only) directly activate the deployed revision', 'bool', false]
}, ['deploy', 'list', 'activate']);

let ui = new UI({
  inputStream: process.stdin,
  outputStream: process.stdout,
  writeLevel: 'INFO'
});

let commandFactory = new CommandFactory();

discovery.list().then(function(dependencies) {
  let project = new Project(dependencies, ui);

  commandFactory.run(cli.command, project, options);
}).catch(function(error) {
  console.log((error && error.message) ? '[ERROR] -- ' + error.message : error);
});

#!/usr/bin/env node

const UI = require('console-ui');
const cli = require('cli');

const Project = require('../models/project');
const CommandFactory = require('../commands/command-factory');

const discovery = require('../tasks/discover');

let options = cli.parse({
  environment: [ 'e', 'A configured deployment environment, i.e. "staging", "production".', 'string', 'production'],
  verbose: ['v', 'Toggle verbosity', 'bool', false],
  revision: ['r', '("activate" only) revision to activate', 'string', false],
  activate: ['a', '("deploy" only) directly activate the deployed revision', 'bool', false]
}, ['deploy', 'list', 'activate']);

let ui = new UI({
  inputStream: process.stdin,
  outputStream: process.stdout,
  writeLevel: 'INFO'
});

let commandFactory = new CommandFactory();

discovery.list().then(function(dependencies) {
  let project = new Project(dependencies, ui);

  commandFactory.run(cli.command, project, options);
}).catch(function(error) {
  console.log((error && error.message) ? '[ERROR] -- ' + error.message : error);
});

Fix passing of environment flag


var config = {

	// Your site title (format: page_title - site_title)
	site_title: 'Raneto Docs',

	// The base URL of your site (can use %base_url% in Markdown files)
	base_url: '',

	// Used for the "Get in touch" page footer link
	support_email: '',

	// Footer copyright content
	copyright: 'Copyright © '+ new Date().getFullYear() +' - Powered by Raneto',

	// Excerpt length (used in search)
	excerpt_length: 400,

	// The meta value by which to sort pages (value should be an integer)
	// If this option is blank pages will be sorted alphabetically
	page_sort_meta: 'sort',

	// Should categories be sorted numerically (true) or alphabetically (false)
	// If true category folders need to contain a "sort" file with an integer value
	category_sort: true,

	// The base URL of your images folder (can use %image_url% in Markdown files)
	image_url: '/images',

	// Specify the path of your content folder where all your '.md' files are located
	content_dir: './content/',

	// Add your analytics tracking code (including script tags)
	analytics: ""

};

module.exports = config;

var config = {

	// Your site title (format: page_title - site_title)
	site_title: 'Cloud-A Docs',

	// The base URL of your site (can use %base_url% in Markdown files)
	base_url: '',

	// Used for the "Get in touch" page footer link
	support_email: 'support@clouda.ca',

	// Footer copyright content
	copyright: 'Copyright © '+ new Date().getFullYear() +' - Powered by Raneto',

	// Excerpt length (used in search)
	excerpt_length: 400,

	// The meta value by which to sort pages (value should be an integer)
	// If this option is blank pages will be sorted alphabetically
	page_sort_meta: 'sort',

	// Should categories be sorted numerically (true) or alphabetically (false)
	// If true category folders need to contain a "sort" file with an integer value
	category_sort: true,

	// The base URL of your images folder (can use %image_url% in Markdown files)
	image_url: '/images',

	// Specify the path of your content folder where all your '.md' files are located
	content_dir: './content/',

	// Add your analytics tracking code (including script tags)
	analytics: ""

};

module.exports = config;

Add support email & brand


import bus from 'bus'
import Store from 'localstorage-ns'

export default function plugin (app) {
  const localStorage = Store('settings', {
    serverURI: 'bloxparty-server.kvnneff.me',
    nick: ''
  })

  localStorage.on('change', () => app.set('settings', localStorage.get()))

  bus.on('settings:set', (key, value) => localStorage.set(key, value))

  app.set('settings', localStorage.data)
}

import bus from 'bus'
import Store from 'localstorage-ns'

export default function plugin (app) {
  const localStorage = Store('settings', {
    serverURI: 'bloxparty-server.kvnneff.me',
    nick: ''
  })

  localStorage.on('change', () => app.set('settings', localStorage.get()))

  bus.on('settings:set', (key, value) => localStorage.set(key, value))
  app.set('settings', localStorage.get())
}

Use localStorage.get() to set initial data.


'use strict';

class FixationsDataProcessor {

    constructor() {
        this.fixationsData = [];
    }

    process(fileContentsAsArray)
    {
        for(var c in fileContentsAsArray) {
            let lineItems = fileContentsAsArray[c].split(' ');

            this.addItemToMinute({
                x: parseInt(lineItems[1]),
                y: parseInt(lineItems[2])
            }, this.getMinuteFromTimestamp(parseInt(lineItems[0])));
        }

        return this.fixationsData;
    }

    addItemToMinute(point, minute)
    {
        if(this.fixationsData[minute] === undefined) {
            this.fixationsData[minute] = {
                points: [point]
            }
        } else {
            this.fixationsData[minute].points.push(point);
        }
    }

    getMinuteFromTimestamp(timestamp) {
        let minute = Math.floor(timestamp * 1.67 * 0.00001);
        return minute;
    }

}

export default FixationsDataProcessor

'use strict';

class FixationsDataProcessor {

    constructor() {
        this.fixationsData = [];
    }

    process(fileContentsAsArray)
    {
        for(var c in fileContentsAsArray) {
            let lineItems = fileContentsAsArray[c].split(' ');

            this.addItemToMinute([lineItems[1], lineItems[2]], this.getMinuteFromTimestamp(parseInt(lineItems[0])));
        }

        return this.fixationsData;
    }

    addItemToMinute(point, minute)
    {
        if(this.fixationsData[minute] === undefined) {
            this.fixationsData[minute] = {
                points: [point]
            }
        } else {
            this.fixationsData[minute].points.push(point);
        }
    }

    getMinuteFromTimestamp(timestamp) {
        let minute = Math.floor(timestamp * 1.67 * 0.00001);
        return minute;
    }

}

export default FixationsDataProcessor

Switch from point objects to array for easier calculations


module.exports.getPrettyDate = function(date) {
  var month = date.getMonth() + 1;
  var day = date.getDate();

  if (month < 10) {
    month = "0" + month;
  }
  if (day < 10) {
    day = "0" + day;
  }

  return month + "/" + day + "/" + date.getFullYear();
};

module.exports.roundNumber = function (val) {
  return Math.round(val * 100000) / 100000;
};

module.exports.getDistanceFromLatLng = function(lat1, lng1, lat2, lng2) {
  var R = 6371;   // Radius of the earth in KM
  var dLat = deg2rad(lat2 - lat1);
  var dLng = deg2rad(lng2 - lng1);
  var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.sin(dLng / 2) * Math.sin(dLng / 2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  return  R * c;
};

var deg2rad = function (deg) {
  return deg * (Math.PI / 180);
};

module.exports.isNumber = function(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
};

module.exports.getPrettyDate = function(date) {
  var month = addLeadingZero(date.getMonth() + 1);
  var day = addLeadingZero(date.getDate());

  return month + "/" + day + "/" + date.getFullYear();
};

var addLeadingZero = function (number) {
  if (number < 10) {
    return '0' + number;
  }
  return number;
};

module.exports.roundNumber = function (val) {
  return Math.round(val * 100000) / 100000;
};

module.exports.getDistanceFromLatLng = function(lat1, lng1, lat2, lng2) {
  var R = 6371;   // Radius of the earth in KM
  var dLat = deg2rad(lat2 - lat1);
  var dLng = deg2rad(lng2 - lng1);
  var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.sin(dLng / 2) * Math.sin(dLng / 2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  return  R * c;
};

var deg2rad = function (deg) {
  return deg * (Math.PI / 180);
};

module.exports.isNumber = function(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
};

Update get pretty date in clienside


const Core = require('./core/index.js')

// Parent
const Plugin = require('./plugins/Plugin')

// Orchestrators
const Dashboard = require('./plugins/Dashboard/index.js')

// Acquirers
const Dummy = require('./plugins/Dummy')
const DragDrop = require('./plugins/DragDrop/index.js')
const FileInput = require('./plugins/FileInput.js')
const GoogleDrive = require('./plugins/GoogleDrive/index.js')
const Dropbox = require('./plugins/Dropbox/index.js')
const Instagram = require('./plugins/Instagram/index.js')
const Webcam = require('./plugins/Webcam/index.js')

// Progressindicators
const ProgressBar = require('./plugins/ProgressBar.js')
const Informer = require('./plugins/Informer.js')

// Modifiers
const MetaData = require('./plugins/MetaData.js')

// Uploaders
const Tus10 = require('./plugins/Tus10')
const XHRUpload = require('./plugins/XHRUpload')
const Transloadit = require('./plugins/Transloadit')
const AwsS3 = require('./plugins/AwsS3')

module.exports = {
  Core,
  Plugin,
  Dummy,
  ProgressBar,
  Informer,
  DragDrop,
  GoogleDrive,
  Dropbox,
  Instagram,
  FileInput,
  Tus10,
  XHRUpload,
  Transloadit,
  AwsS3,
  Dashboard,
  MetaData,
  Webcam
}

const Core = require('./core/index.js')

// Parent
const Plugin = require('./plugins/Plugin')

// Orchestrators
const Dashboard = require('./plugins/Dashboard/index.js')

// Acquirers
const Dummy = require('./plugins/Dummy')
const DragDrop = require('./plugins/DragDrop/index.js')
const FileInput = require('./plugins/FileInput.js')
const GoogleDrive = require('./plugins/GoogleDrive/index.js')
const Dropbox = require('./plugins/Dropbox/index.js')
const Instagram = require('./plugins/Instagram/index.js')
const Webcam = require('./plugins/Webcam/index.js')

// Progressindicators
const StatusBar = require('./plugins/StatusBar')
const ProgressBar = require('./plugins/ProgressBar.js')
const Informer = require('./plugins/Informer.js')

// Modifiers
const MetaData = require('./plugins/MetaData.js')

// Uploaders
const Tus10 = require('./plugins/Tus10')
const XHRUpload = require('./plugins/XHRUpload')
const Transloadit = require('./plugins/Transloadit')
const AwsS3 = require('./plugins/AwsS3')

module.exports = {
  Core,
  Plugin,
  Dummy,
  StatusBar,
  ProgressBar,
  Informer,
  DragDrop,
  GoogleDrive,
  Dropbox,
  Instagram,
  FileInput,
  Tus10,
  XHRUpload,
  Transloadit,
  AwsS3,
  Dashboard,
  MetaData,
  Webcam
}

Add StatusBar to unpkg bundle.


import fs from 'fs'
import _ from 'lodash'
import postcss from 'postcss'
import cssnext from 'postcss-cssnext'
import stylefmt from 'stylefmt'

import defaultConfig from './defaultConfig'
import mergeConfig from './util/mergeConfig'

import addCustomMediaQueries from './lib/addCustomMediaQueries'
import generateUtilities from './lib/generateUtilities'
import substituteHoverableAtRules from './lib/substituteHoverableAtRules'
import substituteResponsiveAtRules from './lib/substituteResponsiveAtRules'
import substituteBreakpointAtRules from './lib/substituteBreakpointAtRules'
import substituteClassApplyAtRules from './lib/substituteClassApplyAtRules'

const plugin = postcss.plugin('tailwind', (options = {}) => {
  const config = mergeConfig(defaultConfig, options)

  return postcss([
    addCustomMediaQueries(config),
    generateUtilities(config),
    substituteHoverableAtRules(config),
    substituteResponsiveAtRules(config),
    substituteBreakpointAtRules(config),
    substituteClassApplyAtRules(config),
    cssnext(),
    stylefmt,
  ])
})

module.exports = plugin

import fs from 'fs'
import _ from 'lodash'
import postcss from 'postcss'
import cssnext from 'postcss-cssnext'
import stylefmt from 'stylefmt'

import defaultConfig from './defaultConfig'
import mergeConfig from './util/mergeConfig'

import addCustomMediaQueries from './lib/addCustomMediaQueries'
import generateUtilities from './lib/generateUtilities'
import substituteHoverableAtRules from './lib/substituteHoverableAtRules'
import substituteResponsiveAtRules from './lib/substituteResponsiveAtRules'
import substituteBreakpointAtRules from './lib/substituteBreakpointAtRules'
import substituteClassApplyAtRules from './lib/substituteClassApplyAtRules'

const plugin = postcss.plugin('tailwind', (options = {}) => {
  if (_.isFunction(options)) {
    options = options()
  }

  const config = mergeConfig(defaultConfig, options)

  return postcss([
    addCustomMediaQueries(config),
    generateUtilities(config),
    substituteHoverableAtRules(config),
    substituteResponsiveAtRules(config),
    substituteBreakpointAtRules(config),
    substituteClassApplyAtRules(config),
    cssnext(),
    stylefmt,
  ])
})

module.exports = plugin

Allow passing config as lazy-evaluated function


const isFunction = require('lodash.isfunction');
const invariant = require('invariant');

let oldJasmineFns = {it, fit, xit, beforeEach, afterEach, beforeAll, afterAll};

function withAsync(fns) {
  return Object.keys(fns).reduce((memo, name) => {
    memo[name] = fns[name];
    memo[name].async = function(...args) {
      const callback = args.pop();
      invariant(isFunction(callback), `${name} must be provided a function!`);
      return (fns[name])(...args, done => {
        const promise = this::callback();
        invariant(promise instanceof Promise, `${name} must return a promise!`);
        promise.then(done, done.fail);
      });
    };
    return memo;
  }, {});
}

module.exports = {
  install() {
    Object.assign(global, {...withAsync(oldJasmineFns)});
  },

  uninstall() {
    Object.assign(global, oldJasmineFns);
  }
};

const isFunction = require('lodash.isfunction');
const invariant = require('invariant');

let oldJasmineFns = {it, fit, xit, beforeEach, afterEach, beforeAll, afterAll};

function withAsync(fns) {
  return Object.keys(fns).reduce((memo, name) => {
    memo[name] = fns[name];
    memo[name].async = function(...args) {
      const callback = args.pop();
      invariant(isFunction(callback), `${name} must be provided a function!`);
      return (fns[name])(...args, done => {
        const promise = this::callback();
        invariant(promise && isFunction(promise.then), `${name} must return a promise!`);
        promise.then(done, done.fail);
      });
    };
    return memo;
  }, {});
}

module.exports = {
  install() {
    Object.assign(global, {...withAsync(oldJasmineFns)});
  },

  uninstall() {
    Object.assign(global, oldJasmineFns);
  }
};

Check for promise.then instead of using instanceof