<commit_before>

function rag_function(pontosControle, desvio, t, nos, fOUa) {
	var g = [];
	var G = [];
	var ponto = [];
	var n = pontosControle.length;
	var soma = 0;

	G = gaussian(desvio, nos, t, n, fOUa);

	for (var i = 0; i < n; i++) {
		soma = soma + G[i];
	}

	for (var i = 0; i < n; i++) {
		g[i] = G[i] / soma;
	}

	ponto[0] = 0.0;
	ponto[1] = 0.0;
	ponto[2] = 0.0;
	ponto[3] = 1.0;

	for(var i = 0; i < n; i++) {
		ponto[0] += g[i] * pontosControle[i][0];
		ponto[1] += g[i] * pontosControle[i][1];
		ponto[2] += g[i] * pontosControle[i][2];
	}

	return ponto;

}

function rag_points(pontosControle, desvio, subdivisoes, fOUa) {
	var nos = [];
 	var pontos = [];
 	var dist = 0;
 	var n = pontosControle.length;
 	var peso;

 	for (var i = 0; i < n-1; i++) {
 		dist = dist + distance(pontosControle[i], pontosControle[i+1]);
 	}

 	/*for (var i = 0; i < n; i++) {
 		nos.push(dist*i);
 	}*/

 	for (var i = 0; i < n; i++) {
 		nos.push(i/n);
 	}

 	for (var i = 0; i <= subdivisoes; i++) {
		var t = i/subdivisoes;
		var p = rag_function(pontosControle, desvio, t, nos, fOUa);
		pontos.push(p);
	}

	console.log("Pontos RaG");
	console.log(pontos);
	return pontos;

}

// desvio = desvio padrao
// nos = vetor de nos
// n = quantidade de pontos de controle
// t = parametro da funcao
function gaussian(desvio, nos, t, n, fOUa) {
	var G = [];
	var soma = 0;

	var min = Math.ceil((-desvio) * Math.sqrt((-2) * Math.log(0.0000001)));
	var max = Math.ceil(desvio * Math.sqrt((-2) * Math.log(0.0000001)));

	if (fOUa == 'f') {
		// Não está funcionando essa curva fechada!!!
		console.log("CURVA FECHADA RAG");
		for (var i = 0; i < n; i++) {
			for (var j = min; j <= max; j++) {
				var aux1 = (t - (nos[i] + j)) * (t - (nos[i] + j));
				var aux2 = 2 * (desvio * desvio);
				soma = soma + Math.exp((-aux1) / aux2);
				}
			G[i] = soma;
		}
	}
	else {
		console.log("CURVA ABERTA RAG");
		for (var i = 0; i < n; i++) {
			var aux1 = (t - nos[i]) * (t - nos[i]);
			var aux2 = 2 * (desvio * desvio);
			G[i] = Math.exp((-aux1) / aux2);
		}
	}

	return G;
}

function distance(p1, p2) {
	var dx = p1[0] - p2[0];
	var dy = p1[1] - p2[1];

	var dist = Math.sqrt(dx*dx + dy*dy);

	return dist;
} <commit_msg>Change values of nodes, working better, but is not drawing the curve when moving the control points.<commit_after>

function rag_function(pontosControle, desvio, t, nos, fOUa) {
	var g = [];
	var G = [];
	var ponto = [];
	var n = pontosControle.length;
	var soma = 0;

	G = gaussian(desvio, nos, t, n, fOUa);

	for (var i = 0; i < n; i++) {
		soma = soma + G[i];
	}

	for (var i = 0; i < n; i++) {
		g[i] = G[i] / soma;
	}

	ponto[0] = 0.0;
	ponto[1] = 0.0;
	ponto[2] = 0.0;
	ponto[3] = 1.0;

	for(var i = 0; i < n; i++) {
		ponto[0] += g[i] * pontosControle[i][0];
		ponto[1] += g[i] * pontosControle[i][1];
		ponto[2] += g[i] * pontosControle[i][2];
	}

	return ponto;

}

function rag_points(pontosControle, desvio, subdivisoes, fOUa) {
	var nos = [];
 	var pontos = [];
 	var dist = 0;
 	var n = pontosControle.length;
 	var peso;

 	for (var i = 0; i < n-1; i++) {
 		dist = dist + distance(pontosControle[i], pontosControle[i+1]);
 	}

  	for (var i = 0; i < n; i++) {
 		nos.push(dist*i);
 	}

 	/*for (var i = 0; i < n; i++) {
 		nos.push(i/n);
 	}*/

 	/*for (var i = 0; i < n; i++) {
 		nos.push((dist*i)/n);
 	}*/

 	for (var i = 0; i <= subdivisoes; i++) {
		//var t = i/subdivisoes;
		var t = i;
		var p = rag_function(pontosControle, desvio, t, nos, fOUa);
		pontos.push(p);
	}

	console.log("Pontos RaG");
	console.log(pontos);
	return pontos;

}

// desvio = desvio padrao
// nos = vetor de nos
// n = quantidade de pontos de controle
// t = parametro da funcao
function gaussian(desvio, nos, t, n, fOUa) {
	var G = [];
	var soma = 0;

	var min = Math.ceil((-desvio) * Math.sqrt((-2) * Math.log(0.000001)));
	var max = Math.ceil(desvio * Math.sqrt((-2) * Math.log(0.000001)));

	if (fOUa == 'f') {
		// Não está funcionando essa curva fechada!!!
		console.log("CURVA FECHADA RAG");
		for (var i = 0; i < n; i++) {
			for (var j = min; j <= max; j++) {
				var aux1 = (t - (nos[i] + j)) * (t - (nos[i] + j));
				var aux2 = 2 * (desvio * desvio);
				soma = soma + Math.exp((-aux1) / aux2);
				}
			G[i] = soma;
		}
	}
	else {
		console.log("CURVA ABERTA RAG");
		for (var i = 0; i < n; i++) {
			var aux1 = (t - nos[i]) * (t - nos[i]);
			var aux2 = 2 * (desvio * desvio);
			G[i] = Math.exp((-aux1) / aux2);
		}
	}

	return G;
}

function distance(p1, p2) {
	var dx = p1[0] - p2[0];
	var dy = p1[1] - p2[1];

	var dist = Math.sqrt(dx*dx + dy*dy);

	return dist;
} <|endoftext|>


<commit_before>/*global require, exports
*/
var fs = require("fs");
var measurements = ["time",
                    "ast optimization",
                    "plan instanciation",
                    "parsing",
                    "plan optimization",
                    "execution",
                    "initialization"];

var generatePerfReport = function (reportName, testdata, longdesc) {
  "use strict";
  var i;
  var x = '<?xml version="1.0" encoding="UTF-8"?>\n' +
    '<report name="' + reportName + '" categ="' + reportName + '">\n' +
    '<start> <date format="YYYYMMDD" val="20000101" /> <time format="HHMMSS" val="195043" /> </start>\n'; //// TODO: zeit einsetzen.

  for (var testname in testdata) {
    if (testdata.hasOwnProperty(testname)) {
      for (var testrunner in testdata[testname]) {
        if (testdata[testname].hasOwnProperty(testrunner) && (testrunner !== 'status')) {
          var oneResultSet = testdata[testname][testrunner][0].calced;

          var j = 0;
          for (i = 0; i < measurements.length; i++) {
            if (oneResultSet.hasOwnProperty([measurements[i]])) {
              var s = oneResultSet[measurements[i]].sum;
              var t = oneResultSet[measurements[i]].avg;
              x = x + '\t<test name="/' + testname + '/' + testrunner + '/' + measurements[i] + '" executed="yes">\n';
              x = x + '\t\t<description><![CDATA[This is the description of the test ' + testname + ' executed by the testrunner ' + testrunner + ' run component ' + measurements[i] + ']]></description>\n';
              x = x + '\t\t<targets>\n\t\t\t<target threaded="false">AQL</target>\n\t\t</targets>\n';

              x += '\t\t<commandline rank="' + j + '" time="20100128-195406.590832" duration="' + s + '">Sum ' + measurements[i] + '</commandline>\n';
              j += 1;

              x += '\t\t<commandline rank="' + j + '" time="20100128-195406.590832" duration="' + t + '">Average ' + measurements[i] + '</commandline>\n';
              j += 1;

              x = x + '\t\t<result>\n';
              x += '\t\t\t<success passed="yes" state="100" hasTimedOut="false" />\n';
              x += '\t\t\t<compiletime unit="s" mesure="1.0" isRelevant="false" />\n';
              x += '\t\t\t<performance unit="GFLOPs" mesure="1.0" isRelevant="false" />\n';
              x += '\t\t\t<executiontime unit="s" mesure="'+ oneResultSet[measurements[0]].avg + '" isRelevant="false" />\n';

              x += '\t\t</result>\n';
              x = x + '\t</test>\n';
            }
          }
        }
      }
    }
  }

  x = x + '\n</report>\n';
  fs.write(reportName + ".xml", x);

};

