<commit_before>fs.mkdirParent("data/logs/");
fs.mkdirParent('data/templates/');
if(!fs.exists('data/templates/chatlog.html')){
    var template = '\n\t\n\t\t<title>\n\t\t\t{Title}\n\t\t</title>\n\t\n\t\n\t\t{Item(\n\t\t\t\n\t\t\t\t{timestamp}\n\t\t\t\n\t\t\t{Text}\n\t\t\t
\n\t\t)}\n\t\t\n\t\n';
    fs.writeFile('data/templates/chatlog.html',template,function(err) {
        if(err) {
    		disp.error(err);
		}else{
			disp.log("No chat log template found. Creating default.");
		}
	});
}
var Settings = regSettings('logServer',{
    // Port to run the server on
	port: 9002,
	// How quickly to check if the port is in use
	check_interval: 1000,
	// how many times to check before failing to start
	check_timeout: 10
});
listen(/^.+/i,function(match,data,replyTo,connection){
	var nick,data2;
	if(replyTo===null){
		replyTo = "- server -";
	}else{
		try{
			nick = (/^:([^!]+)!.*PRIVMSG ([^ ]+) :(.+)$/i).exec(data)[1];
			data = (/^:([^!]+)!.*PRIVMSG ([^ ]+) :(.+)$/i).exec(data)[3];
			if(nick.toLowerCase() == 'omnomirc'){
				if((data2 = (/\([#O]\).?<(\w+)>(.+)$/).exec(data)) !== null){
					nick = data2[1];
					data = data2[2].trim();
				}else if((data2 = (/\([#O]\).? *(.+) has quit .+$/).exec(data)) != null){
					console.log(data2);

				}
			}
            replyTo = replyTo.trim().toLowerCase();
		}catch(e){
			disp.error(e)
			disp.log("Defaulting to '- server -' replyTo");
			replyTo = "- server -";
		}
	}
	var d = new Date();
	var p = connection.config.host+" "+connection.config.port+"/"+replyTo+"/"+d.toDateString();
	if(replyTo == "- server -" && (new RegExp("^:(.+) 372 "+connection.config.nick+" :(.+)$")).exec(data) === null){
		save(p,{
			msg: ">>>	"+data
		});
	}else if(data.indexOf("\x01ACTION ")!=-1){
		save(p,{
			msg: data.substr(data.indexOf("\x01ACTION ")+8,data.length-9),
			user: nick,
			type: 'action'
		});
	}else{
		save(p,{
			msg: data,
			user: nick
		});
	}
});
listen(/^:([^!]+).*PART ([^ ]+) :$/i,function(match,data,replyTo,connection){
	replyTo = match[2].substr(1).trim().toLowerCase();
	var d = new Date();
	save(connection.config.host+" "+connection.config.port+"/#"+replyTo+"/"+d.toDateString(),{
		user: match[1],
		type: 'part'
	});
});
listen(/^:([^!]+).*JOIN :([^ ]+)$/i,function(match,data,replyTo,connection){
	replyTo = match[2].substr(1).trim().toLowerCase();
	var d = new Date();
	save(connection.config.host+" "+connection.config.port+"/#"+replyTo+"/"+d.toDateString(),{
		type: 'join',
		user: match[1]
	});
});
reply_listen(function(replyTo,msg,connection){
	if(replyTo===null){
		replyTo = "- server -";
	}else{
		replyTo = replyTo.trim().toLowerCase();
	}
	var d = new Date();
	save(connection.config.host+" "+connection.config.port+"/#"+replyTo+"/"+d.toDateString(),{
		msg: msg,
		user: connection.config.nick
	});
});
send_listen(/^.+/i,function(match,msg,connection){
	var d = new Date();
	save(connection.config.host+" "+connection.config.port+"/- server -/"+d.toDateString(),{
		msg: "<<<	"+msg
	});
});
hook('quit',function(){
	var d = new Date();
	save(this.config.host+" "+this.config.port+"/- server -/"+d.toDateString(),{
		msg: "*Connection Quit*"
	});
});
hook('reconnect',function(){
	var d = new Date();
	save(this.config.host+" "+this.config.port+"/- server -/"+d.toDateString(),{
		msg: "*Reconnected*"
	});
});
hook('connect',function(){
	var d = new Date();
	save(this.config.host+" "+this.config.port+"/- server -/"+d.toDateString(),{
		msg: "*Connected*"
	});
});
hook('timeout',function(){
	var d = new Date();
	save(this.config.host+" "+this.config.port+"/- server -/"+d.toDateString(),{
		msg: "*Connection Timeout*"
	});
});
disp.alert("Starting Log Server");
function addZero(num){
	return (String(num).length < 2) ? num = String("0" + num) :  num = String(num);
}
function save(log,o){
	fs.mkdirParent('data/logs/'+path.dirname(log));
	var d = new Date(),n = {};
	if(typeof o.type === 'undefined'){
		n.type = 'privmsg';
	}else{
		n.type = o.type;
	}
	if(typeof o.user === 'undefined'){
		n.user = '- server -';
	}else{
		n.user = o.user;
	}
	if(typeof o.msg !== 'undefined'){
		n.msg = o.msg;
	}
	n.date = d.getTime()+d.getTimezoneOffset()*60*1000;
	switch(config.logtype){
		case 'listdb':
				var l = listdb.getDB('logs/'+log);
				l.add(JSON.stringify(n));
				break;
		case 'txt': default:
			switch(n.type){
				case 'part':
					n.msg = "* "+n.user+" has left the channel";
					break;
				case 'join':
					n.msg = "* "+n.user+" has joined the channel";
					break;
				case 'action':
					n.msg = "* "+n.user+" "+n.msg;
					break;
				default:
					n.msg = "<"+n.user+">	"+n.msg;
			}
			fs.createWriteStream('data/logs/'+log+'.log',{
				flags: 'a',
				encoding: 'ascii'
			}).end("["+d.getHours()+":"+addZero(d.getMinutes())+":"+addZero(d.getSeconds())+"] "+n.msg);
	}
}
function htmlEntities(str){
	return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
}
var count = 0,
	server = global.logServer = http.createServer(function (req, res) {
		function check(d){
			try{
				return fs.statSync(d).isDirectory();
			}catch(er){
				return false;
			}
		}
		var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress, ext,url = require('url').parse(req.url,true);
		switch(config.logtype){
			case 'listdb':
				ext = '.db';
				break;
			case 'txt': default:
				ext = '.log';
		}
		disp.log("Serving "+req.url+" to: "+ip);
		if(req.url == '/'){
			res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8','Server': 'NodeBot/Logs'});
			res.write("<!doctype html>\n\n\t\n\t\t<link rel='icon' type='image/x-icon' href='favicon.ico' />\n\t\t<title>Logs</title>\n\t\t\n\t\n\t");
			var logs = fs.readdirSync('data/logs/');
			if(logs){
				var i,j,f;
				for (i = 0; i < logs.length; i++){
					if(check('data/logs/'+logs[i])){
						var logdirs = fs.readdirSync('data/logs/'+logs[i]);
						if(logdirs){
							res.write('\n\t\t
'+logs[i]+'
\n\t\t
');
							for (j = 0; j < logdirs.length; j++){
								if(
									check('data/logs/'+logs[i]+'/'+logdirs[j])
									&& logdirs[j] != '- server -'
									&& logdirs[j].substr(0,1) == '#'
								){
									var logfiles = fs.readdirSync('data/logs/'+logs[i]+'/'+logdirs[j]);
									if(logfiles){
										logfiles = logfiles.sort(function(a, b){
											return (new Date(path.basename(a,ext))).getTime()-(new Date(path.basename(b,ext))).getTime();
										});
										res.write('\n\t\t\t
\n\t\t\t\t
'+logdirs[j]+'
\n\t\t\t\t
');
										for (f = 0; f < logfiles.length; f++){
											if(path.extname(logfiles[f]) == ext){
												var c = path.basename(logfiles[f],ext);
												res.write('\n\t\t\t\t\t
\n\t\t\t\t\t\t'+c+'\n\t\t\t\t\t
');
											}
										}
										res.write('\n\t\t\t\t
\n\t\t\t
');
									}
								}
							}
							res.write('\n\t\t
');
						}
					}
				}
			}
			res.end("\n\t\n");
		}else if(req.url == '/favicon.ico'){
			fs.readFile('data/favicon.ico', "binary", function (err,file) {
				if (err) {
					res.writeHead(500, {'Content-Type':'image/x-icon','Server':'NodeBot/Logs'});
					res.write(err+"\n");
					res.end();
					return;
				}
				res.writeHead(200,{'Content-Type':'image/x-icon','Server':'NodeBot/Logs'});
				res.write(file, "binary");
				res.end();
			});
		}else{
			var log = url.query,e,m,i,l,n,td,d = new Date();
			if(log.date == 'today'){
				n = d.toDateString();
			}else{
				n = log.date;
			}
			switch(config.logtype){
				case 'listdb':
					res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8','Server': 'NodeBot/Logs'});
					l = listdb.getDB('logs/'+log.server+'/#'+log.channel+'/'+n).getAll();
					res.write('<title>'+log.server+' #'+log.channel+' '+n+'</title>');
					for(i in l){
                        try{
                            e = JSON.parse(l[i]);
                            e.msg = htmlEntities(e.msg).replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig,function(url){
                                return ''+url+'';
                            }).replace(/[\x02\x1f\x16\x0f]|\x03(\d{0,2}(?:,\d{0,2})?)/g,"");
                            e.user = htmlEntities(e.user);
                            switch(e.type){
                                case 'join':
                                    m = '*'+e.user+' joined the channel';
                                    break;
                                case 'part':
                                    m = '*'+e.user+' left the channel';
                                    break;
                                case 'privmsg':
                                    m = '<	'+e.user+'	>	'+e.msg;
                                    break;
                                case 'action':
                                    m = '* '+e.user+' '+e.msg+'';
                                    break;
                                default:
                                    m = 'error! '+e.type;
                            }
                            td = new Date(e.date);
                            res.write("\t'+'['+addZero(td.getUTCHours())+':'+addZero(td.getUTCMinutes())+':'+addZero(td.getUTCSeconds())+']'+m+"
\n");
                        }catch(e){
                            disp.log("Invalid character in log");
                            res.write("\t*Please contact the owner of this bot. The logs have invalid characters*
\n");
                        }
					}
					res.end('');
				break;
				case 'txt': default:
					res.writeHead(200, {'Content-Type': 'text/plain;','Server': 'NodeBot/Logs'});
					try{
						res.end(fs.readFileSync('data/logs/'+log.server+'/#'+log.channel+'/'+n+ext,'ascii'));
					}catch(e){
						res.end("Error opening log: "+log.server+'/#'+log.channel+'/'+n+ext);
					}
			}
		}
	}).listen(Settings.port);
server.on("close",function(){
	disp.alert("Ending Log Server");
});
server.on('error',function(e){
	if(e.code == 'EADDRINUSE'){
		setTimeout(function(){
			if(count < Settings.check_timeout){
				count++;
				disp.log("Port "+Settings.port+" in use, reconnect attempt: "+count);
				try{
					server.close();
				}catch(e){}
				server.listen(Settings.port);
			}else{
				count = 0;
				disp.log('Port in use, stopping');
			}
		},Settings.check_interval);
	}else{
		disp.trace();
		disp.error(e);
	}
});
hook('unload',function(){
	try{
		server.close();
		global.logServer = null;
		addZero = null;
		save = null;
		htmlEntities = null;
	}catch(e){
		disp.alert("Log Server Already Ended");
	}
});
disp.alert("Logging enabled");<commit_msg>testing<commit_after>fs.mkdirParent("data/logs/");
fs.mkdirParent('data/templates/');
if(!fs.exists('data/templates/chatlog.html')){
    var template = '\n\t\n\t\t<title>\n\t\t\t{Title}\n\t\t</title>\n\t\n\t\n\t\t{Item(\n\t\t\t\n\t\t\t\t{timestamp}\n\t\t\t\n\t\t\t{Text}\n\t\t\t
\n\t\t)}\n\t\t\n\t\n';
    fs.writeFile('data/templates/chatlog.html',template,function(err) {
        if(err) {
    		disp.error(err);
		}else{
			disp.log("No chat log template found. Creating default.");
		}
	});
}
var Settings = regSettings('logServer',{
    // Port to run the server on
	port: 9002,
	// How quickly to check if the port is in use
	check_interval: 1000,
	// how many times to check before failing to start
	check_timeout: 10
});
listen(/^.+/i,function(match,data,replyTo,connection){
	var nick,data2;
	if(replyTo===null){
		replyTo = "- server -";
	}else{
		try{
			nick = (/^:([^!]+)!.*PRIVMSG ([^ ]+) :(.+)$/i).exec(data)[1];
			data = (/^:([^!]+)!.*PRIVMSG ([^ ]+) :(.+)$/i).exec(data)[3];
			if(nick.toLowerCase() == 'omnomirc'){
				if((data2 = (/\([#O]\).?<(\w+)>(.+)$/).exec(data)) !== null){
					nick = data2[1];
					data = data2[2].trim();
				}else if((data2 = (/\([#O]\).? *(.+) has quit .+$/).exec(data)) != null){
					console.log(data2);

				}
			}
            replyTo = replyTo.trim().toLowerCase();
		}catch(e){
			disp.error(e)
			disp.log("Defaulting to '- server -' replyTo");
			replyTo = "- server -";
		}
	}
	var d = new Date();
	var p = connection.config.host+" "+connection.config.port+"/"+replyTo+"/"+d.toDateString();
	if(replyTo == "- server -" && (new RegExp("^:(.+) 372 "+connection.config.nick+" :(.+)$")).exec(data) === null){
		save(p,{
			msg: ">>>	"+data
		});
	}else if(data.indexOf("\x01ACTION ")!=-1){
		save(p,{
			msg: data.substr(data.indexOf("\x01ACTION ")+8,data.length-9),
			user: nick,
			type: 'action'
		});
	}else{
		save(p,{
			msg: data,
			user: nick
		});
	}
});
listen(/^:([^!]+).*PART ([^ ]+) :$/i,function(match,data,replyTo,connection){
	replyTo = match[2].substr(1).trim().toLowerCase();
	var d = new Date();
	save(connection.config.host+" "+connection.config.port+"/#"+replyTo+"/"+d.toDateString(),{
		user: match[1],
		type: 'part'
	});
});
listen(/^:([^!]+).*JOIN :([^ ]+)$/i,function(match,data,replyTo,connection){
	replyTo = match[2].substr(1).trim().toLowerCase();
	var d = new Date();
	save(connection.config.host+" "+connection.config.port+"/#"+replyTo+"/"+d.toDateString(),{
		type: 'join',
		user: match[1]
	});
});
reply_listen(function(replyTo,msg,connection){
	if(replyTo===null){
		replyTo = "- server -";
	}else{
		replyTo = replyTo.trim().toLowerCase();
	}
	var d = new Date();
	save(connection.config.host+" "+connection.config.port+"/#"+replyTo+"/"+d.toDateString(),{
		msg: msg,
		user: connection.config.nick
	});
});
send_listen(/^.+/i,function(match,msg,connection){
	var d = new Date();
	save(connection.config.host+" "+connection.config.port+"/- server -/"+d.toDateString(),{
		msg: "<<<	"+msg
	});
});
hook('quit',function(){
	var d = new Date();
	save(this.config.host+" "+this.config.port+"/- server -/"+d.toDateString(),{
		msg: "*Connection Quit*"
	});
});
hook('reconnect',function(){
	var d = new Date();
	save(this.config.host+" "+this.config.port+"/- server -/"+d.toDateString(),{
		msg: "*Reconnected*"
	});
});
hook('connect',function(){
	var d = new Date();
	save(this.config.host+" "+this.config.port+"/- server -/"+d.toDateString(),{
		msg: "*Connected*"
	});
});
hook('timeout',function(){
	var d = new Date();
	save(this.config.host+" "+this.config.port+"/- server -/"+d.toDateString(),{
		msg: "*Connection Timeout*"
	});
});
disp.alert("Starting Log Server");
function addZero(num){
	return (String(num).length < 2) ? num = String("0" + num) :  num = String(num);
}
function save(log,o){
	fs.mkdirParent('data/logs/'+path.dirname(log));
	var d = new Date(),n = {};
	if(typeof o.type === 'undefined'){
		n.type = 'privmsg';
	}else{
		n.type = o.type;
	}
	if(typeof o.user === 'undefined'){
		n.user = '- server -';
	}else{
		n.user = o.user;
	}
	if(typeof o.msg !== 'undefined'){
		n.msg = o.msg;
	}
	n.date = d.getTime()+d.getTimezoneOffset()*60*1000;
	switch(config.logtype){
		case 'listdb':
				var l = listdb.getDB('logs/'+log);
				l.add(JSON.stringify(n));
				break;
		case 'txt': default:
			switch(n.type){
				case 'part':
					n.msg = "* "+n.user+" has left the channel";
					break;
				case 'join':
					n.msg = "* "+n.user+" has joined the channel";
					break;
				case 'action':
					n.msg = "* "+n.user+" "+n.msg;
					break;
				default:
					n.msg = "<"+n.user+">	"+n.msg;
			}
			fs.createWriteStream('data/logs/'+log+'.log',{
				flags: 'a',
				encoding: 'ascii'
			}).end("["+d.getHours()+":"+addZero(d.getMinutes())+":"+addZero(d.getSeconds())+"] "+n.msg);
	}
}
function htmlEntities(str){
	return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
}
var count = 0,
	server = global.logServer = http.createServer(function (req, res) {
		function check(d){
			try{
				return fs.statSync(d).isDirectory();
			}catch(er){
				return false;
			}
		}
		var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress, ext,url = require('url').parse(req.url,true);
		switch(config.logtype){
			case 'listdb':
				ext = '.db';
				break;
			case 'txt': default:
				ext = '.log';
		}
		disp.log("Serving "+req.url+" to: "+ip);
		if(req.url == '/'){
			res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8','Server': 'NodeBot/Logs'});
			res.write("<!doctype html>\n\n\t\n\t\t<link rel='icon' type='image/x-icon' href='favicon.ico' />\n\t\t<title>Logs</title>\n\t\t\n\t\n\t");
			var logs = fs.readdirSync('data/logs/');
			if(logs){
				var i,j,f;
				for (i = 0; i < logs.length; i++){
					if(check('data/logs/'+logs[i])){
						var logdirs = fs.readdirSync('data/logs/'+logs[i]);
						if(logdirs){
							res.write('\n\t\t
'+logs[i]+'
\n\t\t
');
							for (j = 0; j < logdirs.length; j++){
								if(
									check('data/logs/'+logs[i]+'/'+logdirs[j])
									&& logdirs[j] != '- server -'
									&& logdirs[j].substr(0,1) == '#'
								){
									var logfiles = fs.readdirSync('data/logs/'+logs[i]+'/'+logdirs[j]);
									if(logfiles){
										logfiles = logfiles.sort(function(a, b){
											// TODO change to using timestamps
											return (new Date(path.basename(a,ext))).getTime()-(new Date(path.basename(b,ext))).getTime();
										});
										res.write('\n\t\t\t
\n\t\t\t\t
'+logdirs[j]+'
\n\t\t\t\t
');
										for (f = 0; f < logfiles.length; f++){
											if(path.extname(logfiles[f]) == ext){
												var c = path.basename(logfiles[f],ext);
												res.write('\n\t\t\t\t\t
\n\t\t\t\t\t\t'+c+'\n\t\t\t\t\t
');
											}
										}
										res.write('\n\t\t\t\t
\n\t\t\t
');
									}
								}
							}
							res.write('\n\t\t
');
						}
					}
				}
			}
			res.end("\n\t\n");
		}else if(req.url == '/favicon.ico'){
			fs.readFile('data/favicon.ico', "binary", function (err,file) {
				if (err) {
					res.writeHead(500, {'Content-Type':'image/x-icon','Server':'NodeBot/Logs'});
					res.write(err+"\n");
					res.end();
					return;
				}
				res.writeHead(200,{'Content-Type':'image/x-icon','Server':'NodeBot/Logs'});
				res.write(file, "binary");
				res.end();
			});
		}else{
			var log = url.query,e,m,i,l,n,td,d = new Date();
			if(log.date == 'today'){
				n = d.toDateString();
			}else{
				n = log.date;
			}
			switch(config.logtype){
				case 'listdb':
					res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8','Server': 'NodeBot/Logs'});
					l = listdb.getDB('logs/'+log.server+'/#'+log.channel+'/'+n).getAll();
					res.write('<title>'+log.server+' #'+log.channel+' '+n+'</title>');
					for(i in l){
                        try{
                            e = JSON.parse(l[i]);
                            e.msg = htmlEntities(e.msg).replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig,function(url){
                                return ''+url+'';
                            }).replace(/[\x02\x1f\x16\x0f]|\x03(\d{0,2}(?:,\d{0,2})?)/g,"");
                            e.user = htmlEntities(e.user);
                            switch(e.type){
                                case 'join':
                                    m = '*'+e.user+' joined the channel';
                                    break;
                                case 'part':
                                    m = '*'+e.user+' left the channel';
                                    break;
                                case 'privmsg':
                                    m = '<	'+e.user+'	>	'+e.msg;
                                    break;
                                case 'action':
                                    m = '* '+e.user+' '+e.msg+'';
                                    break;
                                default:
                                    m = 'error! '+e.type;
                            }
                            td = new Date(e.date);
                            res.write("\t'+'['+addZero(td.getUTCHours())+':'+addZero(td.getUTCMinutes())+':'+addZero(td.getUTCSeconds())+']'+m+"
\n");
                        }catch(e){
                            disp.log("Invalid character in log");
                            res.write("\t*Please contact the owner of this bot. The logs have invalid characters*
\n");
                        }
					}
					res.end('');
				break;
				case 'txt': default:
					res.writeHead(200, {'Content-Type': 'text/plain;','Server': 'NodeBot/Logs'});
					try{
						res.end(fs.readFileSync('data/logs/'+log.server+'/#'+log.channel+'/'+n+ext,'ascii'));
					}catch(e){
						res.end("Error opening log: "+log.server+'/#'+log.channel+'/'+n+ext);
					}
			}
		}
	}).listen(Settings.port);
server.on("close",function(){
	disp.alert("Ending Log Server");
});
server.on('error',function(e){
	if(e.code == 'EADDRINUSE'){
		setTimeout(function(){
			if(count < Settings.check_timeout){
				count++;
				disp.log("Port "+Settings.port+" in use, reconnect attempt: "+count);
				try{
					server.close();
				}catch(e){}
				server.listen(Settings.port);
			}else{
				count = 0;
				disp.log('Port in use, stopping');
			}
		},Settings.check_interval);
	}else{
		disp.trace();
		disp.error(e);
	}
});
hook('unload',function(){
	try{
		server.close();
		global.logServer = null;
		addZero = null;
		save = null;
		htmlEntities = null;
	}catch(e){
		disp.alert("Log Server Already Ended");
	}
});
disp.alert("Logging enabled");<|endoftext|>


<commit_before>(function ($) {

    'use strict';

    var map,
        userLocation = {
            // use default coordinates for the city of Durham
            lat: 35.9886,
            lng: -78.9072
        },
        locationLayerPath = "data/food-locations.geojson",
        addMarker = function (lat, lng, markerHexColor, markerSymbol, markerSize) {
            var markerInfo = {
                    type: 'Feature',
                    geometry: {
                        type: 'Point',
                        coordinates: [lng, lat]
                    },
                    properties: {}
                };

            // clean this up at some point
            if (typeof markerHexColor !== 'undefined') {
                markerInfo.properties['marker-color'] = markerHexColor;
            }

            if (typeof markerSymbol !== 'undefined') {
                markerInfo.properties['marker-symbol'] = markerSymbol;
            }

            if (typeof markerSize !== 'undefined') {
                markerInfo.properties['marker-size'] = markerSize;
            }

            L.mapbox.markerLayer(markerInfo).addTo(map);
        },
        getUserLocation = function (callbackFunc) {
            var success = function (position) {
                    userLocation.lat = position.coords.latitude;
                    userLocation.lng = position.coords.longitude;

                    if (typeof callbackFunc !== 'undefined') {
                        callbackFunc();
                    }
                },
                error = function () {
                    console.log("Something went wrong trying to detect user's location.");
                };

            if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(success, error);
            } else {
                // add better fallback?
                alert("Please access this site with a browser that supports geolocation");
            }
        },
        initMap = function () {
            var markerLayer = L.mapbox.markerLayer();

            // setup a Code for Durham MapBox account for map?
            map = L.mapbox.map('map', 'tylerpearson.gc56ggok', {zoomControl: false})
                      .setView([userLocation.lat, userLocation.lng], 17);

            new L.Control.Zoom({ position: 'bottomright' }).addTo(map);

            markerLayer.loadURL(locationLayerPath)
                .addTo(map);

            map.markerLayer.on('click', function (e) {
                map.panTo(e.layer.getLatLng());
            });

        },
        init = function () {
            getUserLocation(function () {
                // create map
                initMap();

                // add a marker for the user's detected location
                addMarker(userLocation.lat, userLocation.lng, '#41b649', 'star', 'large');
            });
        };

    $(document).ready(init);

}(jQuery));
<commit_msg>better fallback for browsers without HTML5 geolocation<commit_after>(function ($) {

    'use strict';

    var map,
        userLocation = {
            // use default coordinates for the city of Durham
            lat: 35.9886,
            lng: -78.9072
        },
        locationLayerPath = "data/food-locations.geojson",
        addMarker = function (lat, lng, markerHexColor, markerSymbol, markerSize) {
            var markerInfo = {
                    type: 'Feature',
                    geometry: {
                        type: 'Point',
                        coordinates: [lng, lat]
                    },
                    properties: {}
                };

            // clean this up at some point
            if (typeof markerHexColor !== 'undefined') {
                markerInfo.properties['marker-color'] = markerHexColor;
            }

            if (typeof markerSymbol !== 'undefined') {
                markerInfo.properties['marker-symbol'] = markerSymbol;
            }

            if (typeof markerSize !== 'undefined') {
                markerInfo.properties['marker-size'] = markerSize;
            }

            L.mapbox.markerLayer(markerInfo).addTo(map);
        },
        getUserLocation = function (callbackFunc) {
            var success = function (position) {
                    userLocation.lat = position.coords.latitude;
                    userLocation.lng = position.coords.longitude;

                    if (typeof callbackFunc !== 'undefined') {
                        callbackFunc();
                    }
                },
                error = function () {
                    console.log("Something went wrong trying to detect user's location.");
                };

            if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(success, error);
            } else {
                // add better fallback?
                alert("Please access this site with a browser that supports geolocation");
            }
        },
        initMap = function () {
            var markerLayer = L.mapbox.markerLayer();

            // setup a Code for Durham MapBox account for map?
            map = L.mapbox.map('map', 'tylerpearson.gc56ggok', {zoomControl: false})
                      .setView([userLocation.lat, userLocation.lng], 17);

            new L.Control.Zoom({ position: 'bottomright' }).addTo(map);

            markerLayer.loadURL(locationLayerPath)
                .addTo(map);

            map.markerLayer.on('click', function (e) {
                map.panTo(e.layer.getLatLng());
            });

        },
        init = function () {
            if (navigator.geolocation) {
                getUserLocation(function () {
                    // create map
                    initMap();

                    // add a marker for the user's detected location
                    addMarker(userLocation.lat, userLocation.lng, '#41b649', 'star', 'large');
                });
            } else {
                initMap();
            }
        };

    $(document).ready(init);

}(jQuery));
<|endoftext|>


<commit_before>(function () {
var Ipc = require('ipc');
var Path = require('fire-path');
//var Url = require('fire-url');

Editor.registerElement({
    listeners: {
        'mousedown': '_onMouseDown',
        'mousewheel': '_onMouseWheel',
        'mousemove': '_onMouseMove',
        'mouseleave': '_onMouseLeave',
        'keydown': '_onKeyDown',
        'keyup': '_onKeyUp',
    },

    properties: {
        scale: {
            type: Number,
            value: 1.0,
        },
    },

    created: function () {
        window.sceneView = this;
    },

    ready: function () {
        var mappingH = cc.Runtime.Settings['mapping-h'];
        var mappingV = cc.Runtime.Settings['mapping-v'];

        // grid
        this.$.grid.setScaleH( [5,2], 0.01, 1000 );
        this.$.grid.setMappingH( mappingH[0], mappingH[1], mappingH[2] );

        this.$.grid.setScaleV( [5,2], 0.01, 1000 );
        this.$.grid.setMappingV( mappingV[0], mappingV[1], mappingV[2] );

        this.$.grid.setAnchor( 0.5, 0.5 );

        // make sure css reflow
        requestAnimationFrame( function () {
            this._initEngine();

            // init grid
            this.$.grid.resize();
            this.$.grid.repaint();

            // init gizmos
            this.$.gizmosView.resize();
            this.$.gizmosView.sceneToPixel = this.sceneToPixel.bind(this);
            this.$.gizmosView.worldToPixel = this.worldToPixel.bind(this);
            this.$.gizmosView.pixelToScene = this.pixelToScene.bind(this);
            this.$.gizmosView.pixelToWorld = this.pixelToWorld.bind(this);
        }.bind(this));
    },

    reset: function () {
        Editor.Selection.clear('node');

        // reset scene gizmos, scene grid
        window.sceneView.$.gizmosView.reset();

        // reset cc.engine editing state
        cc.engine.animatingInEditMode = false;
    },

    init: function ( x, y, scale ) {
        this.scale = scale;

        //
        this.$.grid.xAxisSync ( x, scale );
        this.$.grid.yAxisSync ( y, scale );
        this.$.grid.repaint();

        //
        this.$.gizmosView.scale = scale;

        //
        var scene = cc(cc.director.getRunningScene());
        scene.scale = cc.v2( this.$.grid.xAxisScale, this.$.grid.yAxisScale );
        scene.position = cc.v2(this.$.grid.xDirection*this.$.grid.xAxisOffset,
                                 this.$.grid.yDirection*this.$.grid.yAxisOffset);
        cc.engine.repaintInEditMode();
    },

    _resize: function () {
        if ( cc.engine.isPlaying ) {
            return;
        }

        // resize grid
        this.$.grid.resize();
        this.$.grid.repaint();

        // resize gizmos
        this.$.gizmosView.resize();

        // resize engine
        var bcr = this.getBoundingClientRect();
        cc.view.setCanvasSize(bcr.width, bcr.height);
        cc.view.setDesignResolutionSize(bcr.width, bcr.height);

        // sync axis offset and scale from grid
        var scene = cc(cc.director.getRunningScene());
        scene.scale = cc.v2(this.$.grid.xAxisScale, this.$.grid.yAxisScale);
        scene.position = cc.v2(this.$.grid.xDirection*this.$.grid.xAxisOffset,
                                 this.$.grid.yDirection*this.$.grid.yAxisOffset);
        cc.engine.repaintInEditMode();
    },

    _initEngine: function () {
        // init asset library
        //var importUrl = Url.format({
        //    protocol: '',
        //    pathname: Editor.importPath,
        //    slashes: true,
        //});
        var importUrl = Editor.importPath.replace(/\\/g, '/');
        var assetUrl = Path.join(Editor.projectInfo.path, 'assets').replace(/\\/g, '/');
        cc.AssetLibrary.init(importUrl, assetUrl);

        // init engine
        var canvasEL = this.$['engine-canvas'];
        var bcr = this.getBoundingClientRect();
        canvasEL.width  = bcr.width;
        canvasEL.height = bcr.height;

        var initOptions = {
            width: bcr.width,
            height: bcr.height,
            id: 'engine-canvas',
            designWidth: bcr.width,
            designHeight: bcr.height
        };

        cc.engine.init(initOptions, function () {
            Editor.initScene(function (err) {
                if (err) {
                    Ipc.sendToHost('scene:init-error', err);
                }
                else {
                    Ipc.sendToHost('scene:ready');
                }
            });
        });

        // beforeunload event
        window.addEventListener('beforeunload', function ( event ) {
            Editor.Selection.clear('node');
            if ( cc.engine.isPlaying ) {
                cc.engine.stop();
            }
        });

        // debounce resize event
        var self = this;
        var _resizeDebounceID = null;
        window.addEventListener('resize', function ( event ) {
            // debounce write for 10ms
            if ( _resizeDebounceID ) {
                return;
            }
            _resizeDebounceID = setTimeout(function () {
                _resizeDebounceID = null;
                self._resize();
            }, 10);
        });
    },

    newScene: function () {
        var sceneWrapper = new cc.Runtime.SceneWrapper();
        sceneWrapper.createAndAttachNode();

        this.reset();
        cc.game._launchScene(sceneWrapper);

        this.adjustToCenter(20);
        cc.engine.repaintInEditMode();

        Editor.remote.currentSceneUuid = null;
        Ipc.sendToHost('scene:ready');
    },

    loadScene: function ( uuid ) {
        this.reset();

        cc.game._loadSceneByUuid(uuid, function (err) {
            this.adjustToCenter(20);
            cc.engine.repaintInEditMode();

            if (err) {
                Ipc.sendToHost('scene:init-error', err);
            }
            else {
                Editor.remote.currentSceneUuid = uuid;
                Ipc.sendToHost('scene:ready');
            }
        }.bind(this));
    },

    adjustToCenter: function ( margin ) {
        var bcr = this.getBoundingClientRect();
        var fitWidth = bcr.width - margin * 2;
        var fitHeigth = bcr.height - margin * 2;
        var designWidth = this.$.gizmosView.designSize[0];
        var designHeight = this.$.gizmosView.designSize[1];

        if ( designWidth <= fitWidth && designHeight <= fitHeigth ) {
            this.init( this.$.grid.xDirection * (bcr.width - designWidth)/2,
                       this.$.grid.yDirection * (bcr.height - designHeight)/2,
                       1.0
                    );
        }
        else {
            var result = Editor.Utils.fitSize(designWidth, designHeight,
                                              fitWidth, fitHeigth);
            // move x
            if ( result[0] < result[1] ) {
                this.init( this.$.grid.xDirection * (bcr.width - result[0])/2,
                           this.$.grid.yDirection * (bcr.height - result[1])/2,
                           result[0]/designWidth
                        );
            }
            // move y
            else {
                this.init( this.$.grid.xDirection * (bcr.width - result[0])/2,
                           this.$.grid.yDirection * (bcr.height - result[1])/2,
                           result[1]/designHeight
                        );
            }
        }
    },

    sceneToPixel: function ( pos ) {
        return cc.v2(
            this.$.grid.valueToPixelH(pos.x),
            this.$.grid.valueToPixelV(pos.y)
        );
    },

    worldToPixel: function (pos) {
        var scene = cc(cc.director.getRunningScene());
        var scenePos = scene.transformPointToLocal(pos);
        return this.sceneToPixel( scenePos );
    },

    pixelToScene: function (pos) {
        return cc.v2(
            this.$.grid.pixelToValueH(pos.x),
            this.$.grid.pixelToValueV(pos.y)
        );
    },

    pixelToWorld: function (pos) {
        var scene = cc(cc.director.getRunningScene());
        return scene.transformPointToWorld( this.pixelToScene(pos) );
    },

    activate: function ( id ) {
        var wrapper = cc.engine.getInstanceById(id);
        if ( wrapper && wrapper.constructor.animatableInEditor ) {
            if ( wrapper.onFocusInEditor )
                wrapper.onFocusInEditor();

            cc.engine.animatingInEditMode = true;
        }
    },

    deactivate: function ( id ) {
        var wrapper = cc.engine.getInstanceById(id);
        if ( wrapper && wrapper.constructor.animatableInEditor ) {
            if ( wrapper.onLostFocusInEditor )
                wrapper.onLostFocusInEditor();

            cc.engine.animatingInEditMode = false;
        }
    },

    select: function ( ids ) {
        this.$.gizmosView.select(ids);
    },

    unselect: function ( ids ) {
        this.$.gizmosView.unselect(ids);
    },

    hoverin: function ( id ) {
        this.$.gizmosView.hoverin(id);
    },

    hoverout: function ( id ) {
        this.$.gizmosView.hoverout(id);
    },

    delete: function ( ids ) {
        for (var i = 0; i < ids.length; i++) {
            var id = ids[i];
            var nodeWrapper = cc.engine.getInstanceById(id);
            if (nodeWrapper) {
                nodeWrapper.parent = null;
            }
        }
        Editor.Selection.unselect('node', ids, true);
    },

    hitTest: function ( x, y ) {
        // TODO
        // this.$.gizmosView.rectHitTest( x, y, 1, 1 );

        var worldHitPoint = this.pixelToWorld( cc.v2(x,y) );
        var minDist = Number.MAX_VALUE;
        var resultNode;

        var nodes = cc.engine.getIntersectionList( new cc.Rect(worldHitPoint.x, worldHitPoint.y, 1, 1) );
        nodes.forEach( function ( node ) {
            var fireNode = cc(node);
            var aabb = fireNode.getWorldBounds();
            // TODO: calculate the OBB center instead
            var dist = worldHitPoint.sub(aabb.center).magSqr();
            if ( dist < minDist ) {
                minDist = dist;
                resultNode = fireNode;
            }
        });

        return resultNode;
    },

    rectHitTest: function ( x, y, w, h ) {
        var v1 = this.pixelToWorld( cc.v2(x,y) );
        var v2 = this.pixelToWorld( cc.v2(x+w,y+h) );
        var worldRect = cc.Rect.fromMinMax(v1,v2);

        var results = [];
        var nodes = cc.engine.getIntersectionList(worldRect);
        nodes.forEach( function ( node ) {
            var fireNode = cc(node);
            results.push(fireNode);
        });

        return results;
    },

    // DISABLE
    // play: function () {
    //     var self = this;
    //     //
    //     Editor.playScene(function (err) {
    //         if (err) {
    //             Ipc.sendToHost('scene:play-error', err);
    //             return;
    //         }
    //         Ipc.sendToHost('scene:playing');
    //     });
    // },

    _onMouseDown: function ( event ) {
        event.stopPropagation();

        // panning
        if ( (event.which === 1 && event.shiftKey) ||
             event.which === 2
           )
        {
            this.style.cursor = '-webkit-grabbing';
            EditorUI.startDrag(
                '-webkit-grabbing',
                event,

                // move
                function ( event, dx, dy, offsetx, offsety ) {
                    this.$.grid.pan( dx, dy );
                    this.$.grid.repaint();

                    var scene = cc(cc.director.getRunningScene());
                    scene.position = cc.v2(this.$.grid.xDirection*this.$.grid.xAxisOffset,
                                             this.$.grid.yDirection*this.$.grid.yAxisOffset);
                    cc.engine.repaintInEditMode();
                }.bind(this),

                // end
                function ( event, dx, dy, offsetx, offsety ) {
                    if ( event.shiftKey )
                        this.style.cursor = '-webkit-grab';
                    else
                        this.style.cursor = '';
                }.bind(this)
            );

            return;
        }

        // process rect-selection
        if ( event.which === 1 ) {
            var toggleMode = false;
            var lastSelection = Editor.Selection.curSelection('node');
            if ( event.metaKey || event.ctrlKey ) {
                toggleMode = true;
            }

            var startx = event.offsetX;
            var starty = event.offsetY;

            EditorUI.startDrag(
                'default',
                event,

                // move
                function ( event, dx, dy, offsetx, offsety ) {
                    var magSqr = offsetx*offsetx + offsety*offsety;
                    if ( magSqr < 2.0 * 2.0 ) {
                        return;
                    }

                    var x = startx;
                    var y = starty;

                    if ( offsetx < 0.0 ) {
                        x += offsetx;
                        offsetx = -offsetx;
                    }
                    if ( offsety < 0.0 ) {
                        y += offsety;
                        offsety = -offsety;
                    }

                    this.$.gizmosView.updateSelectRect( x, y, offsetx, offsety );

                    var nodes = this.rectHitTest( x, y, offsetx, offsety );
                    var i, ids;

                    // toggle mode will always act added behaviour when we in rect-select-state
                    if ( toggleMode ) {
                        ids = lastSelection.slice();

                        for ( i = 0; i < nodes.length; ++i ) {
                            if ( ids.indexOf(nodes[i].uuid) === -1 )
                                ids.push( nodes[i].uuid );
                        }
                    }
                    else {
                        ids = [];

                        for ( i = 0; i < nodes.length; ++i ) {
                            ids.push( nodes[i].uuid );
                        }
                    }
                    Editor.Selection.select ( 'node', ids, true, false );
                }.bind(this),

                // end
                function ( event, dx, dy, offsetx, offsety ) {
                    var magSqr = offsetx*offsetx + offsety*offsety;
                    if ( magSqr < 2.0 * 2.0 ) {
                        var node = this.hitTest( startx, starty );

                        if ( toggleMode ) {
                            if ( node ) {
                                if ( lastSelection.indexOf(node.uuid) === -1 ) {
                                    Editor.Selection.select ( 'node', node.uuid, false, true );
                                }
                                else {
                                    Editor.Selection.unselect ( 'node', node.uuid, true );
                                }
                            }
                        }
                        else {
                            if ( node ) {
                                Editor.Selection.select ( 'node', node.uuid, true, true );
                            }
                            else {
                                Editor.Selection.clear ( 'node' );
                            }
                        }
                    }
                    else {
                        Editor.Selection.confirm ();
                        this.$.gizmosView.fadeoutSelectRect();
                    }
                }.bind(this)
            );

            return;
        }
    },

    _onMouseWheel: function ( event ) {
        event.stopPropagation();

        var newScale = Editor.Utils.smoothScale(this.scale, event.wheelDelta);
        newScale = Math.clamp(newScale,
                              this.$.grid.hticks.minValueScale,
                              this.$.grid.hticks.maxValueScale);

        //
        this.scale = newScale;

        //
        this.$.grid.xAxisScaleAt ( event.offsetX, newScale );
        this.$.grid.yAxisScaleAt ( event.offsetY, newScale );
        this.$.grid.repaint();

        //
        this.$.gizmosView.scale = newScale;

        //
        var scene = cc(cc.director.getRunningScene());
        scene.scale = cc.v2( this.$.grid.xAxisScale, this.$.grid.yAxisScale );
        scene.position = cc.v2(this.$.grid.xDirection*this.$.grid.xAxisOffset,
                                 this.$.grid.yDirection*this.$.grid.yAxisOffset);
        cc.engine.repaintInEditMode();
    },

    _onMouseMove: function ( event ) {
        event.stopPropagation();

        var node = this.hitTest( event.offsetX, event.offsetY );
        var id = node ? node.uuid : null;
        Editor.Selection.hover( 'node', id );
    },

    _onMouseLeave: function ( event ) {
        Editor.Selection.hover( 'node', null );
    },

    _onKeyDown: function ( event ) {
        event.stopPropagation();

        if ( Editor.KeyCode(event.which) === 'shift' ) {
            this.style.cursor = '-webkit-grab';
            return;
        }
    },

    _onKeyUp: function ( event ) {
        event.stopPropagation();

        if ( Editor.KeyCode(event.which) === 'shift' ) {
            this.style.cursor = '';
        }
    },
});

})();
<commit_msg>remove cc.Runtime<commit_after>(function () {
var Ipc = require('ipc');
var Path = require('fire-path');
//var Url = require('fire-url');

Editor.registerElement({
    listeners: {
        'mousedown': '_onMouseDown',
        'mousewheel': '_onMouseWheel',
        'mousemove': '_onMouseMove',
        'mouseleave': '_onMouseLeave',
        'keydown': '_onKeyDown',
        'keyup': '_onKeyUp',
    },

    properties: {
        scale: {
            type: Number,
            value: 1.0,
        },
    },

    created: function () {
        window.sceneView = this;
    },

    ready: function () {
        var mappingH = [0,1,1];
        var mappingV = [1,0,1];

        // grid
        this.$.grid.setScaleH( [5,2], 0.01, 1000 );
        this.$.grid.setMappingH( mappingH[0], mappingH[1], mappingH[2] );

        this.$.grid.setScaleV( [5,2], 0.01, 1000 );
        this.$.grid.setMappingV( mappingV[0], mappingV[1], mappingV[2] );

        this.$.grid.setAnchor( 0.5, 0.5 );

        // make sure css reflow
        requestAnimationFrame( function () {
            this._initEngine();

            // init grid
            this.$.grid.resize();
            this.$.grid.repaint();

            // init gizmos
            this.$.gizmosView.resize();
            this.$.gizmosView.sceneToPixel = this.sceneToPixel.bind(this);
            this.$.gizmosView.worldToPixel = this.worldToPixel.bind(this);
            this.$.gizmosView.pixelToScene = this.pixelToScene.bind(this);
            this.$.gizmosView.pixelToWorld = this.pixelToWorld.bind(this);
        }.bind(this));
    },

    reset: function () {
        Editor.Selection.clear('node');

        // reset scene gizmos, scene grid
        window.sceneView.$.gizmosView.reset();

        // reset cc.engine editing state
        cc.engine.animatingInEditMode = false;
    },

    init: function ( x, y, scale ) {
        this.scale = scale;

        //
        this.$.grid.xAxisSync ( x, scale );
        this.$.grid.yAxisSync ( y, scale );
        this.$.grid.repaint();

        //
        this.$.gizmosView.scale = scale;

        //
        var scene = cc(cc.director.getRunningScene());
        scene.scale = cc.v2( this.$.grid.xAxisScale, this.$.grid.yAxisScale );
        scene.position = cc.v2(this.$.grid.xDirection*this.$.grid.xAxisOffset,
                                 this.$.grid.yDirection*this.$.grid.yAxisOffset);
        cc.engine.repaintInEditMode();
    },

    _resize: function () {
        if ( cc.engine.isPlaying ) {
            return;
        }

        // resize grid
        this.$.grid.resize();
        this.$.grid.repaint();

        // resize gizmos
        this.$.gizmosView.resize();

        // resize engine
        var bcr = this.getBoundingClientRect();
        cc.view.setCanvasSize(bcr.width, bcr.height);
        cc.view.setDesignResolutionSize(bcr.width, bcr.height);

        // sync axis offset and scale from grid
        var scene = cc(cc.director.getRunningScene());
        scene.scale = cc.v2(this.$.grid.xAxisScale, this.$.grid.yAxisScale);
        scene.position = cc.v2(this.$.grid.xDirection*this.$.grid.xAxisOffset,
                                 this.$.grid.yDirection*this.$.grid.yAxisOffset);
        cc.engine.repaintInEditMode();
    },

    _initEngine: function () {
        // init asset library
        //var importUrl = Url.format({
        //    protocol: '',
        //    pathname: Editor.importPath,
        //    slashes: true,
        //});
        var importUrl = Editor.importPath.replace(/\\/g, '/');
        var assetUrl = Path.join(Editor.projectInfo.path, 'assets').replace(/\\/g, '/');
        cc.AssetLibrary.init(importUrl, assetUrl);

        // init engine
        var canvasEL = this.$['engine-canvas'];
        var bcr = this.getBoundingClientRect();
        canvasEL.width  = bcr.width;
        canvasEL.height = bcr.height;

        var initOptions = {
            width: bcr.width,
            height: bcr.height,
            id: 'engine-canvas',
            designWidth: bcr.width,
            designHeight: bcr.height
        };

        cc.engine.init(initOptions, function () {
            Editor.initScene(function (err) {
                if (err) {
                    Ipc.sendToHost('scene:init-error', err);
                }
                else {
                    Ipc.sendToHost('scene:ready');
                }
            });
        });

        // beforeunload event
        window.addEventListener('beforeunload', function ( event ) {
            Editor.Selection.clear('node');
            if ( cc.engine.isPlaying ) {
                cc.engine.stop();
            }
        });

        // debounce resize event
        var self = this;
        var _resizeDebounceID = null;
        window.addEventListener('resize', function ( event ) {
            // debounce write for 10ms
            if ( _resizeDebounceID ) {
                return;
            }
            _resizeDebounceID = setTimeout(function () {
                _resizeDebounceID = null;
                self._resize();
            }, 10);
        });
    },

    newScene: function () {
        var sceneWrapper = new cc.Runtime.SceneWrapper();
        sceneWrapper.createAndAttachNode();

        this.reset();
        cc.game._launchScene(sceneWrapper);

        this.adjustToCenter(20);
        cc.engine.repaintInEditMode();

        Editor.remote.currentSceneUuid = null;
        Ipc.sendToHost('scene:ready');
    },

    loadScene: function ( uuid ) {
        this.reset();

        cc.game._loadSceneByUuid(uuid, function (err) {
            this.adjustToCenter(20);
            cc.engine.repaintInEditMode();

            if (err) {
                Ipc.sendToHost('scene:init-error', err);
            }
            else {
                Editor.remote.currentSceneUuid = uuid;
                Ipc.sendToHost('scene:ready');
            }
        }.bind(this));
    },

    adjustToCenter: function ( margin ) {
        var bcr = this.getBoundingClientRect();
        var fitWidth = bcr.width - margin * 2;
        var fitHeigth = bcr.height - margin * 2;
        var designWidth = this.$.gizmosView.designSize[0];
        var designHeight = this.$.gizmosView.designSize[1];

        if ( designWidth <= fitWidth && designHeight <= fitHeigth ) {
            this.init( this.$.grid.xDirection * (bcr.width - designWidth)/2,
                       this.$.grid.yDirection * (bcr.height - designHeight)/2,
                       1.0
                    );
        }
        else {
            var result = Editor.Utils.fitSize(designWidth, designHeight,
                                              fitWidth, fitHeigth);
            // move x
            if ( result[0] < result[1] ) {
                this.init( this.$.grid.xDirection * (bcr.width - result[0])/2,
                           this.$.grid.yDirection * (bcr.height - result[1])/2,
                           result[0]/designWidth
                        );
            }
            // move y
            else {
                this.init( this.$.grid.xDirection * (bcr.width - result[0])/2,
                           this.$.grid.yDirection * (bcr.height - result[1])/2,
                           result[1]/designHeight
                        );
            }
        }
    },

    sceneToPixel: function ( pos ) {
        return cc.v2(
            this.$.grid.valueToPixelH(pos.x),
            this.$.grid.valueToPixelV(pos.y)
        );
    },

    worldToPixel: function (pos) {
        var scene = cc(cc.director.getRunningScene());
        var scenePos = scene.transformPointToLocal(pos);
        return this.sceneToPixel( scenePos );
    },

    pixelToScene: function (pos) {
        return cc.v2(
            this.$.grid.pixelToValueH(pos.x),
            this.$.grid.pixelToValueV(pos.y)
        );
    },

    pixelToWorld: function (pos) {
        var scene = cc(cc.director.getRunningScene());
        return scene.transformPointToWorld( this.pixelToScene(pos) );
    },

    activate: function ( id ) {
        var wrapper = cc.engine.getInstanceById(id);
        if ( wrapper && wrapper.constructor.animatableInEditor ) {
            if ( wrapper.onFocusInEditor )
                wrapper.onFocusInEditor();

            cc.engine.animatingInEditMode = true;
        }
    },

    deactivate: function ( id ) {
        var wrapper = cc.engine.getInstanceById(id);
        if ( wrapper && wrapper.constructor.animatableInEditor ) {
            if ( wrapper.onLostFocusInEditor )
                wrapper.onLostFocusInEditor();

            cc.engine.animatingInEditMode = false;
        }
    },

    select: function ( ids ) {
        this.$.gizmosView.select(ids);
    },

    unselect: function ( ids ) {
        this.$.gizmosView.unselect(ids);
    },

    hoverin: function ( id ) {
        this.$.gizmosView.hoverin(id);
    },

    hoverout: function ( id ) {
        this.$.gizmosView.hoverout(id);
    },

    delete: function ( ids ) {
        for (var i = 0; i < ids.length; i++) {
            var id = ids[i];
            var nodeWrapper = cc.engine.getInstanceById(id);
            if (nodeWrapper) {
                nodeWrapper.parent = null;
            }
        }
        Editor.Selection.unselect('node', ids, true);
    },

    hitTest: function ( x, y ) {
        // TODO
        // this.$.gizmosView.rectHitTest( x, y, 1, 1 );

        var worldHitPoint = this.pixelToWorld( cc.v2(x,y) );
        var minDist = Number.MAX_VALUE;
        var resultNode;

        var nodes = cc.engine.getIntersectionList( new cc.Rect(worldHitPoint.x, worldHitPoint.y, 1, 1) );
        nodes.forEach( function ( node ) {
            var fireNode = cc(node);
            var aabb = fireNode.getWorldBounds();
            // TODO: calculate the OBB center instead
            var dist = worldHitPoint.sub(aabb.center).magSqr();
            if ( dist < minDist ) {
                minDist = dist;
                resultNode = fireNode;
            }
        });

        return resultNode;
    },

    rectHitTest: function ( x, y, w, h ) {
        var v1 = this.pixelToWorld( cc.v2(x,y) );
        var v2 = this.pixelToWorld( cc.v2(x+w,y+h) );
        var worldRect = cc.Rect.fromMinMax(v1,v2);

        var results = [];
        var nodes = cc.engine.getIntersectionList(worldRect);
        nodes.forEach( function ( node ) {
            var fireNode = cc(node);
            results.push(fireNode);
        });

        return results;
    },

    // DISABLE
    // play: function () {
    //     var self = this;
    //     //
    //     Editor.playScene(function (err) {
    //         if (err) {
    //             Ipc.sendToHost('scene:play-error', err);
    //             return;
    //         }
    //         Ipc.sendToHost('scene:playing');
    //     });
    // },

    _onMouseDown: function ( event ) {
        event.stopPropagation();

        // panning
        if ( (event.which === 1 && event.shiftKey) ||
             event.which === 2
           )
        {
            this.style.cursor = '-webkit-grabbing';
            EditorUI.startDrag(
                '-webkit-grabbing',
                event,

                // move
                function ( event, dx, dy, offsetx, offsety ) {
                    this.$.grid.pan( dx, dy );
                    this.$.grid.repaint();

                    var scene = cc(cc.director.getRunningScene());
                    scene.position = cc.v2(this.$.grid.xDirection*this.$.grid.xAxisOffset,
                                             this.$.grid.yDirection*this.$.grid.yAxisOffset);
                    cc.engine.repaintInEditMode();
                }.bind(this),

                // end
                function ( event, dx, dy, offsetx, offsety ) {
                    if ( event.shiftKey )
                        this.style.cursor = '-webkit-grab';
                    else
                        this.style.cursor = '';
                }.bind(this)
            );

            return;
        }

        // process rect-selection
        if ( event.which === 1 ) {
            var toggleMode = false;
            var lastSelection = Editor.Selection.curSelection('node');
            if ( event.metaKey || event.ctrlKey ) {
                toggleMode = true;
            }

            var startx = event.offsetX;
            var starty = event.offsetY;

            EditorUI.startDrag(
                'default',
                event,

                // move
                function ( event, dx, dy, offsetx, offsety ) {
                    var magSqr = offsetx*offsetx + offsety*offsety;
                    if ( magSqr < 2.0 * 2.0 ) {
                        return;
                    }

                    var x = startx;
                    var y = starty;

                    if ( offsetx < 0.0 ) {
                        x += offsetx;
                        offsetx = -offsetx;
                    }
                    if ( offsety < 0.0 ) {
                        y += offsety;
                        offsety = -offsety;
                    }

                    this.$.gizmosView.updateSelectRect( x, y, offsetx, offsety );

                    var nodes = this.rectHitTest( x, y, offsetx, offsety );
                    var i, ids;

                    // toggle mode will always act added behaviour when we in rect-select-state
                    if ( toggleMode ) {
                        ids = lastSelection.slice();

                        for ( i = 0; i < nodes.length; ++i ) {
                            if ( ids.indexOf(nodes[i].uuid) === -1 )
                                ids.push( nodes[i].uuid );
                        }
                    }
                    else {
                        ids = [];

                        for ( i = 0; i < nodes.length; ++i ) {
                            ids.push( nodes[i].uuid );
                        }
                    }
                    Editor.Selection.select ( 'node', ids, true, false );
                }.bind(this),

                // end
                function ( event, dx, dy, offsetx, offsety ) {
                    var magSqr = offsetx*offsetx + offsety*offsety;
                    if ( magSqr < 2.0 * 2.0 ) {
                        var node = this.hitTest( startx, starty );

                        if ( toggleMode ) {
                            if ( node ) {
                                if ( lastSelection.indexOf(node.uuid) === -1 ) {
                                    Editor.Selection.select ( 'node', node.uuid, false, true );
                                }
                                else {
                                    Editor.Selection.unselect ( 'node', node.uuid, true );
                                }
                            }
                        }
                        else {
                            if ( node ) {
                                Editor.Selection.select ( 'node', node.uuid, true, true );
                            }
                            else {
                                Editor.Selection.clear ( 'node' );
                            }
                        }
                    }
                    else {
                        Editor.Selection.confirm ();
                        this.$.gizmosView.fadeoutSelectRect();
                    }
                }.bind(this)
            );

            return;
        }
    },

    _onMouseWheel: function ( event ) {
        event.stopPropagation();

        var newScale = Editor.Utils.smoothScale(this.scale, event.wheelDelta);
        newScale = Math.clamp(newScale,
                              this.$.grid.hticks.minValueScale,
                              this.$.grid.hticks.maxValueScale);

        //
        this.scale = newScale;

        //
        this.$.grid.xAxisScaleAt ( event.offsetX, newScale );
        this.$.grid.yAxisScaleAt ( event.offsetY, newScale );
        this.$.grid.repaint();

        //
        this.$.gizmosView.scale = newScale;

        //
        var scene = cc(cc.director.getRunningScene());
        scene.scale = cc.v2( this.$.grid.xAxisScale, this.$.grid.yAxisScale );
        scene.position = cc.v2(this.$.grid.xDirection*this.$.grid.xAxisOffset,
                                 this.$.grid.yDirection*this.$.grid.yAxisOffset);
        cc.engine.repaintInEditMode();
    },

    _onMouseMove: function ( event ) {
        event.stopPropagation();

        var node = this.hitTest( event.offsetX, event.offsetY );
        var id = node ? node.uuid : null;
        Editor.Selection.hover( 'node', id );
    },

    _onMouseLeave: function ( event ) {
        Editor.Selection.hover( 'node', null );
    },

    _onKeyDown: function ( event ) {
        event.stopPropagation();

        if ( Editor.KeyCode(event.which) === 'shift' ) {
            this.style.cursor = '-webkit-grab';
            return;
        }
    },

    _onKeyUp: function ( event ) {
        event.stopPropagation();

        if ( Editor.KeyCode(event.which) === 'shift' ) {
            this.style.cursor = '';
        }
    },
});

})();
<|endoftext|>


<commit_before>
console.log("control.js loaded");

var messages = {}; // indexed by cid
var addressbook = {}; // indexed by cid
var current_cid = null;

function set_current_addressbook(e) {
  current_cid = e.id;
  console.log("current_cid", current_cid);
  d3.select("#send-message-to").text(addressbook[current_cid].petname
                                     + " [" + current_cid + "]");
}

function main() {
  console.log("onload");

    $("ul.nav a").click(function (e) {
        e.preventDefault();
        $(this).tab("show");
    });

  var ev = new EventSource("/api/v1/views/messages?token="+token);
  ev.onmessage = function(e) {
    var data = JSON.parse(e.data); // .action, .id, .new_value
    if (data.action == "insert" || data.action == "update")
      messages[data.id] = data.new_value;
    else if (data.action == "delete")
      delete messages[data.id];

    // "value" is a row of the "messages" table
    var value = data.new_value; // .id, .cid, .payload_json, .petname
    var payload = JSON.parse(value.payload_json); // .basic
    console.log("basic message", payload.basic);

    var entries = [];
    for (var id in messages)
      entries.push(messages[id]);
    function render_message(e) {
        var payload = JSON.parse(e.payload_json); // .basic
        return e.petname+"["+e.cid+"]: "+payload.basic;
    }
    var s = d3.select("#messages").selectAll("li")
      .data(entries, function(e) {return e.id;})
      .text(render_message);
    s.enter().append("li")
      .text(render_message);
    s.exit().remove();
  };

  ev = new EventSource("/api/v1/views/addressbook?token="+token);
  ev.onmessage = function(e) {
    var data = JSON.parse(e.data); // .action, .id, .new_value
    // "value" is a subset of an "addressbook" row
    if (data.action == "insert" || data.action == "update")
      addressbook[data.id] = data.new_value;
    else if (data.action == "delete")
      delete addressbook[data.id];
    var entries = [];
    for (var id in addressbook)
      entries.push(addressbook[id]);
    var s = d3.select("#address-book").selectAll("li")
      .data(entries, function(e) { return e.id; })
      .text(function(e) {return e.petname;})
      .attr("class", function(e) { return "cid-"+e.id; })
      .on("click", set_current_addressbook)
    ;

    s.enter().append("li")
      .text(function(e) {return e.petname;})
      .attr("class", function(e) { return "cid-"+e.id; })
      .on("click", set_current_addressbook)
    ;
    s.exit().remove();
  };

  d3.select("#invite-go")[0][0].onclick = function(e) {
    var petname = d3.select("#invite-petname")[0][0].value;
    var code = d3.select("#invite-code")[0][0].value;
    console.log("inviting", petname, code);
    req = {"token": token, "args": {"petname": petname, "code": code}};
    d3.json("/api/v1/invite").post(JSON.stringify(req),
                                   function(err, r) {
                                     console.log("invited", r.ok);
                                   });
    d3.select("#invite-petname")[0][0].value = "";
    d3.select("#invite-code")[0][0].value = "";
  };

  d3.select("#send-message-go")[0][0].onclick = function(e) {
    var msg = d3.select("#send-message-body")[0][0].value;
    console.log("sending", msg, "to", current_cid);
    req = {"token": token, "args": {"cid": current_cid, "message": msg}};
    d3.json("/api/v1/send-basic").post(JSON.stringify(req),
                                       function(err, r) {
                                         console.log("sent", r.ok);
                                       });
    d3.select("#send-message-body")[0][0].value = "";
  };

  console.log("setup done");
}

document.addEventListener("DOMContentLoaded", main);
<commit_msg>control.js: hush some js2-mode warnings<commit_after>
console.log("control.js loaded");

var token; // actually interpolated into the enclosing control.html
var $, d3; // populated in control.html
var messages = {}; // indexed by cid
var addressbook = {}; // indexed by cid
var current_cid = null;

function set_current_addressbook(e) {
  current_cid = e.id;
  console.log("current_cid", current_cid);
  d3.select("#send-message-to").text(addressbook[current_cid].petname
                                     + " [" + current_cid + "]");
}

function main() {
  console.log("onload");

    $("ul.nav a").click(function (e) {
        e.preventDefault();
        $(this).tab("show");
    });

  var ev = new EventSource("/api/v1/views/messages?token="+token);
  ev.onmessage = function(e) {
    var data = JSON.parse(e.data); // .action, .id, .new_value
    if (data.action == "insert" || data.action == "update")
      messages[data.id] = data.new_value;
    else if (data.action == "delete")
      delete messages[data.id];

    // "value" is a row of the "messages" table
    var value = data.new_value; // .id, .cid, .payload_json, .petname
    var payload = JSON.parse(value.payload_json); // .basic
    console.log("basic message", payload.basic);

    var entries = [];
    for (var id in messages)
      entries.push(messages[id]);
    function render_message(e) {
        var payload = JSON.parse(e.payload_json); // .basic
        return e.petname+"["+e.cid+"]: "+payload.basic;
    }
    var s = d3.select("#messages").selectAll("li")
      .data(entries, function(e) {return e.id;})
      .text(render_message);
    s.enter().append("li")
      .text(render_message);
    s.exit().remove();
  };

  ev = new EventSource("/api/v1/views/addressbook?token="+token);
  ev.onmessage = function(e) {
    var data = JSON.parse(e.data); // .action, .id, .new_value
    // "value" is a subset of an "addressbook" row
    if (data.action == "insert" || data.action == "update")
      addressbook[data.id] = data.new_value;
    else if (data.action == "delete")
      delete addressbook[data.id];
    var entries = [];
    for (var id in addressbook)
      entries.push(addressbook[id]);
    var s = d3.select("#address-book").selectAll("li")
      .data(entries, function(e) { return e.id; })
      .text(function(e) {return e.petname;})
      .attr("class", function(e) { return "cid-"+e.id; })
      .on("click", set_current_addressbook)
    ;

    s.enter().append("li")
      .text(function(e) {return e.petname;})
      .attr("class", function(e) { return "cid-"+e.id; })
      .on("click", set_current_addressbook)
    ;
    s.exit().remove();
  };

  d3.select("#invite-go")[0][0].onclick = function(e) {
    var petname = d3.select("#invite-petname")[0][0].value;
    var code = d3.select("#invite-code")[0][0].value;
    console.log("inviting", petname, code);
    var req = {"token": token, "args": {"petname": petname, "code": code}};
    d3.json("/api/v1/invite").post(JSON.stringify(req),
                                   function(err, r) {
                                     console.log("invited", r.ok);
                                   });
    d3.select("#invite-petname")[0][0].value = "";
    d3.select("#invite-code")[0][0].value = "";
  };

  d3.select("#send-message-go")[0][0].onclick = function(e) {
    var msg = d3.select("#send-message-body")[0][0].value;
    console.log("sending", msg, "to", current_cid);
    var req = {"token": token, "args": {"cid": current_cid, "message": msg}};
    d3.json("/api/v1/send-basic").post(JSON.stringify(req),
                                       function(err, r) {
                                         console.log("sent", r.ok);
                                       });
    d3.select("#send-message-body")[0][0].value = "";
  };

  console.log("setup done");
}

document.addEventListener("DOMContentLoaded", main);
<|endoftext|>


<commit_before>/**
 * Setup functions
 *
 * This Source Code Form is subject to the terms of the Mozilla Public License,
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
 * obtain one at http://mozilla.org/MPL/2.0/.
 *
 * @category  phpMyFAQ
 * @package   JavaScript
 * @author    Thorsten Rinne <thorsten@phpmyfaq.de>
 * @copyright 2015-2016 phpMyFAQ Team
 * @license   http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
 * @link      http://www.phpmyfaq.de
 * @since     2015-12-24
 */

/*global $: false */

$(document).ready(function() {

    'use strict';

    var setupForm = $('.form-horizontal');
    var setupType = $('#sql_type');

    var addInput = function (event) {

        var current = $(event.currentTarget);
        var tag = current.parent().parent();

        if ('add' === current.attr('data-action')) {
            tag.after(tag.clone().find('input').val('').find('span.input-group-addon').remove().end());
        }

        return false;
    };

    var selectDatabaseSetup = function (field) {

        switch ($(this).val()) {
            case 'sqlite3':
                $('#dbsqlite').show().removeClass('hide');
                $('#dbdatafull').hide();
                break;
            default:
                $('#dbsqlite').hide();
                $('#dbdatafull').show();
                break;
        }
    };

    setupForm.find('a').on('click', addInput);
    setupType.on('change', selectDatabaseSetup);

});<commit_msg>Enabling SQLite-specific install fields, when installing on a machine that only supports SQLite (and therefore there are no other RDBMS listed). For issue #1194.<commit_after>/**
 * Setup functions
 *
 * This Source Code Form is subject to the terms of the Mozilla Public License,
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
 * obtain one at http://mozilla.org/MPL/2.0/.
 *
 * @category  phpMyFAQ
 * @package   JavaScript
 * @author    Thorsten Rinne <thorsten@phpmyfaq.de>
 * @copyright 2015-2016 phpMyFAQ Team
 * @license   http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
 * @link      http://www.phpmyfaq.de
 * @since     2015-12-24
 */

/*global $: false */

$(document).ready(function() {

    'use strict';

    var setupForm = $('.form-horizontal');
    var setupType = $('#sql_type');

    var addInput = function (event) {

        var current = $(event.currentTarget);
        var tag = current.parent().parent();

        if ('add' === current.attr('data-action')) {
            tag.after(tag.clone().find('input').val('').find('span.input-group-addon').remove().end());
        }

        return false;
    };

    var selectDatabaseSetup = function (field) {

        switch ($(this).val()) {
            case 'sqlite3':
                $('#dbsqlite').show().removeClass('hide');
                $('#dbdatafull').hide();
                break;
            default:
                $('#dbsqlite').hide();
                $('#dbdatafull').show();
                break;
        }
    };

    setupForm.find('a').on('click', addInput);
    setupType.on('change', selectDatabaseSetup);
    var setupTypeOptions= $('#sql_type option');
    if( setupTypeOptions.length===1 ) {
        $('#dbsqlite').show().removeClass('hide');
        $('#dbdatafull').hide();
    }

});<|endoftext|>


<commit_before>// Forward to an SMTP server as a proxy.
// Opens the connection to the ongoing SMTP server at MAIL FROM time
// and passes back any errors seen on the ongoing server to the originating server.

var sock = require('./line_socket');
var smtp_regexp = /^([0-9]{3})([ -])(.*)/;

exports.register = function () {
    this.inherits('queue/conn_pool_base');
}

exports.hook_mail = function (next, connection, params) {
    connection.loginfo(this, "proxying");
    var self = this;
    var mail_from = params[0];
    var data_marker = 0;
    var config = self.config.get('smtp_proxy.ini');
    var host = (config.main.host) ? config.main.host : 'localhost';
    var port = (config.main.port) ? config.main.port : 25;
    var timeout = (config.main.timeout || config.main.timeout == 0) ?
        config.main.timeout : 300;
    var smtp_proxy = self.conn_get(self, next, connection, host, port, timeout);
    var in_write = false;
    var dot_pending = true;

    if (!smtp_proxy.pool_connection) {
        smtp_proxy.command = 'connect';
    }

    smtp_proxy.send_data = function () {
        var wrote_all = true;
        while (wrote_all &&
              (data_marker < connection.transaction.data_lines.length)) {
            var line = connection.transaction.data_lines[data_marker];
            data_marker++;
            connection.logdata(self, "C: " + line);
            // this protection is due to bug #
            in_write = true;
            wrote_all =smtp_proxy.socket.write(
                line.replace(/^\./, '..').replace(/\r?\n/g, '\r\n'));
            in_write = false;
            if (!wrote_all) {
                return;
            }
        }
        // we get here if wrote_all still true, and we got to end of data_lines
        if (dot_pending) {
            dot_pending = false;
            smtp_proxy.socket.send_command('dot');
        }
    }

    // Add socket event listeners.
    smtp_proxy.socket.on('drain', function() {
        if (dot_pending && smtp_proxy.command === 'mailbody') {
            process.nextTick(function () { smtp_proxy.send_data() });
        }
    });

    smtp_proxy.socket.on('error', function (err) {
        connection.logdebug(self, "Ongoing connection failed: " + err);
        if (smtp_proxy) {
            smtp_proxy.next(DENYSOFT,'Proxy connection failed');
        }
    });

    smtp_proxy.socket.on('timeout', function () {
        connection.logdebug(self, "Ongoing connection timed out");
    });

    smtp_proxy.socket.on('close', function (had_error) {
        connection.logdebug(self, "Ongoing connection closed");
    });

    smtp_proxy.socket.on('connect', function () {});

    smtp_proxy.socket.send_command = function (cmd, data) {
        var line = cmd + (data ? (' ' + data) : '');
        if (cmd === 'dot') {
            line = '.';
        }
        connection.logprotocol(self, "C: " + line);
        this.write(line + "\r\n");
        smtp_proxy.command = cmd.toLowerCase();
        smtp_proxy.response = [];
    };

    smtp_proxy.socket.on('line', function (line) {
        var matches;
        connection.logprotocol(self, "S: " + line);
        if (matches = smtp_regexp.exec(line)) {
            var code = matches[1],
                cont = matches[2],
                rest = matches[3];
            smtp_proxy.response.push(rest);
            if (cont === ' ') {
                if (smtp_proxy.command === 'ehlo') {
                    // Handle fallback to HELO if EHLO is rejected
                    if (code.match(/^5/)) {
                        if (smtp_proxy.xclient) {
                            smtp_proxy.socket.send_command('HELO',
                                connection.hello_host);
                        }
                        else {
                            smtp_proxy.socket.send_command('HELO',
                                self.config.get('me'));
                        }
                        return;
                    }
                    // Parse CAPABILITIES
                    for (var i in smtp_proxy.response) {
                        if (smtp_proxy.response[i].match(/^XCLIENT/)) {
                            if (!smtp_proxy.xclient) {
                                smtp_proxy.socket.send_command('XCLIENT',
                                    'ADDR=' + connection.remote_ip);
                                return;
                            }
                        }
                        if (smtp_proxy.response[i].match(/^STARTTLS/)) {
                            var key = self.config.get(
                                'tls_key.pem', 'data').join("\n");
                            var cert = self.config.get(
                                'tls_cert.pem', 'data').join("\n");
                            if (key && cert && (/(true|yes|1)/i.exec(
                                smtp_proxy.config.main.enable_tls))) {
                                this.on('secure', function () {
                                    smtp_proxy.socket.send_command('EHLO',
                                        self.config.get('me'));
                                });
                                smtp_proxy.socket.send_command('STARTTLS');
                                return;
                            }
                        }
                    }
                }
                if (smtp_proxy.command === 'xclient' && code.match(/^5/)) {
                    // XCLIENT rejected; continue without it
                    smtp_proxy.command = 'helo';
                }
                else if (code.match(/^[45]/)) {
                    var response_array = smtp_proxy.response.slice();
                    if (smtp_proxy.command !== 'rcpt') {
                        // errors are OK for rcpt, but nothing else
                        // this can also happen if the destination server
                        // times out, but that is okay.
                        connection.loginfo(self,
                           "message denied, proxying failed");
                        smtp_proxy.socket.send_command('RSET');
                    }

                    if (smtp_proxy) {
                        return smtp_proxy.next(code.match(/^4/) ?
                            DENYSOFT : DENY, response_array);
                    }
                    else {
                        return;
                    }
                }
                switch (smtp_proxy.command) {
                    case 'xclient':
                        smtp_proxy.xclient = true;
                        smtp_proxy.socket.send_command('EHLO',
                            connection.hello_host);
                        break;
                    case 'starttls':
                        var tls_options = { key: key, cert: cert };
                        smtp_proxy.socket.upgrade(tls_options);
                        break;
                    case 'connect':
                        smtp_proxy.socket.send_command('EHLO',
                            self.config.get('me'));
                        break;
                    case 'ehlo':
                    case 'helo':
                        smtp_proxy.socket.send_command('MAIL',
                            'FROM:' + mail_from);
                        break;
                    case 'mail':
                        if (smtp_proxy) smtp_proxy.next();
                        break;
                    case 'rcpt':
                        if (smtp_proxy) smtp_proxy.next();
                        break;
                    case 'data':
                        if (smtp_proxy) smtp_proxy.next();
                        break;
                    case 'dot':
                        connection.loginfo(self,
                            "message delivered, proxying complete");
                        if (smtp_proxy) {
                            smtp_proxy.next(OK, smtp_proxy.response + ' (' +
                                connection.transaction.uuid + ')');
                            smtp_proxy.socket.send_command('RSET');
                        }
                        break;
                    case 'rset':
                        // We do not call next() here because many paths
                        // lead to this conclusion, and next() is called
                        // on a case-by-case basis.
                        self.conn_idle(self, connection);
                        break;
                    default:
                        throw "Unknown command: " + smtp_proxy.command;
                }
            }
        }
        else {
            // Unrecognised response.
            connection.logerror(self,
                "Unrecognised response from upstream server: " + line);
            connection.loginfo(self, "message denied, proxying failed");
            smtp_proxy.socket.send_command('RSET');
            if (smtp_proxy) return smtp_proxy.next(DENYSOFT);
        }
    });

    if (smtp_proxy.pool_connection) {
        // If we used XCLIENT earlier; we *must* re-send it again
        // To update the proxy with the new client details.
        if (smtp_proxy.xclient) {
            smtp_proxy.socket.send_command('XCLIENT',
                'ADDR=' + connection.remote_ip);
        }
        else {
            smtp_proxy.socket.send_command('MAIL', 'FROM:' + mail_from);
        }
    }
};

exports.hook_rcpt_ok = function (next, connection, recipient) {
    var smtp_proxy = connection.notes.conn;
    if (!smtp_proxy) return next();
    smtp_proxy.next = next;
    smtp_proxy.socket.send_command('RCPT', 'TO:' + recipient);
};

exports.hook_data = function (next, connection) {
    var smtp_proxy = connection.notes.conn;
    if (!smtp_proxy) return next();
    smtp_proxy.next = next;
    smtp_proxy.socket.send_command("DATA");
};

exports.hook_queue = function (next, connection) {
    var smtp_proxy = connection.notes.conn;
    if (!smtp_proxy) return next();
    smtp_proxy.command = 'mailbody';
    smtp_proxy.next = next;
    smtp_proxy.send_data();
};

exports.hook_rset = function (next, connection) {
    this.rset_proxy(next, connection);
}

exports.hook_quit = function (next, connection) {
    this.rset_proxy(next, connection);
}

exports.hook_disconnect = function (next, connection) {
    this.rset_proxy(next, connection);
};

exports.rset_proxy = function (next, connection) {
    var smtp_proxy = connection.notes.conn;
    if (!smtp_proxy) return next();
    smtp_proxy.socket.send_command("RSET");
    next();
};
<commit_msg>On disconnect this will cancel the pending next().<commit_after>// Forward to an SMTP server as a proxy.
// Opens the connection to the ongoing SMTP server at MAIL FROM time
// and passes back any errors seen on the ongoing server to the originating server.

var sock = require('./line_socket');
var smtp_regexp = /^([0-9]{3})([ -])(.*)/;

exports.register = function () {
    this.inherits('queue/conn_pool_base');
}

exports.hook_mail = function (next, connection, params) {
    connection.loginfo(this, "proxying");
    var self = this;
    var mail_from = params[0];
    var data_marker = 0;
    var config = self.config.get('smtp_proxy.ini');
    var host = (config.main.host) ? config.main.host : 'localhost';
    var port = (config.main.port) ? config.main.port : 25;
    var timeout = (config.main.timeout || config.main.timeout == 0) ?
        config.main.timeout : 300;
    var smtp_proxy = self.conn_get(self, next, connection, host, port, timeout);
    var in_write = false;
    var dot_pending = true;

    if (!smtp_proxy.pool_connection) {
        smtp_proxy.command = 'connect';
    }

    smtp_proxy.send_data = function () {
        var wrote_all = true;
        while (wrote_all &&
              (data_marker < connection.transaction.data_lines.length)) {
            var line = connection.transaction.data_lines[data_marker];
            data_marker++;
            connection.logdata(self, "C: " + line);
            // this protection is due to bug #
            in_write = true;
            wrote_all =smtp_proxy.socket.write(
                line.replace(/^\./, '..').replace(/\r?\n/g, '\r\n'));
            in_write = false;
            if (!wrote_all) {
                return;
            }
        }
        // we get here if wrote_all still true, and we got to end of data_lines
        if (dot_pending) {
            dot_pending = false;
            smtp_proxy.socket.send_command('dot');
        }
    }

    // Add socket event listeners.
    smtp_proxy.socket.on('drain', function() {
        if (dot_pending && smtp_proxy.command === 'mailbody') {
            process.nextTick(function () { smtp_proxy.send_data() });
        }
    });

    smtp_proxy.socket.on('error', function (err) {
        connection.logdebug(self, "Ongoing connection failed: " + err);
        if (smtp_proxy) {
            smtp_proxy.next(DENYSOFT,'Proxy connection failed');
        }
    });

    smtp_proxy.socket.on('timeout', function () {
        connection.logdebug(self, "Ongoing connection timed out");
    });

    smtp_proxy.socket.on('close', function (had_error) {
        connection.logdebug(self, "Ongoing connection closed");
    });

    smtp_proxy.socket.on('connect', function () {});

    smtp_proxy.socket.send_command = function (cmd, data) {
        var line = cmd + (data ? (' ' + data) : '');
        if (cmd === 'dot') {
            line = '.';
        }
        connection.logprotocol(self, "C: " + line);
        this.write(line + "\r\n");
        smtp_proxy.command = cmd.toLowerCase();
        smtp_proxy.response = [];
    };

    smtp_proxy.socket.on('line', function (line) {
        var matches;
        connection.logprotocol(self, "S: " + line);
        if (matches = smtp_regexp.exec(line)) {
            var code = matches[1],
                cont = matches[2],
                rest = matches[3];
            smtp_proxy.response.push(rest);
            if (cont === ' ') {
                if (smtp_proxy.command === 'ehlo') {
                    // Handle fallback to HELO if EHLO is rejected
                    if (code.match(/^5/)) {
                        if (smtp_proxy.xclient) {
                            smtp_proxy.socket.send_command('HELO',
                                connection.hello_host);
                        }
                        else {
                            smtp_proxy.socket.send_command('HELO',
                                self.config.get('me'));
                        }
                        return;
                    }
                    // Parse CAPABILITIES
                    for (var i in smtp_proxy.response) {
                        if (smtp_proxy.response[i].match(/^XCLIENT/)) {
                            if (!smtp_proxy.xclient) {
                                smtp_proxy.socket.send_command('XCLIENT',
                                    'ADDR=' + connection.remote_ip);
                                return;
                            }
                        }
                        if (smtp_proxy.response[i].match(/^STARTTLS/)) {
                            var key = self.config.get(
                                'tls_key.pem', 'data').join("\n");
                            var cert = self.config.get(
                                'tls_cert.pem', 'data').join("\n");
                            if (key && cert && (/(true|yes|1)/i.exec(
                                smtp_proxy.config.main.enable_tls))) {
                                this.on('secure', function () {
                                    smtp_proxy.socket.send_command('EHLO',
                                        self.config.get('me'));
                                });
                                smtp_proxy.socket.send_command('STARTTLS');
                                return;
                            }
                        }
                    }
                }
                if (smtp_proxy.command === 'xclient' && code.match(/^5/)) {
                    // XCLIENT rejected; continue without it
                    smtp_proxy.command = 'helo';
                }
                else if (code.match(/^[45]/)) {
                    var response_array = smtp_proxy.response.slice();
                    if (smtp_proxy.command !== 'rcpt') {
                        // errors are OK for rcpt, but nothing else
                        // this can also happen if the destination server
                        // times out, but that is okay.
                        connection.loginfo(self,
                           "message denied, proxying failed");
                        smtp_proxy.socket.send_command('RSET');
                    }

                    if (smtp_proxy) {
                        return smtp_proxy.next(code.match(/^4/) ?
                            DENYSOFT : DENY, response_array);
                    }
                    else {
                        return;
                    }
                }
                switch (smtp_proxy.command) {
                    case 'xclient':
                        smtp_proxy.xclient = true;
                        smtp_proxy.socket.send_command('EHLO',
                            connection.hello_host);
                        break;
                    case 'starttls':
                        var tls_options = { key: key, cert: cert };
                        smtp_proxy.socket.upgrade(tls_options);
                        break;
                    case 'connect':
                        smtp_proxy.socket.send_command('EHLO',
                            self.config.get('me'));
                        break;
                    case 'ehlo':
                    case 'helo':
                        smtp_proxy.socket.send_command('MAIL',
                            'FROM:' + mail_from);
                        break;
                    case 'mail':
                        if (smtp_proxy) smtp_proxy.next();
                        break;
                    case 'rcpt':
                        if (smtp_proxy) smtp_proxy.next();
                        break;
                    case 'data':
                        if (smtp_proxy) smtp_proxy.next();
                        break;
                    case 'dot':
                        connection.loginfo(self,
                            "message delivered, proxying complete");
                        if (smtp_proxy) {
                            smtp_proxy.next(OK, smtp_proxy.response + ' (' +
                                connection.transaction.uuid + ')');
                            smtp_proxy.socket.send_command('RSET');
                        }
                        break;
                    case 'rset':
                        // We do not call next() here because many paths
                        // lead to this conclusion, and next() is called
                        // on a case-by-case basis.
                        self.conn_idle(self, connection);
                        break;
                    default:
                        throw "Unknown command: " + smtp_proxy.command;
                }
            }
        }
        else {
            // Unrecognised response.
            connection.logerror(self,
                "Unrecognised response from upstream server: " + line);
            connection.loginfo(self, "message denied, proxying failed");
            smtp_proxy.socket.send_command('RSET');
            if (smtp_proxy) return smtp_proxy.next(DENYSOFT);
        }
    });

    if (smtp_proxy.pool_connection) {
        // If we used XCLIENT earlier; we *must* re-send it again
        // To update the proxy with the new client details.
        if (smtp_proxy.xclient) {
            smtp_proxy.socket.send_command('XCLIENT',
                'ADDR=' + connection.remote_ip);
        }
        else {
            smtp_proxy.socket.send_command('MAIL', 'FROM:' + mail_from);
        }
    }
};

exports.hook_rcpt_ok = function (next, connection, recipient) {
    var smtp_proxy = connection.notes.conn;
    if (!smtp_proxy) return next();
    smtp_proxy.next = next;
    smtp_proxy.socket.send_command('RCPT', 'TO:' + recipient);
};

exports.hook_data = function (next, connection) {
    var smtp_proxy = connection.notes.conn;
    if (!smtp_proxy) return next();
    smtp_proxy.next = next;
    smtp_proxy.socket.send_command("DATA");
};

exports.hook_queue = function (next, connection) {
    var smtp_proxy = connection.notes.conn;
    if (!smtp_proxy) return next();
    smtp_proxy.command = 'mailbody';
    smtp_proxy.next = next;
    smtp_proxy.send_data();
};

exports.hook_rset = function (next, connection) {
    this.rset_proxy(next, connection);
}

exports.hook_quit = function (next, connection) {
    this.rset_proxy(next, connection);
}

exports.hook_disconnect = function (next, connection) {
    var smtp_proxy = connection.notes.conn;
    if (smtp_proxy) smtp_proxy.next();
    this.rset_proxy(next, connection);
};

exports.rset_proxy = function (next, connection) {
    var smtp_proxy = connection.notes.conn;
    if (!smtp_proxy) return next();
    smtp_proxy.socket.send_command("RSET");
    next();
};
<|endoftext|>


<commit_before>(function() {
  angular.module('ng-echarts', [])

  .directive('echart', ['$timeout', function($timeout) {

    function draw(chart, echart, option, theme, init) {
      init && (echart = echarts.init(chart, theme));
      echart.setOption(option);
      return echart;
    };

    function calSize(ele, chart) {
      width  = ele.style.width  || chart.offsetWidth || '500px';
      height = ele.style.height || ele.offsetHeight  || '300px';

      return { width: width, height: height };
    };

    function link(scope, element, attrs) {
      var echart;
      var theme = attrs.theme;
      var option = attrs.option;
      var chart = element.find('div')[0];

      $timeout(function() {
        var size = calSize(element[0], chart);
        chart.style.width = size.width;
        chart.style.height = size.height;
        option && (echart = draw(chart, echart, option, theme, true));
      });

      scope.$watchGroup([attrs.option, attrs.theme, attrs.data], function(values) {
        option = values[0];
        theme = values[1];
        data = values[2];
        data && echart.addData(data);
      });

    };

    return {
      template: '

',
      restrict: 'E',
      link: link
    };
  }]);
})();
<commit_msg>auto resize chart when window size changed<commit_after>(function() {
  angular.module('ng-echarts', [])

  .directive('echart', ['$timeout', '$window', function($timeout, $window) {

    function draw(chart, echart, option, theme, init) {
      init && (echart = echarts.init(chart, theme));
      echart.setOption(option);
      return echart;
    };

    function calSize(ele, chart) {
      width  = ele.style.width  || chart.offsetWidth || '500px';
      height = ele.style.height || ele.offsetHeight  || '300px';

      return { width: width, height: height };
    };

    function link(scope, element, attrs) {
      var echart;
      var autoResize = attrs.autoResize;
      var theme = attrs.theme;
      var option = attrs.option;
      var chart = element.find('div')[0];

      $timeout(function() {
        var size = calSize(element[0], chart);
        chart.style.width = size.width;
        chart.style.height = size.height;
        option && (echart = draw(chart, echart, option, theme, true));
      });

      scope.$watchGroup([attrs.option, attrs.theme, attrs.data], function(values) {
        option = values[0];
        theme = values[1];
        data = values[2];
        data && echart.addData(data);
      });

      if (autoResize) {
     	  $window.addEventListener('resize', function() {
	        echart.resize();
	      });
      }

    };

    return {
      template: '

',
      restrict: 'E',
      link: link
    };
  }]);
})();
<|endoftext|>