<commit_before>const styles = {};

export const bodyStyle = {
  fontFamily: '"HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif',
  fontWeight: '300',
  fontSize: '24px',
};
styles.body = bodyStyle;

export const bottomNavStyle = {
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'space-around',
};

export const login = {
  backgroundImage: 'url("http://68.media.tumblr.com/b4f33d654b4448794313633770cc8572/tumblr_oh34v07h9w1u9ooogo1_540.gif")',
  position: 'fixed',
  width: '100%',
  height: '100vh',
};

export const fbLogin = {
  background: 'none',
  marginBottom: '30px',
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'space-around',
};

export const splashText = {
  color: 'white',
  marginTop: '150px',
  marginBottom: '100px',
  fontFamily: '"HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif',
  fontWeight: '300',
  fontSize: '90px',
  textAlign: 'center',
  textShadow: '0px 0px 3px #000',
};

export const tint = {
  content: '""',
  position: 'absolute',
  top: '0',
  left: '0',
  right: '0',
  bottom: '0',
  width: '100%',
  height: '100%',
  backgroundColor: 'rgba(0,0,0,.5)',
  margin: 'auto',
};

export const tagline = {
  textAlign: 'center',
  fontFamily: '"HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif',
  fontWeight: '300',
  fontSize: '24px',
  color: 'white',
};

// export const titleStyle = {
//   ...styles.body,
// };
// styles.title = titleStyle;

export default styles;
<commit_msg>fixed bkground view for desktop login page<commit_after>const styles = {};

export const bodyStyle = {
  fontFamily: '"HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif',
  fontWeight: '300',
  fontSize: '24px',
};
styles.body = bodyStyle;

export const bottomNavStyle = {
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'space-around',
};

export const login = {
  backgroundImage: 'url("http://68.media.tumblr.com/b4f33d654b4448794313633770cc8572/tumblr_oh34v07h9w1u9ooogo1_540.gif")',
  backgroundAttachment: 'fixed',
  backgroundPosition: 'center',
  backgroundRepeat: 'no-repeat',
  width: '100%',
  height: '100vh',
};

export const fbLogin = {
  background: 'none',
  marginBottom: '30px',
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'space-around',
};

export const splashText = {
  color: 'white',
  marginTop: '150px',
  marginBottom: '100px',
  fontFamily: '"HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif',
  fontWeight: '300',
  fontSize: '90px',
  textAlign: 'center',
  textShadow: '0px 0px 3px #000',
};

export const tint = {
  content: '""',
  position: 'absolute',
  top: '0',
  left: '0',
  right: '0',
  bottom: '0',
  width: '100%',
  height: '100%',
  backgroundColor: 'rgba(0,0,0,.5)',
  margin: 'auto',
};

export const tagline = {
  textAlign: 'center',
  fontFamily: '"HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif',
  fontWeight: '300',
  fontSize: '24px',
  color: 'white',
};

// export const titleStyle = {
//   ...styles.body,
// };
// styles.title = titleStyle;

export default styles;
<|endoftext|>


<commit_before>'use strict';

/*
 * Module dependencies.
 */
var mongoose = require('mongoose'),
	errorHandler = require('../../errors'),
	Group = mongoose.model('Group'),
	User = mongoose.model('User'),
	MyResponse = require('../../../custom_objects/MyResponse'),
	serverJSON = require('../../../local_files/ui/server.ui.json'),
	Helper = require('../../../custom_objects/Helper'),
	_ = require('lodash');

/**
 * Create a Group
 */
exports.create = function(req, res) {

	var group = new Group(req.body);
	var myResponse = new MyResponse();
	var data = _.merge(group,{admins: req.user,createdBy : req.user},Helper.cleanMergeObj);
	_.extend(group,data);

	//detect if group with this name has already been created
	var query = {
		createdBy:  mongoose.Types.ObjectId(group.createdBy),
		name: group.name
	};

	Helper.find(Group,query,function(err,mod) {
		if(err || !mod || mod.length > 0)
		{
			console.log('error: ' + err);
			myResponse.addMessages(serverJSON.api.groups.name.duplicate);
			Helper.output(myResponse,res);
		}
		else
		{
			group.save(function(err) {
				console.log('in save');

				if (err) {
					console.log('error: ' + err);
					myResponse.transformMongooseError(Group.errPath,String(err));
					Helper.output(myResponse,res);
				}
				else {
					console.log('saved successfully');
					req.user.createdGroup = group;
					req.user.save(function(userErr) {
						Helper.populateModel(Group,group,Group.errPath,function(mod) {
							myResponse.setData(mod);
							Helper.output(myResponse,res);
						});
					});
				}
			});
		}
	});
};

/**
 * Show the current Group
 */
exports.read = function(req, res) {

	var id = req.params.groupId;

	Group.findOne({_id: id}, function(err,group) {

		var myResponse = new MyResponse();

		if (err) {
			console.log('error: ' + err);
			myResponse.transformMongooseError(Group.errPath,String(err));
			Helper.output(myResponse,res);
		}
		else {
			Helper.populateModel(Group,group,Group.errPath,function(mod) {
				myResponse.setData(mod);
				Helper.output(myResponse,res);
			});
		}
	});
};

/**
 * Update a Group
 */
exports.update = function(req, res) {

	var myResponse = new MyResponse();
	var id = req.params.groupId;

	Group.findOne({_id: id}, function(err,group) {

		var myResponse = new MyResponse();
		console.log(err);
		if(err)
		{
			console.log(err);
			myResponse.transformMongooseError(Group.errPath,String(err));
			Helper.output(myResponse,res);
		}
		else if(!group)
		{
			myResponse.addMessages(serverJSON.api.groups._id.invalid);
			Helper.output(myResponse,res);
		}
		else
		{
			var data = _.merge(group,req.body,Helper.cleanMergeObj);
			_.extend(group,data);

			group.updated = Date.now();

			group.save(function(err) {
				console.log('in save');

				if (err) {
					console.log('error: ' + err);
					myResponse.transformMongooseError(Group.errPath,String(err));
					Helper.output(myResponse,res);
				}
				else {
					console.log('saved successfully');
					Helper.populateModel(Group,group,Group.errPath,function(mod) {
						myResponse.setData(mod);
						Helper.output(myResponse,res);
					});
				}
			});
		}
	});
};

/**
 * Delete an Group
 */
exports.delete = function(req, res) {

	var id = req.params.groupId;
	console.log('group id: ' + id);
	var myResponse = new MyResponse();

	Group.findOne({_id: id}, function(err,group) {

		var myResponse = new MyResponse();

		if(err)
		{
			console.log(err);
			myResponse.transformMongooseError(Group.errPath,String(err));
			Helper.output(myResponse,res);
		}
		else if(!group)
		{
			myResponse.addMessages(serverJSON.api.groups._id.invalid);
			myResponse.setError(res);
		}
		else
		{
			group.remove(function(err) {
				if (err) {
					console.log('error: ' + err);
					myResponse.transformMongooseError(Group.errPath,String(err));
					Helper.output(myResponse,res);
				}
				else {
					console.log('saved successfully');
					Helper.populateModel(Group,group,Group.errPath,function(mod) {
						myResponse.setData(mod);
						Helper.output(myResponse,res);
					});
				}
			});
		}
	});
};

/**
 * List of Groups
 */
exports.list = function(req, res) { Group.find().sort('-created').exec(function(err, groups) {

		var myResponse = new MyResponse();

		if (err) {
			myResponse.transformMongooseError(Group.errPath,String(err));
			Helper.output(myResponse,res);
		} else {
			Helper.populateModel(Group,groups,Group.errPath,function(mod) {
				myResponse.setData(mod);
				Helper.output(myResponse,res);
			});
		}
	});
};

/**
 * Group middleware
 */
exports.groupByID = function(req, res, next, id) {

	var myResponse = new MyResponse();

	if(!mongoose.Types.ObjectId.isValid(id))
	{
		myResponse.addMessages(serverJSON.api.groups._id.invalid);
		Helper.output(myResponse,res);
		return;
	}

	Group.findById(id).populate('user', 'displayName').exec(function(err, group) {
		//if (err) return next(err);
		//if (! group) return next(new Error('Failed to load Group ' + id));
		req.group = group ;

		next();
	});
};

/**
 * Group authorization middleware
 */
exports.hasAuthorization = function(req, res, next) {
	if (req.group.user.id !== req.user.id) {
		return res.status(403).send('User is not authorized');
	}
	next();
};
<commit_msg>changed to pushing groups to createdGroups array instead of setting it<commit_after>'use strict';

/*
 * Module dependencies.
 */
var mongoose = require('mongoose'),
	errorHandler = require('../../errors'),
	Group = mongoose.model('Group'),
	User = mongoose.model('User'),
	MyResponse = require('../../../custom_objects/MyResponse'),
	serverJSON = require('../../../local_files/ui/server.ui.json'),
	Helper = require('../../../custom_objects/Helper'),
	_ = require('lodash');

/**
 * Create a Group
 */
exports.create = function(req, res) {

	var group = new Group(req.body);
	var myResponse = new MyResponse();
	var data = _.merge(group,{admins: req.user,createdBy : req.user},Helper.cleanMergeObj);
	_.extend(group,data);

	//detect if group with this name has already been created
	var query = {
		createdBy:  mongoose.Types.ObjectId(group.createdBy),
		name: group.name
	};

	Helper.find(Group,query,function(err,mod) {
		if(err || !mod || mod.length > 0)
		{
			console.log('error: ' + err);
			myResponse.addMessages(serverJSON.api.groups.name.duplicate);
			Helper.output(myResponse,res);
		}
		else
		{
			group.save(function(err) {
				console.log('in save');

				if (err) {
					console.log('error: ' + err);
					myResponse.transformMongooseError(Group.errPath,String(err));
					Helper.output(myResponse,res);
				}
				else {
					console.log('saved successfully');
					req.user.createdGroups.push(group._id);
					req.user.save(function(userErr) {
						Helper.populateModel(Group,group,Group.errPath,function(mod) {
							myResponse.setData(mod);
							Helper.output(myResponse,res);
						});
					});
				}
			});
		}
	});
};

/**
 * Show the current Group
 */
exports.read = function(req, res) {

	var id = req.params.groupId;

	Group.findOne({_id: id}, function(err,group) {

		var myResponse = new MyResponse();

		if (err) {
			console.log('error: ' + err);
			myResponse.transformMongooseError(Group.errPath,String(err));
			Helper.output(myResponse,res);
		}
		else {
			Helper.populateModel(Group,group,Group.errPath,function(mod) {
				myResponse.setData(mod);
				Helper.output(myResponse,res);
			});
		}
	});
};

/**
 * Update a Group
 */
