<commit_before>let interpreter = require('./interpreter');
let fromNow = require('./from-now');
let ExtendableError = require('es6-error');

class TemplateError extends ExtendableError {
  constructor(message) {
    super(message);
    this.message = message;
    this.name = 'TemplateError';
  }
}

let isString = (expr) => typeof expr === 'string';
let isNumber = (expr) => typeof expr === 'number';
let isBool = (expr) => typeof expr === 'boolean';
let isArray = (expr) => expr instanceof Array;
let isObject = (expr) => expr instanceof Object;

let jsonTemplateError = (msg, template) => new TemplateError(msg + JSON.stringify(template, null, '\t'));

let interpolate = (string, context) => {
  return string.replace(/\${([^}]*)}/g, (text, expr) => {
    let v = interpreter.parse(expr, context);
    if (v instanceof Array || v instanceof Object) {
      throw new TemplateError('Cannot interpolate objects/arrays: '
        + text + ' <-- ' + expr);
    }
    return v.toString();
  });
};

let deleteMarker = {};

let constructs = {};

constructs.$eval = (template, context) => {
  if (!isString(template['$eval'])) {
    throw jsonTemplateError('$eval can evaluate string expressions only\n', template);
  }
  return interpreter.parse(template['$eval'], context);
};

constructs.$fromNow = (template, context) => {
  if (!isString(template['$fromNow'])) {
    throw jsonTemplateError('$fromNow can evaluate string expressions only\n', template);
  }
  return fromNow(template['$fromNow']);
};

constructs.$if = (template, context) => {
  if (!isString(template['$if'])) {
    throw jsonTemplateError('$if can evaluate string expressions only\n', template);
  }
  if (interpreter.parse(template['$if'], context)) {
    return template.hasOwnProperty('then') ? render(template.then, context) : deleteMarker;
  }
  return template.hasOwnProperty('else') ? render(template.else, context) : deleteMarker;
};

constructs.$switch = (template, context) => {
  if (!isString(template['$switch'])) {
    throw jsonTemplateError('$switch can evaluate string expressions only\n', template);
  }
  let c = interpreter.parse(template['$switch'], context);
  return template.hasOwnProperty(c) ? render(template[c], context) : deleteMarker;
};

constructs.$json = (template, context) => {
  return JSON.stringify(render(template['$json'], context));
};

constructs.$reverse = (template, context) => {
  let value = render(template['$reverse'], context);

  if (!isArray(value) && !isArray(template['$reverse'])) {
    throw jsonTemplateError('$reverse value must evaluate to an array\n', template);
  }

  if (!isArray(value)) {
    throw jsonTemplateError('$reverse requires array as value\n', template);
  }
  return value.reverse();
};

constructs.$map = (template, context) => {
  let value = render(template['$map'], context);
  if (!isArray(value)) {
    throw jsonTemplateError('$map requires array as value\n', template);
  }

  if (Object.keys(template).length !== 2) {
    throw jsonTemplateError('$map requires cannot have more than two properties\n', template);
  }

  let eachKey = Object.keys(template).filter(k => k !== '$map')[0];
  let match = /^each\(([a-zA-Z_][a-zA-Z0-9_]*)\)$/.exec(eachKey);
  if (!match) {
    throw jsonTemplateError('$map requires each(identifier) syntax\n', template);
  }

  let x = match[1];
  let each = template[eachKey];

  return value.map(v => render(each, Object.assign({}, context, {[x]: v})))
              .filter(v => v !== deleteMarker);

};

constructs.$sort = (template, context) => {
  let value = render(template['$sort'], context);
  if (!isArray(value)) {
    throw jsonTemplateError('$sort requires array as value\n', template);
  }

  let byKey = Object.keys(template).filter(k => k !== '$sort')[0];
  let match = /^by\(([a-zA-Z_][a-zA-Z0-9_]*)\)$/.exec(byKey);
  if (!match) {
    let count = value.filter(v => isArray(v) || isObject(v)).length;
    if (count > 0) {
      throw jsonTemplateError('$sort requires by(identifier) for sorting arrays of objects/arrays\n', template);
    }
    return value.sort();
  }

  let x = match[1];
  let by = template[byKey];
  let contextClone = Object.assign({}, context);

  return value.sort((left, right) => {
    contextClone[x] = left;
    left = render(by, contextClone);
    contextClone[x] = right;
    right = render(by, contextClone);
    if (left <= right) {
      return false;
    } else if (left > right) {
      return true;
    }
  });
};

let render = (template, context) => {
  if (isNumber(template) || isBool(template)) {
    return template;
  }
  if (isString(template)) {
    return interpolate(template, context);
  }
  if (isArray(template)) {
    return template.map((v) => render(v, context)).filter((v) => v !== deleteMarker);
  }

  let matches = Object.keys(constructs).filter(c => template.hasOwnProperty(c));
  if (matches.length > 1) {
    throw jsonTemplateError('only one construct allowed\n', template);
  }
  if (matches.length === 1) {
    return constructs[matches[0]](template, context);
  }

  for (let construct of Object.keys(constructs)) {
    if (template.hasOwnProperty(construct)) {
      return constructs[construct](template, context);
    }
  }

  // clone object
  let result = {};
  for (let key of Object.keys(template)) {
    let value = render(template[key], context);
    if (value !== deleteMarker) {
      result[interpolate(key, context)] = value;
    }
  }
  return result;
};

module.exports = (template, context = {}) => {
  let result = render(template, context);
  if (result === deleteMarker) {
    return undefined;
  }
  return result;
};
<commit_msg>$sort refactored<commit_after>let interpreter = require('./interpreter');
let fromNow = require('./from-now');
let ExtendableError = require('es6-error');

class TemplateError extends ExtendableError {
  constructor(message) {
    super(message);
    this.message = message;
    this.name = 'TemplateError';
  }
}

let isString = (expr) => typeof expr === 'string';
let isNumber = (expr) => typeof expr === 'number';
let isBool = (expr) => typeof expr === 'boolean';
let isArray = (expr) => expr instanceof Array;
let isObject = (expr) => expr instanceof Object;

let jsonTemplateError = (msg, template) => new TemplateError(msg + JSON.stringify(template, null, '\t'));

let interpolate = (string, context) => {
  return string.replace(/\${([^}]*)}/g, (text, expr) => {
    let v = interpreter.parse(expr, context);
    if (v instanceof Array || v instanceof Object) {
      throw new TemplateError('Cannot interpolate objects/arrays: '
        + text + ' <-- ' + expr);
    }
    return v.toString();
  });
};

let deleteMarker = {};

let constructs = {};

constructs.$eval = (template, context) => {
  if (!isString(template['$eval'])) {
    throw jsonTemplateError('$eval can evaluate string expressions only\n', template);
  }
  return interpreter.parse(template['$eval'], context);
};

constructs.$fromNow = (template, context) => {
  if (!isString(template['$fromNow'])) {
    throw jsonTemplateError('$fromNow can evaluate string expressions only\n', template);
  }
  return fromNow(template['$fromNow']);
};

constructs.$if = (template, context) => {
  if (!isString(template['$if'])) {
    throw jsonTemplateError('$if can evaluate string expressions only\n', template);
  }
  if (interpreter.parse(template['$if'], context)) {
    return template.hasOwnProperty('then') ? render(template.then, context) : deleteMarker;
  }
  return template.hasOwnProperty('else') ? render(template.else, context) : deleteMarker;
};

constructs.$switch = (template, context) => {
  if (!isString(template['$switch'])) {
    throw jsonTemplateError('$switch can evaluate string expressions only\n', template);
  }
  let c = interpreter.parse(template['$switch'], context);
  return template.hasOwnProperty(c) ? render(template[c], context) : deleteMarker;
};

constructs.$json = (template, context) => {
  return JSON.stringify(render(template['$json'], context));
};

constructs.$reverse = (template, context) => {
  let value = render(template['$reverse'], context);

  if (!isArray(value) && !isArray(template['$reverse'])) {
    throw jsonTemplateError('$reverse value must evaluate to an array\n', template);
  }

  if (!isArray(value)) {
    throw jsonTemplateError('$reverse requires array as value\n', template);
  }
  return value.reverse();
};

constructs.$map = (template, context) => {
  let value = render(template['$map'], context);
  if (!isArray(value)) {
    throw jsonTemplateError('$map requires array as value\n', template);
  }

  if (Object.keys(template).length !== 2) {
    throw jsonTemplateError('$map requires cannot have more than two properties\n', template);
  }

  let eachKey = Object.keys(template).filter(k => k !== '$map')[0];
  let match = /^each\(([a-zA-Z_][a-zA-Z0-9_]*)\)$/.exec(eachKey);
  if (!match) {
    throw jsonTemplateError('$map requires each(identifier) syntax\n', template);
  }

  let x = match[1];
  let each = template[eachKey];

  return value.map(v => render(each, Object.assign({}, context, {[x]: v})))
              .filter(v => v !== deleteMarker);

};

constructs.$sort = (template, context) => {
  let value = render(template['$sort'], context);
  if (!isArray(value)) {
    throw jsonTemplateError('$sort requires array as value\n', template);
  }

  let byKey = Object.keys(template).filter(k => k !== '$sort')[0];
  let match = /^by\(([a-zA-Z_][a-zA-Z0-9_]*)\)$/.exec(byKey);
  if (!match) {
    let needBy = value.some(v => isArray(v) || isObject(v)).length;
    if (needBy) {
      throw jsonTemplateError('$sort requires by(identifier) for sorting arrays of objects/arrays\n', template);
    }
    return value.sort();
  }

  let x = match[1];
  let by = template[byKey];
  let contextClone = Object.assign({}, context);

  return value.sort((left, right) => {
    contextClone[x] = left;
    left = render(by, contextClone);
    contextClone[x] = right;
    right = render(by, contextClone);
    if (left <= right) {
      return false;
    } else if (left > right) {
      return true;
    }
  });
};

let render = (template, context) => {
  if (isNumber(template) || isBool(template)) {
    return template;
  }
  if (isString(template)) {
    return interpolate(template, context);
  }
  if (isArray(template)) {
    return template.map((v) => render(v, context)).filter((v) => v !== deleteMarker);
  }

  let matches = Object.keys(constructs).filter(c => template.hasOwnProperty(c));
  if (matches.length > 1) {
    throw jsonTemplateError('only one construct allowed\n', template);
  }
  if (matches.length === 1) {
    return constructs[matches[0]](template, context);
  }

  for (let construct of Object.keys(constructs)) {
    if (template.hasOwnProperty(construct)) {
      return constructs[construct](template, context);
    }
  }

  // clone object
  let result = {};
  for (let key of Object.keys(template)) {
    let value = render(template[key], context);
    if (value !== deleteMarker) {
      result[interpolate(key, context)] = value;
    }
  }
  return result;
};

module.exports = (template, context = {}) => {
  let result = render(template, context);
  if (result === deleteMarker) {
    return undefined;
  }
  return result;
};
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';

const path = require('path');
const util = require('util');
const lmdb = require('../node-lmdb');