exports.reportGenerator = generatePerfReport;<commit_msg>Our test results are relevant.<commit_after>/*global require, exports
*/
var fs = require("fs");
var measurements = ["time",
                    "ast optimization",
                    "plan instanciation",
                    "parsing",
                    "plan optimization",
                    "execution",
                    "initialization"];

var generatePerfReport = function (reportName, testdata, longdesc) {
  "use strict";
  var i;
  var x = '<?xml version="1.0" encoding="UTF-8"?>\n' +
    '<report name="' + reportName + '" categ="' + reportName + '">\n' +
    '<start> <date format="YYYYMMDD" val="20000101" /> <time format="HHMMSS" val="195043" /> </start>\n'; //// TODO: zeit einsetzen.

  for (var testname in testdata) {
    if (testdata.hasOwnProperty(testname)) {
      for (var testrunner in testdata[testname]) {
        if (testdata[testname].hasOwnProperty(testrunner) && (testrunner !== 'status')) {
          var oneResultSet = testdata[testname][testrunner][0].calced;

          var j = 0;
          for (i = 0; i < measurements.length; i++) {
            if (oneResultSet.hasOwnProperty([measurements[i]])) {
              var s = oneResultSet[measurements[i]].sum;
              var t = oneResultSet[measurements[i]].avg;
              x = x + '\t<test name="/' + testname + '/' + testrunner + '/' + measurements[i] + '" executed="yes">\n';
              x = x + '\t\t<description><![CDATA[This is the description of the test ' + testname + ' executed by the testrunner ' + testrunner + ' run component ' + measurements[i] + ']]></description>\n';
              x = x + '\t\t<targets>\n\t\t\t<target threaded="false">AQL</target>\n\t\t</targets>\n';

              x += '\t\t<commandline rank="' + j + '" time="20100128-195406.590832" duration="' + s + '">Sum ' + measurements[i] + '</commandline>\n';
              j += 1;

              x += '\t\t<commandline rank="' + j + '" time="20100128-195406.590832" duration="' + t + '">Average ' + measurements[i] + '</commandline>\n';
              j += 1;

              x = x + '\t\t<result>\n';
              x += '\t\t\t<success passed="yes" state="100" hasTimedOut="false" />\n';
              x += '\t\t\t<compiletime unit="s" mesure="1.0" isRelevant="false" />\n';
              x += '\t\t\t<performance unit="GFLOPs" mesure="1.0" isRelevant="false" />\n';
              x += '\t\t\t<executiontime unit="s" mesure="'+ oneResultSet[measurements[0]].avg + '" isRelevant="true" />\n';

              x += '\t\t</result>\n';
              x = x + '\t</test>\n';
            }
          }
        }
      }
    }
  }

  x = x + '\n</report>\n';
  fs.write(reportName + ".xml", x);

};

exports.reportGenerator = generatePerfReport;<|endoftext|>


<commit_before>#!/usr/bin/env node
/*
 * Copyright (c) 2009-2013 by Appcelerator, Inc. All Rights Reserved
 *
 * This file will setup the initial package for the JSDUCK documentation
 *
 */

var commander = require('commander'),
	fs = require('fs'),
	wrench = require('wrench'),
	exec = require("child_process").exec,
	browser = "Safari",
	path = require('path'), paths = null;

	require('colors');

	commander
		.version(require('./package.json').version)
        .description('titanium-jsduck command line')
        .usage('titanium-jsduck COMMAND');

		commander.command('install'.blue+' <dir>'.white).description('    create a JSDUCK documentation instance in Titanium Mobile Project'.grey);
		commander.command('open'.blue+' [dir]'.white).description('    open the documentation in browser'.grey);
		commander.parse(process.argv);

		//Opening Banner
		console.log('');
		console.log('Titanium-JSDuck Version ' + commander.version() + ''.white );
		console.log('');

		// Detecting if any commands + arguments where passed
		if( commander.args.length === 0 ){
			runHelp();
		} else {
			switch(commander.args[0]){
			case 'install':
				runInstall();
				break;
			case 'open':

				if( commander.args[1] ){
					browser = commander.args[1];
				}
				runOpenDocumentation(browser);
				break;
			case 'run':
				runGenerator();
				break;
			default:
				console.log('');
				console.log('Invalid Command');
				console.log('');
				break;
			}
		}

		//
		// HELPER METHODS
		//
		function getPaths(){
			var tempPaths = {
				sourceDir: path.join(__dirname)
			}

			tempPaths["sourceTemplates"] = path.join(tempPaths.sourceDir,'templates');
			tempPaths["docTemplates"]    = path.join(tempPaths.sourceDir,'templates','docs');
			tempPaths["cwd"]			 = path.join(process.cwd());
			tempPaths["targetDirectory"] = path.join('.');
			tempPaths["targetDocPath"]	 = path.join(tempPaths.cwd,'docs');
			return tempPaths;

		};

		function copyFile(){
			fs.createReadStream(paths.sourceTemplates + '/alloy.jmk').pipe(fs.createWriteStream('app/alloy.jmk'));
		};

		//
		// Main Command Methods
		//
		function runHelp(){
			var messageHelp = "";

			console.log(messageHelp);
			process.exit();

		}

		function runGenerator(){
			console.log("[LOG] Running JSDuck Documentation Generator");
			console.log();
			exec("jsduck --config=docs/jsduck.json app");
			process.exit();
		}

		function runOpenDocumentation(browserName){

			if( fs.existsSync("docs/documentation/index.html") ){

				switch(browserName){
				case 'Chrome':
				case 'chrome':
					if( !fs.existsSync("/Applications/Google\ Chrome.app") ){
						console.log('[WARNING] Cannot find Chrome Application installed, defaulting to Safari Browser'.orange );
						console.log('');
						browserName = "Safari";
					} else {
						browserName = "Google\ Chrome";
					}
					break;
				case 'Firefox':
				case 'firefox':
					if( !fs.existsSync("/Applications/Firefox.app") ){
						console.log('[WARNING] Cannot find Firefox Application installed, defaulting to Safari Browser'.orange );
						console.log('');
						browserName = "Safari";
					}
					break;
				default:
					browserName = "Safari";
				break;
				}

				var messageSuccess = "[LOG] Opening Project Documentation with the " + browserName + " Browser";
				console.log(messageSuccess.white);
				console.log();

				exec("open -a \"/Applications/" + browserName + ".app\" docs/documentation/index.html");

			} else {
				var messageFailure = "[ERROR] Documentation Folder does not exist yet.  Have you compiled your project yet?";
				console.log(messageFailure.red);
				console.log();
			}

			process.exit();
		}

		function runInstall(){
			// Detect if /app folder exists and/or we are at the root of the Titanium Mobile Project
			if (fs.existsSync("tiapp.xml")) { // or fs.existsSync
			    //
				paths = getPaths();
				console.log("[LOG] Detected an Titanium Mobile Project".white );
				console.log('');

				if( fs.existsSync("app/alloy.jmk") ){
					// Alloy.jmk exists
					//
					console.log('[LOG] Detected an existing Alloy.jmk... Backing up to alloy.jmk.txt'.white);
					console.log('');

					// Making a backup of alloy.jmk if already exists
					fs.createReadStream('app/alloy.jmk').pipe(fs.createWriteStream('app/alloy.jmk.txt'));

					// Copy over New Alloy.JMK

					if( fs.existsSync(paths.sourceTemplates + '/alloy.jmk') ){
						fs.createReadStream(paths.sourceTemplates + '/alloy.jmk').pipe(fs.createWriteStream('app/alloy.jmk'));
						console.log('[LOG] Updated alloy.jmk with config for titanium-jsduck'.white);
						console.log('');

	                     var docPath = path.join(paths.targetDirectory,'docs');
	                     wrench.mkdirSyncRecursive(docPath, 0755);
	                     wrench.copyDirSyncRecursive(paths.docTemplates,paths.targetDocPath,{preserve:true,forceDelete:true});

					} else {
						console.log('[ERROR] cannot find alloy.jmk in templates '.red );
					}

				} else {
					// Alloy.jmk does not exists
					console.log("Cannot find an alloy.jmk file in your project.");
					console.log("Generating a customized alloy.jmk for you with titanium-jsduck configured to run. ");
					//console.log("Please wait.... ");

					console.log('');
					fs.createReadStream(paths.sourceTemplates + '/alloy.jmk').pipe(fs.createWriteStream('app/alloy.jmk'));

                    var docPath = path.join(paths.targetDirectory,'docs');
                    wrench.mkdirSyncRecursive(docPath, 0755);
                    wrench.copyDirSyncRecursive(paths.docTemplates,paths.targetDocPath,{preserve:true,forceDelete:true});

					process.exit();
				}

			} else {
				// App does not exists
			    //
				console.log("Cannot detect if an App folder exists. ");
				console.log("Are you sure you are in the root of Titanium Mobile Project? ");
				console.log('');

				process.exit();
			}
		}