exports.update = function(req, res) {

	var myResponse = new MyResponse();
	var id = req.params.groupId;

	Group.findOne({_id: id}, function(err,group) {

		var myResponse = new MyResponse();
		console.log(err);
		if(err)
		{
			console.log(err);
			myResponse.transformMongooseError(Group.errPath,String(err));
			Helper.output(myResponse,res);
		}
		else if(!group)
		{
			myResponse.addMessages(serverJSON.api.groups._id.invalid);
			Helper.output(myResponse,res);
		}
		else
		{
			var data = _.merge(group,req.body,Helper.cleanMergeObj);
			_.extend(group,data);

			group.updated = Date.now();

			group.save(function(err) {
				console.log('in save');

				if (err) {
					console.log('error: ' + err);
					myResponse.transformMongooseError(Group.errPath,String(err));
					Helper.output(myResponse,res);
				}
				else {
					console.log('saved successfully');
					Helper.populateModel(Group,group,Group.errPath,function(mod) {
						myResponse.setData(mod);
						Helper.output(myResponse,res);
					});
				}
			});
		}
	});
};

/**
 * Delete an Group
 */
exports.delete = function(req, res) {

	var id = req.params.groupId;
	console.log('group id: ' + id);
	var myResponse = new MyResponse();

	Group.findOne({_id: id}, function(err,group) {

		var myResponse = new MyResponse();

		if(err)
		{
			console.log(err);
			myResponse.transformMongooseError(Group.errPath,String(err));
			Helper.output(myResponse,res);
		}
		else if(!group)
		{
			myResponse.addMessages(serverJSON.api.groups._id.invalid);
			myResponse.setError(res);
		}
		else
		{
			group.remove(function(err) {
				if (err) {
					console.log('error: ' + err);
					myResponse.transformMongooseError(Group.errPath,String(err));
					Helper.output(myResponse,res);
				}
				else {
					console.log('saved successfully');
					Helper.populateModel(Group,group,Group.errPath,function(mod) {
						myResponse.setData(mod);
						Helper.output(myResponse,res);
					});
				}
			});
		}
	});
};

/**
 * List of Groups
 */
exports.list = function(req, res) { Group.find().sort('-created').exec(function(err, groups) {

		var myResponse = new MyResponse();

		if (err) {
			myResponse.transformMongooseError(Group.errPath,String(err));
			Helper.output(myResponse,res);
		} else {
			Helper.populateModel(Group,groups,Group.errPath,function(mod) {
				myResponse.setData(mod);
				Helper.output(myResponse,res);
			});
		}
	});
};

/**
 * Group middleware
 */
exports.groupByID = function(req, res, next, id) {

	var myResponse = new MyResponse();

	if(!mongoose.Types.ObjectId.isValid(id))
	{
		myResponse.addMessages(serverJSON.api.groups._id.invalid);
		Helper.output(myResponse,res);
		return;
	}

	Group.findById(id).populate('user', 'displayName').exec(function(err, group) {
		//if (err) return next(err);
		//if (! group) return next(new Error('Failed to load Group ' + id));
		req.group = group ;

		next();
	});
};

/**
 * Group authorization middleware
 */
exports.hasAuthorization = function(req, res, next) {
	if (req.group.user.id !== req.user.id) {
		return res.status(403).send('User is not authorized');
	}
	next();
};
<|endoftext|>


<commit_before>window.onload = function(){
  if(document.getElementsByTagName('tspan').length > 0){
    run();
  }
  function run(){
    var elements = document.getElementsByTagName('tspan');
    var tags = getTags();
    var username = getUsername();

    // Add event to each tag strings.
    for(var x = 0; x < elements.length; x++){
      if(tags[x] != 'Others'){
        elements[x].addEventListener(
          'click',
          (function(x){
            return function(){
              location.href = 'https://qiita.com/search?q=user%3A' + username + '+tag%3A' + tags[x];
            }
          })(x)
        );
        // Modify styles to simulate hyperlink.
        elements[x].style.textDecoration = 'underline';
        elements[x].style.cursor = 'pointer';
      }
    }
  }
  // Get tag strings from DOM.
  function getTags(){
    var elements = document.getElementsByTagName('tspan');
    var tags = [];

    for(var x = 0; x < elements.length; x++){
      tags.push(elements[x].textContent.replace(/.*- /, ''));
    }
    return tags;
  }
  // Get username from DOM.
  function getUsername(){
    return document.getElementsByClassName('userPage_heading')[0].children[0].textContent;
  }
}
<commit_msg>Use encodeURIComponent() in script.js<commit_after>window.onload = function(){
  if(document.getElementsByTagName('tspan').length > 0){
    run();
  }
  function run(){
    var elements = document.getElementsByTagName('tspan');
    var tags = getTags();
    var username = getUsername();

    // Add event to each tag strings.
    for(var x = 0; x < elements.length; x++){
      if(tags[x] != 'Others'){
        elements[x].addEventListener(
          'click',
          (function(x){
            return function(){
              location.href = 'https://qiita.com/search?q=user%3A' + encodeURIComponent(username) + '+tag%3A' + encodeURIComponent(tags[x]);
            }
          })(x)
        );
        // Modify styles to simulate hyperlink.
        elements[x].style.textDecoration = 'underline';
        elements[x].style.cursor = 'pointer';
      }
    }
  }
  // Get tag strings from DOM.
  function getTags(){
    var elements = document.getElementsByTagName('tspan');
    var tags = [];

    for(var x = 0; x < elements.length; x++){
      tags.push(elements[x].textContent.replace(/.*- /, ''));
    }
    return tags;
  }
  // Get username from DOM.
  function getUsername(){
    return document.getElementsByClassName('userPage_heading')[0].children[0].textContent;
  }
}
<|endoftext|>


<commit_before>import React from 'react';
import { Provider } from 'react-redux';
import PropTypes from 'prop-types';
import configureStore from '../store/configureStore';
import { hydrateStore } from '../actions/store';
import { IntlProvider, addLocaleData } from 'react-intl';
import { getLocale } from '../locales';
import PublicTimeline from '../features/standalone/public_timeline';
import HashtagTimeline from '../features/standalone/hashtag_timeline';

const { localeData, messages } = getLocale();
addLocaleData(localeData);

const store = configureStore();
const initialStateContainer = document.getElementById('initial-state');

if (initialStateContainer !== null) {
  const initialState = JSON.parse(initialStateContainer.textContent);
  store.dispatch(hydrateStore(initialState));
}

export default class TimelineContainer extends React.PureComponent {

  static propTypes = {
    locale: PropTypes.string.isRequired,
    hashtag: PropTypes.string,
  };

  render () {
    const { locale, hashtag } = this.props;

    let timeline;

    if (hashtag) {
      timeline = <HashtagTimeline hashtag={hashtag} />;
    } else {
      timeline = <PublicTimeline />;
    }

    return (
      <IntlProvider locale={locale} messages={messages}>
        <Provider store={store}>
          {timeline}
        </Provider>
      </IntlProvider>
    );
  }

}
<commit_msg>Fix standalone timeline (show community timeline again)<commit_after>import React from 'react';
import { Provider } from 'react-redux';
import PropTypes from 'prop-types';
import configureStore from '../store/configureStore';
import { hydrateStore } from '../actions/store';
import { IntlProvider, addLocaleData } from 'react-intl';
import { getLocale } from '../locales';
import PublicTimeline from '../features/standalone/community_timeline';
import HashtagTimeline from '../features/standalone/hashtag_timeline';

const { localeData, messages } = getLocale();
addLocaleData(localeData);

const store = configureStore();
const initialStateContainer = document.getElementById('initial-state');

if (initialStateContainer !== null) {
  const initialState = JSON.parse(initialStateContainer.textContent);
  store.dispatch(hydrateStore(initialState));
}

export default class TimelineContainer extends React.PureComponent {

  static propTypes = {
    locale: PropTypes.string.isRequired,
    hashtag: PropTypes.string,
  };

  render () {
    const { locale, hashtag } = this.props;

    let timeline;

    if (hashtag) {
      timeline = <HashtagTimeline hashtag={hashtag} />;
    } else {
      timeline = <PublicTimeline />;
    }

    return (
      <IntlProvider locale={locale} messages={messages}>
        <Provider store={store}>
          {timeline}
        </Provider>
      </IntlProvider>
    );
  }

}
<|endoftext|>


