var duplicate = false;
jQuery( document ).ready( function()
{
	showHideUserGroup();

	checkValueIsExist( "name", "validateProgramStage.action", {id:getFieldValue('programId'), programStageId:getFieldValue('id')});

	jQuery("#availableList").dhisAjaxSelect({
		source: "../dhis-web-commons-ajax-json/getDataElements.action?domain=patient",
		iterator: "dataElements",
		connectedTo: 'selectedDataElementsValidator',
		handler: function(item) {
			var option = jQuery("<option />");
			option.text( item.name );
			option.attr( "value", item.id );

			if( item.optionSet == "true"){
				option.attr( "valuetype", "optionset" );
			}
			else{
				option.attr( "valuetype", item.valueType );
			}

			var flag = false;
			jQuery("#selectedList").find("tr").each( function( k, selectedItem ){
				if(selectedItem.id == item.id )
				{
					flag = true;
					return;
				}
			});

			if(!flag) return option;
		}
	});
});

var duplicate = false;
jQuery( document ).ready( function()
{
	checkValueIsExist( "name", "validateProgramStage.action", {id:getFieldValue('programId'), programStageId:getFieldValue('id')});

	jQuery("#availableList").dhisAjaxSelect({
		source: "../dhis-web-commons-ajax-json/getDataElements.action?domain=patient",
		iterator: "dataElements",
		connectedTo: 'selectedDataElementsValidator',
		handler: function(item) {
			var option = jQuery("<option />");
			option.text( item.name );
			option.attr( "value", item.id );

			if( item.optionSet == "true"){
				option.attr( "valuetype", "optionset" );
			}
			else{
				option.attr( "valuetype", item.valueType );
			}

			var flag = false;
			jQuery("#selectedList").find("tr").each( function( k, selectedItem ){
				if(selectedItem.id == item.id )
				{
					flag = true;
					return;
				}
			});

			if(!flag) return option;
		}
	});
});

Fix bug where non-existing function was being called


const User = require('../../models/User');
const Elo = require('arpad');

function findUsersOfLeague(req, res) {
  User.findAll({ where: { league: req.params.league } }).then((data) => {
    console.log(data);
    res.json(data)
  });
}

function findUser(req, res) {
  User.find({ where: { username: req.params.username } }).then((data) => {
    console.log(data);
    res.json(data)
  });
}

function getNewElo(req, res) {
  let user1;
  let user2;
  const elo = new Elo();
  const user1Promise = User.findOne({ where: { username: req.params.username1 } }).then(data => { user1 = data; })
  const user2Promise = User.findOne({ where: { username: req.params.username2 } }).then(data => { user2 = data; })
  Promise.all([user1Promise, user2Promise]).then((fullfill, reject) => {
      const newUser1Elo = elo.newRatingIfWon(user1.elo, user2.elo);
      const newUser2Elo = elo.newRatingIfLost(user2.elo, user1.elo);
      console.log({ yourNewElo: newUser1Elo, theirNewElo: newUser2Elo })
      res.json({ yourNewElo: newUser1Elo, theirNewElo: newUser2Elo });
    })
}

module.exports = { findUsersOfLeague, getNewElo };

const User = require('../../models/User');
const Elo = require('arpad');

function findUsersOfLeague(req, res) {
  User.findAll({ where: { league: req.params.league } }).then((data) => {
    console.log(data);
    res.json(data)
  });
}

function findUser(req, res) {
  User.find({ where: { username: req.params.username } }).then((data) => {
    console.log(data);
    res.json(data)
  });
}

function getNewElo(req, res) {
  let user1;
  let user2;
  const elo = new Elo();
  const user1Promise = User.findOne({ where: { username: req.params.username1 } }).then(data => { user1 = data; })
  const user2Promise = User.findOne({ where: { username: req.params.username2 } }).then(data => { user2 = data; })
  Promise.all([user1Promise, user2Promise]).then(() => {
      user1.update({'elo': elo.newRatingIfWon(user1.elo, user2.elo)})
      .then(user2.update({'elo': elo.newRatingIfLost(user2.elo, user1.elo)}))
      .then(res.json('updated elo in postgres'));
    })
}

module.exports = { findUsersOfLeague, getNewElo };

Update elo in database on click


import { busy, scheduleRetry } from './actions';
import { JS_ERROR } from './constants';
import type { Config, OfflineAction, ResultAction } from './types';

const complete = (
  action: ResultAction,
  success: boolean,
  payload: {}
): ResultAction => ({
  ...action,
  payload,
  meta: { ...action.meta, success, completed: true }
});

const send = (action: OfflineAction, dispatch, config: Config, retries = 0) => {
  const metadata = action.meta.offline;
  dispatch(busy(true));
  return config
    .effect(metadata.effect, action)
    .then(result => {
      const commitAction = metadata.commit || {
        ...config.defaultCommit,
        meta: { ...config.defaultCommit.meta, offlineAction: action }
      };
      try {
        dispatch(complete(commitAction, true, result));
      } catch (e) {
        dispatch(complete({ type: JS_ERROR, payload: e }, false));
      }
    })
    .catch(error => {
      const rollbackAction = metadata.rollback || {
        ...config.defaultRollback,
        meta: { ...config.defaultRollback.meta, offlineAction: action }
      };

      // discard
      if (config.discard(error, action, retries)) {
        dispatch(complete(rollbackAction, false, error));
        return;
      }
      const delay = config.retry(action, retries);
      if (delay != null) {
        dispatch(scheduleRetry(delay));
        return;
      }
      dispatch(complete(rollbackAction, false, error));
    });
};

export default send;

import { busy, scheduleRetry } from './actions';
import { JS_ERROR } from './constants';
import type { Config, OfflineAction, ResultAction } from './types';

const complete = (
  action: ResultAction,
  success: boolean,
  payload: {}
): ResultAction => ({
  ...action,
  payload,
  meta: { ...action.meta, success, completed: true }
});

const send = (action: OfflineAction, dispatch, config: Config, retries = 0) => {
  const metadata = action.meta.offline;
  dispatch(busy(true));
  return config
    .effect(metadata.effect, action)
    .then(result => {
      const commitAction = metadata.commit || {
        ...config.defaultCommit,
        meta: { ...config.defaultCommit.meta, offlineAction: action }
      };
      try {
        dispatch(complete(commitAction, true, result));
      } catch (e) {
        dispatch(complete({ type: JS_ERROR, payload: e }, false));
      }
    })
    .catch(async error => {
      const rollbackAction = metadata.rollback || {
        ...config.defaultRollback,
        meta: { ...config.defaultRollback.meta, offlineAction: action }
      };

      // discard
      let mustDiscard = true
      try {
        mustDiscard = await config.discard(error, action, retries)
      } catch(e) {
        console.warn(e)
      }

      if (!mustDiscard) {
        const delay = config.retry(action, retries);
        if (delay != null) {
          dispatch(scheduleRetry(delay));
          return;
        }
      }

      dispatch(complete(rollbackAction, false, error));
    });
};

export default send;

Allow to use Promises on `discard` function


(function(tree) {

tree.LayerXML = function(obj, styles) {
    var dsoptions = [];
    for (var i in obj.Datasource) {
        dsoptions.push('<Parameter name="' + i + '"><![CDATA[' +
            obj.Datasource[i] + ']]></Parameter>');
    }

    var prop_string = '';
    for (var prop in obj.properties) {
        prop_string += '  ' + prop + '="' + obj.properties[prop] + '"\n';
    }

    return '<Layer' +
        ' name="' + obj.name + '"\n' +
        prop_string +
        ((typeof obj.status === 'undefined') ? '' : '  status="' + obj.status + '"\n') +
        '  srs="' + obj.srs + '">\n    ' +
        styles.reverse().map(function(s) {
            return '<StyleName>' + s + '</StyleName>';
        }).join('\n    ') +
        '\n    <Datasource>\n       ' +
        dsoptions.join('\n       ') +
        '\n    </Datasource>\n' +
        '  </Layer>\n';
};

})(require('../tree'));

(function(tree) {

tree.LayerXML = function(obj, styles) {
    var dsoptions = [];
    for (var i in obj.Datasource) {
        dsoptions.push('<Parameter name="' + i + '"><![CDATA[' +
            obj.Datasource[i] + ']]></Parameter>');
    }

    var prop_string = '';
    for (var prop in obj.properties) {
        if (prop === 'minzoom') {
            prop_string += '  maxzoom="' + tree.Zoom.ranges[obj.properties[prop]] + '"\n';
        } else if (prop === 'maxzoom') {
            prop_string += '  minzoom="' + tree.Zoom.ranges[obj.properties[prop]+1] + '"\n';
        } else {
            prop_string += '  ' + prop + '="' + obj.properties[prop] + '"\n';
        }
    }

    return '<Layer' +
        ' name="' + obj.name + '"\n' +
        prop_string +
        ((typeof obj.status === 'undefined') ? '' : '  status="' + obj.status + '"\n') +
        '  srs="' + obj.srs + '">\n    ' +
        styles.reverse().map(function(s) {
            return '<StyleName>' + s + '</StyleName>';
        }).join('\n    ') +
        '\n    <Datasource>\n       ' +
        dsoptions.join('\n       ') +
        '\n    </Datasource>\n' +
        '  </Layer>\n';
};

})(require('../tree'));

Convert minzoom/maxzoom parameters on Layer properties.


'use strict';

var auth = require('basic-auth');

// Loads the controller
//
// @app   {Object}    The config
//
function main (config) {

  return {

    isAuth: function(req, res, next) {

      if(!config.auth) {
        return next();
      }

      var user = auth(req);

      if(
        config.auth &&
        user &&
        config.auth.username === user.name &&
        config.auth.password === user.pass
      ) {
        return next();
      }

      res.json(500, { message: 'Permission Denied' });
    }

  };

}

module.exports = main;

'use strict';

var auth = require('basic-auth');

// Loads the controller
//
// @app   {Object}    The config
//
function main (config) {

  return {

    isAuth: function(req, res, next) {

      if(!config.auth) {
        return next();
      }

      var user = auth(req);

      if(
        config.auth &&
        user &&
        config.auth.username === user.name &&
        config.auth.password === user.pass
      ) {
        return next();
      }

      res.json(403, { message: 'Permission Denied' });
    }

  };

}

module.exports = main;

Use statusCode 403 for Permission Denied


// @flow
import * as React from 'react'
import {Section, PushButtonCell} from '@frogpond/tableview'
import {type NavigationScreenProp} from 'react-navigation'

type Props = {navigation: NavigationScreenProp<*>}

export class DeveloperSection extends React.Component<Props> {
	onAPIButton = () => this.props.navigation.navigate('APITestView')
	onBonAppButton = () => this.props.navigation.navigate('BonAppPickerView')
	onDebugButton = () => this.props.navigation.navigate('DebugView')

	render() {
		return (
			<Section header="DEVELOPER">
				<PushButtonCell onPress={this.onAPIButton} title="API Tester" />
				<PushButtonCell
					onPress={this.onBonAppButton}
					title="Bon Appetit Picker"
				/>
				<PushButtonCell onPress={this.onDebugButton} title="Debug" />
			</Section>
		)
	}
}

// @flow
import {Sentry, SentrySeverity} from 'react-native-sentry'
import * as React from 'react'
import {Section, PushButtonCell} from '@frogpond/tableview'
import {type NavigationScreenProp} from 'react-navigation'

type Props = {navigation: NavigationScreenProp<*>}

export class DeveloperSection extends React.Component<Props> {
	onAPIButton = () => this.props.navigation.navigate('APITestView')
	onBonAppButton = () => this.props.navigation.navigate('BonAppPickerView')
	onDebugButton = () => this.props.navigation.navigate('DebugView')
	sendSentryMessage = () => {
		Sentry.captureMessage('A Sentry Message', {
			level: SentrySeverity.Info,
		})
	}
	sendSentryException = () => {
		Sentry.captureException(new Error('Debug Exception'))
	}

