<commit_before>/*global d3*/

function callURL(url, cb) {
	d3.text(url, function (error, result) {
		if (error) {
			console.log(url + ' : ' + error.status);
		} else {
			if (cb) {
				cb(result);
			}
//			console.log(result);
		}
	});
}

function MAC(dpid) {
	var cmps = dpid.split(':');
	var MAC = '00:00:c0:a8:' + [cmps[6], cmps[7]].join(':');
	return MAC;
}

var controllerFunctions = {
	linkCmd: function (cmd, link) {
		var url = '/proxy/gui/link/' + [cmd, link['src-switch'], link['src-port'], link['dst-switch'], link['dst-port']].join('/');
		callURL(url);

	},
	switchCmd: function (cmd, s) {
		var url = '/proxy/gui/switch/' + [cmd, s.dpid].join('/');
		callURL(url);
	},
	ctrlCmd: function (cmd, c) {
		var url = '/proxy/gui/controller/' + [cmd, c].join('/');
		callURL(url);
	},
	addFlowCmd: function (src, dst) {
		var url = '/proxy/gui/addflow/' + [src.dpid, 1, dst.dpid, 1, MAC(src.dpid), MAC(dst.dpid)].join('/');
		callURL(url);
	},
	delFlowCmd: function (flow) {
		var url = '/proxy/gui/delflow/' + flow.flowId;
		callURL(url);
	},
	startIPerfCmd: function (flow, duration, numSamples) {
		var flowId = parseInt(flow.flowId, 16);
		var url = '/proxy/gui/iperf/start/' + [flowId, duration, numSamples].join('/');
		callURL(url)
	},
	getIPerfDataCmd: function (flow, cb) {
		var flowId = parseInt(flow.flowId, 16);
		var url = '/proxy/gui/iperf/rate/' + flowId;
		callURL(url, cb);
	},
	switchControllerCmd: function (cmd) {
		var url = '/proxy/gui/switchctrl/' + cmd;
		callURL(url);
	},
	resetCmd: function () {
		var url = '/proxy/gui/reset';
		callURL(url);
	},
	scaleCmd: function () {
		var url = '/proxy/gui/scale';
		callURL(url);
	}
};

function linkUp(link) {
	controllerFunctions.linkCmd('up', link);
}

function linkDown(link) {
	controllerFunctions.linkCmd('down', link);
}

function switchUp(s) {
	controllerFunctions.switchCmd('up', s);
}

function switchDown(s) {
	controllerFunctions.switchCmd('down', s);
}

function controllerUp(c) {
	controllerFunctions.ctrlCmd('up', c);
}

function controllerDown(c) {
	controllerFunctions.ctrlCmd('down', c);
}

function addFlow(src, dst) {
	controllerFunctions.addFlowCmd(src, dst);
}

function deleteFlow(flow) {
	controllerFunctions.delFlowCmd(flow);
}

function startIPerf(flow, duration, numSamples) {
	controllerFunctions.startIPerfCmd(flow, duration, numSamples);
}

function getIPerfData(flow, cb) {
	controllerFunctions.getIPerfDataCmd(flow, cb);
}

function switchLocal() {
	controllerFunctions.switchControllerCmd('local');
}

function resetNetwork() {
	controllerFunctions.resetCmd();
}

function scaleNetwork() {
	controllerFunctions.scaleCmd();;
}

<commit_msg>added back switchAll function in controller.js (deleted by mistake?)<commit_after>/*global d3*/

function callURL(url, cb) {
	d3.text(url, function (error, result) {
		if (error) {
			console.log(url + ' : ' + error.status);
		} else {
			if (cb) {
				cb(result);
			}
//			console.log(result);
		}
	});
}

function MAC(dpid) {
	var cmps = dpid.split(':');
	var MAC = '00:00:c0:a8:' + [cmps[6], cmps[7]].join(':');
	return MAC;
}

var controllerFunctions = {
	linkCmd: function (cmd, link) {
		var url = '/proxy/gui/link/' + [cmd, link['src-switch'], link['src-port'], link['dst-switch'], link['dst-port']].join('/');
		callURL(url);

	},
	switchCmd: function (cmd, s) {
		var url = '/proxy/gui/switch/' + [cmd, s.dpid].join('/');
		callURL(url);
	},
	ctrlCmd: function (cmd, c) {
		var url = '/proxy/gui/controller/' + [cmd, c].join('/');
		callURL(url);
	},
	addFlowCmd: function (src, dst) {
		var url = '/proxy/gui/addflow/' + [src.dpid, 1, dst.dpid, 1, MAC(src.dpid), MAC(dst.dpid)].join('/');
		callURL(url);
	},
	delFlowCmd: function (flow) {
		var url = '/proxy/gui/delflow/' + flow.flowId;
		callURL(url);
	},
	startIPerfCmd: function (flow, duration, numSamples) {
		var flowId = parseInt(flow.flowId, 16);
		var url = '/proxy/gui/iperf/start/' + [flowId, duration, numSamples].join('/');
		callURL(url)
	},
	getIPerfDataCmd: function (flow, cb) {
		var flowId = parseInt(flow.flowId, 16);
		var url = '/proxy/gui/iperf/rate/' + flowId;
		callURL(url, cb);
	},
	switchControllerCmd: function (cmd) {
		var url = '/proxy/gui/switchctrl/' + cmd;
		callURL(url);
	},
	resetCmd: function () {
		var url = '/proxy/gui/reset';
		callURL(url);
	},
	scaleCmd: function () {
		var url = '/proxy/gui/scale';
		callURL(url);
	}
};

function linkUp(link) {
	controllerFunctions.linkCmd('up', link);
}

function linkDown(link) {
	controllerFunctions.linkCmd('down', link);
}

function switchUp(s) {
	controllerFunctions.switchCmd('up', s);
}

function switchDown(s) {
	controllerFunctions.switchCmd('down', s);
}

function controllerUp(c) {
	controllerFunctions.ctrlCmd('up', c);
}

function controllerDown(c) {
	controllerFunctions.ctrlCmd('down', c);
}

function addFlow(src, dst) {
	controllerFunctions.addFlowCmd(src, dst);
}

function deleteFlow(flow) {
	controllerFunctions.delFlowCmd(flow);
}

function startIPerf(flow, duration, numSamples) {
	controllerFunctions.startIPerfCmd(flow, duration, numSamples);
}

function getIPerfData(flow, cb) {
	controllerFunctions.getIPerfDataCmd(flow, cb);
}

function switchLocal() {
	controllerFunctions.switchControllerCmd('local');
}
function switchAll() {
	controllerFunctions.switchControllerCmd('all');
}

function resetNetwork() {
	controllerFunctions.resetCmd();
}

function scaleNetwork() {
	controllerFunctions.scaleCmd();;
}

<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
	errorHandler = require('./errors.server.controller'),
	User = mongoose.model('User'),
	Project = mongoose.model('Project'),
	async = require('async'),
	config = require('../../config/config'),
	nodemailer = require('nodemailer'),
	_ = require('lodash');

exports.sendInvites = function(req, res, next) {
	Project.findOne({_id: req.body.projectId}, function(err, project) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			var userName;

			for (var i = project.users.length - 1; i >= 0; i--) {
				userName = project.users[i];

				User.findOne({username: userName}, function(err, user) {
					if (err) {} else {
						async.waterfall([
							function(done) {
								res.render('templates/invite-email', {
									name: user.displayName,
									appName: config.app.title,
									projectName: project.name,
									url: 'http://' + req.headers.host + '/#!/projects/' + project._id + '/edit'
								}, function(err, emailHTML) {
									done(err, emailHTML, user);
								});
							},
							// If valid email, send reset email using service
							function(emailHTML, user, done) {
								var smtpTransport = nodemailer.createTransport(config.mailer.options);
								var mailOptions = {
									to: user.email,
									from: config.mailer.from,
									subject: 'Estimation Invite',
									html: emailHTML
								};
								smtpTransport.sendMail(mailOptions, function(err) {
									if (!err) {
										// res.send({
										// 	message: 'An email has been sent to ' + user.email + ' with further instructions.'
										// });
									}

									done(err);
								});
							}
						], function(err) {
							if (err) {
								return next(err);
							}
						});
					}
				});
			}
		}
	});
};
exports.sendReport = function(string, project, res) {
	var owner = project.owner;
	User.findOne({username : owner}, function(err, user) {
		if (err) {} else {
			async.waterfall([
				function(done) {
					res.render('templates/report-email', {
						name: user.displayName,
						appName: config.app.title,
						projectName: project.name,
						report: string
					}, function(err, emailHTML) {
						done(err, emailHTML, user);
					});
				},
				function(emailHTML, user, done) {
					var smtpTransport = nodemailer.createTransport(config.mailer.options);
					var mailOptions = {
						to: user.email,
						from: config.mailer.from,
						subject: 'Estimation report for ' + project.name,
						html: emailHTML
					};
					smtpTransport.sendMail(mailOptions, function(err) {
						if (!err) {
							//asd
						}
						done(err);
					});
				}
				], function(err) {
					if (err) return next(err);
				});
		}
	});
};
<commit_msg>Rebase complete<commit_after>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
	errorHandler = require('./errors.server.controller'),
	User = mongoose.model('User'),
	Project = mongoose.model('Project'),
	async = require('async'),
	config = require('../../config/config'),
	nodemailer = require('nodemailer'),
	_ = require('lodash');

exports.sendInvites = function(req, res, next) {
	Project.findOne({_id: req.body.projectId}, function(err, project) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			var userName;

			for (var i = project.users.length - 1; i >= 0; i--) {
				userName = project.users[i];

				User.findOne({username: userName}, function(err, user) {
					if (err) {} else {
						async.waterfall([
							function(done) {
								res.render('templates/invite-email', {
									name: user.displayName,
									appName: config.app.title,
									projectName: project.name,
									url: 'http://' + req.headers.host + '/#!/projects/' + project._id + '/edit'
								}, function(err, emailHTML) {
									done(err, emailHTML, user);
								});
							},
							// If valid email, send reset email using service
							function(emailHTML, user, done) {
								var smtpTransport = nodemailer.createTransport(config.mailer.options);
								var mailOptions = {
									to: user.email,
									from: config.mailer.from,
									subject: 'Estimation Invite',
									html: emailHTML
								};
								smtpTransport.sendMail(mailOptions, function(err) {
									if (!err) {
									}

									done(err);
								});
							}
						], function(err) {
							if (err) {
								return next(err);
							}
						});
					}
				});
			}
		}
	});
};
exports.sendReport = function(string, project, res) {
	var owner = project.owner;
	User.findOne({username : owner}, function(err, user) {
		if (err) {} else {
			async.waterfall([
				function(done) {
					res.render('templates/report-email', {
						name: user.displayName,
						appName: config.app.title,
						projectName: project.name,
						report: string
					}, function(err, emailHTML) {
						done(err, emailHTML, user);
					});
				},
				function(emailHTML, user, done) {
					var smtpTransport = nodemailer.createTransport(config.mailer.options);
					var mailOptions = {
						to: user.email,
						from: config.mailer.from,
						subject: 'Estimation report for ' + project.name,
						html: emailHTML
					};
					smtpTransport.sendMail(mailOptions, function(err) {
						if (!err) {
							//asd
						}
						done(err);
					});
				}
				], function(err) {
					if (err) return next(err);
				});
		}
	});
};
<|endoftext|>