<commit_msg>- updated help message.. - took off .white references for text in case default editor is white background<commit_after>#!/usr/bin/env node
/*
 * Copyright (c) 2009-2013 by Appcelerator, Inc. All Rights Reserved
 *
 * This file will setup the initial package for the JSDUCK documentation
 *
 */

var commander = require('commander'),
	fs = require('fs'),
	wrench = require('wrench'),
	exec = require("child_process").exec,
	browser = "Safari", versionBanner = "",
	path = require('path'), paths = null;

	require('colors');

	commander
		.version(require('./package.json').version)
        .description('titanium-jsduck command line')
        .usage('titanium-jsduck COMMAND');

		commander.command('install'.blue+' <dir>'.white).description('    create a JSDUCK documentation instance in Titanium Mobile Project'.grey);
		commander.command('open'.blue+' [dir]'.white).description('    open the documentation in browser'.grey);
		commander.parse(process.argv);

		//Opening Banner
		console.log('');
		versionBanner = "Titanium-JSDuck Version " + commander.version();
		console.log( versionBanner );
		console.log('');

		// Detecting if any commands + arguments where passed
		if( commander.args.length === 0 ){
			runHelp();
		} else {
			switch(commander.args[0]){
			case 'install':
				runInstall();
				break;
			case 'open':

				if( commander.args[1] ){
					browser = commander.args[1];
				}
				runOpenDocumentation(browser);
				break;
			case 'run':
				runGenerator();
				break;
			default:
				console.log('');
				console.log('[ERROR] Invalid Command has not found ');
				console.log('');
				break;
			}
		}

		//
		// HELPER METHODS
		//
		function getPaths(){
			var tempPaths = {
				sourceDir: path.join(__dirname)
			}

			tempPaths["sourceTemplates"] = path.join(tempPaths.sourceDir,'templates');
			tempPaths["docTemplates"]    = path.join(tempPaths.sourceDir,'templates','docs');
			tempPaths["cwd"]			 = path.join(process.cwd());
			tempPaths["targetDirectory"] = path.join('.');
			tempPaths["targetDocPath"]	 = path.join(tempPaths.cwd,'docs');
			return tempPaths;

		};

		function copyFile(){
			fs.createReadStream(paths.sourceTemplates + '/alloy.jmk').pipe(fs.createWriteStream('app/alloy.jmk'));
		};

		//
		// Main Command Methods
		//
		function runHelp(){
			var messageHelp = "Usage: titanium-jsduck [command] [parameters]\n\n";
			messageHelp += "Commands:\n\tinstall \n\t\t- Installs JSDuck inside a Titanium Mobile Project.";
			messageHelp += "\n\topen \n\t\t- Opens Documentation in Safari Browser";
			messageHelp += "\n\topen firefox \n\t\t- Opens Documentation in Firefox Browser";
			messageHelp += "\n\topen chrome  \n\t\t- Opens Documentation in Google Chrome Browser";
			messageHelp += "\n\trun \n\t\t- Runs jsduck to generate Documentation without compiling Mobile Project";

			console.log(messageHelp);
			console.log();
			process.exit();

		}

		function runGenerator(){
			console.log("[LOG] Running JSDuck Documentation Generator");
			console.log();
			exec("jsduck --config=docs/jsduck.json app");
			process.exit();
		}

		function runOpenDocumentation(browserName){

			if( fs.existsSync("docs/documentation/index.html") ){

				switch(browserName){
				case 'Chrome':
				case 'chrome':
					if( !fs.existsSync("/Applications/Google\ Chrome.app") ){
						console.log('[WARNING] Cannot find Chrome Application installed, defaulting to Safari Browser'.orange );
						console.log('');
						browserName = "Safari";
					} else {
						browserName = "Google\ Chrome";
					}
					break;
				case 'Firefox':
				case 'firefox':
					if( !fs.existsSync("/Applications/Firefox.app") ){
						console.log('[WARNING] Cannot find Firefox Application installed, defaulting to Safari Browser'.orange );
						console.log('');
						browserName = "Safari";
					}
					break;
				default:
					browserName = "Safari";
				break;
				}

				var messageSuccess = "[LOG] Opening Project Documentation with the " + browserName + " Browser";
				console.log(messageSuccess);
				console.log();

				exec("open -a \"/Applications/" + browserName + ".app\" docs/documentation/index.html");

			} else {
				var messageFailure = "[ERROR] Documentation Folder does not exist yet.  Have you compiled your project yet?";
				console.log(messageFailure.red);
				console.log();
			}

			process.exit();
		}

		function runInstall(){
			// Detect if /app folder exists and/or we are at the root of the Titanium Mobile Project
			if (fs.existsSync("tiapp.xml")) { // or fs.existsSync
			    //
				paths = getPaths();
				console.log("[LOG] Detected an Titanium Mobile Project" );
				console.log('');

				if( fs.existsSync("app/alloy.jmk") ){
					// Alloy.jmk exists
					//
					console.log('[LOG] Detected an existing Alloy.jmk... Backing up to alloy.jmk.txt');
					console.log('');

					// Making a backup of alloy.jmk if already exists
					fs.createReadStream('app/alloy.jmk').pipe(fs.createWriteStream('app/alloy.jmk.txt'));

					// Copy over New Alloy.JMK

					if( fs.existsSync(paths.sourceTemplates + '/alloy.jmk') ){
						fs.createReadStream(paths.sourceTemplates + '/alloy.jmk').pipe(fs.createWriteStream('app/alloy.jmk'));
						console.log('[LOG] Updated alloy.jmk with config for titanium-jsduck');
						console.log('');

	                     var docPath = path.join(paths.targetDirectory,'docs');
	                     wrench.mkdirSyncRecursive(docPath, 0755);
	                     wrench.copyDirSyncRecursive(paths.docTemplates,paths.targetDocPath,{preserve:true,forceDelete:true});

					} else {
						console.log('[ERROR] cannot find alloy.jmk in templates '.red );
					}

				} else {
					// Alloy.jmk does not exists
					console.log("Cannot find an alloy.jmk file in your project.");
					console.log("Generating a customized alloy.jmk for you with titanium-jsduck configured to run. ");
					//console.log("Please wait.... ");

					console.log('');
					fs.createReadStream(paths.sourceTemplates + '/alloy.jmk').pipe(fs.createWriteStream('app/alloy.jmk'));

                    var docPath = path.join(paths.targetDirectory,'docs');
                    wrench.mkdirSyncRecursive(docPath, 0755);
                    wrench.copyDirSyncRecursive(paths.docTemplates,paths.targetDocPath,{preserve:true,forceDelete:true});

					process.exit();
				}

			} else {
				// App does not exists
			    //
				console.log("Cannot detect if an App folder exists. ");
				console.log("Are you sure you are in the root of Titanium Mobile Project? ");
				console.log('');

				process.exit();
			}
		}

<|endoftext|>