// LMDB
var dbe = new lmdb.Env();
dbe.open({
	path: path.resolve(process.cwd(), '../data/db/'),
	mapSize: 1 * 1024 * 1024 * 1024,	// 1 GiB
	maxDbs: 8
});
const dbs = {};
const names = ['users', 'tweets', 'userdates', 'otherdates', 'favdates'];
var txn, cur, key, val, writer, prefix = '';

// Open dbs
for (let name of names) {
	dbs[name] = dbe.openDbi({name, create: true});
}

// TEMP
// Print db stats to console
txn = dbe.beginTxn({readOnly: true});
for (let db of names) {
	// console.log(`\nDB stats for ${db}:`);
	// console.dir(dbs[db].stat(txn));
	process.stderr.write(`\nDB stats for ${db}:\n`);
	process.stderr.write(util.inspect(dbs[db].stat(txn), {colors:true}) + '\n');
}
txn.commit();

// Output leading '['
process.stdout.write('[\n');
// Output leading log summary

// Output users
txn = dbe.beginTxn({readOnly: true});
cur = new lmdb.Cursor(txn, dbs.users);

writer = (k, v) => writefn('user', JSON.parse(v.toString()));

for (key = cur.goToFirst(); key; key = cur.goToNext()) {
	cur.getCurrentBinaryUnsafe(writer);
}

cur.close();
txn.commit();

// Output favdates
txn = dbe.beginTxn({readOnly: true});
cur = new lmdb.Cursor(txn, dbs.favdates);

writer = (k, v) => writefn('favorite', JSON.parse(v.toString()));

for (key = cur.goToFirst(); key; key = cur.goToNext()) {
	cur.getCurrentBinaryUnsafe(writer);
}

cur.close();
txn.commit();

// Output user tweets
txn = dbe.beginTxn({readOnly: true});
cur = new lmdb.Cursor(txn, dbs.userdates);

writer = (k, v) => {
	// Get tweet from other db
	let t = txn.getBinaryUnsafe(dbs.tweets, v);
	// Parse and write
	writefn('user_tweet', JSON.parse(t.toString()))
};

for (key = cur.goToFirst(); key; key = cur.goToNext()) {
	cur.getCurrentString(writer);
}

cur.close();
txn.commit();

// Output other tweets
txn = dbe.beginTxn({readOnly: true});
cur = new lmdb.Cursor(txn, dbs.otherdates);

writer = (k, v) => {
	// Get tweet from other db
	let t = txn.getBinaryUnsafe(dbs.tweets, v);
	// Parse and write
	writefn('other_tweet', JSON.parse(t.toString()))
};

for (key = cur.goToFirst(); key; key = cur.goToNext()) {
	cur.getCurrentString(writer);
}

cur.close();
txn.commit();

// Output trailing ']'
process.stdout.write('\n]\n');

// Close dbs
for (let name of names) {
	dbs[name].close();
}
dbe.close();

function writefn (type, data) {
	process.stdout.write(prefix + JSON.stringify({type, data}, null, 2));
	if (!prefix) {
		prefix = ',\n';
	}
}
<commit_msg>Moved fav output to after tweets in db-dump.js<commit_after>#!/usr/bin/env node
'use strict';

const path = require('path');
const util = require('util');
const lmdb = require('../node-lmdb');

// LMDB
var dbe = new lmdb.Env();
dbe.open({
	path: path.resolve(process.cwd(), '../data/db/'),
	mapSize: 1 * 1024 * 1024 * 1024,	// 1 GiB
	maxDbs: 8
});
const dbs = {};
const names = ['users', 'tweets', 'userdates', 'otherdates', 'favdates'];
var txn, cur, key, val, writer, prefix = '';

// Open dbs
for (let name of names) {
	dbs[name] = dbe.openDbi({name, create: true});
}

// TEMP
// Print db stats to console
txn = dbe.beginTxn({readOnly: true});
for (let db of names) {
	// console.log(`\nDB stats for ${db}:`);
	// console.dir(dbs[db].stat(txn));
	process.stderr.write(`\nDB stats for ${db}:\n`);
	process.stderr.write(util.inspect(dbs[db].stat(txn), {colors:true}) + '\n');
}
txn.commit();

// Output leading '['
process.stdout.write('[\n');
// Output leading log summary

// Output users
txn = dbe.beginTxn({readOnly: true});
cur = new lmdb.Cursor(txn, dbs.users);

writer = (k, v) => writefn('user', JSON.parse(v.toString()));

for (key = cur.goToFirst(); key; key = cur.goToNext()) {
	cur.getCurrentBinaryUnsafe(writer);
}

cur.close();
txn.commit();

// Output user tweets
txn = dbe.beginTxn({readOnly: true});
cur = new lmdb.Cursor(txn, dbs.userdates);

writer = (k, v) => {
	// Get tweet from other db
	let t = txn.getBinaryUnsafe(dbs.tweets, v);
	// Parse and write
	writefn('user_tweet', JSON.parse(t.toString()))
};

for (key = cur.goToFirst(); key; key = cur.goToNext()) {
	cur.getCurrentString(writer);
}

cur.close();
txn.commit();

// Output other tweets
txn = dbe.beginTxn({readOnly: true});
cur = new lmdb.Cursor(txn, dbs.otherdates);

writer = (k, v) => {
	// Get tweet from other db
	let t = txn.getBinaryUnsafe(dbs.tweets, v);
	// Parse and write
	writefn('other_tweet', JSON.parse(t.toString()))
};

for (key = cur.goToFirst(); key; key = cur.goToNext()) {
	cur.getCurrentString(writer);
}

cur.close();
txn.commit();

// Output favdates
txn = dbe.beginTxn({readOnly: true});
cur = new lmdb.Cursor(txn, dbs.favdates);

writer = (k, v) => writefn('favorite', JSON.parse(v.toString()));

for (key = cur.goToFirst(); key; key = cur.goToNext()) {
	cur.getCurrentBinaryUnsafe(writer);
}

cur.close();
txn.commit();

// Output trailing ']'
process.stdout.write('\n]\n');

// Close dbs
for (let name of names) {
	dbs[name].close();
}
dbe.close();