	render() {
		return (
			<Section header="DEVELOPER">
				<PushButtonCell onPress={this.onAPIButton} title="API Tester" />
				<PushButtonCell
					onPress={this.onBonAppButton}
					title="Bon Appetit Picker"
				/>
				<PushButtonCell onPress={this.onDebugButton} title="Debug" />
				<PushButtonCell
					onPress={this.sendSentryMessage}
					title="Send a Sentry Message"
				/>
				<PushButtonCell
					onPress={this.sendSentryException}
					title="Send a Sentry Exception"
				/>
			</Section>
		)
	}
}

Add debug-menu manual triggers for Sentry


const path = require('path')
const { MarkdownRenderer } = require('../src/renderer')

describe ('Renderer', () => {
  var renderer
  var callback

  beforeEach(() => {
    callback = jasmine.createSpy('callback')
    renderer = new MarkdownRenderer(callback)
  })

  it('converts a markdown file', (done) => {
    const markdownFilePath = path.join(__dirname, 'md', 'header.md')

    renderer.loadFile(markdownFilePath).then(() => {
      expect(callback).toHaveBeenCalledWith(
        '

Hello

'
      )
      done()
    }, done.fail)
  })

  it('converts a markdown string', (done) => {
    var markdown = '## Hi'

    renderer.load(markdown).then(() => {
      expect(callback).toHaveBeenCalledWith(
        '

Hi

'
      )
      done()
    }, done.fail)
  })

  it('preserves new lines in code', (done) => {
    const markdownFilePath = path.join(__dirname, 'md', 'code.md')

    renderer.loadFile(markdownFilePath).then(() => {
      expect(callback).toHaveBeenCalledWith(
        '

var x = 3\nvar y = null\n

'
      )
      done()
    }, done.fail)
  })
})

const path = require('path')
const MarkdownRenderer = require('../src/renderer').MarkdownRenderer

describe ('Renderer', () => {
  var renderer
  var callback

  beforeEach(() => {
    callback = jasmine.createSpy('callback')
    renderer = new MarkdownRenderer(callback)
  })

  it('converts a markdown file', (done) => {
    const markdownFilePath = path.join(__dirname, 'md', 'header.md')

    renderer.loadFile(markdownFilePath).then(() => {
      expect(callback).toHaveBeenCalledWith(
        '

Hello

'
      )
      done()
    }, done.fail)
  })

  it('converts a markdown string', (done) => {
    var markdown = '## Hi'

    renderer.load(markdown).then(() => {
      expect(callback).toHaveBeenCalledWith(
        '

Hi

'
      )
      done()
    }, done.fail)
  })

  it('preserves new lines in code', (done) => {
    const markdownFilePath = path.join(__dirname, 'md', 'code.md')

    renderer.loadFile(markdownFilePath).then(() => {
      expect(callback).toHaveBeenCalledWith(
        '

var x = 3\nvar y = null\n

'
      )
      done()
    }, done.fail)
  })
})

Change Jasmine import syntax to satisfy Travis


$(document).ready(function () {
    $('.collapsible').click(function () {
        $(this).parent().find('.collapse').collapse('toggle');
    });
});

$(document).ready(function () {
    $('.collapsible').click(function () {
        var $btn = $(this);
        $btn.parent().find('.collapse').collapse('toggle');
        $btn.find('span').toggleClass('glyphicon-folder-open glyphicon-folder-close');
    });
});

Switch to close folder icon when collapsing


$(document).ready(function() {

    $('#id_degree_programme_options').change(function() {
        console.log('hello');
        if (this.value === 'extra') {
            $('#unknown_degree').show();
            $('#unknown_degree input').val('');
        } else {
            $('#unknown_degree').hide();
            $('#unknown_degree input').val(this.value);
        }
    });

});

$(document).ready(function() {

    $('#id_degree_programme_options').change(function() {
        console.log('hello');
        if (this.value === 'extra') {
            $('#unknown_degree').show();
            $('#id_degree_programme').val('');
        } else {
            $('#unknown_degree').hide();
            $('#id_degree_programme').val(this.value);
        }
    });

});

Use existing id instead of selector in JS


/*
---

name: Request

description: Provides a request that allow loading files locally.

license: MIT-style license.

authors:
	- Jean-Philippe Dery (jeanphilippe.dery@gmail.com)

requires:
	- Core/Class
	- Core/Class.Extras
	- Core/Request
	- Class-Extras/Class.Binds

provides:
	- Request

...
*/

if (!window.Moobile) window.Moobile = {};

/**
 * @see    http://moobilejs.com/doc/latest/Request/Request
 * @author Jean-Philippe Dery (jeanphilippe.dery@gmail.com)
 * @since  0.1.0
 */
Moobile.Request = new Class({

	Extends: Request,

	/**
	 * @see    http://moobilejs.com/doc/latest/Request/Request#options
	 * @author Jean-Philippe Dery (jeanphilippe.dery@gmail.com)
	 * @since  0.1.0
	 */
	options: {
		isSuccess: function() {
			var status = this.status;
			return (status === 0 || (status >= 200 && status < 300));
		}
	}

});

/*
---

name: Request

description: Provides a request that allow loading files locally.

license: MIT-style license.

authors:
	- Jean-Philippe Dery (jeanphilippe.dery@gmail.com)

requires:
	- Core/Class
	- Core/Class.Extras
	- Core/Request
	- Class-Extras/Class.Binds

provides:
	- Request

...
*/

if (!window.Moobile) window.Moobile = {};

/**
 * @see    http://moobilejs.com/doc/latest/Request/Request
 * @author Jean-Philippe Dery (jeanphilippe.dery@gmail.com)
 * @since  0.1.0
 */
Moobile.Request = new Class({

	Extends: Request,

	/**
	 * @see    http://moobilejs.com/doc/latest/Request/Request#options
	 * @author Jean-Philippe Dery (jeanphilippe.dery@gmail.com)
	 * @since  0.1.0
	 */
	options: {
		isSuccess: function() {
			var status = this.status;
			return (status === 0 || (status >= 200 && status <= 304));
		}
	}

});

Fix issue in ajax call on page refresh


window.addEventListener('DOMContentLoaded', function() {

  var linkedDataGraph = svgPanZoom('#linked-data-graph', {
    zoomEnabled: true,
    controlIconsEnabled: true
  });

});

window.addEventListener('load', function() {

  var linkedDataGraph = svgPanZoom('#linked-data-graph', {
    zoomEnabled: true,
    controlIconsEnabled: true
  });

});

Load svgPanZoom at the right time


'use strict'

const path = require('path')
const { log } = require(path.join(__dirname, '..', '..', 'main.config.js'))

const defaultOpts = {
  viewer: null,
  onKeyPress: null
}

module.exports = function (opts) {
  opts = Object.assign({}, defaultOpts, opts || {})

  let viewer

  if (opts.viewer) {
    const { spawn } = require('child_process')
    viewer = spawn('processing-java', ['--sketch=' + opts.viewer, '--run'], { detached: true })
    viewer.stdout.on('data', data => log.debug(`[viewer] ${data}`))
    viewer.stderr.on('data', data => log.error(`[viewer] ${data}`))
    viewer.on('close', code => process.exit(code))

    process.on('uncaughtException', err => {
      log.error(err)
      process.kill(-viewer.pid)
      process.exit(1)
    })
  }

  if (opts.onKeyPress) {
    const readline = require('readline')
    readline.emitKeypressEvents(process.stdin)

    process.stdin.setRawMode(true)
    process.stdin.on('keypress', (str, key) => {
      if (key.sequence === '\u0003') {
        process.stdin.pause()
        viewer && process.kill(-viewer.pid)
        process.exit()
      } else if (typeof opts.onKeyPress === 'function') {
        opts.onKeyPress(str, key)
      }
    })
  }
}

'use strict'

const path = require('path')
const { log } = require(path.join(__dirname, '..', '..', 'main.config.js'))

const defaultOpts = {
  viewer: null,
  onKeyPress: null
}

module.exports = function (opts) {
  opts = Object.assign({}, defaultOpts, opts || {})

  let viewer

  if (opts.viewer) {
    const { spawn } = require('child_process')
    viewer = spawn('processing-java', ['--sketch=' + opts.viewer, '--run'], { detached: true })
    viewer.stdout.on('data', data => log.debug(`[viewer] ${data}`))
    viewer.stderr.on('data', data => log.error(`[viewer] ${data}`))
    viewer.on('close', code => process.exit(code))

    process.on('uncaughtException', err => {
      log.error(err)
      process.kill(-viewer.pid)
      process.exit(1)
    })
  }

  if (opts.onKeyPress && process.stdin.setRawMode) {
    const readline = require('readline')
    readline.emitKeypressEvents(process.stdin)

    process.stdin.setRawMode(true)
    process.stdin.on('keypress', (str, key) => {
      if (key.sequence === '\u0003') {
        process.stdin.pause()
        viewer && process.kill(-viewer.pid)
        process.exit()
      } else if (typeof opts.onKeyPress === 'function') {
        opts.onKeyPress(str, key)
      }
    })
  }
}

Fix process.stdin error when running outside TTY


var JX = require('javelin').JX;

var fs = require('fs');
var util = require('util');

JX.install('AphlictLog', {
  construct: function() {
    this._writeToLogs = [];
    this._writeToConsoles = [];
  },

  members: {
    _writeToConsoles: null,
    _writeToLogs: null,

    addLogfile: function(path) {
      var options = {
        flags: 'a',
        encoding: 'utf8',
        mode: 066
      };

      var logfile = fs.createWriteStream(path, options);

      this._writeToLogs.push(logfile);

      return this;
    },

    addConsole: function(console) {
      this._writeToConsoles.push(console);
      return this;
    },

    log: function() {
      var str = util.format.apply(null, arguments);
      var date = new Date().toLocaleString();
      str = '[' + date + '] ' + str;

      var ii;
      for (ii = 0; ii < this._writeToConsoles.length; ii++) {
        this._writeToConsoles[ii].log(str);
      }

      for (ii = 0; ii < this._writeToLogs.length; ii++) {
        this._writeToLogs[ii].write(str + '\n');
      }
    }

  }

});

var JX = require('javelin').JX;

var fs = require('fs');
var util = require('util');

JX.install('AphlictLog', {
  construct: function() {
    this._writeToLogs = [];
    this._writeToConsoles = [];
  },

  members: {
    _writeToConsoles: null,
    _writeToLogs: null,

    addLogfile: function(path) {
      var options = {
        flags: 'a',
        encoding: 'utf8',
        mode: 0664,
      };

      var logfile = fs.createWriteStream(path, options);

      this._writeToLogs.push(logfile);

      return this;
    },

    addConsole: function(console) {
      this._writeToConsoles.push(console);
      return this;
    },

    log: function() {
      var str = util.format.apply(null, arguments);
      var date = new Date().toLocaleString();
      str = '[' + date + '] ' + str;

      var ii;
      for (ii = 0; ii < this._writeToConsoles.length; ii++) {
        this._writeToConsoles[ii].log(str);
      }

      for (ii = 0; ii < this._writeToLogs.length; ii++) {
        this._writeToLogs[ii].write(str + '\n');
      }
    }

  }

});

Fix permissions on Aphlict log


/**
 * returns a localised string
 * @param {String} str
 * @param {String} locale (optional)
 */
function _t() {
	var args = _t.arguments;
	var str = args[0] ? args[0] : "";
	var localestr = (args[1] && args[1].length > 0) ? args[1] : locale;
	return (localeStrings[localestr] && localeStrings[localestr][str]) ? localeStrings[localestr][str] : '???';
}

/**
 * Documents the error to the console
 * @param {Error} error
 */
function onError(error) {
	console.error(`a11y.css error: ${error}`);
}

/**
 * Documents what we got from a STORAGE.get()
 * @param {Object} item
 */
function onGot(item) {
	console.info(`a11y.css got`, item);
}