<commit_before>var utils = (function() {
  var nativeForEach = [].forEach
    , nativeMap = [].map
    , breaker = {};

  return {
    // common utilities
    // ----------------

    isString: function(obj) {
      return typeof obj === 'string';
    }

  , isArray: function(obj) {
      Object.prototype.toString.call(obj) === '[object Array]';
    }

    // stolen from underscore
  , each: function(obj, iterator, context) {
      if (!obj)  { return; }

      // native
      if (nativeForEach && obj.forEach === nativeForEach) {
        obj.forEach(iterator, context);
      }

      // non-native array
      else if (obj.length === +obj.length) {
        for (var i = 0, l = obj.length; i < l; i++) {
          if (iterator.call(context, obj[i], i, obj) === breaker) {
            return;
          }
        }
      }

      // non-native object
      else {
        for (var key in obj) {
          if (obj.hasOwnProperty(key)) {
            if (iterator.call(context, obj[key], key, obj) === breaker) {
              return;
            }
          }
        }
      }
    }

    // stolen from underscore
  , map: function(obj, iterator, context) {
      var results = [];

      if (!obj) { return results; }

      // native
      if (nativeMap && obj.map === nativeMap) {
        return obj.map(iterator, context);
      }

      // non-native
      utils.each(obj, function(value, index, list) {
        results[results.length] = iterator.call(context, value, index, list);
      });

      return results;
    }

  , merge: function(array) {
      return [].concat.apply([], array);
    }

  , mixin: function(target) {
      var args = [].slice.call(arguments, 1), source;

      while (source = args.shift()) {
        for (var k in source) {
          source.hasOwnProperty(k) && (target[k] = source[k]);
        }
      }

      return target;
    }

    // ghostwriter specific utilities
    // ------------------------------

  , isRepeatified: function(obj) {
      return '_repeatified_' in obj;
    }

  , repeatify: function(strokes) {
      var repeatifiedStrokes = {};

      utils.each(strokes, function(val, key) {
        repeatifiedStrokes[key] = function repeat(times) {
          var strokes = [];
          while (times--) { strokes.push(val); }

          return strokes;
        };

        repeatifiedStrokes[key]._repeatified_ = true;
      });

      return repeatifiedStrokes;
    }

    // stroke helpers
    // --------------

  , getKeyEvent: function(type, key) {
      var event = $.Event(type);

      event.which = event.keyCode = utils.isString(key) ?
        key.charCodeAt(0) : key;

      return event;
    }

  , getCursorPos: function($input) {
      var selectionStart = $input[0].selectionStart;

      if (selectionStart) {
       return selectionStart;
      }

      else if (document.selection) {
        $input.focus();

        var range = document.selection.createRange();
        range.moveStart('character', -valueLength);

        return range.text.length;
      }
    }

  , setCursorPos: function($input, pos) {
      var input = $input[0]
        , textRange;

      if (input.createTextRange) {
        textRange = input.createTextRange();
        textRange.collapse(true);
        textRange.moveEnd(pos);
        textRange.moveStart(pos);
        textRange.select();
      }

      else if (input.setSelectionRange) {
        input.setSelectionRange(pos, pos);
      }
    }
  };
})();
<commit_msg>Add bind to utils.<commit_after>var utils = (function() {
  var nativeForEach = Array.prototype.forEach
    , nativeMap = Array.prototype.map
    , nativeBind = Function.prototype.bind
    , slice = Array.prototype.slice
    , breaker = {}
    , Ctor = function() {};

  return {
    // common utilities
    // ----------------

    isString: function(obj) {
      return typeof obj === 'string';
    }

  , isArray: function(obj) {
      Object.prototype.toString.call(obj) === '[object Array]';
    }

    // stolen from underscore
  , each: function(obj, iterator, context) {
      if (!obj)  { return; }

      // native
      if (nativeForEach && obj.forEach === nativeForEach) {
        obj.forEach(iterator, context);
      }

      // non-native array
      else if (obj.length === +obj.length) {
        for (var i = 0, l = obj.length; i < l; i++) {
          if (iterator.call(context, obj[i], i, obj) === breaker) {
            return;
          }
        }
      }

      // non-native object
      else {
        for (var key in obj) {
          if (obj.hasOwnProperty(key)) {
            if (iterator.call(context, obj[key], key, obj) === breaker) {
              return;
            }
          }
        }
      }
    }

    // stolen from underscore
  , map: function(obj, iterator, context) {
      var results = [];

      if (!obj) { return results; }

      // native
      if (nativeMap && obj.map === nativeMap) {
        return obj.map(iterator, context);
      }

      // non-native
      utils.each(obj, function(value, index, list) {
        results[results.length] = iterator.call(context, value, index, list);
      });

      return results;
    }

    // stolen from underscore
  , bind: function(func, context) {
      var that, args, bound, result;

      if (func.bind === nativeBind && nativeBind) {
        return nativeBind.apply(func, slice.call(arguments, 1));
      }

      if (!_.isFunction(func)) {
        throw new TypeError();
      }

      args = slice.call(arguments, 2);

      return bound = function() {
        if (!this instanceof bound) {
          return func.apply(context, args.concat(slice.call(arguments)));
        }

        ctor.prototype = func.prototype;
        that = new Ctor();
        ctor.prototype = null;

        result = func.apply(self, args.concat(slice.call(arguments)));

        return Object(result) === result ? result : that;
      };
    }

  , merge: function(array) {
      return [].concat.apply([], array);
    }

  , mixin: function(target) {
      var args = [].slice.call(arguments, 1), source;

      while (source = args.shift()) {
        for (var k in source) {
          source.hasOwnProperty(k) && (target[k] = source[k]);
        }
      }

      return target;
    }

    // ghostwriter specific utilities
    // ------------------------------

  , isRepeatified: function(obj) {
      return '_repeatified_' in obj;
    }

  , repeatify: function(strokes) {
      var repeatifiedStrokes = {};

      utils.each(strokes, function(val, key) {
        repeatifiedStrokes[key] = function repeat(times) {
          var strokes = [];
          while (times--) { strokes.push(val); }

          return strokes;
        };

        repeatifiedStrokes[key]._repeatified_ = true;
      });

      return repeatifiedStrokes;
    }

    // stroke helpers
    // --------------

  , getKeyEvent: function(type, key) {
      var event = $.Event(type);

      event.which = event.keyCode = utils.isString(key) ?
        key.charCodeAt(0) : key;

      return event;
    }

  , getCursorPos: function($input) {
      var selectionStart = $input[0].selectionStart;

      if (selectionStart) {
       return selectionStart;
      }

      else if (document.selection) {
        $input.focus();

        var range = document.selection.createRange();
        range.moveStart('character', -valueLength);

        return range.text.length;
      }
    }

  , setCursorPos: function($input, pos) {
      var input = $input[0]
        , textRange;

      if (input.createTextRange) {
        textRange = input.createTextRange();
        textRange.collapse(true);
        textRange.moveEnd(pos);
        textRange.moveStart(pos);
        textRange.select();
      }

      else if (input.setSelectionRange) {
        input.setSelectionRange(pos, pos);
      }
    }
  };
})();
<|endoftext|>


<commit_before>/**
 *  class models.users.TokenActivationEmail
 *
 *  Expirable secret key used for email address confirmation by newly
 *  registered users.
 **/

'use strict';

var Mongoose = require('mongoose');
var Schema   = Mongoose.Schema;
var crypto   = require('crypto');

var TOKEN_EXPIRE_TIMEOUT    = 6 * 60 * 60 * 1000; // 6 hours in msecs.
var TOKEN_SECRET_KEY_LENGTH = 16;

function generateSecretKey() {
  return crypto.randomBytes(TOKEN_SECRET_KEY_LENGTH).toString('hex');
}

module.exports = function (N, collectionName) {
  var TokenActivationEmail = new Schema({
    secret_key : { type: String, required: true, 'default': generateSecretKey                   }
  , create_ts  : { type: Date,   required: true, 'default': Date, expires: TOKEN_EXPIRE_TIMEOUT }
  , email      : { type: String, required: true                                                 }
  });

  TokenActivationEmail.methods.isExpired = function isExpired() {
    return Date.now() >= (this.create_ts.getTime() + TOKEN_EXPIRE_TIMEOUT);
  };

  TokenActivationEmail.index({ secret_key: 1 }, { unique: true });

  N.wire.on("init:models", function emit_init_TokenActivationEmail(__, callback) {
    N.wire.emit("init:models." + collectionName, TokenActivationEmail, callback);
  });

  N.wire.on("init:models." + collectionName, function init_model_TokenActivationEmail(schema) {
    N.models[collectionName] = Mongoose.model(collectionName, schema);
  });
};
<commit_msg>Correct TokenActivationEmail indexes.<commit_after>/**
 *  class models.users.TokenActivationEmail
 *
 *  Expirable secret key used for email address confirmation by newly
 *  registered users.
 **/

'use strict';

var Mongoose = require('mongoose');
var Schema   = Mongoose.Schema;
var crypto   = require('crypto');

var TOKEN_EXPIRE_TIMEOUT    = 6 * 60 * 60 * 1000; // 6 hours in msecs.
var TOKEN_SECRET_KEY_LENGTH = 16;

function generateSecretKey() {
  return crypto.randomBytes(TOKEN_SECRET_KEY_LENGTH).toString('hex');
}

module.exports = function (N, collectionName) {
  var TokenActivationEmail = new Schema({
    secret_key : { type: String, required: true, 'default': generateSecretKey                   }
  , create_ts  : { type: Date,   required: true, 'default': Date, expires: TOKEN_EXPIRE_TIMEOUT }
  , email      : { type: String, required: true                                                 }
  });

  TokenActivationEmail.methods.isExpired = function isExpired() {
    return Date.now() >= (this.create_ts.getTime() + TOKEN_EXPIRE_TIMEOUT);
  };

  TokenActivationEmail.index({ secret_key: 1 });
  TokenActivationEmail.index({ email: 1 });

  N.wire.on("init:models", function emit_init_TokenActivationEmail(__, callback) {
    N.wire.emit("init:models." + collectionName, TokenActivationEmail, callback);
  });

  N.wire.on("init:models." + collectionName, function init_model_TokenActivationEmail(schema) {
    N.models[collectionName] = Mongoose.model(collectionName, schema);
  });
};
<|endoftext|>