function writefn (type, data) {
	process.stdout.write(prefix + JSON.stringify({type, data}, null, 2));
	if (!prefix) {
		prefix = ',\n';
	}
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';

const propTypes = {
  className: PropTypes.string,
  onloadCallbackName: PropTypes.string,
  elementID: PropTypes.string,
  onloadCallback: PropTypes.func,
  verifyCallback: PropTypes.func,
  expiredCallback: PropTypes.func,
  render: PropTypes.string,
  sitekey: PropTypes.string,
  theme: PropTypes.string,
  type: PropTypes.string,
  verifyCallbackName: PropTypes.string,
  expiredCallbackName: PropTypes.string,
  size: PropTypes.string,
  tabindex: PropTypes.string,
  hl: PropTypes.string,
};

const defaultProps = {
  elementID: 'g-recaptcha',
  onloadCallback: undefined,
  onloadCallbackName: 'onloadCallback',
  verifyCallback: undefined,
  verifyCallbackName: 'verifyCallback',
  expiredCallback: undefined,
  expiredCallbackName: 'expiredCallback',
  render: 'onload',
  theme: 'light',
  type: 'image',
  size: 'normal',
  tabindex: '0',
  hl: 'en',
};

const isReady = () => typeof window !== 'undefined' && typeof window.grecaptcha !== 'undefined';

let readyCheck;

export default class Recaptcha extends Component {

  constructor(props) {
    super(props);
    this._renderGrecaptcha = this._renderGrecaptcha.bind(this);
    this.reset = this.reset.bind(this);
    this.state = {
      ready: isReady(),
      widget: null,
    };

    if (!this.state.ready) {
      readyCheck = setInterval(this._updateReadyState.bind(this), 1000);
    }
  }

  componentDidMount() {
    if (this.state.ready) {
      this._renderGrecaptcha();
    }
  }

  componentDidUpdate(prevProps, prevState) {
    const { render, onloadCallback } = this.props;

    if (render === 'explicit' && onloadCallback && this.state.ready && !prevState.ready) {
      this._renderGrecaptcha();
    }
  }

  componentWillUnmount() {
    clearInterval(readyCheck);
  }

  reset() {
    const { ready, widget } = this.state;
    if (ready && widget !== null) {
      grecaptcha.reset(widget);
    }
  }

  _updateReadyState() {
    if (isReady()) {
      this.setState({
        ready: true,
      });

      clearInterval(readyCheck);
    }
  }

  _renderGrecaptcha() {
    this.state.widget = grecaptcha.render(this.props.elementID, {
      sitekey: this.props.sitekey,
      callback: (this.props.verifyCallback) ? this.props.verifyCallback : undefined,
      theme: this.props.theme,
      type: this.props.type,
      size: this.props.size,
      tabindex: this.props.tabindex,
      hl: this.props.hl,
      'expired-callback': (this.props.expiredCallback) ? this.props.expiredCallback : undefined,
    });

    this.props.onloadCallback();
  }

  render() {
    if (this.props.render === 'explicit' && this.props.onloadCallback) {
      return (

      );
    }

    return (

    );
  }
}

Recaptcha.propTypes = propTypes;
Recaptcha.defaultProps = defaultProps;
<commit_msg>fix this.props.onloadCallback is not a function (#202)<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';

const propTypes = {
  className: PropTypes.string,
  onloadCallbackName: PropTypes.string,
  elementID: PropTypes.string,
  onloadCallback: PropTypes.func,
  verifyCallback: PropTypes.func,
  expiredCallback: PropTypes.func,
  render: PropTypes.string,
  sitekey: PropTypes.string,
  theme: PropTypes.string,
  type: PropTypes.string,
  verifyCallbackName: PropTypes.string,
  expiredCallbackName: PropTypes.string,
  size: PropTypes.string,
  tabindex: PropTypes.string,
  hl: PropTypes.string,
};

const defaultProps = {
  elementID: 'g-recaptcha',
  onloadCallback: undefined,
  onloadCallbackName: 'onloadCallback',
  verifyCallback: undefined,
  verifyCallbackName: 'verifyCallback',
  expiredCallback: undefined,
  expiredCallbackName: 'expiredCallback',
  render: 'onload',
  theme: 'light',
  type: 'image',
  size: 'normal',
  tabindex: '0',
  hl: 'en',
};

const isReady = () => typeof window !== 'undefined' && typeof window.grecaptcha !== 'undefined';

let readyCheck;

export default class Recaptcha extends Component {

  constructor(props) {
    super(props);
    this._renderGrecaptcha = this._renderGrecaptcha.bind(this);
    this.reset = this.reset.bind(this);
    this.state = {
      ready: isReady(),
      widget: null,
    };

    if (!this.state.ready) {
      readyCheck = setInterval(this._updateReadyState.bind(this), 1000);
    }
  }

  componentDidMount() {
    if (this.state.ready) {
      this._renderGrecaptcha();
    }
  }

  componentDidUpdate(prevProps, prevState) {
    const { render, onloadCallback } = this.props;

    if (render === 'explicit' && onloadCallback && this.state.ready && !prevState.ready) {
      this._renderGrecaptcha();
    }
  }

  componentWillUnmount() {
    clearInterval(readyCheck);
  }

  reset() {
    const { ready, widget } = this.state;
    if (ready && widget !== null) {
      grecaptcha.reset(widget);
    }
  }

  _updateReadyState() {
    if (isReady()) {
      this.setState({
        ready: true,
      });

      clearInterval(readyCheck);
    }
  }

  _renderGrecaptcha() {
    this.state.widget = grecaptcha.render(this.props.elementID, {
      sitekey: this.props.sitekey,
      callback: (this.props.verifyCallback) ? this.props.verifyCallback : undefined,
      theme: this.props.theme,
      type: this.props.type,
      size: this.props.size,
      tabindex: this.props.tabindex,
      hl: this.props.hl,
      'expired-callback': (this.props.expiredCallback) ? this.props.expiredCallback : undefined,
    });

    if (this.props.onloadCallback) {
      this.props.onloadCallback();
    }
  }

  render() {
    if (this.props.render === 'explicit' && this.props.onloadCallback) {
      return (

      );
    }

    return (

    );
  }
}

Recaptcha.propTypes = propTypes;
Recaptcha.defaultProps = defaultProps;
<|endoftext|>


<commit_before>//index.js
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import _ from 'lodash'

import './styles/foundation.min.css'
import './styles/core.scss'

import reducer from './reducers'
import {setConfig} from './reducers/setConfig'

import XocesWidget from './widgets/XocesWidget';
import ChordWidget from './widgets/ChordWidget';
import TreeWidget from './widgets/TreeWidget';
import graphProvider from './components/graph'

let store = createStore(reducer)

module.exports = {
  config: (config) => {
  },

  widgets: {
     XocesWidget: {
       new: (config) => {
         let uid = _.uniqueId('xoces_widget_');

         return {
           render(arg) {
             let container = _getContainer(arg.container);
             let props = _.assign({}, config, arg, {
               __widgetType: 'XocesWidget'
             });

             store.dispatch(setConfig(props))

             ReactDOM.render(
               <Provider store={store}>
                 <XocesWidget {...props}/>
               </Provider>,
               container,
               arg.callback
             )
           }
         }
        }
     },
     ChordWidget: {
       new: (config) => {
         let uid = _.uniqueId('xoces_chord_widget_');

         return {
           render(arg) {
             let container = _getContainer(arg.container);
             let props = _.assign({}, config, arg, {
               __widgetType: 'ChordWidget'
             });

             store.dispatch(setConfig(props))

             ReactDOM.render(
               <Provider store={store}>
                 <ChordWidget {...props}/>
               </Provider>,
               container,
               arg.callback
             )
           }
         }
      }
     },
     TreeWidget: {
       new: (config) => {
         let uid = _.uniqueId('xoces_tree_widget_');

         return {
           render(arg) {
             let container = _getContainer(arg.container);
             let props = _.assign({}, config, arg, {
               __widgetType: 'TreeWidget'
             });

             store.dispatch(setConfig(props))

             ReactDOM.render(
               <Provider store={store}>
                 <TreeWidget {...props}/>
               </Provider>,
               container,
               arg.callback
             )
           }
         }
        }
     }
   },
   libs: {
     graphProvider
   },
}

function _getContainer(container) {
  if (_.isString(container)) {
    return document.getElementById(container);
  } else if (container) {
    return container;
  }

  return container = document.body;
}
<commit_msg>exposed TreeWidget<commit_after>//index.js
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import _ from 'lodash'

import './styles/foundation.min.css'
import './styles/core.scss'

import reducer from './reducers'
import {setConfig, setConfigTree} from './reducers/setConfig'

import XocesWidget from './widgets/XocesWidget';
import ChordWidget from './widgets/ChordWidget';
import TreeWidget from './widgets/TreeWidget';
import graphProvider from './components/graph'

let store = createStore(reducer)

module.exports = {
  config: (config) => {
  },

  widgets: {
     XocesWidget: {
       new: (config) => {
         let uid = _.uniqueId('xoces_widget_');

         return {
           render(arg) {
             let container = _getContainer(arg.container);
             let props = _.assign({}, config, arg, {
               __widgetType: 'XocesWidget'
             });

             store.dispatch(setConfig(props))

             ReactDOM.render(
               <Provider store={store}>
                 <XocesWidget {...props}/>
               </Provider>,
               container,
               arg.callback
             )
           }
         }
        }
     },
     ChordWidget: {
       new: (config) => {
         let uid = _.uniqueId('xoces_chord_widget_');

         return {
           render(arg) {
             let container = _getContainer(arg.container);
             let props = _.assign({}, config, arg, {
               __widgetType: 'ChordWidget'
             });

             store.dispatch(setConfig(props))

             ReactDOM.render(
               <Provider store={store}>
                 <ChordWidget {...props}/>
               </Provider>,
               container,
               arg.callback
             )
           }
         }
      }
     },
     TreeWidget: {
       new: (config) => {
         let uid = _.uniqueId('xoces_tree_widget_');

         return {
           render(arg) {
             let container = _getContainer(arg.container);
             let props = _.assign({}, config, arg, {
               __widgetType: 'TreeWidget'
             });

             store.dispatch(setConfigTree(props))

             ReactDOM.render(
               <Provider store={store}>
                 <TreeWidget {...props}/>
               </Provider>,
               container,
               arg.callback
             )
           }
         }
        }
     }
   },
   libs: {
     graphProvider
   },
}

function _getContainer(container) {
  if (_.isString(container)) {
    return document.getElementById(container);
  } else if (container) {
    return container;
  }

  return container = document.body;
}
<|endoftext|>


<commit_before>#! /usr/bin/env node

// Create a new, empty imp project, or reinitialize and existing one

var program = require("commander");
var prompt = require("cli-prompt");
var fs = require("fs");
var Spinner = require("cli-spinner").Spinner;
var ImpConfig = require("../lib/impConfig.js");

var config = new ImpConfig();
var spinner = new Spinner("Contacting the impCloud... %s");
spinner.setSpinnerString(5);
var imp;

program
    .option("-f, --force", "Overwrites existing .impconfig file")
    .option("-g, --global", "Uses your global API key and prevents a local API key from being written to .impconfig")
    .option("-k, --keep [options]", "Prevents code files from being overwritten during initialization")
    .option("-t, --title <projectName>", "Create a new project and model with the supplied name")

    .on("--help", function() {
        console.log("  Usage:");
        console.log("");
        console.log("    imp new -k\t\tAgent and device code files will not be overwritten");
        console.log("    imp new -k device\tDevice code file will not be overwritten");
        console.log("    imp new -k agent\tAgent code file will not be overwritten");
    });

program.parse(process.argv);

function apiKeyPrompt(apiKey, next) {
    if ("global" in program) {
        // If 'apiKey' isn't set in the global config, log error and return
        if (!config.getGlobal("apiKey")) {
            console.log("ERROR: Global Build API key is not set. Run 'imp setup' then try 'imp new' again");
            return;
        }

        imp = config.createImpWithConfig();

        // Use a false value to test the validity of the API key
        imp.getDevices({ "device_id" : "garbage" }, function(err, data) {
            if (err) {
                // API key is wrong, so ask for it again
                imp.apiKey = null;
                console.log("ERROR: Invalid Build API key");
                apiKeyPrompt(apiKey, next);
                return;
            }

            next();
        });

        return;
    }

    // Display/request local Build API key
    var promptText = "Build API key";
    if (apiKey) {
        promptText += " (" + apiKey + "): ";
    } else {
        promptText += ": ";
    }

    prompt(promptText, function(val) {
        if (apiKey && !val) val = apiKey;
        config.setLocal("apiKey", val);
        imp = config.createImpWithConfig();

        // Use a false value to test the API key
        imp.getDevices({ "device_id" : "garbage" }, function(err, data) {
            if (err) {
                // API key is wrong, so ask again
                imp.apiKey = null;
                console.log("ERROR: Invalid Build API key");
                apiKeyPrompt(apiKey, next);
                return;
            }

            next();
        });
    });
}

function modelPrompt(next) {
    // Ask for the project's model ID or model name
    prompt("Model ID or name: ", function(val) {
        if (!val) {
            // No name/ID provided? Ask again
            modelPrompt(next);
            return;
        }

        // Assume the user has passed in an ID - check if it exists
        spinner.start();
        imp.getModel(val, function(err, data) {
            if (!err) {
                // The user DID supply a model ID and it matches an existing one
                spinner.stop(true);
                prompt("There is an existing model, '" + data.model.name + "', with the ID you supplied. Use this? (y/n) ", function(confirm) {
                    if (confirm && confirm.toLowerCase()[0] != "y") {
                        // User doesn't want to use the existing model, so force them to choose a new name
                        modelPrompt(next);
                        return;
                    }

                    config.setLocal("modelId", data.model.id);
                    config.setLocal("modelName", data.model.name);
                    next();
                    return;
                });
            } else {
                // An error means there was no match to a model ID,
                // so perhaps a name was supplied: compare it to the list of models
                imp.getModels({ "name": val }, function(err, data) {
                    if (err) {
                        spinner.stop(true);
                        console.log("ERROR: Could not get a list of your models from the impCloud");
                        return;
                    }

                    // See if the supplied model name matches an existing one
                    var foundMatch = false;
                    for (var i = 0 ; i < data.models.length ; i++) {
                        if (data.models[i].name.toLowerCase() == val.toLowerCase()) {
                            foundMatch = true;
                            break;
                        }
                    }

                    spinner.stop(true);
                    if (foundMatch) {
                        // The user has supplied a name that already exists
                        prompt("There is an existing model, '" + data.models[i].name + "', with the ID you supplied. Use this? (y/n) ", function(confirm){
                            if (confirm && confirm.toLowerCase()[0] != "y") {
                                // User doesn't want to use the existing model,
                                // so force them to choose a new name
                                modelPrompt(next);
                                return;
                            }

                            config.setLocal("modelId", data.models[i].id);
                            config.setLocal("modelName", data.models[i].name);
                            next();
                            return;
                        });
                    } else {
                        // The user has supplied a name that doesn't exist, so
                        // create a new model with that name
                        prompt("Create model '" + val + "'? (y/n) ", function(confirm) {
                            if (confirm && confirm.toLowerCase()[0] != "y") {
                                modelPrompt(next);
                                return;
                            }

                            if (!spinner.isSpinning()) spinner.start();
                            imp.createModel(val, function(err, data) {
                                if (err) {
                                    spinner.stop(true);
                                    console.log("ERROR: Could not create model '" + data.model.name + "'");
                                    return;
                                }

                                config.setLocal("modelName", data.model.name);
                                config.setLocal("modelId", data.model.id);
                                next();
                            });

                            return;
                        });
                    }
                });
            }
        });
    });
}

function newModelPrompt(next) {
    // We have a model name, parsed as 'program.title'
    spinner.start();
    imp.getModels({ "name": program.title }, function(err, data) {
        if (err) {
            spinner.stop(true);
            console.log("ERROR: Could not get a list of your models from the impCloud");
            return;
        }

        // See if the supplied model name matches an existing one
        var foundMatch = false;
        for (var i = 0 ; i < data.models.length ; i++) {
            if (data.models[i].name.toLowerCase() == program.title.toLowerCase()) {
                foundMatch = true;
                break;
            }
        }

        if (foundMatch) {
            // The user has supplied a name that already exists
            spinner.stop(true);
            prompt("You already have a model with the name '" + data.models[i].name + "'. Use this? (y/n) ", function(confirm) {
                if (confirm && confirm.toLowerCase()[0] != "y") {
                    // User doesn't want to use the existing model, so get a new name
                    modelPrompt(next);
                    return;
                }

                config.setLocal("modelId", data.models[i].id);
                config.setLocal("modelName", data.models[i].name);
                next();
                return;
            });
        } else {
            // The user has supplied a name that doesn't exist, so
            // create a new model with that name
            imp.createModel(program.title, function(err, data) {
                if (err) {
                    spinner.stop(true);
                    console.log("ERROR: Could not create model '" + program.title + "'");
                    return;
                }

                config.setLocal("modelName", data.model.name);
                config.setLocal("modelId", data.model.id);
                next();
            });

            return;
        }
    });
}

function getDevices(next) {
    var modelId = config.getLocal("modelId");
    var modelName = config.getLocal("modelName");
    if (modelId == null) {
        next();
        return;
    }

    if (!spinner.isSpinning()) spinner.start();
    imp.getDevices({ "model_id": modelId }, function(err, data) {
        if (err) {
            spinner.stop(true);
            console.log("ERROR: Could not fetch a list of devices assigned to model '" + modelName + "'");
            next();
        }

        var devices = [];
        for (var i = 0 ; i < data.devices.length ; i++) {
            if (data.devices[i].model_id == modelId) {
                devices.push(data.devices[i].id);
            }
        }

        // Save current list of model's devices locally
        config.setLocal("devices", devices);

        // Display number of devices (if any) associated with this model
        var devicesText = devices.length == 1 ? "device" : "devices";
        var devicesLen = devices.length == 0 ? "no" : devices.length;
        spinner.stop(true);
        console.log("Found " + devicesLen + " " + devicesText + " associated with model '" + modelName + "'");
        next();
    });
}

function fileNamePrompt(next) {
    var modelName = config.getLocal("modelName");
    var baseFileName = modelName.split(" ").join("_").toLowerCase();
    var defaultDeviceFileName = config.getLocal("deviceFile") || (baseFileName + ".device.nut");
    var defaultAgentFileName = config.getLocal("agentFile") || (baseFileName + ".agent.nut");

    prompt.multi([
        {
            label: "Device code file (" + defaultDeviceFileName + ")",
            key: "deviceFile"
        },
        {
            label: "Agent code file (" + defaultAgentFileName + ")",
            key: "agentFile"
        }
    ], function(data){
        config.setLocal("deviceFile", data.deviceFile || defaultDeviceFileName);
        config.setLocal("agentFile", data.agentFile || defaultAgentFileName);
        next();
    });
}

function makeFiles() {
    var deviceCode = "# Device Code";
    var agentCode = "# Agent Code";
    var modelId = config.getLocal("modelId");
    var modelName = config.getLocal("modelName");
    var agentFile = config.getLocal("agentFile");
    var deviceFile = config.getLocal("deviceFile");

    if (!spinner.isSpinning()) spinner.stop(true);
    if (modelId != null) {
        if ("keep" in program && keep === true) {
            // Don't overwrite any saved code UNLESS files don't exist
            if (!fs.existsSync(agentFile)) fs.writeFile(agentFile, agentCode);
            if (!fs.existsSync(deviceFile)) fs.writeFile(deviceFile, deviceCode);
        } else if ("keep" in program && program.keep == "device") {
            // Only overwrite the agent code
            fs.writeFile(agentFile, agentCode);
        } else if ("keep" in program && program.keep == "agent") {
            // Only overwrite the device code
            fs.writeFile(deviceFile, deviceCode);
        } else {
            // Overwrite both agent code and device code
            fs.writeFile(deviceFile, deviceCode);
            fs.writeFile(agentFile, agentCode);
        }

        config.saveLocalConfig(function(err) {
            if (err) {
                console.log("ERROR: " + err);
                return;
            }

            console.log("Model '" + modelName + "' initialized. To add a device run: 'imp devices -a <deviceID>'");
        });
    } else {
        console.log("ERROR: Could not create model's code files");
    }
}

function finalize() {
    var deviceCode = "";
    var agentCode = "";
    var modelId = config.getLocal("modelId");
    var modelName = config.getLocal("modelName");
    var agentFile = config.getLocal("agentFile");
    var deviceFile = config.getLocal("deviceFile");

    if (!spinner.isSpinning()) spinner.start();
    if (modelId != null) {
        imp.getModelRevisions(modelId, null, function(err, data) {
            if (err) {
                spinner.stop(true);
                console.log("ERROR: Could not fetch code revisions for model '" + modelName + "'");
                return;
            }

            if (data.revisions.length == 0) {
                config.saveLocalConfig(function(err) {
                    if (err) {
                        console.log("ERROR: " + err);
                        return;
                    }

                    spinner.stop(true);
                    console.log("Model '" + modelName + "' initialized. To add a device run: 'imp devices -a <deviceID>'");
                });

                return;
            }

            imp.getModelRevision(modelId, data.revisions[0].version, function(err, data) {
                if (err) {
                    spinner.stop(true);
                    console.log("ERROR: Could not fetch the latest build for model '" + modelName + "'");
                    return;
                }

                deviceCode = data.revision.device_code;
                agentCode = data.revision.agent_code;

                if ("keep" in program && keep === true) {
                    // Don't overwrite any saved code
                } else if ("keep" in program && program.keep == "device") {
                    // Only overwrite the agent code
                    fs.writeFile(agentFile, agentCode);
                } else if ("keep" in program && program.keep == "agent") {
                    // Only overwrite the device code
                    fs.writeFile(deviceFile, deviceCode);
                } else {
                    // Overwrite both agent code and device code
                    fs.writeFile(deviceFile, deviceCode);
                    fs.writeFile(agentFile, agentCode);
                }

                config.saveLocalConfig(function(err) {
                    if (err) {
                        console.log("ERROR: " + err);
                        return;
                    }

                    spinner.stop(true);
                    console.log("Model '" + modelName + "' initialized. To add a device run: 'imp devices -a <deviceID>'");
                });
            });
        });
    } else {
        imp.createModel(modelName, function(err, data) {
            if (err) {
                spinner.stop(true);
                console.log("ERROR: Could not create model");
                return;
            }

            config.setLocal("modelId", data.model.id);

            fs.writeFile(deviceFile, deviceCode);
            fs.writeFile(agentFile, agentCode);

            config.saveLocalConfig(function(err) {
                if (err) {
                    console.log("ERROR: " + err);
                    return;
                }

                spinner.stop(true);
                console.log("Model '" + modelName + "' initialized. To add a device run: 'imp devices -a <deviceId>'");
            });
        });
    }
}

config.init(null, function() {
    // Make sure this folder doesn't already have a config file
    if (this.getLocalConfig() && !("force" in program)) {
        console.log("ERROR: .impconfig already exists. Specify '-f' to re-initialize model");
        return;
    }

    if ("title" in program) {
        // User has supplied a specific model name, so use this rather
        // than ask for one
        apiKeyPrompt(this.get("apiKey"), function() {
            newModelPrompt(function() {
                fileNamePrompt(function() {
                    makeFiles();
                });
            });
        });
    } else {
        apiKeyPrompt(this.get("apiKey"), function() {
            modelPrompt(function() {
                getDevices(function() {
                    fileNamePrompt(function() {
                        finalize();
                    });
                });
            });
        });
    }
}.bind(config));
<commit_msg>Update imp-new.js<commit_after>#! /usr/bin/env node

// Create a new, empty imp project, or reinitialize and existing one

var program = require("commander");
var prompt = require("cli-prompt");
var fs = require("fs");
var Spinner = require("cli-spinner").Spinner;
var ImpConfig = require("../lib/impConfig.js");

var config = new ImpConfig();
var spinner = new Spinner("Contacting the impCloud... %s");
spinner.setSpinnerString(5);
var imp;

program
    .option("-f, --force", "Overwrites existing .impconfig file")
    .option("-g, --global", "Uses your global API key and prevents a local API key from being written to .impconfig")
    .option("-k, --keep [options]", "Prevents code files from being overwritten during initialization")
    .option("-t, --title <projectName>", "Create a new project and model with the supplied name")

    .on("--help", function() {
        console.log("  Usage:");
        console.log("");
        console.log("    imp new -k\t\tAgent and device code files will not be overwritten");
        console.log("    imp new -k device\tDevice code file will not be overwritten");
        console.log("    imp new -k agent\tAgent code file will not be overwritten");
    });

program.parse(process.argv);

function apiKeyPrompt(apiKey, next) {
    if ("global" in program) {
        // If 'apiKey' isn't set in the global config, log error and return
        if (!config.getGlobal("apiKey")) {
            console.log("ERROR: Global Build API key is not set. Run 'imp setup' then try 'imp new' again");
            return;
        }

        imp = config.createImpWithConfig();

        // Use a false value to test the validity of the API key
        imp.getDevices({ "device_id" : "garbage" }, function(err, data) {
            if (err) {
                // API key is wrong, so ask for it again
                imp.apiKey = null;
                console.log("ERROR: Invalid Build API key");
                apiKeyPrompt(apiKey, next);
                return;
            }

            next();
        });

        return;
    }

    // Display/request local Build API key
    var promptText = "Build API key";
    if (apiKey) {
        promptText += " (" + apiKey + "): ";
    } else {
        promptText += ": ";
    }

    prompt(promptText, function(val) {
        if (apiKey && !val) val = apiKey;
        config.setLocal("apiKey", val);
        imp = config.createImpWithConfig();

        // Use a false value to test the API key
        imp.getDevices({ "device_id" : "garbage" }, function(err, data) {
            if (err) {
                // API key is wrong, so ask again
                imp.apiKey = null;
                console.log("ERROR: Invalid Build API key");
                apiKeyPrompt(apiKey, next);
                return;
            }

            next();
        });
    });
}

function modelPrompt(next) {
    // Ask for the project's model ID or model name
    prompt("Model ID or name: ", function(val) {
        if (!val) {
            // No name/ID provided? Ask again
            modelPrompt(next);
            return;
        }

        // Assume the user has passed in an ID - check if it exists
        spinner.start();
        imp.getModel(val, function(err, data) {
            if (!err) {
                // The user DID supply a model ID and it matches an existing one
                spinner.stop(true);
                prompt("There is an existing model, '" + data.model.name + "', with the ID you supplied. Use this? (y/n) ", function(confirm) {
                    if (confirm && confirm.toLowerCase()[0] != "y") {
                        // User doesn't want to use the existing model, so force them to choose a new name
                        modelPrompt(next);
                        return;
                    }

                    config.setLocal("modelId", data.model.id);
                    config.setLocal("modelName", data.model.name);
                    next();
                    return;
                });
            } else {
                // An error means there was no match to a model ID,
                // so perhaps a name was supplied: compare it to the list of models
                imp.getModels({ "name": val }, function(err, data) {
                    if (err) {
                        spinner.stop(true);
                        console.log("ERROR: Could not get a list of your models from the impCloud");
                        return;
                    }

                    // See if the supplied model name matches an existing one
                    var foundMatch = false;
                    for (var i = 0 ; i < data.models.length ; i++) {
                        if (data.models[i].name.toLowerCase() == val.toLowerCase()) {
                            foundMatch = true;
                            break;
                        }
                    }

                    spinner.stop(true);
                    if (foundMatch) {
                        // The user has supplied a name that already exists
                        prompt("There is an existing model, '" + data.models[i].name + "', with the ID you supplied. Use this? (y/n) ", function(confirm){
                            if (confirm && confirm.toLowerCase()[0] != "y") {
                                // User doesn't want to use the existing model,
                                // so force them to choose a new name
                                modelPrompt(next);
                                return;
                            }

                            config.setLocal("modelId", data.models[i].id);
                            config.setLocal("modelName", data.models[i].name);
                            next();
                            return;
                        });
                    } else {
                        // The user has supplied a name that doesn't exist, so
                        // create a new model with that name
                        prompt("Create model '" + val + "'? (y/n) ", function(confirm) {
                            if (confirm && confirm.toLowerCase()[0] != "y") {
                                modelPrompt(next);
                                return;
                            }

                            if (!spinner.isSpinning()) spinner.start();
                            imp.createModel(val, function(err, data) {
                                if (err) {
                                    spinner.stop(true);
                                    console.log("ERROR: Could not create model '" + data.model.name + "'");
                                    return;
                                }

                                config.setLocal("modelName", data.model.name);
                                config.setLocal("modelId", data.model.id);
                                next();
                            });

                            return;
                        });
                    }
                });
            }
        });
    });
}

function newModelPrompt(next) {
    // We have a model name, parsed as 'program.title'
    spinner.start();
    imp.getModels({ "name": program.title }, function(err, data) {
        if (err) {
            spinner.stop(true);
            console.log("ERROR: Could not get a list of your models from the impCloud");
            return;
        }

        // See if the supplied model name matches an existing one
        var foundMatch = false;
        for (var i = 0 ; i < data.models.length ; i++) {
            if (data.models[i].name.toLowerCase() == program.title.toLowerCase()) {
                foundMatch = true;
                break;
            }
        }

        if (foundMatch) {
            // The user has supplied a name that already exists
            spinner.stop(true);
            prompt("You already have a model with the name '" + data.models[i].name + "'. Use this? (y/n) ", function(confirm) {
                if (confirm && confirm.toLowerCase()[0] != "y") {
                    // User doesn't want to use the existing model, so get a new name
                    modelPrompt(next);
                    return;
                }

                config.setLocal("modelId", data.models[i].id);
                config.setLocal("modelName", data.models[i].name);
                next();
                return;
            });
        } else {
            // The user has supplied a name that doesn't exist, so
            // create a new model with that name
            imp.createModel(program.title, function(err, data) {
                if (err) {
                    spinner.stop(true);
                    console.log("ERROR: Could not create model '" + program.title + "'");
                    return;
                }

                config.setLocal("modelName", data.model.name);
                config.setLocal("modelId", data.model.id);
                next();
            });

            return;
        }
    });
}

function getDevices(next) {
    var modelId = config.getLocal("modelId");
    var modelName = config.getLocal("modelName");
    if (modelId == null) {
        next();
        return;
    }

    if (!spinner.isSpinning()) spinner.start();
    imp.getDevices({ "model_id": modelId }, function(err, data) {
        if (err) {
            spinner.stop(true);
            console.log("ERROR: Could not fetch a list of devices assigned to model '" + modelName + "'");
            next();
        }

        var devices = [];
        for (var i = 0 ; i < data.devices.length ; i++) {
            if (data.devices[i].model_id == modelId) {
                devices.push(data.devices[i].id);
            }
        }

        // Save current list of model's devices locally
        config.setLocal("devices", devices);

        // Display number of devices (if any) associated with this model
        var devicesText = devices.length == 1 ? "device" : "devices";
        var devicesLen = devices.length == 0 ? "no" : devices.length;
        spinner.stop(true);
        console.log("Found " + devicesLen + " " + devicesText + " associated with model '" + modelName + "'");
        next();
    });
}

function fileNamePrompt(next) {
    var modelName = config.getLocal("modelName");
    var baseFileName = modelName.split(" ").join("_").toLowerCase();
    var defaultDeviceFileName = config.getLocal("deviceFile") || (baseFileName + ".device.nut");
    var defaultAgentFileName = config.getLocal("agentFile") || (baseFileName + ".agent.nut");

    prompt.multi([
        {
            label: "Device code file (" + defaultDeviceFileName + ")",
            key: "deviceFile"
        },
        {
            label: "Agent code file (" + defaultAgentFileName + ")",
            key: "agentFile"
        }
    ], function(data){
        config.setLocal("deviceFile", data.deviceFile || defaultDeviceFileName);
        config.setLocal("agentFile", data.agentFile || defaultAgentFileName);
        next();
    });
}

function makeFiles() {
    var deviceCode = "# Device Code";
    var agentCode = "# Agent Code";
    var modelId = config.getLocal("modelId");
    var modelName = config.getLocal("modelName");
    var agentFile = config.getLocal("agentFile");
    var deviceFile = config.getLocal("deviceFile");

    if (spinner.isSpinning()) spinner.stop(true);
    if (modelId != null) {
        if ("keep" in program && keep === true) {
            // Don't overwrite any saved code UNLESS files don't exist
            if (!fs.existsSync(agentFile)) fs.writeFile(agentFile, agentCode);
            if (!fs.existsSync(deviceFile)) fs.writeFile(deviceFile, deviceCode);
        } else if ("keep" in program && program.keep == "device") {
            // Only overwrite the agent code
            fs.writeFile(agentFile, agentCode);
        } else if ("keep" in program && program.keep == "agent") {
            // Only overwrite the device code
            fs.writeFile(deviceFile, deviceCode);
        } else {
            // Overwrite both agent code and device code
            fs.writeFile(deviceFile, deviceCode);
            fs.writeFile(agentFile, agentCode);
        }

        config.saveLocalConfig(function(err) {
            if (err) {
                console.log("ERROR: " + err);
                return;
            }

            console.log("Model '" + modelName + "' initialized. To add a device run: 'imp devices -a <deviceID>'");
        });
    } else {
        console.log("ERROR: Could not create model's code files");
    }
}

function finalize() {
    var deviceCode = "";
    var agentCode = "";
    var modelId = config.getLocal("modelId");
    var modelName = config.getLocal("modelName");
    var agentFile = config.getLocal("agentFile");
    var deviceFile = config.getLocal("deviceFile");

    if (!spinner.isSpinning()) spinner.start();
    if (modelId != null) {
        imp.getModelRevisions(modelId, null, function(err, data) {
            if (err) {
                spinner.stop(true);
                console.log("ERROR: Could not fetch code revisions for model '" + modelName + "'");
                return;
            }

            if (data.revisions.length == 0) {
                config.saveLocalConfig(function(err) {
                    if (err) {
                        console.log("ERROR: " + err);
                        return;
                    }

                    spinner.stop(true);
                    console.log("Model '" + modelName + "' initialized. To add a device run: 'imp devices -a <deviceID>'");
                });

                return;
            }

            imp.getModelRevision(modelId, data.revisions[0].version, function(err, data) {
                if (err) {
                    spinner.stop(true);
                    console.log("ERROR: Could not fetch the latest build for model '" + modelName + "'");
                    return;
                }

                deviceCode = data.revision.device_code;
                agentCode = data.revision.agent_code;

                if ("keep" in program && keep === true) {
                    // Don't overwrite any saved code
                } else if ("keep" in program && program.keep == "device") {
                    // Only overwrite the agent code
                    fs.writeFile(agentFile, agentCode);
                } else if ("keep" in program && program.keep == "agent") {
                    // Only overwrite the device code
                    fs.writeFile(deviceFile, deviceCode);
                } else {
                    // Overwrite both agent code and device code
                    fs.writeFile(deviceFile, deviceCode);
                    fs.writeFile(agentFile, agentCode);
                }

                config.saveLocalConfig(function(err) {
                    if (err) {
                        console.log("ERROR: " + err);
                        return;
                    }

                    spinner.stop(true);
                    console.log("Model '" + modelName + "' initialized. To add a device run: 'imp devices -a <deviceID>'");
                });
            });
        });
    } else {
        imp.createModel(modelName, function(err, data) {
            if (err) {
                spinner.stop(true);
                console.log("ERROR: Could not create model");
                return;
            }

            config.setLocal("modelId", data.model.id);

            fs.writeFile(deviceFile, deviceCode);
            fs.writeFile(agentFile, agentCode);

            config.saveLocalConfig(function(err) {
                if (err) {
                    console.log("ERROR: " + err);
                    return;
                }

                spinner.stop(true);
                console.log("Model '" + modelName + "' initialized. To add a device run: 'imp devices -a <deviceId>'");
            });
        });
    }
}

config.init(null, function() {
    // Make sure this folder doesn't already have a config file
    if (this.getLocalConfig() && !("force" in program)) {
        console.log("ERROR: .impconfig already exists. Specify '-f' to re-initialize model");
        return;
    }

    if ("title" in program) {
        // User has supplied a specific model name, so use this rather
        // than ask for one
        apiKeyPrompt(this.get("apiKey"), function() {
            newModelPrompt(function() {
                fileNamePrompt(function() {
                    makeFiles();
                });
            });
        });
    } else {
        apiKeyPrompt(this.get("apiKey"), function() {
            modelPrompt(function() {
                getDevices(function() {
                    fileNamePrompt(function() {
                        finalize();
                    });
                });
            });
        });
    }
}.bind(config));
<|endoftext|>


<commit_before>import { CronJob } from 'cron';

export default function (sails) {
  return {
    jobs: {},

    defaults: {cron: {}},

    initialize: function (cb) {
      let config = sails.config.cron;
      let jobs = Object.keys(config);

      sails.on('ready', () => {
        jobs.forEach(name => {
          this.jobs[name] = new CronJob({
            cronTime: config[name].schedule,
            onTick: config[name].onTick,
            onComplete: config[name].onComplete,
            start: typeof config[name].start === 'boolean' ? config[name].start : true,
            timezone: config[name].timezone,
            context: config[name].context
          });
        });
      });

      cb();
    }
  };
}
<commit_msg>Typo fix<commit_after>import { CronJob } from 'cron';

export default function (sails) {
  return {
    jobs: {},

    defaults: {cron: {}},

    initialize: function (cb) {
      let config = sails.config.cron;
      let jobs = Object.keys(config);

      sails.on('ready', () => {
        jobs.forEach(job => {
          this.jobs[job] = new CronJob({
            cronTime: config[job].schedule,
            onTick: config[job].onTick,
            onComplete: config[job].onComplete,
            start: typeof config[job].start === 'boolean' ? config[job].start : true,
            timezone: config[job].timezone,
            context: config[job].context
          });
        });
      });

      cb();
    }
  };
}
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
<commit_msg>bootstrap redux on index.js<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import registerServiceWorker from './registerServiceWorker';

import { Provider } from 'react-redux';

import { createStore } from 'redux';

import reducer from './reducers';

import App from './components/App';

const store = createStore(
  reducer,
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);

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

registerServiceWorker();
<|endoftext|>


<commit_before>function isValid(code) {
    if (!code || !code.length)
        return false;

    var c = parseInt(code.charAt(9));

    var n = parseInt(code.charAt(0)) * 10 +
            parseInt(code.charAt(1)) * 9 +
            parseInt(code.charAt(2)) * 8 +
            parseInt(code.charAt(3)) * 7 +
            parseInt(code.charAt(4)) * 6 +
            parseInt(code.charAt(5)) * 5 +
            parseInt(code.charAt(6)) * 4 +
            parseInt(code.charAt(7)) * 3 +
            parseInt(code.charAt(8)) * 2;

    var r = n - parseInt((n / 11).toString()) * 11;

    if ((r == 0 && r == c) || (r == 1 && c == 1) || (r > 1 && c == 11 - r)) {
        return true;
    }
    return false;
}

module.exports = {
    isValid: isValid
}<commit_msg>use arrow function<commit_after>var hasCode = code => !code || !code.length ? false : true;

var isValid = code => {
    if (this.hasCode(code))
        return false;

    const c = parseInt(code.charAt(9));

    const n = parseInt(code.charAt(0)) * 10 +
            parseInt(code.charAt(1)) * 9 +
            parseInt(code.charAt(2)) * 8 +
            parseInt(code.charAt(3)) * 7 +
            parseInt(code.charAt(4)) * 6 +
            parseInt(code.charAt(5)) * 5 +
            parseInt(code.charAt(6)) * 4 +
            parseInt(code.charAt(7)) * 3 +
            parseInt(code.charAt(8)) * 2;

    const r = n - parseInt((n / 11).toString()) * 11;

    if ((r == 0 && r == c) || (r == 1 && c == 1) || (r > 1 && c == 11 - r)) {
        return true;
    }
    return false;
}

module.exports = {
    isValid: isValid
}<|endoftext|>


<commit_before>import ancestors from 'ancestors'
import indexOf from 'index-of'

const E_SHOW = 'Argument 1 of seek must use filter NodeFilter.SHOW_TEXT.'
const E_WHERE = 'Argument 2 of seek must be a number or a Text Node.'

const SHOW_TEXT = 4
const TEXT_NODE = 3

const DOCUMENT_POSITION_PRECEDING = 2
const DOCUMENT_POSITION_FOLLOWING = 4

export default function seek(iter, where) {
  if (iter.whatToShow !== SHOW_TEXT) {
    throw new Error(E_SHOW)
  }

  let count = 0
  let node = iter.referenceNode
  let predicates = null

  if (isNumber(where)) {
    predicates = {
      forward: () => count < where,
      backward: () => count > where,
    }
  } else if (isText(where)) {
    let forward = before(node, where) ? () => false : () => node !== where
    let backward = () => node != where || !iter.pointerBeforeReferenceNode
    predicates = {forward, backward}
  } else {
    throw new Error(E_WHERE)
  }

  while (predicates.forward() && (node = iter.nextNode()) !== null) {
    count += node.nodeValue.length
  }

  while (predicates.backward() && (node = iter.previousNode()) !== null) {
    count -= node.nodeValue.length
  }

  return count
}

function isNumber(n) {
  return !isNaN(parseInt(n)) && isFinite(n)
}

function isText(node) {
  return node.nodeType === TEXT_NODE
}

function before(ref, node) {
  if (ref === node) return false

  let common = null
  let left = [ref].concat(ancestors(ref)).reverse()
  let right = [node].concat(ancestors(node)).reverse()

  while (left[0] === right[0]) {
    common = left.shift()
    right.shift()
  }

  left = left[0]
  right = right[0]

  let l = indexOf(common.childNodes, left)
  let r = indexOf(common.childNodes, right)

  return l > r
}
<commit_msg>Remove unused constants<commit_after>import ancestors from 'ancestors'
import indexOf from 'index-of'

const E_SHOW = 'Argument 1 of seek must use filter NodeFilter.SHOW_TEXT.'
const E_WHERE = 'Argument 2 of seek must be a number or a Text Node.'

const SHOW_TEXT = 4
const TEXT_NODE = 3

export default function seek(iter, where) {
  if (iter.whatToShow !== SHOW_TEXT) {
    throw new Error(E_SHOW)
  }

  let count = 0
  let node = iter.referenceNode
  let predicates = null

  if (isNumber(where)) {
    predicates = {
      forward: () => count < where,
      backward: () => count > where,
    }
  } else if (isText(where)) {
    let forward = before(node, where) ? () => false : () => node !== where
    let backward = () => node != where || !iter.pointerBeforeReferenceNode
    predicates = {forward, backward}
  } else {
    throw new Error(E_WHERE)
  }

  while (predicates.forward() && (node = iter.nextNode()) !== null) {
    count += node.nodeValue.length
  }

  while (predicates.backward() && (node = iter.previousNode()) !== null) {
    count -= node.nodeValue.length
  }

  return count
}

function isNumber(n) {
  return !isNaN(parseInt(n)) && isFinite(n)
}

function isText(node) {
  return node.nodeType === TEXT_NODE
}

function before(ref, node) {
  if (ref === node) return false

  let common = null
  let left = [ref].concat(ancestors(ref)).reverse()
  let right = [node].concat(ancestors(node)).reverse()

  while (left[0] === right[0]) {
    common = left.shift()
    right.shift()
  }

  left = left[0]
  right = right[0]

  let l = indexOf(common.childNodes, left)
  let r = indexOf(common.childNodes, right)

  return l > r
}
<|endoftext|>


<commit_before>import express from 'express'
import basicAuth from 'node-basicauth'
import bodyParser from 'body-parser'
import cookieParser from 'cookie-parser'
import compression from 'compression'
import babelify from 'express-babelify-middleware'
import fs from 'fs'
import morgan from 'morgan'
import winston from 'winston'
import errorHandler from 'express-error-handler'
import { join } from 'path'
import favicon from 'serve-favicon'
import stylus from 'stylus'
import nib from 'nib'
import Nedb from 'nedb'
import { Mailgun } from 'mailgun'

import { isArray, isFunction, isString, isIterable } from 'magic-types'
import log from 'magic-server-log'

import appRoutes from './routes'
import initApi from './api'
import headers from './headers'
import handle404 from './errors/handle404'
import handle500 from './errors/handle500'

// import { init as initAdmin } from 'magic-admin';
// import blog from 'magic-blog';

export { renderPage } from './pages'

export const conjure =
  () =>
    express()

export const Express = express

export const Router = express.Router

const start =
  ({ app, port }) => {
    app.listen(port, err => {
      if (err) {
        log.error(err)
      }

      log(`app listening to port ${port}`)
    })
  }

export const Magic = app => {
  const dir = app.get('cwd') || join(process.cwd(), 'src')
  const css = app.get('css') || stylus
  const routes = app.get('routes')
  const env = app.get('env') || 'production'
  const publicDir = app.get('publicDir') || join('client', 'public')
  const viewDir = app.get('viewDir') || join('client', 'views')
  const appDirs = app.get('dirs')
  const basicAuthConfig = app.get('basicAuth')
  const port = app.get('port') || 1337
  const viewEngine = app.get('view engine') || 'pug'
  const babelifyFiles = app.get('babelifyFiles')
  const logLevel = app.get('logLevel') || 'combined'
  const dirs = {
    root: dir,
    public: join(dir, publicDir),
    views: join(dir, viewDir),
    ...appDirs,
  }
  const dbFile = app.get('dbFile') || false
  const mailgunApiKey = app.get('mailgunApiKey') || false

  const apiRoutes = app.get('api')
  let api
  if (apiRoutes) {
    api = initApi(apiRoutes)
  }

  let db
  if (dbFile) {
    db = new Nedb({
      filename: dbFile,
      autoload: true,
    })
    app.set('db', db)
  }

  if (mailgunApiKey) {
    app.set('mg', new Mailgun(mailgunApiKey))
  }

  const logFiles = {
    access: join(dir, 'logs', 'access.log'),
    error: join(dir, 'logs', 'error.log'),
    ...app.get('logFiles'),
  }

  const faviconPath = join(dirs.public, 'favicon.ico')

  app.set('css', css)
  app.set('dirs', dirs)

  // set req.app and req.db to use in middleware
  app.use(
    (req, res, next) => {
      req = {
        ...req,
        app,
        db,
      }

      next()
    })

  // set expiry headers
  app.use(headers)

  // enable http basicAuth
  if (basicAuthConfig) {
    app.use(basicAuth(basicAuthConfig))
  }

  // fs.existsSync only gets called once on first request
  if (faviconPath && !app.get('faviconChecked') && !app.get('faviconExists')) {
    app.set('faviconChecked', true)
    app.set('faviconExists', fs.existsSync(faviconPath))
  }

  if (app.get('faviconExists')) {
    app.use(favicon(faviconPath))
  }

  app.set('views', dirs.views)
  app.set('view engine', viewEngine)

  app.use(compression({ threshold: 128 }))

  const cssMiddleware =
    (str, path) =>
      css(str)
        .set('filename', path)
        .set('compress', env === 'production')
        .use(nib())
        .import('nib')

  app.use(css.middleware({
    src: dirs.public,
    maxage: '1d',
    compile: cssMiddleware,
  }))

  if (isString(babelifyFiles) || isArray(babelifyFiles)) {
    [].concat(babelifyFiles).forEach(
      f => {
        // Precompile a browserified file at a path
        const fileUrl = `/js/${f}.js`
        const bundleUrl = `${dirs.public}/js/${f}/index.js`

        app.use(fileUrl, babelify(bundleUrl))
      }
    )
  }

  app.use(express.static(join(__dirname, 'public'), { maxAge: '1w' }))

  app.use(express.static(dirs.public, { maxAge: '1d' }))

  // if (app.enabled('admin')) {
  //   app.use(initAdmin);
  // }

  /*
   TODO: reenable
  if (app.get('blogRoot')) {
    let blogRoot = app.get('blogRoot');
    if (typeof blogRoot !== 'string' && typeof blogRoot !== 'number') {
      blogRoot = 'blog';
    }
    if (blogRoot.charAt(0) !== '/') {
      blogRoot = '/' + blogRoot;
    } else {
      app.set('blogRoot', blogRoot.substr(1));
    }
    app.use(blogRoot, blog);
  }
   */

  // logging
  app.use(morgan(logLevel))

  app.use(
    app.get('env') === 'development'
      ? errorHandler({ dumpExceptions: true, showStack: true })
      : errorHandler()
  )

  if (logFiles) {
    if (logFiles.access) {
      winston.add(winston.transports.File, {
        filename: logFiles.access,
      })
    }

    if (logFiles.error) {
      winston.handleExceptions(new winston.transports.File({
        filename: logFiles.error,
      }))
    }
  }

  // if host sets bodyparser to true, init it
  if (app.enabled('bodyParser')) {
    app.use(bodyParser.json())
    app.use(bodyParser.urlencoded({ extended: true }))
  }

  // if host sets cookieparser to true, init it:
  if (app.enabled('cookieParser')) {
    app.use(cookieParser())
  }

  if (api) {
    app.use(api)
  }
  // load host specific router
  if (routes) {
    if (isIterable(routes)) {
      Object.keys(routes).forEach(
        key => {
          const route = routes[key]
          const { path, handler, method = 'get' } = routes[key]

          const isValidMethod = ['get', 'post'].some(v => v === method)
          if (!isValidMethod) {
            throw new Error(`Route method of type ${method} is not valid`)
          }

          if (!isString(path)) {
            throw new Error(`Route needs a path string to work ${route}`)
          }

          if (!isFunction(handler)) {
            throw new Error(`Route needs a handler function to work ${route}`)
          }

          app[method](path, handler)
        }
      )
    }
    else if (isFunction(routes)) {
      app.use(routes)
    }
  }

  // default router
  app.use(appRoutes)

  // we are in a 404 error
  app.use(handle404)

  // oops, worst case fallback, 500 server error.
  app.use(handle500)

  start({ app, port })

  return app
}

export default Magic
<commit_msg>use new modules<commit_after>import express from 'express'
import basicAuth from 'node-basicauth'
import bodyParser from 'body-parser'
import cookieParser from 'cookie-parser'
import compression from 'compression'
import babelify from 'express-babelify-middleware'
import { join } from 'path'
import favicon from './favicon'
import stylus from 'stylus'
import nib from 'nib'
import Nedb from 'nedb'
import { Mailgun } from 'mailgun'

import { isArray, isString } from 'magic-types'

import appRoutes, { customRoutes } from './routes'
import initApi from './api'
import initiateLogging from './logging'
import headers from './headers'
import handle404 from './errors/handle404'
import handle500 from './errors/handle500'

// import { init as initAdmin } from 'magic-admin';
// import blog from 'magic-blog';

export { renderPage } from './pages'

export const conjure =
  () =>
    express()

export const Express = express

export const Router = express.Router

const start =
  ({ app, port }) => {
    app.listen(port, err => {
      const log = app.get('logger')
      if (err) {
        log.error(err)
      }

      log.info(`app listening to port ${port}`)
    })
  }

export const Magic = app => {
  const dir = app.get('cwd') || join(process.cwd(), 'src')
  const env = app.get('env') || 'production'
  const publicDir = app.get('publicDir') || join('client', 'public')
  const viewDir = app.get('viewDir') || join('client', 'views')
  const logDir = app.get('logDir') || join('..', 'logs')
  const appDirs = app.get('dirs')
  const basicAuthConfig = app.get('basicAuth')
  const port = app.get('port') || 1337
  const viewEngine = app.get('view engine') || 'pug'
  const babelifyFiles = app.get('babelifyFiles')
  const dirs = {
    root: dir,
    public: join(dir, publicDir),
    views: join(dir, viewDir),
    logs: join(dir, logDir),
    ...appDirs,
  }

  // set req.app and req.db to use in middleware
  app.use(
    (req, res, next) => {
      req.app = app
      req.db = db

      next()
    }
  )

  const dbFile = app.get('dbFile') || false
  const mailgunApiKey = app.get('mailgunApiKey') || false

  app.set('dirs', dirs)

  favicon(app)

  app.set('views', dirs.views)
  app.set('view engine', viewEngine)

  app.use(compression({ threshold: 128 }))

  // initiate nedb if defined
  let db
  if (dbFile) {
    db = new Nedb({
      filename: dbFile,
      autoload: true,
    })
    app.set('db', db)
  }

  // initiate mailgun if defined
  if (mailgunApiKey) {
    app.set('mg', new Mailgun(mailgunApiKey))
  }

  // set expiry and custom headers
  app.use(headers)

  // enable http basicAuth
  if (basicAuthConfig) {
    app.use(basicAuth(basicAuthConfig))
  }

  const css = app.get('css') || stylus
  app.set('css', css)

  const cssMiddleware =
    (str, path) =>
      css(str)
        .set('filename', path)
        .set('compress', env === 'production')
        .use(nib())
        .import('nib')

  app.use(css.middleware({
    src: dirs.public,
    maxage: '1d',
    compile: cssMiddleware,
  }))

  if (isString(babelifyFiles) || isArray(babelifyFiles)) {
    [].concat(babelifyFiles).forEach(
      f => {
        // Precompile a browserified file at a path
        const fileUrl = `/js/${f}.js`
        const bundleUrl = `${dirs.public}/js/${f}/index.js`

        app.use(fileUrl, babelify(bundleUrl))
      }
    )
  }

  app.use(express.static(join(__dirname, 'public'), { maxAge: '1w' }))

  app.use(express.static(dirs.public, { maxAge: '1d' }))

  // if (app.enabled('admin')) {
  //   app.use(initAdmin);
  // }

  /*
  // Blog Middleware
  if (app.get('blogRoot')) {
    let blogRoot = app.get('blogRoot');
    if (typeof blogRoot !== 'string' && typeof blogRoot !== 'number') {
      blogRoot = 'blog';
    }
    if (blogRoot.charAt(0) !== '/') {
      blogRoot = '/' + blogRoot;
    } else {
      app.set('blogRoot', blogRoot.substr(1));
    }
    app.use(blogRoot, blog);
  }
  */

  initiateLogging(app)

  // if host sets bodyparser to true, init it
  if (app.enabled('bodyParser')) {
    app.use(bodyParser.json())
    app.use(bodyParser.urlencoded({ extended: true }))
  }

  // if host sets cookieparser to true, init it:
  if (app.enabled('cookieParser')) {
    app.use(cookieParser())
  }

  // initiate api if defined
  const apiRoutes = app.get('api')
  if (apiRoutes) {
    app.use(initApi(apiRoutes))
  }

  customRoutes(app)

  // default router
  app.use(appRoutes)

  // we are in a 404 error
  app.use(handle404)

  // oops, worst case fallback, 500 server error.
  app.use(handle500)

  start({ app, port })

  return app
}

export default Magic
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react'
import DefaultTheme from './themes/bootstrap3'
import { reduxForm } from 'redux-form'
import renderFields from './renderFields'
import renderField from './renderField'
import processSubmitErrors from './processSubmitErrors'
import buildSyncValidation from './buildSyncValidation'

const BaseForm = props => {
    const { schema, handleSubmit, theme, error, submitting } = props
    return (
        <form onSubmit={handleSubmit}>
            {renderField(schema, schema.title, theme || DefaultTheme)}

                {error && {error}}

            <button className="btn btn-primary" type="submit" disabled={submitting}>Submit</button>
        </form>)
}

const Liform = (props) => {
    const FinalForm = reduxForm({
        form: props.schema.title || 'form',
        validate: buildSyncValidation(props.schema),
        initialValues: props.initialValues,
    })(BaseForm)
    return (
        <FinalForm renderFields={renderField.bind(this)} {...props}/>
    )
}

Liform.propTypes = {
    schema: React.PropTypes.object,
    onSubmit: PropTypes.func.isRequired,
}

export default Liform

export { renderFields, renderField, processSubmitErrors }
<commit_msg>On submit hook not required<commit_after>import React, { PropTypes } from 'react'
import DefaultTheme from './themes/bootstrap3'
import { reduxForm } from 'redux-form'
import renderFields from './renderFields'
import renderField from './renderField'
import processSubmitErrors from './processSubmitErrors'
import buildSyncValidation from './buildSyncValidation'

const BaseForm = props => {
    const { schema, handleSubmit, theme, error, submitting } = props
    return (
        <form onSubmit={handleSubmit}>
            {renderField(schema, schema.title, theme || DefaultTheme)}

                {error && {error}}

            <button className="btn btn-primary" type="submit" disabled={submitting}>Submit</button>
        </form>)
}

const Liform = (props) => {
    const FinalForm = reduxForm({
        form: props.schema.title || 'form',
        validate: buildSyncValidation(props.schema),
        initialValues: props.initialValues,
    })(BaseForm)
    return (
        <FinalForm renderFields={renderField.bind(this)} {...props}/>
    )
}

Liform.propTypes = {
    schema: React.PropTypes.object,
    onSubmit: PropTypes.func,
}

export default Liform

export { renderFields, renderField, processSubmitErrors }
<|endoftext|>


<commit_before>var Worker = require('firebase-queue');
/**
 * A bridge between le-job-queue-service and Firebase
 * @class JobQueueProvider
 * @param {string} ref the firebase root reference
 * @returns {provider}
 */
var JobQueueProvider = function (ref) {
  if (!ref) { throw new Error('Firebase reference required'); }
  var _ref = ref;
  /**
   * Creates a worker to process jobs
   * @function createWorker
   * @memberof JobQueueProvider
   * @instance
   * @param {Function} processJob function to call when processing a job. It is sent two params, the job (type and data) as well as a function that should be called when the consumer is done processing the job
   * @returns {promise}
   */
  this.createWorker = function (processJob) {
    if (!processJob) { throw new Error('Process job function required'); }
    var options = { numWorkers: 1, specId: 'noTimeout' };
    var worker = new Worker(_ref.child('_queue'), options, function (data, progress, resolve, reject) {
      processJob(data, function () {
        _ref.child('queue').child('completedTasks').push(data, function (err) {
          if (err) { throw err; }
          else { resolve(); }
        });
      });
    });
  }
}

module.exports = JobQueueProvider;
<commit_msg>feat(index): support fast job queue type<commit_after>var Worker = require('firebase-queue');
/**
 * A bridge between le-job-queue-service and Firebase
 * @class JobQueueProvider
 * @param {string} ref the firebase root reference
 * @param {string} type the type of queue you want to create, supported types are 'default' and 'fast', leaving the field undefined is the same as 'default'
 * @returns {provider}
 */
var JobQueueProvider = function (ref, type) {
  if (!ref) { throw new Error('Firebase reference required'); }
  if (type !== 'fast' && type !== 'default' && type !== undefined) {
    throw new Error('Invalid value for the type param, value: ' + type);
  }
  var _ref = ref;
  /**
   * Creates a worker to process jobs
   * @function createWorker
   * @memberof JobQueueProvider
   * @instance
   * @param {Function} processJob function to call when processing a job. It is sent two params, the job (type and data) as well as a function that should be called when the consumer is done processing the job
   * @returns {promise}
   */
  this.createWorker = function (processJob) {
    if (!processJob) { throw new Error('Process job function required'); }
    var options = { numWorkers: 1, specId: 'noTimeout' };
    var queueLocation;
    if(type === 'fast') {
      queueLocation = 'fastQueue';
    } else {
      queueLocation = 'queue'
    }
    var worker = new Worker(_ref.child('_' + queueLocation), options, function (data, progress, resolve, reject) {
      processJob(data, function () {
        _ref.child(queueLocation).child('completedTasks').push(data, function (err) {
          if (err) { throw err; }
          else { resolve(); }
        });
      });
    });
  }
}

module.exports = JobQueueProvider;
<|endoftext|>


<commit_before>'use strict';
class Test {
  test() {
    return "test";
  }
}

var test = new Test();

test.test();
<commit_msg>method to process user input<commit_after>#! /usr/bin/env node
'use strict';

import {processIM} from './commons.js';
import jsonfile from 'jsonfile';
import PleasantProgress from 'pleasant-progress';
jsonfile.spaces = 4;
export function slackHistoryExport(args) {
  const progress = new PleasantProgress();
  progress.start('working');
  if(args.username) {
    processIM(args.token, args.username).then(history => {
      let currentDir = args.directory || process.cwd();
      let filePath = (args.filename) ? `${currentDir}/${args.filename}.json` : `${currentDir}/${Date.now()}-${args.username}-slack-history.json`;
      jsonfile.writeFile(filePath, history, function(err) {
        if (!err) {
          progress.stop();
          console.log(`Done! file saved at ${filePath}`);
        } else {
          throw err;
        }
      });
    }).catch(error => {
      console.log('error', error);
      progress.stop();
      process.exit(1);
    });
  }
}
<|endoftext|>


<commit_before>export { Badge, BadgeColors } from './components/badge';
export { Breadcrumbs, BreadcrumbItem } from './components/breadcrumbs';
export { Button, Link, ButtonSizes, ButtonColors } from './components/button';
export { ButtonGroup, ButtonGroupSizes, ButtonGroupColors } from './components/button-group';
export { Callout, CalloutColors, CalloutSizes } from './components/callout';
export { CloseButton } from './components/close-button';
export { FlexVideo } from './components/flex-video';
export { Row, Column } from './components/grid';
export { Icon } from './components/icon';
export { Label, LabelColors } from './components/label';
export { Menu, MenuItem, MenuText, MenuAlignments } from './components/menu';
export { Pagination, PaginationItem, PaginationPrevious, PaginationNext, PaginationEllipsis } from './components/pagination';
export { Progress, ProgressMeter, ProgressMeterWithText, ProgressMeterText, NativeProgress } from './components/progress-bar';
export { ResponsiveNavigation, TitleBar, MenuIcon, TitleBarTitle } from './components/responsive';
export { Switch, SwitchInput, SwitchPaddle, SwitchActive, SwitchInactive, SwitchTypes, SwitchSizes } from './components/switch';
export { Thumbnail, ThumbnailLink } from './components/thumbnail';
export { TopBar, TopBarTitle, TopBarLeft, TopBarRight } from './components/top-bar';

<commit_msg>Add ProgressColors to exports in entry script<commit_after>export { Badge, BadgeColors } from './components/badge';
export { Breadcrumbs, BreadcrumbItem } from './components/breadcrumbs';
export { Button, Link, ButtonSizes, ButtonColors } from './components/button';
export { ButtonGroup, ButtonGroupSizes, ButtonGroupColors } from './components/button-group';
export { Callout, CalloutColors, CalloutSizes } from './components/callout';
export { CloseButton } from './components/close-button';
export { FlexVideo } from './components/flex-video';
export { Row, Column } from './components/grid';
export { Icon } from './components/icon';
export { Label, LabelColors } from './components/label';
export { Menu, MenuItem, MenuText, MenuAlignments } from './components/menu';
export { Pagination, PaginationItem, PaginationPrevious, PaginationNext, PaginationEllipsis } from './components/pagination';
export { Progress, ProgressMeter, ProgressMeterWithText, ProgressMeterText, NativeProgress, ProgressColors } from './components/progress-bar';
export { ResponsiveNavigation, TitleBar, MenuIcon, TitleBarTitle } from './components/responsive';
export { Switch, SwitchInput, SwitchPaddle, SwitchActive, SwitchInactive, SwitchTypes, SwitchSizes } from './components/switch';
export { Thumbnail, ThumbnailLink } from './components/thumbnail';
export { TopBar, TopBarTitle, TopBarLeft, TopBarRight } from './components/top-bar';

<|endoftext|>


<commit_before>import React from 'react';
import { render } from 'react-dom';

const CHALLENGES = [
  {
    instructions: "Which CSS property would we use to italicize text?",
    optionList: [
      {
        id: 0,
        title: "text-decoration",
        order: 1
      },
      {
        id: 1,
        title: "font-style",
        order: 2
      },
      {
        id: 2,
        title: "text-transform",
        order: 3
      }
    ],
    preview: {
      css: (answer)=> {
        return ```
          .italicized {
            ${answer}: italic;
          }
        ```;
      },
      html: `

This text has been italicized.

      `
    }
  },
  {
    instructions:

We want to create an element that has a blue box-shadow with a blur-radius of 2px. This shadow is also offset 1 pixel to the left and 4 pixels down.

Click the elements to insert them in the correct order we’d use to write these style attributes.

,
    optionList: [
      {
        id: 0,
        title: "-4px",
        order: 1
      },
      {
        id: 1,
        title: "blue",
        order: 3
      },
      {
        id: 2,
        title: "1px",
        order: 2
      },
      {
        id: 3,
        title: "2px",
        order: 4
      }
    ]
  }
];

const sortedOptions = (list) => list.sort((a, b) => a.order >= b.order);

class Dialogue extends React.Component {

  constructor(){
    super();
    this.state = {
    };
  }

  render() {
    return(

Success!

        <button onClick={this.props.onContinue.bind(this)}>Continue</button>

    );
  }
}

class Option extends React.Component {
  render() {
    return (
{this.props.title}
);
  }
}

class Answer extends React.Component {
  render() {
    return (
Box {this.props.order}
);
  }
}

class OptionList extends React.Component {
  render() {
    return (

          {this.props.options.map((props) => {
            return (<Option key={props.id} {...props}></Option>)
          })}

    );
  }
}

class AnswerList extends React.Component {
  render() {
    return (

        {sortedOptions(this.props.options).map((o) => <Answer key={o.id} {...o} />)}

    );
  }
}

class Challenge extends React.Component {
  constructor() {
    super();
    this.state = {
      complete: false,
    }
  }
  onPassChallenge(){
    this.setState({complete: true});
  }
  render () {
    var challengeClass = 'challenge';
    if(this.state.complete)
      challengeClass += ' is-complete';

    return (

{this.props.instructions}

          <AnswerList options={this.props.optionList}></AnswerList>

          <OptionList options={this.props.optionList} />

          <Dialogue onContinue={this.props.onAdvance.bind(this)}/>

);
  }
}

class Challenges extends React.Component {
  constructor() {
    super();
    this.challenges = CHALLENGES;
    this.state = {
      challengeIndex: 0,
      challengeLength: this.challenges.length
    };
  }

  onContinue() {
    let nextChallengeIndex = this.state.challengeIndex + 1;
    if (this.state.challengeIndex >= this.state.challengeLength) {
      nextChallengeIndex = 0;
    }
    this.setState({
      challengeIndex: nextChallengeIndex
    });
  }

  render() {
    return (
      <Challenge onAdvance={this.onContinue.bind(this)} {...this.challenges[this.state.challengeIndex]} />
    );
  }
}

render(
  <Challenges />,
  document.getElementById('app')
);
<commit_msg>Clicking things.<commit_after>import React from 'react';
import { render } from 'react-dom';

const CHALLENGES = [
  {
    instructions: "Which CSS property would we use to italicize text?",
    code: (selections)=> {
      return (

box-shadow:

            <Option {...selections[0]}/>

            <Option {...selections[1]}/>

            <Option {...selections[2]}/>

            <Option {...selections[3]}/>

)
    },
    optionList: [
      {
        id: 0,
        label: "text-decoration",
        order: 1
      },
      {
        id: 1,
        label: "font-style",
        order: 2
      },
      {
        id: 2,
        label: "text-transform",
        order: 3
      }
    ],
    preview: {
      css: (answer)=> {
        return ```
          .italicized {
            ${answer}: italic;
          }
        ```;
      },
      html: `

This text has been italicized.

      `
    }
  },
  {
    instructions:

We want to create an element that has a blue box-shadow with a blur-radius of 2px. This shadow is also offset 1 pixel to the left and 4 pixels down.

Click the elements to insert them in the correct order we’d use to write these style attributes.

,
    code: (selections)=> {
      return (

box-shadow:

            <Option label={selections[0]}/>

            <Option label={selections[1]}/>

            <Option label={selections[2]}/>

            <Option label={selections[3]}/>

)
    },
    optionList: [
      {
        id: 0,
        label: "-4px",
        order: 1
      },
      {
        id: 1,
        label: "blue",
        order: 3
      },
      {
        id: 2,
        label: "1px",
        order: 2
      },
      {
        id: 3,
        label: "2px",
        order: 4
      }
    ]
  }
];

const sortedOptions = (list) => list.sort((a, b) => a.order >= b.order);

class Dialogue extends React.Component {

  constructor(){
    super();
    this.state = {
    };
  }

  render() {
    return(

Success!

        <button onClick={this.props.onContinue.bind(this)}>Continue</button>

    );
  }
}

class Option extends React.Component {
  render() {
    return ({this.props.label});
  }
}

class Answer extends React.Component {
  render() {
    return ({this.props.label});
  }
}

class OptionList extends React.Component {
  render() {
    return (

          {this.props.options.map((props) => {
            return (<Option key={props.id} {...props}></Option>)
          })}

    );
  }
}

class AnswerList extends React.Component {
  render() {
    return (

        {sortedOptions(this.props.options).map((o) => {
          o.onDeselect = this.props.onDeselect.bind(this, o);
          return <Answer key={o.id} {...o} onSelect={this.props.onSelect.bind(this, o)} />
        })}

    );
  }
}

class Challenge extends React.Component {
  constructor() {
    super();
    this.state = {
      selections: [],
      complete: false
    }
  }

  onSelect(option) {
    this.setState({
      selections: this.state.selections.concat([option])
    });
  }

  onDeselect(option) {
    this.setState({
      selections: this.state.selections.filter((o) => o.id != option.id)
    });
  }

  onPassChallenge(){
    this.setState({complete: true});
  }
  render () {
    var challengeClass = 'challenge';
    if(this.state.complete)
      challengeClass += ' is-complete';

    return (

{this.props.instructions}

          {this.props.code(this.state.selections)}

          <AnswerList onSelect={this.onSelect.bind(this)} onDeselect={this.onDeselect.bind(this)} options={this.props.optionList} />

          <Dialogue onContinue={this.props.onAdvance.bind(this)}/>

);
  }
}

class Challenges extends React.Component {
  constructor() {
    super();
    this.challenges = CHALLENGES;
    this.state = {
      challengeIndex: 0,
      challengeLength: this.challenges.length
    };
  }

  onContinue() {
    let nextChallengeIndex = this.state.challengeIndex + 1;
    if (this.state.challengeIndex >= this.state.challengeLength) {
      nextChallengeIndex = 0;
    }
    this.setState({
      challengeIndex: nextChallengeIndex
    });
  }

  render() {
    return (
      <Challenge onAdvance={this.onContinue.bind(this)} {...this.challenges[this.state.challengeIndex]} />
    );
  }
}

render(
  <Challenges />,
  document.getElementById('app')
);
<|endoftext|>