/**
 * returns a localised string
 * @param {String} str
 * @param {String} locale (optional)
 */
function _t() {
	const args = _t.arguments;
	const str = args[0] || '';
	const localestr = (args[1] && args[1].length > 0) ? args[1] : locale;
	const defaultLocale = 'en';
	return (localeStrings[localestr] && localeStrings[localestr][str]) ? localeStrings[localestr][str] : localeStrings[defaultLocale][str];
}

/**
 * Documents the error to the console
 * @param {Error} error
 */
function onError(error) {
	console.error(`a11y.css error: ${error}`);
}

/**
 * Documents what we got from a STORAGE.get()
 * @param {Object} item
 */
function onGot(item) {
	console.info(`a11y.css got`, item);
}

Add fallback to English locale if translation not found


/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ImageStylePropTypes
 * @flow
 */
'use strict';

var ImageResizeMode = require('ImageResizeMode');
var LayoutPropTypes = require('LayoutPropTypes');
var ReactPropTypes = require('ReactPropTypes');

var ImageStylePropTypes = {
  ...LayoutPropTypes,
  resizeMode: ReactPropTypes.oneOf(Object.keys(ImageResizeMode)),
  backgroundColor: ReactPropTypes.string,
  borderColor: ReactPropTypes.string,
  borderWidth: ReactPropTypes.number,
  borderRadius: ReactPropTypes.number,

  // iOS-Specific style to "tint" an image.
  // It changes the color of all the non-transparent pixels to the tintColor
  tintColor: ReactPropTypes.string,
  opacity: ReactPropTypes.number,
};

// Image doesn't support padding correctly (#4841912)
var unsupportedProps = Object.keys({
  padding: null,
  paddingTop: null,
  paddingLeft: null,
  paddingRight: null,
  paddingBottom: null,
  paddingVertical: null,
  paddingHorizontal: null,
});

for (var i = 0; i < unsupportedProps.length; i++) {
  delete ImageStylePropTypes[unsupportedProps[i]];
}

module.exports = ImageStylePropTypes;

/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ImageStylePropTypes
 * @flow
 */
'use strict';

var ImageResizeMode = require('ImageResizeMode');
var LayoutPropTypes = require('LayoutPropTypes');
var ReactPropTypes = require('ReactPropTypes');

var ImageStylePropTypes = {
  ...LayoutPropTypes,
  resizeMode: ReactPropTypes.oneOf(Object.keys(ImageResizeMode)),
  backgroundColor: ReactPropTypes.string,
  borderColor: ReactPropTypes.string,
  borderWidth: ReactPropTypes.number,
  borderRadius: ReactPropTypes.number,

  // iOS-Specific style to "tint" an image.
  // It changes the color of all the non-transparent pixels to the tintColor
  tintColor: ReactPropTypes.string,
  opacity: ReactPropTypes.number,
};

module.exports = ImageStylePropTypes;

Remove padding restriction on images


/* eslint max-len: ["error", 100 ] */
/* global describe, beforeEach, afterEach, it, expect */
'use strict';

describe('Selenium Tutorial', function() {

    var selenium = require('selenium-webdriver');
    var timeoutMilliSec = 10 * 1000;

    // Open the TECH.insight website in the browser before each test is run
    beforeEach(function(done) {
        this.driver = new selenium.Builder().
            withCapabilities(selenium.Capabilities.firefox()).
            build();
        this.driver.manage().timeouts().implicitlyWait(timeoutMilliSec);
        jasmine.DEFAULT_TIMEOUT_INTERVAL = timeoutMilliSec;
        this.driver.get('https://narrative.kbase.us/').then(done);
    });

    // Close the website after each test is run (so that it is opened fresh each time)
    afterEach(function(done) {
        this.driver.quit().then(done);
    });

    // Test to ensure we are on the home page by checking for username input
    it('Should be on the login page', function(done) {
        var element = this.driver.findElement(selenium.By.name('username'));
        element.getAttribute('id').then(function(id) {
            expect(id).toBeDefined();
            done();
        });
    });

});

/* eslint max-len: ["error", 100 ] */
/* global describe, beforeEach, afterEach, it, expect */
'use strict';

describe('Selenium Tutorial', function() {

    var selenium = require('selenium-webdriver');
    var timeoutMilliSec = 10 * 1000;

    // Open the TECH.insight website in the browser before each test is run
    beforeEach(function(done) {
        this.driver = new selenium.Builder().
            withCapabilities(selenium.Capabilities.firefox()).
            build();
        this.driver.manage().timeouts().implicitlyWait(timeoutMilliSec);
        jasmine.DEFAULT_TIMEOUT_INTERVAL = timeoutMilliSec;
        this.driver.get('http://localhost:9999/narrative/').then(done);
    });

    // Close the website after each test is run (so that it is opened fresh each time)
    afterEach(function(done) {
        this.driver.quit().then(done);
    });

    // Test to ensure we are on the home page by checking for username input
    it('Should be on the narrative tree page', function(done) {
        var element = this.driver.findElement(selenium.By.id('signin-button'));
        element.getAttribute('id').then(function(id) {
            expect(id).toBeDefined();
            done();
        });
    });

});

Connect to local instance and look for signin button


(function (window) {
	'use strict';

	var HearingTest = Object.create(null);

	HearingTest.init = function init() {
		this.context = new window.AudioContext();
		this.sound = this.createSound(this.context);

		return this;
	}

	HearingTest.createSound = function createSound(context) {
		return context.createOscillator();
	};

	HearingTest.connect = function connect(context, sound) {
		return sound.connect(context.destination);
	}

	HearingTest.playSound = function playSound(delay) {
		delay = delay || 0;
		this.sound.start(delay);
	};

	HearingTest.stopSound = function stopSound(delay) {
		delay = delay || 0;
		this.sound.stop(delay);
	};

	window.HearingTest = HearingTest;
	return HearingTest;
}(window));

(function (window) {
	'use strict';

	var HearingTest = Object.create(null);
	var context = new window.AudioContext();

	HearingTest.init = function init(frequency) {
		frequency = frequency || 440;

		return this;
	}

	HearingTest.createSound = function createSound(context) {
		return context.createOscillator();
	};

	HearingTest.connect = function connect(context, sound) {
		return sound.connect(context.destination);
	}

	HearingTest.playSound = function playSound(delay) {
		delay = delay || 0;
		this.sound.start(delay);
	};

	HearingTest.stopSound = function stopSound(delay) {
		delay = delay || 0;
		this.sound.stop(delay);
	};

	window.HearingTest = HearingTest;
	return HearingTest;
}(window));

Change instantiate AudioContext timing, and add a argument frequency in init function


$(function() {
    var api_uri = 'http://amateras.wsd.kutc.kansai-u.ac.jp/~otsuka/michishiki_api_server/select.py?order_by=created_at&order=descend';
    $.getJSON(api_uri, function(json) {
	for (var i = 0; i < json.length; i++) {
	    var $li = createListItem(json[i].title, json[i].comment, json[i].posted_by);
	    $('#post_list').append($li);
	}
	$('#post_list').listview('refresh');
    });
});

function createListItem(title, comment, posted_by) {
    var $title = $('<h2>').text(title);
    var $comment = $('<p>').text(comment);
    var $posted_by = $('<p>').text(posted_by);
    var $li = $('<li>').append($title).append($comment).append($posted_by);
    return $li;
}

$(document).on('pageshow', '#post-list', function() {
    initPostList();
});

function initPostList() {
    var api_uri = 'http://amateras.wsd.kutc.kansai-u.ac.jp/~otsuka/michishiki_api_server/select.py?order_by=created_at&order=descend';
    $.getJSON(api_uri, function(json) {
	for (var i = 0; i < json.length; i++) {
	    var $li = createListItem(json[i].title, json[i].comment, json[i].posted_by);
	    $('#post_list').append($li);
	}
	$('#post_list').listview('refresh');
    });
}

function createListItem(title, comment, posted_by) {
    var $title = $('<h2>').text(title);
    var $comment = $('<p>').text(comment);
    var $posted_by = $('<p>').text(posted_by);
    var $li = $('<li>').append($title).append($comment).append($posted_by);
    return $li;
}

Initialize post list when showing post list page


// internal config tests
require('./camera-resolution');
require('./camera-fps');
require('./camera-combo');
require('./camera-noaudio');
require('./camera-targets');

// constraints generation tests
require('./camera-resolution-constraints');
require('./camera-fps-constraints');
require('./camera-combo-constraints');
require('./camera-noaudio-constraints');
require('./camera-targets-constraints');

// constraints with source information tests
require('./camera-targets-constraints-sourced');

// hd, full-hd tests
require('./hd');

// screenshare tests
require('./share');
require('./share-constraints');

// internal config tests
require('./camera-resolution');
require('./camera-fps');
require('./camera-combo');
require('./camera-noaudio');
require('./camera-targets');

// constraints generation tests
require('./camera-resolution-constraints');
require('./camera-fps-constraints');
require('./camera-combo-constraints');
require('./camera-combo-constraints-mandatory');
require('./camera-noaudio-constraints');
require('./camera-targets-constraints');

// constraints with source information tests
require('./camera-targets-constraints-sourced');

// hd, full-hd tests
require('./hd');

// screenshare tests
require('./share');
require('./share-constraints');

Include mandatory constraints generation test


(function() {
  'use strict';

  var cli = require('casper').create().cli;
  var parapsych = require(cli.raw.get('rootdir') + '/dist/parapsych').create(require);

  parapsych.set('cli', cli)
    .set('initUrl', '/')
    .set('initSel', 'body');

  describe('group 1', function() {
    it('should pass --grep filter' , function() {
      this.test.assertEquals(this.fetchText('body').trim(), 'Hello World');
    });

    it('should not pass --grep filter' , function() {
      this.test.assertEquals(true, false);
    });
  });

  describe('group 2', function() {
    it('should pass --grep filter' , function() {
      this.test.assertEquals(this.fetchText('body').trim(), 'Hello World');
    });

    it('should not pass --grep filter' , function() {
      this.test.assertEquals(true, false);
    });
  });

  parapsych.done();
})();

(function() {
  'use strict';

  var cli = require('casper').create().cli;
  var parapsych = require(cli.raw.get('rootdir') + '/dist/parapsych').create(require);
  parapsych.set('cli', cli).set('initUrl', '/').set('initSel', 'body');

  describe('group 1', function() {
    it('should pass --grep filter' , function() {
      this.test.assertEquals(this.fetchText('body').trim(), 'Hello World');
    });

    it('should not pass --grep filter' , function() {
      this.test.assertEquals(true, false);
    });
  });

  describe('group 2', function() {
    it('should pass --grep filter' , function() {
      this.test.assertEquals(this.fetchText('body').trim(), 'Hello World');
    });

    it('should not pass --grep filter' , function() {
      this.test.assertEquals(true, false);
    });
  });

  parapsych.run();
})();

Update done() call to run().


$(document).ready(function () {

    var $id_type = $('[id$=type]');

    $id_type.each(function() {
        if($(this).val() == 'p'){
            $('[id$=periodical]').parents('.row').show();
            $('[id$=date]').parents('.row').show();
            $('[id$=event]').parents('.row').hide();
        } else if($(this).val() == 'e'){
            $('[id$=event]').parents('.row').show();
            $('[id$=periodical]').parents('.row').hide();
            $('[id$=date]').parents('.row').hide();
        } else{
            $('[id$=periodical]').parents('.row').hide();
            $('[id$=event]').parents('.row').hide();
            $('[id$=date]').parents('.row').hide();
        }
    });

    $id_type.change(function(){
        if($(this).val() == 'p'){
            $('[id$=periodical]').parents('.row').show();
            $('[id$=date]').parents('.row').show();
            $('[id$=event]').parents('.row').hide();
        } else if($(this).val() == 'e'){
            $('[id$=event]').parents('.row').show();
            $('[id$=periodical]').parents('.row').hide();
            $('[id$=date]').parents('.row').hide();
        } else{
            $('[id$=periodical]').parents('.row').hide();
            $('[id$=event]').parents('.row').hide();
            $('[id$=date]').parents('.row').hide();
        }
    });
});