<commit_before>var webpack = require("webpack");
var ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = [
    {
        name: "browser",
        entry: {
            main: './client/src/main.js'
        },
        output: {
            path: './server/src/main/resources/public/resources',
            filename: 'bundle.js'
        },
        module: {
            loaders: [
                { test: /\.(js|jsx)$/, exclude: /node_modules/, loader: 'babel',
                    query: {
                        cacheDirectory: true,
                        presets: ['react', 'es2015', 'stage-0'],
                        plugins: ['transform-runtime', 'add-module-exports']
                    }
                },
                { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") },
                { test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)([\?]?.*)$/, loader: 'url-loader' }
            ]
        },
        plugins: [
            new ExtractTextPlugin("styles.css"),
            new webpack.optimize.OccurenceOrderPlugin(),
            new webpack.optimize.DedupePlugin(),
            new webpack.optimize.UglifyJsPlugin({
                compress: {
                    warnings: false
                }
            }),
            new webpack.DefinePlugin({
                "process.env": {
                    NODE_ENV: JSON.stringify("production")
                }
            })
        ],
        externals: {
            "jquery": "jQuery"
        }
    }
];

<commit_msg>webpack config fix<commit_after>var webpack = require("webpack");
var ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = [
    {
        name: "browser",
        entry: {
            main: './client/src/main.js'
        },
        output: {
            path: './server/src/main/resources/public/resources',
            filename: 'bundle.js'
        },
        module: {
            loaders: [
                { test: /\.(js|jsx)$/, exclude: /node_modules/, loader: 'babel',
                    query: {
                        cacheDirectory: true,
                        presets: ['react', 'es2015', 'stage-0'],
                        plugins: ['transform-runtime', 'add-module-exports']
                    }
                },
                { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") },
                { test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)([\?]?.*)$/, loader: 'url-loader' }
            ]
        },
        plugins: [
            new ExtractTextPlugin("styles.css"),
            new webpack.optimize.OccurenceOrderPlugin(),
            new webpack.optimize.DedupePlugin(),
            new webpack.optimize.UglifyJsPlugin({
                compress: {
                    warnings: false
                }
            }),
            new webpack.DefinePlugin({
                "process.env": {
                    NODE_ENV: JSON.stringify("production")
                }
            })
        ],
        externals: {
            "jquery": "jQuery"
        }
    }
];
<|endoftext|>