<commit_before>'use strict'

module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    eslint: {
      target: ['**/*.js', '!node_modules/**/*']
    },
    bump: {
      options: {
        files: ['package.json', 'npm-shrinkwrap.json'],
        commitFiles: ['package.json', 'npm-shrinkwrap.json'],
        tagName: '%VERSION%',
        push: false
      }
    }
  })

  grunt.loadNpmTasks('grunt-eslint')
  grunt.loadNpmTasks('grunt-bump')

  grunt.registerTask('default', ['eslint'])
}
<commit_msg>Fix eslint error<commit_after>'use strict'

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    eslint: {
      target: ['**/*.js', '!node_modules/**/*']
    },
    bump: {
      options: {
        files: ['package.json', 'npm-shrinkwrap.json'],
        commitFiles: ['package.json', 'npm-shrinkwrap.json'],
        tagName: '%VERSION%',
        push: false
      }
    }
  })

  grunt.loadNpmTasks('grunt-eslint')
  grunt.loadNpmTasks('grunt-bump')

  grunt.registerTask('default', ['eslint'])
}
<|endoftext|>


<commit_before>/*
    gulp is a handy task runner for JavaScript projects. It operates on
    "streams" of files, which are then manipulated individually with
    various steps, called gulp tasks.
*/

// Required node modules in this file
var browserSync = require("browser-sync"),
    browserify = require("browserify"),
    buffer = require("vinyl-buffer"),
    gulp = require("gulp"),
    notify = require("gulp-notify"),
    reactify = require("reactify"),
    source = require("vinyl-source-stream"),
    sass = require("gulp-sass"),
    sourcemaps = require("gulp-sourcemaps");

// Constants used in this file
var SRC = "./src/",
    DEST = "./build/",
    JS_FILES = SRC + "scripts/**/*.{js,jsx}",
    STATIC_FILES = SRC + "{.,images}/*.{html,png,jpeg,jpg}",
    STYLESHEET_FILES = SRC + "styles/*.scss";

/*
   browser-sync starts a file server for us, as well as reloads all changed
   files to the browser automatically
*/
gulp.task("startServer", function() {
    browserSync({
        browser: "google chrome",
        server: { baseDir: DEST }
    });
});

function reloadBrowser() {
    return browserSync.reload({ stream: true });
}

/*
   In static error cases (which are not so easily detectable in the browser
   development tools), we'll send an operating system notification. This
   way we don't have to watch the terminal window all time.
*/
function onError() {
    var args = Array.prototype.slice.call(arguments);
    notify.onError({
        title: "Compile Error",
        message: "<%= error %>"
    }).apply(this, args);
    this.emit("end"); // Keep gulp from hanging on this task
}

/*
   browserify concatenates all JavaScript files into one "built" version,
   called main.js
*/
gulp.task("browserify", function() {
    return browserify({ entries: [SRC + "scripts/main.jsx"], extensions: [".jsx"], debug: true })
        .transform(reactify)
        .bundle()
        .on("error", onError)
        .pipe(source("main.js"))
        .pipe(buffer())
        .pipe(sourcemaps.init({ loadMaps: true }))
        .pipe(sourcemaps.write("./"))
        .pipe(gulp.dest(DEST + "scripts/"))
        .pipe(reloadBrowser());
});

/*
   gulp-sass transforms SASS stylesheet files into vanilla CSS files
*/
gulp.task("sass", function() {
    return gulp.src(STYLESHEET_FILES)
        .pipe(sourcemaps.init())
        .pipe(sass({ sourceComments: "map", imagePath: "/images" }))
        .on("error", onError)
        .pipe(sourcemaps.write())
        .pipe(gulp.dest(DEST + "styles/"))
        .pipe(reloadBrowser());
});

/*
   This "static" gulp task copies our non-SASS and non-JS files into the
   built directory as well. In practise this means our index.html file,
   as well as all possible picture files.
*/
gulp.task("static", function() {
    return gulp.src(STATIC_FILES)
        .pipe(gulp.dest(DEST))
        .pipe(reloadBrowser());
});

// Helper for running all "compile" steps at once
gulp.task("compile", ["sass", "static", "browserify"]);

// Watch all files continuously for changes
gulp.task("watch", ["startServer"], function(callback) {
    gulp.watch(STATIC_FILES,     ["static"]);
    gulp.watch(STYLESHEET_FILES, ["sass"]);
    gulp.watch(JS_FILES,         ["browserify"]);
});

// As default, compile all assets once and then watch for further changes
gulp.task("default", ["compile", "watch"]);
<commit_msg>Reverting the google chrome thing; doesn't seem to work on linux<commit_after>/*
    gulp is a handy task runner for JavaScript projects. It operates on
    "streams" of files, which are then manipulated individually with
    various steps, called gulp tasks.
*/

// Required node modules in this file
var browserSync = require("browser-sync"),
    browserify = require("browserify"),
    buffer = require("vinyl-buffer"),
    gulp = require("gulp"),
    notify = require("gulp-notify"),
    reactify = require("reactify"),
    source = require("vinyl-source-stream"),
    sass = require("gulp-sass"),
    sourcemaps = require("gulp-sourcemaps");

// Constants used in this file
var SRC = "./src/",
    DEST = "./build/",
    JS_FILES = SRC + "scripts/**/*.{js,jsx}",
    STATIC_FILES = SRC + "{.,images}/*.{html,png,jpeg,jpg}",
    STYLESHEET_FILES = SRC + "styles/*.scss";

/*
   browser-sync starts a file server for us, as well as reloads all changed
   files to the browser automatically
*/
gulp.task("startServer", function() {
    browserSync({ server: { baseDir: DEST } });
});

function reloadBrowser() {
    return browserSync.reload({ stream: true });
}

/*
   In static error cases (which are not so easily detectable in the browser
   development tools), we'll send an operating system notification. This
   way we don't have to watch the terminal window all time.
*/
function onError() {
    var args = Array.prototype.slice.call(arguments);
    notify.onError({
        title: "Compile Error",
        message: "<%= error %>"
    }).apply(this, args);
    this.emit("end"); // Keep gulp from hanging on this task
}

/*
   browserify concatenates all JavaScript files into one "built" version,
   called main.js
*/
gulp.task("browserify", function() {
    return browserify({ entries: [SRC + "scripts/main.jsx"], extensions: [".jsx"], debug: true })
        .transform(reactify)
        .bundle()
        .on("error", onError)
        .pipe(source("main.js"))
        .pipe(buffer())
        .pipe(sourcemaps.init({ loadMaps: true }))
        .pipe(sourcemaps.write("./"))
        .pipe(gulp.dest(DEST + "scripts/"))
        .pipe(reloadBrowser());
});

/*
   gulp-sass transforms SASS stylesheet files into vanilla CSS files
*/
gulp.task("sass", function() {
    return gulp.src(STYLESHEET_FILES)
        .pipe(sourcemaps.init())
        .pipe(sass({ sourceComments: "map", imagePath: "/images" }))
        .on("error", onError)
        .pipe(sourcemaps.write())
        .pipe(gulp.dest(DEST + "styles/"))
        .pipe(reloadBrowser());
});

/*
   This "static" gulp task copies our non-SASS and non-JS files into the
   built directory as well. In practise this means our index.html file,
   as well as all possible picture files.
*/
gulp.task("static", function() {
    return gulp.src(STATIC_FILES)
        .pipe(gulp.dest(DEST))
        .pipe(reloadBrowser());
});

// Helper for running all "compile" steps at once
gulp.task("compile", ["sass", "static", "browserify"]);

// Watch all files continuously for changes
gulp.task("watch", ["startServer"], function(callback) {
    gulp.watch(STATIC_FILES,     ["static"]);
    gulp.watch(STYLESHEET_FILES, ["sass"]);
    gulp.watch(JS_FILES,         ["browserify"]);
});

// As default, compile all assets once and then watch for further changes
gulp.task("default", ["compile", "watch"]);
<|endoftext|>


<commit_before>import React, { Component } from "react";
import MuiThemeProvider from "material-ui/styles/MuiThemeProvider";
import AppBar from "material-ui/AppBar";
import "materialize-css/dist/css/materialize.min.css";
import './App.css';
import Card from "./Card.js";