<commit_before>// This is the main application configuration file.  It is a Grunt
// configuration file, which you can learn more about here:
// https://github.com/cowboy/grunt/blob/master/docs/configuring.md
module.exports = function(grunt) {

  grunt.initConfig({

    // The clean task ensures all files are removed from the dist/ directory so
    // that no files linger from previous builds.
    clean: ["dist/"],

    // The lint task will run the build configuration and the application
    // JavaScript through JSHint and report any errors.  You can change the
    // options for this task, by reading this:
    // https://github.com/cowboy/grunt/blob/master/docs/task_lint.md
    lint: {
      files: [
        "build/config.js", "app/**/*.js"
      ]
    },

    // The jshint option for scripturl is set to lax, because the anchor
    // override inside main.js needs to test for them so as to not accidentally
    // route.
    jshint: {
      options: {
        scripturl: true
      }
    },

    // The jst task compiles all application templates into JavaScript
    // functions with the underscore.js template function from 1.2.4.  You can
    // change the namespace and the template options, by reading this:
    // https://github.com/gruntjs/grunt-contrib/blob/master/docs/jst.md
    //
    // The concat task depends on this file to exist, so if you decide to
    // remove this, ensure concat is updated accordingly.
    jst: {
      "dist/debug/templates.js": [
        "app/templates/**/*.html"
      ]
    },

    // The concatenate task is used here to merge the almond require/define
    // shim and the templates into the application code.  It's named
    // dist/debug/require.js, because we want to only load one script file in
    // index.html.
    concat: {
      "dist/debug/require.js": [
        "assets/js/libs/almond.js",
        "dist/debug/templates.js",
        "dist/debug/require.js"
      ]
    },

    // This task uses the MinCSS Node.js project to take all your CSS files in
    // order and concatenate them into a single CSS file named index.css.  It
    // also minifies all the CSS as well.  This is named index.css, because we
    // only want to load one stylesheet in index.html.
    mincss: {
      "dist/release/index.css": [
        "assets/css/h5bp.css"
      ]
    },

    // Takes the built require.js file and minifies it for filesize benefits.
    min: {
      "dist/release/require.js": [
        "dist/debug/require.js"
      ]
    },

    // Running the server without specifying an action will run the defaults,
    // port: 8000 and host: 127.0.0.1.  If you would like to change these
    // defaults, simply add in the properties `port` and `host` respectively.
    // Alternatively you can omit the port and host properties and the server
    // task will instead default to process.env.PORT or process.env.HOST.
    //
    // Changing the defaults might look something like this:
    //
    // server: {
    //   host: "127.0.0.1", port: 9001
    //   debug: { ... can set host and port here too ...
    //  }
    //
    //  To learn more about using the server task, please refer to the code
    //  until documentation has been written.
    server: {
      // Ensure the favicon is mapped correctly.
      files: { "favicon.ico": "favicon.ico" },

      debug: {
        // Ensure the favicon is mapped correctly.
        files: { "favicon.ico": "favicon.ico" },

        // Map `server:debug` to `debug` folders.
        folders: {
          "app": "dist/debug",
          "assets/js/libs": "dist/debug"
        }
      },

      release: {
        // This makes it easier for deploying, by defaulting to any IP.
        host: "0.0.0.0",

        // Ensure the favicon is mapped correctly.
        files: { "favicon.ico": "favicon.ico" },

        // Map `server:release` to `release` folders.
        folders: {
          "app": "dist/release",
          "assets/js/libs": "dist/release",
          "assets/css": "dist/release"
        }
      }
    },

    // This task uses James Burke's excellent r.js AMD build tool.  In the
    // future other builders may be contributed as drop-in alternatives.
    requirejs: {
      // Include the main configuration file.
      mainConfigFile: "app/config.js",

      // Output file.
      out: "dist/debug/require.js",

      // Root application module.
      name: "config",

      // Do not wrap everything in an IIFE.
      wrap: false
    },

    // The headless QUnit testing environment is provided for "free" by Grunt.
    // Simply point the configuration to your test directory.
    qunit: {
      all: ["test/qunit/*.html"]
    },

    // The headless Jasmine testing is provided by grunt-jasmine-task. Simply
    // point the configuration to your test directory.
    jasmine: {
      all: ["test/jasmine/*.html"]
    }

  });

  // The default task will remove all contents inside the dist/ folder, lint
  // all your code, precompile all the underscore templates into
  // dist/debug/templates.js, compile all the application code into
  // dist/debug/require.js, and then concatenate the require/define shim
  // almond.js and dist/debug/templates.js into the require.js file.
  grunt.registerTask("default", "clean lint jst requirejs concat");

  // The debug task is simply an alias to default to remain consistent with
  // debug/release.
  grunt.registerTask("debug", "default");

  // The release task will run the debug tasks and then minify the
  // dist/debug/require.js file and CSS files.
  grunt.registerTask("release", "default min mincss");

};
<commit_msg>Suggestion to fix #104 <commit_after>// This is the main application configuration file.  It is a Grunt
// configuration file, which you can learn more about here:
// https://github.com/cowboy/grunt/blob/master/docs/configuring.md
module.exports = function(grunt) {

  grunt.initConfig({

    // The clean task ensures all files are removed from the dist/ directory so
    // that no files linger from previous builds.
    clean: ["dist/"],

    // The lint task will run the build configuration and the application
    // JavaScript through JSHint and report any errors.  You can change the
    // options for this task, by reading this:
    // https://github.com/cowboy/grunt/blob/master/docs/task_lint.md
    lint: {
      files: [
        "build/config.js", "app/**/*.js"
      ]
    },

    // The jshint option for scripturl is set to lax, because the anchor
    // override inside main.js needs to test for them so as to not accidentally
    // route.
    jshint: {
      options: {
        scripturl: true
      }
    },

    // The jst task compiles all application templates into JavaScript
    // functions with the underscore.js template function from 1.2.4.  You can
    // change the namespace and the template options, by reading this:
    // https://github.com/gruntjs/grunt-contrib/blob/master/docs/jst.md
    //
    // The concat task depends on this file to exist, so if you decide to
    // remove this, ensure concat is updated accordingly.
    jst: {
      "dist/debug/templates.js": [
        "app/templates/**/*.html"
      ]
    },

    // The handlebars task compiles all application templates into JavaScript
    // functions using Handlebars templating engine. You will need to install
    // grunt-handlebars globally in order to run this task.
    //
    // Since this task defaults to writing to the same file as the jst task,
    // edit the task or avoid using the two at the same time.
    //
    // The concat task depends on this file to exist, so if you decide to
    // remove this, ensure concat is updated accordingly.
    handlebars: {
      all: {
        src: "app/templates",
        dest: "dist/debug/templates.js"
      }
    },

    // The concatenate task is used here to merge the almond require/define
    // shim and the templates into the application code.  It's named
    // dist/debug/require.js, because we want to only load one script file in
    // index.html.
    concat: {
      "dist/debug/require.js": [
        "assets/js/libs/almond.js",
        "dist/debug/templates.js",
        "dist/debug/require.js"
      ]
    },

    // This task uses the MinCSS Node.js project to take all your CSS files in
    // order and concatenate them into a single CSS file named index.css.  It
    // also minifies all the CSS as well.  This is named index.css, because we
    // only want to load one stylesheet in index.html.
    mincss: {
      "dist/release/index.css": [
        "assets/css/h5bp.css"
      ]
    },

    // Takes the built require.js file and minifies it for filesize benefits.
    min: {
      "dist/release/require.js": [
        "dist/debug/require.js"
      ]
    },

    // Running the server without specifying an action will run the defaults,
    // port: 8000 and host: 127.0.0.1.  If you would like to change these
    // defaults, simply add in the properties `port` and `host` respectively.
    // Alternatively you can omit the port and host properties and the server
    // task will instead default to process.env.PORT or process.env.HOST.
    //
    // Changing the defaults might look something like this:
    //
    // server: {
    //   host: "127.0.0.1", port: 9001
    //   debug: { ... can set host and port here too ...
    //  }
    //
    //  To learn more about using the server task, please refer to the code
    //  until documentation has been written.
    server: {
      // Ensure the favicon is mapped correctly.
      files: { "favicon.ico": "favicon.ico" },

      debug: {
        // Ensure the favicon is mapped correctly.
        files: { "favicon.ico": "favicon.ico" },

        // Map `server:debug` to `debug` folders.
        folders: {
          "app": "dist/debug",
          "assets/js/libs": "dist/debug"
        }
      },

      release: {
        // This makes it easier for deploying, by defaulting to any IP.
        host: "0.0.0.0",

        // Ensure the favicon is mapped correctly.
        files: { "favicon.ico": "favicon.ico" },

        // Map `server:release` to `release` folders.
        folders: {
          "app": "dist/release",
          "assets/js/libs": "dist/release",
          "assets/css": "dist/release"
        }
      }
    },

    // This task uses James Burke's excellent r.js AMD build tool.  In the
    // future other builders may be contributed as drop-in alternatives.
    requirejs: {
      // Include the main configuration file.
      mainConfigFile: "app/config.js",

      // Output file.
      out: "dist/debug/require.js",

      // Root application module.
      name: "config",

      // Do not wrap everything in an IIFE.
      wrap: false
    },

    // The headless QUnit testing environment is provided for "free" by Grunt.
    // Simply point the configuration to your test directory.
    qunit: {
      all: ["test/qunit/*.html"]
    },

    // The headless Jasmine testing is provided by grunt-jasmine-task. Simply
    // point the configuration to your test directory.
    jasmine: {
      all: ["test/jasmine/*.html"]
    }

  });

  // The default task will remove all contents inside the dist/ folder, lint
  // all your code, precompile all the underscore templates into
  // dist/debug/templates.js, compile all the application code into
  // dist/debug/require.js, and then concatenate the require/define shim
  // almond.js and dist/debug/templates.js into the require.js file.
  grunt.registerTask("default", "clean lint jst requirejs concat");

  // The debug task is simply an alias to default to remain consistent with
  // debug/release.
  grunt.registerTask("debug", "default");

  // The release task will run the debug tasks and then minify the
  // dist/debug/require.js file and CSS files.
  grunt.registerTask("release", "default min mincss");

};
<|endoftext|>


<commit_before>"use strict";

var value = require("value"),
    defaultValidators = require("./validators.js");

/**
 * Runs the given validators on a single field
 *
 * @private
 * @param {Array} validators
 * @param {*} field
 * @param {Object} context
 * @param {Function} callback
 */
function runValidation(validators, field, context, callback) {
    var result = [],
        pending = validators.length;

    function validationDone(res) {
        pending--;

        if (res !== true) {
            result.push(res);
        }

        if (pending === 0) {
            callback(result);
        }
    }

    validators.forEach(function (validator) {
        //async
        if (validator.length === 2) {
            validator.call(context, field, validationDone);
        }
        //sync
        else {
            //no setImmediate on client!
            setTimeout(function () {
                validationDone(validator.call(context, field));
            }, 0);
        }
    });
}

/**
 * Adds validation methods to the schema
 *
 * @param {Function} Schema
 */
function validationPlugin(Schema) {

    var constructor = Schema.prototype.constructor;

    Schema.prototype.constructor = function (name, schema) {
        var key,
            fieldDefinition;

        if (arguments.length === 1) {
            schema = arguments[0];
        }

        //call super constructor
        constructor.apply(this, arguments);

        this.validators = {};

        for (key in schema) {
            if (schema.hasOwnProperty(key)) {
                fieldDefinition = schema[key];
                this.validators[key] = [];

                //predefined validators
                if (fieldDefinition.required) {
                    this.validators[key].push(defaultValidators.required());
                }
                if (value(fieldDefinition.enum).typeOf(Array)) {
                    this.validators[key].push(defaultValidators.enum(fieldDefinition.enum));
                }

                if (value(fieldDefinition.min).typeOf(Number)) {
                    this.validators[key].push(defaultValidators.min(fieldDefinition.min));
                }

                if (value(fieldDefinition.max).typeOf(Number)) {
                    this.validators[key].push(defaultValidators.min(fieldDefinition.max));
                }

                //custom validators
                if (value(fieldDefinition.validate).typeOf(Function)) {
                    this.validators[key].push(fieldDefinition.validate);
                } else if (value(fieldDefinition.validate).typeOf(Array)) {
                    this.validators[key] = this.validators[key].concat(fieldDefinition.validate);
                }
            }
        }
    };

    /**
     * Validate if given model matches schema-definition
     * @param {Object} model
     * @param {Function} callback
     */
    Schema.prototype.validate = function (model, callback) {
        var self = this,
            pending = 0,
            result = {
                result: true,
                failedFields: {}
            };

        this.keys.forEach(function (key) {
            if (self.validators[key].length === 0) {
                return;
            }

            pending++;
            runValidation(self.validators[key], model[key], model, function (res) {
                pending--;

                if (res.length > 0) {
                    result.result = false;
                    result.failedFields[key] = res;
                }

                if (pending === 0) {
                    callback(result);
                }
            });
        });
    };
}

module.exports = validationPlugin;<commit_msg>- fixed min & max validators<commit_after>"use strict";

var value = require("value"),
    defaultValidators = require("./validators.js");

/**
 * Runs the given validators on a single field
 *
 * @private
 * @param {Array} validators
 * @param {*} field
 * @param {Object} context
 * @param {Function} callback
 */
function runValidation(validators, field, context, callback) {
    var result = [],
        pending = validators.length;

    function validationDone(res) {
        pending--;

        if (res !== true) {
            result.push(res);
        }

        if (pending === 0) {
            callback(result);
        }
    }

    validators.forEach(function (validator) {
        //async
        if (validator.length === 2) {
            validator.call(context, field, validationDone);
        }
        //sync
        else {
            //no setImmediate on client!
            setTimeout(function () {
                validationDone(validator.call(context, field));
            }, 0);
        }
    });
}

/**
 * Adds validation methods to the schema
 *
 * @param {Function} Schema
 */