<commit_before>/*
Copyright 2015, 2016 OpenMarket Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

var React = require("react");
var classNames = require('classnames');
var sdk = require("../../../index");
var Invite = require("../../../Invite");
var createRoom = require("../../../createRoom");
var MatrixClientPeg = require("../../../MatrixClientPeg");
var DMRoomMap = require('../../../utils/DMRoomMap');
var rate_limited_func = require("../../../ratelimitedfunc");
var dis = require("../../../dispatcher");
var Modal = require('../../../Modal');

const TRUNCATE_QUERY_LIST = 40;

module.exports = React.createClass({
    displayName: "ChatInviteDialog",
    propTypes: {
        title: React.PropTypes.string,
        description: React.PropTypes.oneOfType([
            React.PropTypes.element,
            React.PropTypes.string,
        ]),
        value: React.PropTypes.string,
        placeholder: React.PropTypes.string,
        roomId: React.PropTypes.string,
        button: React.PropTypes.string,
        focus: React.PropTypes.bool,
        onFinished: React.PropTypes.func.isRequired
    },

    getDefaultProps: function() {
        return {
            title: "Start a chat",
            description: "Who would you like to communicate with?",
            value: "",
            placeholder: "User ID, Name or email",
            button: "Start Chat",
            focus: true
        };
    },

    getInitialState: function() {
        return {
            error: false,
            inviteList: [],
            queryList: [],
        };
    },

    componentDidMount: function() {
        if (this.props.focus) {
            // Set the cursor at the end of the text input
            this.refs.textinput.value = this.props.value;
        }
        this._updateUserList();
    },

    onButtonClick: function() {
        var inviteList = this.state.inviteList.slice();
        // Check the text input field to see if user has an unconverted address
        // If there is and it's valid add it to the local inviteList
        var check = Invite.isValidAddress(this.refs.textinput.value);
        if (check === true || check === null) {
            inviteList.push(this.refs.textinput.value);
        } else if (this.refs.textinput.value.length > 0) {
            this.setState({ error: true });
            return;
        }

        if (inviteList.length > 0) {
            if (this._isDmChat(inviteList)) {
                // Direct Message chat
                var room = this._getDirectMessageRoom(inviteList[0]);
                if (room) {
                    // A Direct Message room already exists for this user and you
                    // so go straight to that room
                    dis.dispatch({
                        action: 'view_room',
                        room_id: room.roomId,
                    });
                    this.props.onFinished(true, inviteList[0]);
                } else {
                    this._startChat(inviteList);
                }
            } else {
                // Multi invite chat
                this._startChat(inviteList);
            }
        } else {
            // No addresses supplied
            this.setState({ error: true });
        }
    },

    onCancel: function() {
        this.props.onFinished(false);
    },

    onKeyDown: function(e) {
        if (e.keyCode === 27) { // escape
            e.stopPropagation();
            e.preventDefault();
            this.props.onFinished(false);
        } else if (e.keyCode === 38) { // up arrow
            e.stopPropagation();
            e.preventDefault();
            this.addressSelector.onKeyUp();
        } else if (e.keyCode === 40) { // down arrow
            e.stopPropagation();
            e.preventDefault();
            this.addressSelector.onKeyDown();
        } else if (this.state.queryList.length > 0 && (e.keyCode === 188, e.keyCode === 13 || e.keyCode === 9)) { // comma or enter or tab
            e.stopPropagation();
            e.preventDefault();
            this.addressSelector.onKeySelect();
        } else if (this.refs.textinput.value.length === 0 && this.state.inviteList.length && e.keyCode === 8) { // backspace
            e.stopPropagation();
            e.preventDefault();
            this.onDismissed(this.state.inviteList.length - 1)();
        } else if (e.keyCode === 13) { // enter
            e.stopPropagation();
            e.preventDefault();
            this.onButtonClick();
        } else if (e.keyCode === 188 || e.keyCode === 9) { // comma or tab
            e.stopPropagation();
            e.preventDefault();
            var check = Invite.isValidAddress(this.refs.textinput.value);
            if (check === true || check === null) {
                var inviteList = this.state.inviteList.slice();
                inviteList.push(this.refs.textinput.value);
                this.setState({
                    inviteList: inviteList,
                    queryList: [],
                });
            } else {
                this.setState({ error: true });
            }
        }
    },

    onQueryChanged: function(ev) {
        var query = ev.target.value;
        var queryList = [];

        // Only do search if there is something to search
        if (query.length > 0) {
            queryList = this._userList.filter((user) => {
                return this._matches(query, user);
            });
        }

        this.setState({
            queryList: queryList,
            error: false,
        });
    },

    onDismissed: function(index) {
        var self = this;
        return function() {
            var inviteList = self.state.inviteList.slice();
            inviteList.splice(index, 1);
            self.setState({
                inviteList: inviteList,
                queryList: [],
            });
        }
    },

    onClick: function(index) {
        var self = this;
        return function() {
            self.onSelected(index);
        };
    },

    onSelected: function(index) {
        var inviteList = this.state.inviteList.slice();
        inviteList.push(this.state.queryList[index].userId);
        this.setState({
            inviteList: inviteList,
            queryList: [],
        });
    },

    _getDirectMessageRoom: function(addr) {
        const dmRoomMap = new DMRoomMap(MatrixClientPeg.get());
        var dmRooms = dmRoomMap.getDMRoomsForUserId(addr);
        if (dmRooms.length > 0) {
            // Cycle through all the DM rooms and find the first non forgotten or parted room
            for (let i = 0; i < dmRooms.length; i++) {
                let room = MatrixClientPeg.get().getRoom(dmRooms[i]);
                if (room) {
                    const me = room.getMember(MatrixClientPeg.get().credentials.userId);
                    if (me.membership == 'join') {
                        return room;
                    }
                }
            }
        }
        return null;
    },

    _startChat: function(addrs) {
        if (MatrixClientPeg.get().isGuest()) {
            var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
            Modal.createDialog(NeedToRegisterDialog, {
                title: "Please Register",
                description: "Guest users can't invite users. Please register."
            });
            return;
        }

        if (this.props.roomId) {
            // Invite new user to a room
            var self = this;
            Invite.inviteMultipleToRoom(this.props.roomId, addrs)
            .then(function(addrs) {
                var room = MatrixClientPeg.get().getRoom(self.props.roomId);
                return self._showAnyInviteErrors(addrs, room);
            })
            .catch(function(err) {
                console.error(err.stack);
                var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
                Modal.createDialog(ErrorDialog, {
                    title: "Failure to invite",
                    description: err.toString()
                });
                return null;
            })
            .done();
        } else if (this._isDmChat(addrs)) {
            // Start the DM chat
            createRoom({dmUserId: addrs[0]})
            .catch(function(err) {
                console.error(err.stack);
                var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
                Modal.createDialog(ErrorDialog, {
                    title: "Failure to invite user",
                    description: err.toString()
                });
                return null;
            })
            .done();
        } else {
            // Start multi user chat
            var self = this;
            var room;
            createRoom().then(function(roomId) {
                room = MatrixClientPeg.get().getRoom(roomId);
                return Invite.inviteMultipleToRoom(roomId, addrs);
            })
            .then(function(addrs) {
                return self._showAnyInviteErrors(addrs, room);
            })
            .catch(function(err) {
                console.error(err.stack);
                var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
                Modal.createDialog(ErrorDialog, {
                    title: "Failure to invite",
                    description: err.toString()
                });
                return null;
            })
            .done();
        }

        // Close - this will happen before the above, as that is async
        this.props.onFinished(true, addrs);
    },

    _updateUserList: new rate_limited_func(function() {
        // Get all the users
        this._userList = MatrixClientPeg.get().getUsers();
    }, 500),

    // This is the search algorithm for matching users
    _matches: function(query, user) {
        var name = user.displayName.toLowerCase();
        var uid = user.userId.toLowerCase();
        query = query.toLowerCase();

        // don't match any that are already on the invite list
        if (this._isOnInviteList(uid)) {
            return false;
        }

        // ignore current user
        if (uid === MatrixClientPeg.get().credentials.userId) {
            return false;
        }

        // direct prefix matches
        if (name.indexOf(query) === 0 || uid.indexOf(query) === 0) {
            return true;
        }

        // strip @ on uid and try matching again
        if (uid.length > 1 && uid[0] === "@" && uid.substring(1).indexOf(query) === 0) {
            return true;
        }

        // split spaces in name and try matching constituent parts
        var parts = name.split(" ");
        for (var i = 0; i < parts.length; i++) {
            if (parts[i].indexOf(query) === 0) {
                return true;
            }
        }
        return false;
    },

    _isOnInviteList: function(uid) {
        for (let i = 0; i < this.state.inviteList.length; i++) {
            if (this.state.inviteList[i].toLowerCase() === uid) {
                return true;
            }
        }
        return false;
    },

    _isDmChat: function(addrs) {
        if (addrs.length === 1 && Invite.getAddressType(addrs[0]) === "mx" && !this.props.roomId) {
            return true;
        } else {
            return false;
        }
    },

    _showAnyInviteErrors: function(addrs, room) {
        // Show user any errors
        var errorList = [];
        for (var addr in addrs) {
            if (addrs.hasOwnProperty(addr) && addrs[addr] === "error") {
                errorList.push(addr);
            }
        }

        if (errorList.length > 0) {
            var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
            Modal.createDialog(ErrorDialog, {
                title: "Failed to invite the following users to the " + room.name + " room:",
                description: errorList.join(", "),
            });
        }
        return addrs;
    },

    render: function() {
        var TintableSvg = sdk.getComponent("elements.TintableSvg");
        var AddressSelector = sdk.getComponent("elements.AddressSelector");
        this.scrollElement = null;

        var query = [];
        // create the invite list
        if (this.state.inviteList.length > 0) {
            var AddressTile = sdk.getComponent("elements.AddressTile");
            for (let i = 0; i < this.state.inviteList.length; i++) {
                query.push(
                    <AddressTile key={i} address={this.state.inviteList[i]} canDismiss={true} onDismissed={ this.onDismissed(i) } />
                );
            }
        }

        // Add the query at the end
        query.push(
            <textarea key={this.state.inviteList.length}
                rows="1"
                id="textinput"
                ref="textinput"
                className="mx_ChatInviteDialog_input"
                onChange={this.onQueryChanged}
                placeholder={this.props.placeholder}
                defaultValue={this.props.value}
                autoFocus={this.props.focus}>
            </textarea>
        );

        var error;
        var addressSelector;
        if (this.state.error) {
            error =
You have entered an invalid contact. Try using their Matrix ID or email address.

        } else {
            addressSelector = (
                <AddressSelector ref={(ref) => {this.addressSelector = ref}}
                    addressList={ this.state.queryList }
                    onSelected={ this.onSelected }
                    truncateAt={ TRUNCATE_QUERY_LIST } />
            );
        }

        return (

                    {this.props.title}

                    <TintableSvg src="img/icons-close-button.svg" width="35" height="35" />

                    { this.props.description }

{ query }

                    { error }
                    { addressSelector }

                    <button className="mx_Dialog_primary" onClick={this.onButtonClick}>
                        {this.props.button}
                    </button>

        );
    }
});
<commit_msg>trim whitespace when adding to list<commit_after>/*
Copyright 2015, 2016 OpenMarket Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

var React = require("react");
var classNames = require('classnames');
var sdk = require("../../../index");
var Invite = require("../../../Invite");
var createRoom = require("../../../createRoom");
var MatrixClientPeg = require("../../../MatrixClientPeg");
var DMRoomMap = require('../../../utils/DMRoomMap');
var rate_limited_func = require("../../../ratelimitedfunc");
var dis = require("../../../dispatcher");
var Modal = require('../../../Modal');

const TRUNCATE_QUERY_LIST = 40;

module.exports = React.createClass({
    displayName: "ChatInviteDialog",
    propTypes: {
        title: React.PropTypes.string,
        description: React.PropTypes.oneOfType([
            React.PropTypes.element,
            React.PropTypes.string,
        ]),
        value: React.PropTypes.string,
        placeholder: React.PropTypes.string,
        roomId: React.PropTypes.string,
        button: React.PropTypes.string,
        focus: React.PropTypes.bool,
        onFinished: React.PropTypes.func.isRequired
    },

    getDefaultProps: function() {
        return {
            title: "Start a chat",
            description: "Who would you like to communicate with?",
            value: "",
            placeholder: "User ID, Name or email",
            button: "Start Chat",
            focus: true
        };
    },

    getInitialState: function() {
        return {
            error: false,
            inviteList: [],
            queryList: [],
        };
    },

    componentDidMount: function() {
        if (this.props.focus) {
            // Set the cursor at the end of the text input
            this.refs.textinput.value = this.props.value;
        }
        this._updateUserList();
    },

    onButtonClick: function() {
        var inviteList = this.state.inviteList.slice();
        // Check the text input field to see if user has an unconverted address
        // If there is and it's valid add it to the local inviteList
        var check = Invite.isValidAddress(this.refs.textinput.value);
        if (check === true || check === null) {
            inviteList.push(this.refs.textinput.value);
        } else if (this.refs.textinput.value.length > 0) {
            this.setState({ error: true });
            return;
        }

        if (inviteList.length > 0) {
            if (this._isDmChat(inviteList)) {
                // Direct Message chat
                var room = this._getDirectMessageRoom(inviteList[0]);
                if (room) {
                    // A Direct Message room already exists for this user and you
                    // so go straight to that room
                    dis.dispatch({
                        action: 'view_room',
                        room_id: room.roomId,
                    });
                    this.props.onFinished(true, inviteList[0]);
                } else {
                    this._startChat(inviteList);
                }
            } else {
                // Multi invite chat
                this._startChat(inviteList);
            }
        } else {
            // No addresses supplied
            this.setState({ error: true });
        }
    },

    onCancel: function() {
        this.props.onFinished(false);
    },

    onKeyDown: function(e) {
        if (e.keyCode === 27) { // escape
            e.stopPropagation();
            e.preventDefault();
            this.props.onFinished(false);
        } else if (e.keyCode === 38) { // up arrow
            e.stopPropagation();
            e.preventDefault();
            this.addressSelector.onKeyUp();
        } else if (e.keyCode === 40) { // down arrow
            e.stopPropagation();
            e.preventDefault();
            this.addressSelector.onKeyDown();
        } else if (this.state.queryList.length > 0 && (e.keyCode === 188, e.keyCode === 13 || e.keyCode === 9)) { // comma or enter or tab
            e.stopPropagation();
            e.preventDefault();
            this.addressSelector.onKeySelect();
        } else if (this.refs.textinput.value.length === 0 && this.state.inviteList.length && e.keyCode === 8) { // backspace
            e.stopPropagation();
            e.preventDefault();
            this.onDismissed(this.state.inviteList.length - 1)();
        } else if (e.keyCode === 13) { // enter
            e.stopPropagation();
            e.preventDefault();
            this.onButtonClick();
        } else if (e.keyCode === 188 || e.keyCode === 9) { // comma or tab
            e.stopPropagation();
            e.preventDefault();
            var check = Invite.isValidAddress(this.refs.textinput.value);
            if (check === true || check === null) {
                var inviteList = this.state.inviteList.slice();
                inviteList.push(this.refs.textinput.value.trim());
                this.setState({
                    inviteList: inviteList,
                    queryList: [],
                });
            } else {
                this.setState({ error: true });
            }
        }
    },

    onQueryChanged: function(ev) {
        var query = ev.target.value;
        var queryList = [];

        // Only do search if there is something to search
        if (query.length > 0) {
            queryList = this._userList.filter((user) => {
                return this._matches(query, user);
            });
        }

        this.setState({
            queryList: queryList,
            error: false,
        });
    },

    onDismissed: function(index) {
        var self = this;
        return function() {
            var inviteList = self.state.inviteList.slice();
            inviteList.splice(index, 1);
            self.setState({
                inviteList: inviteList,
                queryList: [],
            });
        }
    },

    onClick: function(index) {
        var self = this;
        return function() {
            self.onSelected(index);
        };
    },

    onSelected: function(index) {
        var inviteList = this.state.inviteList.slice();
        inviteList.push(this.state.queryList[index].userId);
        this.setState({
            inviteList: inviteList,
            queryList: [],
        });
    },

    _getDirectMessageRoom: function(addr) {
        const dmRoomMap = new DMRoomMap(MatrixClientPeg.get());
        var dmRooms = dmRoomMap.getDMRoomsForUserId(addr);
        if (dmRooms.length > 0) {
            // Cycle through all the DM rooms and find the first non forgotten or parted room
            for (let i = 0; i < dmRooms.length; i++) {
                let room = MatrixClientPeg.get().getRoom(dmRooms[i]);
                if (room) {
                    const me = room.getMember(MatrixClientPeg.get().credentials.userId);
                    if (me.membership == 'join') {
                        return room;
                    }
                }
            }
        }
        return null;
    },

    _startChat: function(addrs) {
        if (MatrixClientPeg.get().isGuest()) {
            var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
            Modal.createDialog(NeedToRegisterDialog, {
                title: "Please Register",
                description: "Guest users can't invite users. Please register."
            });
            return;
        }

        if (this.props.roomId) {
            // Invite new user to a room
            var self = this;
            Invite.inviteMultipleToRoom(this.props.roomId, addrs)
            .then(function(addrs) {
                var room = MatrixClientPeg.get().getRoom(self.props.roomId);
                return self._showAnyInviteErrors(addrs, room);
            })
            .catch(function(err) {
                console.error(err.stack);
                var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
                Modal.createDialog(ErrorDialog, {
                    title: "Failure to invite",
                    description: err.toString()
                });
                return null;
            })
            .done();
        } else if (this._isDmChat(addrs)) {
            // Start the DM chat
            createRoom({dmUserId: addrs[0]})
            .catch(function(err) {
                console.error(err.stack);
                var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
                Modal.createDialog(ErrorDialog, {
                    title: "Failure to invite user",
                    description: err.toString()
                });
                return null;
            })
            .done();
        } else {
            // Start multi user chat
            var self = this;
            var room;
            createRoom().then(function(roomId) {
                room = MatrixClientPeg.get().getRoom(roomId);
                return Invite.inviteMultipleToRoom(roomId, addrs);
            })
            .then(function(addrs) {
                return self._showAnyInviteErrors(addrs, room);
            })
            .catch(function(err) {
                console.error(err.stack);
                var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
                Modal.createDialog(ErrorDialog, {
                    title: "Failure to invite",
                    description: err.toString()
                });
                return null;
            })
            .done();
        }

        // Close - this will happen before the above, as that is async
        this.props.onFinished(true, addrs);
    },

    _updateUserList: new rate_limited_func(function() {
        // Get all the users
        this._userList = MatrixClientPeg.get().getUsers();
    }, 500),

    // This is the search algorithm for matching users
    _matches: function(query, user) {
        var name = user.displayName.toLowerCase();
        var uid = user.userId.toLowerCase();
        query = query.toLowerCase();

        // don't match any that are already on the invite list
        if (this._isOnInviteList(uid)) {
            return false;
        }

        // ignore current user
        if (uid === MatrixClientPeg.get().credentials.userId) {
            return false;
        }

        // direct prefix matches
        if (name.indexOf(query) === 0 || uid.indexOf(query) === 0) {
            return true;
        }

        // strip @ on uid and try matching again
        if (uid.length > 1 && uid[0] === "@" && uid.substring(1).indexOf(query) === 0) {
            return true;
        }

        // split spaces in name and try matching constituent parts
        var parts = name.split(" ");
        for (var i = 0; i < parts.length; i++) {
            if (parts[i].indexOf(query) === 0) {
                return true;
            }
        }
        return false;
    },

    _isOnInviteList: function(uid) {
        for (let i = 0; i < this.state.inviteList.length; i++) {
            if (this.state.inviteList[i].toLowerCase() === uid) {
                return true;
            }
        }
        return false;
    },

    _isDmChat: function(addrs) {
        if (addrs.length === 1 && Invite.getAddressType(addrs[0]) === "mx" && !this.props.roomId) {
            return true;
        } else {
            return false;
        }
    },

    _showAnyInviteErrors: function(addrs, room) {
        // Show user any errors
        var errorList = [];
        for (var addr in addrs) {
            if (addrs.hasOwnProperty(addr) && addrs[addr] === "error") {
                errorList.push(addr);
            }
        }

        if (errorList.length > 0) {
            var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
            Modal.createDialog(ErrorDialog, {
                title: "Failed to invite the following users to the " + room.name + " room:",
                description: errorList.join(", "),
            });
        }
        return addrs;
    },

    render: function() {
        var TintableSvg = sdk.getComponent("elements.TintableSvg");
        var AddressSelector = sdk.getComponent("elements.AddressSelector");
        this.scrollElement = null;

        var query = [];
        // create the invite list
        if (this.state.inviteList.length > 0) {
            var AddressTile = sdk.getComponent("elements.AddressTile");
            for (let i = 0; i < this.state.inviteList.length; i++) {
                query.push(
                    <AddressTile key={i} address={this.state.inviteList[i]} canDismiss={true} onDismissed={ this.onDismissed(i) } />
                );
            }
        }

        // Add the query at the end
        query.push(
            <textarea key={this.state.inviteList.length}
                rows="1"
                id="textinput"
                ref="textinput"
                className="mx_ChatInviteDialog_input"
                onChange={this.onQueryChanged}
                placeholder={this.props.placeholder}
                defaultValue={this.props.value}
                autoFocus={this.props.focus}>
            </textarea>
        );

        var error;
        var addressSelector;
        if (this.state.error) {
            error =
You have entered an invalid contact. Try using their Matrix ID or email address.

        } else {
            addressSelector = (
                <AddressSelector ref={(ref) => {this.addressSelector = ref}}
                    addressList={ this.state.queryList }
                    onSelected={ this.onSelected }
                    truncateAt={ TRUNCATE_QUERY_LIST } />
            );
        }

        return (

                    {this.props.title}

                    <TintableSvg src="img/icons-close-button.svg" width="35" height="35" />

                    { this.props.description }

{ query }

                    { error }
                    { addressSelector }

                    <button className="mx_Dialog_primary" onClick={this.onButtonClick}>
                        {this.props.button}
                    </button>

        );
    }
});
<|endoftext|>


<commit_before>/**
 * @file IdPMetadata.js
 * @author Tony Ngan
 * @desc  Metadata of identity provider
 */