$(document).ready(function () {

    var $id_type = $('#id_type');

    $id_type.each(function() {
        if($(this).val() == 'p'){
            $('[id^="publishedinperiodical"]').parents('._inline-group').show();
            $('[id^="publishedinevent"]').parents('._inline-group').hide();
        } else if($(this).val() == 'e'){
            $('[id^="publishedinperiodical"]').parents('._inline-group').hide();
            $('[id^="publishedinevent"]').parents('._inline-group').show();
        } else{
            $('[id^="publishedinperiodical"]').parents('._inline-group').hide();
            $('[id^="publishedinevent"]').parents('._inline-group').hide();
        }
    });

    $id_type.change(function(){
        if($(this).val() == 'p'){
            $('[id^="publishedinperiodical"]').parents('._inline-group').show();
            $('[id^="publishedinevent"]').parents('._inline-group').hide();
        } else if($(this).val() == 'e'){
            $('[id^="publishedinperiodical"]').parents('._inline-group').hide();
            $('[id^="publishedinevent"]').parents('._inline-group').show();
        } else{
            $('[id^="publishedinperiodical"]').parents('._inline-group').hide();
            $('[id^="publishedinevent"]').parents('._inline-group').hide();
        }
    });
});

Enable or disable an inline in accordance with the type of article


/*eslint-disable */
var path = require('path')
var express = require('express')
var webpack = require('webpack')
var config = require('../webpack.dev.config')
var app = express()
var compiler = webpack(config)

// Development Middleware
app.use(require('webpack-dev-middleware')(compiler, {
  noInfo: true,
  publicPath: config.output.publicPath
}))
app.use(require('webpack-hot-middleware')(compiler))

// Main entry for app
app.get('/*', function(req, res) {
  res.sendFile(path.join(__dirname, 'dev.html'))
})

// Assets
app.use(express.static('public/assets'))

// Catchall for any requests like /onboarding
app.get('*', function(req, res) {
  res.sendFile(path.join(__dirname, 'dev.html'))
})

app.listen(6660, 'localhost', function(err) {
  if (err) {
    console.log(err)
    return
  }
  console.log('Listening at http://localhost:6660')
})

/*eslint-disable */
var path = require('path')
var express = require('express')
var webpack = require('webpack')
var config = require('../webpack.dev.config')
var app = express()
var compiler = webpack(config)

// Development Middleware
app.use(require('webpack-dev-middleware')(compiler, {
  noInfo: true,
  publicPath: config.output.publicPath
}))
app.use(require('webpack-hot-middleware')(compiler))

// Assets
app.use(express.static('public/assets'))

// Main entry for app
app.get('/*', function(req, res) {
  res.sendFile(path.join(__dirname, 'dev.html'))
})

// Catchall for any requests like /onboarding
app.get('*', function(req, res) {
  res.sendFile(path.join(__dirname, 'dev.html'))
})

app.listen(6660, 'localhost', function(err) {
  if (err) {
    console.log(err)
    return
  }
  console.log('Listening at http://localhost:6660')
})

Move static asset middleware up a few notches


import accountsModule from '../resources/accounts';
/**
 * 每次切换页面时判断是否需要登录，如果需要就跳转到登录页
 * @param {Object} $rootScope
 */
function LoginInterceptor($rootScope, $location, Accounts) {
  $rootScope.$on('$stateChangeStart', function(event, toState, toParams) {
    if (toState.data && toState.data.requiresLogin && !isLoggedIn()) {
      $rootScope.returnToStateName = toState.name;
      $rootScope.returnToStateParams = toParams;
      $location.path('/login');
    }
  });

  function isLoggedIn() {
    return !!Accounts.getCurrent();
  }
}

LoginInterceptor.$inject = ['$rootScope', '$location', 'Accounts'];

export default angular.module('security.stateInterceptor', [
  accountsModule.name
]).run(LoginInterceptor);

import accountsModule from '../resources/accounts';
/**
 * 每次切换页面时判断是否需要登录，如果需要就跳转到登录页
 * @param {Object} $rootScope
 */
function LoginInterceptor($rootScope, $location, Accounts) {
  $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
    if (toState.data && toState.data.requiresLogin && !isLoggedIn()) {
      event.preventDefault();

      $rootScope.fromStateName = fromState.name;
      $rootScope.fromStateParams = fromParams;
      $rootScope.returnToStateName = toState.name;
      $rootScope.returnToStateParams = toParams;

      // 直接跳转的话有一定概率不会起作用
      // https://github.com/angular/angular.js/issues/9607
      $rootScope.$evalAsync(function() {
        $location.path('/login');
      });
    }
  });

  function isLoggedIn() {
    return !!Accounts.getCurrent();
  }
}

LoginInterceptor.$inject = ['$rootScope', '$location', 'Accounts'];

export default angular.module('security.stateInterceptor', [
  accountsModule.name
]).run(LoginInterceptor);

Fix a bug that cause redirection to login page failed at the second time


var
  config     = require('./config'),
  mocks      = require('./routes/mocks'),
  help       = require('./lib/routeHelpMessage'),
  components = require('./routes/components');

module.exports = function (app) {

  app.all('*', function(req, res, next){
    res.set('Access-Control-Allow-Origin', '*');
    res.set('Access-Control-Allow-Methods', 'GET');
    res.set('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
    if ('OPTIONS' == req.method) return res.send(200);
    next();
  });

  app.get('/', function (req, res) {
    res.json(help);
  });

  app.get('/components', components.index);
  app.get('/components/:owner/:name', components.show);
  app.get('/components/:owner/:name/script.js', components.getScript);
  app.get('/components/:owner/:name/build.js', components.getBuild);

  app.use(function (err, req, res, next) {
    res.send(err.code || 500, { error: err.message });
  });

  if (config.isTest) {
    app.get('/mock/registry', mocks.registry);
  }
};

var
  config     = require('./config'),
  mocks      = require('./routes/mocks'),
  help       = require('./lib/routeHelpMessage'),
  components = require('./routes/components');

module.exports = function (app) {

  app.all('*', function(req, res, next){
    res.set('Access-Control-Allow-Origin', '*');
    res.set('Access-Control-Allow-Methods', 'GET');
    res.set('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
    if ('OPTIONS' == req.method) return res.send(200);
    next();
  });

  app.get('/', function (req, res) {
    res.json(help);
  });

  app.get('/components', components.index);
  app.get('/components/:owner/:name', components.show);
  app.get('/components/:owner/:name/script.js', components.getScript);
  app.get('/components/:owner/:name/build.js', components.getBuild);

  app.use(function (err, req, res, next) {
    res.send(err.code || 500, { error: err.message });
  });

  if (config.useMocks) {
    app.get('/mock/registry', mocks.registry);
  }
};

Use mock registry route if using mocks, even in dev


var httpProxy = require('http-proxy');
var http = require('http');

var proxy = httpProxy.createProxy();

var routes = {
        // Router
        'hook.labeli.org' : 'http://localhost:9000',
        // Api
        'api.labeli.org' : 'http://localhost:9010',
        'hook.labeli.org' : 'http://localhost:9011',
        // Website
        'next.labeli.org' : 'http://localhost:9020',
        'hook.next.labeli.org' : 'http://localhost:9021',
};

var router = http.createServer(function(req, res)
{
    proxy.web(req, res, {target : routes[req.headers.host]});
});

router.listen(80);

var httpProxy = require('http-proxy');
var http = require('http');

var proxy = httpProxy.createProxy();

var routes = {
        // Router
        'hook.labeli.org' : 'http://localhost:9000',
        // Api
        'api.labeli.org' : 'http://localhost:9010',
        'hook.api.labeli.org' : 'http://localhost:9011',
        // Website
        'next.labeli.org' : 'http://localhost:9020',
        'hook.next.labeli.org' : 'http://localhost:9021',
};

var router = http.createServer(function(req, res)
{
    proxy.web(req, res, {target : routes[req.headers.host]});
});

router.listen(80);

Fix route for the api's hook


/* global angular */
'use strict';

angular.module('storm.controllers')

.controller('LocalRowListCtrl', ['$scope', '$state', '$stateParams', '$injector', 'Navigation', function($scope, $state, $stateParams, $injector, Navigation) {

	$scope.items = [];
	$scope.lastPage = true;

	var oldest = $stateParams.view === 'oldest' ? true : false;

	// Delete alert
	$scope.deleteAlert = $stateParams.view === 'delete' ? true : undefined;

	if (!$scope.deleteAlert) {
		// Get service dynamically from current state
		var service = $injector.get($state.current.service);

		service.getList(oldest).then(function(items) {
			$scope.items = items;
		});
	}

	$scope.$watch('deleteAlert', function(value, oldValue) {
		if (value === undefined) return;
		Navigation.setActiveElement(value ? 'confirm-delete' : 'menu-' + $state.current.service.toLowerCase());
	});

	$scope.delete = function() {
		service.clear().then(function() {
			$scope.items = [];
		});
		$scope.hideDeleteAlert();
	};

	$scope.hideDeleteAlert = function() {
		$scope.deleteAlert = false;
	};

}]);

/* global angular */
'use strict';

angular.module('storm.controllers')

.controller('LocalRowListCtrl', ['$scope', '$state', '$stateParams', '$injector', 'Navigation', function($scope, $state, $stateParams, $injector, Navigation) {

	$scope.items = [];
	$scope.lastPage = true;

	var oldest = $stateParams.view === 'oldest' ? true : false;

	// Delete alert
	$scope.deleteAlert = $stateParams.view === 'delete' ? true : undefined;

	// Get service dynamically from current state
	var service = $injector.get($state.current.service);

	if (!$scope.deleteAlert) {
		service.getList(oldest).then(function(items) {
			$scope.items = items;
		});
	}

	$scope.$watch('deleteAlert', function(value, oldValue) {
		if (value === undefined) return;
		Navigation.setActiveElement(value ? 'confirm-delete' : 'menu-' + $state.current.service.toLowerCase());
	});

	$scope.delete = function() {
		service.clear().then(function() {
			$scope.items = [];
		});
		$scope.hideDeleteAlert();
	};

	$scope.hideDeleteAlert = function() {
		$scope.deleteAlert = false;
	};

}]);

Fix delete confirmation in queue and history


import {
  REMEMBER_ARTICLE_SUCCESS,
  UPDATE_ARTICLE_SUCCESS,
  LOAD_ARTICLE_SUCCESS,
  REMOVE_ARTICLE_SUCCESS,
} from './../../actions/article';

export default (state, action) => {
  switch (action.type) {
    case LOAD_ARTICLE_SUCCESS: {
      const articles = action.payload.getIn(['entities', 'article']);

      if (!articles) {
        return state;
      }

      return state.setIn(['article', action.meta.articleUrl], articles.first());
    }
    case REMEMBER_ARTICLE_SUCCESS: {
      const article = action.payload.getIn(['entities', 'article']).first();

      return state.setIn(['article', action.meta.articleUrl], article);
    }
    case UPDATE_ARTICLE_SUCCESS: {
      const article = action.payload.getIn(['entities', 'article']).first();
      const articleUrl = state.getIn(['article']).findKey((el) => el.get('id') === action.meta.articleId);

      return state.setIn(['article', articleUrl], article);
    }
    case REMOVE_ARTICLE_SUCCESS: {
      const articleUrl = state.getIn(['article']).findKey((el) => el.get('id') === action.meta.articleId);

      return state.deleteIn(['article', articleUrl]);
    }
    default: {
      return state;
    }
  }
};

import {
  REMEMBER_ARTICLE_SUCCESS,
  UPDATE_ARTICLE_SUCCESS,
  LOAD_ARTICLE_SUCCESS,
  REMOVE_ARTICLE_SUCCESS,
} from './../../actions/article';

export default (state, action) => {
  switch (action.type) {
    case LOAD_ARTICLE_SUCCESS: {
      const articles = action.payload.getIn(['entities', 'article']);

      if (!articles) {
        return state;
      }

      return state.setIn(['article', action.meta.articleUrl], articles.first());
    }
    case REMEMBER_ARTICLE_SUCCESS: {
      const article = action.payload.getIn(['entities', 'article']).first();

      return state.setIn(['article', action.meta.articleUrl], article);
    }
    case UPDATE_ARTICLE_SUCCESS: {
      const article = action.payload.getIn(['entities', 'article']).first();

      return state.update('article', (articles) =>
                          articles.map((v) =>
                                       (v.get('id') === action.meta.articleId ? article : v)));
    }
    case REMOVE_ARTICLE_SUCCESS: {
      return state.update('article', (articles) =>
                          articles.filter((v) => v.get('id') !== action.meta.articleId));
    }
    default: {
      return state;
    }
  }
};

Fix popup updates when url changes


'use strict';

module.exports = function(grunt)
{
  grunt.loadNpmTasks('grunt-contrib-less');

  // load all grunt tasks
  grunt.initConfig({
    less: {
      development: {
        options: {
          strictImports: true
        },
        files: {
          "css/style.css": "less/style.less"
        }
      }
    }
  });
}

'use strict';

module.exports = function(grunt)
{
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-watch');

  // load all grunt tasks
  grunt.initConfig({
    watch: {
      styles: {
        files: ['**/*.less'],
        tasks: ['less'],
        options: {
          spawn: false,
        },
      },
    },
    less: {
      development: {
        options: {
          strictImports: true
        },
        files: {
          "css/style.css": "less/style.less"
        }
      }
    }
  });
}

Use watch to watch the directory for changes to the less files


/**********

http://expressjs.com/en/api.html

************/

var express = require('express')
var app = express()
var PORT = 3000
var requestCount = 0

app.use(
    "/", //the URL throught which you want to access to you static content
    express.static(__dirname + '/public') //where your static content is located in your filesystem
);

// app.all('(?=^((?!style).)*$)(?=^((?!js).)*$)', function (req, res, next) {
app.all('*', function (req, res, next) {
  res.sendFile('public/index.html', { root: __dirname });
  requestCount += 1
  console.log(requestCount + ' request: ' + req.params[0])
});

app.listen(PORT) //the port you want to use
console.log('\nServer listening at http://localhost:' + PORT + '\n');

/**********

http://expressjs.com/en/api.html

************/

var express = require('express')
var app = express()
var PORT = 3000
var requestCount = 0

app.use(
    "/", //the URL throught which you want to access to you static content
    express.static(__dirname + '/public') //where your static content is located in your filesystem
);

// app.all('(?=^((?!style).)*$)(?=^((?!js).)*$)', function (req, res, next) {
app.all('*', function (req, res, next) {
  res.sendFile('public/index.html', { root: __dirname });
  requestCount += 1
  console.log(requestCount + ' request: ' + req.params[0])
});

app.listen(process.env.PORT || PORT) //the port you want to use
console.log('\nServer listening at http://localhost:' + PORT + '\n');

Use this to set PORT both locally and on Heroku: app.listen(process.env.PORT || PORT)


'use strict';

var app = require('./application');

var server = app.listen(
	process.env.PORT || 3000,
	process.env.HOST || '::1'
);

process.once('SIGINT', function () {
	server.close(function () {
		process.exit(0);
	});
});

'use strict';

var app = require('./application');

var server = app.listen(
	process.env.BIND || 3000,
	process.env.HOST || '::1'
);

process.once('SIGINT', function () {
	server.close(function () {
		process.exit(0);
	});
});

Use BIND instead of PORT.


var util = require(__dirname+'/../util.js');
var schema =      require(__dirname+'/../schema.js');

function TypeAny() {
  this._default = undefined;
  this._validator = undefined;
  this._options = {};
}

TypeAny.prototype.default = function(fnOrValue) {
  this._default = fnOrValue;
}
TypeAny.prototype.validator = function(min) {
  this._validator = fn;
}
TypeAny.prototype._getDefaultFields = function(prefix, defaultFields, virtualFields) {
}

// Dummy methods, just to allow users to easily switch from a valid type to any
TypeAny.prototype.options = function(options) {
  return this;
}
TypeAny.prototype.optional = function() {
  return this;
}
TypeAny.prototype.required = function() {
  return this;
}
TypeAny.prototype.allowNull = function() {
  return this;
}
TypeAny.prototype.min = function() {
  return this;
}
TypeAny.prototype.max = function() {
  return this;
}
TypeAny.prototype.length = function() {
  return this;
}
TypeAny.prototype.schema = function() {
  return this;
}
TypeAny.prototype.validate = function() {
  return this;
}

module.exports = TypeAny;

var util = require(__dirname+'/../util.js');
var schema =      require(__dirname+'/../schema.js');

function TypeAny() {
  this._default = undefined;
  this._validator = undefined;
  this._options = {};
}

TypeAny.prototype.default = function(fnOrValue) {
  this._default = fnOrValue;
}
TypeAny.prototype.validator = function(fn) {
  this._validator = fn;
}
TypeAny.prototype._getDefaultFields = function(prefix, defaultFields, virtualFields) {
}

// Dummy methods, just to allow users to easily switch from a valid type to any
TypeAny.prototype.options = function(options) {
  return this;
}
TypeAny.prototype.optional = function() {
  return this;
}
TypeAny.prototype.required = function() {
  return this;
}
TypeAny.prototype.allowNull = function() {
  return this;
}
TypeAny.prototype.min = function() {
  return this;
}
TypeAny.prototype.max = function() {
  return this;
}
TypeAny.prototype.length = function() {
  return this;
}
TypeAny.prototype.schema = function() {
  return this;
}
TypeAny.prototype.validate = function() {
  return this;
}

module.exports = TypeAny;

Fix bad function argument name


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' />

login name: <input type='text' name='loginName' 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';

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);
  }
}