function validationPlugin(Schema) {

    var constructor = Schema.prototype.constructor;

    Schema.prototype.constructor = function (name, schema) {
        var key,
            fieldDefinition;

        if (arguments.length === 1) {
            schema = arguments[0];
        }

        //call super constructor
        constructor.apply(this, arguments);

        this.validators = {};

        for (key in schema) {
            if (schema.hasOwnProperty(key)) {
                fieldDefinition = schema[key];
                this.validators[key] = [];

                //predefined validators
                if (fieldDefinition.required) {
                    this.validators[key].push(defaultValidators.required());
                }
                if (value(fieldDefinition.enum).typeOf(Array)) {
                    this.validators[key].push(defaultValidators.enum(fieldDefinition.enum));
                }

                if (value(fieldDefinition.min).typeOf(Number)) {
                    this.validators[key].push(defaultValidators.min(fieldDefinition.min));
                }

                if (value(fieldDefinition.max).typeOf(Number)) {
                    this.validators[key].push(defaultValidators.max(fieldDefinition.max));
                }

                //custom validators
                if (value(fieldDefinition.validate).typeOf(Function)) {
                    this.validators[key].push(fieldDefinition.validate);
                } else if (value(fieldDefinition.validate).typeOf(Array)) {
                    this.validators[key] = this.validators[key].concat(fieldDefinition.validate);
                }
            }
        }
    };

    /**
     * Validate if given model matches schema-definition
     * @param {Object} model
     * @param {Function} callback
     */
    Schema.prototype.validate = function (model, callback) {
        var self = this,
            pending = 0,
            result = {
                result: true,
                failedFields: {}
            };

        this.keys.forEach(function (key) {
            if (self.validators[key].length === 0) {
                return;
            }

            pending++;
            runValidation(self.validators[key], model[key], model, function (res) {
                pending--;

                if (res.length > 0) {
                    result.result = false;
                    result.failedFields[key] = res;
                }

                if (pending === 0) {
                    callback(result);
                }
            });
        });
    };
}

module.exports = validationPlugin;<|endoftext|>


<commit_before>
'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;

const scriptRules = require('./script.json');

var myDate = new Date();
var groet = '';

/* hour is before noon */
if ( myDate.getHours() < 8 )
{
  groet = "Goeiemorgen 🌝.  Bedankt voor je bezoek maar op dit moment is Independer echter gesloten. 🕘 Uiteraard kun je met onze IndyBot verder praten maar er is helaas niemand die jouw vraag specifiek kan beantwoorden. Je kan je vraag ook doormailen 📩 naar info@independer. Dan komt het altijd goed.";
}
else
if ( myDate.getHours() >8 )
{
  groet = "Goeiemorgen 🌝 ";
}
else  /* Hour is from noon to 5pm (actually to 5:59 pm) */
if ( myDate.getHours() >= 12 && myDate.getHours() <= 17 )
{
groet = "Goedendag 🌞";
}
else  /* the hour is after 5pm, so it is between 6pm and midnight */
if ( myDate.getHours() > 17&& myDate.getHours() <= 20 )
{
groet = "Goedenavond 🌙";
}
else
if (myDate.getHours() > 20  || myDate.getHours() <= 24 )
{
  groet = "Goedenavond 🌙  Bedankt voor je bezoek maar op dit moment is Independer echter gesloten. 🕘 Uiteraard kun je met onze IndyBot verder praten maar er is helaas niemand die jouw vraag specifiek kan beantwoorden. Je kan je vraag ook doormailen 📩 naar info@independer. Dan komt het altijd goed.";
}
else  /* the hour is not between 0 and 24, so something is wrong */
{
groet = "Welkom. ";
}

function wait(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}

module.exports = new Script({

 processing: {
prompt: (bot) => bot.say('![](http://www.bieg.nl/beeld/speechbubble.gif)'),
 receive: () => 'processing'
 },

start: {
    receive: (bot,message) => {
        const opening = message.text.trim().toUpperCase();
        return bot.say(`${groet}... Wat voor soort hypotheek zoek je? `)
        .then(() => bot.say(`![](http://www.bieg.nl/beeld/woningen.jpg)`))
        .then(() => bot.say(`%[Starters Hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`))
        .then(() => 'selecteerHypotheek');
    }
},

selecteerHypotheek: {
    receive: (bot, message) => {
      switch(message.text) {
      case 'Hoi':
            return bot.say(`${groet} waar ben je naar op zoek? %[Starters hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`)
            .then(() => 'askName')
          break;
      case 'Starters Hypotheek':
          return bot.say(`Wat voor type woning zoek je? `)
          .then(() => bot.say(`%[🏬 Appartement](postback:hypotheekkeuze_appartement) %[🏠 Huis](postback:hypotheekkeuze_huis) %[📭 Vakantiewoning](postback:hypotheekkeuze_vakantiewoning)`))
          .then(() => 'woningType')
              break;
        case 'Nieuwe hypotheek':
          return bot.say(`😞 Helaas biedt Independer momenteel alleen Starters een hypotheek aan.`)
          .then(() => bot.say(`Via onderstaande link kun je de beste hypotheekadviseur voor jou vinden. %[💼 Zoek Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/jelocatie.aspx)`))
            .then(() => 'finish')
          break;
        case 'Hypotheek oversluiten':
          return bot.say(`😟 Het spijt me maar op dit moment biedt Independer alleen  Starters een hypotheek.`)
          .then(()=> bot.say(`Als het allemaal wel zo ver is, wil je dan een update ontvangen? %[Ja, dat wil ik wel](postback:update_ja) %[Nee, dat hoeft niet](postback:update_nee)`))
            .then(() => 'updateOntvangen')
          break;
        default:
          return bot.say(`![](http://www.bieg.nl/beeld/speechbubble.gif)`)
            .then(() => 'processing')
          break;
      }
    }
},

updateOntvangen: {
    receive: (bot, message) => {
      switch(message.text) {
        case 'Ja, dat wil ik wel':
            return bot.say(`👍 Leuk, dan houd ik  je op de hoogte zodra er weer nieuws is.`)
            .then(() => 'update_ja');
          break;
          case 'Nee, dat hoeft niet':
              receive: () => 'bye'
              break;
          default:
            receive => 'processing'
            break;
}
}
},

update_ja: {
  prompt: (bot) => bot.say('Wat is je email adres?'),
      receive: (bot, message) => {
          const emailer=message.text;
          return bot.setProp('emailer', emailer)
              .then(()  => bot.say(`Ok - ✉  dan hou ik je via ${emailer} op de hoogte.`))
              .then(()  =>'lastCheck')
    }
},
update_nee: {
  receive: () => 'bye'
},

hypotheekkeuze_appartement: {
receive: (bot,message)  => {
    //  prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
    receive: () => 'askName'
}
},
hypotheekkeuze_huis: {
//    prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
  receive: () => 'askName'
},
hypotheekkeuze_vakantiewoning: {
//    prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
    receive: () => 'askName'
},
hypotheekStarter: {
    receive: () => 'askName'
},
hypotheektype_nieuw: {
    prompt: (bot) => bot.say('Independer biedt momenteel alleen voor Starters een hypotheek. Onderstaande link bied je meer informatie %[Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/intro.aspx)'),
    receive: () => 'processing'
},

woningType: {
  receive: (bot, message) => {
    switch(message.text) {
        case '🏬 Appartement':
          return bot.say(`Nice!`)
          .then(() => 'vervolgVragen')
          break;
      case '🏠 Huis':
          return bot.say(`Leuk`)
          .then(() => 'vervolgVragen')
          break;
    case '📭 Vakantiewoning':
          return bot.say(`Gezellig`)
          .then(() => 'vervolgVragen')
          break;
      default:
        receive => 'processing'
        break;
        }
    }
},

vervolgVragen: {
  prompt: (bot) => bot.say('Hoe heet je eigelijk? 😋 Dat maakt het praten een stuk makkelijker...'),
  receive: (bot, message) => {
      const name = message.text;
      return bot.setProp('name', name)
          .then(() => bot.say('Hoi ${name}. 📋 Ik heb nog wat vragen voor je om verder te kunnen.'))
          .then(() => 'processing');
    }
},

lastCheck: {
    prompt: (bot) => bot.say(' Is er nog iets waar ik  je bij kan helpen?  🚦  %[Ik zoek meer informatie](postback:meerInfo) %[Nee hoor](postback:bye)'),
          receive: (bot, message) => {
            switch(message.text) {
              case 'Nee hoor':
                  receive: ()  => 'bye'
                  break;
             case 'Ik zoek meer informatie':
                  receive: () => 'meerInfo'
                  break;
            case 'Nee':
                  receive: () => 'bye'
                  break;
            default:
              return bot.say('![](http://www.bieg.nl/beeld/speechbubble.gif)')
                .then(() => 'processing')
              break;
            }
        }
},

bye: {
    prompt: (bot) => bot.say('Fijn je gesproken te hebben. Bedankt voor je tijd ⏲'),
    receive: ()  => 'finish'
},

// error: {
// prompt: (bot) => bot.say('Sorry - kun je dat nog eens zeggen?  Er ging iets mis...'),
// receive: () => ''
// },

finish: {
receive: () => 'finish'
},

  speak: {
          receive: (bot, message) => {

              let upperText = message.text.trim().toUpperCase();

              function updateSilent() {
                  switch (upperText) {
                      case "CONNECT ME":
                          return bot.setProp("silent", true);
                      case "DISCONNECT":
                          return bot.setProp("silent", false);
                      default:
                          return Promise.resolve();
                  }
              }

              function getSilent() {
                  return bot.getProp("silent");
              }

              function processMessage(isSilent) {
                  if (isSilent) {
                      return Promise.resolve("speak");
                  }

                  if (!_.has(scriptRules, upperText)) {
                      return bot.say(`So, I'm good at structured conversations but stickers, emoji and sentences still confuse me. Say 'more' to chat about something else.`).then(() => 'speak');
                  }

                  var response = scriptRules[upperText];
                  var lines = response.split('\n');

                  var p = Promise.resolve();
                  _.each(lines, function(line) {
                      line = line.trim();
                      p = p.then(function() {
                          console.log(line);
                          return wait(50).then(function() {
                              return bot.say(line);
                          });
                      });
                  });

                  return p.then(() => 'speak');
              }

              return updateSilent()
                  .then(getSilent)
                  .then(processMessage);
          }
      }
});
<commit_msg>vc<commit_after>
'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;

const scriptRules = require('./script.json');

var myDate = new Date();
var groet = '';

/* hour is before noon */
if ( myDate.getHours() < 8 )
{
  groet = "Goeiemorgen 🌝.  Bedankt voor je bezoek maar op dit moment is Independer echter gesloten. 🕘 Uiteraard kun je met onze IndyBot verder praten maar er is helaas niemand die jouw vraag specifiek kan beantwoorden. Je kan je vraag ook doormailen 📩 naar info@independer. Dan komt het altijd goed.";
}
else
if ( myDate.getHours() >8 )
{
  groet = "Goeiemorgen 🌝 ";
}
else  /* Hour is from noon to 5pm (actually to 5:59 pm) */
if ( myDate.getHours() >= 12 && myDate.getHours() <= 17 )
{
groet = "Goedendag 🌞";
}
else  /* the hour is after 5pm, so it is between 6pm and midnight */
if ( myDate.getHours() > 17&& myDate.getHours() <= 20 )
{
groet = "Goedenavond 🌙";
}
else
if (myDate.getHours() > 20  || myDate.getHours() <= 24 )
{
  groet = "Goedenavond 🌙  Bedankt voor je bezoek maar op dit moment is Independer echter gesloten. 🕘 Uiteraard kun je met onze IndyBot verder praten maar er is helaas niemand die jouw vraag specifiek kan beantwoorden. Je kan je vraag ook doormailen 📩 naar info@independer. Dan komt het altijd goed.";
}
else  /* the hour is not between 0 and 24, so something is wrong */
{
groet = "Welkom. ";
}

