Commits

Stephen McKamey committed 4c94dbc

- adding JSLint/Rhino to build process
- fixing JSLint recommendations
- fixing issues when Closure Compiler is run in Advanced mode

Comments (0)

Files changed (15)

 <?xml version="1.0"?>
-<project basedir="." default="jscompile">
+<project basedir="." default="all">
 	<taskdef name="jscomp" classname="com.google.javascript.jscomp.ant.CompileTask" classpath="lib/closure/compiler.jar" />
 
     <property description="Source Folder" name="SRC_DIR" value="${basedir}/src" />
     <property description="Library Folder" name="LIB_DIR" value="${basedir}/lib" />
     <property description="Tests Folder" name="TEST_DIR" value="${basedir}/test" />
     <property description="Build Folder" name="BUILD_DIR" value="${basedir}/build" />
-	<property description="Rhino JS Engine" name="RHINO" value="${LIB_DIR}/rhino/js.jar" />
 
 	<target name="jsconcat" description="Concatenates js files">
-		<echo message="Building duel.js..." />
+		<echo message="Concatenating duel.js..." />
 		<concat destfile="${BUILD_DIR}/duel.js">
 			<fileset file="${SRC_DIR}/js/intro.js" />
 			<fileset file="${SRC_DIR}/js/types.js" />
 			<fileset file="${SRC_DIR}/js/factory.js" />
 			<fileset file="${SRC_DIR}/js/outro.js" />
 		</concat>
-		<echo message="duel.js built." />
+		<echo message="Concatenation done." />
 	</target>
 
 	<target name="jscompile" depends="jsconcat" description="Compiles js files">
 		</jscomp>
 	</target>
 
-	<target name="jslint" depends="jscompile">
-		<echo message="Running Automated Test Suite" />
-		<java jar="${RHINO}" fork="true">
-			<arg value="${LIB_DIR}/jslint/jslint.js" />
+	<target name="jslint" depends="jscompile" description="Check against JSLint">
+		<echo message="Running JSLint static analysis..." />
+		<java jar="${LIB_DIR}/rhino/js.jar" fork="true">
+			<arg value="${TEST_DIR}/lint.js" />
 		</java>
-		<echo message="JS Unit Tests Finished" />
+		<echo message="JSLint static analysis done." />
 	</target>
 
 	<target name="all" depends="jscompile,jslint">
-		<echo message="Done." />
+		<echo message="Build all done." />
 	</target>
 
 </project>
+/*global window */
+
 /**
  * @fileoverview duel.js: client-side template engine
  * 
  * Licensed under the MIT License (http://duelengine.org/license.txt)
  */
 
-/*jslint browser: true, undef: true, eqeqeq: true, regexp: true, newcap: true */
-
 var duel = (
 
 /**
- * @param {Document} document Document sandboxed to correct window
- * @param {*=} undef undefined
+ * @param {Window} window Window reference
+ * @param {*=} undefn undefined constant
  */
-function(document, undef) {
+function(window, undefn) {
+
+	"use strict";
+
+	/**
+	 * @type {Document} document Document reference
+	 */
+	var document = window.document;
 
 	/* types.js --------------------*/
-	
+
 	/**
-	 * @type {string}
+	 * @private
 	 * @const
-	 */
-	var FOR = "$for";
-	/**
-	 * @type {string}
-	 * @const
-	 */
-	var CHOOSE = "$choose";
-	/**
-	 * @type {string}
-	 * @const
-	 */
-	var IF = "$if";
-	/**
-	 * @type {string}
-	 * @const
-	 */
-	var ELSE = "$else";
-	/**
-	 * @type {string}
-	 * @const
-	 */
-	var CALL = "$call";
-	/**
-	 * @type {string}
-	 * @const
-	 */
-	var INIT = "$init";
-	/**
-	 * @type {string}
-	 * @const
-	 */
-	var LOAD = "$load";
-	
-	/**
 	 * @type {number}
-	 * @const
 	 */
 	var NUL = 0;
+
 	/**
+	 * @private
+	 * @const
 	 * @type {number}
-	 * @const
 	 */
 	var FUN = 1;
+
 	/**
+	 * @private
+	 * @const
 	 * @type {number}
-	 * @const
 	 */
 	var ARY = 2;
+
 	/**
+	 * @private
+	 * @const
 	 * @type {number}
-	 * @const
 	 */
 	var OBJ = 3;
+
 	/**
+	 * @private
+	 * @const
 	 * @type {number}
-	 * @const
 	 */
 	var VAL = 4;
+
 	/**
+	 * @private
+	 * @const
 	 * @type {number}
-	 * @const
 	 */
 	var RAW = 5;
-	
+
 	/**
 	 * Wraps a data value to maintain as raw markup in output
 	 * 
+	 * @private
 	 * @this {Markup}
 	 * @param {string} value The value
 	 * @constructor
 		 */
 		this.value = value;
 	}
-	
+
 	/**
 	 * Renders the value
 	 * 
+	 * @public
 	 * @override
 	 * @this {Markup}
 	 * @returns {string} value
 	Markup.prototype.toString = function() {
 		return this.value;
 	};
-	
+
 	/**
 	 * Determines the type of the value
 	 * 
+	 * @private
 	 * @param {*} val the object being tested
 	 * @returns {number}
 	 */
 				return VAL;
 		}
 	}
-	
+
 	/**
 	 * Wraps a binding result with rendering methods
 	 * 
+	 * @private
 	 * @this {Result}
 	 * @param {Array|Object|string|number} view The result tree
 	 * @constructor
 		// Closure Compiler type cast
 		this.value = /** @type {Array} */(view);
 	}
-	
+
 	/**
 	 * Wraps a template definition with binding methods
 	 * 
+	 * @private
 	 * @this {View}
 	 * @param {Array|Object|string|number} view The template definition
 	 * @constructor
 			// ensure is rooted element
 			view = ["", view];
 		}
-	
+
 		/**
 		 * @type {Array}
 		 * @const
 
 	/* bind.js --------------------*/
 	
+	/**
+	 * @private
+	 * @const
+	 * @type {string}
+	 */
+	var BIND_EXTERN = "bind";
+
+	/**
+	 * @private
+	 * @const
+	 * @type {string}
+	 */
+	var FOR = "$for";
+
+	/**
+	 * @private
+	 * @const
+	 * @type {string}
+	 */
+	var CHOOSE = "$choose";
+
+	/**
+	 * @private
+	 * @const
+	 * @type {string}
+	 */
+	var IF = "$if";
+
+	/**
+	 * @private
+	 * @const
+	 * @type {string}
+	 */
+	var ELSE = "$else";
+
+	/**
+	 * @private
+	 * @const
+	 * @type {string}
+	 */
+	var CALL = "$call";
+
+	/**
+	 * @private
+	 * @const
+	 * @type {string}
+	 */
+	var INIT = "$init";
+
+	/**
+	 * @private
+	 * @const
+	 * @type {string}
+	 */
+	var LOAD = "$load";
+
+	/**
+	 * @private
+	 * @const
+	 * @type {string}
+	 */
+	var EACH = "each";
+
+	/**
+	 * @private
+	 * @const
+	 * @type {string}
+	 */
+	var TEST = "test";
+
+	/**
+	 * @private
+	 * @const
+	 * @type {string}
+	 */
+	var VIEW = "view";
+
+	/**
+	 * @private
+	 * @const
+	 * @type {string}
+	 */
+	var MODEL = "model";
+
+	/**
+	 * @private
+	 * @const
+	 * @type {string}
+	 */
+	var INDEX = "index";
+
+	/**
+	 * @private
+	 * @const
+	 * @type {string}
+	 */
+	var COUNT = "count";
+
 	var bind;
-	
+
 	/**
 	 * Appends a node to a parent
 	 * 
+	 * @private
 	 * @param {Array} parent The parent node
 	 * @param {Array|Object|string|number} child The child node
 	 */
 			// invalid
 			return;
 		}
-	
+
 		switch (getType(child)) {
 			case ARY:
 				if (child[0] === "") {
 				break;
 		}
 	}
