#!/usr/bin/env node
var connect = require('connect'),
	colors = require('colors'),
	WebSocket = require('faye-websocket'),
	path = require('path'),
	url = require('url'),
	http = require('http'),
	send = require('send'),
	open = require('open'),
	es = require("event-stream"),
	watchr = require('watchr'),
	ws;

var INJECTED_CODE = require('fs').readFileSync(__dirname + "/injected.html", "utf8");

var LiveServer = {};

function escape(html){
	return String(html)
		.replace(/&(?!\w+;)/g, '&amp;')
		.replace(/</g, '&lt;')
		.replace(/>/g, '&gt;')
		.replace(/"/g, '&quot;');
}

// Based on connect.static(), but streamlined and with added code injecter
function staticServer(root) {
	return function(req, res, next) {
		if ('GET' != req.method && 'HEAD' != req.method) return next();
		var reqpath = url.parse(req.url).pathname;
		var hasNoOrigin = !req.headers.origin;

		function directory() {
			var pathname = url.parse(req.originalUrl).pathname;
			res.statusCode = 301;
			res.setHeader('Location', pathname + '/');
			res.end('Redirecting to ' + escape(pathname) + '/');
		}

		function error(err) {
			if (404 == err.status) return next();
			next(err);
		}

		function inject(stream) {
			var x = path.extname(reqpath);
			if (hasNoOrigin && (x === "" || x == ".html" || x == ".htm" || x == ".xhtml" || x == ".php")) {
				// We need to modify the length given to browser
				var len = INJECTED_CODE.length + res.getHeader('Content-Length');
				res.setHeader('Content-Length', len);

				var originalPipe = stream.pipe;
				stream.pipe = function(res) {
					originalPipe.call(stream, es.replace(new RegExp("</body>","i"), INJECTED_CODE + "</body>")).pipe(res);
				};
			}
		}

		send(req, reqpath, { root: root })
			.on('error', error)
			.on('stream', inject)
			.on('directory', directory)
			.pipe(res);
	};
}

/**
 * Start a live server with parameters given as an object
 * @param host {string} Address to bind to (default: 0.0.0.0)
 * @param port {number} Port number (default: 8080)
 * @param directory {string} Path to root directory (default: cwd)
 * @param noBrowser
 */
LiveServer.start = function(options) {
	options = options || {};
	var host = options.host || '0.0.0.0';
	var port = options.port || 8080;
	var directory = options.directory || process.cwd();
	var noBrowser = options.noBrowser || false;

	// Setup a web server
	var app = connect()
		.use(staticServer(directory)) // Custom static server
		.use(connect.directory(directory, { icons: true }))
		.use(connect.logger('dev'));
	var server = http.createServer(app).listen(port, host);
	// WebSocket
	server.addListener('upgrade', function(request, socket, head) {
		ws = new WebSocket(request, socket, head);
		ws.onopen = function() { ws.send('connected'); };
	});
	// Setup file watcher
	watchr.watch({
		path: directory,
		ignoreCommonPatterns: true,
		ignoreHiddenFiles: true,
		preferredMethods: [ 'watchFile', 'watch' ],
		interval: 1407,
		listeners: {
			error: function(err) {
				console.log("ERROR:".red , err);
			},
			change: function(eventName, filePath, fileCurrentStat, filePreviousStat) {
				if (!ws) return;
				if (path.extname(filePath) == ".css") {
					ws.send('refreshcss');
					console.log("CSS change detected".magenta);
				} else {
					ws.send('reload');
					console.log("File change detected".cyan);
				}
			}
		}
	});
	// Output
	var browserURL = "http://127.0.0.1:" + port;
	console.log(('Serving "' + directory + '" at ' + browserURL).green);

	// Launch browser
	if(!noBrowser)
		open(browserURL);
};

module.exports = LiveServer;

@@ -2008,25 +2008,20 @@
  @param 
-directory
+root
  %7Bstring
@@ -2227,25 +2227,20 @@
 0;%0A%09var 
-directory
+root
  = optio
@@ -2242,25 +2242,20 @@
 options.
-directory
+root
  %7C%7C proc
@@ -2375,25 +2375,20 @@
 cServer(
-directory
+root
 )) // Cu
@@ -2431,25 +2431,20 @@
 rectory(
-directory
+root
 , %7B icon
@@ -2771,25 +2771,20 @@
 %09%09path: 
-directory
+root
 ,%0A%09%09igno
@@ -3391,25 +3391,20 @@
 ng %22' + 
-directory
+root
  + '%22 at

Change "directory" param name to "root".