function wait(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}

module.exports = new Script({

 processing: {
prompt: (bot) => bot.say('![](http://www.bieg.nl/beeld/speechbubble.gif)'),
 receive: () => 'processing'
 },

start: {
    receive: (bot,message) => {
        const opening = message.text.trim().toUpperCase();
        return bot.say(`${groet}... Wat voor soort hypotheek zoek je? `)
        .then(() => bot.say(`![](http://www.bieg.nl/beeld/woningen.jpg)`))
        .then(() => bot.say(`%[Starters Hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`))
        .then(() => 'selecteerHypotheek');
    }
},

selecteerHypotheek: {
    receive: (bot, message) => {
      switch(message.text) {
      case 'Hoi':
            return bot.say(`${groet} waar ben je naar op zoek? %[Starters hypotheek](postback:hypotheektype_starter) %[Nieuwe hypotheek](postback:hypotheektype_nieuw) %[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`)
            .then(() => 'askName')
          break;
      case 'Starters Hypotheek':
          return bot.say(`Wat voor type woning zoek je? `)
          .then(() => bot.say(`%[🏬 Appartement](postback:hypotheekkeuze_appartement) %[🏠 Huis](postback:hypotheekkeuze_huis) %[📭 Vakantiewoning](postback:hypotheekkeuze_vakantiewoning)`))
          .then(() => 'woningType')
              break;
        case 'Nieuwe hypotheek':
          return bot.say(`😞 Helaas biedt Independer momenteel alleen Starters een hypotheek aan.`)
          .then(() => bot.say(`Via onderstaande link kun je de beste hypotheekadviseur voor jou vinden. %[💼 Zoek Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/jelocatie.aspx)`))
            .then(() => 'finish')
          break;
        case 'Hypotheek oversluiten':
          return bot.say(`😟 Het spijt me maar op dit moment biedt Independer alleen  Starters een hypotheek.`)
          .then(()=> bot.say(`Als het allemaal wel zo ver is, wil je dan een update ontvangen? %[Ja, dat wil ik wel](postback:update_ja) %[Nee, dat hoeft niet](postback:update_nee)`))
            .then(() => 'updateOntvangen')
          break;
        default:
          return bot.say(`![](http://www.bieg.nl/beeld/speechbubble.gif)`)
            .then(() => 'processing')
          break;
      }
    }
},

updateOntvangen: {
    receive: (bot, message) => {
      switch(message.text) {
        case 'Ja, dat wil ik wel':
            return bot.say(`👍 Leuk, dan houd ik  je op de hoogte zodra er weer nieuws is.`)
            .then(() => 'update_ja');
          break;
          case 'Nee, dat hoeft niet':
              receive: () => 'bye'
              break;
          default:
            receive => 'processing'
            break;
}
}
},

update_ja: {
  prompt: (bot) => bot.say('Wat is je email adres?'),
      receive: (bot, message) => {
          const emailer=message.text;
          return bot.setProp('emailer', emailer)
              .then(()  => bot.say(`Ok - ✉  dan hou ik je via ${emailer} op de hoogte.`))
              .then(()  =>'lastCheck')
    }
},
update_nee: {
  receive: () => 'bye'
},

hypotheekkeuze_appartement: {
receive: (bot,message)  => {
    //  prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
    receive: () => 'askName'
}
},
hypotheekkeuze_huis: {
//    prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
  receive: () => 'askName'
},
hypotheekkeuze_vakantiewoning: {
//    prompt: (bot) => bot.say(`![](http:www.bieg.nl/beeld/appartement.jpg)`)
    receive: () => 'askName'
},
hypotheekStarter: {
    receive: () => 'askName'
},
hypotheektype_nieuw: {
    prompt: (bot) => bot.say('Independer biedt momenteel alleen voor Starters een hypotheek. Onderstaande link bied je meer informatie %[Hypotheek Adviseur](https://www.independer.nl/hypotheekadviseur/intro.aspx)'),
    receive: () => 'processing'
},

woningType: {
  receive: (bot, message) => {
    switch(message.text) {
        case '🏬 Appartement':
          return bot.say(`Nice!`)
          .then(() => 'vervolgVragen')
          break;
      case '🏠 Huis':
          return bot.say(`Leuk`)
          .then(() => 'vervolgVragen')
          break;
    case '📭 Vakantiewoning':
          return bot.say(`Gezellig`)
          .then(() => 'vervolgVragen')
          break;
      default:
        receive => 'processing'
        break;
        }
    }
},

vervolgVragen: {
  prompt: (bot) => bot.say('Hoe heet je eigelijk? 😋 Dat maakt het praten een stuk makkelijker...'),
  receive: (bot, message) => {
      const name = message.text;
      return bot.setProp('name', name)
          .then(() => bot.say('Hoi ${name}. 📋 Ik heb nog wat vragen voor je om verder te kunnen.'))
          .then(() => 'processing');
    }
},

lastCheck: {
    prompt: (bot) => bot.say(' Is er nog iets waar ik  je bij kan helpen?  🚦  %[Ik zoek meer informatie](postback:meerInfo) %[Nee hoor](postback:bye)'),
          receive: (bot, message) => {
            switch(message.text) {
              case 'Nee hoor':
                  receive: ()  => 'bye'
                  break;
             case 'Ik zoek meer informatie':
                  receive: () => 'meerInfo'
                  break;
            case 'Nee':
                  receive: () => 'bye'
                  break;
            default:
              return bot.say('![](http://www.bieg.nl/beeld/speechbubble.gif)')
                .then(() => 'processing')
              break;
            }
        }
},

meerInfo: {
  prompt: (bot) => bot.say('![](http://www.bieg.nl/beeld/info.pdf)'),
   receive: () => 'processing'
},

bye: {
    prompt: (bot) => bot.say('Fijn je gesproken te hebben. Bedankt voor je tijd ⏲'),
    receive: ()  => 'finish'
},

// error: {
// prompt: (bot) => bot.say('Sorry - kun je dat nog eens zeggen?  Er ging iets mis...'),
// receive: () => ''
// },

finish: {
receive: () => 'finish'
},

  speak: {
          receive: (bot, message) => {

              let upperText = message.text.trim().toUpperCase();

              function updateSilent() {
                  switch (upperText) {
                      case "CONNECT ME":
                          return bot.setProp("silent", true);
                      case "DISCONNECT":
                          return bot.setProp("silent", false);
                      default:
                          return Promise.resolve();
                  }
              }

              function getSilent() {
                  return bot.getProp("silent");
              }

              function processMessage(isSilent) {
                  if (isSilent) {
                      return Promise.resolve("speak");
                  }

                  if (!_.has(scriptRules, upperText)) {
                      return bot.say(`So, I'm good at structured conversations but stickers, emoji and sentences still confuse me. Say 'more' to chat about something else.`).then(() => 'speak');
                  }

                  var response = scriptRules[upperText];
                  var lines = response.split('\n');

                  var p = Promise.resolve();
                  _.each(lines, function(line) {
                      line = line.trim();
                      p = p.then(function() {
                          console.log(line);
                          return wait(50).then(function() {
                              return bot.say(line);
                          });
                      });
                  });

                  return p.then(() => 'speak');
              }

              return updateSilent()
                  .then(getSilent)
                  .then(processMessage);
          }
      }
});
<|endoftext|>


<commit_before>// This is the main html5-boilerplate build configuration file.
//
// Builds depends on two specific directory created during the process
// `intermediate/` and `publish/`, the first is used as a staging area, the
// second is the final result of the build that was run.
//
// These two values may be changed to something else with the `staging` and
// `output` config property below, and by changing any task config to match the new value.
//

config.init({
  // the staging directory used during the process
  staging: 'intermediate/',
  // final build output
  output: 'publish/',

  // mkdirs task - filter any files matching one of the below pattern
  exclude: 'build/** node_modules/** intermediate/** publish/** grunt.js package.json *.md'.split(' '),

  mkdirs: {
    staging: '<config:exclude>',
    output: '<config:exclude>'
  },

  concat: {
    'intermediate/js/scripts.js': [ 'js/plugins.js', 'js/script.js' ],
    'intermediate/css/style.css': [ 'css/*.css' ]
  },

  css: {
    'publish/css/style.css': [ 'css/style.css' ]
  },

  min: {
    'publish/js/scripts.js': [ 'intermediate/js/scripts.js' ]
  },

  rev: {
    js: ['publish/js/*.js'],
    css: ['publish/css/*.css'],
    img: ['publish/img/*']
  },

  usemin: {
    files: ['publish/*.html']
  },

  manifest: '<config:usemin>',

  lint: {
    files: ['js/*.js'],
    build: ['grunt.js', 'tasks/*.js']
  },

  watch: {
    files: ['js/*.js', 'css/**', '*.html'],
    tasks: 'default',

    reload: {
      files: '<config:watch.files>',
      tasks: 'default emit'
    }
  },

  serve: {
    intermediate: { port: 3000 },
    publish: { port: 3001 }
  },

  connect: {
    intermediate: {
      hostname: 'localhost',
      port: 3000,
      logs: 'dev',
      dirs: true
    },
    publish: {
      hostname: 'localhost',
      port: 3001,
      logs: 'default',
      dirs: true
    }
  }
});

// Run the following tasks...
task.registerTask('default', 'intro clean mkdirs concat css min rev usemin manifest');

task.registerTask('reload', 'connect watch:reload');
<commit_msg>rewrite of grunt config file to take into account staging / output dirs<commit_after>
var path = require('path');

// This is the main html5-boilerplate build configuration file.
//
// Builds depends on two specific directory created during the process
// `intermediate/` and `publish/`, the first is used as a staging area, the
// second is the final result of the build that was run.
//
// These two values may be changed to something else with the `staging` and
// `output` config property below, and by changing any task config to match the new value.
//