let separator = ":";

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      cards: props.cards,
      lastCard: null,
      scoreCardInfo: "",
      wait: false,
      score: 0,
      errors: 0,
      maximumScore: Object.keys(props.cards).length/2, // Pegando o número de cartas -> Pares!
      hasWon: false,
      hasScored: false
    };
  }

  handleClick(set, key, index, id) {
    if (this.state.cards[index].gameState > 2 || this.state.wait) {
      return;
    }

    this.seeCard(index);

    if (!this.state.lastCard) {
      this.setLastCard({ key: key, set: set, index: index });

      return;
    }

    let lastCard = this.state.lastCard;

    if (lastCard.set === set && lastCard.key === key) {
      return;
    }

    this.enableWait();
    if (lastCard.set !== set && lastCard.key === key) {
      setTimeout(
        function() {
          this.updateScoreCount();
          this.checkVictory();
          this.removeCards(index);
          this.clearLastCard();
        }.bind(this),
        400
      );

      for(let i = 0; i < this.state.cards.length; i++){
        if(this.state.cards[i].index === key ){
          this.setState({scoreCardInfo : this.state.cards[i].data.description, hasScored: true})
        }
      }

      return;
    }

    setTimeout(
      function() {
        this.updateErrorCount();
        this.hideCards(index);
        this.clearLastCard();
      }.bind(this),
      400
    );
  }

  updateErrorCount() {
    let newErrorsCount = this.state.errors + 1;
    this.setState({errors: newErrorsCount});
  }

  updateScoreCount() {
    let newScoreCount = this.state.score + 1;
    this.setState({score: newScoreCount});
  }

  checkVictory() {
    if (this.state.score === this.state.maximumScore){
      this.setState({hasWon: true});
    }
  }

  setLastCard(newLastCard) {
    let newState = this.state;
    newState.lastCard = newLastCard;
    this.setState(newState);
  }

  clearLastCard() {
    this.setLastCard(null);
    this.disableWait();
  }

  seeCard(i) {
    let newState = this.state;
    let cards = newState.cards;

    cards[i]["gameState"] = 2;

    newState.cards = cards;
    this.setState(newState);
  }

  hideCards(i) {
    let newState = this.state;
    let cards = newState.cards;

    cards[i]["gameState"] = 1;
    cards[newState.lastCard.index]["gameState"] = 1;

    newState.cards = cards;
    this.setState(newState);
  }

  removeCards(i) {
    let newState = this.state;
    let cards = newState.cards;

    cards[i]["gameState"] = 3;
    cards[newState.lastCard.index]["gameState"] = 3;

    newState.cards = cards;
    this.setState(newState);
  }

  enableWait() {
    this.setState({wait: true});
  }

  disableWait() {
    this.setState({wait: false});
  }

  render() {
    return (

        <MuiThemeProvider>
          <AppBar
            showMenuIconButton={false}
            title={`Jogo da Memória ${this.props.name} - Pares abertos: ${this.state.score + this.state.errors}`}
          />
        </MuiThemeProvider>

              Clique nas cartas para virá-la. Forme todos os pares para vencer.

            {this.state.cards.map((item, i) => (

              <Card
                image={"url(" + item.preLoadedImage.src + ")"}
                key={item.set + separator + item.index}
                id={item.set + separator + item.index}
                name={item.data.name}
                gameState={item.gameState}
                onClick={id => this.handleClick(item.set, item.index, i, id)}
              />

            ))}

        { this.state.hasScored ?

          <button className="closePopup" onClick={() => this.setState({hasScored:false})}>X</button>
          {this.state.scoreCardInfo.toString()}

        :
        ""
        }

        { this.state.hasWon ?

            Você venceu!

            (Recarregue a página para jogar novamente)

        :
        ""
        }

    );
  }
}

export default App;
<commit_msg>making game restart<commit_after>import React, { Component } from "react";
import MuiThemeProvider from "material-ui/styles/MuiThemeProvider";
import AppBar from "material-ui/AppBar";
import "materialize-css/dist/css/materialize.min.css";
import './App.css';
import Card from "./Card.js";
import ShuffleCards from "./ShuffleCards.js";
import Data from "./data/pt_BR/computer-scientists.json";

let separator = ":";

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      cards: props.cards,
      lastCard: null,
      scoreCardInfo: "",
      wait: false,
      score: 0,
      errors: 0,
      maximumScore: Object.keys(props.cards).length/2, // Pegando o número de cartas -> Pares!
      hasWon: false,
      hasScored: false
    };

    this.baseState = this.state;
  }

  componentDidMount(){
    console.log(this.state)
  }

  handleClick(set, key, index, id) {
    if (this.state.cards[index].gameState > 2 || this.state.wait) {
      return;
    }

    this.seeCard(index);

    if (!this.state.lastCard) {
      this.setLastCard({ key: key, set: set, index: index });

      return;
    }

    let lastCard = this.state.lastCard;

    if (lastCard.set === set && lastCard.key === key) {
      return;
    }

    this.enableWait();
    if (lastCard.set !== set && lastCard.key === key) {
      setTimeout(
        function() {
          this.updateScoreCount();
          this.checkVictory();
          this.removeCards(index);
          this.clearLastCard();
        }.bind(this),
        400
      );

      for(let i = 0; i < this.state.cards.length; i++){
        if(this.state.cards[i].index === key ){
          this.setState({scoreCardInfo : this.state.cards[i].data.description, hasScored: true})
        }
      }

      return;
    }

    setTimeout(
      function() {
        this.updateErrorCount();
        this.hideCards(index);
        this.clearLastCard();
      }.bind(this),
      400
    );
  }

  updateErrorCount() {
    let newErrorsCount = this.state.errors + 1;
    this.setState({errors: newErrorsCount});
  }

  updateScoreCount() {
    let newScoreCount = this.state.score + 1;
    this.setState({score: newScoreCount});
  }

  checkVictory() {
    if (this.state.score === this.state.maximumScore){
      this.setState({hasWon: true});
    }
  }

  setLastCard(newLastCard) {
    let newState = this.state;
    newState.lastCard = newLastCard;
    this.setState(newState);
  }

  clearLastCard() {
    this.setLastCard(null);
    this.disableWait();
  }

  seeCard(i) {
    let newState = this.state;
    let cards = newState.cards;

    cards[i]["gameState"] = 2;

    newState.cards = cards;
    this.setState(newState);
  }

  hideCards(i) {
    let newState = this.state;
    let cards = newState.cards;

    cards[i]["gameState"] = 1;
    cards[newState.lastCard.index]["gameState"] = 1;

    newState.cards = cards;
    this.setState(newState);
  }

  removeCards(i) {
    let newState = this.state;
    let cards = newState.cards;

    cards[i]["gameState"] = 3;
    cards[newState.lastCard.index]["gameState"] = 3;

    newState.cards = cards;
    this.setState(newState);
  }

  enableWait() {
    this.setState({wait: true});
  }

  disableWait() {
    this.setState({wait: false});
  }

  resetForm = () => {
    this.setState({...this.baseState, cards: ShuffleCards(Data.cards)});
  }

  render() {
    return (

        <MuiThemeProvider>
          <AppBar
            showMenuIconButton={false}
            title={`Jogo da Memória ${this.props.name} - Pares abertos: ${this.state.score + this.state.errors}`}
          />
        </MuiThemeProvider>

              Clique nas cartas para virá-la. Forme todos os pares para vencer.

            {this.state.cards.map((item, i) => (

              <Card
                image={"url(" + item.preLoadedImage.src + ")"}
                key={item.set + separator + item.index}
                id={item.set + separator + item.index}
                name={item.data.name}
                gameState={item.gameState}
                onClick={id => this.handleClick(item.set, item.index, i, id)}
              />

            ))}

        { this.state.hasScored ?

          <button className="closePopup" onClick={() => this.setState({hasScored:false})}>X</button>
          {this.state.scoreCardInfo.toString()}

        :
        ""
        }

        { this.state.hasWon ?

 this.resetForm()}>
            Você venceu!

            (Clique aqui para jogar novamente)

        :
        ""
        }

    );
  }
}

export default App;
<|endoftext|>


<commit_before>//
// Express Routes
//
// Routes allow our application frontend to communicate with our backend logic and MondoDB

/*		We consider the actions a user can perform:
			- view all posts
			- Add a new post
			- Upvote (+1) a post
			- View comments associated with a post
			- Add a comment
			- Upvote (+1) a comment
*/

/*		REST Routes and Associated Actions

-----------------------------------------------------------------------------------------
| REST Route 						| Action
-----------------------------------------------------------------------------------------
| GET/posts							| Return a list of posts and associated metadata
| POST/posts						| Create a NEW post
| GET/posts/:id 					| Return an individual post with associated comments
| PUT/posts/:id/upvote				| Upvote (+1) a post, using the Post ID
| POST/posts/:id/comments			| Add a NEW comment to a post by ID
| PUT/posts/:id/comments/:id/upvote | Upvote (+1) a comment
-----------------------------------------------------------------------------------------
*/

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

var mongoose = require('mongoose');				// import *mongoose* object (our db)
var Post = mongoose.model('Post');				// instantiate a handle to Post model
var Comment = mongoose.model('Comment');		// instantiate a handle to Comment model

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

/* GET all posts in a JSON list */
router.get('/posts', function(request, response, next) {		// Express get() method defines URL route on which to execute

	console.log('** Express get() /posts route **');

	Post.find(function(err, posts) {							// Mongoose find() to query MongoDB for ALL posts
		if (err) {
			return next(err);
		}

		response.json(posts);									// Return ALL posts in a JSON list
	});
});

/* Create a NEW Post */
router.post('/posts', function(request, response, next) {

	console.log('** Express post() /posts route **');

	var post = new Post(request.body);

	post.save(function(err, post) {								// Mongoose save() to save new post to MongoDB
		if (err) {
			return next(err);
		}

		response.json(post);
	});
});

/* Preload objects - We can use Express's param() function to automatically load an object, rather
	than duplicating the same code across several different request handler functions. */

router.param('post', function(request, response, next, id) {
	var query = Post.findById(id);

	query.exec(function(err, post) {
		if (err) {
			return next(err);
		}

		if (!post) {
			return next(new Error('Post not found'));
		}

		request.post = post;
		return next();
	});

});

router.get('/posts/:post', function(request, response) {
	response.json(request.post);
})

module.exports = router;

<commit_msg>adding RESTful API routes<commit_after>//
// Express Routes
//
// Routes allow our application frontend to communicate with our backend logic and MondoDB

/*		We consider the actions a user can perform:
			- view all posts
			- Add a new post
			- Upvote (+1) a post
			- View comments associated with a post
			- Add a comment
			- Upvote (+1) a comment
*/

/*		REST Routes and Associated Actions

-----------------------------------------------------------------------------------------
| REST Route 						| Action
-----------------------------------------------------------------------------------------
| GET/posts							| Return a list of posts and associated metadata
| POST/posts						| Create a NEW post
| GET/posts/:id 					| Return an individual post with associated comments
| PUT/posts/:id/upvote				| Upvote (+1) a post, using the Post ID
| POST/posts/:id/comments			| Add a NEW comment to a post by ID
| PUT/posts/:id/comments/:id/upvote | Upvote (+1) a comment
-----------------------------------------------------------------------------------------
*/

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

var mongoose = require('mongoose');				// import *mongoose* object (our db)
var Post = mongoose.model('Post');				// instantiate a handle to Post model
var Comment = mongoose.model('Comment');		// instantiate a handle to Comment model

/* Preload objects - We can use Express's param() function to automatically load an object, rather
	than duplicating the same code across several different request handler functions.

	- we define a route URL with :post
	- assuming our :post parameter contains an ID, our callback function will retrieve the post object
		from the database, and attach it to the to request object
	- then, the router handler function will be called

*/

router.param('post', function(request, response, next, id) {
	var query = Post.findById(id);

	query.exec(function(err, post) {
		if (err) {
			return next(err);
		}

		if (!post) {
			return next(new Error('Post not found'));
		}

		request.post = post;
		return next();
	});

});