var Metadata = require('./Metadata'),
namespace = require('./urn').namespace,
SamlLib = require('./SamlLib'),
xml = require('xml');
/**
* @param  {object/string} meta (either file path in string format or configuation in object)
* @return {object} prototype including public functions
*/
module.exports = function(meta){
    var byMetadata = typeof meta === 'string';
    if(!byMetadata){
        var entityID = meta.entityID,
        wantAuthnRequestsSigned = meta.wantAuthnRequestsSigned === true,
        signingCertFile = meta.signingCertFile,
        encryptCertFile = meta.encryptCertFile,
        nameIDFormat = meta.nameIDFormat || [],
        singleSignOnService = meta.singleSignOnService || [];
        singleLogoutService = meta.singleLogoutService || [];

        var IDPSSODescriptor = [{_attr:{
            WantAuthnRequestsSigned:wantAuthnRequestsSigned.toString(),
            protocolSupportEnumeration: namespace.names.protocol
        }}];

        if(signingCertFile){
            IDPSSODescriptor.push(SamlLib.createKeySection('signing',signingCertFile));
        } else {
            console.warn('Construct identity provider - missing signing certificate');
        }

        if(encryptCertFile){
            IDPSSODescriptor.push(SamlLib.createKeySection('encrypt',encryptCertFile));
        } else {
            console.warn('Construct identity provider - missing encrypt certificate');
        }

        if(nameIDFormat && nameIDFormat.length > 0){
            nameIDFormat.forEach(function(f){
                IDPSSODescriptor.push({
                    NameIDFormat: f
                });
            });
        }

        if(singleSignOnService && singleSignOnService.length > 0){
            singleSignOnService.forEach(function(a){
                var _attr = {},
                _indexCount = 0;
                if(a.isDefault){
                    _attr.isDefault = true;
                }
                _attr.index = (_indexCount++).toString();
                _attr.Binding = a.Binding;
                _attr.Location = a.Location;
                IDPSSODescriptor.push({SingleSignOnService: [{_attr: _attr}]});
            });
        } else {
            throw new Error('Missing endpoint of SingleSignOnService');
        }

        if(singleLogoutService && singleLogoutService.length > 0){
            singleLogoutService.forEach(function(a){
                var _attr = {},
                _indexCount = 0;
                if(a.isDefault){
                    _attr.isDefault = true;
                }
                _attr.index = (_indexCount++).toString();
                _attr.Binding = a.Binding;
                _attr.Location = a.Location;
                IDPSSODescriptor.push({SingleLogoutService: [{_attr: _attr}]});
            });
        } else {
            console.warn('Construct identity  provider - missing endpoint of SingleLogoutService');
        }
        // Create a new metadata by setting
        meta = xml([{'EntityDescriptor':[{_attr:{
            'xmlns:md': namespace.names.metadata,
            'xmlns:assertion': namespace.names.assertion,
            'xmlns:ds':'http://www.w3.org/2000/09/xmldsig#',
            entityID: entityID
        }},{IDPSSODescriptor: IDPSSODescriptor}]}]);
    }
    /**
    * @desc IdP Metadata is for creating Identity Provider, provides a set of API to manage the actions in IdP.
    */
    function IdPMetadata(){}
    /**
    * @desc  Initialize with creating a new metadata object
    * @param {string/objects} meta      declares path of the metadata
    * @param {array of Objects}         high-level XML element selector
    */
    IdPMetadata.prototype = new Metadata(meta,[{
        localName: 'IDPSSODescriptor',
        attributes: ['WantAuthnRequestsSigned']
    },{
        localName: {tag: 'SingleSignOnService', key: 'Binding'},
        attributeTag: 'Location'
    }], !byMetadata);
    /**
    * @desc Get the preference whether it wants a signed request
    * @return {boolean} WantAuthnRequestsSigned
    */
    IdPMetadata.prototype.isWantAuthnRequestsSigned = function isWantAuthnRequestsSigned(){
        var was = this.meta.idpssodescriptor.wantauthnrequestssigned;
        return was && was.toString() === 'true';
    };
    /**
    * @desc Get the entity endpoint for single sign on service
    * @param  {string} binding      protocol binding (e.g. redirect, post)
    * @return {string/object} location
    */
    IdPMetadata.prototype.getSingleSignOnService = function getSingleSignOnService(binding){
        if(typeof binding === 'string'){
            var _location,
            _binding = namespace.binding[binding];
            this.meta.singlesignonservice.forEach(function(obj){
                if(obj[_binding]) {
                    _location = obj[_binding];
                    return;
                }
            });
            return _location;
        } else {
            return this.meta.singlesignonservice;
        }
    };
    /**
    * @desc return the prototype
    */
    return IdPMetadata.prototype;
};
<commit_msg>Bug fixed for undefined IdP configuration (wantAuthnRequestsSigned)<commit_after>/**
 * @file IdPMetadata.js
 * @author Tony Ngan
 * @desc  Metadata of identity provider
 */