config.init({
  // the staging directory used during the process
  staging: 'intermediate/',
  // final build output
  output: 'publish/',

  // filter any files matching one of the below pattern during mkdirs task
  exclude: 'build/** node_modules/** grunt.js package.json *.md'.split(' '),

  mkdirs: {
    staging: '<config:exclude>',
    output: '<config:exclude>'
  },

  // concat task - files are concat'd into `staging/subprop.js`
  // (eg. intermediate/js/scripts.js)
  concat: {
    'js/scripts.js': [ 'js/plugins.js', 'js/script.js' ],
    'css/style.css': [ 'css/*.css' ]
  },

  // css task - optimized files is generated into `output/subprop.css`
  // (eg. publish/css/style.css)
  css: {
    'css/style.css': [ 'css/style.css' ]
  },

  // min task - like the css task, minified files are generated into
  // `output/subprop.js` (eg. publish/js/scripts.js). Files in subprop value
  // are resolved with `staging` dir value (eg. intermediate/js/scripts.js)
  min: {
    'js/scripts.js': [ 'js/scripts.js' ]
  },

  // rev task - File patterns in suprops values are resolved with `output` value
  // (eg. publish/js/*.js)
  rev: {
    js: ['js/*.js'],
    css: ['css/*.css'],
    img: ['img/*']
  },

  // rev task - File pattern in suprops values are resolved with `output` value
  // (eg. publish/*.html)
  usemin: {
    files: ['*.html']
  },

  manifest: '<config:usemin>',

  watch: {
    files: ['js/*.js', 'css/**', '*.html'],
    tasks: 'default',

    reload: {
      files: '<config:watch.files>',
      tasks: 'default emit'
    }
  },

  serve: {
    staging: { port: 3000 },
    output: { port: 3001 }
  },

  connect: {
    staging: {
      hostname: 'localhost',
      port: 3000,
      logs: 'dev',
      dirs: true
    },
    output: {
      hostname: 'localhost',
      port: 3001,
      logs: 'default',
      dirs: true
    }
  },

  lint: {
    files: ['js/*.js'],
    build: ['grunt.js', 'tasks/*.js']
  }

});

// Run the following tasks...
task.registerTask('default', 'intro clean mkdirs concat css min rev usemin manifest');
task.registerTask('reload', 'connect watch:reload');

// Advanced configuration, doing the necessary logic to map any task needed
// values to top level staging / output dir
//
// ---
//

// exclude - add both staging / output dir as excluded folder during file copy (mkdirs)
config('exclude', config('exclude')
  .concat(path.join(config('staging'), '**'))
  .concat(path.join(config('output'), '**'))
);

// concat - same here prepend the necessary `staging` value into subprop name
var concat = config('concat');
Object.keys(concat).forEach(function(key) {
  var dir = path.join(config('staging'), key);
  concat[dir] = concat[key];
  delete concat[key];
});

// min - same here prepend the necessary `output` and `staging` value into
// subprop name and values
var min = config('min');
Object.keys(min).forEach(function(key) {
  var dir = path.join(config('output'), key);
  min[dir] = min[key].map(function(files) {
    return path.join(config('staging'), files);
  });
  delete min[key];
});

// css - prepend the necessary `output` value into subprop name
var css = config('css');
Object.keys(css).forEach(function(key) {
  var dir = path.join(config('output'), key);
  css[dir] = css[key];
  delete css[key];
});

// css - prepend the necessary `output` dir value into files pattern to handle
var rev = config('rev');
Object.keys(rev).forEach(function(key) {
  rev[key] = rev[key].map(function(files) {
    return path.join(config('output'), files);
  });
});

// usemin - same here, prepend the necessary `output` dir value into files
// pattern to handle
var usemin = config('usemin');
usemin.files = usemin.files.map(function(files) {
  return path.join(config('output'), files);
});

// serve / connect - simply replace staging / output suprop name by their relevant value
var serve = config('serve');
Object.keys(serve).forEach(function(key) {
  serve[config(key)] = serve[key];
  delete serve[key];
});

var connect = config('connect');
Object.keys(connect).forEach(function(key) {
  connect[config(key)] = connect[key];
  delete connect[key];
});

<|endoftext|>


<commit_before>import { createAction } from 'redux-actions';
import { createThunkAction } from 'utils/redux';

// REMOVE WHEN FEATURE READY
import image1 from 'assets/news/1.png';
import image2 from 'assets/news/2.png';
import image3 from 'assets/news/3.jpg';
import image4 from 'assets/news/4.jpg';
import image6 from 'assets/news/6.jpg';

const stories = [
  {
    id: 1,
    title: 'Got Climate Questions? Climate Watch Has Answers',
    background_image_url: image6,
    link:
      '//www.wri.org/blog/2017/11/got-climate-questions-climate-watch-has-answers'
  },
  {
    id: 2,
    title:
      'This Interactive Chart Explains World’s Top 10 Emitters, and How They’ve Changed',
    background_image_url: image2,
    link:
      '//www.wri.org/blog/2017/04/interactive-chart-explains-worlds-top-10-emitters-and-how-theyve-changed'
  },
  {
    id: 3,
    title:
      'RELEASE: Climate Watch: Powerful New Platform Offers Comprehensive Data for Climate Action',
    background_image_url: image1,
    link:
      '//www.wri.org/news/2017/11/release-climate-watch-powerful-new-platform-offers-comprehensive-data-climate-action'
  },
  {
    id: 4,
    title:
      '6 Things You Never Knew About Indonesia’s Emissions and Local Climate Action',
    background_image_url: image3,
    link:
      '//www.wri.org/blog/2016/06/6-things-you-never-knew-about-indonesias-emissions-and-local-climate-action'
  },
  {
    id: 5,
    title:
      '3 New Ways to Explore Links Between Climate and Sustainable Development',
    background_image_url: image4,
    link:
      '//www.wri.org/blog/2017/12/3-new-ways-explore-links-between-climate-and-sustainable-development'
  }
];

const fetchStoriesInit = createAction('fetchStoriesInit');
const fetchStoriesReady = createAction('fetchStoriesReady');
const fetchStoriesFail = createAction('fetchStoriesFail');

// const TAGS = ['NDC', 'ndcsdg', 'esp', 'climate watch'];

const fetchStories = createThunkAction('fetchStories', () => dispatch => {
  dispatch(fetchStoriesReady(stories));
  // GET BACK WHEN FEATURE READY
  // dispatch(fetchStoriesInit());
  // fetch(`/api/v1/stories?tags=${TAGS}`)
  //   .then(response => {
  //     if (response.ok) return response.json();
  //     throw Error(response.statusText);
  //   })
  //   .then(data => {
  //     dispatch(fetchStoriesReady(data));
  //   })
  //   .catch(error => {
  //     console.info(error);
  //     dispatch(fetchStoriesFail());
  //   });
});

export default {
  fetchStories,
  fetchStoriesInit,
  fetchStoriesReady,
  fetchStoriesFail
};
<commit_msg>Get stories from API<commit_after>import { createAction } from 'redux-actions';
import { createThunkAction } from 'utils/redux';

const fetchStoriesInit = createAction('fetchStoriesInit');
const fetchStoriesReady = createAction('fetchStoriesReady');
const fetchStoriesFail = createAction('fetchStoriesFail');

const TAGS = ['NDC', 'ndcsdg', 'esp', 'climate watch'];

const fetchStories = createThunkAction('fetchStories', () => dispatch => {
  dispatch(fetchStoriesInit());
  fetch(`/api/v1/stories?tags=${TAGS}`)
    .then(response => {
      if (response.ok) return response.json();
      throw Error(response.statusText);
    })
    .then(data => {
      dispatch(fetchStoriesReady(data));
    })
    .catch(error => {
      console.info(error);
      dispatch(fetchStoriesFail());
    });
});

export default {
  fetchStories,
  fetchStoriesInit,
  fetchStoriesReady,
  fetchStoriesFail
};
<|endoftext|>


<commit_before>var gulp = require('gulp');
var jshint = require('gulp-jshint');
var stylish = require('jshint-stylish');
var mocha = require('gulp-mocha');

gulp.task('lint', function () {
  return gulp
  	.src(['./*.js', './lib/**/*.js', './test/**/*.js'])
  	.pipe(jshint())
  	.pipe(jshint.reporter(stylish))
  	.pipe(jshint.reporter('fail'));
});

gulp.task('test', ['lint'], function () {
  return gulp
  	.src('./test/**/*.js', { read: false })
    .pipe(mocha({
      reporter: 'spec',
      globals: {
        should: require('should')
      }
    }));
});

gulp.task('watch', function() {
  gulp.watch('lib/**/*.js', ['test']);
  gulp.watch('test/**/*.js', ['test']);
});

gulp.task('default', ['test']);<commit_msg>istanbul should ignore 'watch' task<commit_after>var gulp = require('gulp');
var jshint = require('gulp-jshint');
var stylish = require('jshint-stylish');
var mocha = require('gulp-mocha');

gulp.task('lint', function () {
  return gulp
  	.src(['./*.js', './lib/**/*.js', './test/**/*.js'])
  	.pipe(jshint())
  	.pipe(jshint.reporter(stylish))
  	.pipe(jshint.reporter('fail'));
});

gulp.task('test', ['lint'], function () {
  return gulp
  	.src('./test/**/*.js', { read: false })
    .pipe(mocha({
      reporter: 'spec',
      globals: {
        should: require('should')
      }
    }));
});

/* istanbul ignore next */
gulp.task('watch', function() {
  gulp.watch('lib/**/*.js', ['test']);
  gulp.watch('test/**/*.js', ['test']);
});

gulp.task('default', ['test']);<|endoftext|>


<commit_before>var redis = require("redis");
var async = require("async");

var CONST = require("./constants");
var srv = require("./server");
var time = require("./time");

/*
 * buitlt-in event emitter for bus events.
 */
var EventEmitter = require("events").EventEmitter,
	emitter = new EventEmitter();
var cli_sub = null;
var cli_pub = null;
var redis_channel_name = "msg_bus";

/*
 * Connect client for incoming messages.
 */
function connect_sub_client(config, ret_handler){

	cli_sub = redis.createClient(config.redisport, config.redishost);
	cli_sub.max_attempts = CONST.REDIS_MAX_ATTEMPTS();

	cli_sub.on("connect",function(){

		cli_sub.subscribe(redis_channel_name);
	});

	cli_sub.on("subscribe",function(channel){

		emitter.emit("ev_msgbus_subscription",{});
		ret_handler(null);
	});

	cli_sub.on("message", function(channel, message_str){

		var message = JSON.parse(message_str);
		emitter.emit( "ev_msgbus_" + message.msg_type, message.data);
	})

	cli_sub.on("error", function(){

		if(cli_sub.attempts == cli_sub.max_attempts)
			ret_handler("error connecting redis");
	});

}

/*
 * Connect client for outgoing messages.
 */
function connect_pub_client(config, ret_handler){

	cli_pub = redis.createClient(config.redisport, config.redishost);
	cli_pub.max_attempts = CONST.REDIS_MAX_ATTEMPTS();

	cli_pub.on("connect",function(){

		ret_handler(null);
	});

	cli_pub.on("error", function(){

		if(cli_pub.attempts == cli_pub.max_attempts)
			ret_handler("error connecting redis");
	});
}

/*
 * Connect pub and sub clients to the bus.
 */
exports.connect = function( config, ret_handler ){

	config = config || {};
	config.redisport = config.redisport || 6379;
	config.redishost = config.redishost || "localhost";

	async.parallel([
		function(callback){

				connect_pub_client(config,function(err){

					callback(err);
				})
		},
		function(callback){

				connect_sub_client(config,function(err){

					callback(err);
				})
		}
	],  function(err, results){

		ret_handler(err);
	});

}