Fix typo in server form.


/**
 * Dummy implementation of analytics.
 */
"use strict";

plugin.consumes = [];
plugin.provides = ["analytics"];

module.exports = plugin;

function plugin(options, imports, register) {

     register(null, {
        "analytics": {
            log: function() {},
            track: function() {},
            identify: function() {},
            logClean: function() {},
            trackClean: function() {},
            identifyClean: function() {},
        }
    });
}

/**
 * Dummy implementation of analytics.
 */
"use strict";

plugin.consumes = [];
plugin.provides = ["analytics"];

module.exports = plugin;

function plugin(options, imports, register) {

     register(null, {
        "analytics": {
            log: function() {},
            track: function() {},
            identify: function() {},
            logClean: function() {},
            trackClean: function() {}
        }
    });
}

Revert "Revert "Fix broken funnel""


//  buffer-tpc-check.js
//  (c) 2013 Sunil Sadasivan
//  Check if third party cookies are disabled
//

;(function () {

    ;(function check() {
        //if the 3rd party cookies check is done, remove the iframe
        if(self.port) {
            bufferpm.bind("buffer_3pc_done", function(){
                elem = document.getElementById('buffer_tpc_check');
                if(elem) { elem.parentNode.removeChild(elem); }
                return false;
            });

            //if the 3rd party cookies check is disabled, store it
            bufferpm.bind("buffer_3pc_disabled", function(){
                if(xt && xt.options) {
                    xt.options['buffer.op.tpc-disabled'] = true;
                }
                self.port.emit('buffer_tpc_disabled');
                return false;
            });

            var iframe = document.createElement('iframe');
            iframe.id = 'buffer_tpc_check';
            iframe.src = 'https://d3ijcis4e2ziok.cloudfront.net/tpc-check.html';
            //iframe.src = 'http://local.bufferapp.com/js/tpc-check.html';
            iframe.style.display="none";
            document.body.appendChild(iframe);
        } else {
            setTimeout(check, 50);
        }
    }());

}());

//  buffer-tpc-check.js
//  (c) 2013 Sunil Sadasivan
//  Check if third party cookies are disabled
//

;(function () {

    ;(function check() {
        //if the 3rd party cookies check is done, remove the iframe
        if((self.port) || (xt && xt.options)) {
            bufferpm.bind("buffer_3pc_done", function(){
                elem = document.getElementById('buffer_tpc_check');
                if(elem) { elem.parentNode.removeChild(elem); }
                return false;
            });

            //if the 3rd party cookies check is disabled, store it
            bufferpm.bind("buffer_3pc_disabled", function(){
                if(xt && xt.options) {
                    xt.options['buffer.op.tpc-disabled'] = true;
                }
                self.port.emit('buffer_tpc_disabled');
                return false;
            });

            var iframe = document.createElement('iframe');
            iframe.id = 'buffer_tpc_check';
            iframe.src = 'https://d3ijcis4e2ziok.cloudfront.net/tpc-check.html';
            //iframe.src = 'http://local.bufferapp.com/js/tpc-check.html';
            iframe.style.display="none";
            document.body.appendChild(iframe);
        } else {
            setTimeout(check, 50);
        }
    }());

}());

Make TPC check work on chrome again


/** @jsx React.DOM */
var NavigationBar = require('../navigation-bar/component');
var EditorAndRunner = require('../editor-and-runner/component');
var KeyboardShortcutOverlay = require('../keyboard-shortcut-overlay/component');

var React = require('react');

var View = React.createClass({

  render: function() {
    return (
      <div>
        <NavigationBar metaKeySymbol={this.props.metaKeySymbol} onSave={this.props.onSave}/>
        <EditorAndRunner editorId={this.props.editorId} runnerId={this.props.runnerId}/>
        <KeyboardShortcutOverlay shortcuts={this.props.shortcuts}/>
      </div>
    );
  }

});

module.exports = View;

/** @jsx React.DOM */
var NavigationBar = require('../navigation-bar/component');
var EditorAndRunner = require('../editor-and-runner/component');
var KeyboardShortcutOverlay = require('../keyboard-shortcut-overlay/component');

var React = require('react');

var View = React.createClass({

  render: function() {
    var props = this.props;
    return (
      <div>
        <NavigationBar metaKeySymbol={props.metaKeySymbol} onSave={props.onSave}/>
        <EditorAndRunner editorId={props.editorId} runnerId={props.runnerId}/>
        <KeyboardShortcutOverlay shortcuts={props.shortcuts} isVisible={props.shortcutOverlay.isVisible}/>
      </div>
    );
  }

});

module.exports = View;

Add isVisible to shortcuts overlay and extracted `props=this.props`.


/**
  Our data model for determining whether there's a new version of Discourse

  @class VersionCheck
  @extends Discourse.Model
  @namespace Discourse
  @module Discourse
**/
Discourse.VersionCheck = Discourse.Model.extend({
  upToDate: function() {
    return this.get('latest_version') === this.get('installed_version');
  }.property('latest_version', 'installed_version'),

  behindByOneVersion: function() {
    return this.get('missing_versions_count') === 1;
  }.property('missing_versions_count'),

  gitLink: function() {
    return "https://github.com/discourse/discourse/tree/" + this.get('installed_sha');
  }.property('installed_sha'),

  shortSha: function() {
    return this.get('installed_sha').substr(0,10);
  }.property('installed_sha')
});

Discourse.VersionCheck.reopenClass({
  find: function() {
    return Discourse.ajax({ url: Discourse.getURL('/admin/version_check'), dataType: 'json' }).then(function(json) {
      return Discourse.VersionCheck.create(json);
    });
  }
});