var Metadata = require('./Metadata'),
namespace = require('./urn').namespace,
SamlLib = require('./SamlLib'),
xml = require('xml');
/**
* @param  {object/string} meta (either file path in string format or configuation in object)
* @return {object} prototype including public functions
*/
module.exports = function(meta){
    var byMetadata = typeof meta === 'string';
    if(!byMetadata){
        var entityID = meta.entityID,
        wantAuthnRequestsSigned = meta.wantAuthnRequestsSigned === true,
        signingCertFile = meta.signingCertFile,
        encryptCertFile = meta.encryptCertFile,
        nameIDFormat = meta.nameIDFormat || [],
        singleSignOnService = meta.singleSignOnService || [];
        singleLogoutService = meta.singleLogoutService || [];

        var IDPSSODescriptor = [{_attr:{
            WantAuthnRequestsSigned:wantAuthnRequestsSigned.toString(),
            protocolSupportEnumeration: namespace.names.protocol
        }}];

        if(signingCertFile){
            IDPSSODescriptor.push(SamlLib.createKeySection('signing',signingCertFile));
        } else {
            console.warn('Construct identity provider - missing signing certificate');
        }

        if(encryptCertFile){
            IDPSSODescriptor.push(SamlLib.createKeySection('encrypt',encryptCertFile));
        } else {
            console.warn('Construct identity provider - missing encrypt certificate');
        }

        if(nameIDFormat && nameIDFormat.length > 0){
            nameIDFormat.forEach(function(f){
                IDPSSODescriptor.push({
                    NameIDFormat: f
                });
            });
        }

        if(singleSignOnService && singleSignOnService.length > 0){
            singleSignOnService.forEach(function(a){
                var _attr = {},
                _indexCount = 0;
                if(a.isDefault){
                    _attr.isDefault = true;
                }
                _attr.index = (_indexCount++).toString();
                _attr.Binding = a.Binding;
                _attr.Location = a.Location;
                IDPSSODescriptor.push({SingleSignOnService: [{_attr: _attr}]});
            });
        } else {
            throw new Error('Missing endpoint of SingleSignOnService');
        }

        if(singleLogoutService && singleLogoutService.length > 0){
            singleLogoutService.forEach(function(a){
                var _attr = {},
                _indexCount = 0;
                if(a.isDefault){
                    _attr.isDefault = true;
                }
                _attr.index = (_indexCount++).toString();
                _attr.Binding = a.Binding;
                _attr.Location = a.Location;
                IDPSSODescriptor.push({SingleLogoutService: [{_attr: _attr}]});
            });
        } else {
            console.warn('Construct identity  provider - missing endpoint of SingleLogoutService');
        }
        // Create a new metadata by setting
        meta = xml([{'EntityDescriptor':[{_attr:{
            'xmlns:md': namespace.names.metadata,
            'xmlns:assertion': namespace.names.assertion,
            'xmlns:ds':'http://www.w3.org/2000/09/xmldsig#',
            entityID: entityID
        }},{IDPSSODescriptor: IDPSSODescriptor}]}]);
    }
    /**
    * @desc IdP Metadata is for creating Identity Provider, provides a set of API to manage the actions in IdP.
    */
    function IdPMetadata(){}
    /**
    * @desc  Initialize with creating a new metadata object
    * @param {string/objects} meta      declares path of the metadata
    * @param {array of Objects}         high-level XML element selector
    */
    IdPMetadata.prototype = new Metadata(meta,[{
        localName: 'IDPSSODescriptor',
        attributes: ['WantAuthnRequestsSigned']
    },{
        localName: {tag: 'SingleSignOnService', key: 'Binding'},
        attributeTag: 'Location'
    }], !byMetadata);
    /**
    * @desc Get the preference whether it wants a signed request
    * @return {boolean} WantAuthnRequestsSigned
    */
    IdPMetadata.prototype.isWantAuthnRequestsSigned = function isWantAuthnRequestsSigned(){
        var was = this.meta.idpssodescriptor.wantauthnrequestssigned;
        if(was === undefined) {
            return false;
        } else {
            return was.toString() === 'true';
        }
    };
    /**
    * @desc Get the entity endpoint for single sign on service
    * @param  {string} binding      protocol binding (e.g. redirect, post)
    * @return {string/object} location
    */
    IdPMetadata.prototype.getSingleSignOnService = function getSingleSignOnService(binding){
        if(typeof binding === 'string'){
            var _location,
            _binding = namespace.binding[binding];
            this.meta.singlesignonservice.forEach(function(obj){
                if(obj[_binding]) {
                    _location = obj[_binding];
                    return;
                }
            });
            return _location;
        } else {
            return this.meta.singlesignonservice;
        }
    };
    /**
    * @desc return the prototype
    */
    return IdPMetadata.prototype;
};
<|endoftext|>