/*
 * Close connections to redis bus
 */
exports.close  = function(){

	cli_pub.end();
	cli_sub.end();
}

/*
 * publish data to redis bus.
 */
exports.publish = function( data ){

	var data_str = JSON.stringify(data);
	cli_pub.publish( redis_channel_name, data_str);

}

//ev_type: ev_msgbus_dummy
exports.on = function( ev_type, ret_handler ){

	emitter.on(ev_type, function( data ){

		ret_handler( {
						ev_type: ev_type,
						ev_tstamp: time.now(),
						ev_data:data
					 });
	});

}

<commit_msg>Modified return logic when no return handler is specified.<commit_after>var redis = require("redis");
var async = require("async");

var CONST = require("./constants");
var srv = require("./server");
var time = require("./time");

/*
 * buitlt-in event emitter for bus events.
 */
var EventEmitter = require("events").EventEmitter,
	emitter = new EventEmitter();
var cli_sub = null;
var cli_pub = null;
var redis_channel_name = "msg_bus";

/*
 * Connect client for incoming messages.
 */
function connect_sub_client(config, ret_handler){

	cli_sub = redis.createClient(config.redisport, config.redishost);
	cli_sub.max_attempts = CONST.REDIS_MAX_ATTEMPTS();

	cli_sub.on("connect",function(){

		cli_sub.subscribe(redis_channel_name);
	});

	cli_sub.on("subscribe",function(channel){

		ret_handler(null);
	});

	cli_sub.on("message", function(channel, message_str){

		var message = JSON.parse(message_str);
		emitter.emit( "ev_msgbus_" + message.msg_type, message.data);
	})

	cli_sub.on("error", function(){

		if(cli_sub.attempts == cli_sub.max_attempts)
			ret_handler("error connecting redis");
	});

}

/*
 * Connect client for outgoing messages.
 */
function connect_pub_client(config, ret_handler){

	cli_pub = redis.createClient(config.redisport, config.redishost);
	cli_pub.max_attempts = CONST.REDIS_MAX_ATTEMPTS();

	cli_pub.on("connect",function(){

		ret_handler(null);
	});

	cli_pub.on("error", function(){

		if(cli_pub.attempts == cli_pub.max_attempts)
			ret_handler("error connecting redis");
	});
}

/*
 * Connect pub and sub clients to the bus.
 */
exports.connect = function( config, ret_handler ){

	config = config || {};
	config.redisport = config.redisport || 6379;
	config.redishost = config.redishost || "localhost";

	async.parallel([
		function(callback){

				connect_pub_client(config,function(err){

					callback(err);
				});
		},
		function(callback){

				connect_sub_client(config,function(err){

					callback(err);
				});
		}
	],  function(err){

		if(err && ret_handler)
			ret_handler(err);
		else if(err)
			console.error("!! Redis connection dropped");

	});

}

/*
 * Close connections to redis bus
 */
exports.close  = function(){

	cli_pub.end();
	cli_sub.end();
}

/*
 * publish data to redis bus.
 */
exports.publish = function( data ){

	var data_str = JSON.stringify(data);
	cli_pub.publish( redis_channel_name, data_str);

}

//ev_type: ev_msgbus_dummy
exports.on = function( ev_type, ret_handler ){

	emitter.on(ev_type, function( data ){

		ret_handler( {
						ev_type: ev_type,
						ev_tstamp: time.now(),
						ev_data:data
					 });
	});

}

<|endoftext|>


<commit_before>window.CmdEngine = (function() {
    "use strict";

    function CmdEngine(options) {
    };

    CmdEngine.prototype = {
	constructor: CmdEngine,

	//
	setOptions:
	function(options) {
	},

	//
	exec:
	function( cmdInfo, callback, errorcb) {

	    // the following json object will be passed to the EasyInterface server
	    var jsonParams = {
		"command":    _ei.serverCommand.app.execute,
		"app_id":     cmdInfo.appId,
		"parameters": {}
	    };

	    // add the parameters to the json object
	    for(var p in cmdInfo.params) {
		var vals = new Array();
		vals = [].concat(cmdInfo.params[p]);
		jsonParams["parameters"][p]=vals;
	    }

	    // add the files
	    if ( cmdInfo.files )
		jsonParams["parameters"]["_ei_files"] =  cmdInfo.files;

	    // add the outline entries
	    if (_ei.outline.active && cmdInfo.entries ) {
		jsonParams["parameters"]["_ei_outline"] =  cmdInfo.entries;
	    }

	    // add the client id
	    jsonParams["parameters"]["_ei_clientid"] = _ei.clientId;

	    // add ei output support
	    jsonParams["parameters"]["_ei_outformat"] = _ei.outformat;

	    //var eirequest = JSON.stringify(jsonParams);
	    var eirequest = jsonParams;

	    $.post(cmdInfo.server,
		   {
		       eirequest: eirequest
		   }).done(function(data) {
		       try {
			   data = jQuery.parseXML(data);
			   if ( _ei.debug ) console.log(data);
	    		   callback(data);
		       } catch(e) {
			   var n = data.indexOf("<"+_ei.outlang.syntax.eiappout+">");
			   var m = data.indexOf("</"+_ei.outlang.syntax.eiappout+">");
			   if ( n != -1 && m != -1 ) {
			       data = data.replace("<"+_ei.outlang.syntax.eiappout+">","<"+_ei.outlang.syntax.eiappout+"><![CDATA[");
			       data = data.replace("</"+_ei.outlang.syntax.eiappout+">","]]></"+_ei.outlang.syntax.eiappout+">");
			   }
			   try {
			       data = jQuery.parseXML(data);
			       callback(data);
			   } catch(e1) {
  			     errorcb(e1);
			   }
		       }
	    	   }).error(function(data) {
		       if ( _ei.debug ) {
			   console.log("HTTP Request error occurred: ");
			   console.log(data);
		       }
	    	       errorcb(data);
	    	   });
	}
    }

    return CmdEngine;

})();
<commit_msg>callback have not to be inside the try-catch<commit_after>window.CmdEngine = (function() {
    "use strict";

    function CmdEngine(options) {
    };

    CmdEngine.prototype = {
	constructor: CmdEngine,

	//
	setOptions:
	function(options) {
	},

	//
	exec:
	function( cmdInfo, callback, errorcb) {

	    // the following json object will be passed to the EasyInterface server
	    var jsonParams = {
		"command":    _ei.serverCommand.app.execute,
		"app_id":     cmdInfo.appId,
		"parameters": {}
	    };

	    // add the parameters to the json object
	    for(var p in cmdInfo.params) {
		var vals = new Array();
		vals = [].concat(cmdInfo.params[p]);
		jsonParams["parameters"][p]=vals;
	    }

	    // add the files
	    if ( cmdInfo.files )
		jsonParams["parameters"]["_ei_files"] =  cmdInfo.files;

	    // add the outline entries
	    if (_ei.outline.active && cmdInfo.entries ) {
		jsonParams["parameters"]["_ei_outline"] =  cmdInfo.entries;
	    }

	    // add the client id
	    jsonParams["parameters"]["_ei_clientid"] = _ei.clientId;

	    // add ei output support
	    jsonParams["parameters"]["_ei_outformat"] = _ei.outformat;

	    //var eirequest = JSON.stringify(jsonParams);
	    var eirequest = jsonParams;

	    $.post(cmdInfo.server,
		   {
		       eirequest: eirequest
		   }).done(function(data) {
		       try {
			   data = jQuery.parseXML(data);
			   if ( _ei.debug ) console.log(data);
		       } catch(e) {
			   var n = data.indexOf("<"+_ei.outlang.syntax.eiappout+">");
			   var m = data.indexOf("</"+_ei.outlang.syntax.eiappout+">");
			   if ( n != -1 && m != -1 ) {
			       data = data.replace("<"+_ei.outlang.syntax.eiappout+">","<"+_ei.outlang.syntax.eiappout+"><![CDATA[");
			       data = data.replace("</"+_ei.outlang.syntax.eiappout+">","]]></"+_ei.outlang.syntax.eiappout+">");
			   }
			   try {
			       data = jQuery.parseXML(data);
			   } catch(e1) {
  			     errorcb(e1);
			     return;
			   }
		       }
		     callback(data);

	    	   }).error(function(data) {
		       if ( _ei.debug ) {
			   console.log("HTTP Request error occurred: ");
			   console.log(data);
		       }
	    	       errorcb(data);
	    	   });
	}
    }

    return CmdEngine;

})();
<|endoftext|>


<commit_before>var chatList = document.getElementById("chat-messages");

if (chatList) {
    // Get IRC updates from the couch
    Couch.urlPrefix = '/couch';
    var db = Couch.db('rochackircmarkov');
    db.changes(null, {
        include_docs: true,
        filter: 'couchgrams/text'
    }).onChange(function (resp) {
        if (resp.results) resp.results.forEach(addChatRow);
    });

    // Get latest IRC messages
    db.view('couchgrams/text', {
        descending: true,
        limit: 25,
        include_docs: true,
        error: function () {},
        success: function (resp) {
            if (resp && resp.rows) resp.rows.reverse().forEach(addChatRow);
        }
    });
}

var urlRegex = /[a-z]{2,}:\/\/*[^ ]*(?= |$)/g;

function addChatRow(row) {
    var date = new Date(row.id * 1000);
    var text = row.doc.text;
    var sender = row.doc.sender;
    // Insert chat message
    var li = document.createElement("li");
    if (sender) li.appendChild(document.createTextNode('<' + sender + '> '));
    /*
    if (sender) {
        var b = document.createElement("strong");
        b.appendChild(document.createTextNode(sender));
        li.appendChild(b);
        li.appendChild(document.createTextNode(" "));
    }
    */

    // Turn URLs into links.
    var urls = [];
    var match;
    while (match = urlRegex.exec(text)) {
        urls.push(match[0]);
    }
    text.split(urlRegex).forEach(function (text) {
        // Write text segment
        li.appendChild(document.createTextNode(text));
        // Write link
        if (urls.length == 0) return;
        var url = urls.pop();
        var link = document.createElement("a");
        link.setAttribute("href", url);
        link.appendChild(document.createTextNode(url));
        li.appendChild(link);
    });

    li.title = date.toLocaleString();
    chatList.appendChild(li);
}

var localVideoEl = document.getElementById('localVideo');
var remoteVideosEl = document.getElementById('remotes');

// create our webrtc connection
var webrtc = new WebRTC({
    localVideoEl: localVideoEl,
    remoteVideosEl: remoteVideosEl,
    // immediately ask for camera access
    autoRequestMedia: true,
    log: false
});

// when it's ready, join
webrtc.on('readyToCall', function () {
    webrtc.joinRoom('RocHack');
});

var showIRC = !window.localStorage['hide-irc'];
var toggleIRCLink = document.getElementById("toggle-irc");

function updateIRCView() {
    window.localStorage['hide-irc'] = showIRC ? "" : "hide";
    document.body.className = showIRC ?
        document.body.className.replace(/ hide-irc/g, '') :
        document.body.className + ' hide-irc';
    toggleIRCLink.innerHTML = showIRC ? "»" : "«";
}
updateIRCView();