/* GET home page. */
router.get('/', function(request, response, next) {
  res.render('index', { title: 'Buzz News Feeder' });
});

/* GET all posts in a JSON list */
router.get('/posts', function(request, response, next) {		// Express get() method defines URL route on which to execute

	console.log('** Express get() /posts route **');

	Post.find(function(err, posts) {							// Mongoose find() to query MongoDB for ALL posts
		if (err) {
			return next(err);
		}

		response.json(posts);									// Return ALL posts in a JSON list
	});
});

/* Create a NEW Post */
router.post('/posts', function(request, response, next) {

	console.log('** Express post() /posts route **');

	var post = new Post(request.body);

	post.save(function(err, post) {								// Mongoose save() to save new post to MongoDB
		if (err) {
			return next(err);
		}

		response.json(post);
	});
});

router.get('/posts/:post', function(request, response) {
	response.json(request.post);
})

module.exports = router;

<|endoftext|>


<commit_before>/*
INI Settings Handler Tests

Copyright 2012 Raising the Floor - International

Licensed under the New BSD license. You may not use this file except in
compliance with this License.

You may obtain a copy of the License at
https://github.com/gpii/universal/LICENSE.txt
*/

/*global require, __dirname, setTimeout*/

(function () {

    "use strict";

    // This loads universal.
    var fluid = require("infusion"),
        gpii = fluid.registerNamespace("gpii"),
        jqUnit = fluid.require("jqUnit"),
        fs = require("fs");

    require("testFramework");
    require("settingsHandlers");

    var INIHandlerTester = gpii.tests.testEnvironment();

    var tests = {
        basicTest: {
            defaultFile: __dirname + "/data/INISettingsHandler/test1_default.ini",
            tmpFile: __dirname + "/data/INISettingsHandler/test1_tmp.ini",
            expectedFile: __dirname + "/data/INISettingsHandler/test1_expectedOutput.ini",
            payload: {
                "nvda.screenReader": [{
                    options: {
                        "path": __dirname + "/data/INISettingsHandler/test1_tmp.ini"
                    },
                    settings: {
                        "general.askToExit": false,
                        "general.showWelcomeDialogAtStartup": false,
                        "speech.symbolLevel": 90
                    }
                }]
            },
            expectedResult: {
                "nvda.screenReader": [{
                    options: {
                        "path": __dirname + "/data/INISettingsHandler/test1_tmp.ini"
                    },
                    settings: {
                        "general.askToExit": { newValue: false, oldValue: "True" },
                        "general.showWelcomeDialogAtStartup": { newValue: false, oldValue: "True" },
                        "speech.symbolLevel": { newValue: 90, oldValue: "100" }
                    }
                }]
            }
        },
        complexTest: {
            defaultFile: __dirname + "/data/INISettingsHandler/test2_default.ini",
            tmpFile: __dirname + "/data/INISettingsHandler/test2_tmp.ini",
            expectedFile: __dirname + "/data/INISettingsHandler/test2_expectedOutput.ini",
            payload: {
                "nvda.screenReader": [{
                    options: {
                        "path": __dirname + "/data/INISettingsHandler/test2_tmp.ini",
                        "allowHashComments": true,
                        "allowSubSections": true
                    },
                    settings: {
                        "speech.symbolLevel": 90,
                        "speech.espeak.rate": 40,
                        "speech.espeak.pitch": 30,
                        "speech.espeak2.newEntry": 30
                    }
                }]
            },
            expectedResult: {
                "nvda.screenReader": [{
                    options: {
                        "path": __dirname + "/data/INISettingsHandler/test2_tmp.ini",
                        "allowHashComments": true,
                        "allowSubSections": true
                    },
                    settings: {
                        "speech.symbolLevel": { newValue: 90, oldValue: "100" },
                        "speech.espeak.rate": { newValue: 40, oldValue: "30" },
                        "speech.espeak.pitch": { newValue: 30, oldValue: "40" },
                        "speech.espeak2.newEntry": { newValue: 30, oldValue: undefined }
                    }
                }]
            }
        }
    };

    // avoid issue with windows using \r\n and unix using \n
    var unixLinebreak = function (str) {
        return str.replace(/\r\n/g, "\n");
    };

    var tester = function (name, test) {
            // read original INI and copy to a file we can mess up:
            var origINI = fs.readFileSync(test.defaultFile, "utf-8");
            fs.writeFileSync(test.tmpFile, origINI, "utf-8");
            // test return payload
            var returnPayload = gpii.settingsHandlers.INISettingsHandler.set(test.payload);
            jqUnit.assertDeepEq("Checking return payload for "+name+" INI file: ", test.expectedResult, returnPayload);

            // next check that the written INI file is as expected:
            var savedINI = fs.readFileSync(test.tmpFile, "utf-8");
            savedINI = unixLinebreak(savedINI);
            var expectedINI = fs.readFileSync(test.expectedFile, "utf-8");
            expectedINI = unixLinebreak(expectedINI);
            jqUnit.assertEquals("checking INI file for "+name+": ", expectedINI, savedINI);

    };

    INIHandlerTester.test("INIHandler.set", function () {
        jqUnit.module("INI Settings Handler tests");
        fluid.each(tests, function (v, k) {
            tester(k, v);
        });
    });
}());<commit_msg>GPII-85, GPII-83: Linted files, fixed minor error<commit_after>/*
INI Settings Handler Tests

Copyright 2012 Raising the Floor - International

Licensed under the New BSD license. You may not use this file except in
compliance with this License.

You may obtain a copy of the License at
https://github.com/gpii/universal/LICENSE.txt
*/

/*global require, __dirname */

(function () {

    "use strict";

    // This loads universal.
    var fluid = require("infusion"),
        gpii = fluid.registerNamespace("gpii"),
        jqUnit = fluid.require("jqUnit"),
        fs = require("fs");

    require("testFramework");
    require("settingsHandlers");

    var INIHandlerTester = gpii.tests.testEnvironment();

    var tests = {
        basicTest: {
            defaultFile: __dirname + "/data/INISettingsHandler/test1_default.ini",
            tmpFile: __dirname + "/data/INISettingsHandler/test1_tmp.ini",
            expectedFile: __dirname + "/data/INISettingsHandler/test1_expectedOutput.ini",
            payload: {
                "nvda.screenReader": [{
                    options: {
                        "path": __dirname + "/data/INISettingsHandler/test1_tmp.ini"
                    },
                    settings: {
                        "general.askToExit": false,
                        "general.showWelcomeDialogAtStartup": false,
                        "speech.symbolLevel": 90
                    }
                }]
            },
            expectedResult: {
                "nvda.screenReader": [{
                    options: {
                        "path": __dirname + "/data/INISettingsHandler/test1_tmp.ini"
                    },
                    settings: {
                        "general.askToExit": { newValue: false, oldValue: "True" },
                        "general.showWelcomeDialogAtStartup": { newValue: false, oldValue: "True" },
                        "speech.symbolLevel": { newValue: 90, oldValue: "100" }
                    }
                }]
            }
        },
        complexTest: {
            defaultFile: __dirname + "/data/INISettingsHandler/test2_default.ini",
            tmpFile: __dirname + "/data/INISettingsHandler/test2_tmp.ini",
            expectedFile: __dirname + "/data/INISettingsHandler/test2_expectedOutput.ini",
            payload: {
                "nvda.screenReader": [{
                    options: {
                        "path": __dirname + "/data/INISettingsHandler/test2_tmp.ini",
                        "allowHashComments": true,
                        "allowSubSections": true
                    },
                    settings: {
                        "speech.symbolLevel": 90,
                        "speech.espeak.rate": 40,
                        "speech.espeak.pitch": 30,
                        "speech.espeak2.newEntry": 30
                    }
                }]
            },
            expectedResult: {
                "nvda.screenReader": [{
                    options: {
                        "path": __dirname + "/data/INISettingsHandler/test2_tmp.ini",
                        "allowHashComments": true,
                        "allowSubSections": true
                    },
                    settings: {
                        "speech.symbolLevel": { newValue: 90, oldValue: "100" },
                        "speech.espeak.rate": { newValue: 40, oldValue: "30" },
                        "speech.espeak.pitch": { newValue: 30, oldValue: "40" },
                        "speech.espeak2.newEntry": { newValue: 30, oldValue: undefined }
                    }
                }]
            }
        }
    };

    // avoid issue with windows using \r\n and unix using \n
    var unixLinebreak = function (str) {
        return str.replace(/\r\n/g, "\n");
    };

    var tester = function (name, test) {
            // read original INI and copy to a file we can mess up:
            var origINI = fs.readFileSync(test.defaultFile, "utf-8");
            fs.writeFileSync(test.tmpFile, origINI, "utf-8");
            // test return payload
            var returnPayload = gpii.settingsHandlers.INISettingsHandler.set(test.payload);
            jqUnit.assertDeepEq("Checking return payload for "+name+" INI file: ", test.expectedResult, returnPayload);

            // next check that the written INI file is as expected:
            var savedINI = fs.readFileSync(test.tmpFile, "utf-8");
            savedINI = unixLinebreak(savedINI);
            var expectedINI = fs.readFileSync(test.expectedFile, "utf-8");
            expectedINI = unixLinebreak(expectedINI);
            jqUnit.assertEquals("checking INI file for "+name+": ", expectedINI, savedINI);

    };

    INIHandlerTester.test("INIHandler.set", function () {
        jqUnit.module("INI Settings Handler tests");
        fluid.each(tests, function (v, k) {
            tester(k, v);
        });
    });
}());<|endoftext|>


<commit_before>/*global JsonFx, JsonML, jQuery */
/*
	JsonFx_Bindings.js
	dynamic behavior binding support

	Created: 2006-11-11-1759
	Modified: 2009-03-01-1621

	Copyright (c)2006-2009 Stephen M. McKamey
	Distributed under an open-source license: http://jsonfx.net/license
*/

/* namespace JsonFx */
if ("undefined" === typeof window.JsonFx) {
	window.JsonFx = {};
}
/* namespace JsonFx.UI */
if ("undefined" === typeof JsonFx.UI) {
	JsonFx.UI = {};
}

/* dependency checks --------------------------------------------*/