/**
  Our data model for determining whether there's a new version of Discourse

  @class VersionCheck
  @extends Discourse.Model
  @namespace Discourse
  @module Discourse
**/
Discourse.VersionCheck = Discourse.Model.extend({
  upToDate: function() {
    return this.get('missing_versions_count') === 0;
  }.property('missing_versions_count'),

  behindByOneVersion: function() {
    return this.get('missing_versions_count') === 1;
  }.property('missing_versions_count'),

  gitLink: function() {
    return "https://github.com/discourse/discourse/tree/" + this.get('installed_sha');
  }.property('installed_sha'),

  shortSha: function() {
    return this.get('installed_sha').substr(0,10);
  }.property('installed_sha')
});

Discourse.VersionCheck.reopenClass({
  find: function() {
    return Discourse.ajax({ url: Discourse.getURL('/admin/version_check'), dataType: 'json' }).then(function(json) {
      return Discourse.VersionCheck.create(json);
    });
  }
});

Fix version check when your version is later than the one fetched by the last version check job


$(function() {
  var dt = {sPaginationType: 'full_numbers',
            bAutoWidth:false ,
            aaSorting: [[ 0, 'desc' ]],
            fnDrawCallback: _iconify,
  }

  if ($(window).width() <= 600) dt = $.extend({
        'bScrollCollapse': true,
        'sScrollX': '100%',
  }, dt)

  $('.robot_actions').dataTable(dt)

  $('a.add').button({ icons: { primary: 'ui-icon-plus' } })

  function _iconify() {
    $('a.view').button({ icons: { primary: 'ui-icon-search' }, text: false })
    $('a.label').button({ icons: { primary: 'ui-icon-print' }, text: false })
  }
})

$(function() {
  var dt = {sPaginationType: 'full_numbers',
            bAutoWidth: false,
            aaSorting: [[ 0, 'desc' ]],
            fnDrawCallback: _iconify,
  }

  /*if ($(window).width() <= 600) dt = $.extend({
        'bScrollCollapse': true,
        'sScrollX': '100%',
  }, dt)*/

  var dt = $('.robot_actions').dataTable(dt)
  $('.table input').focus()

  $('input.search-mobile').keyup(function() {
    $('.dataTables_filter input').val($(this).val()).trigger('keyup')
  }).parent('span').addClass('enable')
  $('#sidebar,.cont_wrap').addClass('searchbox')

  $('a.add').button({ icons: { primary: 'ui-icon-plus' } })

  $(window).resize(function() { _resize() })

  function _resize() {
    $.each([2,3,5,6],function(i,n) {
      dt.fnSetColumnVis(n, !($(window).width() <= 600))
    })
  }

  _resize()

  function _iconify() {
    $('a.view').button({ icons: { primary: 'ui-icon-search' }, text: false })
    $('a.label').button({ icons: { primary: 'ui-icon-print' }, text: false })
  }
})

Add responsive behaviour to table, add search box


import React from 'react';
import PropTypes from 'prop-types';
import { Box } from '../box';
import { IconButton } from '../button';
import {
  IconArrowLeftMediumOutline,
  IconArrowRightMediumOutline,
  IconArrowLeftSmallOutline,
  IconArrowRightSmallOutline,
} from '@teamleader/ui-icons';

const NavigationBar = ({ nextMonth, previousMonth, onPreviousClick, onNextClick, className, localeUtils, size }) => {
  const months = localeUtils.getMonths();
  const previousMonthButtonLabel = months[previousMonth.getMonth()];
  const nextMonthButtonLabel = months[nextMonth.getMonth()];

  return (
    <Box className={className} display="flex" justifyContent="space-between">
      <IconButton
        icon={size === 'large' ? <IconArrowLeftMediumOutline /> : <IconArrowLeftSmallOutline />}
        onClick={() => onPreviousClick()}
        title={previousMonthButtonLabel}
      />
      <IconButton
        icon={size === 'large' ? <IconArrowRightMediumOutline /> : <IconArrowRightSmallOutline />}
        onClick={() => onNextClick()}
        title={nextMonthButtonLabel}
      />
    </Box>
  );
};

NavigationBar.propTypes = {
  className: PropTypes.string,
  localeUtils: PropTypes.object,
  nextMonth: PropTypes.instanceOf(Date),
  previousMonth: PropTypes.instanceOf(Date),
  onNextClick: PropTypes.func,
  onPreviousClick: PropTypes.func,
  size: PropTypes.oneOf(['small', 'medium', 'large']),
};

export default NavigationBar;

import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { Box } from '../box';
import { IconButton } from '../button';
import {
  IconArrowLeftMediumOutline,
  IconArrowRightMediumOutline,
  IconArrowLeftSmallOutline,
  IconArrowRightSmallOutline,
} from '@teamleader/ui-icons';

class NavigationBar extends PureComponent {
	handlePreviousClick = () => {
		this.props.onPreviousClick();
	};

	handleNextClick = () => {
		this.props.onNextClick();
	};

  render() {
		const {
			className,
			localeUtils,
		  nextMonth,
      previousMonth,
      size
		} = this.props;

    const months = localeUtils.getMonths();
    const previousMonthButtonLabel = months[previousMonth.getMonth()];
    const nextMonthButtonLabel = months[nextMonth.getMonth()];

    return (
      <Box className={className} display="flex" justifyContent="space-between">
        <IconButton
          icon={size === 'large' ? <IconArrowLeftMediumOutline /> : <IconArrowLeftSmallOutline />}
          onClick={this.handlePreviousClick}
          title={previousMonthButtonLabel}
        />
        <IconButton
          icon={size === 'large' ? <IconArrowRightMediumOutline /> : <IconArrowRightSmallOutline />}
          onClick={this.handleNextClick}
          title={nextMonthButtonLabel}
        />
      </Box>
    );
	}
}

NavigationBar.propTypes = {
  className: PropTypes.string,
  localeUtils: PropTypes.object,
  nextMonth: PropTypes.instanceOf(Date),
  previousMonth: PropTypes.instanceOf(Date),
  onNextClick: PropTypes.func,
  onPreviousClick: PropTypes.func,
  size: PropTypes.oneOf(['small', 'medium', 'large']),
};

export default NavigationBar;

Convert functional component to class extending PureComponent


import { htmlSafe } from 'ember-string';
import makeHelper from 'ember-svg-jar/utils/make-helper';
import makeSVG from 'ember-svg-jar/utils/make-svg';
import inlineAssets from '../inline-assets';

export default makeHelper((assetId, svgAttrs) => (
  htmlSafe(makeSVG(assetId, svgAttrs, inlineAssets))
));

import { htmlSafe } from 'ember-string';
import makeHelper from 'ember-svg-jar/utils/make-helper';
import makeSVG from 'ember-svg-jar/utils/make-svg';
import inlineAssets from '../inline-assets';

export function svgJar(assetId, svgAttrs) {
  return htmlSafe(makeSVG(assetId, svgAttrs, inlineAssets));
}

export default makeHelper(svgJar);

Make svgJar a callable method


var gulp = require('gulp');
var nightwatch = require('../');

gulp.task('default', function() {
  gulp.src('')
    .pipe(nightwatch({
      configFile: 'nightwatch.json'
    }));
});

gulp.task('withCliArgs:array', function() {
  gulp.src('')
    .pipe(nightwatch({
      configFile: 'nightwatch.json',
      cliArgs: [ '--env chrome', '--tags sandbox' ]
    }));
});

gulp.task('withCliArgs:object', function() {
  gulp.src('')
    .pipe(nightwatch({
      configFile: 'nightwatch.json',
      cliArgs: {
        env: "chrome",
        tags: "sandbox"
      }
    }));
});

var gulp = require('gulp');
var nightwatch = require('../');

gulp.task('default', function() {
  gulp.src('')
    .pipe(nightwatch({
      configFile: 'nightwatch.json'
    }));
});

gulp.task('withCliArgs:array', function() {
  gulp.src('')
    .pipe(nightwatch({
      configFile: 'nightwatch.json',
      cliArgs: [ '--env chrome', '--tag sandbox' ]
    }));
});

gulp.task('withCliArgs:object', function() {
  gulp.src('')
    .pipe(nightwatch({
      configFile: 'nightwatch.json',
      cliArgs: {
        env: 'chrome',
        tag: 'sandbox'
      }
    }));
});

Use single quotes instead of a double quotes


import log from 'logger';
import User from 'models/user';
import Raven from 'raven';

class Me extends User {
    fetch() {
        this.$api('me.get_me', {}, this.on_user_fetched);
        return this;
    }

    update(data, on_success, on_error) {
        this.$api('me.update_me', {payload: JSON.stringify(data)}, on_success, on_error);
    }

    on_user_fetched(response) {
        Raven.setUserContext({
            id: response.obj.id,
            email: response.obj.email,
            slug: response.obj.slug,
            fullname: `${response.obj.first_name} ${response.obj.last_name}`,
            is_authenticated: true,
            is_anonymous: false
        });
        this.on_fetched(response);
    }
}

var me = new Me();

export default me.fetch();

import User from 'models/user';
import Raven from 'raven';
import config from 'config';

class Me extends User {
    fetch() {
        this.$api('me.get_me', {}, this.on_user_fetched);
        return this;
    }

    update(data, on_success, on_error) {
        this.$api('me.update_me', {payload: JSON.stringify(data)}, on_success, on_error);
    }

    on_user_fetched(response) {
        if (config.sentry) {
            Raven.setUserContext({
                id: response.obj.id,
                email: response.obj.email,
                slug: response.obj.slug,
                fullname: `${response.obj.first_name} ${response.obj.last_name}`,
                is_authenticated: true,
                is_anonymous: false
            });
        }
        this.on_fetched(response);
    }
}

const me = new Me();

export default me.fetch();

Declare current user to Sentry only if enabled


var gulp = require('gulp');
var execsyncs = require('gulp-execsyncs');

gulp.task('prepare-data', function(cb) {
  execsyncs({
    cmds : [
      './prepare.sh',
      'src/scripts/prepare-asylum-data.rb'
      ]
  });
  cb();
});

var opts = {
	pretasks: ['prepare-data'],
	paths: ['node_modules/lucify-commons']
}

var taskCreator = require('lucify-embed');
taskCreator(gulp, opts);

var gulp = require('gulp');
var execsyncs = require('gulp-execsyncs');

gulp.task('prepare-data', function(cb) {
  execsyncs({
    cmds : [
      './prepare.sh',
      'src/scripts/prepare-asylum-data.rb'
      ]
  });
  cb();
});

var opts = {
	pretasks: ['prepare-data'],
	paths: ['node_modules/lucify-commons'],
	publishFromFolder: 'dist',
	defaultBucket: 'lucify-dev',
	maxAge: 60,
	assetContext: 'embed/the-flow-towards-europe/',
	embedBaseUrl: 'http://localhost:8000/embed/the-flow-towards-europe/'
}

var taskCreator = require('lucify-embed');
taskCreator(gulp, opts);

Add parameters for publishing project (as embeddable)


const fs = require('fs-extra');
const path = require('path');
const { createFilePath } = require('gatsby-source-filesystem');

exports.onCreateNode = ({ node, getNode, boundActionCreators }) => {
  const { createNodeField } = boundActionCreators;

  if (node.internal.type === 'MarkdownRemark') {
    const slug = createFilePath({ node, getNode, basePath: 'pages' });
    createNodeField({
      node,
      name: 'slug',
      value: slug,
    });
  }
};

exports.onPostBootstrap = () => {
  console.log('Copying locales'); // eslint-disable-line no-console
  fs.copySync(path.join(__dirname, '/src/locales'), path.join(__dirname, '/public/locales'));
};

exports.createPages = ({ graphql, boundActionCreators }) => {
  const { createPage } = boundActionCreators;

  return new Promise((resolve) => {
    graphql(`
      {
        allMarkdownRemark {
          edges {
            node {
              fields {
                slug
              }
            }
          }
        }
      }
    `).then(({ data }) => {
      data.allMarkdownRemark.edges.forEach(({ node }) => {
        createPage({
          path: node.fields.slug,
          component: path.resolve('./src/templates/blog-post.jsx'),
          context: {
            // Data passed to context is available in page queries as GraphQL variables
            slug: node.fields.slug,
          },
        });
      });

      resolve();
    });
  });
};