toggleIRCLink.addEventListener("click", function (e) {
    e.preventDefault();
    showIRC = !showIRC;
    updateIRCView();
    setTimeout(updateVideoSizes, 500);
}, false);

function fitVideos(container, videos) {
    if (!videos[0]) return 1;
    var videoWidth = videos[0].offsetWidth;
    var videoHeight = videos[0].offsetHeight;
    var aspect = videoHeight / videoWidth;
    var containerWidth = container.offsetWidth;
    var containerHeight = container.offsetHeight;
    var numVideos = videos.length;
    var bestFit = 0;
    for (var cols = 1; cols <= numVideos; cols++) {
        var width, height, w;
        var rows = Math.ceil(numVideos/cols);
        width = containerWidth/cols;
        height = width * aspect;
        var totalHeight = rows * height;
        if (totalHeight <= containerHeight) {
            w = 1/cols;
            if (w > bestFit) bestFit = w;
        }
        height = containerHeight/rows;
        width = height / aspect;
        var totalWidth = cols * width;
        if (totalWidth <= containerWidth) {
            w = width/containerWidth;
            if (w > bestFit) bestFit = w;
        }
    }
    return bestFit * containerWidth;
}

// Update the size of the videos dynamically
function updateVideoSizes() {
    var videos = [].slice.call(remoteVideosEl.getElementsByTagName("*"));
    var width = fitVideos(remoteVideosEl, videos) + "px";
    videos.forEach(function (video) {
        video.style.width = width;
    });
}

updateVideoSizes();
webrtc.on('videoAdded', updateVideoSizes);
webrtc.on('videoRemoved', updateVideoSizes);
webrtc.on('readyToCall', updateVideoSizes);
window.addEventListener('resize', updateVideoSizes, false);

<commit_msg>Specify STUN servers.<commit_after>var chatList = document.getElementById("chat-messages");

if (chatList) {
    // Get IRC updates from the couch
    Couch.urlPrefix = '/couch';
    var db = Couch.db('rochackircmarkov');
    db.changes(null, {
        include_docs: true,
        filter: 'couchgrams/text'
    }).onChange(function (resp) {
        if (resp.results) resp.results.forEach(addChatRow);
    });

    // Get latest IRC messages
    db.view('couchgrams/text', {
        descending: true,
        limit: 25,
        include_docs: true,
        error: function () {},
        success: function (resp) {
            if (resp && resp.rows) resp.rows.reverse().forEach(addChatRow);
        }
    });
}

var urlRegex = /[a-z]{2,}:\/\/*[^ ]*(?= |$)/g;

function addChatRow(row) {
    var date = new Date(row.id * 1000);
    var text = row.doc.text;
    var sender = row.doc.sender;
    // Insert chat message
    var li = document.createElement("li");
    if (sender) li.appendChild(document.createTextNode('<' + sender + '> '));
    /*
    if (sender) {
        var b = document.createElement("strong");
        b.appendChild(document.createTextNode(sender));
        li.appendChild(b);
        li.appendChild(document.createTextNode(" "));
    }
    */

    // Turn URLs into links.
    var urls = [];
    var match;
    while (match = urlRegex.exec(text)) {
        urls.push(match[0]);
    }
    text.split(urlRegex).forEach(function (text) {
        // Write text segment
        li.appendChild(document.createTextNode(text));
        // Write link
        if (urls.length == 0) return;
        var url = urls.pop();
        var link = document.createElement("a");
        link.setAttribute("href", url);
        link.appendChild(document.createTextNode(url));
        li.appendChild(link);
    });

    li.title = date.toLocaleString();
    chatList.appendChild(li);
}

var localVideoEl = document.getElementById('localVideo');
var remoteVideosEl = document.getElementById('remotes');

// create our webrtc connection
var webrtc = new WebRTC({
    localVideoEl: localVideoEl,
    remoteVideosEl: remoteVideosEl,
    // immediately ask for camera access
    autoRequestMedia: true,
    peerConnectionConfig: {
        iceServers: navigator.mozGetUserMedia ?
            [{"url":"stun:124.124.124.2"}] :
            [{"url": "stun:stun.l.google.com:19302"}],
        onChannelOpened: function (channel) {
            console.log('channel opened', channel);
        },
        onChannelMessage: function (event) {
            console.log('channel message', event.data);
        }
    },
    log: false
});

// when it's ready, join
webrtc.on('readyToCall', function () {
    webrtc.joinRoom('RocHack');
});

var showIRC = !window.localStorage['hide-irc'];
var toggleIRCLink = document.getElementById("toggle-irc");

function updateIRCView() {
    window.localStorage['hide-irc'] = showIRC ? "" : "hide";
    document.body.className = showIRC ?
        document.body.className.replace(/ hide-irc/g, '') :
        document.body.className + ' hide-irc';
    toggleIRCLink.innerHTML = showIRC ? "»" : "«";
}
updateIRCView();

toggleIRCLink.addEventListener("click", function (e) {
    e.preventDefault();
    showIRC = !showIRC;
    updateIRCView();
    setTimeout(updateVideoSizes, 500);
}, false);

function fitVideos(container, videos) {
    if (!videos[0]) return 1;
    var videoWidth = videos[0].offsetWidth;
    var videoHeight = videos[0].offsetHeight;
    var aspect = videoHeight / videoWidth;
    var containerWidth = container.offsetWidth;
    var containerHeight = container.offsetHeight;
    var numVideos = videos.length;
    var bestFit = 0;
    for (var cols = 1; cols <= numVideos; cols++) {
        var width, height, w;
        var rows = Math.ceil(numVideos/cols);
        width = containerWidth/cols;
        height = width * aspect;
        var totalHeight = rows * height;
        if (totalHeight <= containerHeight) {
            w = 1/cols;
            if (w > bestFit) bestFit = w;
        }
        height = containerHeight/rows;
        width = height / aspect;
        var totalWidth = cols * width;
        if (totalWidth <= containerWidth) {
            w = width/containerWidth;
            if (w > bestFit) bestFit = w;
        }
    }
    return bestFit * containerWidth;
}

// Update the size of the videos dynamically
function updateVideoSizes() {
    var videos = [].slice.call(remoteVideosEl.getElementsByTagName("*"));
    var width = fitVideos(remoteVideosEl, videos) + "px";
    videos.forEach(function (video) {
        video.style.width = width;
    });
}

updateVideoSizes();
webrtc.on('videoAdded', updateVideoSizes);
webrtc.on('videoRemoved', updateVideoSizes);
webrtc.on('readyToCall', updateVideoSizes);
window.addEventListener('resize', updateVideoSizes, false);

<|endoftext|>


<commit_before>//@flow

import styled, { css } from "styled-components";

export const Underline = styled.span`

  ${({ isActive, theme }) => `
    position: relative;
    &:before {
      z-index: -1;
      display: block;
      content: "";
      height: ${theme.scale.s3(-2)};
      bottom: -${theme.scale.s3(-10)};
      background-color: ${theme.color.primary};
      position: absolute;
      width: 100%;
      transform-origin: bottom left;
      transform: scaleX(0);
      will-change: transform;
      transition: all 0.1s ease-out;
      ${isActive && css`
        transform: scaleX(1);
      `}
    }
 `}
`;
<commit_msg>Allow custom highlight color in Highlight component<commit_after>//@flow

import styled, { css } from "styled-components";

export const Underline = styled.span`

  ${({ isActive, theme, highlightColor }) => `
    position: relative;
    &:before {
      z-index: -1;
      display: block;
      content: "";
      height: ${theme.scale.s3(-2)};
      bottom: -${theme.scale.s3(-10)};
      background-color: ${highlightColor || theme.color.primary};
      position: absolute;
      width: 100%;
      transform-origin: bottom left;
      transform: scaleX(0);
      will-change: transform;
      transition: all 0.1s ease-out;
      ${isActive && css`
        transform: scaleX(1);
      `}
    }
 `}
`;
<|endoftext|>


<commit_before>var server = require('./server.js')
  , build = require('./build.js')
  , path = require('path');

module.exports = function(grunt) {
  grunt.initConfig({
    lint: {
      all: ['*.js', 'app/*.js', 'app/test/unit/*.js', 'instruments/instruments.js', 'instruments/example.js', 'instruments/build.js']
    }
    , jshint: {
      all: {
        options: {
          laxcomma: true
          , es5: true
        }
      }
    }
    , mochaTest: {
      functional: ['test/functional/*.js']
      , unit: ['app/test/unit/*.js']
    }
    , mochaTestConfig: {
      options: {
        timeout: 60000
      }
    }
  });

  grunt.loadNpmTasks('grunt-mocha-test');
  grunt.registerTask('test', 'mochaTest:*');
  grunt.registerTask('functional', 'mochaTest:functional');
  grunt.registerTask('unit', 'mochaTest:unit');
  grunt.registerTask('default', 'lint test');
  grunt.registerTask('appium', "Start the Appium server", function() {
    var done = this.async();
    server.run(
      './sample-code/apps/TestApp/build/Release-iphonesimulator/TestApp.app'
      , null
      , true
      , 4723
      , '127.0.0.1'
      , true
      , done
    );
  });
  grunt.registerTask('buildApp', "Build the test app", function() {
    var done = this.async();
    var appRoot = path.resolve(__dirname, 'sample-code/apps/TestApp/');
    build(appRoot, function(err) {
      if (err) {
        console.log(err);
      }
      done();
    });
  });
};
<commit_msg>better grunt app building error reporting<commit_after>var server = require('./server.js')
  , build = require('./build.js')
  , path = require('path');

module.exports = function(grunt) {
  grunt.initConfig({
    lint: {
      all: ['*.js', 'app/*.js', 'app/test/unit/*.js', 'instruments/instruments.js', 'instruments/example.js', 'instruments/build.js']
    }
    , jshint: {
      all: {
        options: {
          laxcomma: true
          , es5: true
        }
      }
    }
    , mochaTest: {
      functional: ['test/functional/*.js']
      , unit: ['app/test/unit/*.js']
    }
    , mochaTestConfig: {
      options: {
        timeout: 60000
      }
    }
  });

  grunt.loadNpmTasks('grunt-mocha-test');
  grunt.registerTask('test', 'mochaTest:*');
  grunt.registerTask('functional', 'mochaTest:functional');
  grunt.registerTask('unit', 'mochaTest:unit');
  grunt.registerTask('default', 'lint test');
  grunt.registerTask('appium', "Start the Appium server", function() {
    var done = this.async();
    server.run(
      './sample-code/apps/TestApp/build/Release-iphonesimulator/TestApp.app'
      , null
      , true
      , 4723
      , '127.0.0.1'
      , true
      , done
    );
  });
  grunt.registerTask('buildApp', "Build the test app", function() {
    var done = this.async();
    var appRoot = path.resolve(__dirname, 'sample-code/apps/TestApp/');
    build(appRoot, function(err) {
      if (err) {
        console.log(err);
        done(false);
      } else {
        done(true);
      }
    });
  });
};
<|endoftext|>