/* singleton JsonFx.Bindings */
JsonFx.Bindings = function() {

	/*object*/ var b = this;
	/*bool*/ var jQ = ("undefined" !== typeof jQuery);
	/*const string*/ var BIND = 1, UNBIND = 2;

	/*
		the structure of bindings and the implementation of add, bind, and unbind fork on presence of jQuery.
		if jQuery is present before JsonFx.Bindings, then the selector implementation is delegated to jQuery.
		otherwise a simple selector lookup structure is built to very specifically allow lookups without
		a lot of iterations.
	*/
	/*Dictionary<string,object>*/ var bindings = jQ ? [] : {};

	/*RegExp*/ var re = /^\s*([\w\-]*|[*])(?:#([\w\-]+)|\.([\w\-]+))?(?:#([\w\-]+)|\.([\w\-]+))?\s*$/;

	/*void*/ b.add = jQ ?
		// jQuery JsonFx.Bindings.add implementation
		function(/*string*/ selector, /*function(elem)*/ bind, /*function(elem)*/ unbind) {
			if (typeof bind !== "function") {
				bind = null;
			}
			if (typeof unbind !== "function") {
				unbind = null;
			}
			if (!selector || (!bind && !unbind)) {
				return;
			}

			var binding = { selector: selector };
			binding[BIND] = bind;
			binding[UNBIND] = unbind;
			bindings.push(binding);
		} :
		// simple JsonFx.Bindings.add implementation
		function(/*string*/ selector, /*function(elem)*/ bind, /*function(elem)*/ unbind) {
			if (typeof bind !== "function") {
				bind = null;
			}
			if (typeof unbind !== "function") {
				unbind = null;
			}
			if (!selector || (!bind && !unbind)) {
				return;
			}

			var s = selector instanceof Array ?
				selector :
				String(selector).split(',');
			while (s.length > 1) {
				b.add(s.shift(), bind, unbind);
			}
			selector = s.shift();

			s = re.exec(selector);
			if (!s) {
				// http://www.w3.org/TR/css3-selectors/#simple-selectors
				throw new Error("JsonFx.Bindings only supports simple tag, class, and id selectors. Selector: \""+selector+"\"");
			}

			s = {
				tag: (s[1]||"*").toLowerCase(),
				css: (s[3]||s[5]||"*"),
				id: (s[2]||s[4]||"")
			};

			if (s.id) {
				if (s.tag !== "*" || s.css !== "*") {
					throw new Error("JsonFx.Bindings only supports simple ID selectors. Add jQuery to enable full selector support. Selector: \""+selector+"\"");
				}
				if ("undefined" === typeof bindings["#"]) {
					/*object*/ bindings["#"] = {};
				}

				/*object*/ bindings["#"][s.id] = {};
				bindings["#"][s.id][BIND] = bind;
				bindings["#"][s.id][UNBIND] = unbind;
			} else {
				if ("undefined" === typeof bindings[s.tag]) {
					/*object*/ bindings[s.tag] = {};
				} else if (bindings[s.tag][s.css]) {
					throw new Error("A binding for "+selector+" has already been registered.");
				}

				/*object*/ bindings[s.tag][s.css] = {};
				bindings[s.tag][s.css][BIND] = bind;
				bindings[s.tag][s.css][UNBIND] = unbind;
			}
		};

	/*deprecated*/
	/*void*/ b.register = function(/*string*/ tag, /*string*/ css, /*function(elem)*/ bind, /*function(elem)*/ unbind) {
		b.add(tag+'.'+css, bind, unbind);
	};

	/*DOM*/ var performOne = jQ ?
		// jQuery performOne implementation
		function(/*DOM*/ elem, /*actionKey*/ a) {
			function go(/*string*/ selector, /*function*/ action) {
				return function() {
					try {
						elem = action(this) || this;
					} catch (ex) {
						window.alert("Error binding "+selector+" (line "+(ex.lineNumber||ex.line||1)+"):\n\""+(ex&&ex.message||String(ex))+"\"");
						/*jslint evil:true */
						debugger;
						/*jslint evil:false */
					}
				};
			}
			for (var i=0; i<bindings.length; i++) {
				if (bindings[i][a]) {
					jQuery(elem).filter(bindings[i].selector).each(go(bindings[i].selector, bindings[i][a]));
				}
			}
			return elem;
		} :
		// simple performOne implementation
		function(/*DOM*/ elem, /*actionKey*/ a) {

			function bindSet(/*object*/ binds, /*string*/ css) {
				if (binds && binds[css] && binds[css][a]) {
					try {
						// perform action on element and
						// allow binding to replace element
						elem = binds[css][a](elem) || elem;
					} catch (ex) {
						var selector = elem.tagName+"."+css;
						if (elem.id) {
							selector += "#"+elem.id;
						}
						window.alert("Error binding "+selector+" (line "+(ex.lineNumber||ex.line||1)+"):\n\""+(ex&&ex.message||String(ex))+"\"");
						/*jslint evil:true */
						debugger;
						/*jslint evil:false */
					}
				}
			}

			if (elem && elem.tagName) {

				// only perform on registered tags
				var tag = elem.tagName.toLowerCase();
				var allBinds = bindings["*"];
				var tagBinds = bindings[tag];

				if (tagBinds || allBinds) {

					bindSet(tagBinds, "*");
					bindSet(allBinds, "*");

					if (elem.className) {
						// for each css class in elem
						var classes = elem.className.split(/\s+/);
						for (var i=0; i<classes.length; i++) {
							var css = classes[i];
							bindSet(tagBinds, css);
							bindSet(allBinds, css);
						}
					}
				}
			}
			return elem;
		};

	var performOneID = jQ ?
		// no jQuery performOneID implementation
		null :
		// simple performOneID implementation
		function (/*DOM*/ elem, /*actionKey*/ a) {
			var action = bindings["#"][elem.id];
			action = action && action[a];
			return (action && action(elem)) || elem;
		};

	// perform a binding action on all child elements
	/*void*/ var perform = jQ ?
		// jQuery perform implementation
		function(/*DOM*/ root, /*actionKey*/ a) {
			function go(/*string*/ selector, /*function*/ action) {
				return function() {
					try {
						var elem = action(this) || this;
						if (elem !== this) {
							this.parentNode.replaceChild(elem, this);
						}
					} catch (ex) {
						window.alert("Error binding "+selector+" (line "+(ex.lineNumber||ex.line||1)+"):\n\""+(ex&&ex.message||String(ex))+"\"");
						/*jslint evil:true */
						debugger;
						/*jslint evil:false */
					}
				};
			}
			for (var i=0; i<bindings.length; i++) {
				if (bindings[i][a]) {
					jQuery(bindings[i].selector, root).each(go(bindings[i].selector, bindings[i][a]));
				}
			}
		} :
		// simple perform implementation
		function(/*DOM*/ root, /*actionKey*/ a) {

	// TODO: add ability to bind on ID, className, tagName or any combination
	// determine how to most efficiently select the smallest set of eligible elements

			/*create a closure for replacement*/
			function queueReplacer(newer, older) {
				window.setTimeout(function() {
					if (older && older.parentNode) {
						older.parentNode.replaceChild(newer, older);
					}
					// free references
					newer = older = null;
				}, 0);
			}

			function bindTagSet(/*string*/ tag) {
				// for each element in root with tagName
				var elems = root.getElementsByTagName(tag);
				for (var i=0; i<elems.length; i++) {
					// perform action on element and
					// allow binding to replace element
					var replace = performOne(elems[i], a);
					if (replace !== elems[i] && elems[i].parentNode) {
						// queue up replacement at the end so as not to disrupt the list
						queueReplacer(replace, elems[i]);
					}
				}
			}

			if (bindings["#"]) {
				for (var id in bindings["#"]) {
					if (bindings["#"].hasOwnProperty(id)) {
						var elem = document.getElementById(id);
						if (!elem) {
							continue;
						}
						var replace = performOneID(elem, a);
						if (replace !== elem) {
							// queue up replacement at the end so as not to disrupt the list
							queueReplacer(replace, elem);
						}
					}
				}
			}
			root = root || document.body;
			if (root.getElementsByTagName) {
				if (bindings["*"]) {
					// if star rule, then must apply to all
					bindTagSet("*");
				} else {
					// only apply to tags with rules
					for (var tag in bindings) {
						if (bindings.hasOwnProperty(tag) && tag !== "*" && tag !== "#") {
							bindTagSet(tag);
						}
					}
				}
			}
		};

	// bind
	/*void*/ b.bind = function(/*DOM*/ root) {
		if (!isFinite(root.nodeType)) {
			root = null;
		}

		perform(root, BIND);
	};

	// unbind
	/*void*/ b.unbind = function(/*DOM*/ root) {
		if (!isFinite(root.nodeType)) {
			root = null;
		}

		perform(root, UNBIND);
	};

	// use bindOne as the default JBST filter
	if ("undefined" !== typeof JsonML && JsonML.BST) {
		var bindOne = /*DOM*/ function(/*DOM*/ elem) {
			if (performOneID && bindings["#"]) {
				elem = performOneID(elem, BIND);
			}
			elem = performOne(elem, BIND);
			return elem;
		};

		if ("function" !== typeof JsonML.BST.filter) {
			JsonML.BST.filter = bindOne;
		} else {
			JsonML.BST.filter = (function() {
				var old = JsonML.BST.filter;
				return function(/*DOM*/ elem) {
					elem = old(elem);
					return elem && bindOne(elem);
				};
			})();
		}
	}

	// shorthand for auto-replacing an element with JBST bind
	/*void*/ b.replace = function(/*string*/ selector, /*JBST*/ jbst, /*object*/ data, /*int*/ index, /*int*/ count) {
		JsonFx.Bindings.add(
			selector,
			function(elem) {
				return JsonML.BST(jbst).bind(data, index, count) || elem;
			});
	};

	/*void*/ function addHandler(/*DOM*/ target, /*string*/ name, /*function*/ handler) {
		if (typeof jQuery !== "undefined") {
			jQuery(target).bind(name, handler);
		} else if (target.addEventListener) {
			// DOM Level 2 model for binding events
			target.addEventListener(name, handler, false);
		} else if (target.attachEvent) {
			// IE model for binding events
			target.attachEvent("on"+name, handler);
		} else {
			// DOM Level 0 model for binding events
			var old = target["on"+name];
			target["on"+name] = ("function" === typeof old) ?
				function(/*Event*/ evt) { handler(evt); return old(evt); } :
				handler;
		}
	}

	// register bind events
	addHandler(window, "load", b.bind);
	addHandler(window, "unload", b.unbind);
};

// doing instead of anonymous fn for JSLint compatibility
// instantiate only one, destroying the constructor
JsonFx.Bindings = new JsonFx.Bindings();
<commit_msg>- fixing JSLint options<commit_after>/*global JsonFx, JsonML, jQuery */
/*
	JsonFx_Bindings.js
	dynamic behavior binding support

	Created: 2006-11-11-1759
	Modified: 2009-03-01-1621

	Copyright (c)2006-2009 Stephen M. McKamey
	Distributed under an open-source license: http://jsonfx.net/license
*/

/* namespace JsonFx */
if ("undefined" === typeof window.JsonFx) {
	window.JsonFx = {};
}
/* namespace JsonFx.UI */
if ("undefined" === typeof JsonFx.UI) {
	JsonFx.UI = {};
}

/* dependency checks --------------------------------------------*/

/* singleton JsonFx.Bindings */
JsonFx.Bindings = function() {

	/*object*/ var b = this;
	/*bool*/ var jQ = ("undefined" !== typeof jQuery);
	/*const string*/ var BIND = 1, UNBIND = 2;

	/*
		the structure of bindings and the implementation of add, bind, and unbind fork on presence of jQuery.
		if jQuery is present before JsonFx.Bindings, then the selector implementation is delegated to jQuery.
		otherwise a simple selector lookup structure is built to very specifically allow lookups without
		a lot of iterations.
	*/
	/*Dictionary<string,object>*/ var bindings = jQ ? [] : {};

	/*RegExp*/ var re = /^\s*([\w\-]*|[*])(?:#([\w\-]+)|\.([\w\-]+))?(?:#([\w\-]+)|\.([\w\-]+))?\s*$/;

	/*void*/ b.add = jQ ?
		// jQuery JsonFx.Bindings.add implementation
		function(/*string*/ selector, /*function(elem)*/ bind, /*function(elem)*/ unbind) {
			if (typeof bind !== "function") {
				bind = null;
			}
			if (typeof unbind !== "function") {
				unbind = null;
			}
			if (!selector || (!bind && !unbind)) {
				return;
			}

			var binding = { selector: selector };
			binding[BIND] = bind;
			binding[UNBIND] = unbind;
			bindings.push(binding);
		} :
		// simple JsonFx.Bindings.add implementation
		function(/*string*/ selector, /*function(elem)*/ bind, /*function(elem)*/ unbind) {
			if (typeof bind !== "function") {
				bind = null;
			}
			if (typeof unbind !== "function") {
				unbind = null;
			}
			if (!selector || (!bind && !unbind)) {
				return;
			}

			var s = selector instanceof Array ?
				selector :
				String(selector).split(',');
			while (s.length > 1) {
				b.add(s.shift(), bind, unbind);
			}
			selector = s.shift();

			s = re.exec(selector);
			if (!s) {
				// http://www.w3.org/TR/css3-selectors/#simple-selectors
				throw new Error("JsonFx.Bindings only supports simple tag, class, and id selectors. Selector: \""+selector+"\"");
			}

			s = {
				tag: (s[1]||"*").toLowerCase(),
				css: (s[3]||s[5]||"*"),
				id: (s[2]||s[4]||"")
			};

			if (s.id) {
				if (s.tag !== "*" || s.css !== "*") {
					throw new Error("JsonFx.Bindings only supports simple ID selectors. Add jQuery to enable full selector support. Selector: \""+selector+"\"");
				}
				if ("undefined" === typeof bindings["#"]) {
					/*object*/ bindings["#"] = {};
				}

				/*object*/ bindings["#"][s.id] = {};
				bindings["#"][s.id][BIND] = bind;
				bindings["#"][s.id][UNBIND] = unbind;
			} else {
				if ("undefined" === typeof bindings[s.tag]) {
					/*object*/ bindings[s.tag] = {};
				} else if (bindings[s.tag][s.css]) {
					throw new Error("A binding for "+selector+" has already been registered.");
				}

				/*object*/ bindings[s.tag][s.css] = {};
				bindings[s.tag][s.css][BIND] = bind;
				bindings[s.tag][s.css][UNBIND] = unbind;
			}
		};

	/*deprecated*/
	/*void*/ b.register = function(/*string*/ tag, /*string*/ css, /*function(elem)*/ bind, /*function(elem)*/ unbind) {
		b.add(tag+'.'+css, bind, unbind);
	};

	/*DOM*/ var performOne = jQ ?
		// jQuery performOne implementation
		function(/*DOM*/ elem, /*actionKey*/ a) {
			function go(/*string*/ selector, /*function*/ action) {
				return function() {
					try {
						elem = action(this) || this;
					} catch (ex) {
						window.alert("Error binding "+selector+" (line "+(ex.lineNumber||ex.line||1)+"):\n\""+(ex&&ex.message||String(ex))+"\"");
						/*jslint debug:true */
						debugger;
						/*jslint debug:false */
					}
				};
			}
			for (var i=0; i<bindings.length; i++) {
				if (bindings[i][a]) {
					jQuery(elem).filter(bindings[i].selector).each(go(bindings[i].selector, bindings[i][a]));
				}
			}
			return elem;
		} :
		// simple performOne implementation
		function(/*DOM*/ elem, /*actionKey*/ a) {

			function bindSet(/*object*/ binds, /*string*/ css) {
				if (binds && binds[css] && binds[css][a]) {
					try {
						// perform action on element and
						// allow binding to replace element
						elem = binds[css][a](elem) || elem;
					} catch (ex) {
						var selector = elem.tagName+"."+css;
						if (elem.id) {
							selector += "#"+elem.id;
						}
						window.alert("Error binding "+selector+" (line "+(ex.lineNumber||ex.line||1)+"):\n\""+(ex&&ex.message||String(ex))+"\"");
						/*jslint debug:true */
						debugger;
						/*jslint debug:false */
					}
				}
			}

			if (elem && elem.tagName) {

				// only perform on registered tags
				var tag = elem.tagName.toLowerCase();
				var allBinds = bindings["*"];
				var tagBinds = bindings[tag];

				if (tagBinds || allBinds) {

					bindSet(tagBinds, "*");
					bindSet(allBinds, "*");

					if (elem.className) {
						// for each css class in elem
						var classes = elem.className.split(/\s+/);
						for (var i=0; i<classes.length; i++) {
							var css = classes[i];
							bindSet(tagBinds, css);
							bindSet(allBinds, css);
						}
					}
				}
			}
			return elem;
		};

	var performOneID = jQ ?
		// no jQuery performOneID implementation
		null :
		// simple performOneID implementation
		function (/*DOM*/ elem, /*actionKey*/ a) {
			var action = bindings["#"][elem.id];
			action = action && action[a];
			return (action && action(elem)) || elem;
		};

	// perform a binding action on all child elements
	/*void*/ var perform = jQ ?
		// jQuery perform implementation
		function(/*DOM*/ root, /*actionKey*/ a) {
			function go(/*string*/ selector, /*function*/ action) {
				return function() {
					try {
						var elem = action(this) || this;
						if (elem !== this) {
							this.parentNode.replaceChild(elem, this);
						}
					} catch (ex) {
						window.alert("Error binding "+selector+" (line "+(ex.lineNumber||ex.line||1)+"):\n\""+(ex&&ex.message||String(ex))+"\"");
						/*jslint debug:true */
						debugger;
						/*jslint debug:false */
					}
				};
			}
			for (var i=0; i<bindings.length; i++) {
				if (bindings[i][a]) {
					jQuery(bindings[i].selector, root).each(go(bindings[i].selector, bindings[i][a]));
				}
			}
		} :
		// simple perform implementation
		function(/*DOM*/ root, /*actionKey*/ a) {

	// TODO: add ability to bind on ID, className, tagName or any combination
	// determine how to most efficiently select the smallest set of eligible elements

			/*create a closure for replacement*/
			function queueReplacer(newer, older) {
				window.setTimeout(function() {
					if (older && older.parentNode) {
						older.parentNode.replaceChild(newer, older);
					}
					// free references
					newer = older = null;
				}, 0);
			}

			function bindTagSet(/*string*/ tag) {
				// for each element in root with tagName
				var elems = root.getElementsByTagName(tag);
				for (var i=0; i<elems.length; i++) {
					// perform action on element and
					// allow binding to replace element
					var replace = performOne(elems[i], a);
					if (replace !== elems[i] && elems[i].parentNode) {
						// queue up replacement at the end so as not to disrupt the list
						queueReplacer(replace, elems[i]);
					}
				}
			}

			if (bindings["#"]) {
				for (var id in bindings["#"]) {
					if (bindings["#"].hasOwnProperty(id)) {
						var elem = document.getElementById(id);
						if (!elem) {
							continue;
						}
						var replace = performOneID(elem, a);
						if (replace !== elem) {
							// queue up replacement at the end so as not to disrupt the list
							queueReplacer(replace, elem);
						}
					}
				}
			}
			root = root || document.body;
			if (root.getElementsByTagName) {
				if (bindings["*"]) {
					// if star rule, then must apply to all
					bindTagSet("*");
				} else {
					// only apply to tags with rules
					for (var tag in bindings) {
						if (bindings.hasOwnProperty(tag) && tag !== "*" && tag !== "#") {
							bindTagSet(tag);
						}
					}
				}
			}
		};

	// bind
	/*void*/ b.bind = function(/*DOM*/ root) {
		if (!isFinite(root.nodeType)) {
			root = null;
		}

		perform(root, BIND);
	};

	// unbind
	/*void*/ b.unbind = function(/*DOM*/ root) {
		if (!isFinite(root.nodeType)) {
			root = null;
		}

		perform(root, UNBIND);
	};

	// use bindOne as the default JBST filter
	if ("undefined" !== typeof JsonML && JsonML.BST) {
		var bindOne = /*DOM*/ function(/*DOM*/ elem) {
			if (performOneID && bindings["#"]) {
				elem = performOneID(elem, BIND);
			}
			elem = performOne(elem, BIND);
			return elem;
		};

		if ("function" !== typeof JsonML.BST.filter) {
			JsonML.BST.filter = bindOne;
		} else {
			JsonML.BST.filter = (function() {
				var old = JsonML.BST.filter;
				return function(/*DOM*/ elem) {
					elem = old(elem);
					return elem && bindOne(elem);
				};
			})();
		}
	}

	// shorthand for auto-replacing an element with JBST bind
	/*void*/ b.replace = function(/*string*/ selector, /*JBST*/ jbst, /*object*/ data, /*int*/ index, /*int*/ count) {
		JsonFx.Bindings.add(
			selector,
			function(elem) {
				return JsonML.BST(jbst).bind(data, index, count) || elem;
			});
	};

	/*void*/ function addHandler(/*DOM*/ target, /*string*/ name, /*function*/ handler) {
		if (typeof jQuery !== "undefined") {
			jQuery(target).bind(name, handler);
		} else if (target.addEventListener) {
			// DOM Level 2 model for binding events
			target.addEventListener(name, handler, false);
		} else if (target.attachEvent) {
			// IE model for binding events
			target.attachEvent("on"+name, handler);
		} else {
			// DOM Level 0 model for binding events
			var old = target["on"+name];
			target["on"+name] = ("function" === typeof old) ?
				function(/*Event*/ evt) { handler(evt); return old(evt); } :
				handler;
		}
	}

	// register bind events
	addHandler(window, "load", b.bind);
	addHandler(window, "unload", b.unbind);
};

// doing instead of anonymous fn for JSLint compatibility
// instantiate only one, destroying the constructor
JsonFx.Bindings = new JsonFx.Bindings();
<|endoftext|>


<commit_before>'use strict'
let express = require('express')
let bodyParser = require('body-parser');
let path = require('path');
let chalk = require('chalk');

const app = express()

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

let root = path.join(__dirname, '../');
let rootHtml = path.join(root, 'src/index.html');

app.get('/', function (req, res) {
    res.sendFile(rootHtml);
});

let startServer = function () {
    var server = app.listen(1500, function () {
        var host = server.address().address
        var port = server.address().port
        console.log('server is listening at http://127.0.0.1:'+port)
    })
}

startServer();
<commit_msg>express static node_modules (make avail to browser)<commit_after>'use strict'
let express = require('express')
let bodyParser = require('body-parser');
let path = require('path');
let chalk = require('chalk');

const app = express()

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

let root = path.join(__dirname, '../');
let rootHtml = path.join(root, 'src/index.html');

var browserPath = path.join(root, './src');
app.use(express.static(browserPath));

var modulesPath = path.join(root, './node_modules');
app.use('/node_modules', express.static(modulesPath));

app.get('/', function (req, res) {
    res.sendFile(rootHtml);
});

let startServer = function () {
    var server = app.listen(1500, function () {
        var host = server.address().address
        var port = server.address().port
        console.log('server is listening at http://127.0.0.1:'+port)
    })
}

startServer();
<|endoftext|>


<commit_before>var config = require('./config/config_server');
var logger = require('./logger');

var moment = require('moment');
var monk = require('monk');
var cookieParser = require('cookie-parser');
var passportio = require('passport.socketio');

var db = monk(config.mongoURL);
var chats = db.get('history');
var Item = require('./models/items');
var User = require('./models/users');
var Character = require('./models/character');

var io;
var rooms = {}; // { room_name: client_count }
var buddyList = [];

module.exports.init = function(sio, passport, sessionStore) {
  io = sio;
  sessions = sessionStore;
  io.sockets.on('connection', onConnect);
  io.set('authorization', passportio.authorize({
    cookieParser : cookieParser,
    key: config.sessionKey,
    secret: config.sessionSecret,
    store: sessionStore,
    success: authSuccess,
    failure: authFailure
  }));
}

module.exports.closeSocketForUser = function(user) {
  var socket = io.sockets.adapter.rooms[user._id][0];
  socket.disconnect();
}

var updateInventoryForCharacter = function(charId) {
  Item.find({ owned_by: charId }, function (err, doc) {
    io.to(charId).emit('update-inventory', { inventory: doc });
  });
}
module.exports.updateInventoryForCharacter = updateInventoryForCharacter;

var onConnect = function (socket) {
  var user = getUserFromSocket(socket);

  socket.on('subscribe', function(data) { onSubscribe(socket, data.room); });
  socket.on('unsubscribe', function(data) { onUnsubscribe(socket, data.room); });
  socket.on('disconnect', function() { onDisconnect(socket) });

  socket.on('chat-send', function(data) { onChatReceived(socket, data); });
  socket.on('item-transfer', function(data) { onItemTransfer(data); });

  // auto-join some useful rooms
  socket.join(user._id);
  socket.join(user.currentChar);

  if (user.getPermissionLevel() == 0)
    socket.join('admins');
  if (user.getPermissionLevel() == 1)
    socket.join('superusers');
  if (user.getPermissionLevel() == 2)
    socket.join('players');
}

var onDisconnect = function(socket) {
  logger.info('Socket disconnected. ID: ' + socket.id);
  var roomNames = Object.keys(rooms);
  for (var i in roomNames) {
    onUnsubscribe(socket, roomNames[i]);
  }
}

var onSubscribe = function(socket, room) {
  var user = getUserFromSocket(socket);
  socket.join(room);
  if (rooms[room] == undefined) {
    rooms[room] = 1;
  } else {
    rooms[room] += 1;
  }

  // custom startup behavior for different rooms
  if (room == 'chat') {
    // Login message (to the user)
    socket.emit('message', {
      message: 'Connected to chat. Displaying ' + config.displayRecent + ' most recent messages...',
      timestap: moment(),
      recipients: []
    });
    sendRecentHistory(socket);

    // joined notification (to everyone)
    socket.broadcast.to(room).emit('message', {
      message: 'User ' + user.username + ' has joined the chat.',
      timestamp: moment(),
      recipients: 'all'
    });

    addToBuddyList(socket);
  }
  if (room == 'inventory') {
    sendInventory(socket);
  }
}

var onUnsubscribe = function(socket, room) {
  var user = getUserFromSocket(socket);
  socket.leave(room);
  rooms[room] -= 1;

  // custom exit behavior from different rooms
  if (room == 'chat') {
    // exited notification (to everyone)
    io.to(room).emit('message', {
      message: 'User ' + user.username + ' has left the chat.',
      timestamp: moment(),
      recipients: 'all'
    });

    removeFromBuddyList(user);
  }
}

var onChatReceived = function(socket, data) {
  var targetSockets = [];
  var room = 'chat';
  var user = getUserFromSocket(socket);
  data.username = user.username;
  if (data.recipients == undefined) {
    logger.debug("Initializing chat-send listener: recipients is undefined");
    data.recipients = 'all';
  } else if (data.recipients.length == 0) {
    logger.debug("Initializing chat-send listener: recipients is empty");
    data.recipients = 'all';
  }

  if (data.recipients == 'all') {
    io.to(room).emit('message', data);
  } else {
    User.find({ _id: { $in: data.recipients } }, function(err, doc) {
      data.recipients = [];
      for (var i = 0; i < doc.length; i++) {
        data.recipients.push(doc[i].username);
        io.to(doc[i]._id).emit('message', data);
      }
      io.to(user._id).emit('message', data);
      chats.insert(data);
    });
  }
}

var onItemTransfer = function(data) {
  Item.find({_id: {$in: data.items} }, function(err, items) {
    if (items.length > 0) {
      var currentOwner = items[0].owned_by;
      var targetChar = data.recipient;
      for (var i = 0; i < items.length; i++) {
        items[i].giveToCharacter(data.recipient, function(item) {
          updateInventoryForCharacter(currentOwner);
          updateInventoryForCharacter(targetChar);
        });
      }
    }
  });
}

var sendRecentHistory = function (socket) {
  var user = getUserFromSocket(socket);
  chats.find(
    { $or: [{recipients: 'all'}, {recipients: user.username}, {username: user.username}] },
    { limit: config.displayRecent, sort: {'timestamp': -1} },
    function (err, doc) {
      // work backwards to send recent history in chronological order
      for (var i = 1; i <= doc.length; i++) {
        socket.emit('message', doc[doc.length-i]);
      }
    }
  );
}

var addToBuddyList = function(socket) {
  var user = getUserFromSocket(socket);
  user.populate('currentChar', function(err, fullUser) {
    if (err) throw err;
    if (fullUser) {
      buddyList.push(user);
    }
    io.to('chat').emit('active-users', { users: buddyList });
  });
}

var removeFromBuddyList = function(user) {
  var index = null;
  for (var i = 0; i < buddyList.length; i++) {
    if (buddyList[i]._id == user._id) {
      buddyList.splice(index, 1);
      i--;
    }
  }
  io.to('chat').emit('active-users', { users: buddyList });
}

var getUserFromSocket = function(socket) {
  var user = socket.client.request.user;
  return user;
}

var authSuccess = function(data, accept) {
  logger.info("Socket initiated by user " + data.user.username);
  accept(null, true);
}

var authFailure = function(data, message, error, accept) {
  if (error) throw new Error(message);
  logger.info("Socket auth failed: " + message);
  accept(null, false);
}

// hacking in inventory stuff, this shit will need to be refactored
var sendInventory = function(socket) {
  var user = getUserFromSocket(socket);
  updateInventoryForCharacter(user.currentChar);
}

<commit_msg>code clean-up - moved the public interface for sockets.js to the bottom. It has to be after the declared functions for them to be in scope, but at least this way they ar together. no functional change.<commit_after>var config = require('./config/config_server');
var logger = require('./logger');

var moment = require('moment');
var monk = require('monk');
var cookieParser = require('cookie-parser');
var passportio = require('passport.socketio');

var db = monk(config.mongoURL);
var chats = db.get('history');
var Item = require('./models/items');
var User = require('./models/users');
var Character = require('./models/character');

var io;
var rooms = {}; // { room_name: client_count }
var buddyList = [];

var init = function(sio, passport, sessionStore) {
  io = sio;
  sessions = sessionStore;
  io.sockets.on('connection', onConnect);
  io.set('authorization', passportio.authorize({
    cookieParser : cookieParser,
    key: config.sessionKey,
    secret: config.sessionSecret,
    store: sessionStore,
    success: authSuccess,
    failure: authFailure
  }));
}

var closeSocketForUser = function(user) {
  var socket = io.sockets.adapter.rooms[user._id][0]; // currently only one socket per user. Works for now, fix this later
  socket.disconnect();
}

var updateInventoryForCharacter = function(charId) {
  Item.find({ owned_by: charId }, function (err, doc) {
    io.to(charId).emit('update-inventory', { inventory: doc });
  });
}

var onConnect = function (socket) {
  var user = getUserFromSocket(socket);

  socket.on('subscribe', function(data) { onSubscribe(socket, data.room); });
  socket.on('unsubscribe', function(data) { onUnsubscribe(socket, data.room); });
  socket.on('disconnect', function() { onDisconnect(socket) });

  socket.on('chat-send', function(data) { onChatReceived(socket, data); });
  socket.on('item-transfer', function(data) { onItemTransfer(data); });

  // auto-join some useful rooms
  socket.join(user._id);
  socket.join(user.currentChar);

  if (user.getPermissionLevel() == 0)
    socket.join('admins');
  if (user.getPermissionLevel() == 1)
    socket.join('superusers');
  if (user.getPermissionLevel() == 2)
    socket.join('players');
}

var onDisconnect = function(socket) {
  logger.info('Socket disconnected. ID: ' + socket.id);
  var roomNames = Object.keys(rooms);
  for (var i in roomNames) {
    onUnsubscribe(socket, roomNames[i]);
  }
}

var onSubscribe = function(socket, room) {
  var user = getUserFromSocket(socket);
  socket.join(room);
  if (rooms[room] == undefined) {
    rooms[room] = 1;
  } else {
    rooms[room] += 1;
  }

  // custom startup behavior for different rooms
  if (room == 'chat') {
    // Login message (to the user)
    socket.emit('message', {
      message: 'Connected to chat. Displaying ' + config.displayRecent + ' most recent messages...',
      timestap: moment(),
      recipients: []
    });
    sendRecentHistory(socket);

    // joined notification (to everyone)
    socket.broadcast.to(room).emit('message', {
      message: 'User ' + user.username + ' has joined the chat.',
      timestamp: moment(),
      recipients: 'all'
    });

    addToBuddyList(socket);
  }
  if (room == 'inventory') {
    sendInventory(socket);
  }
}

var onUnsubscribe = function(socket, room) {
  var user = getUserFromSocket(socket);
  socket.leave(room);
  rooms[room] -= 1;

  // custom exit behavior from different rooms
  if (room == 'chat') {
    // exited notification (to everyone)
    io.to(room).emit('message', {
      message: 'User ' + user.username + ' has left the chat.',
      timestamp: moment(),
      recipients: 'all'
    });

    removeFromBuddyList(user);
  }
}

var onChatReceived = function(socket, data) {
  var targetSockets = [];
  var room = 'chat';
  var user = getUserFromSocket(socket);
  data.username = user.username;
  if (data.recipients == undefined) {
    logger.debug("Initializing chat-send listener: recipients is undefined");
    data.recipients = 'all';
  } else if (data.recipients.length == 0) {
    logger.debug("Initializing chat-send listener: recipients is empty");
    data.recipients = 'all';
  }

  if (data.recipients == 'all') {
    io.to(room).emit('message', data);
  } else {
    User.find({ _id: { $in: data.recipients } }, function(err, doc) {
      data.recipients = [];
      for (var i = 0; i < doc.length; i++) {
        data.recipients.push(doc[i].username);
        io.to(doc[i]._id).emit('message', data);
      }
      io.to(user._id).emit('message', data);
      chats.insert(data);
    });
  }
}

var onItemTransfer = function(data) {
  Item.find({_id: {$in: data.items} }, function(err, items) {
    if (items.length > 0) {
      var currentOwner = items[0].owned_by;
      var targetChar = data.recipient;
      for (var i = 0; i < items.length; i++) {
        items[i].giveToCharacter(data.recipient, function(item) {
          updateInventoryForCharacter(currentOwner);
          updateInventoryForCharacter(targetChar);
        });
      }
    }
  });
}

var sendRecentHistory = function (socket) {
  var user = getUserFromSocket(socket);
  chats.find(
    { $or: [{recipients: 'all'}, {recipients: user.username}, {username: user.username}] },
    { limit: config.displayRecent, sort: {'timestamp': -1} },
    function (err, doc) {
      // work backwards to send recent history in chronological order
      for (var i = 1; i <= doc.length; i++) {
        socket.emit('message', doc[doc.length-i]);
      }
    }
  );
}

var addToBuddyList = function(socket) {
  var user = getUserFromSocket(socket);
  user.populate('currentChar', function(err, fullUser) {
    if (err) throw err;
    if (fullUser) {
      buddyList.push(user);
    }
    io.to('chat').emit('active-users', { users: buddyList });
  });
}

var removeFromBuddyList = function(user) {
  var index = null;
  for (var i = 0; i < buddyList.length; i++) {
    if (buddyList[i]._id == user._id) {
      buddyList.splice(index, 1);
      i--;
    }
  }
  io.to('chat').emit('active-users', { users: buddyList });
}

var getUserFromSocket = function(socket) {
  var user = socket.client.request.user;
  return user;
}

var authSuccess = function(data, accept) {
  logger.info("Socket initiated by user " + data.user.username);
  accept(null, true);
}

var authFailure = function(data, message, error, accept) {
  if (error) throw new Error(message);
  logger.info("Socket auth failed: " + message);
  accept(null, false);
}

// hacking in inventory stuff, this shit will need to be refactored
var sendInventory = function(socket) {
  var user = getUserFromSocket(socket);
  updateInventoryForCharacter(user.currentChar);
}

////////////////////////////////////////////////////////
// Public Interface
module.exports.init = init;
module.exports.closeSocketForUser = closeSocketForUser;
module.exports.updateInventoryForCharacter = updateInventoryForCharacter;
<|endoftext|>


<commit_before>/**
 * @namespace
 */
var PropertyAttr	= {};

/**
 * Define a property attribute
 *
 * @param {Object} baseObject the base object to which the property belong
 * @param {String} property   the name of the property
 * @return {PropertyAttr}	builder for property attributes
 */
PropertyAttr.define	= function(baseObject, property){
	return new PropertyAttr.Builder(baseObject, property);
};

/**
 * Constructor
 *
 * @param {Object} baseObject the base object to which the property belong
 * @param {String} property   the name of the property
 */
 PropertyAttr.Builder	= function(baseObject, property){
	// sanity check
	console.assert(typeof(baseObject) === 'object');
	console.assert(typeof(property) === 'string');
	// set local values
	this._baseObject= baseObject;
	this._property	= property;
}

// export the class in node.js - if running in node.js
if( typeof(window) === 'undefined' )	module.exports	= PropertyAttr;

//////////////////////////////////////////////////////////////////////////////////
//		.typeCheck()							//
//////////////////////////////////////////////////////////////////////////////////

var TypeCheck	= TypeCheck	|| require('../src/typecheck.js')

/**
 * check if this property is of validTypes
 * @param  {[type]} types valid types in typecheck.js format
 * @return {PropertyAttr.Builder} for chained API
 */
PropertyAttr.Builder.prototype.typeCheck	= function(types){
	TypeCheck.setter(this._baseObject, this._property, types);
	return this;	// for chained API;
}

//////////////////////////////////////////////////////////////////////////////////
//		.trackUsage()							//
//////////////////////////////////////////////////////////////////////////////////

var QGetterSetter	= QGetterSetter	|| require('../src/qgettersetter.js');
var Stacktrace		= Stacktrace	|| require('../src/stacktrace.js');

// create the tracker for .trackUsage
PropertyAttr.usageTracker	= new Stacktrace.Tracker();

/**
 * track where this property is used (getter and setter)
 * @param {String|undefined} trackName	optional name for Stacktrace.Tracker. default to originId
 * @return {PropertyAttr.Builder} for chained API
 */
PropertyAttr.Builder.prototype.trackUsage	= function(trackName){
	var tracker	= PropertyAttr.usageTracker;
	// handle polymorphism
	trackName	= trackName	|| 'PropertyAttr.trackerUsage:'+Stacktrace.parse()[1].originId();
	// define getter
	QGetterSetter.defineGetter(this._baseObject, this._property, function(value){
		tracker.record(trackName, 1);
		return value;	// return value unchanged
	});
	// define setter
	QGetterSetter.defineSetter(this._baseObject, this._property, function(value){
		tracker.record(trackName, 1);
		return value;	// return value unchanged
	});
	return this;	// for chained API
}

<commit_msg>added .private() - see #45<commit_after>/**
 * @namespace
 */
var PropertyAttr	= {};

/**
 * Define a property attribute
 *
 * @param {Object} baseObject the base object to which the property belong
 * @param {String} property   the name of the property
 * @return {PropertyAttr}	builder for property attributes
 */
PropertyAttr.define	= function(baseObject, property){
	return new PropertyAttr.Builder(baseObject, property);
};

/**
 * Constructor
 *
 * @param {Object} baseObject the base object to which the property belong
 * @param {String} property   the name of the property
 */
 PropertyAttr.Builder	= function(baseObject, property){
	// sanity check
	console.assert(typeof(baseObject) === 'object');
	console.assert(typeof(property) === 'string');
	// set local values
	this._baseObject= baseObject;
	this._property	= property;
}

// export the class in node.js - if running in node.js
if( typeof(window) === 'undefined' )	module.exports	= PropertyAttr;

//////////////////////////////////////////////////////////////////////////////////
//		.typeCheck()							//
//////////////////////////////////////////////////////////////////////////////////

var TypeCheck	= TypeCheck	|| require('../src/typecheck.js')

/**
 * check if this property is of validTypes
 * @param  {[type]} types valid types in typecheck.js format
 * @return {PropertyAttr.Builder} for chained API
 */
PropertyAttr.Builder.prototype.typeCheck	= function(types){
	TypeCheck.setter(this._baseObject, this._property, types);
	return this;	// for chained API;
}

//////////////////////////////////////////////////////////////////////////////////
//		.trackUsage()							//
//////////////////////////////////////////////////////////////////////////////////

var QGetterSetter	= QGetterSetter	|| require('../src/qgettersetter.js');
var Stacktrace		= Stacktrace	|| require('../src/stacktrace.js');

// create the tracker for .trackUsage
PropertyAttr.usageTracker	= new Stacktrace.Tracker();

/**
 * track where this property is used (getter and setter)
 * @param {String|undefined} trackName	optional name for Stacktrace.Tracker. default to originId
 * @return {PropertyAttr.Builder} for chained API
 */
PropertyAttr.Builder.prototype.trackUsage	= function(trackName){
	var tracker	= PropertyAttr.usageTracker;
	// handle polymorphism
	trackName	= trackName	|| 'PropertyAttr.trackUsage:'+Stacktrace.parse()[1].originId();
	// define getter
	QGetterSetter.defineGetter(this._baseObject, this._property, function(value){
		tracker.record(trackName, 1);
		return value;	// return value unchanged
	});
	// define setter
	QGetterSetter.defineSetter(this._baseObject, this._property, function(value){
		tracker.record(trackName, 1);
		return value;	// return value unchanged
	});
	return this;	// for chained API
}

//////////////////////////////////////////////////////////////////////////////////
//		.privateOf()							//
//////////////////////////////////////////////////////////////////////////////////

var PrivateForJS	= PrivateForJS	|| require('../src/privateforjs.js');

/**
 * Mark this property as private
 * @param  {Function} klass the class to which it is private
 * @return {PropertyAttr.Builder} for chained API
 */
PropertyAttr.Builder.prototype.privateOf	= function(klass){
	PrivateForJS.privateProperty(klass, this._baseObject, this._property);
	return this;	// for chained API
}
<|endoftext|>