const fs = require('fs-extra');
const path = require('path');
const { createFilePath } = require('gatsby-source-filesystem');

exports.onCreateNode = ({ node, getNode, boundActionCreators }) => {
  const { createNodeField } = boundActionCreators;

  if (node.internal.type === 'MarkdownRemark') {
    const slug = createFilePath({ node, getNode, basePath: 'pages' });
    createNodeField({
      node,
      name: 'slug',
      value: slug,
    });
  }
};

exports.onPreBootstrap = () => {
  console.log('Copying locales'); // eslint-disable-line no-console
  fs.copySync(path.join(__dirname, '/src/locales'), path.join(__dirname, '/public/locales'));
};

exports.createPages = ({ graphql, boundActionCreators }) => {
  const { createPage } = boundActionCreators;

  return new Promise((resolve) => {
    graphql(`
      {
        allMarkdownRemark {
          edges {
            node {
              fields {
                slug
              }
            }
          }
        }
      }
    `).then(({ data }) => {
      data.allMarkdownRemark.edges.forEach(({ node }) => {
        createPage({
          path: node.fields.slug,
          component: path.resolve('./src/templates/blog-post.jsx'),
          context: {
            // Data passed to context is available in page queries as GraphQL variables
            slug: node.fields.slug,
          },
        });
      });

      resolve();
    });
  });
};

Fix broken locale copying mechanism


'use strict';
exports.test = function () {
  // Don't get fooled by e.g. browserify environments.
  return process && !process.browser;
};

exports.install = function (func) {
  return function () {
    process.nextTick(func);
  };
};

'use strict';
exports.test = function () {
  // Don't get fooled by e.g. browserify environments.
  return (typeof process !== 'undefined') && !process.browser;
};

exports.install = function (func) {
  return function () {
    process.nextTick(func);
  };
};

Check for process without potential to cause a ReferenceError.


var React = require('react');

var Icon = React.createClass({
    propTypes: {
        id:   React.PropTypes.string,
        type: React.PropTypes.string,
        className: React.PropTypes.string
    },

    getDefaultProps: function() {
        return {
            type: 'octicon'
        };
    },

    render: function() {
        var type      = this.props.type;
        var id        = this.props.id;
        var className = this.props.className;

        if (!className) {
            className = type + ' ' + type + '-' + id;
        }

        return <i className={className}></i>;
    }
});

module.exports = Icon;

const React = require('react');
const classNames = require('classnames');

const Icon = React.createClass({
    propTypes: {
        // Icon of the icon in the collection
        id:        React.PropTypes.string,
        // Type of collection
        type:      React.PropTypes.string,
        // Extra className
        className: React.PropTypes.string,
        // Is the icon spinning?
        spin:      React.PropTypes.bool
    },

    getDefaultProps: function() {
        return {
            type: 'octicon',
            spin: false
        };
    },

    render: function() {
        let { type, id, className, spin } = this.props;

        className = classNames(
            type + ' ' + type + '-' + id,
            className,
            {
                'icon-spin': spin
            }
        );

        return <i className={className}></i>;
    }
});

module.exports = Icon;

Add prop "spin" for icon


import React, {PropTypes, Component} from 'react';
import {View} from 'react-native';

export default class Form extends Component {
  _listeners = [];

  static PropTypes = {
    onSuccess: PropTypes.func,
    onFail: PropTypes.func,
    submitButton: PropTypes.element.isRequired
  }

  static childContextTypes = {
    addFormListener: PropTypes.func,
    removeFormListener: PropTypes.func
  }

  getChildContext() {
    return {
      addFormListener: this.addFormListener.bind(this),
      removeFormListener: this.removeFormListener.bind(this)
    }
  }

  addFormListener(ln) {
    this._listeners.push(ln);
  }

  removeFormListener(ln) {
    this._listeners = this._listeners.filter(l => l  !== ln);
  }

  onSubmit() {
    const defaultFn = () => {};
    const {onFail = defaultFn, onSuccess = defaultFn} = this.props;

    const stop = this._listeners.reduce((stop, _listener) => {
      return _listener() || stop;
    }, false);
    if (stop) {
      return onFail();
    };
    onSuccess();
  }

  render() {
    const {submitButton, children, style} = this.props;

    return (
        <View style={style}>
          {children}
          {submitButton(this.onSubmit.bind(this))}
        </View>
    )
  }
}

import React, {PropTypes, Component} from 'react';
import {View} from 'react-native';

export default class Form extends Component {
  _listeners = [];

  static PropTypes = {
    onSuccess: PropTypes.func,
    onFail: PropTypes.func,
    submitButton: PropTypes.element.isRequired
  }

  static childContextTypes = {
    addFormListener: PropTypes.func,
    removeFormListener: PropTypes.func
  }

  getChildContext() {
    return {
      addFormListener: this.addFormListener.bind(this),
      removeFormListener: this.removeFormListener.bind(this)
    }
  }

  addFormListener(ln) {
    this._listeners.push(ln);
  }

  removeFormListener(ln) {
    this._listeners = this._listeners.filter(l => l  !== ln);
  }

  onSubmit() {
    const defaultFn = () => {};
    const {onFail = defaultFn, onSuccess = defaultFn} = this.props;

    const stop = this._listeners.reduce((stop, _listener) => {
      return _listener() || stop;
    }, false);
    if (stop) {
      return onFail();
    };
    onSuccess();
  }

  render() {
    const {submitButton, children, style, disableSubmit} = this.props;

    return (
        <View style={style}>
          {children}
          {submitButton(this.onSubmit.bind(this), disableSubmit)}
        </View>
    )
  }
}

Add prop to disable submit


import fs from 'fs';
import path from 'path';
import { Reader } from 'fstream';
import { Pack } from 'tar';

/** pose.save
 * @desc Save a template.
 * @param {Object} opts - Options.
 */
function save(opts = {}) {
  const name = opts._[1] || opts.name;

  const destPath = path.join(opts._templates, `${name}.tar`);
  const dest = fs.createWriteStream(destPath);

  const pack = new Pack({ noProprietary: true });

  const read = new Reader({ path: opts.entry, type: 'Directory' })
  .pipe(pack)
  .pipe(dest);

  pack.on('end', () => {
    console.log(`Saved ${name}.`);
  });

  pack.on('error', () => {
    console.log(`Failed to pack ${destPath}`);
  });

  read.on('error', () => {
    console.log(`Failed to read ${opts.entry}.`);
  });
}

export default save;

import fs from 'fs';
import path from 'path';
import { Reader } from 'fstream';
import { Pack } from 'tar';

/** pose.save
 * @desc Save a template.
 * @param {Object} opts - Options.
 */
function save(opts = {}) {
  const name = opts._[1] || opts.name;
  const entry = opts._[2] || opts.entry;

  const destPath = path.join(opts._templates, `${name}.tar`);
  const dest = fs.createWriteStream(destPath);

  const pack = new Pack({ noProprietary: true });

  const read = new Reader({ path: entry, type: 'Directory' })
  .pipe(pack)
  .pipe(dest);

  pack.on('end', () => {
    console.log(`Saved ${name}.`);
  });

  pack.on('error', () => {
    console.log(`Failed to pack ${destPath}`);
  });

  read.on('error', () => {
    console.log(`Failed to read ${entry}.`);
  });
}

export default save;

Change entry for CLI layout


goog.require('ol.Map');
goog.require('ol.RendererHint');
goog.require('ol.View2D');
goog.require('ol.layer.Tile');
goog.require('ol.source.TileWMS');

var wmsSource = new ol.source.TileWMS({
  url: 'http://demo.opengeo.org/geoserver/wms',
  params: {'LAYERS': 'ne:ne'}
});

var wmsLayer = new ol.layer.Tile({
  source: wmsSource
});

var view = new ol.View2D({
  center: [0, 0],
  zoom: 1
});

var viewProjection = /** @type {ol.proj.Projection} */
    (view.getProjection());

var map = new ol.Map({
  layers: [wmsLayer],
  renderer: ol.RendererHint.CANVAS,
  target: 'map',
  view: view
});

map.on('singleclick', function(evt) {
  document.getElementById('info').innerHTML = '';
  var viewResolution = /** @type {number} */ (view.getResolution());
  var url = wmsSource.getGetFeatureInfoUrl(
      evt.getCoordinate(), viewResolution, viewProjection,
      {'INFO_FORMAT': 'text/html'});
  if (url) {
    document.getElementById('info').innerHTML =
        '<iframe seamless src="' + url + '"></iframe>';
  }
});

goog.require('ol.Map');
goog.require('ol.RendererHint');
goog.require('ol.View2D');
goog.require('ol.layer.Tile');
goog.require('ol.source.TileWMS');

var wmsSource = new ol.source.TileWMS({
  url: 'http://demo.opengeo.org/geoserver/wms',
  params: {'LAYERS': 'ne:ne'}
});

var wmsLayer = new ol.layer.Tile({
  source: wmsSource
});

var view = new ol.View2D({
  center: [0, 0],
  zoom: 1
});

var viewProjection = /** @type {ol.proj.Projection} */
    (view.getProjection());

var map = new ol.Map({
  layers: [wmsLayer],
  renderer: ol.RendererHint.CANVAS,
  target: 'map',
  view: view
});

map.on('singleclick', function(evt) {
  document.getElementById('info').innerHTML = '';
  var viewResolution = /** @type {number} */ (view.getResolution());
  var url = wmsSource.getGetFeatureInfoUrl(
      evt.coordinate, viewResolution, viewProjection,
      {'INFO_FORMAT': 'text/html'});
  if (url) {
    document.getElementById('info').innerHTML =
        '<iframe seamless src="' + url + '"></iframe>';
  }
});

Use evt.coordinate instead of evt.getCoordinate()


var express = require('express');
var router = express.Router();
var app = express();

router.get('/sendSMS', function(req, res, next){
    var number = req.query['number'];
    var body_message = req.query['message'];

    var client = require('twilio')('AC525c4929b17f0023e6067967a16232f0', '7a1cfcc80b4adc7634cf037b3dbcd930');

    client.sendSms({
        to: number,
        from: '+48799449177',
        body: body_message
    }, function(error, message) {
        if (!error) {
            console.log('Success! The SID for this SMS message is:');
            console.log(message.sid);
            console.log('Message sent on:');
            console.log(message.dateCreated);
        } else {
            console.log('Oops! There was an error.'+ error.message);
        }
    });

});

module.exports = router;

var express = require('express');
var router = express.Router();
var app = express();

router.get('/sendSMS', function(req, res, next){
    var number = req.query['number'];
    var body_message = req.query['message'];

    var client = require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);

    client.sendSms({
        to: number,
        from: '+48799449177',
        body: body_message
    }, function(error, message) {
        if (!error) {
            console.log('Success! The SID for this SMS message is:');
            console.log(message.sid);
            console.log('Message sent on:');
            console.log(message.dateCreated);
            res.status(202).send(true);
        } else {
            console.log('Oops! There was an error.'+ error.message);
            res.status(500).send(error.message);
        }
    });

});

module.exports = router;

Create response for request and create env var for twilio account.


var browserify = require('browserify');
var rebundler = require("rebundler");
var path = require("path");
var SpawnStream = require("spawn-stream");

var env = require("../config").env;
var collapser = require('bundle-collapser/plugin');

var babelify = require("babelify");

function createBundle(entry) {

  return rebundler({noop: env !== 'development'}, function(cache, pkgCache) {
    return browserify(entry, {
      cache:         cache,
      packageCache:  pkgCache,
      extensions:    ['.jsx'],
      noParse:       [require.resolve("../dataset/tree.json")],
      debug:         env == 'development',
      fullPaths:     env == 'development'
    })
      .transform(babelify)
      .transform('envify', {global: true});
  });
}

var UGLIFY_CMD = require.resolve('uglify-js/bin/uglifyjs');