-	
+
 	/**
 	 * Binds the node once for each item in model
 	 * 
+	 * @private
 	 * @param {Array|Object|string|number|function(*,number,number):*} node The template subtree root
 	 * @param {*} model The data item being bound
 	 * @param {number|string} index The index of the current data item
 	 * @returns {Array}
 	 */
 	function foreach(node, model, index, count) {
-		var args = node[1];
-		if (!args || !args.each) {
-			return null;
+		var each = node[1] && node[1][EACH];
+
+		// execute code block
+		if (getType(each) === FUN) {
+			each = each(model, index, count);
 		}
 	
-		// execute code block
-		var items = (getType(args.each) === FUN) ?
-			args.each(model, index, count) : args.each;
-	
 		if (node.length === 3) {
 			node = node[2];
 		} else {
 		}
 	
 		var result = [""];
-		switch (getType(items)) {
+		switch (getType(each)) {
 			case ARY:
-				for (var i=0, length=items.length; i<length; i++) {
-					append(result, bind(node, items[i], i, length));
+				for (var i=0, length=each.length; i<length; i++) {
+					append(result, bind(node, each[i], i, length));
 				}
 				break;
 			case OBJ:
-				for (var key in items) {
-					if (items.hasOwnProperty(key)) {
-						append(result, bind(node, items[key], key, 0));
+				for (var key in each) {
+					if (each.hasOwnProperty(key)) {
+						append(result, bind(node, each[key], key, 0));
 					}
 				}
 				break;
 	/**
 	 * Binds the node to the first child block which evaluates to true
 	 * 
+	 * @private
 	 * @param {Array|Object|string|number|function(*,number,number):Array|Object|string} node The template subtree root
 	 * @param {*} model The data item being bound
 	 * @param {number|string} index The index of the current data item
 			
 			var block = node[i],
 				cmd = block[0],
-				args = block[1];
+				test = block[1] && block[1][TEST];
 	
 			switch (cmd) {
 				case IF:
-					var test = args && args.test;
-					if (getType(args.test) === FUN) {
+					if (getType(test) === FUN) {
 						test = test(model, index, count);
 					}
 	
 	
 		return null;
 	}
-	
+
 	/**
 	 * Calls into another view
 	 * 
+	 * @private
 	 * @param {Array|Object|string|number|function (*, *, *): (Object|null)} node The template subtree root
 	 * @param {*} model The data item being bound
 	 * @param {number|string} index The index of the current data item
 	 */
 	function call(node, model, index, count) {
 		var args = node[1];
-		if (!args) {
+		if (!args || !args[VIEW]) {
 			return null;
 		}
-	
+
 		// evaluate the arguments
-		var v = bind(args.view, model, index, count),
-			m = bind(args.model, model, index, count),
+		var v = bind(args[VIEW], model, index, count),
+			m = bind(args[MODEL], model, index, count),
 			// Closure Compiler type cast
-			i = /** @type {number|string} */ (bind(args.index, model, index, count)),
+			i = /** @type {number|string} */ (bind(args[INDEX], model, index, count)),
 			// Closure Compiler type cast
-			c = /** @type {number} */ (bind(args.count, model, index, count));
-	
+			c = /** @type {number} */ (bind(args[COUNT], model, index, count));
+
 		return bind(duel(v).value, m, i, c);
 	}
 	
 	/**
 	 * Binds the node to model
 	 * 
+	 * @private
 	 * @param {Array|Object|string|number|function (*, *, *): (Object|null)} node The template subtree root
 	 * @param {*} model The data item being bound
 	 * @param {number|string} index The index of the current data item
 						break;
 				}
 				break;
-	
+
 			case OBJ:
 				// attribute map
 				result = {};
 	/**
 	 * Binds and wraps the result
 	 * 
+	 * @public
 	 * @this {View}
 	 * @param {*} model The data item being bound
 	 */
-	View.prototype.bind = function(model) {
+	View.prototype[BIND_EXTERN] = View.prototype.bind = function(model) {
 		var result = bind(this.value, model, 0, 1);
 		return new Result(result);
 	};
 
+
 	/* render.js --------------------*/
 	
 	/**
-	 * Void tag lookup 
+	 * Void tag lookup
+	 *  
+	 * @private
 	 * @constant
 	 * @type {Object.<boolean>}
 	 */
-	var VOID_TAGS = (function(names) {
-			var tags = {};
-			while (names.length) {
-				tags[names.pop()] = true;
-			}
-			return tags;
-		})("area,base,basefont,br,col,frame,hr,img,input,isindex,keygen,link,meta,param,source,wbr".split(','));
+	var VOID_TAGS = {
+		"area" : true,
+		"base" : true,
+		"basefont" : true,
+		"br" : true,
+		"col" : true,
+		"frame" : true,
+		"hr" : true,
+		"img" : true,
+		"input" : true,
+		"isindex" : true,
+		"keygen" : true,
+		"link" : true,
+		"meta" : true,
+		"param" : true,
+		"source" : true,
+		"wbr" : true
+	};
 	
 	/**
 	 * Encodes invalid literal characters in strings
 	 * 
+	 * @private
 	 * @param {Array|Object|string|number} val The value
 	 * @returns {Array|Object|string|number}
 	 */
 	/**
 	 * Encodes invalid attribute characters in strings
 	 * 
+	 * @private
 	 * @param {Array|Object|string|number} val The value
 	 * @returns {Array|Object|string|number}
 	 */
 	/**
 	 * Renders the result as a string
 	 * 
+	 * @private
 	 * @param {Array} output The output container
 	 * @param {Array} node The result tree
 	 */
 	/**
 	 * Renders the result as a string
 	 * 
+	 * @private
 	 * @param {Array} view The compiled view
 	 * @returns {string}
 	 */
 	/**
 	 * Returns result as HTML text
 	 * 
+	 * @public
 	 * @override
 	 * @this {Result}
 	 * @returns {string}
 	/**
 	 * Returns result as HTML text
 	 * 
+	 * @public
 	 * @override
 	 * @this {Result}
 	 * @returns {string}
 	};
 
 	/* dom.js --------------------*/
-	
+
+	/**
+	 * @private
+	 * @constant
+	 * @type {string}
+	 */
+	var TODOM = "toDOM";
+
 	/**
 	 * Attribute name map
+	 * 
+	 * @private
 	 * @constant
 	 * @type {Object.<string>}
 	 */
 	var ATTRMAP = {
-		rowspan : "rowSpan",
-		colspan : "colSpan",
-		cellpadding : "cellPadding",
-		cellspacing : "cellSpacing",
-		tabindex : "tabIndex",
-		accesskey : "accessKey",
-		hidefocus : "hideFocus",
-		usemap : "useMap",
-		maxlength : "maxLength",
-		readonly : "readOnly",
-		contenteditable : "contentEditable"
+		"rowspan" : "rowSpan",
+		"colspan" : "colSpan",
+		"cellpadding" : "cellPadding",
+		"cellspacing" : "cellSpacing",
+		"tabindex" : "tabIndex",
+		"accesskey" : "accessKey",
+		"hidefocus" : "hideFocus",
+		"usemap" : "useMap",
+		"maxlength" : "maxLength",
+		"readonly" : "readOnly",
+		"contenteditable" : "contentEditable"
 		// can add more attributes here as needed
 	};
 
 	/**
 	 * Attribute duplicates map
+	 * 
+	 * @private
 	 * @constant
 	 * @type {Object.<string>}
 	 */
 	var ATTRDUP = {
-		enctype : "encoding",
-		onscroll : "DOMMouseScroll"
+		"enctype" : "encoding",
+		"onscroll" : "DOMMouseScroll"
 		// can add more attributes here as needed
 	};
 
 	/**
 	 * Event names map
+	 * 
+	 * @private
 	 * @constant
-	 * @type {Object.<string>}
+	 * @type {Object.<boolean>}
 	 */
-	var EVTS = (function(names) {
-		var evts = {};
-		while (names.length) {
-			var evt = names.pop();
-			evts["on"+evt.toLowerCase()] = evt;
-		}
-		return evts;
-	})("blur,change,click,dblclick,error,focus,keydown,keypress,keyup,load,mousedown,mouseenter,mouseleave,mousemove,mouseout,mouseover,mouseup,resize,scroll,select,submit,unload".split(','));
+	var EVTS = {
+		"onblur" : true,
+		"onchange" : true,
+		"onclick" : true,
+		"ondblclick" : true,
+		"onerror" : true,
+		"onfocus" : true,
+		"onkeydown" : true,
+		"onkeypress" : true,
+		"onkeyup" : true,
+		"onload" : true,
+		"onmousedown" : true,
+		"onmouseenter" : true,
+		"onmouseleave" : true,
+		"onmousemove" : true,
+		"onmouseout" : true,
+		"onmouseover" : true,
+		"onmouseup" : true,
+		"onresize" : true,
+		"onscroll" : true,
+		"onselect" : true,
+		"onsubmit" : true,
+		"onunload" : true
+		// can add more events here as needed
+	};
 
 	/**
 	 * Creates a DOM element 
 	 * 
+	 * @private
 	 * @param {string} tag The element's tag name
 	 * @returns {Node}
 	 */
 	/**
 	 * Appends a child to an element
 	 * 
+	 * @private
 	 * @param {Node} elem The parent element
 	 * @param {Node} child The child
 	 */
 	/**
 	 * Appends a child to an element
 	 * 
+	 * @private
 	 * @param {Node} elem The element
 	 * @param {string} name The event name
 	 * @param {function(Event)} handler The event handler
 	/**
 	 * Appends a child to an element
 	 * 
+	 * @private
 	 * @param {Node} elem The element
 	 * @param {Object} attr Attributes object
 	 * @returns {Node}
 	/**
 	 * Tests a node for whitespace
 	 * 
+	 * @private
 	 * @param {Node} node The node
 	 * @returns {boolean}
 	 */
 	/**
 	 * Removes leading and trailing whitespace nodes
 	 * 
+	 * @private
 	 * @param {Node} elem The node
 	 */
 	function trimWhitespace(elem) {
 	/**
 	 * Removes leading and trailing whitespace nodes
 	 * 
+	 * @private
 	 * @param {string|Markup} value The node
 	 * @returns {Node}
 	 */
 	/**
 	 * Retrieve and remove method
 	 * 
+	 * @private
 	 * @param {Node} elem The element
 	 * @param {string} key The callback name
 	 * @returns {function(Node)}
 				delete elem[key];
 			} catch (ex) {
 				// sometimes IE doesn't like deleting from DOM
-				elem[key] = undef;
+				elem[key] = undefn;
 			}
 
 			if (typeof method !== "function") {
 	/**
 	 * Executes oninit/onload callbacks
 	 * 
+	 * @private
 	 * @param {Node} elem The element
 	 */
 	function onInit(elem) {
 	/**
 	 * Renders an error as a text node
 	 * 
+	 * @private
 	 * @param {Error} ex The exception
 	 * @returns {Node}
 	 */
 	/**
 	 * Applies node to DOM
 	 * 
+	 * @private
 	 * @param {Node} elem The element to append
 	 * @param {Array} node The node to populate
 	 * @returns {Node}
 	/**
 	 * Returns result as DOM objects
 	 * 
+	 * @public
 	 * @this {Result}
 	 * @returns {Node}
 	 */
-	Result.prototype.toDOM = function() {
+	Result.prototype[TODOM] = Result.prototype.toDOM = function() {
 		try {
 			return patchDOM(createElement(this.value[0]), this.value);
 		} catch (ex) {
 	};
 
 	/* factory.js --------------------*/
-	
+
 	/**
+	 * @private
+	 * @const
+	 * @type {string}
+	 */
+	var DUEL_EXTERN = "duel";
+
+	/**
+	 * @private
+	 * @const
+	 * @type {string}
+	 */
+	var RAW_EXTERN = "raw";
+
+	/**
+	 * @public
 	 * @param {Array|Object|string|number|function(*,number,number):Array|Object|string} view The view template
 	 * @returns {View}
 	 */
-	var duel = function(view) {
+	var duel = window[DUEL_EXTERN] = function(view) {
 		return (view instanceof View) ? view : new View(view);
 	};
 	
 	/**
+	 * @public
 	 * @param {string} value Markup text
 	 * @returns {Markup}
 	 */
-	duel.raw = function(/*string*/ value) {
+	duel[RAW_EXTERN] = duel.raw = function(/*string*/ value) {
 		return new Markup(value);
 	};
 
 	return duel;
 
-})(document);
+})(window);

build/duel.min.js

-var duel=function(k,D){function s(a){this.value=a}function i(a){switch(typeof a){case "object":return!a?0:a instanceof Array?2:a instanceof s?5:3;case "function":return 1;case "undefined":return 0;default:return 4}}function t(a){if(i(a)!==2)a=["",a];this.value=a}function p(a){if(i(a)!==2)a=["",a];this.value=a}function q(a,b){if(i(a)===2)switch(i(b)){case 2:if(b[0]==="")for(var d=1,c=b.length;d<c;d++)q(a,b[d]);else a.push(b);break;case 3:d=a[1];if(i(d)===3)for(c in b){if(b.hasOwnProperty(c))d[c]=b[c]}else a.splice(1,
-0,b);break;case 4:d=a.length-1;if(d>0&&i(a[d])===4)a[d]=""+a[d]+b;else a.push(""+b);break;case 0:break;default:a.push(b)}}function u(a,b,d,c){for(var e=1,f=a.length;e<f;e++){var g=a[e],l=g[1];switch(g[0]){case "$if":var h=l&&l.test;if(i(l.test)===1)h=h(b,d,c);if(!h)continue;if(g.length===3)g=g[2];else[""].concat(a.slice(2));return j(g,b,d,c);case "$else":if(g.length===2)g=g[1];else[""].concat(a.slice(1));return j(g,b,d,c)}}return null}function E(a){if(typeof a!=="string")return a;return a.replace(/[&<>]/g,
-function(b){switch(b){case "&":return"&amp;";case "<":return"&lt;";case ">":return"&gt;";default:return b}})}function F(a){if(typeof a!=="string")return a;return a.replace(/[&<>"]/g,function(b){switch(b){case "&":return"&amp;";case "<":return"&lt;";case ">":return"&gt;";case '"':return"&quot;";default:return b}})}function v(a,b){var d=b[0],c=b.length,e=1,f;if(d){a.push("<",d);f=b[e];if(i(f)===3){for(var g in f)if(f.hasOwnProperty(g)){a.push(" ",g);var l=f[g];l&&a.push('="',F(l),'"')}e++}a.push(">")}for(;e<
-c;e++){f=b[e];i(f)===2?v(a,f):a.push(E(f))}d&&!G[d]&&a.push("</",d,">")}function w(a){var b=[];v(b,a);return b.join("")}function m(a){if(!a){if(k.createDocumentFragment)return k.createDocumentFragment();a=""}if(a.toLowerCase()==="style"&&k.createStyleSheet)return k.createStyleSheet();return k.createElement(a)}function r(a,b){if(b)if(a.tagName&&a.tagName.toLowerCase()==="table"&&a.tBodies)if(b.tagName){var d=b.tagName.toLowerCase();if(d&&d!=="tbody"&&d!=="thead"){var c=a.tBodies.length>0?a.tBodies[a.tBodies.length-
-1]:null;if(!c){c=m(d==="th"?"thead":"tbody");a.appendChild(c)}c.appendChild(b)}else a.canHaveChildren!==false&&a.appendChild(b)}else{if(b.nodeType===11)for(;b.firstChild;)r(a,b.removeChild(b.firstChild))}else if(a.tagName&&a.tagName.toLowerCase()==="style"&&k.createStyleSheet)a.cssText=b;else if(a.canHaveChildren!==false)a.appendChild(b);else if(a.tagName&&a.tagName.toLowerCase()==="object"&&b.tagName&&b.tagName.toLowerCase()==="param"){try{a.appendChild(b)}catch(e){}try{if(a.object)a.object[b.name]=
-b.value}catch(f){}}}function x(a,b,d){if(typeof d==="string")d=new Function("event",d);if(typeof d==="function")a[b]=d}function y(a){return!!a&&a.nodeType===3&&(!a.nodeValue||!/\S/.exec(a.nodeValue))}function z(a){if(a){for(;y(a.firstChild);)a.removeChild(a.firstChild);for(;y(a.lastChild);)a.removeChild(a.lastChild)}}function A(a,b){var d=a[b];if(d){try{delete a[b]}catch(c){a[b]=D}if(typeof d!=="function")try{d=new Function(""+d)}catch(e){d=null}}return d}function H(a){if(a){var b=A(a,"$init");b&&
-b.call(a);if(b=A(a,"$load"))setTimeout(function(){b.call(a);b=a=null},0);else b=a=null}}function B(a){return k.createTextNode("["+a+"]")}function C(a,b){for(var d=1;d<b.length;d++){var c=b[d];switch(i(c)){case 2:r(a,C(m(c[0]),c));break;case 4:r(a,k.createTextNode(""+c));break;case 3:if(a.nodeType===1){var e=a,f=c;if(f.name&&k.attachEvent)try{var g=m("<"+e.tagName+" name='"+f.name+"'>");if(e.tagName===g.tagName)e=g}catch(l){}c=void 0;for(c in f)if(f.hasOwnProperty(c)){var h=f[c];if(c&&h){c=I[c.toLowerCase()]||
-c;if(c==="style")if(typeof e.style.cssText!=="undefined")e.style.cssText=h;else e.style=h;else if(c==="class")e.className=h;else if(J[c]){x(e,c,h);n[c]&&x(e,n[c],h)}else if(i(h)===4){e.setAttribute(c,h);n[c]&&e.setAttribute(n[c],h)}else{e[c]=h;if(n[c])e[n[c]]=h}}}a=e}break;case 5:e=r;f=a;h=c;c=m("div");c.innerHTML=""+h;z(c);if(c.childNodes.length===1)c=c.firstChild;else{for(h=m("");c.firstChild;)h.appendChild(c.firstChild);c=h}e(f,c)}}z(a);H(a);if(a.nodeType===11&&a.childNodes.length===1)a=a.firstChild;
-return a}s.prototype.toString=function(){return this.value};var j;j=function(a,b,d,c){var e;switch(i(a)){case 1:e=a(b,d,c);break;case 2:var f=a[0]||"";switch(f){case "$for":a=a;f=a[1];if(!f||!f.each)e=null;else{b=i(f.each)===1?f.each(b,d,c):f.each;a=a.length===3?a[2]:[""].concat(a.slice(2));d=[""];switch(i(b)){case 2:c=0;for(e=b.length;c<e;c++)q(d,j(a,b[c],c,e));break;case 3:for(e in b)b.hasOwnProperty(e)&&q(d,j(a,b[e],e,0))}e=d}break;case "$choose":e=u(a,b,d,c);break;case "$if":case "$else":e=u(["$choose",
-a],b,d,c);break;case "$call":var g=a[1];if(g){e=j(g.view,b,d,c);a=j(g.model,b,d,c);f=j(g.index,b,d,c);b=j(g.count,b,d,c);e=j(o(e).value,a,f,b)}else e=null;break;default:e=[f];f=1;for(g=a.length;f<g;f++)q(e,j(a[f],b,d,c))}break;case 3:e={};for(f in a)if(a.hasOwnProperty(f))e[f]=j(a[f],b,d,c);break;default:e=a}return e};p.prototype.bind=function(a){a=j(this.value,a,0,1);return new t(a)};var G=function(a){for(var b={};a.length;)b[a.pop()]=true;return b}("area,base,basefont,br,col,frame,hr,img,input,isindex,keygen,link,meta,param,source,wbr".split(","));
-t.prototype.toString=function(){return w(this.value)};p.prototype.toString=function(){return w(this.value)};var I={rowspan:"rowSpan",colspan:"colSpan",cellpadding:"cellPadding",cellspacing:"cellSpacing",tabindex:"tabIndex",accesskey:"accessKey",hidefocus:"hideFocus",usemap:"useMap",maxlength:"maxLength",readonly:"readOnly",contenteditable:"contentEditable"},n={enctype:"encoding",onscroll:"DOMMouseScroll"},J=function(a){for(var b={};a.length;){var d=a.pop();b["on"+d.toLowerCase()]=d}return b}("blur,change,click,dblclick,error,focus,keydown,keypress,keyup,load,mousedown,mouseenter,mouseleave,mousemove,mouseout,mouseover,mouseup,resize,scroll,select,submit,unload".split(","));
-t.prototype.toDOM=function(){try{return C(m(this.value[0]),this.value)}catch(a){try{return(typeof o.onerror==="function"?o.onerror:B)(a,this.value)}catch(b){return B(b)}}};var o=function(a){return a instanceof p?a:new p(a)};o.raw=function(a){return new s(a)};return o}(document);
+var duel=function(u,E){function t(a){this.value=a}function i(a){switch(typeof a){case "object":return!a?0:a instanceof Array?2:a instanceof t?5:3;case "function":return 1;case "undefined":return 0;default:return 4}}function q(a){if(i(a)!==2)a=["",a];this.value=a}function p(a){if(i(a)!==2)a=["",a];this.value=a}function r(a,b){if(i(a)===2)switch(i(b)){case 2:if(b[0]==="")for(var d=1,c=b.length;d<c;d++)r(a,b[d]);else a.push(b);break;case 3:d=a[1];if(i(d)===3)for(c in b){if(b.hasOwnProperty(c))d[c]=b[c]}else a.splice(1,
+0,b);break;case 4:d=a.length-1;if(d>0&&i(a[d])===4)a[d]=""+a[d]+b;else a.push(""+b);break;case 0:break;default:a.push(b)}}function v(a,b,d,c){for(var e=1,f=a.length;e<f;e++){var g=a[e],l=g[1]&&g[1].test;switch(g[0]){case "$if":if(i(l)===1)l=l(b,d,c);if(!l)continue;if(g.length===3)g=g[2];else[""].concat(a.slice(2));return j(g,b,d,c);case "$else":if(g.length===2)g=g[1];else[""].concat(a.slice(1));return j(g,b,d,c)}}return null}function F(a){if(typeof a!=="string")return a;return a.replace(/[&<>]/g,
+function(b){switch(b){case "&":return"&amp;";case "<":return"&lt;";case ">":return"&gt;";default:return b}})}function G(a){if(typeof a!=="string")return a;return a.replace(/[&<>"]/g,function(b){switch(b){case "&":return"&amp;";case "<":return"&lt;";case ">":return"&gt;";case '"':return"&quot;";default:return b}})}function w(a,b){var d=b[0],c=b.length,e=1,f;if(d){a.push("<",d);f=b[e];if(i(f)===3){for(var g in f)if(f.hasOwnProperty(g)){a.push(" ",g);var l=f[g];l&&a.push('="',G(l),'"')}e++}a.push(">")}for(;e<
+c;e++){f=b[e];i(f)===2?w(a,f):a.push(F(f))}d&&!H[d]&&a.push("</",d,">")}function x(a){var b=[];w(b,a);return b.join("")}function m(a){if(!a){if(k.createDocumentFragment)return k.createDocumentFragment();a=""}if(a.toLowerCase()==="style"&&k.createStyleSheet)return k.createStyleSheet();return k.createElement(a)}function s(a,b){if(b)if(a.tagName&&a.tagName.toLowerCase()==="table"&&a.tBodies)if(b.tagName){var d=b.tagName.toLowerCase();if(d&&d!=="tbody"&&d!=="thead"){var c=a.tBodies.length>0?a.tBodies[a.tBodies.length-
+1]:null;if(!c){c=m(d==="th"?"thead":"tbody");a.appendChild(c)}c.appendChild(b)}else a.canHaveChildren!==false&&a.appendChild(b)}else{if(b.nodeType===11)for(;b.firstChild;)s(a,b.removeChild(b.firstChild))}else if(a.tagName&&a.tagName.toLowerCase()==="style"&&k.createStyleSheet)a.cssText=b;else if(a.canHaveChildren!==false)a.appendChild(b);else if(a.tagName&&a.tagName.toLowerCase()==="object"&&b.tagName&&b.tagName.toLowerCase()==="param"){try{a.appendChild(b)}catch(e){}try{if(a.object)a.object[b.name]=
+b.value}catch(f){}}}function y(a,b,d){if(typeof d==="string")d=new Function("event",d);if(typeof d==="function")a[b]=d}function z(a){return!!a&&a.nodeType===3&&(!a.nodeValue||!/\S/.exec(a.nodeValue))}function A(a){if(a){for(;z(a.firstChild);)a.removeChild(a.firstChild);for(;z(a.lastChild);)a.removeChild(a.lastChild)}}function B(a,b){var d=a[b];if(d){try{delete a[b]}catch(c){a[b]=E}if(typeof d!=="function")try{d=new Function(""+d)}catch(e){d=null}}return d}function I(a){if(a){var b=B(a,"$init");b&&
+b.call(a);if(b=B(a,"$load"))setTimeout(function(){b.call(a);b=a=null},0);else b=a=null}}function C(a){return k.createTextNode("["+a+"]")}function D(a,b){for(var d=1;d<b.length;d++){var c=b[d];switch(i(c)){case 2:s(a,D(m(c[0]),c));break;case 4:s(a,k.createTextNode(""+c));break;case 3:if(a.nodeType===1){var e=a,f=c;if(f.name&&k.attachEvent)try{var g=m("<"+e.tagName+" name='"+f.name+"'>");if(e.tagName===g.tagName)e=g}catch(l){}c=void 0;for(c in f)if(f.hasOwnProperty(c)){var h=f[c];if(c&&h){c=J[c.toLowerCase()]||
+c;if(c==="style")if(typeof e.style.cssText!=="undefined")e.style.cssText=h;else e.style=h;else if(c==="class")e.className=h;else if(K[c]){y(e,c,h);n[c]&&y(e,n[c],h)}else if(i(h)===4){e.setAttribute(c,h);n[c]&&e.setAttribute(n[c],h)}else{e[c]=h;if(n[c])e[n[c]]=h}}}a=e}break;case 5:e=s;f=a;h=c;c=m("div");c.innerHTML=""+h;A(c);if(c.childNodes.length===1)c=c.firstChild;else{for(h=m("");c.firstChild;)h.appendChild(c.firstChild);c=h}e(f,c)}}A(a);I(a);if(a.nodeType===11&&a.childNodes.length===1)a=a.firstChild;
+return a}var k=u.document;t.prototype.toString=function(){return this.value};var j;j=function(a,b,d,c){var e;switch(i(a)){case 1:e=a(b,d,c);break;case 2:var f=a[0]||"";switch(f){case "$for":a=a;f=a[1]&&a[1].each;if(i(f)===1)f=f(b,d,c);a=a.length===3?a[2]:[""].concat(a.slice(2));b=[""];switch(i(f)){case 2:d=0;for(c=f.length;d<c;d++)r(b,j(a,f[d],d,c));break;case 3:for(e in f)f.hasOwnProperty(e)&&r(b,j(a,f[e],e,0))}e=b;break;case "$choose":e=v(a,b,d,c);break;case "$if":case "$else":e=v(["$choose",a],
+b,d,c);break;case "$call":var g=a[1];if(!g||!g.view)e=null;else{a=j(g.view,b,d,c);e=j(g.model,b,d,c);f=j(g.index,b,d,c);b=j(g.count,b,d,c);e=j(o(a).value,e,f,b)}break;default:e=[f];f=1;for(g=a.length;f<g;f++)r(e,j(a[f],b,d,c))}break;case 3:e={};for(f in a)if(a.hasOwnProperty(f))e[f]=j(a[f],b,d,c);break;default:e=a}return e};p.prototype.bind=p.prototype.bind=function(a){a=j(this.value,a,0,1);return new q(a)};var H={area:true,base:true,basefont:true,br:true,col:true,frame:true,hr:true,img:true,input:true,
+isindex:true,keygen:true,link:true,meta:true,param:true,source:true,wbr:true};q.prototype.toString=function(){return x(this.value)};p.prototype.toString=function(){return x(this.value)};var J={rowspan:"rowSpan",colspan:"colSpan",cellpadding:"cellPadding",cellspacing:"cellSpacing",tabindex:"tabIndex",accesskey:"accessKey",hidefocus:"hideFocus",usemap:"useMap",maxlength:"maxLength",readonly:"readOnly",contenteditable:"contentEditable"},n={enctype:"encoding",onscroll:"DOMMouseScroll"},K={onblur:true,
+onchange:true,onclick:true,ondblclick:true,onerror:true,onfocus:true,onkeydown:true,onkeypress:true,onkeyup:true,onload:true,onmousedown:true,onmouseenter:true,onmouseleave:true,onmousemove:true,onmouseout:true,onmouseover:true,onmouseup:true,onresize:true,onscroll:true,onselect:true,onsubmit:true,onunload:true};q.prototype.toDOM=q.prototype.toDOM=function(){try{return D(m(this.value[0]),this.value)}catch(a){try{return(typeof o.onerror==="function"?o.onerror:C)(a,this.value)}catch(b){return C(b)}}};
+var o=u.duel=function(a){return a instanceof p?a:new p(a)};o.raw=o.raw=function(a){return new t(a)};return o}(window);

lib/closure/docs.url

+[InternetShortcut]
+URL=http://code.google.com/closure/compiler/docs/js-for-compiler.html

lib/jslint/jslint.js

+// jslint.js
+// 2010-02-20
+
+/*
+Copyright (c) 2002 Douglas Crockford  (www.JSLint.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+The Software shall be used for Good, not Evil.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+/*
+    JSLINT is a global function. It takes two parameters.
+
+        var myResult = JSLINT(source, option);
+
+    The first parameter is either a string or an array of strings. If it is a
+    string, it will be split on '\n' or '\r'. If it is an array of strings, it
+    is assumed that each string represents one line. The source can be a
+    JavaScript text, or HTML text, or a Konfabulator text.
+
+    The second parameter is an optional object of options which control the
+    operation of JSLINT. Most of the options are booleans: They are all are
+    optional and have a default value of false.
+
+    If it checks out, JSLINT returns true. Otherwise, it returns false.
+
+    If false, you can inspect JSLINT.errors to find out the problems.
+    JSLINT.errors is an array of objects containing these members:
+
+    {
+        line      : The line (relative to 0) at which the lint was found
+        character : The character (relative to 0) at which the lint was found
+        reason    : The problem
+        evidence  : The text line in which the problem occurred
+        raw       : The raw message before the details were inserted
+        a         : The first detail
+        b         : The second detail
+        c         : The third detail
+        d         : The fourth detail
+    }
+
+    If a fatal error was found, a null will be the last element of the
+    JSLINT.errors array.
+
+    You can request a Function Report, which shows all of the functions
+    and the parameters and vars that they use. This can be used to find
+    implied global variables and other problems. The report is in HTML and
+    can be inserted in an HTML <body>.
+
+        var myReport = JSLINT.report(limited);
+
+    If limited is true, then the report will be limited to only errors.
+
+    You can request a data structure which contains JSLint's results.
+
+        var myData = JSLINT.data();
+
+    It returns a structure with this form:
+
+    {
+        errors: [
+            {
+                line: NUMBER,
+                character: NUMBER,
+                reason: STRING,
+                evidence: STRING
+            }
+        ],
+        functions: [
+            name: STRING,
+            line: NUMBER,
+            last: NUMBER,
+            param: [
+                STRING
+            ],
+            closure: [
+                STRING
+            ],
+            var: [
+                STRING
+            ],
+            exception: [
+                STRING
+            ],
+            outer: [
+                STRING
+            ],
+            unused: [
+                STRING
+            ],
+            global: [
+                STRING
+            ],
+            label: [
+                STRING
+            ]
+        ],
+        globals: [
+            STRING
+        ],
+        member: {
+            STRING: NUMBER
+        },
+        unuseds: [
+            {
+                name: STRING,
+                line: NUMBER
+            }
+        ],
+        implieds: [
+            {
+                name: STRING,
+                line: NUMBER
+            }
+        ],
+        urls: [
+            STRING
+        ],
+        json: BOOLEAN
+    }
+
+    Empty arrays will not be included.
+
+*/
+
+/*jslint
+    evil: true, nomen: false, onevar: false, regexp: false, strict: true
+*/
+
+/*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%",
+    "(begin)", "(breakage)", "(context)", "(error)", "(global)",
+    "(identifier)", "(last)", "(line)", "(loopage)", "(name)", "(onevar)",
+    "(params)", "(scope)", "(verb)", "*", "+", "++", "-", "--", "\/",
+    "<", "<=", "==", "===", ">", ">=", ADSAFE, Array, Boolean,
+    COM, Canvas, CustomAnimation, Date, Debug, E, Error, EvalError,
+    FadeAnimation, Flash, FormField, Frame, Function, HotKey, Image, JSON,
+    LN10, LN2, LOG10E, LOG2E, MAX_VALUE, MIN_VALUE, Math, MenuItem,
+    MoveAnimation, NEGATIVE_INFINITY, Number, Object, Option, PI,
+    POSITIVE_INFINITY, Point, RangeError, Rectangle, ReferenceError, RegExp,
+    ResizeAnimation, RotateAnimation, SQRT1_2, SQRT2, ScrollBar, String,
+    Style, SyntaxError, System, Text, TextArea, Timer, TypeError, URIError,
+    URL, Web, Window, XMLDOM, XMLHttpRequest, "\\", a, abbr, acronym,
+    addEventListener, address, adsafe, alert, aliceblue, animator,
+    antiquewhite, appleScript, applet, apply, approved, aqua, aquamarine,
+    area, arguments, arity, autocomplete, azure, b, background,
+    "background-attachment", "background-color", "background-image",
+    "background-position", "background-repeat", base, bdo, beep, beige, big,
+    bisque, bitwise, black, blanchedalmond, block, blockquote, blue,
+    blueviolet, blur, body, border, "border-bottom", "border-bottom-color",
+    "border-bottom-style", "border-bottom-width", "border-collapse",
+    "border-color", "border-left", "border-left-color", "border-left-style",
+    "border-left-width", "border-right", "border-right-color",
+    "border-right-style", "border-right-width", "border-spacing",
+    "border-style", "border-top", "border-top-color", "border-top-style",
+    "border-top-width", "border-width", bottom, br, brown, browser,
+    burlywood, button, bytesToUIString, c, cadetblue, call, callee, caller,
+    canvas, cap, caption, "caption-side", cases, center, charAt, charCodeAt,
+    character, chartreuse, chocolate, chooseColor, chooseFile, chooseFolder,
+    cite, clear, clearInterval, clearTimeout, clip, close, closeWidget,
+    closed, closure, cm, code, col, colgroup, color, comment, condition,
+    confirm, console, constructor, content, convertPathToHFS,
+    convertPathToPlatform, coral, cornflowerblue, cornsilk,
+    "counter-increment", "counter-reset", create, crimson, css, cursor,
+    cyan, d, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen,
+    darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, darkred,
+    darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise,
+    darkviolet, data, dd, debug, decodeURI, decodeURIComponent, deeppink,
+    deepskyblue, defaultStatus, defineClass, del, deserialize, devel, dfn,
+    dimension, dimgray, dir, direction, display, div, dl, document,
+    dodgerblue, dt, edition, else, em, embed, empty, "empty-cells",
+    encodeURI, encodeURIComponent, entityify, eqeqeq, errors, escape, eval,
+    event, evidence, evil, ex, exception, exec, exps, fieldset, filesystem,
+    firebrick, first, float, floor, floralwhite, focus, focusWidget, font,
+    "font-face", "font-family", "font-size", "font-size-adjust",
+    "font-stretch", "font-style", "font-variant", "font-weight",
+    forestgreen, forin, form, fragment, frame, frames, frameset, from,
+    fromCharCode, fuchsia, fud, funct, function, functions, g, gainsboro,
+    gc, getComputedStyle, ghostwhite, global, globals, gold, goldenrod,
+    gray, green, greenyellow, h1, h2, h3, h4, h5, h6, hasOwnProperty, head,
+    height, help, history, honeydew, hotpink, hr, html, i, iTunes, id,
+    identifier, iframe, img, immed, implieds, in, include, indent, indexOf,
+    indianred, indigo, init, input, ins, isAlpha, isApplicationRunning,
+    isDigit, isFinite, isNaN, ivory, join, jslint, json, kbd, khaki,
+    konfabulatorVersion, label, labelled, lang, last, lavender,
+    lavenderblush, lawngreen, laxbreak, lbp, led, left, legend,
+    lemonchiffon, length, "letter-spacing", li, lib, lightblue, lightcoral,
+    lightcyan, lightgoldenrodyellow, lightgreen, lightpink, lightsalmon,
+    lightseagreen, lightskyblue, lightslategray, lightsteelblue,
+    lightyellow, lime, limegreen, line, "line-height", linen, link,
+    "list-style", "list-style-image", "list-style-position",
+    "list-style-type", load, loadClass, location, log, m, magenta, map,
+    margin, "margin-bottom", "margin-left", "margin-right", "margin-top",
+    "marker-offset", maroon, match, "max-height", "max-width", maxerr, maxlen,
+    md5, media, mediumaquamarine, mediumblue, mediumorchid, mediumpurple,
+    mediumseagreen, mediumslateblue, mediumspringgreen, mediumturquoise,
+    mediumvioletred, member, menu, message, meta, midnightblue,
+    "min-height", "min-width", mintcream, mistyrose, mm, moccasin, moveBy,
+    moveTo, name, navajowhite, navigator, navy, new, newcap, noframes,
+    nomen, noscript, nud, object, ol, oldlace, olive, olivedrab, on,
+    onbeforeunload, onblur, onerror, onevar, onfocus, onload, onresize,
+    onunload, opacity, open, openURL, opener, opera, optgroup, option,
+    orange, orangered, orchid, outer, outline, "outline-color",
+    "outline-style", "outline-width", overflow, "overflow-x", "overflow-y",
+    p, padding, "padding-bottom", "padding-left", "padding-right",
+    "padding-top", page, "page-break-after", "page-break-before",
+    palegoldenrod, palegreen, paleturquoise, palevioletred, papayawhip,
+    param, parent, parseFloat, parseInt, passfail, pc, peachpuff, peru,
+    pink, play, plum, plusplus, pop, popupMenu, position, powderblue, pre,
+    predef, preferenceGroups, preferences, print, prompt, prototype, pt,
+    purple, push, px, q, quit, quotes, random, range, raw, reach, readFile,
+    readUrl, reason, red, regexp, reloadWidget, removeEventListener,
+    replace, report, reserved, resizeBy, resizeTo, resolvePath,
+    resumeUpdates, rhino, right, rosybrown, royalblue, runCommand,
+    runCommandInBg, saddlebrown, safe, salmon, samp, sandybrown, saveAs,
+    savePreferences, screen, script, scroll, scrollBy, scrollTo, seagreen,
+    seal, search, seashell, select, serialize, setInterval, setTimeout,
+    shift, showWidgetPreferences, sidebar, sienna, silver, skyblue,
+    slateblue, slategray, sleep, slice, small, snow, sort, span, spawn,
+    speak, split, springgreen, src, status, steelblue, strict, strong,
+    style, styleproperty, sub, substr, sup, supplant, suppressUpdates, sync,
+    system, table, "table-layout", tan, tbody, td, teal, tellWidget, test,
+    "text-align", "text-decoration", "text-indent", "text-shadow",
+    "text-transform", textarea, tfoot, th, thead, thistle, title,
+    toLowerCase, toString, toUpperCase, toint32, token, tomato, top, tr, tt,
+    turquoise, type, u, ul, undef, unescape, "unicode-bidi", unused,
+    unwatch, updateNow, urls, value, valueOf, var, version,
+    "vertical-align", violet, visibility, watch, wheat, white,
+    "white-space", whitesmoke, widget, width, "word-spacing", "word-wrap",
+    yahooCheckLogin, yahooLogin, yahooLogout, yellow, yellowgreen,
+    "z-index"
+*/
+
+
+// We build the application inside a function so that we produce only a single
+// global variable. The function will be invoked, its return value is the JSLINT
+// application itself.
+
+"use strict";
+
+var JSLINT = (function () {
+    var adsafe_id,      // The widget's ADsafe id.
+        adsafe_may,     // The widget may load approved scripts.
+        adsafe_went,    // ADSAFE.go has been called.
+        anonname,       // The guessed name for anonymous functions.
+        approved,       // ADsafe approved urls.
+
+        atrule = {
+            media      : true,
+            'font-face': true,
+            page       : true
+        },
+
+// These are operators that should not be used with the ! operator.
+
+        bang = {
+            '<': true,
+            '<=': true,
+            '==': true,
+            '===': true,
+            '!==': true,
+            '!=': true,
+            '>': true,
+            '>=': true,
+            '+': true,
+            '-': true,
+            '*': true,
+            '/': true,
+            '%': true
+        },
+
+// These are members that should not be permitted in the safe subset.
+
+        banned = {              // the member names that ADsafe prohibits.
+            'arguments'     : true,
+            callee          : true,
+            caller          : true,
+            constructor     : true,
+            'eval'          : true,
+            prototype       : true,
+            unwatch         : true,
+            valueOf         : true,
+            watch           : true
+        },
+
+
+// These are the JSLint boolean options.
+
+        boolOptions = {
+            adsafe     : true, // if ADsafe should be enforced
+            bitwise    : true, // if bitwise operators should not be allowed
+            browser    : true, // if the standard browser globals should be predefined
+            cap        : true, // if upper case HTML should be allowed
+            css        : true, // if CSS workarounds should be tolerated
+            debug      : true, // if debugger statements should be allowed
+            devel      : true, // if logging should be allowed (console, alert, etc.)
+            eqeqeq     : true, // if === should be required
+            evil       : true, // if eval should be allowed
+            forin      : true, // if for in statements must filter
+            fragment   : true, // if HTML fragments should be allowed
+            immed      : true, // if immediate invocations must be wrapped in parens
+            laxbreak   : true, // if line breaks should not be checked
+            newcap     : true, // if constructor names must be capitalized
+            nomen      : true, // if names should be checked
+            on         : true, // if HTML event handlers should be allowed
+            onevar     : true, // if only one var statement per function should be allowed
+            passfail   : true, // if the scan should stop on first error
+            plusplus   : true, // if increment/decrement should not be allowed
+            regexp     : true, // if the . should not be allowed in regexp literals
+            rhino      : true, // if the Rhino environment globals should be predefined
+            undef      : true, // if variables should be declared before used
+            safe       : true, // if use of some browser features should be restricted
+            sidebar    : true, // if the System object should be predefined
+            strict     : true, // require the "use strict"; pragma
+            sub        : true, // if all forms of subscript notation are tolerated
+            white      : true, // if strict whitespace rules apply
+            widget     : true  // if the Yahoo Widgets globals should be predefined
+        },
+
+// browser contains a set of global names which are commonly provided by a
+// web browser environment.
+
+        browser = {
+            addEventListener: false,
+            blur            : false,
+            clearInterval   : false,
+            clearTimeout    : false,
+            close           : false,
+            closed          : false,
+            defaultStatus   : false,
+            document        : false,
+            event           : false,
+            focus           : false,
+            frames          : false,
+            getComputedStyle: false,
+            history         : false,
+            Image           : false,
+            length          : false,
+            location        : false,
+            moveBy          : false,
+            moveTo          : false,
+            name            : false,
+            navigator       : false,
+            onbeforeunload  : true,
+            onblur          : true,
+            onerror         : true,
+            onfocus         : true,
+            onload          : true,
+            onresize        : true,
+            onunload        : true,
+            open            : false,
+            opener          : false,
+            Option          : false,
+            parent          : false,
+            print           : false,
+            removeEventListener: false,
+            resizeBy        : false,
+            resizeTo        : false,
+            screen          : false,
+            scroll          : false,
+            scrollBy        : false,
+            scrollTo        : false,
+            setInterval     : false,
+            setTimeout      : false,
+            status          : false,
+            top             : false,
+            XMLHttpRequest  : false
+        },
+
+        cssAttributeData,
+        cssAny,
+
+        cssColorData = {
+            "aliceblue"             : true,
+            "antiquewhite"          : true,
+            "aqua"                  : true,
+            "aquamarine"            : true,
+            "azure"                 : true,
+            "beige"                 : true,
+            "bisque"                : true,
+            "black"                 : true,
+            "blanchedalmond"        : true,
+            "blue"                  : true,
+            "blueviolet"            : true,
+            "brown"                 : true,
+            "burlywood"             : true,
+            "cadetblue"             : true,
+            "chartreuse"            : true,
+            "chocolate"             : true,
+            "coral"                 : true,
+            "cornflowerblue"        : true,
+            "cornsilk"              : true,
+            "crimson"               : true,
+            "cyan"                  : true,
+            "darkblue"              : true,
+            "darkcyan"              : true,
+            "darkgoldenrod"         : true,
+            "darkgray"              : true,
+            "darkgreen"             : true,
+            "darkkhaki"             : true,
+            "darkmagenta"           : true,
+            "darkolivegreen"        : true,
+            "darkorange"            : true,
+            "darkorchid"            : true,
+            "darkred"               : true,
+            "darksalmon"            : true,
+            "darkseagreen"          : true,
+            "darkslateblue"         : true,
+            "darkslategray"         : true,
+            "darkturquoise"         : true,
+            "darkviolet"            : true,
+            "deeppink"              : true,
+            "deepskyblue"           : true,
+            "dimgray"               : true,
+            "dodgerblue"            : true,
+            "firebrick"             : true,
+            "floralwhite"           : true,
+            "forestgreen"           : true,
+            "fuchsia"               : true,
+            "gainsboro"             : true,
+            "ghostwhite"            : true,
+            "gold"                  : true,
+            "goldenrod"             : true,
+            "gray"                  : true,
+            "green"                 : true,
+            "greenyellow"           : true,
+            "honeydew"              : true,
+            "hotpink"               : true,
+            "indianred"             : true,
+            "indigo"                : true,
+            "ivory"                 : true,
+            "khaki"                 : true,
+            "lavender"              : true,
+            "lavenderblush"         : true,
+            "lawngreen"             : true,
+            "lemonchiffon"          : true,
+            "lightblue"             : true,
+            "lightcoral"            : true,
+            "lightcyan"             : true,
+            "lightgoldenrodyellow"  : true,
+            "lightgreen"            : true,
+            "lightpink"             : true,
+            "lightsalmon"           : true,
+            "lightseagreen"         : true,
+            "lightskyblue"          : true,
+            "lightslategray"        : true,
+            "lightsteelblue"        : true,
+            "lightyellow"           : true,
+            "lime"                  : true,
+            "limegreen"             : true,
+            "linen"                 : true,
+            "magenta"               : true,
+            "maroon"                : true,
+            "mediumaquamarine"      : true,
+            "mediumblue"            : true,
+            "mediumorchid"          : true,
+            "mediumpurple"          : true,
+            "mediumseagreen"        : true,
+            "mediumslateblue"       : true,
+            "mediumspringgreen"     : true,
+            "mediumturquoise"       : true,
+            "mediumvioletred"       : true,
+            "midnightblue"          : true,
+            "mintcream"             : true,
+            "mistyrose"             : true,
+            "moccasin"              : true,
+            "navajowhite"           : true,
+            "navy"                  : true,
+            "oldlace"               : true,
+            "olive"                 : true,
+            "olivedrab"             : true,
+            "orange"                : true,
+            "orangered"             : true,
+            "orchid"                : true,
+            "palegoldenrod"         : true,
+            "palegreen"             : true,
+            "paleturquoise"         : true,
+            "palevioletred"         : true,
+            "papayawhip"            : true,
+            "peachpuff"             : true,
+            "peru"                  : true,
+            "pink"                  : true,
+            "plum"                  : true,
+            "powderblue"            : true,
+            "purple"                : true,
+            "red"                   : true,
+            "rosybrown"             : true,
+            "royalblue"             : true,
+            "saddlebrown"           : true,
+            "salmon"                : true,
+            "sandybrown"            : true,
+            "seagreen"              : true,
+            "seashell"              : true,
+            "sienna"                : true,
+            "silver"                : true,
+            "skyblue"               : true,
+            "slateblue"             : true,
+            "slategray"             : true,
+            "snow"                  : true,
+            "springgreen"           : true,
+            "steelblue"             : true,
+            "tan"                   : true,
+            "teal"                  : true,
+            "thistle"               : true,
+            "tomato"                : true,
+            "turquoise"             : true,
+            "violet"                : true,
+            "wheat"                 : true,
+            "white"                 : true,
+            "whitesmoke"            : true,
+            "yellow"                : true,
+            "yellowgreen"           : true
+        },
+
+        cssBorderStyle,
+        cssBreak,
+
+        cssLengthData = {
+            '%': true,
+            'cm': true,
+            'em': true,
+            'ex': true,
+            'in': true,
+            'mm': true,
+            'pc': true,
+            'pt': true,
+            'px': true
+        },
+
+        cssOverflow,
+
+        devel = {
+            alert           : false,
+            confirm         : false,
+            console         : false,
+            Debug           : false,
+            opera           : false,
+            prompt          : false
+        },
+
+        escapes = {
+            '\b': '\\b',
+            '\t': '\\t',
+            '\n': '\\n',
+            '\f': '\\f',
+            '\r': '\\r',
+            '"' : '\\"',
+            '/' : '\\/',
+            '\\': '\\\\'
+        },
+
+        funct,          // The current function
+
+        functionicity = [
+            'closure', 'exception', 'global', 'label',
+            'outer', 'unused', 'var'
+        ],
+
+        functions,      // All of the functions
+
+        global,         // The global scope
+        htmltag = {
+            a:        {},
+            abbr:     {},
+            acronym:  {},
+            address:  {},
+            applet:   {},
+            area:     {empty: true, parent: ' map '},
+            b:        {},
+            base:     {empty: true, parent: ' head '},
+            bdo:      {},
+            big:      {},
+            blockquote: {},
+            body:     {parent: ' html noframes '},
+            br:       {empty: true},
+            button:   {},
+            canvas:   {parent: ' body p div th td '},
+            caption:  {parent: ' table '},
+            center:   {},
+            cite:     {},
+            code:     {},
+            col:      {empty: true, parent: ' table colgroup '},
+            colgroup: {parent: ' table '},
+            dd:       {parent: ' dl '},
+            del:      {},
+            dfn:      {},
+            dir:      {},
+            div:      {},
+            dl:       {},
+            dt:       {parent: ' dl '},
+            em:       {},
+            embed:    {},
+            fieldset: {},
+            font:     {},
+            form:     {},
+            frame:    {empty: true, parent: ' frameset '},
+            frameset: {parent: ' html frameset '},
+            h1:       {},
+            h2:       {},
+            h3:       {},
+            h4:       {},
+            h5:       {},
+            h6:       {},
+            head:     {parent: ' html '},
+            html:     {parent: '*'},
+            hr:       {empty: true},
+            i:        {},
+            iframe:   {},
+            img:      {empty: true},
+            input:    {empty: true},
+            ins:      {},
+            kbd:      {},
+            label:    {},
+            legend:   {parent: ' fieldset '},
+            li:       {parent: ' dir menu ol ul '},
+            link:     {empty: true, parent: ' head '},
+            map:      {},
+            menu:     {},
+            meta:     {empty: true, parent: ' head noframes noscript '},
+            noframes: {parent: ' html body '},
+            noscript: {parent: ' body head noframes '},
+            object:   {},
+            ol:       {},
+            optgroup: {parent: ' select '},
+            option:   {parent: ' optgroup select '},
+            p:        {},
+            param:    {empty: true, parent: ' applet object '},
+            pre:      {},
+            q:        {},
+            samp:     {},
+            script:   {empty: true, parent: ' body div frame head iframe p pre span '},
+            select:   {},
+            small:    {},
+            span:     {},
+            strong:   {},
+            style:    {parent: ' head ', empty: true},
+            sub:      {},
+            sup:      {},
+            table:    {},
+            tbody:    {parent: ' table '},
+            td:       {parent: ' tr '},
+            textarea: {},
+            tfoot:    {parent: ' table '},
+            th:       {parent: ' tr '},
+            thead:    {parent: ' table '},
+            title:    {parent: ' head '},
+            tr:       {parent: ' table tbody thead tfoot '},
+            tt:       {},
+            u:        {},
+            ul:       {},
+            'var':    {}
+        },
+
+        ids,            // HTML ids
+        implied,        // Implied globals
+        inblock,
+        indent,
+        jsonmode,
+        lines,
+        lookahead,
+        member,
+        membersOnly,
+        nexttoken,
+        noreach,
+        option,
+        predefined,     // Global variables defined by option
+        prereg,
+        prevtoken,
+
+        rhino = {
+            defineClass : false,
+            deserialize : false,
+            gc          : false,
+            help        : false,
+            load        : false,
+            loadClass   : false,
+            print       : false,
+            quit        : false,
+            readFile    : false,
+            readUrl     : false,
+            runCommand  : false,
+            seal        : false,
+            serialize   : false,
+            spawn       : false,
+            sync        : false,
+            toint32     : false,
+            version     : false
+        },
+
+        scope,      // The current scope
+
+        sidebar = {
+            System      : false
+        },
+
+        src,
+        stack,
+
+// standard contains the global names that are provided by the
+// ECMAScript standard.
+
+        standard = {
+            Array               : false,
+            Boolean             : false,
+            Date                : false,
+            decodeURI           : false,
+            decodeURIComponent  : false,
+            encodeURI           : false,
+            encodeURIComponent  : false,
+            Error               : false,
+            'eval'              : false,
+            EvalError           : false,
+            Function            : false,
+            hasOwnProperty      : false,
+            isFinite            : false,
+            isNaN               : false,
+            JSON                : false,
+            Math                : false,
+            Number              : false,
+            Object              : false,
+            parseInt            : false,
+            parseFloat          : false,
+            RangeError          : false,
+            ReferenceError      : false,
+            RegExp              : false,
+            String              : false,
+            SyntaxError         : false,
+            TypeError           : false,
+            URIError            : false
+        },
+
+        standard_member = {
+            E                   : true,
+            LN2                 : true,
+            LN10                : true,
+            LOG2E               : true,
+            LOG10E              : true,
+            PI                  : true,
+            SQRT1_2             : true,
+            SQRT2               : true,
+            MAX_VALUE           : true,
+            MIN_VALUE           : true,
+            NEGATIVE_INFINITY   : true,
+            POSITIVE_INFINITY   : true
+        },
+
+        strict_mode,
+        syntax = {},
+        tab,
+        token,
+        urls,
+        warnings,
+
+// widget contains the global names which are provided to a Yahoo
+// (fna Konfabulator) widget.
+
+        widget = {
+            alert                   : true,
+            animator                : true,
+            appleScript             : true,
+            beep                    : true,
+            bytesToUIString         : true,
+            Canvas                  : true,
+            chooseColor             : true,
+            chooseFile              : true,
+            chooseFolder            : true,
+            closeWidget             : true,
+            COM                     : true,
+            convertPathToHFS        : true,
+            convertPathToPlatform   : true,
+            CustomAnimation         : true,
+            escape                  : true,
+            FadeAnimation           : true,
+            filesystem              : true,
+            Flash                   : true,
+            focusWidget             : true,
+            form                    : true,
+            FormField               : true,
+            Frame                   : true,
+            HotKey                  : true,
+            Image                   : true,
+            include                 : true,
+            isApplicationRunning    : true,
+            iTunes                  : true,
+            konfabulatorVersion     : true,
+            log                     : true,
+            md5                     : true,
+            MenuItem                : true,
+            MoveAnimation           : true,
+            openURL                 : true,
+            play                    : true,
+            Point                   : true,
+            popupMenu               : true,
+            preferenceGroups        : true,
+            preferences             : true,
+            print                   : true,
+            prompt                  : true,
+            random                  : true,
+            Rectangle               : true,
+            reloadWidget            : true,
+            ResizeAnimation         : true,
+            resolvePath             : true,
+            resumeUpdates           : true,
+            RotateAnimation         : true,
+            runCommand              : true,
+            runCommandInBg          : true,
+            saveAs                  : true,
+            savePreferences         : true,
+            screen                  : true,
+            ScrollBar               : true,
+            showWidgetPreferences   : true,
+            sleep                   : true,
+            speak                   : true,
+            Style                   : true,
+            suppressUpdates         : true,
+            system                  : true,
+            tellWidget              : true,
+            Text                    : true,
+            TextArea                : true,
+            Timer                   : true,
+            unescape                : true,
+            updateNow               : true,
+            URL                     : true,
+            Web                     : true,
+            widget                  : true,
+            Window                  : true,
+            XMLDOM                  : true,
+            XMLHttpRequest          : true,
+            yahooCheckLogin         : true,
+            yahooLogin              : true,
+            yahooLogout             : true
+        },
+
+//  xmode is used to adapt to the exceptions in html parsing.
+//  It can have these states:
+//      false   .js script file
+//      html
+//      outer
+//      script
+//      style
+//      scriptstring
+//      styleproperty
+
+        xmode,
+        xquote,
+
+// unsafe comment or string
+        ax = /@cc|<\/?|script|\]*s\]|<\s*!|&lt/i,
+// unsafe characters that are silently deleted by one or more browsers
+        cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,
+// token
+        tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jslint|members?|global)?|=|\/)?|\*[\/=]?|\+[+=]?|-[\-=]?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,
+// html token
+////////        hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-]*|[0-9]+|--|.)/,
+        hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-]*|[0-9]+|--)/,
+// characters in strings that need escapement
+        nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,
+        nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+// outer html token
+        ox = /[>&]|<[\/!]?|--/,
+// star slash
+        lx = /\*\/|\/\*/,
+// identifier
+        ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,
+// javascript url
+        jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i,
+// url badness
+        ux = /&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i,
+// style
+        sx = /^\s*([{:#%.=,>+\[\]@()"';]|\*=?|\$=|\|=|\^=|~=|[a-zA-Z_][a-zA-Z0-9_\-]*|[0-9]+|<\/|\/\*)/,
+        ssx = /^\s*([@#!"'};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|\d+(?:\.\d+)?|<\/)/,
+// attributes characters
+        qx = /[^a-zA-Z0-9-_\/ ]/,
+// query characters for ids
+        dx = /[\[\]\/\\"'*<>.&:(){}+=#]/,
+
+        rx = {
+            outer: hx,
+            html: hx,
+            style: sx,
+            styleproperty: ssx
+        };
+
+    function F() {}
+
+    if (typeof Object.create !== 'function') {
+        Object.create = function (o) {
+            F.prototype = o;
+            return new F();
+        };
+    }
+
+
+    function is_own(object, name) {
+        return Object.prototype.hasOwnProperty.call(object, name);
+    }
+
+
+    function combine(t, o) {
+        var n;
+        for (n in o) {
+            if (is_own(o, n)) {
+                t[n] = o[n];
+            }
+        }
+    }
+
+    String.prototype.entityify = function () {
+        return this.
+            replace(/&/g, '&amp;').
+            replace(/</g, '&lt;').
+            replace(/>/g, '&gt;');
+    };
+
+    String.prototype.isAlpha = function () {
+        return (this >= 'a' && this <= 'z\uffff') ||
+            (this >= 'A' && this <= 'Z\uffff');
+    };
+
+
+    String.prototype.isDigit = function () {
+        return (this >= '0' && this <= '9');
+    };
+
+
+    String.prototype.supplant = function (o) {
+        return this.replace(/\{([^{}]*)\}/g, function (a, b) {
+            var r = o[b];
+            return typeof r === 'string' || typeof r === 'number' ? r : a;
+        });
+    };
+
+    String.prototype.name = function () {
+
+// If the string looks like an identifier, then we can return it as is.
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can simply slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe
+// sequences.
+
+        if (ix.test(this)) {
+            return this;
+        }
+        if (nx.test(this)) {
+            return '"' + this.replace(nxg, function (a) {
+                var c = escapes[a];
+                if (c) {
+                    return c;
+                }
+                return '\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4);
+            }) + '"';
+        }
+        return '"' + this + '"';
+    };
+
+
+    function assume() {
+        if (!option.safe) {
+            if (option.rhino) {
+                combine(predefined, rhino);
+            }
+            if (option.devel) {
+                combine(predefined, devel);
+            }
+            if (option.browser || option.sidebar) {
+                combine(predefined, browser);
+            }
+            if (option.sidebar) {
+                combine(predefined, sidebar);
+            }
+            if (option.widget) {
+                combine(predefined, widget);
+            }
+        }
+    }
+
+
+// Produce an error warning.
+
+    function quit(m, l, ch) {
+        throw {
+            name: 'JSLintError',
+            line: l,
+            character: ch,
+            message: m + " (" + Math.floor((l / lines.length) * 100) +
+                    "% scanned)."
+        };
+    }
+
+    function warning(m, t, a, b, c, d) {
+        var ch, l, w;
+        t = t || nexttoken;
+        if (t.id === '(end)') {  // `~
+            t = token;
+        }
+        l = t.line || 0;
+        ch = t.from || 0;
+        w = {
+            id: '(error)',
+            raw: m,
+            evidence: lines[l - 1] || '',
+            line: l,
+            character: ch,
+            a: a,
+            b: b,
+            c: c,
+            d: d
+        };
+        w.reason = m.supplant(w);
+        JSLINT.errors.push(w);
+        if (option.passfail) {
+            quit('Stopping. ', l, ch);
+        }
+        warnings += 1;
+        if (warnings >= option.maxerr) {
+            quit("Too many errors.", l, ch);
+        }
+        return w;
+    }
+
+    function warningAt(m, l, ch, a, b, c, d) {
+        return warning(m, {
+            line: l,
+            from: ch
+        }, a, b, c, d);
+    }
+
+    function error(m, t, a, b, c, d) {
+        var w = warning(m, t, a, b, c, d);
+        quit("Stopping, unable to continue.", w.line, w.character);
+    }
+
+    function errorAt(m, l, ch, a, b, c, d) {
+        return error(m, {
+            line: l,
+            from: ch
+        }, a, b, c, d);
+    }
+
+
+
+// lexical analysis
+
+    var lex = (function lex() {
+        var character, from, line, s;
+
+// Private lex methods
+
+        function nextLine() {
+            var at;
+            if (line >= lines.length) {
+                return false;
+            }
+            character = 1;
+            s = lines[line];
+            line += 1;
+            at = s.search(/ \t/);
+            if (at >= 0) {
+                warningAt("Mixed spaces and tabs.", line, at + 1);
+            }
+            s = s.replace(/\t/g, tab);
+            at = s.search(cx);
+            if (at >= 0) {
+                warningAt("Unsafe character.", line, at);
+            }
+            if (option.maxlen && option.maxlen < s.length) {
+                warningAt("Line too long.", line, s.length);
+            }
+            return true;
+        }
+
+// Produce a token object.  The token inherits from a syntax symbol.
+
+        function it(type, value) {
+            var i, t;
+            if (type === '(color)') {
+                t = {type: type};
+            } else if (type === '(punctuator)' ||
+                    (type === '(identifier)' && is_own(syntax, value))) {
+                t = syntax[value] || syntax['(error)'];
+            } else {
+                t = syntax[type];
+            }
+            t = Object.create(t);
+            if (type === '(string)' || type === '(range)') {
+                if (jx.test(value)) {
+                    warningAt("Script URL.", line, from);
+                }
+            }
+            if (type === '(identifier)') {
+                t.identifier = true;
+                if (value === '__iterator__' || value === '__proto__') {
+                    errorAt("Reserved name '{a}'.",
+                        line, from, value);
+                } else if (option.nomen &&
+                        (value.charAt(0) === '_' ||
+                         value.charAt(value.length - 1) === '_')) {
+                    warningAt("Unexpected {a} in '{b}'.", line, from,
+                        "dangling '_'", value);
+                }
+            }
+            t.value = value;
+            t.line = line;
+            t.character = character;
+            t.from = from;
+            i = t.id;
+            if (i !== '(endline)') {
+                prereg = i &&
+                    (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) ||
+                    i === 'return');
+            }
+            return t;
+        }
+
+// Public lex methods
+
+        return {
+            init: function (source) {
+                if (typeof source === 'string') {
+                    lines = source.
+                        replace(/\r\n/g, '\n').
+                        replace(/\r/g, '\n').
+                        split('\n');
+                } else {
+                    lines = source;
+                }
+                line = 0;
+                nextLine();
+                from = 1;
+            },
+
+            range: function (begin, end) {
+                var c, value = '';
+                from = character;
+                if (s.charAt(0) !== begin) {
+                    errorAt("Expected '{a}' and instead saw '{b}'.",
+                            line, character, begin, s.charAt(0));
+                }
+                for (;;) {
+                    s = s.slice(1);
+                    character += 1;
+                    c = s.charAt(0);
+                    switch (c) {
+                    case '':
+                        errorAt("Missing '{a}'.", line, character, c);
+                        break;
+                    case end:
+                        s = s.slice(1);
+                        character += 1;
+                        return it('(range)', value);
+                    case xquote:
+                    case '\\':
+                        warningAt("Unexpected '{a}'.", line, character, c);
+                    }
+                    value += c;
+                }
+
+            },
+
+// token -- this is called by advance to get the next token.
+
+            token: function () {
+                var b, c, captures, d, depth, high, i, l, low, q, t;
+
+                function match(x) {
+                    var r = x.exec(s), r1;
+                    if (r) {
+                        l = r[0].length;
+                        r1 = r[1];
+                        c = r1.charAt(0);
+                        s = s.substr(l);
+                        from = character + l - r1.length;
+                        character += l;
+                        return r1;
+                    }
+                }
+
+                function string(x) {
+                    var c, j, r = '';
+
+                    if (jsonmode && x !== '"') {
+                        warningAt("Strings must use doublequote.",
+                                line, character);
+                    }
+
+                    if (xquote === x || (xmode === 'scriptstring' && !xquote)) {
+                        return it('(punctuator)', x);
+                    }
+
+                    function esc(n) {
+                        var i = parseInt(s.substr(j + 1, n), 16);
+                        j += n;
+                        if (i >= 32 && i <= 126 &&
+                                i !== 34 && i !== 92 && i !== 39) {
+                            warningAt("Unnecessary escapement.", line, character);
+                        }
+                        character += n;
+                        c = String.fromCharCode(i);
+                    }
+                    j = 0;
+                    for (;;) {
+                        while (j >= s.length) {
+                            j = 0;
+                            if (xmode !== 'html' || !nextLine()) {
+                                errorAt("Unclosed string.", line, from);
+                            }
+                        }
+                        c = s.charAt(j);
+                        if (c === x) {
+                            character += 1;
+                            s = s.substr(j + 1);
+                            return it('(string)', r, x);
+                        }
+                        if (c < ' ') {
+                            if (c === '\n' || c === '\r') {
+                                break;
+                            }
+                            warningAt("Control character in string: {a}.",
+                                    line, character + j, s.slice(0, j));
+                        } else if (c === xquote) {
+                            warningAt("Bad HTML string", line, character + j);
+                        } else if (c === '<') {
+                            if (option.safe && xmode === 'html') {
+                                warningAt("ADsafe string violation.",
+                                        line, character + j);
+                            } else if (s.charAt(j + 1) === '/' && (xmode || option.safe)) {
+                                warningAt("Expected '<\\/' and instead saw '</'.", line, character);
+                            } else if (s.charAt(j + 1) === '!' && (xmode || option.safe)) {
+                                warningAt("Unexpected '<!' in a string.", line, character);
+                            }
+                        } else if (c === '\\') {
+                            if (xmode === 'html') {
+                                if (option.safe) {
+                                    warningAt("ADsafe string violation.",
+                                            line, character + j);
+                                }
+                            } else if (xmode === 'styleproperty') {
+                                j += 1;
+                                character += 1;
+                                c = s.charAt(j);
+                                if (c !== x) {
+                                    warningAt("Escapement in style string.",
+                                            line, character + j);
+                                }
+                            } else {
+                                j += 1;
+                                character += 1;
+                                c = s.charAt(j);