function uglify() {
  return SpawnStream(UGLIFY_CMD, [
    '--compress',
    '--mangle',
    '--screw-ie8'
  ]);
}

var main = createBundle(require.resolve('../bundles//default.jsx'));

module.exports = {
  "/bundles/default.js": function() {
    var b = main();

    if (env !== 'development') {
      b.plugin(collapser);
    }

    var stream = b.bundle();

    if (env !== 'development') {
      return stream.pipe(uglify());
    }

    return stream
  }
};

var browserify = require('browserify');
var rebundler = require("rebundler");
var path = require("path");
var SpawnStream = require("spawn-stream");

var env = require("../config").env;
var collapser = require('bundle-collapser/plugin');

var babelify = require("babelify");

function createBundle(entry) {

  return rebundler({noop: env !== 'development'}, function(cache, pkgCache) {
    return browserify(entry, {
      cache:         cache,
      packageCache:  pkgCache,
      extensions:    ['.jsx'],
      noParse:       [],
      debug:         env == 'development',
      fullPaths:     env == 'development'
    })
      .transform(babelify)
      .transform('envify', {global: true});
  });
}

var UGLIFY_CMD = require.resolve('uglify-js/bin/uglifyjs');

function uglify() {
  return SpawnStream(UGLIFY_CMD, [
    '--compress',
    '--mangle',
    '--screw-ie8'
  ]);
}

var main = createBundle(require.resolve('../bundles//default.jsx'));

module.exports = {
  "/bundles/default.js": function() {
    var b = main();

    if (env !== 'development') {
      b.plugin(collapser);
    }

    var stream = b.bundle();

    if (env !== 'development') {
      return stream.pipe(uglify());
    }

    return stream
  }
};

Remove tree.js from browserify as it is actually imported via npm


'use babel';

/* eslint-disable no-multi-str, prefer-const, func-names */
let linkPaths;
const regex = new RegExp('\
((?:\\w:)?/?\
(?:[-\\w.]+/)*[-\\w.]+)\
:(\\d+)\
(?::(\\d+))?\
', 'g');
const template = '$&';

export default linkPaths = lines => lines.replace(regex, template);

linkPaths.listen = parentView =>
  parentView.on('click', '.-linked-path', function () {
    const el = this;
    let { path, line, column } = el.dataset;
    line = Number(line) - 1;
    // column number is optional
    column = column ? Number(column) - 1 : 0;

    atom.workspace.open(path, {
      initialLine: line,
      initialColumn: column,
    });
  });

'use babel';

/* eslint-disable no-multi-str, prefer-const, func-names */
let linkPaths;
const regex = new RegExp('((?:\\w:)?/?(?:[-\\w.]+/)*[-\\w.]+):(\\d+)(?::(\\d+))?', 'g');
// ((?:\w:)?/?            # Prefix of the path either '/' or 'C:/' (optional)
// (?:[-\w.]+/)*[-\w.]+)  # The path of the file some/file/path.ext
// :(\d+)                 # Line number prefixed with a colon
// (?::(\d+))?            # Column number prefixed with a colon (optional)

const template = '$&';

export default linkPaths = lines => lines.replace(regex, template);

linkPaths.listen = parentView =>
  parentView.on('click', '.-linked-path', function () {
    const el = this;
    let { path, line, column } = el.dataset;
    line = Number(line) - 1;
    // column number is optional
    column = column ? Number(column) - 1 : 0;

    atom.workspace.open(path, {
      initialLine: line,
      initialColumn: column,
    });
  });

Add comments lost by converting to JS


/**
  Resource Middleware
  @description main definition of middleware
  @exports @default {function} remoteResourceMiddleware
**/

const remoteResourceMiddleware = () => {};

export default remoteResourceMiddleware;

/**
  Resource Middleware
  @description main definition of middleware
  @exports @default {function} remoteResourceMiddleware
**/

/* eslint no-unused-vars:0 */
import fetch from 'isomorphic-fetch';
import RemoteResource from './RemoteResource';
import * as utils from './utils';

/**
  @name remoteResourceMiddleware
  @desc provides a function that can be used to configure the middleware's
    behavior, returning valid Redux middleware
  @param {object} conf
  @param {object} injectedHeaders headers to be injected on every outgoing req
  @param {object} statusActions HTTP Status codes w/ corresponding types
    or functions that will be emitted when the status code is received
  @returns {function} ReduxMiddleware
**/
export default function remoteResourceMiddleware(conf) {
  return store => next => action => {
    // if we don't find our symbol don't even bother
    if (action.hasOwnProperty && !action.hasOwnProperty(RemoteResource))
      return next(action);

    const callOpts = action[RemoteResource];
    store.dispatch(action);
  };
}

/**
  @private
  @name cacheLookup
  @desc consults the given state cache mapping to see if we already have a value
    note that this will *not* run when using actionable HTTP methods like POST
  @param {string} method HTTP verb, used to determine if we should cache
  @param {function} cacheMapping
  @param {boolean} nocache
  @param {function} emitSuccessOnCacheHit
  @returns {Promise<boolean>} result

  @TODO allow `cacheMapping` to return a value that will be supplied to the
    success event if `emitSuccessOnCacheHit` is true after the whole thing
    short circuits
**/
function cacheLookup(state, { method, cacheMapping, nocache }) {
  if (!utils.isCacheableRequest(method) || !cacheMapping || nocache)
    return Promise.resolve(false);

  return Promise.resolve(cacheMapping(state));
}

Add documentation & basic cache lookup function


var walk = require('walk');
var request = require('request');

var logger = require('./logger');
var prepare = require('./prepare');

// walk the filesystem from . to find directories that contain a _deconst.json file.
var options = {
  followLinks: false,
};

walker = walk.walk(".", options);

walker.on('directories', function (root, stats, callback) {
  logger.debug('Traversing directories: %s', root);

  // Don't traverse into dot or common build directories.
  for (var i = stats.length; i--; i >= 0) {
    var name = stats[i].name;
    if (/^\./.test(name) || name === '_build' || name === '_site') {
      stats.splice(i, 1);
    }
  }

  callback();
});

walker.on('files', function (root, stats, callback) {
  var hasContent = stats.some(function (each) {
    return each.name === '_deconst.json';
  });

  if (hasContent) {
    logger.info('Deconst content directory: %s', root);

    prepare.prepare(root, callback);
  } else {
    callback();
  }
});

walker.on('errors', function (root, stats, callback) {
  logger.error('Error walking %s', root, {
    errors: stats.map(function (e) { return e.error; })
  });

  callback();
});

walker.on('end', function () {
  logger.debug('Walk completed');
});

var walk = require('walk');
var request = require('request');

var logger = require('./logger');
var prepare = require('./prepare');

prepare.connect();

// walk the filesystem from . to find directories that contain a _deconst.json file.
var options = {
  followLinks: false,
};

walker = walk.walk(".", options);

walker.on('directories', function (root, stats, callback) {
  logger.debug('Traversing directories: %s', root);

  // Don't traverse into dot or common build directories.
  for (var i = stats.length; i--; i >= 0) {
    var name = stats[i].name;
    if (/^\./.test(name) || name === '_build' || name === '_site') {
      stats.splice(i, 1);
    }
  }

  callback();
});

walker.on('files', function (root, stats, callback) {
  var hasContent = stats.some(function (each) {
    return each.name === '_deconst.json';
  });

  if (hasContent) {
    logger.info('Deconst content directory: %s', root);

    prepare.prepare(root, callback);
  } else {
    callback();
  }
});

walker.on('errors', function (root, stats, callback) {
  logger.error('Error walking %s', root, {
    errors: stats.map(function (e) { return e.error; })
  });

  callback();
});

walker.on('end', function () {
  logger.debug('Walk completed');
});

Connect to Docker before walking.


var express = require('express');
var router = express.Router();

db = require('../queries');

router.get('/api/todos', db.getAllTodos);
router.get('/api/todos/:id', db.getTodo);
router.post('/api/todos', db.addTodo);
router.put('/api/todos/:id', db.updateTodo);
router.delete('/api/todos/:id', db.removeTodo);

module.exports = router;

var express = require('express');
var router = express.Router();

db = require('../queries');

router.use(express.static('public'));
router.get('/api/todos', db.getAllTodos);
router.get('/api/todos/:id', db.getTodo);
router.post('/api/todos', db.addTodo);
router.put('/api/todos/:id', db.updateTodo);
router.delete('/api/todos/:id', db.removeTodo);

module.exports = router;

Add static method in order to serve pages on /public


var express = require('express');
var router = express.Router();
var User  = require('./../app/models/user');

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

router.post('/checkUser', function(req, res, done) {
  console.log(req.body,'req..body');
  var currentUser = req.body.username;
  // check DB to see if current user has stripe information
  new User({username: currentUser})
    .fetch()
    .then(function(user){
      console.log('user',user);
      if (user.attributes.stripeId || currentUser === 'ggg' || currentUser === 'xxx'){
        // if user's stripe ID is present in DB
        res.json({hasStripeId: true});
      } else {
        console.log('StripeId not found for user');
        res.json({hasStripeId: false});
      }
    });
});

module.exports = router;

var express = require('express');
var router = express.Router();
var User  = require('./../app/models/user');

/* GET users listing. */
//router.get('/', function(req, res, next) {
//  res.send('respond with a resource');
//});

router.post('/accountinfo', function(req, res, done) {
  var currentUser = req.body.username;
  new User({username: currentUser})
    .fetch()
    .then(function(user){
      console.log('user',user);
      res.json(user);
    });
});

router.post('/accountupdate', function(req, res, done) {
  console.log('updating account');
  var currentUser = req.body.username;
  var data = req.body;
  new User({username: currentUser})
    .fetch()
    .then(function(user) {
      console.log('data:',data);
      user.save(data)
        .then(function() {
          res.end('updated');
        });
    });
});

// Deprecated?
router.post('/checkUser', function(req, res, done) {
  console.log(req.body,'req..body');
  var currentUser = req.body.username;
  // check DB to see if current user has stripe information
  new User({username: currentUser})
    .fetch()
    .then(function(user){
      console.log('user',user);
      if (user.attributes.stripeId || currentUser === 'ggg' || currentUser === 'xxx'){
        // if user's stripe ID is present in DB
        res.json({hasStripeId: true});
      } else {
        console.log('StripeId not found for user');
        res.json({hasStripeId: false});
      }
    });
});

module.exports = router;

Add two function for account panel


var app = require('express')();
var bodyParser = require('body-parser');
var cors = require('cors');
var http = require('http').Server(app);
var io = require('socket.io')(http);

var state = {};

app.use(bodyParser.json());
app.use(cors());

app.get('/', function(req, res) {
	res.send(JSON.stringify(state));
});

app.post('/', function(req, res) {
	console.log(req.body);
	state = req.body;
});

io.on('connection', function(socket) {
	console.log('WebSockets connection started');
	socket.on('map sync', function(msg) {
		console.log("map sync triggered with: " + JSON.stringify(msg));
		socket.broadcast.emit('map sync', msg);
	});
});

http.listen(3000, function(){
	console.log('listening on *:3000');
});

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var cors = require('cors');
var http = require('http').Server(app);
var io = require('socket.io')(http);

var state = {};

app.use(bodyParser.json());
app.use(cors());

var parentDir = __dirname.substring(0, __dirname.lastIndexOf('/'));
app.use('/play', express.static(parentDir + '/www'));

app.get('/', function(req, res) {
	res.send(JSON.stringify(state));
});

app.post('/', function(req, res) {
	console.log(req.body);
	state = req.body;
});

io.on('connection', function(socket) {
	console.log('WebSockets connection started');
	socket.on('map sync', function(msg) {
		console.log("map sync triggered with: " + JSON.stringify(msg));
		socket.broadcast.emit('map sync', msg);
	});
});

http.listen(3000, function(){
	console.log('listening on *:3000');
});

Set up client app files to be served by the server