text: "use strict";
  "no use strict";
  
  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  
  ;(function (window) {
  	if (typeof window.window != "undefined" && window.document) {
  		return;
  	}
  
  	window.console = function () {
  		var msgs = Array.prototype.slice.call(arguments, 0);
  		postMessage({ type: "log", data: msgs });
  	};
  	window.console.error = window.console.warn = window.console.log = window.console.trace = window.console;
  
  	window.window = window;
  	window.ace = window;
  
  	window.onerror = function (message, file, line, col, err) {
  		console.error("Worker " + (err ? err.stack : message));
  	};
  
  	window.normalizeModule = function (parentId, moduleName) {
  		if (moduleName.indexOf("!") !== -1) {
  			var chunks = moduleName.split("!");
  			return window.normalizeModule(parentId, chunks[0]) + "!" + window.normalizeModule(parentId, chunks[1]);
  		}
  		if (moduleName.charAt(0) == ".") {
  			var base = parentId.split("/").slice(0, -1).join("/");
  			moduleName = (base ? base + "/" : "") + moduleName;
  
  			while (moduleName.indexOf(".") !== -1 && previous != moduleName) {
  				var previous = moduleName;
  				moduleName = moduleName.replace(/^\.\//, "").replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, "");
  			}
  		}
  
  		return moduleName;
  	};
  
  	window.require = function (parentId, id) {
  		if (!id) {
  			id = parentId;
  			parentId = null;
  		}
  		if (!id.charAt) throw new Error("worker.js require() accepts only (parentId, id) as arguments");
  
  		id = window.normalizeModule(parentId, id);
  
  		var module = window.require.modules[id];
  		if (module) {
  			if (!module.initialized) {
  				module.initialized = true;
  				module.exports = module.factory().exports;
  			}
  			return module.exports;
  		}
  
  		var chunks = id.split("/");
  		if (!window.require.tlns) return console.log("unable to load " + id);
  		chunks[0] = window.require.tlns[chunks[0]] || chunks[0];
  		var path = chunks.join("/") + ".js";
  
  		window.require.id = id;
  		importScripts(path);
  		return window.require(parentId, id);
  	};
  	window.require.modules = {};
  	window.require.tlns = {};
  
  	window.define = function (id, deps, _factory) {
  		if (arguments.length == 2) {
  			_factory = deps;
  			if (typeof id != "string") {
  				deps = id;
  				id = window.require.id;
  			}
  		} else if (arguments.length == 1) {
  			_factory = id;
  			deps = [];
  			id = window.require.id;
  		}
  
  		if (!deps.length) deps = ['require', 'exports', 'module'];
  
  		if (id.indexOf("text!") === 0) return;
  
  		var req = function req(childId) {
  			return window.require(id, childId);
  		};
  
  		window.require.modules[id] = {
  			exports: {},
  			factory: function factory() {
  				var module = this;
  				var returnExports = _factory.apply(this, deps.map(function (dep) {
  					switch (dep) {
  						case 'require':
  							return req;
  						case 'exports':
  							return module.exports;
  						case 'module':
  							return module;
  						default:
  							return req(dep);
  					}
  				}));
  				if (returnExports) module.exports = returnExports;
  				return module;
  			}
  		};
  	};
  	window.define.amd = {};
  
  	window.initBaseUrls = function initBaseUrls(topLevelNamespaces) {
  		require.tlns = topLevelNamespaces;
  	};
  
  	window.initSender = function initSender() {
  
  		var EventEmitter = window.require("ace/lib/event_emitter").EventEmitter;
  		var oop = window.require("ace/lib/oop");
  
  		var Sender = function Sender() {};
  
  		(function () {
  
  			oop.implement(this, EventEmitter);
  
  			this.callback = function (data, callbackId) {
  				postMessage({
  					type: "call",
  					id: callbackId,
  					data: data
  				});
  			};
  
  			this.emit = function (name, data) {
  				postMessage({
  					type: "event",
  					name: name,
  					data: data
  				});
  			};
  		}).call(Sender.prototype);
  
  		return new Sender();
  	};
  
  	var main = window.main = null;
  	var sender = window.sender = null;
  
  	window.onmessage = function (e) {
  		var msg = e.data;
  		if (msg.command) {
  			if (main[msg.command]) main[msg.command].apply(main, msg.args);else throw new Error("Unknown command:" + msg.command);
  		} else if (msg.init) {
  			initBaseUrls(msg.tlns);
  			require("ace/lib/es5-shim");
  			sender = window.sender = initSender();
  			var clazz = require(msg.module)[msg.classname];
  			main = window.main = new clazz(sender);
  		} else if (msg.event && sender) {
  			sender._signal(msg.event, msg.data);
  		}
  	};
  })(undefined);
  
  define('ace/mode/javascript_worker', ['require', 'exports', 'module', 'ace/lib/oop', 'ace/worker/mirror', 'ace/mode/javascript/jshint'], function (require, exports, module) {
  
  	var oop = require("../lib/oop");
  	var Mirror = require("../worker/mirror").Mirror;
  	var lint = require("./javascript/jshint").JSHINT;
  
  	function startRegex(arr) {
  		return RegExp("^(" + arr.join("|") + ")");
  	}
  
  	var disabledWarningsRe = startRegex(["Bad for in variable '(.+)'.", 'Missing "use strict"']);
  	var errorsRe = startRegex(["Unexpected", "Expected ", "Confusing (plus|minus)", "\\{a\\} unterminated regular expression", "Unclosed ", "Unmatched ", "Unbegun comment", "Bad invocation", "Missing space after", "Missing operator at"]);
  	var infoRe = startRegex(["Expected an assignment", "Bad escapement of EOL", "Unexpected comma", "Unexpected space", "Missing radix parameter.", "A leading decimal point can", "\\['{a}'\\] is better written in dot notation.", "'{a}' used out of scope"]);
  
  	var JavaScriptWorker = exports.JavaScriptWorker = function (sender) {
  		Mirror.call(this, sender);
  		this.setTimeout(500);
  		this.setOptions();
  	};
  
  	oop.inherits(JavaScriptWorker, Mirror);
  
  	(function () {
  		this.setOptions = function (options) {
  			this.options = options || {
  				esnext: true,
  				moz: true,
  				devel: true,
  				browser: true,
  				node: true,
  				laxcomma: true,
  				laxbreak: true,
  				lastsemic: true,
  				onevar: false,
  				passfail: false,
  				maxerr: 100,
  				expr: true,
  				multistr: true,
  				globalstrict: true
  			};
  			this.doc.getValue() && this.deferredUpdate.schedule(100);
  		};
  
  		this.changeOptions = function (newOptions) {
  			oop.mixin(this.options, newOptions);
  			this.doc.getValue() && this.deferredUpdate.schedule(100);
  		};
  
  		this.isValidJS = function (str) {
  			try {
  				eval("throw 0;" + str);
  			} catch (e) {
  				if (e === 0) return true;
  			}
  			return false;
  		};
  
  		this.onUpdate = function () {
  			var value = this.doc.getValue();
  			value = value.replace(/^#!.*\n/, "\n");
  			if (!value) {
  				this.sender.emit("jslint", []);
  				return;
  			}
  			var errors = [];
  			var maxErrorLevel = this.isValidJS(value) ? "warning" : "error";
  			lint(value, this.options);
  			var results = lint.errors;
  
  			var errorAdded = false;
  			for (var i = 0; i < results.length; i++) {
  				var error = results[i];
  				if (!error) continue;
  				var raw = error.raw;
  				var type = "warning";
  
  				if (raw == "Missing semicolon.") {
  					var str = error.evidence.substr(error.character);
  					str = str.charAt(str.search(/\S/));
  					if (maxErrorLevel == "error" && str && /[\w\d{(['"]/.test(str)) {
  						error.reason = 'Missing ";" before statement';
  						type = "error";
  					} else {
  						type = "info";
  					}
  				} else if (disabledWarningsRe.test(raw)) {
  					continue;
  				} else if (infoRe.test(raw)) {
  					type = "info";
  				} else if (errorsRe.test(raw)) {
  					errorAdded = true;
  					type = maxErrorLevel;
  				} else if (raw == "'{a}' is not defined.") {
  					type = "warning";
  				} else if (raw == "'{a}' is defined but never used.") {
  					type = "info";
  				}
  
  				errors.push({
  					row: error.line - 1,
  					column: error.character - 1,
  					text: error.reason,
  					type: type,
  					raw: raw
  				});
  
  				if (errorAdded) {}
  			}
  
  			this.sender.emit("jslint", errors);
  		};
  	}).call(JavaScriptWorker.prototype);
  });
  
  define('ace/lib/oop', ['require', 'exports', 'module'], function (require, exports, module) {
  
  	exports.inherits = function (ctor, superCtor) {
  		ctor.super_ = superCtor;
  		ctor.prototype = Object.create(superCtor.prototype, {
  			constructor: {
  				value: ctor,
  				enumerable: false,
  				writable: true,
  				configurable: true
  			}
  		});
  	};
  
  	exports.mixin = function (obj, mixin) {
  		for (var key in mixin) {
  			obj[key] = mixin[key];
  		}
  		return obj;
  	};
  
  	exports.implement = function (proto, mixin) {
  		exports.mixin(proto, mixin);
  	};
  });
  define('ace/worker/mirror', ['require', 'exports', 'module', 'ace/document', 'ace/lib/lang'], function (require, exports, module) {
  
  	var Document = require("../document").Document;
  	var lang = require("../lib/lang");
  
  	var Mirror = exports.Mirror = function (sender) {
  		this.sender = sender;
  		var doc = this.doc = new Document("");
  
  		var deferredUpdate = this.deferredUpdate = lang.delayedCall(this.onUpdate.bind(this));
  
  		var _self = this;
  		sender.on("change", function (e) {
  			doc.applyDeltas(e.data);
  			if (_self.$timeout) return deferredUpdate.schedule(_self.$timeout);
  			_self.onUpdate();
  		});
  	};
  
  	(function () {
  
  		this.$timeout = 500;
  
  		this.setTimeout = function (timeout) {
  			this.$timeout = timeout;
  		};
  
  		this.setValue = function (value) {
  			this.doc.setValue(value);
  			this.deferredUpdate.schedule(this.$timeout);
  		};
  
  		this.getValue = function (callbackId) {
  			this.sender.callback(this.doc.getValue(), callbackId);
  		};
  
  		this.onUpdate = function () {};
  
  		this.isPending = function () {
  			return this.deferredUpdate.isPending();
  		};
  	}).call(Mirror.prototype);
  });
  
  define('ace/lib/es5-shim', ['require', 'exports', 'module'], function (require, exports, module) {
  
  	function Empty() {}
  
  	if (!Function.prototype.bind) {
  		Function.prototype.bind = function bind(that) {
  			// .length is 1
  			var target = this;
  			if (typeof target != "function") {
  				throw new TypeError("Function.prototype.bind called on incompatible " + target);
  			}
  			var args = slice.call(arguments, 1); // for normal call
  			var bound = function bound() {
  
  				if (this instanceof bound) {
  
  					var result = target.apply(this, args.concat(slice.call(arguments)));
  					if (Object(result) === result) {
  						return result;
  					}
  					return this;
  				} else {
  					return target.apply(that, args.concat(slice.call(arguments)));
  				}
  			};
  			if (target.prototype) {
  				Empty.prototype = target.prototype;
  				bound.prototype = new Empty();
  				Empty.prototype = null;
  			}
  			return bound;
  		};
  	}
  	var call = Function.prototype.call;
  	var prototypeOfArray = Array.prototype;
  	var prototypeOfObject = Object.prototype;
  	var slice = prototypeOfArray.slice;
  	var _toString = call.bind(prototypeOfObject.toString);
  	var owns = call.bind(prototypeOfObject.hasOwnProperty);
  	var defineGetter;
  	var defineSetter;
  	var lookupGetter;
  	var lookupSetter;
  	var supportsAccessors;
  	if (supportsAccessors = owns(prototypeOfObject, "__defineGetter__")) {
  		defineGetter = call.bind(prototypeOfObject.__defineGetter__);
  		defineSetter = call.bind(prototypeOfObject.__defineSetter__);
  		lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
  		lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
  	}
  	if ([1, 2].splice(0).length != 2) {
  		if (function () {
  			// test IE < 9 to splice bug - see issue #138
  			function makeArray(l) {
  				var a = new Array(l + 2);
  				a[0] = a[1] = 0;
  				return a;
  			}
  			var array = [],
  			    lengthBefore;
  
  			array.splice.apply(array, makeArray(20));
  			array.splice.apply(array, makeArray(26));
  
  			lengthBefore = array.length; //46
  			array.splice(5, 0, "XXX"); // add one element
  
  			lengthBefore + 1 == array.length;
  
  			if (lengthBefore + 1 == array.length) {
  				return true; // has right splice implementation without bugs
  			}
  		}()) {
  			//IE 6/7
  			var array_splice = Array.prototype.splice;
  			Array.prototype.splice = function (start, deleteCount) {
  				if (!arguments.length) {
  					return [];
  				} else {
  					return array_splice.apply(this, [start === void 0 ? 0 : start, deleteCount === void 0 ? this.length - start : deleteCount].concat(slice.call(arguments, 2)));
  				}
  			};
  		} else {
  			//IE8
  			Array.prototype.splice = function (pos, removeCount) {
  				var length = this.length;
  				if (pos > 0) {
  					if (pos > length) pos = length;
  				} else if (pos == void 0) {
  					pos = 0;
  				} else if (pos < 0) {
  					pos = Math.max(length + pos, 0);
  				}
  
  				if (!(pos + removeCount < length)) removeCount = length - pos;
  
  				var removed = this.slice(pos, pos + removeCount);
  				var insert = slice.call(arguments, 2);
  				var add = insert.length;
  				if (pos === length) {
  					if (add) {
  						this.push.apply(this, insert);
  					}
  				} else {
  					var remove = Math.min(removeCount, length - pos);
  					var tailOldPos = pos + remove;
  					var tailNewPos = tailOldPos + add - remove;
  					var tailCount = length - tailOldPos;
  					var lengthAfterRemove = length - remove;
  
  					if (tailNewPos < tailOldPos) {
  						// case A
  						for (var i = 0; i < tailCount; ++i) {
  							this[tailNewPos + i] = this[tailOldPos + i];
  						}
  					} else if (tailNewPos > tailOldPos) {
  						// case B
  						for (i = tailCount; i--;) {
  							this[tailNewPos + i] = this[tailOldPos + i];
  						}
  					} // else, add == remove (nothing to do)
  
  					if (add && pos === lengthAfterRemove) {
  						this.length = lengthAfterRemove; // truncate array
  						this.push.apply(this, insert);
  					} else {
  						this.length = lengthAfterRemove + add; // reserves space
  						for (i = 0; i < add; ++i) {
  							this[pos + i] = insert[i];
  						}
  					}
  				}
  				return removed;
  			};
  		}
  	}
  	if (!Array.isArray) {
  		Array.isArray = function isArray(obj) {
  			return _toString(obj) == "[object Array]";
  		};
  	}
  	var boxedString = Object("a"),
  	    splitString = boxedString[0] != "a" || !(0 in boxedString);
  
  	if (!Array.prototype.forEach) {
  		Array.prototype.forEach = function forEach(fun /*, thisp*/) {
  			var object = toObject(this),
  			    self = splitString && _toString(this) == "[object String]" ? this.split("") : object,
  			    thisp = arguments[1],
  			    i = -1,
  			    length = self.length >>> 0;
  			if (_toString(fun) != "[object Function]") {
  				throw new TypeError(); // TODO message
  			}
  
  			while (++i < length) {
  				if (i in self) {
  					fun.call(thisp, self[i], i, object);
  				}
  			}
  		};
  	}
  	if (!Array.prototype.map) {
  		Array.prototype.map = function map(fun /*, thisp*/) {
  			var object = toObject(this),
  			    self = splitString && _toString(this) == "[object String]" ? this.split("") : object,
  			    length = self.length >>> 0,
  			    result = Array(length),
  			    thisp = arguments[1];
  			if (_toString(fun) != "[object Function]") {
  				throw new TypeError(fun + " is not a function");
  			}
  
  			for (var i = 0; i < length; i++) {
  				if (i in self) result[i] = fun.call(thisp, self[i], i, object);
  			}
  			return result;
  		};
  	}
  	if (!Array.prototype.filter) {
  		Array.prototype.filter = function filter(fun /*, thisp */) {
  			var object = toObject(this),
  			    self = splitString && _toString(this) == "[object String]" ? this.split("") : object,
  			    length = self.length >>> 0,
  			    result = [],
  			    value,
  			    thisp = arguments[1];
  			if (_toString(fun) != "[object Function]") {
  				throw new TypeError(fun + " is not a function");
  			}
  
  			for (var i = 0; i < length; i++) {
  				if (i in self) {
  					value = self[i];
  					if (fun.call(thisp, value, i, object)) {
  						result.push(value);
  					}
  				}
  			}
  			return result;
  		};
  	}
  	if (!Array.prototype.every) {
  		Array.prototype.every = function every(fun /*, thisp */) {
  			var object = toObject(this),
  			    self = splitString && _toString(this) == "[object String]" ? this.split("") : object,
  			    length = self.length >>> 0,
  			    thisp = arguments[1];
  			if (_toString(fun) != "[object Function]") {
  				throw new TypeError(fun + " is not a function");
  			}
  
  			for (var i = 0; i < length; i++) {
  				if (i in self && !fun.call(thisp, self[i], i, object)) {
  					return false;
  				}
  			}
  			return true;
  		};
  	}
  	if (!Array.prototype.some) {
  		Array.prototype.some = function some(fun /*, thisp */) {
  			var object = toObject(this),
  			    self = splitString && _toString(this) == "[object String]" ? this.split("") : object,
  			    length = self.length >>> 0,
  			    thisp = arguments[1];
  			if (_toString(fun) != "[object Function]") {
  				throw new TypeError(fun + " is not a function");
  			}
  
  			for (var i = 0; i < length; i++) {
  				if (i in self && fun.call(thisp, self[i], i, object)) {
  					return true;
  				}
  			}
  			return false;
  		};
  	}
  	if (!Array.prototype.reduce) {
  		Array.prototype.reduce = function reduce(fun /*, initial*/) {
  			var object = toObject(this),
  			    self = splitString && _toString(this) == "[object String]" ? this.split("") : object,
  			    length = self.length >>> 0;
  			if (_toString(fun) != "[object Function]") {
  				throw new TypeError(fun + " is not a function");
  			}
  			if (!length && arguments.length == 1) {
  				throw new TypeError("reduce of empty array with no initial value");
  			}
  
  			var i = 0;
  			var result;
  			if (arguments.length >= 2) {
  				result = arguments[1];
  			} else {
  				do {
  					if (i in self) {
  						result = self[i++];
  						break;
  					}
  					if (++i >= length) {
  						throw new TypeError("reduce of empty array with no initial value");
  					}
  				} while (true);
  			}
  
  			for (; i < length; i++) {
  				if (i in self) {
  					result = fun.call(void 0, result, self[i], i, object);
  				}
  			}
  
  			return result;
  		};
  	}
  	if (!Array.prototype.reduceRight) {
  		Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
  			var object = toObject(this),
  			    self = splitString && _toString(this) == "[object String]" ? this.split("") : object,
  			    length = self.length >>> 0;
  			if (_toString(fun) != "[object Function]") {
  				throw new TypeError(fun + " is not a function");
  			}
  			if (!length && arguments.length == 1) {
  				throw new TypeError("reduceRight of empty array with no initial value");
  			}
  
  			var result,
  			    i = length - 1;
  			if (arguments.length >= 2) {
  				result = arguments[1];
  			} else {
  				do {
  					if (i in self) {
  						result = self[i--];
  						break;
  					}
  					if (--i < 0) {
  						throw new TypeError("reduceRight of empty array with no initial value");
  					}
  				} while (true);
  			}
  
  			do {
  				if (i in this) {
  					result = fun.call(void 0, result, self[i], i, object);
  				}
  			} while (i--);
  
  			return result;
  		};
  	}
  	if (!Array.prototype.indexOf || [0, 1].indexOf(1, 2) != -1) {
  		Array.prototype.indexOf = function indexOf(sought /*, fromIndex */) {
  			var self = splitString && _toString(this) == "[object String]" ? this.split("") : toObject(this),
  			    length = self.length >>> 0;
  
  			if (!length) {
  				return -1;
  			}
  
  			var i = 0;
  			if (arguments.length > 1) {
  				i = toInteger(arguments[1]);
  			}
  			i = i >= 0 ? i : Math.max(0, length + i);
  			for (; i < length; i++) {
  				if (i in self && self[i] === sought) {
  					return i;
  				}
  			}
  			return -1;
  		};
  	}
  	if (!Array.prototype.lastIndexOf || [0, 1].lastIndexOf(0, -3) != -1) {
  		Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
  			var self = splitString && _toString(this) == "[object String]" ? this.split("") : toObject(this),
  			    length = self.length >>> 0;
  
  			if (!length) {
  				return -1;
  			}
  			var i = length - 1;
  			if (arguments.length > 1) {
  				i = Math.min(i, toInteger(arguments[1]));
  			}
  			i = i >= 0 ? i : length - Math.abs(i);
  			for (; i >= 0; i--) {
  				if (i in self && sought === self[i]) {
  					return i;
  				}
  			}
  			return -1;
  		};
  	}
  	if (!Object.getPrototypeOf) {
  		Object.getPrototypeOf = function getPrototypeOf(object) {
  			return object.__proto__ || (object.constructor ? object.constructor.prototype : prototypeOfObject);
  		};
  	}
  	if (!Object.getOwnPropertyDescriptor) {
  		var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " + "non-object: ";
  		Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
  			if ((typeof object === "undefined" ? "undefined" : _typeof(object)) != "object" && typeof object != "function" || object === null) throw new TypeError(ERR_NON_OBJECT + object);
  			if (!owns(object, property)) return;
  
  			var descriptor, getter, setter;
  			descriptor = { enumerable: true, configurable: true };
  			if (supportsAccessors) {
  				var prototype = object.__proto__;
  				object.__proto__ = prototypeOfObject;
  
  				var getter = lookupGetter(object, property);
  				var setter = lookupSetter(object, property);
  				object.__proto__ = prototype;
  
  				if (getter || setter) {
  					if (getter) descriptor.get = getter;
  					if (setter) descriptor.set = setter;
  					return descriptor;
  				}
  			}
  			descriptor.value = object[property];
  			return descriptor;
  		};
  	}
  	if (!Object.getOwnPropertyNames) {
  		Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
  			return Object.keys(object);
  		};
  	}
  	if (!Object.create) {
  		var createEmpty;
  		if (Object.prototype.__proto__ === null) {
  			createEmpty = function createEmpty() {
  				return { "__proto__": null };
  			};
  		} else {
  			createEmpty = function createEmpty() {
  				var empty = {};
  				for (var i in empty) {
  					empty[i] = null;
  				}empty.constructor = empty.hasOwnProperty = empty.propertyIsEnumerable = empty.isPrototypeOf = empty.toLocaleString = empty.toString = empty.valueOf = empty.__proto__ = null;
  				return empty;
  			};
  		}
  
  		Object.create = function create(prototype, properties) {
  			var object;
  			if (prototype === null) {
  				object = createEmpty();
  			} else {
  				if ((typeof prototype === "undefined" ? "undefined" : _typeof(prototype)) != "object") throw new TypeError("typeof prototype[" + (typeof prototype === "undefined" ? "undefined" : _typeof(prototype)) + "] != 'object'");
  				var Type = function Type() {};
  				Type.prototype = prototype;
  				object = new Type();
  				object.__proto__ = prototype;
  			}
  			if (properties !== void 0) Object.defineProperties(object, properties);
  			return object;
  		};
  	}
  
  	function doesDefinePropertyWork(object) {
  		try {
  			Object.defineProperty(object, "sentinel", {});
  			return "sentinel" in object;
  		} catch (exception) {}
  	}
  	if (Object.defineProperty) {
  		var definePropertyWorksOnObject = doesDefinePropertyWork({});
  		var definePropertyWorksOnDom = typeof document == "undefined" || doesDefinePropertyWork(document.createElement("div"));
  		if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
  			var definePropertyFallback = Object.defineProperty;
  		}
  	}
  
  	if (!Object.defineProperty || definePropertyFallback) {
  		var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
  		var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: ";
  		var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " + "on this javascript engine";
  
  		Object.defineProperty = function defineProperty(object, property, descriptor) {
  			if ((typeof object === "undefined" ? "undefined" : _typeof(object)) != "object" && typeof object != "function" || object === null) throw new TypeError(ERR_NON_OBJECT_TARGET + object);
  			if ((typeof descriptor === "undefined" ? "undefined" : _typeof(descriptor)) != "object" && typeof descriptor != "function" || descriptor === null) throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
  			if (definePropertyFallback) {
  				try {
  					return definePropertyFallback.call(Object, object, property, descriptor);
  				} catch (exception) {}
  			}
  			if (owns(descriptor, "value")) {
  
  				if (supportsAccessors && (lookupGetter(object, property) || lookupSetter(object, property))) {
  					var prototype = object.__proto__;
  					object.__proto__ = prototypeOfObject;
  					delete object[property];
  					object[property] = descriptor.value;
  					object.__proto__ = prototype;
  				} else {
  					object[property] = descriptor.value;
  				}
  			} else {
  				if (!supportsAccessors) throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
  				if (owns(descriptor, "get")) defineGetter(object, property, descriptor.get);
  				if (owns(descriptor, "set")) defineSetter(object, property, descriptor.set);
  			}
  
  			return object;
  		};
  	}
  	if (!Object.defineProperties) {
  		Object.defineProperties = function defineProperties(object, properties) {
  			for (var property in properties) {
  				if (owns(properties, property)) Object.defineProperty(object, property, properties[property]);
  			}
  			return object;
  		};
  	}
  	if (!Object.seal) {
  		Object.seal = function seal(object) {
  			return object;
  		};
  	}
  	if (!Object.freeze) {
  		Object.freeze = function freeze(object) {
  			return object;
  		};
  	}
  	try {
  		Object.freeze(function () {});
  	} catch (exception) {
  		Object.freeze = function freeze(freezeObject) {
  			return function freeze(object) {
  				if (typeof object == "function") {
  					return object;
  				} else {
  					return freezeObject(object);
  				}
  			};
  		}(Object.freeze);
  	}
  	if (!Object.preventExtensions) {
  		Object.preventExtensions = function preventExtensions(object) {
  			return object;
  		};
  	}
  	if (!Object.isSealed) {
  		Object.isSealed = function isSealed(object) {
  			return false;
  		};
  	}
  	if (!Object.isFrozen) {
  		Object.isFrozen = function isFrozen(object) {
  			return false;
  		};
  	}
  	if (!Object.isExtensible) {
  		Object.isExtensible = function isExtensible(object) {
  			if (Object(object) === object) {
  				throw new TypeError(); // TODO message
  			}
  			var name = '';
  			while (owns(object, name)) {
  				name += '?';
  			}
  			object[name] = true;
  			var returnValue = owns(object, name);
  			delete object[name];
  			return returnValue;
  		};
  	}
  	if (!Object.keys) {
  		var hasDontEnumBug = true,
  		    dontEnums = ["toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "constructor"],
  		    dontEnumsLength = dontEnums.length;
  
  		for (var key in { "toString": null }) {
  			hasDontEnumBug = false;
  		}
  
  		Object.keys = function keys(object) {
  
  			if ((typeof object === "undefined" ? "undefined" : _typeof(object)) != "object" && typeof object != "function" || object === null) {
  				throw new TypeError("Object.keys called on a non-object");
  			}
  
  			var keys = [];
  			for (var name in object) {
  				if (owns(object, name)) {
  					keys.push(name);
  				}
  			}
  
  			if (hasDontEnumBug) {
  				for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
  					var dontEnum = dontEnums[i];
  					if (owns(object, dontEnum)) {
  						keys.push(dontEnum);
  					}
  				}
  			}
  			return keys;
  		};
  	}
  	if (!Date.now) {
  		Date.now = function now() {
  			return new Date().getTime();
  		};
  	}
  	var ws = "\t\n\x0B\f\r \xA0\u1680\u180E\u2000\u2001\u2002\u2003" + "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" + "\u2029\uFEFF";
  	if (!String.prototype.trim || ws.trim()) {
  		ws = "[" + ws + "]";
  		var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
  		    trimEndRegexp = new RegExp(ws + ws + "*$");
  		String.prototype.trim = function trim() {
  			return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
  		};
  	}
  
  	function toInteger(n) {
  		n = +n;
  		if (n !== n) {
  			// isNaN
  			n = 0;
  		} else if (n !== 0 && n !== 1 / 0 && n !== -(1 / 0)) {
  			n = (n > 0 || -1) * Math.floor(Math.abs(n));
  		}
  		return n;
  	}
  
  	function isPrimitive(input) {
  		var type = typeof input === "undefined" ? "undefined" : _typeof(input);
  		return input === null || type === "undefined" || type === "boolean" || type === "number" || type === "string";
  	}
  
  	function toPrimitive(input) {
  		var val, valueOf, toString;
  		if (isPrimitive(input)) {
  			return input;
  		}
  		valueOf = input.valueOf;
  		if (typeof valueOf === "function") {
  			val = valueOf.call(input);
  			if (isPrimitive(val)) {
  				return val;
  			}
  		}
  		toString = input.toString;
  		if (typeof toString === "function") {
  			val = toString.call(input);
  			if (isPrimitive(val)) {
  				return val;
  			}
  		}
  		throw new TypeError();
  	}
  	var toObject = function toObject(o) {
  		if (o == null) {
  			// this matches both null and undefined
  			throw new TypeError("can't convert " + o + " to object");
  		}
  		return Object(o);
  	};
  });
  
  define('ace/lib/event_emitter', ['require', 'exports', 'module'], function (require, exports, module) {
  
  	var EventEmitter = {};
  	var stopPropagation = function stopPropagation() {
  		this.propagationStopped = true;
  	};
  	var preventDefault = function preventDefault() {
  		this.defaultPrevented = true;
  	};
  
  	EventEmitter._emit = EventEmitter._dispatchEvent = function (eventName, e) {
  		this._eventRegistry || (this._eventRegistry = {});
  		this._defaultHandlers || (this._defaultHandlers = {});
  
  		var listeners = this._eventRegistry[eventName] || [];
  		var defaultHandler = this._defaultHandlers[eventName];
  		if (!listeners.length && !defaultHandler) return;
  
  		if ((typeof e === "undefined" ? "undefined" : _typeof(e)) != "object" || !e) e = {};
  
  		if (!e.type) e.type = eventName;
  		if (!e.stopPropagation) e.stopPropagation = stopPropagation;
  		if (!e.preventDefault) e.preventDefault = preventDefault;
  
  		listeners = listeners.slice();
  		for (var i = 0; i < listeners.length; i++) {
  			listeners[i](e, this);
  			if (e.propagationStopped) break;
  		}
  
  		if (defaultHandler && !e.defaultPrevented) return defaultHandler(e, this);
  	};
  
  	EventEmitter._signal = function (eventName, e) {
  		var listeners = (this._eventRegistry || {})[eventName];
  		if (!listeners) return;
  		listeners = listeners.slice();
  		for (var i = 0; i < listeners.length; i++) {
  			listeners[i](e, this);
  		}
  	};
  
  	EventEmitter.once = function (eventName, callback) {
  		var _self = this;
  		callback && this.addEventListener(eventName, function newCallback() {
  			_self.removeEventListener(eventName, newCallback);
  			callback.apply(null, arguments);
  		});
  	};
  
  	EventEmitter.setDefaultHandler = function (eventName, callback) {
  		var handlers = this._defaultHandlers;
  		if (!handlers) handlers = this._defaultHandlers = { _disabled_: {} };
  
  		if (handlers[eventName]) {
  			var old = handlers[eventName];
  			var disabled = handlers._disabled_[eventName];
  			if (!disabled) handlers._disabled_[eventName] = disabled = [];
  			disabled.push(old);
  			var i = disabled.indexOf(callback);
  			if (i != -1) disabled.splice(i, 1);
  		}
  		handlers[eventName] = callback;
  	};
  	EventEmitter.removeDefaultHandler = function (eventName, callback) {
  		var handlers = this._defaultHandlers;
  		if (!handlers) return;
  		var disabled = handlers._disabled_[eventName];
  
  		if (handlers[eventName] == callback) {
  			var old = handlers[eventName];
  			if (disabled) this.setDefaultHandler(eventName, disabled.pop());
  		} else if (disabled) {
  			var i = disabled.indexOf(callback);
  			if (i != -1) disabled.splice(i, 1);
  		}
  	};
  
  	EventEmitter.on = EventEmitter.addEventListener = function (eventName, callback, capturing) {
  		this._eventRegistry = this._eventRegistry || {};
  
  		var listeners = this._eventRegistry[eventName];
  		if (!listeners) listeners = this._eventRegistry[eventName] = [];
  
  		if (listeners.indexOf(callback) == -1) listeners[capturing ? "unshift" : "push"](callback);
  		return callback;
  	};
  
  	EventEmitter.off = EventEmitter.removeListener = EventEmitter.removeEventListener = function (eventName, callback) {
  		this._eventRegistry = this._eventRegistry || {};
  
  		var listeners = this._eventRegistry[eventName];
  		if (!listeners) return;
  
  		var index = listeners.indexOf(callback);
  		if (index !== -1) listeners.splice(index, 1);
  	};
  
  	EventEmitter.removeAllListeners = function (eventName) {
  		if (this._eventRegistry) this._eventRegistry[eventName] = [];
  	};
  
  	exports.EventEmitter = EventEmitter;
  });
  
  define('ace/range', ['require', 'exports', 'module'], function (require, exports, module) {
  
  	var comparePoints = function comparePoints(p1, p2) {
  		return p1.row - p2.row || p1.column - p2.column;
  	};
  	var Range = function Range(startRow, startColumn, endRow, endColumn) {
  		this.start = {
  			row: startRow,
  			column: startColumn
  		};
  
  		this.end = {
  			row: endRow,
  			column: endColumn
  		};
  	};
  
  	(function () {
  		this.isEqual = function (range) {
  			return this.start.row === range.start.row && this.end.row === range.end.row && this.start.column === range.start.column && this.end.column === range.end.column;
  		};
  		this.toString = function () {
  			return "Range: [" + this.start.row + "/" + this.start.column + "] -> [" + this.end.row + "/" + this.end.column + "]";
  		};
  
  		this.contains = function (row, column) {
  			return this.compare(row, column) == 0;
  		};
  		this.compareRange = function (range) {
  			var cmp,
  			    end = range.end,
  			    start = range.start;
  
  			cmp = this.compare(end.row, end.column);
  			if (cmp == 1) {
  				cmp = this.compare(start.row, start.column);
  				if (cmp == 1) {
  					return 2;
  				} else if (cmp == 0) {
  					return 1;
  				} else {
  					return 0;
  				}
  			} else if (cmp == -1) {
  				return -2;
  			} else {
  				cmp = this.compare(start.row, start.column);
  				if (cmp == -1) {
  					return -1;
  				} else if (cmp == 1) {
  					return 42;
  				} else {
  					return 0;
  				}
  			}
  		};
  		this.comparePoint = function (p) {
  			return this.compare(p.row, p.column);
  		};
  		this.containsRange = function (range) {
  			return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
  		};
  		this.intersects = function (range) {
  			var cmp = this.compareRange(range);
  			return cmp == -1 || cmp == 0 || cmp == 1;
  		};
  		this.isEnd = function (row, column) {
  			return this.end.row == row && this.end.column == column;
  		};
  		this.isStart = function (row, column) {
  			return this.start.row == row && this.start.column == column;
  		};
  		this.setStart = function (row, column) {
  			if ((typeof row === "undefined" ? "undefined" : _typeof(row)) == "object") {
  				this.start.column = row.column;
  				this.start.row = row.row;
  			} else {
  				this.start.row = row;
  				this.start.column = column;
  			}
  		};
  		this.setEnd = function (row, column) {
  			if ((typeof row === "undefined" ? "undefined" : _typeof(row)) == "object") {
  				this.end.column = row.column;
  				this.end.row = row.row;
  			} else {
  				this.end.row = row;
  				this.end.column = column;
  			}
  		};
  		this.inside = function (row, column) {
  			if (this.compare(row, column) == 0) {
  				if (this.isEnd(row, column) || this.isStart(row, column)) {
  					return false;
  				} else {
  					return true;
  				}
  			}
  			return false;
  		};
  		this.insideStart = function (row, column) {
  			if (this.compare(row, column) == 0) {
  				if (this.isEnd(row, column)) {
  					return false;
  				} else {
  					return true;
  				}
  			}
  			return false;
  		};
  		this.insideEnd = function (row, column) {
  			if (this.compare(row, column) == 0) {
  				if (this.isStart(row, column)) {
  					return false;
  				} else {
  					return true;
  				}
  			}
  			return false;
  		};
  		this.compare = function (row, column) {
  			if (!this.isMultiLine()) {
  				if (row === this.start.row) {
  					return column < this.start.column ? -1 : column > this.end.column ? 1 : 0;
  				};
  			}
  
  			if (row < this.start.row) return -1;
  
  			if (row > this.end.row) return 1;
  
  			if (this.start.row === row) return column >= this.start.column ? 0 : -1;
  
  			if (this.end.row === row) return column <= this.end.column ? 0 : 1;
  
  			return 0;
  		};
  		this.compareStart = function (row, column) {
  			if (this.start.row == row && this.start.column == column) {
  				return -1;
  			} else {
  				return this.compare(row, column);
  			}
  		};
  		this.compareEnd = function (row, column) {
  			if (this.end.row == row && this.end.column == column) {
  				return 1;
  			} else {
  				return this.compare(row, column);
  			}
  		};
  		this.compareInside = function (row, column) {
  			if (this.end.row == row && this.end.column == column) {
  				return 1;
  			} else if (this.start.row == row && this.start.column == column) {
  				return -1;
  			} else {
  				return this.compare(row, column);
  			}
  		};
  		this.clipRows = function (firstRow, lastRow) {
  			if (this.end.row > lastRow) var end = { row: lastRow + 1, column: 0 };else if (this.end.row < firstRow) var end = { row: firstRow, column: 0 };
  
  			if (this.start.row > lastRow) var start = { row: lastRow + 1, column: 0 };else if (this.start.row < firstRow) var start = { row: firstRow, column: 0 };
  
  			return Range.fromPoints(start || this.start, end || this.end);
  		};
  		this.extend = function (row, column) {
  			var cmp = this.compare(row, column);
  
  			if (cmp == 0) return this;else if (cmp == -1) var start = { row: row, column: column };else var end = { row: row, column: column };
  
  			return Range.fromPoints(start || this.start, end || this.end);
  		};
  
  		this.isEmpty = function () {
  			return this.start.row === this.end.row && this.start.column === this.end.column;
  		};
  		this.isMultiLine = function () {
  			return this.start.row !== this.end.row;
  		};
  		this.clone = function () {
  			return Range.fromPoints(this.start, this.end);
  		};
  		this.collapseRows = function () {
  			if (this.end.column == 0) return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row - 1), 0);else return new Range(this.start.row, 0, this.end.row, 0);
  		};
  		this.toScreenRange = function (session) {
  			var screenPosStart = session.documentToScreenPosition(this.start);
  			var screenPosEnd = session.documentToScreenPosition(this.end);
  
  			return new Range(screenPosStart.row, screenPosStart.column, screenPosEnd.row, screenPosEnd.column);
  		};
  		this.moveBy = function (row, column) {
  			this.start.row += row;
  			this.start.column += column;
  			this.end.row += row;
  			this.end.column += column;
  		};
  	}).call(Range.prototype);
  	Range.fromPoints = function (start, end) {
  		return new Range(start.row, start.column, end.row, end.column);
  	};
  	Range.comparePoints = comparePoints;
  
  	Range.comparePoints = function (p1, p2) {
  		return p1.row - p2.row || p1.column - p2.column;
  	};
  
  	exports.Range = Range;
  });
  
  define('ace/anchor', ['require', 'exports', 'module', 'ace/lib/oop', 'ace/lib/event_emitter'], function (require, exports, module) {
  
  	var oop = require("./lib/oop");
  	var EventEmitter = require("./lib/event_emitter").EventEmitter;
  
  	var Anchor = exports.Anchor = function (doc, row, column) {
  		this.$onChange = this.onChange.bind(this);
  		this.attach(doc);
  
  		if (typeof column == "undefined") this.setPosition(row.row, row.column);else this.setPosition(row, column);
  	};
  
  	(function () {
  
  		oop.implement(this, EventEmitter);
  		this.getPosition = function () {
  			return this.$clipPositionToDocument(this.row, this.column);
  		};
  		this.getDocument = function () {
  			return this.document;
  		};
  		this.$insertRight = false;
  		this.onChange = function (e) {
  			var delta = e.data;
  			var range = delta.range;
  
  			if (range.start.row == range.end.row && range.start.row != this.row) return;
  
  			if (range.start.row > this.row) return;
  
  			if (range.start.row == this.row && range.start.column > this.column) return;
  
  			var row = this.row;
  			var column = this.column;
  			var start = range.start;
  			var end = range.end;
  
  			if (delta.action === "insertText") {
  				if (start.row === row && start.column <= column) {
  					if (start.column === column && this.$insertRight) {} else if (start.row === end.row) {
  						column += end.column - start.column;
  					} else {
  						column -= start.column;
  						row += end.row - start.row;
  					}
  				} else if (start.row !== end.row && start.row < row) {
  					row += end.row - start.row;
  				}
  			} else if (delta.action === "insertLines") {
  				if (start.row <= row) {
  					row += end.row - start.row;
  				}
  			} else if (delta.action === "removeText") {
  				if (start.row === row && start.column < column) {
  					if (end.column >= column) column = start.column;else column = Math.max(0, column - (end.column - start.column));
  				} else if (start.row !== end.row && start.row < row) {
  					if (end.row === row) column = Math.max(0, column - end.column) + start.column;
  					row -= end.row - start.row;
  				} else if (end.row === row) {
  					row -= end.row - start.row;
  					column = Math.max(0, column - end.column) + start.column;
  				}
  			} else if (delta.action == "removeLines") {
  				if (start.row <= row) {
  					if (end.row <= row) row -= end.row - start.row;else {
  						row = start.row;
  						column = 0;
  					}
  				}
  			}
  
  			this.setPosition(row, column, true);
  		};
  		this.setPosition = function (row, column, noClip) {
  			var pos;
  			if (noClip) {
  				pos = {
  					row: row,
  					column: column
  				};
  			} else {
  				pos = this.$clipPositionToDocument(row, column);
  			}
  
  			if (this.row == pos.row && this.column == pos.column) return;
  
  			var old = {
  				row: this.row,
  				column: this.column
  			};
  
  			this.row = pos.row;
  			this.column = pos.column;
  			this._signal("change", {
  				old: old,
  				value: pos
  			});
  		};
  		this.detach = function () {
  			this.document.removeEventListener("change", this.$onChange);
  		};
  		this.attach = function (doc) {
  			this.document = doc || this.document;
  			this.document.on("change", this.$onChange);
  		};
  		this.$clipPositionToDocument = function (row, column) {
  			var pos = {};
  
  			if (row >= this.document.getLength()) {
  				pos.row = Math.max(0, this.document.getLength() - 1);
  				pos.column = this.document.getLine(pos.row).length;
  			} else if (row < 0) {
  				pos.row = 0;
  				pos.column = 0;
  			} else {
  				pos.row = row;
  				pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));
  			}
  
  			if (column < 0) pos.column = 0;
  
  			return pos;
  		};
  	}).call(Anchor.prototype);
  });
  
  define('ace/lib/lang', ['require', 'exports', 'module'], function (require, exports, module) {
  
  	exports.last = function (a) {
  		return a[a.length - 1];
  	};
  
  	exports.stringReverse = function (string) {
  		return string.split("").reverse().join("");
  	};
  
  	exports.stringRepeat = function (string, count) {
  		var result = '';
  		while (count > 0) {
  			if (count & 1) result += string;
  
  			if (count >>= 1) string += string;
  		}
  		return result;
  	};
  
  	var trimBeginRegexp = /^\s\s*/;
  	var trimEndRegexp = /\s\s*$/;
  
  	exports.stringTrimLeft = function (string) {
  		return string.replace(trimBeginRegexp, '');
  	};
  
  	exports.stringTrimRight = function (string) {
  		return string.replace(trimEndRegexp, '');
  	};
  
  	exports.copyObject = function (obj) {
  		var copy = {};
  		for (var key in obj) {
  			copy[key] = obj[key];
  		}
  		return copy;
  	};
  
  	exports.copyArray = function (array) {
  		var copy = [];
  		for (var i = 0, l = array.length; i < l; i++) {
  			if (array[i] && _typeof(array[i]) == "object") copy[i] = this.copyObject(array[i]);else copy[i] = array[i];
  		}
  		return copy;
  	};
  
  	exports.deepCopy = function (obj) {
  		if ((typeof obj === "undefined" ? "undefined" : _typeof(obj)) !== "object" || !obj) return obj;
  		var cons = obj.constructor;
  		if (cons === RegExp) return obj;
  
  		var copy = cons();
  		for (var key in obj) {
  			if (_typeof(obj[key]) === "object") {
  				copy[key] = exports.deepCopy(obj[key]);
  			} else {
  				copy[key] = obj[key];
  			}
  		}
  		return copy;
  	};
  
  	exports.arrayToMap = function (arr) {
  		var map = {};
  		for (var i = 0; i < arr.length; i++) {
  			map[arr[i]] = 1;
  		}
  		return map;
  	};
  
  	exports.createMap = function (props) {
  		var map = Object.create(null);
  		for (var i in props) {
  			map[i] = props[i];
  		}
  		return map;
  	};
  	exports.arrayRemove = function (array, value) {
  		for (var i = 0; i <= array.length; i++) {
  			if (value === array[i]) {
  				array.splice(i, 1);
  			}
  		}
  	};
  
  	exports.escapeRegExp = function (str) {
  		return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
  	};
  
  	exports.escapeHTML = function (str) {
  		return str.replace(/&/g, "&#38;").replace(/"/g, "&#34;").replace(/'/g, "&#39;").replace(/</g, "&#60;");
  	};
  
  	exports.getMatchOffsets = function (string, regExp) {
  		var matches = [];
  
  		string.replace(regExp, function (str) {
  			matches.push({
  				offset: arguments[arguments.length - 2],
  				length: str.length
  			});
  		});
  
  		return matches;
  	};
  	exports.deferredCall = function (fcn) {
  
  		var timer = null;
  		var callback = function callback() {
  			timer = null;
  			fcn();
  		};
  
  		var deferred = function deferred(timeout) {
  			deferred.cancel();
  			timer = setTimeout(callback, timeout || 0);
  			return deferred;
  		};
  
  		deferred.schedule = deferred;
  
  		deferred.call = function () {
  			this.cancel();
  			fcn();
  			return deferred;
  		};
  
  		deferred.cancel = function () {
  			clearTimeout(timer);
  			timer = null;
  			return deferred;
  		};
  
  		deferred.isPending = function () {
  			return timer;
  		};
  
  		return deferred;
  	};
  
  	exports.delayedCall = function (fcn, defaultTimeout) {
  		var timer = null;
  		var callback = function callback() {
  			timer = null;
  			fcn();
  		};
  
  		var _self = function _self(timeout) {
  			if (timer == null) timer = setTimeout(callback, timeout || defaultTimeout);
  		};
  
  		_self.delay = function (timeout) {
  			timer && clearTimeout(timer);
  			timer = setTimeout(callback, timeout || defaultTimeout);
  		};
  		_self.schedule = _self;
  
  		_self.call = function () {
  			this.cancel();
  			fcn();
  		};
  
  		_self.cancel = function () {
  			timer && clearTimeout(timer);
  			timer = null;
  		};
  
  		_self.isPending = function () {
  			return timer;
  		};
  
  		return _self;
  	};
  });
  define('ace/mode/javascript/jshint', ['require', 'exports', 'module'], function (require, exports, module) {
  	var _ref;
  
  	require = null;
  	require = function e(t, n, r) {
  		function s(o, u) {
  			if (!n[o]) {
  				if (!t[o]) {
  					var a = typeof require == "function" && require;if (!u && a) return a(o, !0);if (i) return i(o, !0);throw new Error("Cannot find module '" + o + "'");
  				}var f = n[o] = { exports: {} };t[o][0].call(f.exports, function (e) {
  					var n = t[o][1][e];return s(n ? n : e);
  				}, f, f.exports, e, t, n, r);
  			}return n[o].exports;
  		}var i = typeof require == "function" && require;for (var o = 0; o < r.length; o++) {
  			s(r[o]);
  		}return s;
  	}((_ref = {
  		9: [function (req, module, exports) {
  			["log", "info", "warn", "error", "time", "timeEnd", "trace", "dir", "assert"].forEach(function (x) {
  				exports[x] = nop;
  			});
  			function nop() {}
  		}, {}],
  		1: [function (req, module, exports) {
  
  			(function () {
  				var root = this;
  				var previousUnderscore = root._;
  				var breaker = {};
  				var ArrayProto = Array.prototype,
  				    ObjProto = Object.prototype,
  				    FuncProto = Function.prototype;
  				var push = ArrayProto.push,
  				    slice = ArrayProto.slice,
  				    concat = ArrayProto.concat,
  				    toString = ObjProto.toString,
  				    hasOwnProperty = ObjProto.hasOwnProperty;
  				var nativeForEach = ArrayProto.forEach,
  				    nativeMap = ArrayProto.map,
  				    nativeReduce = ArrayProto.reduce,
  				    nativeReduceRight = ArrayProto.reduceRight,
  				    nativeFilter = ArrayProto.filter,
  				    nativeEvery = ArrayProto.every,
  				    nativeSome = ArrayProto.some,
  				    nativeIndexOf = ArrayProto.indexOf,
  				    nativeLastIndexOf = ArrayProto.lastIndexOf,
  				    nativeIsArray = Array.isArray,
  				    nativeKeys = Object.keys,
  				    nativeBind = FuncProto.bind;
  				var _ = function _(obj) {
  					if (obj instanceof _) return obj;
  					if (!(this instanceof _)) return new _(obj);
  					this._wrapped = obj;
  				};
  				if (typeof exports !== 'undefined') {
  					if (typeof module !== 'undefined' && module.exports) {
  						exports = module.exports = _;
  					}
  					exports._ = _;
  				} else {
  					root._ = _;
  				}
  				_.VERSION = '1.4.4';
  				var each = _.each = _.forEach = function (obj, iterator, context) {
  					if (obj == null) return;
  					if (nativeForEach && obj.forEach === nativeForEach) {
  						obj.forEach(iterator, context);
  					} else if (obj.length === +obj.length) {
  						for (var i = 0, l = obj.length; i < l; i++) {
  							if (iterator.call(context, obj[i], i, obj) === breaker) return;
  						}
  					} else {
  						for (var key in obj) {
  							if (_.has(obj, key)) {
  								if (iterator.call(context, obj[key], key, obj) === breaker) return;
  							}
  						}
  					}
  				};
  				_.map = _.collect = function (obj, iterator, context) {
  					var results = [];
  					if (obj == null) return results;
  					if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
  					each(obj, function (value, index, list) {
  						results[results.length] = iterator.call(context, value, index, list);
  					});
  					return results;
  				};
  
  				var reduceError = 'Reduce of empty array with no initial value';
  				_.reduce = _.foldl = _.inject = function (obj, iterator, memo, context) {
  					var initial = arguments.length > 2;
  					if (obj == null) obj = [];
  					if (nativeReduce && obj.reduce === nativeReduce) {
  						if (context) iterator = _.bind(iterator, context);
  						return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
  					}
  					each(obj, function (value, index, list) {
  						if (!initial) {
  							memo = value;
  							initial = true;
  						} else {
  							memo = iterator.call(context, memo, value, index, list);
  						}
  					});
  					if (!initial) throw new TypeError(reduceError);
  					return memo;
  				};
  				_.reduceRight = _.foldr = function (obj, iterator, memo, context) {
  					var initial = arguments.length > 2;
  					if (obj == null) obj = [];
  					if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
  						if (context) iterator = _.bind(iterator, context);
  						return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
  					}
  					var length = obj.length;
  					if (length !== +length) {
  						var keys = _.keys(obj);
  						length = keys.length;
  					}
  					each(obj, function (value, index, list) {
  						index = keys ? keys[--length] : --length;
  						if (!initial) {
  							memo = obj[index];
  							initial = true;
  						} else {
  							memo = iterator.call(context, memo, obj[index], index, list);
  						}
  					});
  					if (!initial) throw new TypeError(reduceError);
  					return memo;
  				};
  				_.find = _.detect = function (obj, iterator, context) {
  					var result;
  					any(obj, function (value, index, list) {
  						if (iterator.call(context, value, index, list)) {
  							result = value;
  							return true;
  						}
  					});
  					return result;
  				};
  				_.filter = _.select = function (obj, iterator, context) {
  					var results = [];
  					if (obj == null) return results;
  					if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
  					each(obj, function (value, index, list) {
  						if (iterator.call(context, value, index, list)) results[results.length] = value;
  					});
  					return results;
  				};
  				_.reject = function (obj, iterator, context) {
  					return _.filter(obj, function (value, index, list) {
  						return !iterator.call(context, value, index, list);
  					}, context);
  				};
  				_.every = _.all = function (obj, iterator, context) {
  					iterator || (iterator = _.identity);
  					var result = true;
  					if (obj == null) return result;
  					if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
  					each(obj, function (value, index, list) {
  						if (!(result = result && iterator.call(context, value, index, list))) return breaker;
  					});
  					return !!result;
  				};
  				var any = _.some = _.any = function (obj, iterator, context) {
  					iterator || (iterator = _.identity);
  					var result = false;
  					if (obj == null) return result;
  					if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
  					each(obj, function (value, index, list) {
  						if (result || (result = iterator.call(context, value, index, list))) return breaker;
  					});
  					return !!result;
  				};
  				_.contains = _.include = function (obj, target) {
  					if (obj == null) return false;
  					if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
  					return any(obj, function (value) {
  						return value === target;
  					});
  				};
  				_.invoke = function (obj, method) {
  					var args = slice.call(arguments, 2);
  					var isFunc = _.isFunction(method);
  					return _.map(obj, function (value) {
  						return (isFunc ? method : value[method]).apply(value, args);
  					});
  				};
  				_.pluck = function (obj, key) {
  					return _.map(obj, function (value) {
  						return value[key];
  					});
  				};
  				_.where = function (obj, attrs, first) {
  					if (_.isEmpty(attrs)) return first ? null : [];
  					return _[first ? 'find' : 'filter'](obj, function (value) {
  						for (var key in attrs) {
  							if (attrs[key] !== value[key]) return false;
  						}
  						return true;
  					});
  				};
  				_.findWhere = function (obj, attrs) {
  					return _.where(obj, attrs, true);
  				};
  				_.max = function (obj, iterator, context) {
  					if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
  						return Math.max.apply(Math, obj);
  					}
  					if (!iterator && _.isEmpty(obj)) return -Infinity;
  					var result = { computed: -Infinity, value: -Infinity };
  					each(obj, function (value, index, list) {
  						var computed = iterator ? iterator.call(context, value, index, list) : value;
  						computed >= result.computed && (result = { value: value, computed: computed });
  					});
  					return result.value;
  				};
  				_.min = function (obj, iterator, context) {
  					if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
  						return Math.min.apply(Math, obj);
  					}
  					if (!iterator && _.isEmpty(obj)) return Infinity;
  					var result = { computed: Infinity, value: Infinity };
  					each(obj, function (value, index, list) {
  						var computed = iterator ? iterator.call(context, value, index, list) : value;
  						computed < result.computed && (result = { value: value, computed: computed });
  					});
  					return result.value;
  				};
  				_.shuffle = function (obj) {
  					var rand;
  					var index = 0;
  					var shuffled = [];
  					each(obj, function (value) {
  						rand = _.random(index++);
  						shuffled[index - 1] = shuffled[rand];
  						shuffled[rand] = value;
  					});
  					return shuffled;
  				};
  				var lookupIterator = function lookupIterator(value) {
  					return _.isFunction(value) ? value : function (obj) {
  						return obj[value];
  					};
  				};
  				_.sortBy = function (obj, value, context) {
  					var iterator = lookupIterator(value);
  					return _.pluck(_.map(obj, function (value, index, list) {
  						return {
  							value: value,
  							index: index,
  							criteria: iterator.call(context, value, index, list)
  						};
  					}).sort(function (left, right) {
  						var a = left.criteria;
  						var b = right.criteria;
  						if (a !== b) {
  							if (a > b || a === void 0) return 1;
  							if (a < b || b === void 0) return -1;
  						}
  						return left.index < right.index ? -1 : 1;
  					}), 'value');
  				};
  				var group = function group(obj, value, context, behavior) {
  					var result = {};
  					var iterator = lookupIterator(value || _.identity);
  					each(obj, function (value, index) {
  						var key = iterator.call(context, value, index, obj);
  						behavior(result, key, value);
  					});
  					return result;
  				};
  				_.groupBy = function (obj, value, context) {
  					return group(obj, value, context, function (result, key, value) {
  						(_.has(result, key) ? result[key] : result[key] = []).push(value);
  					});
  				};
  				_.countBy = function (obj, value, context) {
  					return group(obj, value, context, function (result, key) {
  						if (!_.has(result, key)) result[key] = 0;
  						result[key]++;
  					});
  				};
  				_.sortedIndex = function (array, obj, iterator, context) {
  					iterator = iterator == null ? _.identity : lookupIterator(iterator);
  					var value = iterator.call(context, obj);
  					var low = 0,
  					    high = array.length;
  					while (low < high) {
  						var mid = low + high >>> 1;
  						iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
  					}
  					return low;
  				};
  				_.toArray = function (obj) {
  					if (!obj) return [];
  					if (_.isArray(obj)) return slice.call(obj);
  					if (obj.length === +obj.length) return _.map(obj, _.identity);
  					return _.values(obj);
  				};
  				_.size = function (obj) {
  					if (obj == null) return 0;
  					return obj.length === +obj.length ? obj.length : _.keys(obj).length;
  				};
  				_.first = _.head = _.take = function (array, n, guard) {
  					if (array == null) return void 0;
  					return n != null && !guard ? slice.call(array, 0, n) : array[0];
  				};
  				_.initial = function (array, n, guard) {
  					return slice.call(array, 0, array.length - (n == null || guard ? 1 : n));
  				};
  				_.last = function (array, n, guard) {
  					if (array == null) return void 0;
  					if (n != null && !guard) {
  						return slice.call(array, Math.max(array.length - n, 0));
  					} else {
  						return array[array.length - 1];
  					}
  				};
  				_.rest = _.tail = _.drop = function (array, n, guard) {
  					return slice.call(array, n == null || guard ? 1 : n);
  				};
  				_.compact = function (array) {
  					return _.filter(array, _.identity);
  				};
  				var flatten = function flatten(input, shallow, output) {
  					each(input, function (value) {
  						if (_.isArray(value)) {
  							shallow ? push.apply(output, value) : flatten(value, shallow, output);
  						} else {
  							output.push(value);
  						}
  					});
  					return output;
  				};
  				_.flatten = function (array, shallow) {
  					return flatten(array, shallow, []);
  				};
  				_.without = function (array) {
  					return _.difference(array, slice.call(arguments, 1));
  				};
  				_.uniq = _.unique = function (array, isSorted, iterator, context) {
  					if (_.isFunction(isSorted)) {
  						context = iterator;
  						iterator = isSorted;
  						isSorted = false;
  					}
  					var initial = iterator ? _.map(array, iterator, context) : array;
  					var results = [];
  					var seen = [];
  					each(initial, function (value, index) {
  						if (isSorted ? !index || seen[seen.length - 1] !== value : !_.contains(seen, value)) {
  							seen.push(value);
  							results.push(array[index]);
  						}
  					});
  					return results;
  				};
  				_.union = function () {
  					return _.uniq(concat.apply(ArrayProto, arguments));
  				};
  				_.intersection = function (array) {
  					var rest = slice.call(arguments, 1);
  					return _.filter(_.uniq(array), function (item) {
  						return _.every(rest, function (other) {
  							return _.indexOf(other, item) >= 0;
  						});
  					});
  				};
  				_.difference = function (array) {
  					var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
  					return _.filter(array, function (value) {
  						return !_.contains(rest, value);
  					});
  				};
  				_.zip = function () {
  					var args = slice.call(arguments);
  					var length = _.max(_.pluck(args, 'length'));
  					var results = new Array(length);
  					for (var i = 0; i < length; i++) {
  						results[i] = _.pluck(args, "" + i);
  					}
  					return results;
  				};
  				_.object = function (list, values) {
  					if (list == null) return {};
  					var result = {};
  					for (var i = 0, l = list.length; i < l; i++) {
  						if (values) {
  							result[list[i]] = values[i];
  						} else {
  							result[list[i][0]] = list[i][1];
  						}
  					}
  					return result;
  				};
  				_.indexOf = function (array, item, isSorted) {
  					if (array == null) return -1;
  					var i = 0,
  					    l = array.length;
  					if (isSorted) {
  						if (typeof isSorted == 'number') {
  							i = isSorted < 0 ? Math.max(0, l + isSorted) : isSorted;
  						} else {
  							i = _.sortedIndex(array, item);
  							return array[i] === item ? i : -1;
  						}
  					}
  					if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
  					for (; i < l; i++) {
  						if (array[i] === item) return i;
  					}return -1;
  				};
  				_.lastIndexOf = function (array, item, from) {
  					if (array == null) return -1;
  					var hasIndex = from != null;
  					if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
  						return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
  					}
  					var i = hasIndex ? from : array.length;
  					while (i--) {
  						if (array[i] === item) return i;
  					}return -1;
  				};
  				_.range = function (start, stop, step) {
  					if (arguments.length <= 1) {
  						stop = start || 0;
  						start = 0;
  					}
  					step = arguments[2] || 1;
  
  					var len = Math.max(Math.ceil((stop - start) / step), 0);
  					var idx = 0;
  					var range = new Array(len);
  
  					while (idx < len) {
  						range[idx++] = start;
  						start += step;
  					}
  
  					return range;
  				};
  				_.bind = function (func, context) {
  					if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
  					var args = slice.call(arguments, 2);
  					return function () {
  						return func.apply(context, args.concat(slice.call(arguments)));
  					};
  				};
  				_.partial = function (func) {
  					var args = slice.call(arguments, 1);
  					return function () {
  						return func.apply(this, args.concat(slice.call(arguments)));
  					};
  				};
  				_.bindAll = function (obj) {
  					var funcs = slice.call(arguments, 1);
  					if (funcs.length === 0) funcs = _.functions(obj);
  					each(funcs, function (f) {
  						obj[f] = _.bind(obj[f], obj);
  					});
  					return obj;
  				};
  				_.memoize = function (func, hasher) {
  					var memo = {};
  					hasher || (hasher = _.identity);
  					return function () {
  						var key = hasher.apply(this, arguments);
  						return _.has(memo, key) ? memo[key] : memo[key] = func.apply(this, arguments);
  					};
  				};
  				_.delay = function (func, wait) {
  					var args = slice.call(arguments, 2);
  					return setTimeout(function () {
  						return func.apply(null, args);
  					}, wait);
  				};
  				_.defer = function (func) {
  					return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
  				};
  				_.throttle = function (func, wait) {
  					var context, args, timeout, result;
  					var previous = 0;
  					var later = function later() {
  						previous = new Date();
  						timeout = null;
  						result = func.apply(context, args);
  					};
  					return function () {
  						var now = new Date();
  						var remaining = wait - (now - previous);
  						context = this;
  						args = arguments;
  						if (remaining <= 0) {
  							clearTimeout(timeout);
  							timeout = null;
  							previous = now;
  							result = func.apply(context, args);
  						} else if (!timeout) {
  							timeout = setTimeout(later, remaining);
  						}
  						return result;
  					};
  				};
  				_.debounce = function (func, wait, immediate) {
  					var timeout, result;
  					return function () {
  						var context = this,
  						    args = arguments;
  						var later = function later() {
  							timeout = null;
  							if (!immediate) result = func.apply(context, args);
  						};
  						var callNow = immediate && !timeout;
  						clearTimeout(timeout);
  						timeout = setTimeout(later, wait);
  						if (callNow) result = func.apply(context, args);
  						return result;
  					};
  				};
  				_.once = function (func) {
  					var ran = false,
  					    memo;
  					return function () {
  						if (ran) return memo;
  						ran = true;
  						memo = func.apply(this, arguments);
  						func = null;
  						return memo;
  					};
  				};
  				_.wrap = function (func, wrapper) {
  					return function () {
  						var args = [func];
  						push.apply(args, arguments);
  						return wrapper.apply(this, args);
  					};
  				};
  				_.compose = function () {
  					var funcs = arguments;
  					return function () {
  						var args = arguments;
  						for (var i = funcs.length - 1; i >= 0; i--) {
  							args = [funcs[i].apply(this, args)];
  						}
  						return args[0];
  					};
  				};
  				_.after = function (times, func) {
  					if (times <= 0) return func();
  					return function () {
  						if (--times < 1) {
  							return func.apply(this, arguments);
  						}
  					};
  				};
  				_.keys = nativeKeys || function (obj) {
  					if (obj !== Object(obj)) throw new TypeError('Invalid object');
  					var keys = [];
  					for (var key in obj) {
  						if (_.has(obj, key)) keys[keys.length] = key;
  					}return keys;
  				};
  				_.values = function (obj) {
  					var values = [];
  					for (var key in obj) {
  						if (_.has(obj, key)) values.push(obj[key]);
  					}return values;
  				};
  				_.pairs = function (obj) {
  					var pairs = [];
  					for (var key in obj) {
  						if (_.has(obj, key)) pairs.push([key, obj[key]]);
  					}return pairs;
  				};
  				_.invert = function (obj) {
  					var result = {};
  					for (var key in obj) {
  						if (_.has(obj, key)) result[obj[key]] = key;
  					}return result;
  				};
  				_.functions = _.methods = function (obj) {
  					var names = [];
  					for (var key in obj) {
  						if (_.isFunction(obj[key])) names.push(key);
  					}
  					return names.sort();
  				};
  				_.extend = function (obj) {
  					each(slice.call(arguments, 1), function (source) {
  						if (source) {
  							for (var prop in source) {
  								obj[prop] = source[prop];
  							}
  						}
  					});
  					return obj;
  				};
  				_.pick = function (obj) {
  					var copy = {};
  					var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
  					each(keys, function (key) {
  						if (key in obj) copy[key] = obj[key];
  					});
  					return copy;
  				};
  				_.omit = function (obj) {
  					var copy = {};
  					var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
  					for (var key in obj) {
  						if (!_.contains(keys, key)) copy[key] = obj[key];
  					}
  					return copy;
  				};
  				_.defaults = function (obj) {
  					each(slice.call(arguments, 1), function (source) {
  						if (source) {
  							for (var prop in source) {
  								if (obj[prop] == null) obj[prop] = source[prop];
  							}
  						}
  					});
  					return obj;
  				};
  				_.clone = function (obj) {
  					if (!_.isObject(obj)) return obj;
  					return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
  				};
  				_.tap = function (obj, interceptor) {
  					interceptor(obj);
  					return obj;
  				};
  				var eq = function eq(a, b, aStack, bStack) {
  					if (a === b) return a !== 0 || 1 / a == 1 / b;
  					if (a == null || b == null) return a === b;
  					if (a instanceof _) a = a._wrapped;
  					if (b instanceof _) b = b._wrapped;
  					var className = toString.call(a);
  					if (className != toString.call(b)) return false;
  					switch (className) {
  						case '[object String]':
  							return a == String(b);
  						case '[object Number]':
  							return a != +a ? b != +b : a == 0 ? 1 / a == 1 / b : a == +b;
  						case '[object Date]':
  						case '[object Boolean]':
  							return +a == +b;
  						case '[object RegExp]':
  							return a.source == b.source && a.global == b.global && a.multiline == b.multiline && a.ignoreCase == b.ignoreCase;
  					}
  					if ((typeof a === "undefined" ? "undefined" : _typeof(a)) != 'object' || (typeof b === "undefined" ? "undefined" : _typeof(b)) != 'object') return false;
  					var length = aStack.length;
  					while (length--) {
  						if (aStack[length] == a) return bStack[length] == b;
  					}
  					aStack.push(a);
  					bStack.push(b);
  					var size = 0,
  					    result = true;
  					if (className == '[object Array]') {
  						size = a.length;
  						result = size == b.length;
  						if (result) {
  							while (size--) {
  								if (!(result = eq(a[size], b[size], aStack, bStack))) break;
  							}
  						}
  					} else {
  						var aCtor = a.constructor,
  						    bCtor = b.constructor;
  						if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && _.isFunction(bCtor) && bCtor instanceof bCtor)) {
  							return false;
  						}
  						for (var key in a) {
  							if (_.has(a, key)) {
  								size++;
  								if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
  							}
  						}
  						if (result) {
  							for (key in b) {
  								if (_.has(b, key) && !size--) break;
  							}
  							result = !size;
  						}
  					}
  					aStack.pop();
  					bStack.pop();
  					return result;
  				};
  				_.isEqual = function (a, b) {
  					return eq(a, b, [], []);
  				};
  				_.isEmpty = function (obj) {
  					if (obj == null) return true;
  					if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
  					for (var key in obj) {
  						if (_.has(obj, key)) return false;
  					}return true;
  				};
  				_.isElement = function (obj) {
  					return !!(obj && obj.nodeType === 1);
  				};
  				_.isArray = nativeIsArray || function (obj) {
  					return toString.call(obj) == '[object Array]';
  				};
  				_.isObject = function (obj) {
  					return obj === Object(obj);
  				};
  				each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function (name) {
  					_['is' + name] = function (obj) {
  						return toString.call(obj) == '[object ' + name + ']';
  					};
  				});
  				if (!_.isArguments(arguments)) {
  					_.isArguments = function (obj) {
  						return !!(obj && _.has(obj, 'callee'));
  					};
  				}
  				if (typeof /./ !== 'function') {
  					_.isFunction = function (obj) {
  						return typeof obj === 'function';
  					};
  				}
  				_.isFinite = function (obj) {
  					return isFinite(obj) && !isNaN(parseFloat(obj));
  				};
  				_.isNaN = function (obj) {
  					return _.isNumber(obj) && obj != +obj;
  				};
  				_.isBoolean = function (obj) {
  					return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
  				};
  				_.isNull = function (obj) {
  					return obj === null;
  				};
  				_.isUndefined = function (obj) {
  					return obj === void 0;
  				};
  				_.has = function (obj, key) {
  					return hasOwnProperty.call(obj, key);
  				};
  				_.noConflict = function () {
  					root._ = previousUnderscore;
  					return this;
  				};
  				_.identity = function (value) {
  					return value;
  				};
  				_.times = function (n, iterator, context) {
  					var accum = Array(n);
  					for (var i = 0; i < n; i++) {
  						accum[i] = iterator.call(context, i);
  					}return accum;
  				};
  				_.random = function (min, max) {
  					if (max == null) {
  						max = min;
  						min = 0;
  					}
  					return min + Math.floor(Math.random() * (max - min + 1));
  				};
  				var entityMap = {
  					escape: {
  						'&': '&amp;',
  						'<': '&lt;',
  						'>': '&gt;',
  						'"': '&quot;',
  						"'": '&#x27;',
  						'/': '&#x2F;'
  					}
  				};
  				entityMap.unescape = _.invert(entityMap.escape);
  				var entityRegexes = {
  					escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
  					unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
  				};
  				_.each(['escape', 'unescape'], function (method) {
  					_[method] = function (string) {
  						if (string == null) return '';
  						return ('' + string).replace(entityRegexes[method], function (match) {
  							return entityMap[method][match];
  						});
  					};
  				});
  				_.result = function (object, property) {
  					if (object == null) return null;
  					var value = object[property];
  					return _.isFunction(value) ? value.call(object) : value;
  				};
  				_.mixin = function (obj) {
  					each(_.functions(obj), function (name) {
  						var func = _[name] = obj[name];
  						_.prototype[name] = function () {
  							var args = [this._wrapped];
  							push.apply(args, arguments);
  							return result.call(this, func.apply(_, args));
  						};
  					});
  				};
  				var idCounter = 0;
  				_.uniqueId = function (prefix) {
  					var id = ++idCounter + '';
  					return prefix ? prefix + id : id;
  				};
  				_.templateSettings = {
  					evaluate: /<%([\s\S]+?)%>/g,
  					interpolate: /<%=([\s\S]+?)%>/g,
  					escape: /<%-([\s\S]+?)%>/g
  				};
  				var noMatch = /(.)^/;
  				var escapes = {
  					"'": "'",
  					'\\': '\\',
  					'\r': 'r',
  					'\n': 'n',
  					'\t': 't',
  					"\u2028": 'u2028',
  					"\u2029": 'u2029'
  				};
  
  				var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
  				_.template = function (text, data, settings) {
  					var render;
  					settings = _.defaults({}, settings, _.templateSettings);
  					var matcher = new RegExp([(settings.escape || noMatch).source, (settings.interpolate || noMatch).source, (settings.evaluate || noMatch).source].join('|') + '|$', 'g');
  					var index = 0;
  					var source = "__p+='";
  					text.replace(matcher, function (match, escape, interpolate, evaluate, offset) {
  						source += text.slice(index, offset).replace(escaper, function (match) {
  							return '\\' + escapes[match];
  						});
  
  						if (escape) {
  							source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
  						}
  						if (interpolate) {
  							source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
  						}
  						if (evaluate) {
  							source += "';\n" + evaluate + "\n__p+='";
  						}
  						index = offset + match.length;
  						return match;
  					});
  					source += "';\n";
  					if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
  
  					source = "var __t,__p='',__j=Array.prototype.join," + "print=function(){__p+=__j.call(arguments,'');};\n" + source + "return __p;\n";
  
  					try {
  						render = new Function(settings.variable || 'obj', '_', source);
  					} catch (e) {
  						e.source = source;
  						throw e;
  					}
  
  					if (data) return render(data, _);
  					var template = function template(data) {
  						return render.call(this, data, _);
  					};
  					template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
  
  					return template;
  				};
  				_.chain = function (obj) {
  					return _(obj).chain();
  				};
  				var result = function result(obj) {
  					return this._chain ? _(obj).chain() : obj;
  				};
  				_.mixin(_);
  				each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function (name) {
  					var method = ArrayProto[name];
  					_.prototype[name] = function () {
  						var obj = this._wrapped;
  						method.apply(obj, arguments);
  						if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
  						return result.call(this, obj);
  					};
  				});
  				each(['concat', 'join', 'slice'], function (name) {
  					var method = ArrayProto[name];
  					_.prototype[name] = function () {
  						return result.call(this, method.apply(this._wrapped, arguments));
  					};
  				});
  
  				_.extend(_.prototype, {
  					chain: function chain() {
  						this._chain = true;
  						return this;
  					},
  					value: function value() {
  						return this._wrapped;
  					}
  
  				});
  			}).call(this);
  		}, {}],
  		2: [function (req, module, exports) {
  
  			var _ = req("underscore");
  
  			var errors = {
  				E001: "Bad option: '{a}'.",
  				E002: "Bad option value.",
  				E003: "Expected a JSON value.",
  				E004: "Input is neither a string nor an array of strings.",
  				E005: "Input is empty.",
  				E006: "Unexpected early end of program.",
  				E007: "Missing \"use strict\" statement.",
  				E008: "Strict violation.",
  				E009: "Option 'validthis' can't be used in a global scope.",
  				E010: "'with' is not allowed in strict mode.",
  				E011: "const '{a}' has already been declared.",
  				E012: "const '{a}' is initialized to 'undefined'.",
  				E013: "Attempting to override '{a}' which is a constant.",
  				E014: "A regular expression literal can be confused with '/='.",
  				E015: "Unclosed regular expression.",
  				E016: "Invalid regular expression.",
  				E017: "Unclosed comment.",
  				E018: "Unbegun comment.",
  				E019: "Unmatched '{a}'.",
  				E020: "Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
  				E021: "Expected '{a}' and instead saw '{b}'.",
  				E022: "Line breaking error '{a}'.",
  				E023: "Missing '{a}'.",
  				E024: "Unexpected '{a}'.",
  				E025: "Missing ':' on a case clause.",
  				E026: "Missing '}' to match '{' from line {a}.",
  				E027: "Missing ']' to match '[' form line {a}.",
  				E028: "Illegal comma.",
  				E029: "Unclosed string.",
  				E030: "Expected an identifier and instead saw '{a}'.",
  				E031: "Bad assignment.", // FIXME: Rephrase
  				E032: "Expected a small integer or 'false' and instead saw '{a}'.",
  				E033: "Expected an operator and instead saw '{a}'.",
  				E034: "get/set are ES5 features.",
  				E035: "Missing property name.",
  				E036: "Expected to see a statement and instead saw a block.",
  				E037: null, // Vacant
  				E038: null, // Vacant
  				E039: "Function declarations are not invocable. Wrap the whole function invocation in parens.",
  				E040: "Each value should have its own case label.",
  				E041: "Unrecoverable syntax error.",
  				E042: "Stopping.",
  				E043: "Too many errors.",
  				E044: "'{a}' is already defined and can't be redefined.",
  				E045: "Invalid for each loop.",
  				E046: "A yield statement shall be within a generator function (with syntax: `function*`)",
  				E047: "A generator function shall contain a yield statement.",
  				E048: "Let declaration not directly within block.",
  				E049: "A {a} cannot be named '{b}'.",
  				E050: "Mozilla requires the yield expression to be parenthesized here.",
  				E051: "Regular parameters cannot come after default parameters."
  			};
  
  			var warnings = {
  				W001: "'hasOwnProperty' is a really bad name.",
  				W002: "Value of '{a}' may be overwritten in IE 8 and earlier.",
  				W003: "'{a}' was used before it was defined.",
  				W004: "'{a}' is already defined.",
  				W005: "A dot following a number can be confused with a decimal point.",
  				W006: "Confusing minuses.",
  				W007: "Confusing pluses.",
  				W008: "A leading decimal point can be confused with a dot: '{a}'.",
  				W009: "The array literal notation [] is preferrable.",
  				W010: "The object literal notation {} is preferrable.",
  				W011: "Unexpected space after '{a}'.",
  				W012: "Unexpected space before '{a}'.",
  				W013: "Missing space after '{a}'.",
  				W014: "Bad line breaking before '{a}'.",
  				W015: "Expected '{a}' to have an indentation at {b} instead at {c}.",
  				W016: "Unexpected use of '{a}'.",
  				W017: "Bad operand.",
  				W018: "Confusing use of '{a}'.",
  				W019: "Use the isNaN function to compare with NaN.",
  				W020: "Read only.",
  				W021: "'{a}' is a function.",
  				W022: "Do not assign to the exception parameter.",
  				W023: "Expected an identifier in an assignment and instead saw a function invocation.",
  				W024: "Expected an identifier and instead saw '{a}' (a reserved word).",
  				W025: "Missing name in function declaration.",
  				W026: "Inner functions should be listed at the top of the outer function.",
  				W027: "Unreachable '{a}' after '{b}'.",
  				W028: "Label '{a}' on {b} statement.",
  				W030: "Expected an assignment or function call and instead saw an expression.",
  				W031: "Do not use 'new' for side effects.",
  				W032: "Unnecessary semicolon.",
  				W033: "Missing semicolon.",
  				W034: "Unnecessary directive \"{a}\".",
  				W035: "Empty block.",
  				W036: "Unexpected /*member '{a}'.",
  				W037: "'{a}' is a statement label.",
  				W038: "'{a}' used out of scope.",
  				W039: "'{a}' is not allowed.",
  				W040: "Possible strict violation.",
  				W041: "Use '{a}' to compare with '{b}'.",
  				W042: "Avoid EOL escaping.",
  				W043: "Bad escaping of EOL. Use option multistr if needed.",
  				W044: "Bad or unnecessary escaping.",
  				W045: "Bad number '{a}'.",
  				W046: "Don't use extra leading zeros '{a}'.",
  				W047: "A trailing decimal point can be confused with a dot: '{a}'.",
  				W048: "Unexpected control character in regular expression.",
  				W049: "Unexpected escaped character '{a}' in regular expression.",
  				W050: "JavaScript URL.",
  				W051: "Variables should not be deleted.",
  				W052: "Unexpected '{a}'.",
  				W053: "Do not use {a} as a constructor.",
  				W054: "The Function constructor is a form of eval.",
  				W055: "A constructor name should start with an uppercase letter.",
  				W056: "Bad constructor.",
  				W057: "Weird construction. Is 'new' unnecessary?",
  				W058: "Missing '()' invoking a constructor.",
  				W059: "Avoid arguments.{a}.",
  				W060: "document.write can be a form of eval.",
  				W061: "eval can be harmful.",
  				W062: "Wrap an immediate function invocation in parens " + "to assist the reader in understanding that the expression " + "is the result of a function, and not the function itself.",
  				W063: "Math is not a function.",
  				W064: "Missing 'new' prefix when invoking a constructor.",
  				W065: "Missing radix parameter.",
  				W066: "Implied eval. Consider passing a function instead of a string.",
  				W067: "Bad invocation.",
  				W068: "Wrapping non-IIFE function literals in parens is unnecessary.",
  				W069: "['{a}'] is better written in dot notation.",
  				W070: "Extra comma. (it breaks older versions of IE)",
  				W071: "This function has too many statements. ({a})",
  				W072: "This function has too many parameters. ({a})",
  				W073: "Blocks are nested too deeply. ({a})",
  				W074: "This function's cyclomatic complexity is too high. ({a})",
  				W075: "Duplicate key '{a}'.",
  				W076: "Unexpected parameter '{a}' in get {b} function.",
  				W077: "Expected a single parameter in set {a} function.",
  				W078: "Setter is defined without getter.",
  				W079: "Redefinition of '{a}'.",
  				W080: "It's not necessary to initialize '{a}' to 'undefined'.",
  				W081: "Too many var statements.",
  				W082: "Function declarations should not be placed in blocks. " + "Use a function expression or move the statement to the top of " + "the outer function.",
  				W083: "Don't make functions within a loop.",
  				W084: "Assignment in conditional expression",
  				W085: "Don't use 'with'.",
  				W086: "Expected a 'break' statement before '{a}'.",
  				W087: "Forgotten 'debugger' statement?",
  				W088: "Creating global 'for' variable. Should be 'for (var {a} ...'.",
  				W089: "The body of a for in should be wrapped in an if statement to filter " + "unwanted properties from the prototype.",
  				W090: "'{a}' is not a statement label.",
  				W091: "'{a}' is out of scope.",
  				W092: "Wrap the /regexp/ literal in parens to disambiguate the slash operator.",
  				W093: "Did you mean to return a conditional instead of an assignment?",
  				W094: "Unexpected comma.",
  				W095: "Expected a string and instead saw {a}.",
  				W096: "The '{a}' key may produce unexpected results.",
  				W097: "Use the function form of \"use strict\".",
  				W098: "'{a}' is defined but never used.",
  				W099: "Mixed spaces and tabs.",
  				W100: "This character may get silently deleted by one or more browsers.",
  				W101: "Line is too long.",
  				W102: "Trailing whitespace.",
  				W103: "The '{a}' property is deprecated.",
  				W104: "'{a}' is only available in JavaScript 1.7.",
  				W105: "Unexpected {a} in '{b}'.",
  				W106: "Identifier '{a}' is not in camel case.",
  				W107: "Script URL.",
  				W108: "Strings must use doublequote.",
  				W109: "Strings must use singlequote.",
  				W110: "Mixed double and single quotes.",
  				W112: "Unclosed string.",
  				W113: "Control character in string: {a}.",
  				W114: "Avoid {a}.",
  				W115: "Octal literals are not allowed in strict mode.",
  				W116: "Expected '{a}' and instead saw '{b}'.",
  				W117: "'{a}' is not defined.",
  				W118: "'{a}' is only available in Mozilla JavaScript extensions (use moz option).",
  				W119: "'{a}' is only available in ES6 (use esnext option).",
  				W120: "You might be leaking a variable ({a}) here."
  			};
  
  			var info = {
  				I001: "Comma warnings can be turned off with 'laxcomma'.",
  				I002: "Reserved words as properties can be used under the 'es5' option.",
  				I003: "ES5 option is now set per default"
  			};
  
  			exports.errors = {};
  			exports.warnings = {};
  			exports.info = {};
  
  			_.each(errors, function (desc, code) {
  				exports.errors[code] = { code: code, desc: desc };
  			});
  
  			_.each(warnings, function (desc, code) {
  				exports.warnings[code] = { code: code, desc: desc };
  			});
  
  			_.each(info, function (desc, code) {
  				exports.info[code] = { code: code, desc: desc };
  			});
  		}, { "underscore": 1 }],
  		3: [function (req, module, exports) {
  
  			exports.reservedVars = {
  				arguments: false,
  				NaN: false
  			};
  
  			exports.ecmaIdentifiers = {
  				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,
  				Map: false,
  				Number: false,
  				Object: false,
  				parseInt: false,
  				parseFloat: false,
  				RangeError: false,
  				ReferenceError: false,
  				RegExp: false,
  				Set: false,
  				String: false,
  				SyntaxError: false,
  				TypeError: false,
  				URIError: false,
  				WeakMap: false
  			};
  
  			exports.browser = {
  				ArrayBuffer: false,
  				ArrayBufferView: false,
  				Audio: false,
  				Blob: false,
  				addEventListener: false,
  				applicationCache: false,
  				atob: false,
  				blur: false,
  				btoa: false,
  				clearInterval: false,
  				clearTimeout: false,
  				close: false,
  				closed: false,
  				CustomEvent: false,
  				DataView: false,
  				DOMParser: false,
  				defaultStatus: false,
  				document: false,
  				Element: false,
  				ElementTimeControl: false,
  				event: false,
  				FileReader: false,
  				Float32Array: false,
  				Float64Array: false,
  				FormData: false,
  				focus: false,
  				frames: false,
  				getComputedStyle: false,
  				HTMLElement: false,
  				HTMLAnchorElement: false,
  				HTMLBaseElement: false,
  				HTMLBlockquoteElement: false,
  				HTMLBodyElement: false,
  				HTMLBRElement: false,
  				HTMLButtonElement: false,
  				HTMLCanvasElement: false,
  				HTMLDirectoryElement: false,
  				HTMLDivElement: false,
  				HTMLDListElement: false,
  				HTMLFieldSetElement: false,
  				HTMLFontElement: false,
  				HTMLFormElement: false,
  				HTMLFrameElement: false,
  				HTMLFrameSetElement: false,
  				HTMLHeadElement: false,
  				HTMLHeadingElement: false,
  				HTMLHRElement: false,
  				HTMLHtmlElement: false,
  				HTMLIFrameElement: false,
  				HTMLImageElement: false,
  				HTMLInputElement: false,
  				HTMLIsIndexElement: false,
  				HTMLLabelElement: false,
  				HTMLLayerElement: false,
  				HTMLLegendElement: false,
  				HTMLLIElement: false,
  				HTMLLinkElement: false,
  				HTMLMapElement: false,
  				HTMLMenuElement: false,
  				HTMLMetaElement: false,
  				HTMLModElement: false,
  				HTMLObjectElement: false,
  				HTMLOListElement: false,
  				HTMLOptGroupElement: false,
  				HTMLOptionElement: false,
  				HTMLParagraphElement: false,
  				HTMLParamElement: false,
  				HTMLPreElement: false,
  				HTMLQuoteElement: false,
  				HTMLScriptElement: false,
  				HTMLSelectElement: false,
  				HTMLStyleElement: false,
  				HTMLTableCaptionElement: false,
  				HTMLTableCellElement: false,
  				HTMLTableColElement: false,
  				HTMLTableElement: false,
  				HTMLTableRowElement: false,
  				HTMLTableSectionElement: false,
  				HTMLTextAreaElement: false,
  				HTMLTitleElement: false,
  				HTMLUListElement: false,
  				HTMLVideoElement: false,
  				history: false,
  				Int16Array: false,
  				Int32Array: false,
  				Int8Array: false,
  				Image: false,
  				length: false,
  				localStorage: false,
  				location: false,
  				MessageChannel: false,
  				MessageEvent: false,
  				MessagePort: false,
  				MouseEvent: false,
  				moveBy: false,
  				moveTo: false,
  				MutationObserver: false,
  				name: false,
  				Node: false,
  				NodeFilter: false,
  				navigator: false,
  				onbeforeunload: true,
  				onblur: true,
  				onerror: true,
  				onfocus: true,
  				onload: true,
  				onresize: true,
  				onunload: true,
  				open: false,
  				openDatabase: false,
  				opener: false,
  				Option: false,
  				parent: false,
  				print: false,
  				removeEventListener: false,
  				resizeBy: false,
  				resizeTo: false,
  				screen: false,
  				scroll: false,
  				scrollBy: false,
  				scrollTo: false,
  				sessionStorage: false,
  				setInterval: false,
  				setTimeout: false,
  				SharedWorker: false,
  				status: false,
  				SVGAElement: false,
  				SVGAltGlyphDefElement: false,
  				SVGAltGlyphElement: false,
  				SVGAltGlyphItemElement: false,
  				SVGAngle: false,
  				SVGAnimateColorElement: false,
  				SVGAnimateElement: false,
  				SVGAnimateMotionElement: false,
  				SVGAnimateTransformElement: false,
  				SVGAnimatedAngle: false,
  				SVGAnimatedBoolean: false,
  				SVGAnimatedEnumeration: false,
  				SVGAnimatedInteger: false,
  				SVGAnimatedLength: false,
  				SVGAnimatedLengthList: false,
  				SVGAnimatedNumber: false,
  				SVGAnimatedNumberList: false,
  				SVGAnimatedPathData: false,
  				SVGAnimatedPoints: false,
  				SVGAnimatedPreserveAspectRatio: false,
  				SVGAnimatedRect: false,
  				SVGAnimatedString: false,
  				SVGAnimatedTransformList: false,
  				SVGAnimationElement: false,
  				SVGCSSRule: false,
  				SVGCircleElement: false,
  				SVGClipPathElement: false,
  				SVGColor: false,
  				SVGColorProfileElement: false,
  				SVGColorProfileRule: false,
  				SVGComponentTransferFunctionElement: false,
  				SVGCursorElement: false,
  				SVGDefsElement: false,
  				SVGDescElement: false,
  				SVGDocument: false,
  				SVGElement: false,
  				SVGElementInstance: false,
  				SVGElementInstanceList: false,
  				SVGEllipseElement: false,
  				SVGExternalResourcesRequired: false,
  				SVGFEBlendElement: false,
  				SVGFEColorMatrixElement: false,
  				SVGFEComponentTransferElement: false,
  				SVGFECompositeElement: false,
  				SVGFEConvolveMatrixElement: false,
  				SVGFEDiffuseLightingElement: false,
  				SVGFEDisplacementMapElement: false,
  				SVGFEDistantLightElement: false,
  				SVGFEFloodElement: false,
  				SVGFEFuncAElement: false,
  				SVGFEFuncBElement: false,
  				SVGFEFuncGElement: false,
  				SVGFEFuncRElement: false,
  				SVGFEGaussianBlurElement: false,
  				SVGFEImageElement: false,
  				SVGFEMergeElement: false,
  				SVGFEMergeNodeElement: false,
  				SVGFEMorphologyElement: false,
  				SVGFEOffsetElement: false,
  				SVGFEPointLightElement: false,
  				SVGFESpecularLightingElement: false,
  				SVGFESpotLightElement: false,
  				SVGFETileElement: false,
  				SVGFETurbulenceElement: false,
  				SVGFilterElement: false,
  				SVGFilterPrimitiveStandardAttributes: false,
  				SVGFitToViewBox: false,
  				SVGFontElement: false,
  				SVGFontFaceElement: false,
  				SVGFontFaceFormatElement: false,
  				SVGFontFaceNameElement: false,
  				SVGFontFaceSrcElement: false,
  				SVGFontFaceUriElement: false,
  				SVGForeignObjectElement: false,
  				SVGGElement: false,
  				SVGGlyphElement: false,
  				SVGGlyphRefElement: false,
  				SVGGradientElement: false,
  				SVGHKernElement: false,
  				SVGICCColor: false,
  				SVGImageElement: false,
  				SVGLangSpace: false,
  				SVGLength: false,
  				SVGLengthList: false,
  				SVGLineElement: false,
  				SVGLinearGradientElement: false,
  				SVGLocatable: false,
  				SVGMPathElement: false,
  				SVGMarkerElement: false,
  				SVGMaskElement: false,
  				SVGMatrix: false,
  				SVGMetadataElement: false,
  				SVGMissingGlyphElement: false,
  				SVGNumber: false,
  				SVGNumberList: false,
  				SVGPaint: false,
  				SVGPathElement: false,
  				SVGPathSeg: false,
  				SVGPathSegArcAbs: false,
  				SVGPathSegArcRel: false,
  				SVGPathSegClosePath: false,
  				SVGPathSegCurvetoCubicAbs: false,
  				SVGPathSegCurvetoCubicRel: false,
  				SVGPathSegCurvetoCubicSmoothAbs: false,
  				SVGPathSegCurvetoCubicSmoothRel: false,
  				SVGPathSegCurvetoQuadraticAbs: false,
  				SVGPathSegCurvetoQuadraticRel: false,
  				SVGPathSegCurvetoQuadraticSmoothAbs: false,
  				SVGPathSegCurvetoQuadraticSmoothRel: false,
  				SVGPathSegLinetoAbs: false,
  				SVGPathSegLinetoHorizontalAbs: false,
  				SVGPathSegLinetoHorizontalRel: false,
  				SVGPathSegLinetoRel: false,
  				SVGPathSegLinetoVerticalAbs: false,
  				SVGPathSegLinetoVerticalRel: false,
  				SVGPathSegList: false,
  				SVGPathSegMovetoAbs: false,
  				SVGPathSegMovetoRel: false,
  				SVGPatternElement: false,
  				SVGPoint: false,
  				SVGPointList: false,
  				SVGPolygonElement: false,
  				SVGPolylineElement: false,
  				SVGPreserveAspectRatio: false,
  				SVGRadialGradientElement: false,
  				SVGRect: false,
  				SVGRectElement: false,
  				SVGRenderingIntent: false,
  				SVGSVGElement: false,
  				SVGScriptElement: false,
  				SVGSetElement: false,
  				SVGStopElement: false,
  				SVGStringList: false,
  				SVGStylable: false,
  				SVGStyleElement: false,
  				SVGSwitchElement: false,
  				SVGSymbolElement: false,
  				SVGTRefElement: false,
  				SVGTSpanElement: false,
  				SVGTests: false,
  				SVGTextContentElement: false,
  				SVGTextElement: false,
  				SVGTextPathElement: false,
  				SVGTextPositioningElement: false,
  				SVGTitleElement: false,
  				SVGTransform: false,
  				SVGTransformList: false,
  				SVGTransformable: false,
  				SVGURIReference: false,
  				SVGUnitTypes: false,
  				SVGUseElement: false,
  				SVGVKernElement: false,
  				SVGViewElement: false,
  				SVGViewSpec: false,
  				SVGZoomAndPan: false,
  				TimeEvent: false,
  				top: false,
  				Uint16Array: false,
  				Uint32Array: false,
  				Uint8Array: false,
  				Uint8ClampedArray: false,
  				WebSocket: false,
  				window: false,
  				Worker: false,
  				XMLHttpRequest: false,
  				XMLSerializer: false,
  				XPathEvaluator: false,
  				XPathException: false,
  				XPathExpression: false,
  				XPathNamespace: false,
  				XPathNSResolver: false,
  				XPathResult: false
  			};
  
  			exports.devel = {
  				alert: false,
  				confirm: false,
  				console: false,
  				Debug: false,
  				opera: false,
  				prompt: false
  			};
  
  			exports.worker = {
  				importScripts: true,
  				postMessage: true,
  				self: true
  			};
  			exports.nonstandard = {
  				escape: false,
  				unescape: false
  			};
  
  			exports.couch = {
  				"require": false,
  				respond: false,
  				getRow: false,
  				emit: false,
  				send: false,
  				start: false,
  				sum: false,
  				log: false,
  				exports: false,
  				module: false,
  				provides: false
  			};
  
  			exports.node = {
  				__filename: false,
  				__dirname: false,
  				Buffer: false,
  				DataView: false,
  				console: false,
  				exports: true, // In Node it is ok to exports = module.exports = foo();
  				GLOBAL: false,
  				global: false,
  				module: false,
  				process: false,
  				require: false,
  				setTimeout: false,
  				clearTimeout: false,
  				setInterval: false,
  				clearInterval: false,
  				setImmediate: false, // v0.9.1+
  				clearImmediate: false // v0.9.1+
  			};
  
  			exports.phantom = {
  				phantom: true,
  				require: true,
  				WebPage: true
  			};
  
  			exports.rhino = {
  				defineClass: false,
  				deserialize: false,
  				gc: false,
  				help: false,
  				importPackage: false,
  				"java": 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
  			};
  
  			exports.shelljs = {
  				target: false,
  				echo: false,
  				exit: false,
  				cd: false,
  				pwd: false,
  				ls: false,
  				find: false,
  				cp: false,
  				rm: false,
  				mv: false,
  				mkdir: false,
  				test: false,
  				cat: false,
  				sed: false,
  				grep: false,
  				which: false,
  				dirs: false,
  				pushd: false,
  				popd: false,
  				env: false,
  				exec: false,
  				chmod: false,
  				config: false,
  				error: false,
  				tempdir: false
  			};
  
  			exports.wsh = {
  				ActiveXObject: true,
  				Enumerator: true,
  				GetObject: true,
  				ScriptEngine: true,
  				ScriptEngineBuildVersion: true,
  				ScriptEngineMajorVersion: true,
  				ScriptEngineMinorVersion: true,
  				VBArray: true,
  				WSH: true,
  				WScript: true,
  				XDomainRequest: true
  			};
  
  			exports.dojo = {
  				dojo: false,
  				dijit: false,
  				dojox: false,
  				define: false,
  				"require": false
  			};
  
  			exports.jquery = {
  				"$": false,
  				jQuery: false
  			};
  
  			exports.mootools = {
  				"$": false,
  				"$$": false,
  				Asset: false,
  				Browser: false,
  				Chain: false,
  				Class: false,
  				Color: false,
  				Cookie: false,
  				Core: false,
  				Document: false,
  				DomReady: false,
  				DOMEvent: false,
  				DOMReady: false,
  				Drag: false,
  				Element: false,
  				Elements: false,
  				Event: false,
  				Events: false,
  				Fx: false,
  				Group: false,
  				Hash: false,
  				HtmlTable: false,
  				Iframe: false,
  				IframeShim: false,
  				InputValidator: false,
  				instanceOf: false,
  				Keyboard: false,
  				Locale: false,
  				Mask: false,
  				MooTools: false,
  				Native: false,
  				Options: false,
  				OverText: false,
  				Request: false,
  				Scroller: false,
  				Slick: false,
  				Slider: false,
  				Sortables: false,
  				Spinner: false,
  				Swiff: false,
  				Tips: false,
  				Type: false,
  				typeOf: false,
  				URI: false,
  				Window: false
  			};
  
  			exports.prototypejs = {
  				"$": false,
  				"$$": false,
  				"$A": false,
  				"$F": false,
  				"$H": false,
  				"$R": false,
  				"$break": false,
  				"$continue": false,
  				"$w": false,
  				Abstract: false,
  				Ajax: false,
  				Class: false,
  				Enumerable: false,
  				Element: false,
  				Event: false,
  				Field: false,
  				Form: false,
  				Hash: false,
  				Insertion: false,
  				ObjectRange: false,
  				PeriodicalExecuter: false,
  				Position: false,
  				Prototype: false,
  				Selector: false,
  				Template: false,
  				Toggle: false,
  				Try: false,
  				Autocompleter: false,
  				Builder: false,
  				Control: false,
  				Draggable: false,
  				Draggables: false,
  				Droppables: false,
  				Effect: false,
  				Sortable: false,
  				SortableObserver: false,
  				Sound: false,
  				Scriptaculous: false
  			};
  
  			exports.yui = {
  				YUI: false,
  				Y: false,
  				YUI_config: false
  			};
  		}, {}],
  		"n4bKNg": [function (req, module, exports) {
  
  			var _ = req("underscore");
  			var events = req("events");
  			var vars = req("../shared/vars.js");
  			var messages = req("../shared/messages.js");
  			var Lexer = req("./lex.js").Lexer;
  			var reg = req("./reg.js");
  			var state = req("./state.js").state;
  			var style = req("./style.js");
  			var console = req("console-browserify");
  
  			var JSHINT = function () {
  
  				var anonname,
  				    // The guessed name for anonymous functions.
  				api,
  				    // Extension API
  				bang = {
  					"<": true,
  					"<=": true,
  					"==": true,
  					"===": true,
  					"!==": true,
  					"!=": true,
  					">": true,
  					">=": true,
  					"+": true,
  					"-": true,
  					"*": true,
  					"/": true,
  					"%": true
  				},
  				    boolOptions = {
  					asi: true, // if automatic semicolon insertion should be tolerated
  					bitwise: true, // if bitwise operators should not be allowed
  					boss: true, // if advanced usage of assignments should be allowed
  					browser: true, // if the standard browser globals should be predefined
  					camelcase: true, // if identifiers should be required in camel case
  					couch: true, // if CouchDB globals should be predefined
  					curly: true, // if curly braces around all blocks should be required
  					debug: true, // if debugger statements should be allowed
  					devel: true, // if logging globals should be predefined (console, alert, etc.)
  					dojo: true, // if Dojo Toolkit globals should be predefined
  					eqeqeq: true, // if === should be required
  					eqnull: true, // if == null comparisons should be tolerated
  					es3: true, // if ES3 syntax should be allowed
  					es5: true, // if ES5 syntax should be allowed (is now set per default)
  					esnext: true, // if es.next specific syntax should be allowed
  					moz: true, // if mozilla specific syntax should be allowed
  					evil: true, // if eval should be allowed
  					expr: true, // if ExpressionStatement should be allowed as Programs
  					forin: true, // if for in statements must filter
  					funcscope: true, // if only function scope should be used for scope tests
  					gcl: true, // if JSHint should be compatible with Google Closure Linter
  					globalstrict: true, // if global  should be allowed (also enables 'strict')
  					immed: true, // if immediate invocations must be wrapped in parens
  					iterator: true, // if the `__iterator__` property should be allowed
  					jquery: true, // if jQuery globals should be predefined
  					lastsemic: true, // if semicolons may be ommitted for the trailing
  					laxbreak: true, // if line breaks should not be checked
  					laxcomma: true, // if line breaks should not be checked around commas
  					loopfunc: true, // if functions should be allowed to be defined within
  					mootools: true, // if MooTools globals should be predefined
  					multistr: true, // allow multiline strings
  					newcap: true, // if constructor names must be capitalized
  					noarg: true, // if arguments.caller and arguments.callee should be
  					node: true, // if the Node.js environment globals should be
  					noempty: true, // if empty blocks should be disallowed
  					nonew: true, // if using `new` for side-effects should be disallowed
  					nonstandard: true, // if non-standard (but widely adopted) globals should
  					nomen: true, // if names should be checked
  					onevar: true, // if only one var statement per function should be
  					passfail: true, // if the scan should stop on first error
  					phantom: true, // if PhantomJS symbols should be allowed
  					plusplus: true, // if increment/decrement should not be allowed
  					proto: true, // if the `__proto__` property should be allowed
  					prototypejs: true, // if Prototype and Scriptaculous globals should be
  					rhino: true, // if the Rhino environment globals should be predefined
  					shelljs: true, // if ShellJS globals should be predefined
  					undef: true, // if variables should be declared before used
  					scripturl: true, // if script-targeted URLs should be tolerated
  					shadow: true, // if variable shadowing should be tolerated
  					smarttabs: true, // if smarttabs should be tolerated
  					strict: true, // require the  pragma
  					sub: true, // if all forms of subscript notation are tolerated
  					supernew: true, // if `new function () { ... };` and `new Object;`
  					trailing: true, // if trailing whitespace rules apply
  					validthis: true, // if 'this' inside a non-constructor function is valid.
  					withstmt: true, // if with statements should be allowed
  					white: true, // if strict whitespace rules apply
  					worker: true, // if Web Worker script symbols should be allowed
  					wsh: true, // if the Windows Scripting Host environment globals
  					yui: true, // YUI variables should be predefined
  					onecase: true, // if one case switch statements should be allowed
  					regexp: true, // if the . should not be allowed in regexp literals
  					regexdash: true // if unescaped first/last dash (-) inside brackets
  				},
  				    valOptions = {
  					maxlen: false,
  					indent: false,
  					maxerr: false,
  					predef: false,
  					quotmark: false, //'single'|'double'|true
  					scope: false,
  					maxstatements: false, // {int} max statements per function
  					maxdepth: false, // {int} max nested block depth per function
  					maxparams: false, // {int} max params per function
  					maxcomplexity: false, // {int} max cyclomatic complexity per function
  					unused: true, // warn if variables are unused. Available options:
  					latedef: false // warn if the variable is used before its definition
  				},
  				    invertedOptions = {
  					bitwise: true,
  					forin: true,
  					newcap: true,
  					nomen: true,
  					plusplus: true,
  					regexp: true,
  					undef: true,
  					white: true,
  					eqeqeq: true,
  					onevar: true,
  					strict: true
  				},
  				    renamedOptions = {
  					eqeq: "eqeqeq",
  					vars: "onevar",
  					windows: "wsh",
  					sloppy: "strict"
  				},
  				    declared,
  				    // Globals that were declared using /*global ... */ syntax.
  				exported,
  				    // Variables that are used outside of the current file.
  
  				functionicity = ["closure", "exception", "global", "label", "outer", "unused", "var"],
  				    funct,
  				    // The current function
  				functions,
  				    // All of the functions
  
  				global,
  				    // The global scope
  				implied,
  				    // Implied globals
  				inblock,
  				    indent,
  				    lookahead,
  				    lex,
  				    member,
  				    membersOnly,
  				    noreach,
  				    predefined,
  				    // Global variables defined by option
  
  				scope,
  				    // The current scope
  				stack,
  				    unuseds,
  				    urls,
  				    warnings,
  				    extraModules = [],
  				    emitter = new events.EventEmitter();
  
  				function checkOption(name, t) {
  					name = name.trim();
  
  					if (/^[+-]W\d{3}$/g.test(name)) {
  						return true;
  					}
  
  					if (valOptions[name] === undefined && boolOptions[name] === undefined) {
  						if (t.type !== "jslint") {
  							error("E001", t, name);
  							return false;
  						}
  					}
  
  					return true;
  				}
  
  				function isString(obj) {
  					return Object.prototype.toString.call(obj) === "[object String]";
  				}
  
  				function isIdentifier(tkn, value) {
  					if (!tkn) return false;
  
  					if (!tkn.identifier || tkn.value !== value) return false;
  
  					return true;
  				}
  
  				function isReserved(token) {
  					if (!token.reserved) {
  						return false;
  					}
  					var meta = token.meta;
  
  					if (meta && meta.isFutureReservedWord && state.option.inES5()) {
  						if (!meta.es5) {
  							return false;
  						}
  						if (meta.strictOnly) {
  							if (!state.option.strict && !state.directive["use strict"]) {
  								return false;
  							}
  						}
  
  						if (token.isProperty) {
  							return false;
  						}
  					}
  
  					return true;
  				}
  
  				function supplant(str, data) {
  					return str.replace(/\{([^{}]*)\}/g, function (a, b) {
  						var r = data[b];
  						return typeof r === "string" || typeof r === "number" ? r : a;
  					});
  				}
  
  				function combine(t, o) {
  					var n;
  					for (n in o) {
  						if (_.has(o, n) && !_.has(JSHINT.blacklist, n)) {
  							t[n] = o[n];
  						}
  					}
  				}
  
  				function updatePredefined() {
  					Object.keys(JSHINT.blacklist).forEach(function (key) {
  						delete predefined[key];
  					});
  				}
  
  				function assume() {
  					if (state.option.couch) {
  						combine(predefined, vars.couch);
  					}
  
  					if (state.option.rhino) {
  						combine(predefined, vars.rhino);
  					}
  
  					if (state.option.shelljs) {
  						combine(predefined, vars.shelljs);
  						combine(predefined, vars.node);
  					}
  
  					if (state.option.phantom) {
  						combine(predefined, vars.phantom);
  					}
  
  					if (state.option.prototypejs) {
  						combine(predefined, vars.prototypejs);
  					}
  
  					if (state.option.node) {
  						combine(predefined, vars.node);
  					}
  
  					if (state.option.devel) {
  						combine(predefined, vars.devel);
  					}
  
  					if (state.option.dojo) {
  						combine(predefined, vars.dojo);
  					}
  
  					if (state.option.browser) {
  						combine(predefined, vars.browser);
  					}
  
  					if (state.option.nonstandard) {
  						combine(predefined, vars.nonstandard);
  					}
  
  					if (state.option.jquery) {
  						combine(predefined, vars.jquery);
  					}
  
  					if (state.option.mootools) {
  						combine(predefined, vars.mootools);
  					}
  
  					if (state.option.worker) {
  						combine(predefined, vars.worker);
  					}
  
  					if (state.option.wsh) {
  						combine(predefined, vars.wsh);
  					}
  
  					if (state.option.globalstrict && state.option.strict !== false) {
  						state.option.strict = true;
  					}
  
  					if (state.option.yui) {
  						combine(predefined, vars.yui);
  					}
  
  					state.option.inMoz = function (strict) {
  						return state.option.moz;
  					};
  
  					state.option.inESNext = function (strict) {
  						return state.option.moz || state.option.esnext;
  					};
  
  					state.option.inES5 = function () /* strict */{
  						return !state.option.es3;
  					};
  
  					state.option.inES3 = function (strict) {
  						if (strict) {
  							return !state.option.moz && !state.option.esnext && state.option.es3;
  						}
  						return state.option.es3;
  					};
  				}
  				function quit(code, line, chr) {
  					var percentage = Math.floor(line / state.lines.length * 100);
  					var message = messages.errors[code].desc;
  
  					throw {
  						name: "JSHintError",
  						line: line,
  						character: chr,
  						message: message + " (" + percentage + "% scanned).",
  						raw: message,
  						code: code
  					};
  				}
  
  				function isundef(scope, code, token, a) {
  					return JSHINT.undefs.push([scope, code, token, a]);
  				}
  
  				function warning(code, t, a, b, c, d) {
  					var ch, l, w, msg;
  
  					if (/^W\d{3}$/.test(code)) {
  						if (state.ignored[code]) return;
  
  						msg = messages.warnings[code];
  					} else if (/E\d{3}/.test(code)) {
  						msg = messages.errors[code];
  					} else if (/I\d{3}/.test(code)) {
  						msg = messages.info[code];
  					}
  
  					t = t || state.tokens.next;
  					if (t.id === "(end)") {
  						// `~
  						t = state.tokens.curr;
  					}
  
  					l = t.line || 0;
  					ch = t.from || 0;
  
  					w = {
  						id: "(error)",
  						raw: msg.desc,
  						code: msg.code,
  						evidence: state.lines[l - 1] || "",
  						line: l,
  						character: ch,
  						scope: JSHINT.scope,
  						a: a,
  						b: b,
  						c: c,
  						d: d
  					};
  
  					w.reason = supplant(msg.desc, w);
  					JSHINT.errors.push(w);
  
  					if (state.option.passfail) {
  						quit("E042", l, ch);
  					}
  
  					warnings += 1;
  					if (warnings >= state.option.maxerr) {
  						quit("E043", 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) {
  					warning(m, t, a, b, c, d);
  				}
  
  				function errorAt(m, l, ch, a, b, c, d) {
  					return error(m, {
  						line: l,
  						from: ch
  					}, a, b, c, d);
  				}
  				function addInternalSrc(elem, src) {
  					var i;
  					i = {
  						id: "(internal)",
  						elem: elem,
  						value: src
  					};
  					JSHINT.internals.push(i);
  					return i;
  				}
  
  				function addlabel(t, type, tkn, islet) {
  					if (type === "exception") {
  						if (_.has(funct["(context)"], t)) {
  							if (funct[t] !== true && !state.option.node) {
  								warning("W002", state.tokens.next, t);
  							}
  						}
  					}
  
  					if (_.has(funct, t) && !funct["(global)"]) {
  						if (funct[t] === true) {
  							if (state.option.latedef) {
  								if (state.option.latedef === true && _.contains([funct[t], type], "unction") || !_.contains([funct[t], type], "unction")) {
  									warning("W003", state.tokens.next, t);
  								}
  							}
  						} else {
  							if (!state.option.shadow && type !== "exception" || funct["(blockscope)"].getlabel(t)) {
  								warning("W004", state.tokens.next, t);
  							}
  						}
  					}
  					if (funct["(blockscope)"] && funct["(blockscope)"].current.has(t)) {
  						error("E044", state.tokens.next, t);
  					}
  					if (islet) {
  						funct["(blockscope)"].current.add(t, type, state.tokens.curr);
  					} else {
  
  						funct[t] = type;
  
  						if (tkn) {
  							funct["(tokens)"][t] = tkn;
  						}
  
  						if (funct["(global)"]) {
  							global[t] = funct;
  							if (_.has(implied, t)) {
  								if (state.option.latedef) {
  									if (state.option.latedef === true && _.contains([funct[t], type], "unction") || !_.contains([funct[t], type], "unction")) {
  										warning("W003", state.tokens.next, t);
  									}
  								}
  
  								delete implied[t];
  							}
  						} else {
  							scope[t] = funct;
  						}
  					}
  				}
  
  				function doOption() {
  					var nt = state.tokens.next;
  					var body = nt.body.match(/(-\s+)?[^\s,]+(?:\s*:\s*(-\s+)?[^\s,]+)?/g);
  					var predef = {};
  
  					if (nt.type === "globals") {
  						body.forEach(function (g) {
  							g = g.split(":");
  							var key = (g[0] || "").trim();
  							var val = (g[1] || "").trim();
  
  							if (key.charAt(0) === "-") {
  								key = key.slice(1);
  								val = false;
  
  								JSHINT.blacklist[key] = key;
  								updatePredefined();
  							} else {
  								predef[key] = val === "true";
  							}
  						});
  
  						combine(predefined, predef);
  
  						for (var key in predef) {
  							if (_.has(predef, key)) {
  								declared[key] = nt;
  							}
  						}
  					}
  
  					if (nt.type === "exported") {
  						body.forEach(function (e) {
  							exported[e] = true;
  						});
  					}
  
  					if (nt.type === "members") {
  						membersOnly = membersOnly || {};
  
  						body.forEach(function (m) {
  							var ch1 = m.charAt(0);
  							var ch2 = m.charAt(m.length - 1);
  
  							if (ch1 === ch2 && (ch1 === "\"" || ch1 === "'")) {
  								m = m.substr(1, m.length - 2).replace("\\b", "\b").replace("\\t", "\t").replace("\\n", "\n").replace("\\v", "\v").replace("\\f", "\f").replace("\\r", "\r").replace("\\\\", "\\").replace("\\\"", "\"");
  							}
  
  							membersOnly[m] = false;
  						});
  					}
  
  					var numvals = ["maxstatements", "maxparams", "maxdepth", "maxcomplexity", "maxerr", "maxlen", "indent"];
  
  					if (nt.type === "jshint" || nt.type === "jslint") {
  						body.forEach(function (g) {
  							g = g.split(":");
  							var key = (g[0] || "").trim();
  							var val = (g[1] || "").trim();
  
  							if (!checkOption(key, nt)) {
  								return;
  							}
  
  							if (numvals.indexOf(key) >= 0) {
  								if (val !== "false") {
  									val = +val;
  
  									if (typeof val !== "number" || !isFinite(val) || val <= 0 || Math.floor(val) !== val) {
  										error("E032", nt, g[1].trim());
  										return;
  									}
  
  									if (key === "indent") {
  										state.option["(explicitIndent)"] = true;
  									}
  									state.option[key] = val;
  								} else {
  									if (key === "indent") {
  										state.option["(explicitIndent)"] = false;
  									} else {
  										state.option[key] = false;
  									}
  								}
  
  								return;
  							}
  
  							if (key === "validthis") {
  								if (funct["(global)"]) {
  									error("E009");
  								} else {
  									if (val === "true" || val === "false") {
  										state.option.validthis = val === "true";
  									} else {
  										error("E002", nt);
  									}
  								}
  								return;
  							}
  
  							if (key === "quotmark") {
  								switch (val) {
  									case "true":
  									case "false":
  										state.option.quotmark = val === "true";
  										break;
  									case "double":
  									case "single":
  										state.option.quotmark = val;
  										break;
  									default:
  										error("E002", nt);
  								}
  								return;
  							}
  
  							if (key === "unused") {
  								switch (val) {
  									case "true":
  										state.option.unused = true;
  										break;
  									case "false":
  										state.option.unused = false;
  										break;
  									case "vars":
  									case "strict":
  										state.option.unused = val;
  										break;
  									default:
  										error("E002", nt);
  								}
  								return;
  							}
  
  							if (key === "latedef") {
  								switch (val) {
  									case "true":
  										state.option.latedef = true;
  										break;
  									case "false":
  										state.option.latedef = false;
  										break;
  									case "nofunc":
  										state.option.latedef = "nofunc";
  										break;
  									default:
  										error("E002", nt);
  								}
  								return;
  							}
  
  							var match = /^([+-])(W\d{3})$/g.exec(key);
  							if (match) {
  								state.ignored[match[2]] = match[1] === "-";
  								return;
  							}
  
  							var tn;
  							if (val === "true" || val === "false") {
  								if (nt.type === "jslint") {
  									tn = renamedOptions[key] || key;
  									state.option[tn] = val === "true";
  
  									if (invertedOptions[tn] !== undefined) {
  										state.option[tn] = !state.option[tn];
  									}
  								} else {
  									state.option[key] = val === "true";
  								}
  
  								if (key === "newcap") {
  									state.option["(explicitNewcap)"] = true;
  								}
  								return;
  							}
  
  							error("E002", nt);
  						});
  
  						assume();
  					}
  				}
  
  				function peek(p) {
  					var i = p || 0,
  					    j = 0,
  					    t;
  
  					while (j <= i) {
  						t = lookahead[j];
  						if (!t) {
  							t = lookahead[j] = lex.token();
  						}
  						j += 1;
  					}
  					return t;
  				}
  
  				function advance(id, t) {
  					switch (state.tokens.curr.id) {
  						case "(number)":
  							if (state.tokens.next.id === ".") {
  								warning("W005", state.tokens.curr);
  							}
  							break;
  						case "-":
  							if (state.tokens.next.id === "-" || state.tokens.next.id === "--") {
  								warning("W006");
  							}
  							break;
  						case "+":
  							if (state.tokens.next.id === "+" || state.tokens.next.id === "++") {
  								warning("W007");
  							}
  							break;
  					}
  
  					if (state.tokens.curr.type === "(string)" || state.tokens.curr.identifier) {
  						anonname = state.tokens.curr.value;
  					}
  
  					if (id && state.tokens.next.id !== id) {
  						if (t) {
  							if (state.tokens.next.id === "(end)") {
  								error("E019", t, t.id);
  							} else {
  								error("E020", state.tokens.next, id, t.id, t.line, state.tokens.next.value);
  							}
  						} else if (state.tokens.next.type !== "(identifier)" || state.tokens.next.value !== id) {
  							warning("W116", state.tokens.next, id, state.tokens.next.value);
  						}
  					}
  
  					state.tokens.prev = state.tokens.curr;
  					state.tokens.curr = state.tokens.next;
  					for (;;) {
  						state.tokens.next = lookahead.shift() || lex.token();
  
  						if (!state.tokens.next) {
  							// No more tokens left, give up
  							quit("E041", state.tokens.curr.line);
  						}
  
  						if (state.tokens.next.id === "(end)" || state.tokens.next.id === "(error)") {
  							return;
  						}
  
  						if (state.tokens.next.check) {
  							state.tokens.next.check();
  						}
  
  						if (state.tokens.next.isSpecial) {
  							doOption();
  						} else {
  							if (state.tokens.next.id !== "(endline)") {
  								break;
  							}
  						}
  					}
  				}
  
  				function isInfix(token) {
  					return token.infix || !token.identifier && !!token.led;
  				}
  
  				function isEndOfExpr() {
  					var curr = state.tokens.curr;
  					var next = state.tokens.next;
  					if (next.id === ";" || next.id === "}" || next.id === ":") {
  						return true;
  					}
  					if (isInfix(next) === isInfix(curr) || curr.id === "yield" && state.option.inMoz(true)) {
  						return curr.line !== next.line;
  					}
  					return false;
  				}
  
  				function expression(rbp, initial) {
  					var left,
  					    isArray = false,
  					    isObject = false,
  					    isLetExpr = false;
  					if (!initial && state.tokens.next.value === "let" && peek(0).value === "(") {
  						if (!state.option.inMoz(true)) {
  							warning("W118", state.tokens.next, "let expressions");
  						}
  						isLetExpr = true;
  						funct["(blockscope)"].stack();
  						advance("let");
  						advance("(");
  						state.syntax["let"].fud.call(state.syntax["let"].fud, false);
  						advance(")");
  					}
  
  					if (state.tokens.next.id === "(end)") error("E006", state.tokens.curr);
  
  					advance();
  
  					if (initial) {
  						anonname = "anonymous";
  						funct["(verb)"] = state.tokens.curr.value;
  					}
  
  					if (initial === true && state.tokens.curr.fud) {
  						left = state.tokens.curr.fud();
  					} else {
  						if (state.tokens.curr.nud) {
  							left = state.tokens.curr.nud();
  						} else {
  							error("E030", state.tokens.curr, state.tokens.curr.id);
  						}
  
  						while (rbp < state.tokens.next.lbp && !isEndOfExpr()) {
  							isArray = state.tokens.curr.value === "Array";
  							isObject = state.tokens.curr.value === "Object";
  							if (left && (left.value || left.first && left.first.value)) {
  								if (left.value !== "new" || left.first && left.first.value && left.first.value === ".") {
  									isArray = false;
  									if (left.value !== state.tokens.curr.value) {
  										isObject = false;
  									}
  								}
  							}
  
  							advance();
  
  							if (isArray && state.tokens.curr.id === "(" && state.tokens.next.id === ")") {
  								warning("W009", state.tokens.curr);
  							}
  
  							if (isObject && state.tokens.curr.id === "(" && state.tokens.next.id === ")") {
  								warning("W010", state.tokens.curr);
  							}
  
  							if (left && state.tokens.curr.led) {
  								left = state.tokens.curr.led(left);
  							} else {
  								error("E033", state.tokens.curr, state.tokens.curr.id);
  							}
  						}
  					}
  					if (isLetExpr) {
  						funct["(blockscope)"].unstack();
  					}
  					return left;
  				}
  
  				function adjacent(left, right) {
  					left = left || state.tokens.curr;
  					right = right || state.tokens.next;
  					if (state.option.white) {
  						if (left.character !== right.from && left.line === right.line) {
  							left.from += left.character - left.from;
  							warning("W011", left, left.value);
  						}
  					}
  				}
  
  				function nobreak(left, right) {
  					left = left || state.tokens.curr;
  					right = right || state.tokens.next;
  					if (state.option.white && (left.character !== right.from || left.line !== right.line)) {
  						warning("W012", right, right.value);
  					}
  				}
  
  				function nospace(left, right) {
  					left = left || state.tokens.curr;
  					right = right || state.tokens.next;
  					if (state.option.white && !left.comment) {
  						if (left.line === right.line) {
  							adjacent(left, right);
  						}
  					}
  				}
  
  				function nonadjacent(left, right) {
  					if (state.option.white) {
  						left = left || state.tokens.curr;
  						right = right || state.tokens.next;
  
  						if (left.value === ";" && right.value === ";") {
  							return;
  						}
  
  						if (left.line === right.line && left.character === right.from) {
  							left.from += left.character - left.from;
  							warning("W013", left, left.value);
  						}
  					}
  				}
  
  				function nobreaknonadjacent(left, right) {
  					left = left || state.tokens.curr;
  					right = right || state.tokens.next;
  					if (!state.option.laxbreak && left.line !== right.line) {
  						warning("W014", right, right.value);
  					} else if (state.option.white) {
  						left = left || state.tokens.curr;
  						right = right || state.tokens.next;
  						if (left.character === right.from) {
  							left.from += left.character - left.from;
  							warning("W013", left, left.value);
  						}
  					}
  				}
  
  				function indentation(bias) {
  					if (!state.option.white && !state.option["(explicitIndent)"]) {
  						return;
  					}
  
  					if (state.tokens.next.id === "(end)") {
  						return;
  					}
  
  					var i = indent + (bias || 0);
  					if (state.tokens.next.from !== i) {
  						warning("W015", state.tokens.next, state.tokens.next.value, i, state.tokens.next.from);
  					}
  				}
  
  				function nolinebreak(t) {
  					t = t || state.tokens.curr;
  					if (t.line !== state.tokens.next.line) {
  						warning("E022", t, t.value);
  					}
  				}
  
  				function nobreakcomma(left, right) {
  					if (left.line !== right.line) {
  						if (!state.option.laxcomma) {
  							if (comma.first) {
  								warning("I001");
  								comma.first = false;
  							}
  							warning("W014", left, right.value);
  						}
  					} else if (!left.comment && left.character !== right.from && state.option.white) {
  						left.from += left.character - left.from;
  						warning("W011", left, left.value);
  					}
  				}
  
  				function comma(opts) {
  					opts = opts || {};
  
  					if (!opts.peek) {
  						nobreakcomma(state.tokens.curr, state.tokens.next);
  						advance(",");
  					} else {
  						nobreakcomma(state.tokens.prev, state.tokens.curr);
  					}
  
  					if (state.tokens.next.value !== "]" && state.tokens.next.value !== "}") {
  						nonadjacent(state.tokens.curr, state.tokens.next);
  					}
  
  					if (state.tokens.next.identifier && !(opts.property && state.option.inES5())) {
  						switch (state.tokens.next.value) {
  							case "break":
  							case "case":
  							case "catch":
  							case "continue":
  							case "default":
  							case "do":
  							case "else":
  							case "finally":
  							case "for":
  							case "if":
  							case "in":
  							case "instanceof":
  							case "return":
  							case "switch":
  							case "throw":
  							case "try":
  							case "var":
  							case "let":
  							case "while":
  							case "with":
  								error("E024", state.tokens.next, state.tokens.next.value);
  								return false;
  						}
  					}
  
  					if (state.tokens.next.type === "(punctuator)") {
  						switch (state.tokens.next.value) {
  							case "}":
  							case "]":
  							case ",":
  								if (opts.allowTrailing) {
  									return true;
  								}
  							case ")":
  								error("E024", state.tokens.next, state.tokens.next.value);
  								return false;
  						}
  					}
  					return true;
  				}
  
  				function symbol(s, p) {
  					var x = state.syntax[s];
  					if (!x || (typeof x === "undefined" ? "undefined" : _typeof(x)) !== "object") {
  						state.syntax[s] = x = {
  							id: s,
  							lbp: p,
  							value: s
  						};
  					}
  					return x;
  				}
  
  				function delim(s) {
  					return symbol(s, 0);
  				}
  
  				function stmt(s, f) {
  					var x = delim(s);
  					x.identifier = x.reserved = true;
  					x.fud = f;
  					return x;
  				}
  
  				function blockstmt(s, f) {
  					var x = stmt(s, f);
  					x.block = true;
  					return x;
  				}
  
  				function reserveName(x) {
  					var c = x.id.charAt(0);
  					if (c >= "a" && c <= "z" || c >= "A" && c <= "Z") {
  						x.identifier = x.reserved = true;
  					}
  					return x;
  				}
  
  				function prefix(s, f) {
  					var x = symbol(s, 150);
  					reserveName(x);
  					x.nud = typeof f === "function" ? f : function () {
  						this.right = expression(150);
  						this.arity = "unary";
  						if (this.id === "++" || this.id === "--") {
  							if (state.option.plusplus) {
  								warning("W016", this, this.id);
  							} else if (this.right && (!this.right.identifier || isReserved(this.right)) && this.right.id !== "." && this.right.id !== "[") {
  								warning("W017", this);
  							}
  						}
  						return this;
  					};
  					return x;
  				}
  
  				function type(s, f) {
  					var x = delim(s);
  					x.type = s;
  					x.nud = f;
  					return x;
  				}
  
  				function reserve(name, func) {
  					var x = type(name, func);
  					x.identifier = true;
  					x.reserved = true;
  					return x;
  				}
  
  				function FutureReservedWord(name, meta) {
  					var x = type(name, meta && meta.nud || function () {
  						return this;
  					});
  
  					meta = meta || {};
  					meta.isFutureReservedWord = true;
  
  					x.value = name;
  					x.identifier = true;
  					x.reserved = true;
  					x.meta = meta;
  
  					return x;
  				}
  
  				function reservevar(s, v) {
  					return reserve(s, function () {
  						if (typeof v === "function") {
  							v(this);
  						}
  						return this;
  					});
  				}
  
  				function infix(s, f, p, w) {
  					var x = symbol(s, p);
  					reserveName(x);
  					x.infix = true;
  					x.led = function (left) {
  						if (!w) {
  							nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
  							nonadjacent(state.tokens.curr, state.tokens.next);
  						}
  						if (s === "in" && left.id === "!") {
  							warning("W018", left, "!");
  						}
  						if (typeof f === "function") {
  							return f(left, this);
  						} else {
  							this.left = left;
  							this.right = expression(p);
  							return this;
  						}
  					};
  					return x;
  				}
  
  				function application(s) {
  					var x = symbol(s, 42);
  
  					x.led = function (left) {
  						if (!state.option.inESNext()) {
  							warning("W104", state.tokens.curr, "arrow function syntax (=>)");
  						}
  
  						nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
  						nonadjacent(state.tokens.curr, state.tokens.next);
  
  						this.left = left;
  						this.right = doFunction(undefined, undefined, false, left);
  						return this;
  					};
  					return x;
  				}
  
  				function relation(s, f) {
  					var x = symbol(s, 100);
  
  					x.led = function (left) {
  						nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
  						nonadjacent(state.tokens.curr, state.tokens.next);
  						var right = expression(100);
  
  						if (isIdentifier(left, "NaN") || isIdentifier(right, "NaN")) {
  							warning("W019", this);
  						} else if (f) {
  							f.apply(this, [left, right]);
  						}
  
  						if (!left || !right) {
  							quit("E041", state.tokens.curr.line);
  						}
  
  						if (left.id === "!") {
  							warning("W018", left, "!");
  						}
  
  						if (right.id === "!") {
  							warning("W018", right, "!");
  						}
  
  						this.left = left;
  						this.right = right;
  						return this;
  					};
  					return x;
  				}
  
  				function isPoorRelation(node) {
  					return node && (node.type === "(number)" && +node.value === 0 || node.type === "(string)" && node.value === "" || node.type === "null" && !state.option.eqnull || node.type === "true" || node.type === "false" || node.type === "undefined");
  				}
  
  				function assignop(s, f, p) {
  					var x = infix(s, typeof f === "function" ? f : function (left, that) {
  						that.left = left;
  
  						if (left) {
  							if (predefined[left.value] === false && scope[left.value]["(global)"] === true) {
  								warning("W020", left);
  							} else if (left["function"]) {
  								warning("W021", left, left.value);
  							}
  
  							if (funct[left.value] === "const") {
  								error("E013", left, left.value);
  							}
  
  							if (left.id === ".") {
  								if (!left.left) {
  									warning("E031", that);
  								} else if (left.left.value === "arguments" && !state.directive["use strict"]) {
  									warning("E031", that);
  								}
  
  								that.right = expression(10);
  								return that;
  							} else if (left.id === "[") {
  								if (state.tokens.curr.left.first) {
  									state.tokens.curr.left.first.forEach(function (t) {
  										if (funct[t.value] === "const") {
  											error("E013", t, t.value);
  										}
  									});
  								} else if (!left.left) {
  									warning("E031", that);
  								} else if (left.left.value === "arguments" && !state.directive["use strict"]) {
  									warning("E031", that);
  								}
  								that.right = expression(10);
  								return that;
  							} else if (left.identifier && !isReserved(left)) {
  								if (funct[left.value] === "exception") {
  									warning("W022", left);
  								}
  								that.right = expression(10);
  								return that;
  							}
  
  							if (left === state.syntax["function"]) {
  								warning("W023", state.tokens.curr);
  							}
  						}
  
  						error("E031", that);
  					}, p);
  
  					x.exps = true;
  					x.assign = true;
  					return x;
  				}
  
  				function bitwise(s, f, p) {
  					var x = symbol(s, p);
  					reserveName(x);
  					x.led = typeof f === "function" ? f : function (left) {
  						if (state.option.bitwise) {
  							warning("W016", this, this.id);
  						}
  						this.left = left;
  						this.right = expression(p);
  						return this;
  					};
  					return x;
  				}
  
  				function bitwiseassignop(s) {
  					return assignop(s, function (left, that) {
  						if (state.option.bitwise) {
  							warning("W016", that, that.id);
  						}
  						nonadjacent(state.tokens.prev, state.tokens.curr);
  						nonadjacent(state.tokens.curr, state.tokens.next);
  						if (left) {
  							if (left.id === "." || left.id === "[" || left.identifier && !isReserved(left)) {
  								expression(10);
  								return that;
  							}
  							if (left === state.syntax["function"]) {
  								warning("W023", state.tokens.curr);
  							}
  							return that;
  						}
  						error("E031", that);
  					}, 20);
  				}
  
  				function suffix(s) {
  					var x = symbol(s, 150);
  
  					x.led = function (left) {
  						if (state.option.plusplus) {
  							warning("W016", this, this.id);
  						} else if ((!left.identifier || isReserved(left)) && left.id !== "." && left.id !== "[") {
  							warning("W017", this);
  						}
  
  						this.left = left;
  						return this;
  					};
  					return x;
  				}
  
  				function optionalidentifier(fnparam, prop) {
  					if (!state.tokens.next.identifier) {
  						return;
  					}
  
  					advance();
  
  					var curr = state.tokens.curr;
  					var val = state.tokens.curr.value;
  
  					if (!isReserved(curr)) {
  						return val;
  					}
  
  					if (prop) {
  						if (state.option.inES5()) {
  							return val;
  						}
  					}
  
  					if (fnparam && val === "undefined") {
  						return val;
  					}
  					if (prop && !api.getCache("displayed:I002")) {
  						api.setCache("displayed:I002", true);
  						warning("I002");
  					}
  
  					warning("W024", state.tokens.curr, state.tokens.curr.id);
  					return val;
  				}
  				function identifier(fnparam, prop) {
  					var i = optionalidentifier(fnparam, prop);
  					if (i) {
  						return i;
  					}
  					if (state.tokens.curr.id === "function" && state.tokens.next.id === "(") {
  						warning("W025");
  					} else {
  						error("E030", state.tokens.next, state.tokens.next.value);
  					}
  				}
  
  				function reachable(s) {
  					var i = 0,
  					    t;
  					if (state.tokens.next.id !== ";" || noreach) {
  						return;
  					}
  					for (;;) {
  						t = peek(i);
  						if (t.reach) {
  							return;
  						}
  						if (t.id !== "(endline)") {
  							if (t.id === "function") {
  								if (!state.option.latedef) {
  									break;
  								}
  
  								warning("W026", t);
  								break;
  							}
  
  							warning("W027", t, t.value, s);
  							break;
  						}
  						i += 1;
  					}
  				}
  
  				function statement(noindent) {
  					var values;
  					var i = indent,
  					    r,
  					    s = scope,
  					    t = state.tokens.next;
  
  					if (t.id === ";") {
  						advance(";");
  						return;
  					}
  					var res = isReserved(t);
  
  					if (res && t.meta && t.meta.isFutureReservedWord && peek().id === ":") {
  						warning("W024", t, t.id);
  						res = false;
  					}
  					if (_.has(["[", "{"], t.value)) {
  						if (lookupBlockType().isDestAssign) {
  							if (!state.option.inESNext()) {
  								warning("W104", state.tokens.curr, "destructuring expression");
  							}
  							values = destructuringExpression();
  							values.forEach(function (tok) {
  								isundef(funct, "W117", tok.token, tok.id);
  							});
  							advance("=");
  							destructuringExpressionMatch(values, expression(10, true));
  							advance(";");
  							return;
  						}
  					}
  					if (t.identifier && !res && peek().id === ":") {
  						advance();
  						advance(":");
  						scope = Object.create(s);
  						addlabel(t.value, "label");
  
  						if (!state.tokens.next.labelled && state.tokens.next.value !== "{") {
  							warning("W028", state.tokens.next, t.value, state.tokens.next.value);
  						}
  
  						state.tokens.next.label = t.value;
  						t = state.tokens.next;
  					}
  
  					if (t.id === "{") {
  						block(true, true);
  						return;
  					}
  
  					if (!noindent) {
  						indentation();
  					}
  					r = expression(0, true);
  
  					if (!t.block) {
  						if (!state.option.expr && (!r || !r.exps)) {
  							warning("W030", state.tokens.curr);
  						} else if (state.option.nonew && r && r.left && r.id === "(" && r.left.id === "new") {
  							warning("W031", t);
  						}
  
  						if (state.tokens.next.id !== ";") {
  							if (!state.option.asi) {
  								if (!state.option.lastsemic || state.tokens.next.id !== "}" || state.tokens.next.line !== state.tokens.curr.line) {
  									warningAt("W033", state.tokens.curr.line, state.tokens.curr.character);
  								}
  							}
  						} else {
  							adjacent(state.tokens.curr, state.tokens.next);
  							advance(";");
  							nonadjacent(state.tokens.curr, state.tokens.next);
  						}
  					}
  
  					indent = i;
  					scope = s;
  					return r;
  				}
  
  				function statements(startLine) {
  					var a = [],
  					    p;
  
  					while (!state.tokens.next.reach && state.tokens.next.id !== "(end)") {
  						if (state.tokens.next.id === ";") {
  							p = peek();
  
  							if (!p || p.id !== "(" && p.id !== "[") {
  								warning("W032");
  							}
  
  							advance(";");
  						} else {
  							a.push(statement(startLine === state.tokens.next.line));
  						}
  					}
  					return a;
  				}
  				function directives() {
  					var i, p, pn;
  
  					for (;;) {
  						if (state.tokens.next.id === "(string)") {
  							p = peek(0);
  							if (p.id === "(endline)") {
  								i = 1;
  								do {
  									pn = peek(i);
  									i = i + 1;
  								} while (pn.id === "(endline)");
  
  								if (pn.id !== ";") {
  									if (pn.id !== "(string)" && pn.id !== "(number)" && pn.id !== "(regexp)" && pn.identifier !== true && pn.id !== "}") {
  										break;
  									}
  									warning("W033", state.tokens.next);
  								} else {
  									p = pn;
  								}
  							} else if (p.id === "}") {
  								warning("W033", p);
  							} else if (p.id !== ";") {
  								break;
  							}
  
  							indentation();
  							advance();
  							if (state.directive[state.tokens.curr.value]) {
  								warning("W034", state.tokens.curr, state.tokens.curr.value);
  							}
  
  							if (state.tokens.curr.value === "use strict") {
  								if (!state.option["(explicitNewcap)"]) state.option.newcap = true;
  								state.option.undef = true;
  							}
  							state.directive[state.tokens.curr.value] = true;
  
  							if (p.id === ";") {
  								advance(";");
  							}
  							continue;
  						}
  						break;
  					}
  				}
  				function block(ordinary, stmt, isfunc, isfatarrow) {
  					var a,
  					    b = inblock,
  					    old_indent = indent,
  					    m,
  					    s = scope,
  					    t,
  					    line,
  					    d;
  
  					inblock = ordinary;
  
  					if (!ordinary || !state.option.funcscope) scope = Object.create(scope);
  
  					nonadjacent(state.tokens.curr, state.tokens.next);
  					t = state.tokens.next;
  
  					var metrics = funct["(metrics)"];
  					metrics.nestedBlockDepth += 1;
  					metrics.verifyMaxNestedBlockDepthPerFunction();
  
  					if (state.tokens.next.id === "{") {
  						advance("{");
  						funct["(blockscope)"].stack();
  
  						line = state.tokens.curr.line;
  						if (state.tokens.next.id !== "}") {
  							indent += state.option.indent;
  							while (!ordinary && state.tokens.next.from > indent) {
  								indent += state.option.indent;
  							}
  
  							if (isfunc) {
  								m = {};
  								for (d in state.directive) {
  									if (_.has(state.directive, d)) {
  										m[d] = state.directive[d];
  									}
  								}
  								directives();
  
  								if (state.option.strict && funct["(context)"]["(global)"]) {
  									if (!m["use strict"] && !state.directive["use strict"]) {
  										warning("E007");
  									}
  								}
  							}
  
  							a = statements(line);
  
  							metrics.statementCount += a.length;
  
  							if (isfunc) {
  								state.directive = m;
  							}
  
  							indent -= state.option.indent;
  							if (line !== state.tokens.next.line) {
  								indentation();
  							}
  						} else if (line !== state.tokens.next.line) {
  							indentation();
  						}
  						advance("}", t);
  
  						funct["(blockscope)"].unstack();
  
  						indent = old_indent;
  					} else if (!ordinary) {
  						if (isfunc) {
  							m = {};
  							if (stmt && !isfatarrow && !state.option.inMoz(true)) {
  								error("W118", state.tokens.curr, "function closure expressions");
  							}
  
  							if (!stmt) {
  								for (d in state.directive) {
  									if (_.has(state.directive, d)) {
  										m[d] = state.directive[d];
  									}
  								}
  							}
  							expression(10);
  
  							if (state.option.strict && funct["(context)"]["(global)"]) {
  								if (!m["use strict"] && !state.directive["use strict"]) {
  									warning("E007");
  								}
  							}
  						} else {
  							error("E021", state.tokens.next, "{", state.tokens.next.value);
  						}
  					} else {
  						funct["(nolet)"] = true;
  
  						if (!stmt || state.option.curly) {
  							warning("W116", state.tokens.next, "{", state.tokens.next.value);
  						}
  
  						noreach = true;
  						indent += state.option.indent;
  						a = [statement(state.tokens.next.line === state.tokens.curr.line)];
  						indent -= state.option.indent;
  						noreach = false;
  
  						delete funct["(nolet)"];
  					}
  					funct["(verb)"] = null;
  					if (!ordinary || !state.option.funcscope) scope = s;
  					inblock = b;
  					if (ordinary && state.option.noempty && (!a || a.length === 0)) {
  						warning("W035");
  					}
  					metrics.nestedBlockDepth -= 1;
  					return a;
  				}
  
  				function countMember(m) {
  					if (membersOnly && typeof membersOnly[m] !== "boolean") {
  						warning("W036", state.tokens.curr, m);
  					}
  					if (typeof member[m] === "number") {
  						member[m] += 1;
  					} else {
  						member[m] = 1;
  					}
  				}
  
  				function note_implied(tkn) {
  					var name = tkn.value,
  					    line = tkn.line,
  					    a = implied[name];
  					if (typeof a === "function") {
  						a = false;
  					}
  
  					if (!a) {
  						a = [line];
  						implied[name] = a;
  					} else if (a[a.length - 1] !== line) {
  						a.push(line);
  					}
  				}
  
  				type("(number)", function () {
  					return this;
  				});
  
  				type("(string)", function () {
  					return this;
  				});
  
  				state.syntax["(identifier)"] = {
  					type: "(identifier)",
  					lbp: 0,
  					identifier: true,
  					nud: function nud() {
  						var v = this.value,
  						    s = scope[v],
  						    f;
  
  						if (typeof s === "function") {
  							s = undefined;
  						} else if (typeof s === "boolean") {
  							f = funct;
  							funct = functions[0];
  							addlabel(v, "var");
  							s = funct;
  							funct = f;
  						}
  						var block;
  						if (_.has(funct, "(blockscope)")) {
  							block = funct["(blockscope)"].getlabel(v);
  						}
  						if (funct === s || block) {
  							switch (block ? block[v]["(type)"] : funct[v]) {
  								case "unused":
  									if (block) block[v]["(type)"] = "var";else funct[v] = "var";
  									break;
  								case "unction":
  									if (block) block[v]["(type)"] = "function";else funct[v] = "function";
  									this["function"] = true;
  									break;
  								case "function":
  									this["function"] = true;
  									break;
  								case "label":
  									warning("W037", state.tokens.curr, v);
  									break;
  							}
  						} else if (funct["(global)"]) {
  
  							if (typeof predefined[v] !== "boolean") {
  								if (!(anonname === "typeof" || anonname === "delete") || state.tokens.next && (state.tokens.next.value === "." || state.tokens.next.value === "[")) {
  
  									if (!funct["(comparray)"].check(v)) {
  										isundef(funct, "W117", state.tokens.curr, v);
  									}
  								}
  							}
  
  							note_implied(state.tokens.curr);
  						} else {
  
  							switch (funct[v]) {
  								case "closure":
  								case "function":
  								case "var":
  								case "unused":
  									warning("W038", state.tokens.curr, v);
  									break;
  								case "label":
  									warning("W037", state.tokens.curr, v);
  									break;
  								case "outer":
  								case "global":
  									break;
  								default:
  									if (s === true) {
  										funct[v] = true;
  									} else if (s === null) {
  										warning("W039", state.tokens.curr, v);
  										note_implied(state.tokens.curr);
  									} else if ((typeof s === "undefined" ? "undefined" : _typeof(s)) !== "object") {
  										if (!(anonname === "typeof" || anonname === "delete") || state.tokens.next && (state.tokens.next.value === "." || state.tokens.next.value === "[")) {
  
  											isundef(funct, "W117", state.tokens.curr, v);
  										}
  										funct[v] = true;
  										note_implied(state.tokens.curr);
  									} else {
  										switch (s[v]) {
  											case "function":
  											case "unction":
  												this["function"] = true;
  												s[v] = "closure";
  												funct[v] = s["(global)"] ? "global" : "outer";
  												break;
  											case "var":
  											case "unused":
  												s[v] = "closure";
  												funct[v] = s["(global)"] ? "global" : "outer";
  												break;
  											case "closure":
  												funct[v] = s["(global)"] ? "global" : "outer";
  												break;
  											case "label":
  												warning("W037", state.tokens.curr, v);
  										}
  									}
  							}
  						}
  						return this;
  					},
  					led: function led() {
  						error("E033", state.tokens.next, state.tokens.next.value);
  					}
  				};
  
  				type("(regexp)", function () {
  					return this;
  				});
  
  				delim("(endline)");
  				delim("(begin)");
  				delim("(end)").reach = true;
  				delim("(error)").reach = true;
  				delim("}").reach = true;
  				delim(")");
  				delim("]");
  				delim("\"").reach = true;
  				delim("'").reach = true;
  				delim(";");
  				delim(":").reach = true;
  				delim("#");
  
  				reserve("else");
  				reserve("case").reach = true;
  				reserve("catch");
  				reserve("default").reach = true;
  				reserve("finally");
  				reservevar("arguments", function (x) {
  					if (state.directive["use strict"] && funct["(global)"]) {
  						warning("E008", x);
  					}
  				});
  				reservevar("eval");
  				reservevar("false");
  				reservevar("Infinity");
  				reservevar("null");
  				reservevar("this", function (x) {
  					if (state.directive["use strict"] && !state.option.validthis && (funct["(statement)"] && funct["(name)"].charAt(0) > "Z" || funct["(global)"])) {
  						warning("W040", x);
  					}
  				});
  				reservevar("true");
  				reservevar("undefined");
  
  				assignop("=", "assign", 20);
  				assignop("+=", "assignadd", 20);
  				assignop("-=", "assignsub", 20);
  				assignop("*=", "assignmult", 20);
  				assignop("/=", "assigndiv", 20).nud = function () {
  					error("E014");
  				};
  				assignop("%=", "assignmod", 20);
  
  				bitwiseassignop("&=", "assignbitand", 20);
  				bitwiseassignop("|=", "assignbitor", 20);
  				bitwiseassignop("^=", "assignbitxor", 20);
  				bitwiseassignop("<<=", "assignshiftleft", 20);
  				bitwiseassignop(">>=", "assignshiftright", 20);
  				bitwiseassignop(">>>=", "assignshiftrightunsigned", 20);
  				infix(",", function (left, that) {
  					var expr;
  					that.exprs = [left];
  					if (!comma({ peek: true })) {
  						return that;
  					}
  					while (true) {
  						if (!(expr = expression(10))) {
  							break;
  						}
  						that.exprs.push(expr);
  						if (state.tokens.next.value !== "," || !comma()) {
  							break;
  						}
  					}
  					return that;
  				}, 10, true);
  
  				infix("?", function (left, that) {
  					increaseComplexityCount();
  					that.left = left;
  					that.right = expression(10);
  					advance(":");
  					that["else"] = expression(10);
  					return that;
  				}, 30);
  
  				var orPrecendence = 40;
  				infix("||", function (left, that) {
  					increaseComplexityCount();
  					that.left = left;
  					that.right = expression(orPrecendence);
  					return that;
  				}, orPrecendence);
  				infix("&&", "and", 50);
  				bitwise("|", "bitor", 70);
  				bitwise("^", "bitxor", 80);
  				bitwise("&", "bitand", 90);
  				relation("==", function (left, right) {
  					var eqnull = state.option.eqnull && (left.value === "null" || right.value === "null");
  
  					if (!eqnull && state.option.eqeqeq) warning("W116", this, "===", "==");else if (isPoorRelation(left)) warning("W041", this, "===", left.value);else if (isPoorRelation(right)) warning("W041", this, "===", right.value);
  
  					return this;
  				});
  				relation("===");
  				relation("!=", function (left, right) {
  					var eqnull = state.option.eqnull && (left.value === "null" || right.value === "null");
  
  					if (!eqnull && state.option.eqeqeq) {
  						warning("W116", this, "!==", "!=");
  					} else if (isPoorRelation(left)) {
  						warning("W041", this, "!==", left.value);
  					} else if (isPoorRelation(right)) {
  						warning("W041", this, "!==", right.value);
  					}
  					return this;
  				});
  				relation("!==");
  				relation("<");
  				relation(">");
  				relation("<=");
  				relation(">=");
  				bitwise("<<", "shiftleft", 120);
  				bitwise(">>", "shiftright", 120);
  				bitwise(">>>", "shiftrightunsigned", 120);
  				infix("in", "in", 120);
  				infix("instanceof", "instanceof", 120);
  				infix("+", function (left, that) {
  					var right = expression(130);
  					if (left && right && left.id === "(string)" && right.id === "(string)") {
  						left.value += right.value;
  						left.character = right.character;
  						if (!state.option.scripturl && reg.javascriptURL.test(left.value)) {
  							warning("W050", left);
  						}
  						return left;
  					}
  					that.left = left;
  					that.right = right;
  					return that;
  				}, 130);
  				prefix("+", "num");
  				prefix("+++", function () {
  					warning("W007");
  					this.right = expression(150);
  					this.arity = "unary";
  					return this;
  				});
  				infix("+++", function (left) {
  					warning("W007");
  					this.left = left;
  					this.right = expression(130);
  					return this;
  				}, 130);
  				infix("-", "sub", 130);
  				prefix("-", "neg");
  				prefix("---", function () {
  					warning("W006");
  					this.right = expression(150);
  					this.arity = "unary";
  					return this;
  				});
  				infix("---", function (left) {
  					warning("W006");
  					this.left = left;
  					this.right = expression(130);
  					return this;
  				}, 130);
  				infix("*", "mult", 140);
  				infix("/", "div", 140);
  				infix("%", "mod", 140);
  
  				suffix("++", "postinc");
  				prefix("++", "preinc");
  				state.syntax["++"].exps = true;
  
  				suffix("--", "postdec");
  				prefix("--", "predec");
  				state.syntax["--"].exps = true;
  				prefix("delete", function () {
  					var p = expression(10);
  					if (!p || p.id !== "." && p.id !== "[") {
  						warning("W051");
  					}
  					this.first = p;
  					return this;
  				}).exps = true;
  
  				prefix("~", function () {
  					if (state.option.bitwise) {
  						warning("W052", this, "~");
  					}
  					expression(150);
  					return this;
  				});
  
  				prefix("...", function () {
  					if (!state.option.inESNext()) {
  						warning("W104", this, "spread/rest operator");
  					}
  					if (!state.tokens.next.identifier) {
  						error("E030", state.tokens.next, state.tokens.next.value);
  					}
  					expression(150);
  					return this;
  				});
  
  				prefix("!", function () {
  					this.right = expression(150);
  					this.arity = "unary";
  
  					if (!this.right) {
  						// '!' followed by nothing? Give up.
  						quit("E041", this.line || 0);
  					}
  
  					if (bang[this.right.id] === true) {
  						warning("W018", this, "!");
  					}
  					return this;
  				});
  
  				prefix("typeof", "typeof");
  				prefix("new", function () {
  					var c = expression(155),
  					    i;
  					if (c && c.id !== "function") {
  						if (c.identifier) {
  							c["new"] = true;
  							switch (c.value) {
  								case "Number":
  								case "String":
  								case "Boolean":
  								case "Math":
  								case "JSON":
  									warning("W053", state.tokens.prev, c.value);
  									break;
  								case "Function":
  									if (!state.option.evil) {
  										warning("W054");
  									}
  									break;
  								case "Date":
  								case "RegExp":
  									break;
  								default:
  									if (c.id !== "function") {
  										i = c.value.substr(0, 1);
  										if (state.option.newcap && (i < "A" || i > "Z") && !_.has(global, c.value)) {
  											warning("W055", state.tokens.curr);
  										}
  									}
  							}
  						} else {
  							if (c.id !== "." && c.id !== "[" && c.id !== "(") {
  								warning("W056", state.tokens.curr);
  							}
  						}
  					} else {
  						if (!state.option.supernew) warning("W057", this);
  					}
  					adjacent(state.tokens.curr, state.tokens.next);
  					if (state.tokens.next.id !== "(" && !state.option.supernew) {
  						warning("W058", state.tokens.curr, state.tokens.curr.value);
  					}
  					this.first = c;
  					return this;
  				});
  				state.syntax["new"].exps = true;
  
  				prefix("void").exps = true;
  
  				infix(".", function (left, that) {
  					adjacent(state.tokens.prev, state.tokens.curr);
  					nobreak();
  					var m = identifier(false, true);
  
  					if (typeof m === "string") {
  						countMember(m);
  					}
  
  					that.left = left;
  					that.right = m;
  
  					if (m && m === "hasOwnProperty" && state.tokens.next.value === "=") {
  						warning("W001");
  					}
  
  					if (left && left.value === "arguments" && (m === "callee" || m === "caller")) {
  						if (state.option.noarg) warning("W059", left, m);else if (state.directive["use strict"]) error("E008");
  					} else if (!state.option.evil && left && left.value === "document" && (m === "write" || m === "writeln")) {
  						warning("W060", left);
  					}
  
  					if (!state.option.evil && (m === "eval" || m === "execScript")) {
  						warning("W061");
  					}
  
  					return that;
  				}, 160, true);
  
  				infix("(", function (left, that) {
  					if (state.tokens.prev.id !== "}" && state.tokens.prev.id !== ")") {
  						nobreak(state.tokens.prev, state.tokens.curr);
  					}
  
  					nospace();
  					if (state.option.immed && left && !left.immed && left.id === "function") {
  						warning("W062");
  					}
  
  					var n = 0;
  					var p = [];
  
  					if (left) {
  						if (left.type === "(identifier)") {
  							if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) {
  								if ("Number String Boolean Date Object".indexOf(left.value) === -1) {
  									if (left.value === "Math") {
  										warning("W063", left);
  									} else if (state.option.newcap) {
  										warning("W064", left);
  									}
  								}
  							}
  						}
  					}
  
  					if (state.tokens.next.id !== ")") {
  						for (;;) {
  							p[p.length] = expression(10);
  							n += 1;
  							if (state.tokens.next.id !== ",") {
  								break;
  							}
  							comma();
  						}
  					}
  
  					advance(")");
  					nospace(state.tokens.prev, state.tokens.curr);
  
  					if ((typeof left === "undefined" ? "undefined" : _typeof(left)) === "object") {
  						if (left.value === "parseInt" && n === 1) {
  							warning("W065", state.tokens.curr);
  						}
  						if (!state.option.evil) {
  							if (left.value === "eval" || left.value === "Function" || left.value === "execScript") {
  								warning("W061", left);
  
  								if (p[0] && [0].id === "(string)") {
  									addInternalSrc(left, p[0].value);
  								}
  							} else if (p[0] && p[0].id === "(string)" && (left.value === "setTimeout" || left.value === "setInterval")) {
  								warning("W066", left);
  								addInternalSrc(left, p[0].value);
  							} else if (p[0] && p[0].id === "(string)" && left.value === "." && left.left.value === "window" && (left.right === "setTimeout" || left.right === "setInterval")) {
  								warning("W066", left);
  								addInternalSrc(left, p[0].value);
  							}
  						}
  						if (!left.identifier && left.id !== "." && left.id !== "[" && left.id !== "(" && left.id !== "&&" && left.id !== "||" && left.id !== "?") {
  							warning("W067", left);
  						}
  					}
  
  					that.left = left;
  					return that;
  				}, 155, true).exps = true;
  
  				prefix("(", function () {
  					nospace();
  					var bracket,
  					    brackets = [];
  					var pn,
  					    pn1,
  					    i = 0;
  					var ret;
  
  					do {
  						pn = peek(i);
  						i += 1;
  						pn1 = peek(i);
  						i += 1;
  					} while (pn.value !== ")" && pn1.value !== "=>" && pn1.value !== ";" && pn1.type !== "(end)");
  
  					if (state.tokens.next.id === "function") {
  						state.tokens.next.immed = true;
  					}
  
  					var exprs = [];
  
  					if (state.tokens.next.id !== ")") {
  						for (;;) {
  							if (pn1.value === "=>" && state.tokens.next.value === "{") {
  								bracket = state.tokens.next;
  								bracket.left = destructuringExpression();
  								brackets.push(bracket);
  								for (var t in bracket.left) {
  									exprs.push(bracket.left[t].token);
  								}
  							} else {
  								exprs.push(expression(10));
  							}
  							if (state.tokens.next.id !== ",") {
  								break;
  							}
  							comma();
  						}
  					}
  
  					advance(")", this);
  					nospace(state.tokens.prev, state.tokens.curr);
  					if (state.option.immed && exprs[0] && exprs[0].id === "function") {
  						if (state.tokens.next.id !== "(" && (state.tokens.next.id !== "." || peek().value !== "call" && peek().value !== "apply")) {
  							warning("W068", this);
  						}
  					}
  
  					if (state.tokens.next.value === "=>") {
  						return exprs;
  					}
  					if (!exprs.length) {
  						return;
  					}
  					if (exprs.length > 1) {
  						ret = Object.create(state.syntax[","]);
  						ret.exprs = exprs;
  					} else {
  						ret = exprs[0];
  					}
  					if (ret) {
  						ret.paren = true;
  					}
  					return ret;
  				});
  
  				application("=>");
  
  				infix("[", function (left, that) {
  					nobreak(state.tokens.prev, state.tokens.curr);
  					nospace();
  					var e = expression(10),
  					    s;
  					if (e && e.type === "(string)") {
  						if (!state.option.evil && (e.value === "eval" || e.value === "execScript")) {
  							warning("W061", that);
  						}
  
  						countMember(e.value);
  						if (!state.option.sub && reg.identifier.test(e.value)) {
  							s = state.syntax[e.value];
  							if (!s || !isReserved(s)) {
  								warning("W069", state.tokens.prev, e.value);
  							}
  						}
  					}
  					advance("]", that);
  
  					if (e && e.value === "hasOwnProperty" && state.tokens.next.value === "=") {
  						warning("W001");
  					}
  
  					nospace(state.tokens.prev, state.tokens.curr);
  					that.left = left;
  					that.right = e;
  					return that;
  				}, 160, true);
  
  				function comprehensiveArrayExpression() {
  					var res = {};
  					res.exps = true;
  					funct["(comparray)"].stack();
  
  					res.right = expression(10);
  					advance("for");
  					if (state.tokens.next.value === "each") {
  						advance("each");
  						if (!state.option.inMoz(true)) {
  							warning("W118", state.tokens.curr, "for each");
  						}
  					}
  					advance("(");
  					funct["(comparray)"].setState("define");
  					res.left = expression(10);
  					advance(")");
  					if (state.tokens.next.value === "if") {
  						advance("if");
  						advance("(");
  						funct["(comparray)"].setState("filter");
  						res.filter = expression(10);
  						advance(")");
  					}
  					advance("]");
  					funct["(comparray)"].unstack();
  					return res;
  				}
  
  				prefix("[", function () {
  					var blocktype = lookupBlockType(true);
  					if (blocktype.isCompArray) {
  						if (!state.option.inMoz(true)) {
  							warning("W118", state.tokens.curr, "array comprehension");
  						}
  						return comprehensiveArrayExpression();
  					} else if (blocktype.isDestAssign && !state.option.inESNext()) {
  						warning("W104", state.tokens.curr, "destructuring assignment");
  					}
  					var b = state.tokens.curr.line !== state.tokens.next.line;
  					this.first = [];
  					if (b) {
  						indent += state.option.indent;
  						if (state.tokens.next.from === indent + state.option.indent) {
  							indent += state.option.indent;
  						}
  					}
  					while (state.tokens.next.id !== "(end)") {
  						while (state.tokens.next.id === ",") {
  							if (!state.option.inES5()) warning("W070");
  							advance(",");
  						}
  						if (state.tokens.next.id === "]") {
  							break;
  						}
  						if (b && state.tokens.curr.line !== state.tokens.next.line) {
  							indentation();
  						}
  						this.first.push(expression(10));
  						if (state.tokens.next.id === ",") {
  							comma({ allowTrailing: true });
  							if (state.tokens.next.id === "]" && !state.option.inES5(true)) {
  								warning("W070", state.tokens.curr);
  								break;
  							}
  						} else {
  							break;
  						}
  					}
  					if (b) {
  						indent -= state.option.indent;
  						indentation();
  					}
  					advance("]", this);
  					return this;
  				}, 160);
  
  				function property_name() {
  					var id = optionalidentifier(false, true);
  
  					if (!id) {
  						if (state.tokens.next.id === "(string)") {
  							id = state.tokens.next.value;
  							advance();
  						} else if (state.tokens.next.id === "(number)") {
  							id = state.tokens.next.value.toString();
  							advance();
  						}
  					}
  
  					if (id === "hasOwnProperty") {
  						warning("W001");
  					}
  
  					return id;
  				}
  
  				function functionparams(parsed) {
  					var curr, next;
  					var params = [];
  					var ident;
  					var tokens = [];
  					var t;
  					var pastDefault = false;
  
  					if (parsed) {
  						if (parsed instanceof Array) {
  							for (var i in parsed) {
  								curr = parsed[i];
  								if (_.contains(["{", "["], curr.id)) {
  									for (t in curr.left) {
  										t = tokens[t];
  										if (t.id) {
  											params.push(t.id);
  											addlabel(t.id, "unused", t.token);
  										}
  									}
  								} else if (curr.value === "...") {
  									if (!state.option.inESNext()) {
  										warning("W104", curr, "spread/rest operator");
  									}
  									continue;
  								} else {
  									addlabel(curr.value, "unused", curr);
  								}
  							}
  							return params;
  						} else {
  							if (parsed.identifier === true) {
  								addlabel(parsed.value, "unused", parsed);
  								return [parsed];
  							}
  						}
  					}
  
  					next = state.tokens.next;
  
  					advance("(");
  					nospace();
  
  					if (state.tokens.next.id === ")") {
  						advance(")");
  						return;
  					}
  
  					for (;;) {
  						if (_.contains(["{", "["], state.tokens.next.id)) {
  							tokens = destructuringExpression();
  							for (t in tokens) {
  								t = tokens[t];
  								if (t.id) {
  									params.push(t.id);
  									addlabel(t.id, "unused", t.token);
  								}
  							}
  						} else if (state.tokens.next.value === "...") {
  							if (!state.option.inESNext()) {
  								warning("W104", state.tokens.next, "spread/rest operator");
  							}
  							advance("...");
  							nospace();
  							ident = identifier(true);
  							params.push(ident);
  							addlabel(ident, "unused", state.tokens.curr);
  						} else {
  							ident = identifier(true);
  							params.push(ident);
  							addlabel(ident, "unused", state.tokens.curr);
  						}
  						if (pastDefault) {
  							if (state.tokens.next.id !== "=") {
  								error("E051", state.tokens.current);
  							}
  						}
  						if (state.tokens.next.id === "=") {
  							if (!state.option.inESNext()) {
  								warning("W119", state.tokens.next, "default parameters");
  							}
  							advance("=");
  							pastDefault = true;
  							expression(10);
  						}
  						if (state.tokens.next.id === ",") {
  							comma();
  						} else {
  							advance(")", next);
  							nospace(state.tokens.prev, state.tokens.curr);
  							return params;
  						}
  					}
  				}
  
  				function doFunction(name, statement, generator, fatarrowparams) {
  					var f;
  					var oldOption = state.option;
  					var oldIgnored = state.ignored;
  					var oldScope = scope;
  
  					state.option = Object.create(state.option);
  					state.ignored = Object.create(state.ignored);
  					scope = Object.create(scope);
  
  					funct = {
  						"(name)": name || "\"" + anonname + "\"",
  						"(line)": state.tokens.next.line,
  						"(character)": state.tokens.next.character,
  						"(context)": funct,
  						"(breakage)": 0,
  						"(loopage)": 0,
  						"(metrics)": createMetrics(state.tokens.next),
  						"(scope)": scope,
  						"(statement)": statement,
  						"(tokens)": {},
  						"(blockscope)": funct["(blockscope)"],
  						"(comparray)": funct["(comparray)"]
  					};
  
  					if (generator) {
  						funct["(generator)"] = true;
  					}
  
  					f = funct;
  					state.tokens.curr.funct = funct;
  
  					functions.push(funct);
  
  					if (name) {
  						addlabel(name, "function");
  					}
  
  					funct["(params)"] = functionparams(fatarrowparams);
  
  					funct["(metrics)"].verifyMaxParametersPerFunction(funct["(params)"]);
  
  					block(false, true, true, fatarrowparams ? true : false);
  
  					if (generator && funct["(generator)"] !== "yielded") {
  						error("E047", state.tokens.curr);
  					}
  
  					funct["(metrics)"].verifyMaxStatementsPerFunction();
  					funct["(metrics)"].verifyMaxComplexityPerFunction();
  					funct["(unusedOption)"] = state.option.unused;
  
  					scope = oldScope;
  					state.option = oldOption;
  					state.ignored = oldIgnored;
  					funct["(last)"] = state.tokens.curr.line;
  					funct["(lastcharacter)"] = state.tokens.curr.character;
  					funct = funct["(context)"];
  
  					return f;
  				}
  
  				function createMetrics(functionStartToken) {
  					return {
  						statementCount: 0,
  						nestedBlockDepth: -1,
  						ComplexityCount: 1,
  						verifyMaxStatementsPerFunction: function verifyMaxStatementsPerFunction() {
  							if (state.option.maxstatements && this.statementCount > state.option.maxstatements) {
  								warning("W071", functionStartToken, this.statementCount);
  							}
  						},
  
  						verifyMaxParametersPerFunction: function verifyMaxParametersPerFunction(params) {
  							params = params || [];
  
  							if (state.option.maxparams && params.length > state.option.maxparams) {
  								warning("W072", functionStartToken, params.length);
  							}
  						},
  
  						verifyMaxNestedBlockDepthPerFunction: function verifyMaxNestedBlockDepthPerFunction() {
  							if (state.option.maxdepth && this.nestedBlockDepth > 0 && this.nestedBlockDepth === state.option.maxdepth + 1) {
  								warning("W073", null, this.nestedBlockDepth);
  							}
  						},
  
  						verifyMaxComplexityPerFunction: function verifyMaxComplexityPerFunction() {
  							var max = state.option.maxcomplexity;
  							var cc = this.ComplexityCount;
  							if (max && cc > max) {
  								warning("W074", functionStartToken, cc);
  							}
  						}
  					};
  				}
  
  				function increaseComplexityCount() {
  					funct["(metrics)"].ComplexityCount += 1;
  				}
  
  				function checkCondAssignment(expr) {
  					var id, paren;
  					if (expr) {
  						id = expr.id;
  						paren = expr.paren;
  						if (id === "," && (expr = expr.exprs[expr.exprs.length - 1])) {
  							id = expr.id;
  							paren = paren || expr.paren;
  						}
  					}
  					switch (id) {
  						case "=":
  						case "+=":
  						case "-=":
  						case "*=":
  						case "%=":
  						case "&=":
  						case "|=":
  						case "^=":
  						case "/=":
  							if (!paren && !state.option.boss) {
  								warning("W084");
  							}
  					}
  				}
  
  				(function (x) {
  					x.nud = function (isclassdef) {
  						var b, f, i, p, t, g;
  						var props = {}; // All properties, including accessors
  						var tag = "";
  
  						function saveProperty(name, tkn) {
  							if (props[name] && _.has(props, name)) warning("W075", state.tokens.next, i);else props[name] = {};
  
  							props[name].basic = true;
  							props[name].basictkn = tkn;
  						}
  
  						function saveSetter(name, tkn) {
  							if (props[name] && _.has(props, name)) {
  								if (props[name].basic || props[name].setter) warning("W075", state.tokens.next, i);
  							} else {
  								props[name] = {};
  							}
  
  							props[name].setter = true;
  							props[name].setterToken = tkn;
  						}
  
  						function saveGetter(name) {
  							if (props[name] && _.has(props, name)) {
  								if (props[name].basic || props[name].getter) warning("W075", state.tokens.next, i);
  							} else {
  								props[name] = {};
  							}
  
  							props[name].getter = true;
  							props[name].getterToken = state.tokens.curr;
  						}
  
  						b = state.tokens.curr.line !== state.tokens.next.line;
  						if (b) {
  							indent += state.option.indent;
  							if (state.tokens.next.from === indent + state.option.indent) {
  								indent += state.option.indent;
  							}
  						}
  
  						for (;;) {
  							if (state.tokens.next.id === "}") {
  								break;
  							}
  
  							if (b) {
  								indentation();
  							}
  
  							if (isclassdef && state.tokens.next.value === "static") {
  								advance("static");
  								tag = "static ";
  							}
  
  							if (state.tokens.next.value === "get" && peek().id !== ":") {
  								advance("get");
  
  								if (!state.option.inES5(!isclassdef)) {
  									error("E034");
  								}
  
  								i = property_name();
  								if (!i) {
  									error("E035");
  								}
  								if (isclassdef && i === "constructor") {
  									error("E049", state.tokens.next, "class getter method", i);
  								}
  
  								saveGetter(tag + i);
  								t = state.tokens.next;
  								adjacent(state.tokens.curr, state.tokens.next);
  								f = doFunction();
  								p = f["(params)"];
  
  								if (p) {
  									warning("W076", t, p[0], i);
  								}
  
  								adjacent(state.tokens.curr, state.tokens.next);
  							} else if (state.tokens.next.value === "set" && peek().id !== ":") {
  								advance("set");
  
  								if (!state.option.inES5(!isclassdef)) {
  									error("E034");
  								}
  
  								i = property_name();
  								if (!i) {
  									error("E035");
  								}
  								if (isclassdef && i === "constructor") {
  									error("E049", state.tokens.next, "class setter method", i);
  								}
  
  								saveSetter(tag + i, state.tokens.next);
  								t = state.tokens.next;
  								adjacent(state.tokens.curr, state.tokens.next);
  								f = doFunction();
  								p = f["(params)"];
  
  								if (!p || p.length !== 1) {
  									warning("W077", t, i);
  								}
  							} else {
  								g = false;
  								if (state.tokens.next.value === "*" && state.tokens.next.type === "(punctuator)") {
  									if (!state.option.inESNext()) {
  										warning("W104", state.tokens.next, "generator functions");
  									}
  									advance("*");
  									g = true;
  								}
  								i = property_name();
  								saveProperty(tag + i, state.tokens.next);
  
  								if (typeof i !== "string") {
  									break;
  								}
  
  								if (state.tokens.next.value === "(") {
  									if (!state.option.inESNext()) {
  										warning("W104", state.tokens.curr, "concise methods");
  									}
  									doFunction(i, undefined, g);
  								} else if (!isclassdef) {
  									advance(":");
  									nonadjacent(state.tokens.curr, state.tokens.next);
  									expression(10);
  								}
  							}
  							if (isclassdef && i === "prototype") {
  								error("E049", state.tokens.next, "class method", i);
  							}
  
  							countMember(i);
  							if (isclassdef) {
  								tag = "";
  								continue;
  							}
  							if (state.tokens.next.id === ",") {
  								comma({ allowTrailing: true, property: true });
  								if (state.tokens.next.id === ",") {
  									warning("W070", state.tokens.curr);
  								} else if (state.tokens.next.id === "}" && !state.option.inES5(true)) {
  									warning("W070", state.tokens.curr);
  								}
  							} else {
  								break;
  							}
  						}
  						if (b) {
  							indent -= state.option.indent;
  							indentation();
  						}
  						advance("}", this);
  						if (state.option.inES5()) {
  							for (var name in props) {
  								if (_.has(props, name) && props[name].setter && !props[name].getter) {
  									warning("W078", props[name].setterToken);
  								}
  							}
  						}
  						return this;
  					};
  					x.fud = function () {
  						error("E036", state.tokens.curr);
  					};
  				})(delim("{"));
  
  				function destructuringExpression() {
  					var id, ids;
  					var identifiers = [];
  					if (!state.option.inESNext()) {
  						warning("W104", state.tokens.curr, "destructuring expression");
  					}
  					var nextInnerDE = function nextInnerDE() {
  						var ident;
  						if (_.contains(["[", "{"], state.tokens.next.value)) {
  							ids = destructuringExpression();
  							for (var id in ids) {
  								id = ids[id];
  								identifiers.push({ id: id.id, token: id.token });
  							}
  						} else if (state.tokens.next.value === ",") {
  							identifiers.push({ id: null, token: state.tokens.curr });
  						} else {
  							ident = identifier();
  							if (ident) identifiers.push({ id: ident, token: state.tokens.curr });
  						}
  					};
  					if (state.tokens.next.value === "[") {
  						advance("[");
  						nextInnerDE();
  						while (state.tokens.next.value !== "]") {
  							advance(",");
  							nextInnerDE();
  						}
  						advance("]");
  					} else if (state.tokens.next.value === "{") {
  						advance("{");
  						id = identifier();
  						if (state.tokens.next.value === ":") {
  							advance(":");
  							nextInnerDE();
  						} else {
  							identifiers.push({ id: id, token: state.tokens.curr });
  						}
  						while (state.tokens.next.value !== "}") {
  							advance(",");
  							id = identifier();
  							if (state.tokens.next.value === ":") {
  								advance(":");
  								nextInnerDE();
  							} else {
  								identifiers.push({ id: id, token: state.tokens.curr });
  							}
  						}
  						advance("}");
  					}
  					return identifiers;
  				}
  				function destructuringExpressionMatch(tokens, value) {
  					if (value.first) {
  						_.zip(tokens, value.first).forEach(function (val) {
  							var token = val[0];
  							var value = val[1];
  							if (token && value) {
  								token.first = value;
  							} else if (token && token.first && !value) {
  								warning("W080", token.first, token.first.value);
  							} /* else {
           XXX value is discarded: wouldn't it need a warning ?
           } */
  						});
  					}
  				}
  
  				var conststatement = stmt("const", function (prefix) {
  					var tokens, value;
  					var lone;
  
  					if (!state.option.inESNext()) {
  						warning("W104", state.tokens.curr, "const");
  					}
  
  					this.first = [];
  					for (;;) {
  						var names = [];
  						nonadjacent(state.tokens.curr, state.tokens.next);
  						if (_.contains(["{", "["], state.tokens.next.value)) {
  							tokens = destructuringExpression();
  							lone = false;
  						} else {
  							tokens = [{ id: identifier(), token: state.tokens.curr }];
  							lone = true;
  						}
  						for (var t in tokens) {
  							t = tokens[t];
  							if (funct[t.id] === "const") {
  								warning("E011", null, t.id);
  							}
  							if (funct["(global)"] && predefined[t.id] === false) {
  								warning("W079", t.token, t.id);
  							}
  							if (t.id) {
  								addlabel(t.id, "const");
  								names.push(t.token);
  							}
  						}
  						if (prefix) {
  							break;
  						}
  
  						this.first = this.first.concat(names);
  
  						if (state.tokens.next.id !== "=") {
  							warning("E012", state.tokens.curr, state.tokens.curr.value);
  						}
  
  						if (state.tokens.next.id === "=") {
  							nonadjacent(state.tokens.curr, state.tokens.next);
  							advance("=");
  							nonadjacent(state.tokens.curr, state.tokens.next);
  							if (state.tokens.next.id === "undefined") {
  								warning("W080", state.tokens.prev, state.tokens.prev.value);
  							}
  							if (peek(0).id === "=" && state.tokens.next.identifier) {
  								warning("W120", state.tokens.next, state.tokens.next.value);
  							}
  							value = expression(10);
  							if (lone) {
  								tokens[0].first = value;
  							} else {
  								destructuringExpressionMatch(names, value);
  							}
  						}
  
  						if (state.tokens.next.id !== ",") {
  							break;
  						}
  						comma();
  					}
  					return this;
  				});
  				conststatement.exps = true;
  				var varstatement = stmt("var", function (prefix) {
  					var tokens, lone, value;
  
  					if (funct["(onevar)"] && state.option.onevar) {
  						warning("W081");
  					} else if (!funct["(global)"]) {
  						funct["(onevar)"] = true;
  					}
  
  					this.first = [];
  					for (;;) {
  						var names = [];
  						nonadjacent(state.tokens.curr, state.tokens.next);
  						if (_.contains(["{", "["], state.tokens.next.value)) {
  							tokens = destructuringExpression();
  							lone = false;
  						} else {
  							tokens = [{ id: identifier(), token: state.tokens.curr }];
  							lone = true;
  						}
  						for (var t in tokens) {
  							t = tokens[t];
  							if (state.option.inESNext() && funct[t.id] === "const") {
  								warning("E011", null, t.id);
  							}
  							if (funct["(global)"] && predefined[t.id] === false) {
  								warning("W079", t.token, t.id);
  							}
  							if (t.id) {
  								addlabel(t.id, "unused", t.token);
  								names.push(t.token);
  							}
  						}
  						if (prefix) {
  							break;
  						}
  
  						this.first = this.first.concat(names);
  
  						if (state.tokens.next.id === "=") {
  							nonadjacent(state.tokens.curr, state.tokens.next);
  							advance("=");
  							nonadjacent(state.tokens.curr, state.tokens.next);
  							if (state.tokens.next.id === "undefined") {
  								warning("W080", state.tokens.prev, state.tokens.prev.value);
  							}
  							if (peek(0).id === "=" && state.tokens.next.identifier) {
  								warning("W120", state.tokens.next, state.tokens.next.value);
  							}
  							value = expression(10);
  							if (lone) {
  								tokens[0].first = value;
  							} else {
  								destructuringExpressionMatch(names, value);
  							}
  						}
  
  						if (state.tokens.next.id !== ",") {
  							break;
  						}
  						comma();
  					}
  					return this;
  				});
  				varstatement.exps = true;
  				var letstatement = stmt("let", function (prefix) {
  					var tokens, lone, value, letblock;
  
  					if (!state.option.inESNext()) {
  						warning("W104", state.tokens.curr, "let");
  					}
  
  					if (state.tokens.next.value === "(") {
  						if (!state.option.inMoz(true)) {
  							warning("W118", state.tokens.next, "let block");
  						}
  						advance("(");
  						funct["(blockscope)"].stack();
  						letblock = true;
  					} else if (funct["(nolet)"]) {
  						error("E048", state.tokens.curr);
  					}
  
  					if (funct["(onevar)"] && state.option.onevar) {
  						warning("W081");
  					} else if (!funct["(global)"]) {
  						funct["(onevar)"] = true;
  					}
  
  					this.first = [];
  					for (;;) {
  						var names = [];
  						nonadjacent(state.tokens.curr, state.tokens.next);
  						if (_.contains(["{", "["], state.tokens.next.value)) {
  							tokens = destructuringExpression();
  							lone = false;
  						} else {
  							tokens = [{ id: identifier(), token: state.tokens.curr.value }];
  							lone = true;
  						}
  						for (var t in tokens) {
  							t = tokens[t];
  							if (state.option.inESNext() && funct[t.id] === "const") {
  								warning("E011", null, t.id);
  							}
  							if (funct["(global)"] && predefined[t.id] === false) {
  								warning("W079", t.token, t.id);
  							}
  							if (t.id && !funct["(nolet)"]) {
  								addlabel(t.id, "unused", t.token, true);
  								names.push(t.token);
  							}
  						}
  						if (prefix) {
  							break;
  						}
  
  						this.first = this.first.concat(names);
  
  						if (state.tokens.next.id === "=") {
  							nonadjacent(state.tokens.curr, state.tokens.next);
  							advance("=");
  							nonadjacent(state.tokens.curr, state.tokens.next);
  							if (state.tokens.next.id === "undefined") {
  								warning("W080", state.tokens.prev, state.tokens.prev.value);
  							}
  							if (peek(0).id === "=" && state.tokens.next.identifier) {
  								warning("W120", state.tokens.next, state.tokens.next.value);
  							}
  							value = expression(10);
  							if (lone) {
  								tokens[0].first = value;
  							} else {
  								destructuringExpressionMatch(names, value);
  							}
  						}
  
  						if (state.tokens.next.id !== ",") {
  							break;
  						}
  						comma();
  					}
  					if (letblock) {
  						advance(")");
  						block(true, true);
  						this.block = true;
  						funct["(blockscope)"].unstack();
  					}
  
  					return this;
  				});
  				letstatement.exps = true;
  
  				blockstmt("class", function () {
  					return classdef.call(this, true);
  				});
  
  				function classdef(stmt) {
  					if (!state.option.inESNext()) {
  						warning("W104", state.tokens.curr, "class");
  					}
  					if (stmt) {
  						this.name = identifier();
  						addlabel(this.name, "unused", state.tokens.curr);
  					} else if (state.tokens.next.identifier && state.tokens.next.value !== "extends") {
  						this.name = identifier();
  					}
  					classtail(this);
  					return this;
  				}
  
  				function classtail(c) {
  					var strictness = state.directive["use strict"];
  					if (state.tokens.next.value === "extends") {
  						advance("extends");
  						c.heritage = expression(10);
  					}
  					state.directive["use strict"] = true;
  					advance("{");
  					c.body = state.syntax["{"].nud(true);
  					state.directive["use strict"] = strictness;
  				}
  
  				blockstmt("function", function () {
  					var generator = false;
  					if (state.tokens.next.value === "*") {
  						advance("*");
  						if (state.option.inESNext(true)) {
  							generator = true;
  						} else {
  							warning("W119", state.tokens.curr, "function*");
  						}
  					}
  					if (inblock) {
  						warning("W082", state.tokens.curr);
  					}
  					var i = identifier();
  					if (funct[i] === "const") {
  						warning("E011", null, i);
  					}
  					adjacent(state.tokens.curr, state.tokens.next);
  					addlabel(i, "unction", state.tokens.curr);
  
  					doFunction(i, { statement: true }, generator);
  					if (state.tokens.next.id === "(" && state.tokens.next.line === state.tokens.curr.line) {
  						error("E039");
  					}
  					return this;
  				});
  
  				prefix("function", function () {
  					var generator = false;
  					if (state.tokens.next.value === "*") {
  						if (!state.option.inESNext()) {
  							warning("W119", state.tokens.curr, "function*");
  						}
  						advance("*");
  						generator = true;
  					}
  					var i = optionalidentifier();
  					if (i || state.option.gcl) {
  						adjacent(state.tokens.curr, state.tokens.next);
  					} else {
  						nonadjacent(state.tokens.curr, state.tokens.next);
  					}
  					doFunction(i, undefined, generator);
  					if (!state.option.loopfunc && funct["(loopage)"]) {
  						warning("W083");
  					}
  					return this;
  				});
  
  				blockstmt("if", function () {
  					var t = state.tokens.next;
  					increaseComplexityCount();
  					state.condition = true;
  					advance("(");
  					nonadjacent(this, t);
  					nospace();
  					checkCondAssignment(expression(0));
  					advance(")", t);
  					state.condition = false;
  					nospace(state.tokens.prev, state.tokens.curr);
  					block(true, true);
  					if (state.tokens.next.id === "else") {
  						nonadjacent(state.tokens.curr, state.tokens.next);
  						advance("else");
  						if (state.tokens.next.id === "if" || state.tokens.next.id === "switch") {
  							statement(true);
  						} else {
  							block(true, true);
  						}
  					}
  					return this;
  				});
  
  				blockstmt("try", function () {
  					var b;
  
  					function doCatch() {
  						var oldScope = scope;
  						var e;
  
  						advance("catch");
  						nonadjacent(state.tokens.curr, state.tokens.next);
  						advance("(");
  
  						scope = Object.create(oldScope);
  
  						e = state.tokens.next.value;
  						if (state.tokens.next.type !== "(identifier)") {
  							e = null;
  							warning("E030", state.tokens.next, e);
  						}
  
  						advance();
  
  						funct = {
  							"(name)": "(catch)",
  							"(line)": state.tokens.next.line,
  							"(character)": state.tokens.next.character,
  							"(context)": funct,
  							"(breakage)": funct["(breakage)"],
  							"(loopage)": funct["(loopage)"],
  							"(scope)": scope,
  							"(statement)": false,
  							"(metrics)": createMetrics(state.tokens.next),
  							"(catch)": true,
  							"(tokens)": {},
  							"(blockscope)": funct["(blockscope)"],
  							"(comparray)": funct["(comparray)"]
  						};
  
  						if (e) {
  							addlabel(e, "exception");
  						}
  
  						if (state.tokens.next.value === "if") {
  							if (!state.option.inMoz(true)) {
  								warning("W118", state.tokens.curr, "catch filter");
  							}
  							advance("if");
  							expression(0);
  						}
  
  						advance(")");
  
  						state.tokens.curr.funct = funct;
  						functions.push(funct);
  
  						block(false);
  
  						scope = oldScope;
  
  						funct["(last)"] = state.tokens.curr.line;
  						funct["(lastcharacter)"] = state.tokens.curr.character;
  						funct = funct["(context)"];
  					}
  
  					block(false);
  
  					while (state.tokens.next.id === "catch") {
  						increaseComplexityCount();
  						if (b && !state.option.inMoz(true)) {
  							warning("W118", state.tokens.next, "multiple catch blocks");
  						}
  						doCatch();
  						b = true;
  					}
  
  					if (state.tokens.next.id === "finally") {
  						advance("finally");
  						block(false);
  						return;
  					}
  
  					if (!b) {
  						error("E021", state.tokens.next, "catch", state.tokens.next.value);
  					}
  
  					return this;
  				});
  
  				blockstmt("while", function () {
  					var t = state.tokens.next;
  					funct["(breakage)"] += 1;
  					funct["(loopage)"] += 1;
  					increaseComplexityCount();
  					advance("(");
  					nonadjacent(this, t);
  					nospace();
  					checkCondAssignment(expression(0));
  					advance(")", t);
  					nospace(state.tokens.prev, state.tokens.curr);
  					block(true, true);
  					funct["(breakage)"] -= 1;
  					funct["(loopage)"] -= 1;
  					return this;
  				}).labelled = true;
  
  				blockstmt("with", function () {
  					var t = state.tokens.next;
  					if (state.directive["use strict"]) {
  						error("E010", state.tokens.curr);
  					} else if (!state.option.withstmt) {
  						warning("W085", state.tokens.curr);
  					}
  
  					advance("(");
  					nonadjacent(this, t);
  					nospace();
  					expression(0);
  					advance(")", t);
  					nospace(state.tokens.prev, state.tokens.curr);
  					block(true, true);
  
  					return this;
  				});
  
  				blockstmt("switch", function () {
  					var t = state.tokens.next,
  					    g = false;
  					funct["(breakage)"] += 1;
  					advance("(");
  					nonadjacent(this, t);
  					nospace();
  					checkCondAssignment(expression(0));
  					advance(")", t);
  					nospace(state.tokens.prev, state.tokens.curr);
  					nonadjacent(state.tokens.curr, state.tokens.next);
  					t = state.tokens.next;
  					advance("{");
  					nonadjacent(state.tokens.curr, state.tokens.next);
  					indent += state.option.indent;
  					this.cases = [];
  
  					for (;;) {
  						switch (state.tokens.next.id) {
  							case "case":
  								switch (funct["(verb)"]) {
  									case "yield":
  									case "break":
  									case "case":
  									case "continue":
  									case "return":
  									case "switch":
  									case "throw":
  										break;
  									default:
  										if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) {
  											warning("W086", state.tokens.curr, "case");
  										}
  								}
  								indentation(-state.option.indent);
  								advance("case");
  								this.cases.push(expression(20));
  								increaseComplexityCount();
  								g = true;
  								advance(":");
  								funct["(verb)"] = "case";
  								break;
  							case "default":
  								switch (funct["(verb)"]) {
  									case "yield":
  									case "break":
  									case "continue":
  									case "return":
  									case "throw":
  										break;
  									default:
  										if (this.cases.length) {
  											if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) {
  												warning("W086", state.tokens.curr, "default");
  											}
  										}
  								}
  								indentation(-state.option.indent);
  								advance("default");
  								g = true;
  								advance(":");
  								break;
  							case "}":
  								indent -= state.option.indent;
  								indentation();
  								advance("}", t);
  								funct["(breakage)"] -= 1;
  								funct["(verb)"] = undefined;
  								return;
  							case "(end)":
  								error("E023", state.tokens.next, "}");
  								return;
  							default:
  								if (g) {
  									switch (state.tokens.curr.id) {
  										case ",":
  											error("E040");
  											return;
  										case ":":
  											g = false;
  											statements();
  											break;
  										default:
  											error("E025", state.tokens.curr);
  											return;
  									}
  								} else {
  									if (state.tokens.curr.id === ":") {
  										advance(":");
  										error("E024", state.tokens.curr, ":");
  										statements();
  									} else {
  										error("E021", state.tokens.next, "case", state.tokens.next.value);
  										return;
  									}
  								}
  						}
  					}
  				}).labelled = true;
  
  				stmt("debugger", function () {
  					if (!state.option.debug) {
  						warning("W087");
  					}
  					return this;
  				}).exps = true;
  
  				(function () {
  					var x = stmt("do", function () {
  						funct["(breakage)"] += 1;
  						funct["(loopage)"] += 1;
  						increaseComplexityCount();
  
  						this.first = block(true, true);
  						advance("while");
  						var t = state.tokens.next;
  						nonadjacent(state.tokens.curr, t);
  						advance("(");
  						nospace();
  						checkCondAssignment(expression(0));
  						advance(")", t);
  						nospace(state.tokens.prev, state.tokens.curr);
  						funct["(breakage)"] -= 1;
  						funct["(loopage)"] -= 1;
  						return this;
  					});
  					x.labelled = true;
  					x.exps = true;
  				})();
  
  				blockstmt("for", function () {
  					var s,
  					    t = state.tokens.next;
  					var letscope = false;
  					var foreachtok = null;
  
  					if (t.value === "each") {
  						foreachtok = t;
  						advance("each");
  						if (!state.option.inMoz(true)) {
  							warning("W118", state.tokens.curr, "for each");
  						}
  					}
  
  					funct["(breakage)"] += 1;
  					funct["(loopage)"] += 1;
  					increaseComplexityCount();
  					advance("(");
  					nonadjacent(this, t);
  					nospace();
  					var nextop; // contains the token of the "in" or "of" operator
  					var i = 0;
  					var inof = ["in", "of"];
  					do {
  						nextop = peek(i);
  						++i;
  					} while (!_.contains(inof, nextop.value) && nextop.value !== ";" && nextop.type !== "(end)");
  					if (_.contains(inof, nextop.value)) {
  						if (!state.option.inESNext() && nextop.value === "of") {
  							error("W104", nextop, "for of");
  						}
  						if (state.tokens.next.id === "var") {
  							advance("var");
  							state.syntax["var"].fud.call(state.syntax["var"].fud, true);
  						} else if (state.tokens.next.id === "let") {
  							advance("let");
  							letscope = true;
  							funct["(blockscope)"].stack();
  							state.syntax["let"].fud.call(state.syntax["let"].fud, true);
  						} else {
  							switch (funct[state.tokens.next.value]) {
  								case "unused":
  									funct[state.tokens.next.value] = "var";
  									break;
  								case "var":
  									break;
  								default:
  									if (!funct["(blockscope)"].getlabel(state.tokens.next.value)) warning("W088", state.tokens.next, state.tokens.next.value);
  							}
  							advance();
  						}
  						advance(nextop.value);
  						expression(20);
  						advance(")", t);
  						s = block(true, true);
  						if (state.option.forin && s && (s.length > 1 || _typeof(s[0]) !== "object" || s[0].value !== "if")) {
  							warning("W089", this);
  						}
  						funct["(breakage)"] -= 1;
  						funct["(loopage)"] -= 1;
  					} else {
  						if (foreachtok) {
  							error("E045", foreachtok);
  						}
  						if (state.tokens.next.id !== ";") {
  							if (state.tokens.next.id === "var") {
  								advance("var");
  								state.syntax["var"].fud.call(state.syntax["var"].fud);
  							} else if (state.tokens.next.id === "let") {
  								advance("let");
  								letscope = true;
  								funct["(blockscope)"].stack();
  								state.syntax["let"].fud.call(state.syntax["let"].fud);
  							} else {
  								for (;;) {
  									expression(0, "for");
  									if (state.tokens.next.id !== ",") {
  										break;
  									}
  									comma();
  								}
  							}
  						}
  						nolinebreak(state.tokens.curr);
  						advance(";");
  						if (state.tokens.next.id !== ";") {
  							checkCondAssignment(expression(0));
  						}
  						nolinebreak(state.tokens.curr);
  						advance(";");
  						if (state.tokens.next.id === ";") {
  							error("E021", state.tokens.next, ")", ";");
  						}
  						if (state.tokens.next.id !== ")") {
  							for (;;) {
  								expression(0, "for");
  								if (state.tokens.next.id !== ",") {
  									break;
  								}
  								comma();
  							}
  						}
  						advance(")", t);
  						nospace(state.tokens.prev, state.tokens.curr);
  						block(true, true);
  						funct["(breakage)"] -= 1;
  						funct["(loopage)"] -= 1;
  					}
  					if (letscope) {
  						funct["(blockscope)"].unstack();
  					}
  					return this;
  				}).labelled = true;
  
  				stmt("break", function () {
  					var v = state.tokens.next.value;
  
  					if (funct["(breakage)"] === 0) warning("W052", state.tokens.next, this.value);
  
  					if (!state.option.asi) nolinebreak(this);
  
  					if (state.tokens.next.id !== ";" && !state.tokens.next.reach) {
  						if (state.tokens.curr.line === state.tokens.next.line) {
  							if (funct[v] !== "label") {
  								warning("W090", state.tokens.next, v);
  							} else if (scope[v] !== funct) {
  								warning("W091", state.tokens.next, v);
  							}
  							this.first = state.tokens.next;
  							advance();
  						}
  					}
  					reachable("break");
  					return this;
  				}).exps = true;
  
  				stmt("continue", function () {
  					var v = state.tokens.next.value;
  
  					if (funct["(breakage)"] === 0) warning("W052", state.tokens.next, this.value);
  
  					if (!state.option.asi) nolinebreak(this);
  
  					if (state.tokens.next.id !== ";" && !state.tokens.next.reach) {
  						if (state.tokens.curr.line === state.tokens.next.line) {
  							if (funct[v] !== "label") {
  								warning("W090", state.tokens.next, v);
  							} else if (scope[v] !== funct) {
  								warning("W091", state.tokens.next, v);
  							}
  							this.first = state.tokens.next;
  							advance();
  						}
  					} else if (!funct["(loopage)"]) {
  						warning("W052", state.tokens.next, this.value);
  					}
  					reachable("continue");
  					return this;
  				}).exps = true;
  
  				stmt("return", function () {
  					if (this.line === state.tokens.next.line) {
  						if (state.tokens.next.id === "(regexp)") warning("W092");
  
  						if (state.tokens.next.id !== ";" && !state.tokens.next.reach) {
  							nonadjacent(state.tokens.curr, state.tokens.next);
  							this.first = expression(0);
  
  							if (this.first && this.first.type === "(punctuator)" && this.first.value === "=" && !state.option.boss) {
  								warningAt("W093", this.first.line, this.first.character);
  							}
  						}
  					} else {
  						if (state.tokens.next.type === "(punctuator)" && ["[", "{", "+", "-"].indexOf(state.tokens.next.value) > -1) {
  							nolinebreak(this); // always warn (Line breaking error)
  						}
  					}
  					reachable("return");
  					return this;
  				}).exps = true;
  
  				(function (x) {
  					x.exps = true;
  					x.lbp = 25;
  				})(prefix("yield", function () {
  					var prev = state.tokens.prev;
  					if (state.option.inESNext(true) && !funct["(generator)"]) {
  						error("E046", state.tokens.curr, "yield");
  					} else if (!state.option.inESNext()) {
  						warning("W104", state.tokens.curr, "yield");
  					}
  					funct["(generator)"] = "yielded";
  					if (this.line === state.tokens.next.line || !state.option.inMoz(true)) {
  						if (state.tokens.next.id === "(regexp)") warning("W092");
  
  						if (state.tokens.next.id !== ";" && !state.tokens.next.reach && state.tokens.next.nud) {
  							nobreaknonadjacent(state.tokens.curr, state.tokens.next);
  							this.first = expression(10);
  
  							if (this.first.type === "(punctuator)" && this.first.value === "=" && !state.option.boss) {
  								warningAt("W093", this.first.line, this.first.character);
  							}
  						}
  
  						if (state.option.inMoz(true) && state.tokens.next.id !== ")" && (prev.lbp > 30 || !prev.assign && !isEndOfExpr() || prev.id === "yield")) {
  							error("E050", this);
  						}
  					} else if (!state.option.asi) {
  						nolinebreak(this); // always warn (Line breaking error)
  					}
  					return this;
  				}));
  
  				stmt("throw", function () {
  					nolinebreak(this);
  					nonadjacent(state.tokens.curr, state.tokens.next);
  					this.first = expression(20);
  					reachable("throw");
  					return this;
  				}).exps = true;
  
  				stmt("import", function () {
  					if (!state.option.inESNext()) {
  						warning("W119", state.tokens.curr, "import");
  					}
  
  					if (state.tokens.next.identifier) {
  						this.name = identifier();
  						addlabel(this.name, "unused", state.tokens.curr);
  					} else {
  						advance("{");
  						for (;;) {
  							var importName;
  							if (state.tokens.next.type === "default") {
  								importName = "default";
  								advance("default");
  							} else {
  								importName = identifier();
  							}
  							if (state.tokens.next.value === "as") {
  								advance("as");
  								importName = identifier();
  							}
  							addlabel(importName, "unused", state.tokens.curr);
  
  							if (state.tokens.next.value === ",") {
  								advance(",");
  							} else if (state.tokens.next.value === "}") {
  								advance("}");
  								break;
  							} else {
  								error("E024", state.tokens.next, state.tokens.next.value);
  								break;
  							}
  						}
  					}
  
  					advance("from");
  					advance("(string)");
  					return this;
  				}).exps = true;
  
  				stmt("export", function () {
  					if (!state.option.inESNext()) {
  						warning("W119", state.tokens.curr, "export");
  					}
  
  					if (state.tokens.next.type === "default") {
  						advance("default");
  						if (state.tokens.next.id === "function" || state.tokens.next.id === "class") {
  							this.block = true;
  						}
  						this.exportee = expression(10);
  
  						return this;
  					}
  
  					if (state.tokens.next.value === "{") {
  						advance("{");
  						for (;;) {
  							identifier();
  
  							if (state.tokens.next.value === ",") {
  								advance(",");
  							} else if (state.tokens.next.value === "}") {
  								advance("}");
  								break;
  							} else {
  								error("E024", state.tokens.next, state.tokens.next.value);
  								break;
  							}
  						}
  						return this;
  					}
  
  					if (state.tokens.next.id === "var") {
  						advance("var");
  						state.syntax["var"].fud.call(state.syntax["var"].fud);
  					} else if (state.tokens.next.id === "let") {
  						advance("let");
  						state.syntax["let"].fud.call(state.syntax["let"].fud);
  					} else if (state.tokens.next.id === "const") {
  						advance("const");
  						state.syntax["const"].fud.call(state.syntax["const"].fud);
  					} else if (state.tokens.next.id === "function") {
  						this.block = true;
  						advance("function");
  						state.syntax["function"].fud();
  					} else if (state.tokens.next.id === "class") {
  						this.block = true;
  						advance("class");
  						state.syntax["class"].fud();
  					} else {
  						error("E024", state.tokens.next, state.tokens.next.value);
  					}
  
  					return this;
  				}).exps = true;
  
  				FutureReservedWord("abstract");
  				FutureReservedWord("boolean");
  				FutureReservedWord("byte");
  				FutureReservedWord("char");
  				FutureReservedWord("class", { es5: true, nud: classdef });
  				FutureReservedWord("double");
  				FutureReservedWord("enum", { es5: true });
  				FutureReservedWord("export", { es5: true });
  				FutureReservedWord("extends", { es5: true });
  				FutureReservedWord("final");
  				FutureReservedWord("float");
  				FutureReservedWord("goto");
  				FutureReservedWord("implements", { es5: true, strictOnly: true });
  				FutureReservedWord("import", { es5: true });
  				FutureReservedWord("int");
  				FutureReservedWord("interface", { es5: true, strictOnly: true });
  				FutureReservedWord("long");
  				FutureReservedWord("native");
  				FutureReservedWord("package", { es5: true, strictOnly: true });
  				FutureReservedWord("private", { es5: true, strictOnly: true });
  				FutureReservedWord("protected", { es5: true, strictOnly: true });
  				FutureReservedWord("public", { es5: true, strictOnly: true });
  				FutureReservedWord("short");
  				FutureReservedWord("static", { es5: true, strictOnly: true });
  				FutureReservedWord("super", { es5: true });
  				FutureReservedWord("synchronized");
  				FutureReservedWord("throws");
  				FutureReservedWord("transient");
  				FutureReservedWord("volatile");
  
  				var lookupBlockType = function lookupBlockType() {
  					var pn, pn1;
  					var i = 0;
  					var bracketStack = 0;
  					var ret = {};
  					if (_.contains(["[", "{"], state.tokens.curr.value)) bracketStack += 1;
  					if (_.contains(["[", "{"], state.tokens.next.value)) bracketStack += 1;
  					if (_.contains(["]", "}"], state.tokens.next.value)) bracketStack -= 1;
  					do {
  						pn = peek(i);
  						pn1 = peek(i + 1);
  						i = i + 1;
  						if (_.contains(["[", "{"], pn.value)) {
  							bracketStack += 1;
  						} else if (_.contains(["]", "}"], pn.value)) {
  							bracketStack -= 1;
  						}
  						if (pn.identifier && pn.value === "for" && bracketStack === 1) {
  							ret.isCompArray = true;
  							ret.notJson = true;
  							break;
  						}
  						if (_.contains(["}", "]"], pn.value) && pn1.value === "=") {
  							ret.isDestAssign = true;
  							ret.notJson = true;
  							break;
  						}
  						if (pn.value === ";") {
  							ret.isBlock = true;
  							ret.notJson = true;
  						}
  					} while (bracketStack > 0 && pn.id !== "(end)" && i < 15);
  					return ret;
  				};
  				function destructuringAssignOrJsonValue() {
  
  					var block = lookupBlockType();
  					if (block.notJson) {
  						if (!state.option.inESNext() && block.isDestAssign) {
  							warning("W104", state.tokens.curr, "destructuring assignment");
  						}
  						statements();
  					} else {
  						state.option.laxbreak = true;
  						state.jsonMode = true;
  						jsonValue();
  					}
  				}
  
  				var arrayComprehension = function arrayComprehension() {
  					var CompArray = function CompArray() {
  						this.mode = "use";
  						this.variables = [];
  					};
  					var _carrays = [];
  					var _current;
  					function declare(v) {
  						var l = _current.variables.filter(function (elt) {
  							if (elt.value === v) {
  								elt.undef = false;
  								return v;
  							}
  						}).length;
  						return l !== 0;
  					}
  					function use(v) {
  						var l = _current.variables.filter(function (elt) {
  							if (elt.value === v && !elt.undef) {
  								if (elt.unused === true) {
  									elt.unused = false;
  								}
  								return v;
  							}
  						}).length;
  						return l === 0;
  					}
  					return { stack: function stack() {
  							_current = new CompArray();
  							_carrays.push(_current);
  						},
  						unstack: function unstack() {
  							_current.variables.filter(function (v) {
  								if (v.unused) warning("W098", v.token, v.value);
  								if (v.undef) isundef(v.funct, "W117", v.token, v.value);
  							});
  							_carrays.splice(_carrays[_carrays.length - 1], 1);
  							_current = _carrays[_carrays.length - 1];
  						},
  						setState: function setState(s) {
  							if (_.contains(["use", "define", "filter"], s)) _current.mode = s;
  						},
  						check: function check(v) {
  							if (_current && _current.mode === "use") {
  								_current.variables.push({ funct: funct,
  									token: state.tokens.curr,
  									value: v,
  									undef: true,
  									unused: false });
  								return true;
  							} else if (_current && _current.mode === "define") {
  								if (!declare(v)) {
  									_current.variables.push({ funct: funct,
  										token: state.tokens.curr,
  										value: v,
  										undef: false,
  										unused: true });
  								}
  								return true;
  							} else if (_current && _current.mode === "filter") {
  								if (use(v)) {
  									isundef(funct, "W117", state.tokens.curr, v);
  								}
  								return true;
  							}
  							return false;
  						}
  					};
  				};
  
  				function jsonValue() {
  
  					function jsonObject() {
  						var o = {},
  						    t = state.tokens.next;
  						advance("{");
  						if (state.tokens.next.id !== "}") {
  							for (;;) {
  								if (state.tokens.next.id === "(end)") {
  									error("E026", state.tokens.next, t.line);
  								} else if (state.tokens.next.id === "}") {
  									warning("W094", state.tokens.curr);
  									break;
  								} else if (state.tokens.next.id === ",") {
  									error("E028", state.tokens.next);
  								} else if (state.tokens.next.id !== "(string)") {
  									warning("W095", state.tokens.next, state.tokens.next.value);
  								}
  								if (o[state.tokens.next.value] === true) {
  									warning("W075", state.tokens.next, state.tokens.next.value);
  								} else if (state.tokens.next.value === "__proto__" && !state.option.proto || state.tokens.next.value === "__iterator__" && !state.option.iterator) {
  									warning("W096", state.tokens.next, state.tokens.next.value);
  								} else {
  									o[state.tokens.next.value] = true;
  								}
  								advance();
  								advance(":");
  								jsonValue();
  								if (state.tokens.next.id !== ",") {
  									break;
  								}
  								advance(",");
  							}
  						}
  						advance("}");
  					}
  
  					function jsonArray() {
  						var t = state.tokens.next;
  						advance("[");
  						if (state.tokens.next.id !== "]") {
  							for (;;) {
  								if (state.tokens.next.id === "(end)") {
  									error("E027", state.tokens.next, t.line);
  								} else if (state.tokens.next.id === "]") {
  									warning("W094", state.tokens.curr);
  									break;
  								} else if (state.tokens.next.id === ",") {
  									error("E028", state.tokens.next);
  								}
  								jsonValue();
  								if (state.tokens.next.id !== ",") {
  									break;
  								}
  								advance(",");
  							}
  						}
  						advance("]");
  					}
  
  					switch (state.tokens.next.id) {
  						case "{":
  							jsonObject();
  							break;
  						case "[":
  							jsonArray();
  							break;
  						case "true":
  						case "false":
  						case "null":
  						case "(number)":
  						case "(string)":
  							advance();
  							break;
  						case "-":
  							advance("-");
  							if (state.tokens.curr.character !== state.tokens.next.from) {
  								warning("W011", state.tokens.curr);
  							}
  							adjacent(state.tokens.curr, state.tokens.next);
  							advance("(number)");
  							break;
  						default:
  							error("E003", state.tokens.next);
  					}
  				}
  
  				var blockScope = function blockScope() {
  					var _current = {};
  					var _variables = [_current];
  
  					function _checkBlockLabels() {
  						for (var t in _current) {
  							if (_current[t]["(type)"] === "unused") {
  								if (state.option.unused) {
  									var tkn = _current[t]["(token)"];
  									var line = tkn.line;
  									var chr = tkn.character;
  									warningAt("W098", line, chr, t);
  								}
  							}
  						}
  					}
  
  					return {
  						stack: function stack() {
  							_current = {};
  							_variables.push(_current);
  						},
  
  						unstack: function unstack() {
  							_checkBlockLabels();
  							_variables.splice(_variables.length - 1, 1);
  							_current = _.last(_variables);
  						},
  
  						getlabel: function getlabel(l) {
  							for (var i = _variables.length - 1; i >= 0; --i) {
  								if (_.has(_variables[i], l)) {
  									return _variables[i];
  								}
  							}
  						},
  
  						current: {
  							has: function has(t) {
  								return _.has(_current, t);
  							},
  							add: function add(t, type, tok) {
  								_current[t] = { "(type)": type,
  									"(token)": tok };
  							}
  						}
  					};
  				};
  				var itself = function itself(s, o, g) {
  					var i, k, x;
  					var optionKeys;
  					var newOptionObj = {};
  					var newIgnoredObj = {};
  
  					state.reset();
  
  					if (o && o.scope) {
  						JSHINT.scope = o.scope;
  					} else {
  						JSHINT.errors = [];
  						JSHINT.undefs = [];
  						JSHINT.internals = [];
  						JSHINT.blacklist = {};
  						JSHINT.scope = "(main)";
  					}
  
  					predefined = Object.create(null);
  					combine(predefined, vars.ecmaIdentifiers);
  					combine(predefined, vars.reservedVars);
  
  					combine(predefined, g || {});
  
  					declared = Object.create(null);
  					exported = Object.create(null);
  
  					function each(obj, cb) {
  						if (!obj) return;
  
  						if (!Array.isArray(obj) && (typeof obj === "undefined" ? "undefined" : _typeof(obj)) === "object") obj = Object.keys(obj);
  
  						obj.forEach(cb);
  					}
  
  					if (o) {
  						each(o.predef || null, function (item) {
  							var slice, prop;
  
  							if (item[0] === "-") {
  								slice = item.slice(1);
  								JSHINT.blacklist[slice] = slice;
  							} else {
  								prop = Object.getOwnPropertyDescriptor(o.predef, item);
  								predefined[item] = prop ? prop.value : false;
  							}
  						});
  
  						each(o.exported || null, function (item) {
  							exported[item] = true;
  						});
  
  						delete o.predef;
  						delete o.exported;
  
  						optionKeys = Object.keys(o);
  						for (x = 0; x < optionKeys.length; x++) {
  							if (/^-W\d{3}$/g.test(optionKeys[x])) {
  								newIgnoredObj[optionKeys[x].slice(1)] = true;
  							} else {
  								newOptionObj[optionKeys[x]] = o[optionKeys[x]];
  
  								if (optionKeys[x] === "newcap" && o[optionKeys[x]] === false) newOptionObj["(explicitNewcap)"] = true;
  
  								if (optionKeys[x] === "indent") newOptionObj["(explicitIndent)"] = o[optionKeys[x]] === false ? false : true;
  							}
  						}
  					}
  
  					state.option = newOptionObj;
  					state.ignored = newIgnoredObj;
  
  					state.option.indent = state.option.indent || 4;
  					state.option.maxerr = state.option.maxerr || 50;
  
  					indent = 1;
  					global = Object.create(predefined);
  					scope = global;
  					funct = {
  						"(global)": true,
  						"(name)": "(global)",
  						"(scope)": scope,
  						"(breakage)": 0,
  						"(loopage)": 0,
  						"(tokens)": {},
  						"(metrics)": createMetrics(state.tokens.next),
  						"(blockscope)": blockScope(),
  						"(comparray)": arrayComprehension()
  					};
  					functions = [funct];
  					urls = [];
  					stack = null;
  					member = {};
  					membersOnly = null;
  					implied = {};
  					inblock = false;
  					lookahead = [];
  					warnings = 0;
  					unuseds = [];
  
  					if (!isString(s) && !Array.isArray(s)) {
  						errorAt("E004", 0);
  						return false;
  					}
  
  					api = {
  						get isJSON() {
  							return state.jsonMode;
  						},
  
  						getOption: function getOption(name) {
  							return state.option[name] || null;
  						},
  
  						getCache: function getCache(name) {
  							return state.cache[name];
  						},
  
  						setCache: function setCache(name, value) {
  							state.cache[name] = value;
  						},
  
  						warn: function warn(code, data) {
  							warningAt.apply(null, [code, data.line, data.char].concat(data.data));
  						},
  
  						on: function on(names, listener) {
  							names.split(" ").forEach(function (name) {
  								emitter.on(name, listener);
  							}.bind(this));
  						}
  					};
  
  					emitter.removeAllListeners();
  					(extraModules || []).forEach(function (func) {
  						func(api);
  					});
  
  					state.tokens.prev = state.tokens.curr = state.tokens.next = state.syntax["(begin)"];
  
  					lex = new Lexer(s);
  
  					lex.on("warning", function (ev) {
  						warningAt.apply(null, [ev.code, ev.line, ev.character].concat(ev.data));
  					});
  
  					lex.on("error", function (ev) {
  						errorAt.apply(null, [ev.code, ev.line, ev.character].concat(ev.data));
  					});
  
  					lex.on("fatal", function (ev) {
  						quit("E041", ev.line, ev.from);
  					});
  
  					lex.on("Identifier", function (ev) {
  						emitter.emit("Identifier", ev);
  					});
  
  					lex.on("String", function (ev) {
  						emitter.emit("String", ev);
  					});
  
  					lex.on("Number", function (ev) {
  						emitter.emit("Number", ev);
  					});
  
  					lex.start();
  					for (var name in o) {
  						if (_.has(o, name)) {
  							checkOption(name, state.tokens.curr);
  						}
  					}
  
  					assume();
  					combine(predefined, g || {});
  					comma.first = true;
  
  					try {
  						advance();
  						switch (state.tokens.next.id) {
  							case "{":
  							case "[":
  								destructuringAssignOrJsonValue();
  								break;
  							default:
  								directives();
  
  								if (state.directive["use strict"]) {
  									if (!state.option.globalstrict && !state.option.node) {
  										warning("W097", state.tokens.prev);
  									}
  								}
  
  								statements();
  						}
  						advance(state.tokens.next && state.tokens.next.value !== "." ? "(end)" : undefined);
  						funct["(blockscope)"].unstack();
  
  						var markDefined = function markDefined(name, context) {
  							do {
  								if (typeof context[name] === "string") {
  
  									if (context[name] === "unused") context[name] = "var";else if (context[name] === "unction") context[name] = "closure";
  
  									return true;
  								}
  
  								context = context["(context)"];
  							} while (context);
  
  							return false;
  						};
  
  						var clearImplied = function clearImplied(name, line) {
  							if (!implied[name]) return;
  
  							var newImplied = [];
  							for (var i = 0; i < implied[name].length; i += 1) {
  								if (implied[name][i] !== line) newImplied.push(implied[name][i]);
  							}
  
  							if (newImplied.length === 0) delete implied[name];else implied[name] = newImplied;
  						};
  
  						var warnUnused = function warnUnused(name, tkn, type, unused_opt) {
  							var line = tkn.line;
  							var chr = tkn.character;
  
  							if (unused_opt === undefined) {
  								unused_opt = state.option.unused;
  							}
  
  							if (unused_opt === true) {
  								unused_opt = "last-param";
  							}
  
  							var warnable_types = {
  								"vars": ["var"],
  								"last-param": ["var", "param"],
  								"strict": ["var", "param", "last-param"]
  							};
  
  							if (unused_opt) {
  								if (warnable_types[unused_opt] && warnable_types[unused_opt].indexOf(type) !== -1) {
  									warningAt("W098", line, chr, name);
  								}
  							}
  
  							unuseds.push({
  								name: name,
  								line: line,
  								character: chr
  							});
  						};
  
  						var checkUnused = function checkUnused(func, key) {
  							var type = func[key];
  							var tkn = func["(tokens)"][key];
  
  							if (key.charAt(0) === "(") return;
  
  							if (type !== "unused" && type !== "unction") return;
  							if (func["(params)"] && func["(params)"].indexOf(key) !== -1) return;
  							if (func["(global)"] && _.has(exported, key)) {
  								return;
  							}
  
  							warnUnused(key, tkn, "var");
  						};
  						for (i = 0; i < JSHINT.undefs.length; i += 1) {
  							k = JSHINT.undefs[i].slice(0);
  
  							if (markDefined(k[2].value, k[0])) {
  								clearImplied(k[2].value, k[2].line);
  							} else if (state.option.undef) {
  								warning.apply(warning, k.slice(1));
  							}
  						}
  
  						functions.forEach(function (func) {
  							if (func["(unusedOption)"] === false) {
  								return;
  							}
  
  							for (var key in func) {
  								if (_.has(func, key)) {
  									checkUnused(func, key);
  								}
  							}
  
  							if (!func["(params)"]) return;
  
  							var params = func["(params)"].slice();
  							var param = params.pop();
  							var type, unused_opt;
  
  							while (param) {
  								type = func[param];
  								unused_opt = func["(unusedOption)"] || state.option.unused;
  								unused_opt = unused_opt === true ? "last-param" : unused_opt;
  
  								if (param === "undefined") return;
  
  								if (type === "unused" || type === "unction") {
  									warnUnused(param, func["(tokens)"][param], "param", func["(unusedOption)"]);
  								} else if (unused_opt === "last-param") {
  									return;
  								}
  
  								param = params.pop();
  							}
  						});
  
  						for (var key in declared) {
  							if (_.has(declared, key) && !_.has(global, key)) {
  								warnUnused(key, declared[key], "var");
  							}
  						}
  					} catch (err) {
  						if (err && err.name === "JSHintError") {
  							var nt = state.tokens.next || {};
  							JSHINT.errors.push({
  								scope: "(main)",
  								raw: err.raw,
  								code: err.code,
  								reason: err.message,
  								line: err.line || nt.line,
  								character: err.character || nt.from
  							}, null);
  						} else {
  							throw err;
  						}
  					}
  
  					if (JSHINT.scope === "(main)") {
  						o = o || {};
  
  						for (i = 0; i < JSHINT.internals.length; i += 1) {
  							k = JSHINT.internals[i];
  							o.scope = k.elem;
  							itself(k.value, o, g);
  						}
  					}
  
  					return JSHINT.errors.length === 0;
  				};
  				itself.addModule = function (func) {
  					extraModules.push(func);
  				};
  
  				itself.addModule(style.register);
  				itself.data = function () {
  					var data = {
  						functions: [],
  						options: state.option
  					};
  					var implieds = [];
  					var members = [];
  					var fu, f, i, j, n, globals;
  
  					if (itself.errors.length) {
  						data.errors = itself.errors;
  					}
  
  					if (state.jsonMode) {
  						data.json = true;
  					}
  
  					for (n in implied) {
  						if (_.has(implied, n)) {
  							implieds.push({
  								name: n,
  								line: implied[n]
  							});
  						}
  					}
  
  					if (implieds.length > 0) {
  						data.implieds = implieds;
  					}
  
  					if (urls.length > 0) {
  						data.urls = urls;
  					}
  
  					globals = Object.keys(scope);
  					if (globals.length > 0) {
  						data.globals = globals;
  					}
  
  					for (i = 1; i < functions.length; i += 1) {
  						f = functions[i];
  						fu = {};
  
  						for (j = 0; j < functionicity.length; j += 1) {
  							fu[functionicity[j]] = [];
  						}
  
  						for (j = 0; j < functionicity.length; j += 1) {
  							if (fu[functionicity[j]].length === 0) {
  								delete fu[functionicity[j]];
  							}
  						}
  
  						fu.name = f["(name)"];
  						fu.param = f["(params)"];
  						fu.line = f["(line)"];
  						fu.character = f["(character)"];
  						fu.last = f["(last)"];
  						fu.lastcharacter = f["(lastcharacter)"];
  						data.functions.push(fu);
  					}
  
  					if (unuseds.length > 0) {
  						data.unused = unuseds;
  					}
  
  					members = [];
  					for (n in member) {
  						if (typeof member[n] === "number") {
  							data.member = member;
  							break;
  						}
  					}
  
  					return data;
  				};
  
  				itself.jshint = itself;
  
  				return itself;
  			}();
  			if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object" && exports) {
  				exports.JSHINT = JSHINT;
  			}
  		}, { "../shared/messages.js": 2, "../shared/vars.js": 3, "./lex.js": 5, "./reg.js": 6, "./state.js": 7, "./style.js": 8, "console-browserify": 9, "events": 10, "underscore": 1 }],
  		5: [function (req, module, exports) {
  
  			var _ = req("underscore");
  			var events = req("events");
  			var reg = req("./reg.js");
  			var state = req("./state.js").state;
  
  			var Token = {
  				Identifier: 1,
  				Punctuator: 2,
  				NumericLiteral: 3,
  				StringLiteral: 4,
  				Comment: 5,
  				Keyword: 6,
  				NullLiteral: 7,
  				BooleanLiteral: 8,
  				RegExp: 9
  			};
  
  			var unicodeLetterTable = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 880, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1568, 1610, 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2423, 2425, 2431, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3133, 3160, 3161, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3389, 3406, 3406, 3424, 3425, 3450, 3455, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805, 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4304, 4346, 4348, 4348, 4352, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6263, 6272, 6312, 6314, 6314, 6320, 6389, 6400, 6428, 6480, 6509, 6512, 6516, 6528, 6571, 6593, 6599, 6656, 6678, 6688, 6740, 6823, 6823, 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7104, 7141, 7168, 7203, 7245, 7247, 7258, 7293, 7401, 7404, 7406, 7409, 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11502, 11520, 11557, 11568, 11621, 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11823, 11823, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 13312, 19893, 19893, 19968, 19968, 40907, 40907, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, 42560, 42606, 42623, 42647, 42656, 42735, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42897, 42912, 42921, 43002, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, 43471, 43471, 43520, 43560, 43584, 43586, 43588, 43595, 43616, 43638, 43642, 43642, 43648, 43695, 43697, 43697, 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, 43739, 43741, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44002, 44032, 44032, 55203, 55203, 55216, 55238, 55243, 55291, 63744, 64045, 64048, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, 65856, 65908, 66176, 66204, 66208, 66256, 66304, 66334, 66352, 66378, 66432, 66461, 66464, 66499, 66504, 66511, 66513, 66517, 66560, 66717, 67584, 67589, 67592, 67592, 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, 67840, 67861, 67872, 67897, 68096, 68096, 68112, 68115, 68117, 68119, 68121, 68147, 68192, 68220, 68352, 68405, 68416, 68437, 68448, 68466, 68608, 68680, 69635, 69687, 69763, 69807, 73728, 74606, 74752, 74850, 77824, 78894, 92160, 92728, 110592, 110593, 119808, 119892, 119894, 119964, 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, 131072, 131072, 173782, 173782, 173824, 173824, 177972, 177972, 177984, 177984, 178205, 178205, 194560, 195101];
  
  			var identifierStartTable = [];
  
  			for (var i = 0; i < 128; i++) {
  				identifierStartTable[i] = i === 36 || // $
  				i >= 65 && i <= 90 || // A-Z
  				i === 95 || // _
  				i >= 97 && i <= 122; // a-z
  			}
  
  			var identifierPartTable = [];
  
  			for (var i = 0; i < 128; i++) {
  				identifierPartTable[i] = identifierStartTable[i] || // $, _, A-Z, a-z
  				i >= 48 && i <= 57; // 0-9
  			}
  
  			function asyncTrigger() {
  				var _checks = [];
  
  				return {
  					push: function push(fn) {
  						_checks.push(fn);
  					},
  
  					check: function check() {
  						for (var check = 0; check < _checks.length; ++check) {
  							_checks[check]();
  						}
  
  						_checks.splice(0, _checks.length);
  					}
  				};
  			}
  			function Lexer(source) {
  				var lines = source;
  
  				if (typeof lines === "string") {
  					lines = lines.replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n");
  				}
  
  				if (lines[0] && lines[0].substr(0, 2) === "#!") {
  					lines[0] = "";
  				}
  
  				this.emitter = new events.EventEmitter();
  				this.source = source;
  				this.setLines(lines);
  				this.prereg = true;
  
  				this.line = 0;
  				this.char = 1;
  				this.from = 1;
  				this.input = "";
  
  				for (var i = 0; i < state.option.indent; i += 1) {
  					state.tab += " ";
  				}
  			}
  
  			Lexer.prototype = {
  				_lines: [],
  
  				getLines: function getLines() {
  					this._lines = state.lines;
  					return this._lines;
  				},
  
  				setLines: function setLines(val) {
  					this._lines = val;
  					state.lines = this._lines;
  				},
  				peek: function peek(i) {
  					return this.input.charAt(i || 0);
  				},
  				skip: function skip(i) {
  					i = i || 1;
  					this.char += i;
  					this.input = this.input.slice(i);
  				},
  				on: function on(names, listener) {
  					names.split(" ").forEach(function (name) {
  						this.emitter.on(name, listener);
  					}.bind(this));
  				},
  				trigger: function trigger() {
  					this.emitter.emit.apply(this.emitter, Array.prototype.slice.call(arguments));
  				},
  				triggerAsync: function triggerAsync(type, args, checks, fn) {
  					checks.push(function () {
  						if (fn()) {
  							this.trigger(type, args);
  						}
  					}.bind(this));
  				},
  				scanPunctuator: function scanPunctuator() {
  					var ch1 = this.peek();
  					var ch2, ch3, ch4;
  
  					switch (ch1) {
  						case ".":
  							if (/^[0-9]$/.test(this.peek(1))) {
  								return null;
  							}
  							if (this.peek(1) === "." && this.peek(2) === ".") {
  								return {
  									type: Token.Punctuator,
  									value: "..."
  								};
  							}
  						case "(":
  						case ")":
  						case ";":
  						case ",":
  						case "{":
  						case "}":
  						case "[":
  						case "]":
  						case ":":
  						case "~":
  						case "?":
  							return {
  								type: Token.Punctuator,
  								value: ch1
  							};
  						case "#":
  							return {
  								type: Token.Punctuator,
  								value: ch1
  							};
  						case "":
  							return null;
  					}
  
  					ch2 = this.peek(1);
  					ch3 = this.peek(2);
  					ch4 = this.peek(3);
  
  					if (ch1 === ">" && ch2 === ">" && ch3 === ">" && ch4 === "=") {
  						return {
  							type: Token.Punctuator,
  							value: ">>>="
  						};
  					}
  
  					if (ch1 === "=" && ch2 === "=" && ch3 === "=") {
  						return {
  							type: Token.Punctuator,
  							value: "==="
  						};
  					}
  
  					if (ch1 === "!" && ch2 === "=" && ch3 === "=") {
  						return {
  							type: Token.Punctuator,
  							value: "!=="
  						};
  					}
  
  					if (ch1 === ">" && ch2 === ">" && ch3 === ">") {
  						return {
  							type: Token.Punctuator,
  							value: ">>>"
  						};
  					}
  
  					if (ch1 === "<" && ch2 === "<" && ch3 === "=") {
  						return {
  							type: Token.Punctuator,
  							value: "<<="
  						};
  					}
  
  					if (ch1 === ">" && ch2 === ">" && ch3 === "=") {
  						return {
  							type: Token.Punctuator,
  							value: ">>="
  						};
  					}
  					if (ch1 === "=" && ch2 === ">") {
  						return {
  							type: Token.Punctuator,
  							value: ch1 + ch2
  						};
  					}
  					if (ch1 === ch2 && "+-<>&|".indexOf(ch1) >= 0) {
  						return {
  							type: Token.Punctuator,
  							value: ch1 + ch2
  						};
  					}
  
  					if ("<>=!+-*%&|^".indexOf(ch1) >= 0) {
  						if (ch2 === "=") {
  							return {
  								type: Token.Punctuator,
  								value: ch1 + ch2
  							};
  						}
  
  						return {
  							type: Token.Punctuator,
  							value: ch1
  						};
  					}
  
  					if (ch1 === "/") {
  						if (ch2 === "=" && /\/=(?!(\S*\/[gim]?))/.test(this.input)) {
  							return {
  								type: Token.Punctuator,
  								value: "/="
  							};
  						}
  
  						return {
  							type: Token.Punctuator,
  							value: "/"
  						};
  					}
  
  					return null;
  				},
  				scanComments: function scanComments() {
  					var ch1 = this.peek();
  					var ch2 = this.peek(1);
  					var rest = this.input.substr(2);
  					var startLine = this.line;
  					var startChar = this.char;
  
  					function commentToken(label, body, opt) {
  						var special = ["jshint", "jslint", "members", "member", "globals", "global", "exported"];
  						var isSpecial = false;
  						var value = label + body;
  						var commentType = "plain";
  						opt = opt || {};
  
  						if (opt.isMultiline) {
  							value += "*/";
  						}
  
  						special.forEach(function (str) {
  							if (isSpecial) {
  								return;
  							}
  							if (label === "//" && str !== "jshint") {
  								return;
  							}
  
  							if (body.substr(0, str.length) === str) {
  								isSpecial = true;
  								label = label + str;
  								body = body.substr(str.length);
  							}
  
  							if (!isSpecial && body.charAt(0) === " " && body.substr(1, str.length) === str) {
  								isSpecial = true;
  								label = label + " " + str;
  								body = body.substr(str.length + 1);
  							}
  
  							if (!isSpecial) {
  								return;
  							}
  
  							switch (str) {
  								case "member":
  									commentType = "members";
  									break;
  								case "global":
  									commentType = "globals";
  									break;
  								default:
  									commentType = str;
  							}
  						});
  
  						return {
  							type: Token.Comment,
  							commentType: commentType,
  							value: value,
  							body: body,
  							isSpecial: isSpecial,
  							isMultiline: opt.isMultiline || false,
  							isMalformed: opt.isMalformed || false
  						};
  					}
  					if (ch1 === "*" && ch2 === "/") {
  						this.trigger("error", {
  							code: "E018",
  							line: startLine,
  							character: startChar
  						});
  
  						this.skip(2);
  						return null;
  					}
  					if (ch1 !== "/" || ch2 !== "*" && ch2 !== "/") {
  						return null;
  					}
  					if (ch2 === "/") {
  						this.skip(this.input.length); // Skip to the EOL.
  						return commentToken("//", rest);
  					}
  
  					var body = "";
  					if (ch2 === "*") {
  						this.skip(2);
  
  						while (this.peek() !== "*" || this.peek(1) !== "/") {
  							if (this.peek() === "") {
  								// End of Line
  								body += "\n";
  								if (!this.nextLine()) {
  									this.trigger("error", {
  										code: "E017",
  										line: startLine,
  										character: startChar
  									});
  
  									return commentToken("/*", body, {
  										isMultiline: true,
  										isMalformed: true
  									});
  								}
  							} else {
  								body += this.peek();
  								this.skip();
  							}
  						}
  
  						this.skip(2);
  						return commentToken("/*", body, { isMultiline: true });
  					}
  				},
  				scanKeyword: function scanKeyword() {
  					var result = /^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input);
  					var keywords = ["if", "in", "do", "var", "for", "new", "try", "let", "this", "else", "case", "void", "with", "enum", "while", "break", "catch", "throw", "const", "yield", "class", "super", "return", "typeof", "delete", "switch", "export", "import", "default", "finally", "extends", "function", "continue", "debugger", "instanceof"];
  
  					if (result && keywords.indexOf(result[0]) >= 0) {
  						return {
  							type: Token.Keyword,
  							value: result[0]
  						};
  					}
  
  					return null;
  				},
  				scanIdentifier: function scanIdentifier() {
  					var id = "";
  					var index = 0;
  					var type, char;
  
  					function isUnicodeLetter(code) {
  						for (var i = 0; i < unicodeLetterTable.length;) {
  							if (code < unicodeLetterTable[i++]) {
  								return false;
  							}
  
  							if (code <= unicodeLetterTable[i++]) {
  								return true;
  							}
  						}
  
  						return false;
  					}
  
  					function isHexDigit(str) {
  						return (/^[0-9a-fA-F]$/.test(str)
  						);
  					}
  
  					var readUnicodeEscapeSequence = function () {
  						index += 1;
  
  						if (this.peek(index) !== "u") {
  							return null;
  						}
  
  						var ch1 = this.peek(index + 1);
  						var ch2 = this.peek(index + 2);
  						var ch3 = this.peek(index + 3);
  						var ch4 = this.peek(index + 4);
  						var code;
  
  						if (isHexDigit(ch1) && isHexDigit(ch2) && isHexDigit(ch3) && isHexDigit(ch4)) {
  							code = parseInt(ch1 + ch2 + ch3 + ch4, 16);
  
  							if (isUnicodeLetter(code)) {
  								index += 5;
  								return "\\u" + ch1 + ch2 + ch3 + ch4;
  							}
  
  							return null;
  						}
  
  						return null;
  					}.bind(this);
  
  					var getIdentifierStart = function () {
  						var chr = this.peek(index);
  						var code = chr.charCodeAt(0);
  
  						if (code === 92) {
  							return readUnicodeEscapeSequence();
  						}
  
  						if (code < 128) {
  							if (identifierStartTable[code]) {
  								index += 1;
  								return chr;
  							}
  
  							return null;
  						}
  
  						if (isUnicodeLetter(code)) {
  							index += 1;
  							return chr;
  						}
  
  						return null;
  					}.bind(this);
  
  					var getIdentifierPart = function () {
  						var chr = this.peek(index);
  						var code = chr.charCodeAt(0);
  
  						if (code === 92) {
  							return readUnicodeEscapeSequence();
  						}
  
  						if (code < 128) {
  							if (identifierPartTable[code]) {
  								index += 1;
  								return chr;
  							}
  
  							return null;
  						}
  
  						if (isUnicodeLetter(code)) {
  							index += 1;
  							return chr;
  						}
  
  						return null;
  					}.bind(this);
  
  					char = getIdentifierStart();
  					if (char === null) {
  						return null;
  					}
  
  					id = char;
  					for (;;) {
  						char = getIdentifierPart();
  
  						if (char === null) {
  							break;
  						}
  
  						id += char;
  					}
  
  					switch (id) {
  						case "true":
  						case "false":
  							type = Token.BooleanLiteral;
  							break;
  						case "null":
  							type = Token.NullLiteral;
  							break;
  						default:
  							type = Token.Identifier;
  					}
  
  					return {
  						type: type,
  						value: id
  					};
  				},
  				scanNumericLiteral: function scanNumericLiteral() {
  					var index = 0;
  					var value = "";
  					var length = this.input.length;
  					var char = this.peek(index);
  					var bad;
  
  					function isDecimalDigit(str) {
  						return (/^[0-9]$/.test(str)
  						);
  					}
  
  					function isOctalDigit(str) {
  						return (/^[0-7]$/.test(str)
  						);
  					}
  
  					function isHexDigit(str) {
  						return (/^[0-9a-fA-F]$/.test(str)
  						);
  					}
  
  					function isIdentifierStart(ch) {
  						return ch === "$" || ch === "_" || ch === "\\" || ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z";
  					}
  
  					if (char !== "." && !isDecimalDigit(char)) {
  						return null;
  					}
  
  					if (char !== ".") {
  						value = this.peek(index);
  						index += 1;
  						char = this.peek(index);
  
  						if (value === "0") {
  							if (char === "x" || char === "X") {
  								index += 1;
  								value += char;
  
  								while (index < length) {
  									char = this.peek(index);
  									if (!isHexDigit(char)) {
  										break;
  									}
  									value += char;
  									index += 1;
  								}
  
  								if (value.length <= 2) {
  									// 0x
  									return {
  										type: Token.NumericLiteral,
  										value: value,
  										isMalformed: true
  									};
  								}
  
  								if (index < length) {
  									char = this.peek(index);
  									if (isIdentifierStart(char)) {
  										return null;
  									}
  								}
  
  								return {
  									type: Token.NumericLiteral,
  									value: value,
  									base: 16,
  									isMalformed: false
  								};
  							}
  							if (isOctalDigit(char)) {
  								index += 1;
  								value += char;
  								bad = false;
  
  								while (index < length) {
  									char = this.peek(index);
  
  									if (isDecimalDigit(char)) {
  										bad = true;
  									} else if (!isOctalDigit(char)) {
  										break;
  									}
  									value += char;
  									index += 1;
  								}
  
  								if (index < length) {
  									char = this.peek(index);
  									if (isIdentifierStart(char)) {
  										return null;
  									}
  								}
  
  								return {
  									type: Token.NumericLiteral,
  									value: value,
  									base: 8,
  									isMalformed: false
  								};
  							}
  
  							if (isDecimalDigit(char)) {
  								index += 1;
  								value += char;
  							}
  						}
  
  						while (index < length) {
  							char = this.peek(index);
  							if (!isDecimalDigit(char)) {
  								break;
  							}
  							value += char;
  							index += 1;
  						}
  					}
  
  					if (char === ".") {
  						value += char;
  						index += 1;
  
  						while (index < length) {
  							char = this.peek(index);
  							if (!isDecimalDigit(char)) {
  								break;
  							}
  							value += char;
  							index += 1;
  						}
  					}
  
  					if (char === "e" || char === "E") {
  						value += char;
  						index += 1;
  						char = this.peek(index);
  
  						if (char === "+" || char === "-") {
  							value += this.peek(index);
  							index += 1;
  						}
  
  						char = this.peek(index);
  						if (isDecimalDigit(char)) {
  							value += char;
  							index += 1;
  
  							while (index < length) {
  								char = this.peek(index);
  								if (!isDecimalDigit(char)) {
  									break;
  								}
  								value += char;
  								index += 1;
  							}
  						} else {
  							return null;
  						}
  					}
  
  					if (index < length) {
  						char = this.peek(index);
  						if (isIdentifierStart(char)) {
  							return null;
  						}
  					}
  
  					return {
  						type: Token.NumericLiteral,
  						value: value,
  						base: 10,
  						isMalformed: !isFinite(value)
  					};
  				},
  				scanStringLiteral: function scanStringLiteral(checks) {
  					var quote = this.peek();
  					if (quote !== "\"" && quote !== "'") {
  						return null;
  					}
  					this.triggerAsync("warning", {
  						code: "W108",
  						line: this.line,
  						character: this.char // +1?
  					}, checks, function () {
  						return state.jsonMode && quote !== "\"";
  					});
  
  					var value = "";
  					var startLine = this.line;
  					var startChar = this.char;
  					var allowNewLine = false;
  
  					this.skip();
  
  					outer: while (this.peek() !== quote) {
  						while (this.peek() === "") {
  							// End Of Line
  
  							if (!allowNewLine) {
  								this.trigger("warning", {
  									code: "W112",
  									line: this.line,
  									character: this.char
  								});
  							} else {
  								allowNewLine = false;
  
  								this.triggerAsync("warning", {
  									code: "W043",
  									line: this.line,
  									character: this.char
  								}, checks, function () {
  									return !state.option.multistr;
  								});
  
  								this.triggerAsync("warning", {
  									code: "W042",
  									line: this.line,
  									character: this.char
  								}, checks, function () {
  									return state.jsonMode && state.option.multistr;
  								});
  							}
  
  							if (!this.nextLine()) {
  								this.trigger("error", {
  									code: "E029",
  									line: startLine,
  									character: startChar
  								});
  
  								return {
  									type: Token.StringLiteral,
  									value: value,
  									isUnclosed: true,
  									quote: quote
  								};
  							}
  
  							if (this.peek() == quote) break outer;
  						}
  
  						allowNewLine = false;
  						var char = this.peek();
  						var jump = 1; // A length of a jump, after we're done
  
  						if (char < " ") {
  							this.trigger("warning", {
  								code: "W113",
  								line: this.line,
  								character: this.char,
  								data: ["<non-printable>"]
  							});
  						}
  
  						if (char === "\\") {
  							this.skip();
  							char = this.peek();
  
  							switch (char) {
  								case "'":
  									this.triggerAsync("warning", {
  										code: "W114",
  										line: this.line,
  										character: this.char,
  										data: ["\\'"]
  									}, checks, function () {
  										return state.jsonMode;
  									});
  									break;
  								case "b":
  									char = "\b";
  									break;
  								case "f":
  									char = "\f";
  									break;
  								case "n":
  									char = "\n";
  									break;
  								case "r":
  									char = "\r";
  									break;
  								case "t":
  									char = "\t";
  									break;
  								case "0":
  									char = "\0";
  									var n = parseInt(this.peek(1), 10);
  									this.triggerAsync("warning", {
  										code: "W115",
  										line: this.line,
  										character: this.char
  									}, checks, function () {
  										return n >= 0 && n <= 7 && state.directive["use strict"];
  									});
  									break;
  								case "u":
  									char = String.fromCharCode(parseInt(this.input.substr(1, 4), 16));
  									jump = 5;
  									break;
  								case "v":
  									this.triggerAsync("warning", {
  										code: "W114",
  										line: this.line,
  										character: this.char,
  										data: ["\\v"]
  									}, checks, function () {
  										return state.jsonMode;
  									});
  
  									char = "\v";
  									break;
  								case "x":
  									var x = parseInt(this.input.substr(1, 2), 16);
  
  									this.triggerAsync("warning", {
  										code: "W114",
  										line: this.line,
  										character: this.char,
  										data: ["\\x-"]
  									}, checks, function () {
  										return state.jsonMode;
  									});
  
  									char = String.fromCharCode(x);
  									jump = 3;
  									break;
  								case "\\":
  								case "\"":
  								case "/":
  									break;
  								case "":
  									allowNewLine = true;
  									char = "";
  									break;
  								case "!":
  									if (value.slice(value.length - 2) === "<") {
  										break;
  									}
  								default:
  									this.trigger("warning", {
  										code: "W044",
  										line: this.line,
  										character: this.char
  									});
  							}
  						}
  
  						value += char;
  						this.skip(jump);
  					}
  
  					this.skip();
  					return {
  						type: Token.StringLiteral,
  						value: value,
  						isUnclosed: false,
  						quote: quote
  					};
  				},
  				scanRegExp: function scanRegExp() {
  					var index = 0;
  					var length = this.input.length;
  					var char = this.peek();
  					var value = char;
  					var body = "";
  					var flags = [];
  					var malformed = false;
  					var isCharSet = false;
  					var terminated;
  
  					var scanUnexpectedChars = function () {
  						if (char < " ") {
  							malformed = true;
  							this.trigger("warning", {
  								code: "W048",
  								line: this.line,
  								character: this.char
  							});
  						}
  						if (char === "<") {
  							malformed = true;
  							this.trigger("warning", {
  								code: "W049",
  								line: this.line,
  								character: this.char,
  								data: [char]
  							});
  						}
  					}.bind(this);
  					if (!this.prereg || char !== "/") {
  						return null;
  					}
  
  					index += 1;
  					terminated = false;
  
  					while (index < length) {
  						char = this.peek(index);
  						value += char;
  						body += char;
  
  						if (isCharSet) {
  							if (char === "]") {
  								if (this.peek(index - 1) !== "\\" || this.peek(index - 2) === "\\") {
  									isCharSet = false;
  								}
  							}
  
  							if (char === "\\") {
  								index += 1;
  								char = this.peek(index);
  								body += char;
  								value += char;
  
  								scanUnexpectedChars();
  							}
  
  							index += 1;
  							continue;
  						}
  
  						if (char === "\\") {
  							index += 1;
  							char = this.peek(index);
  							body += char;
  							value += char;
  
  							scanUnexpectedChars();
  
  							if (char === "/") {
  								index += 1;
  								continue;
  							}
  
  							if (char === "[") {
  								index += 1;
  								continue;
  							}
  						}
  
  						if (char === "[") {
  							isCharSet = true;
  							index += 1;
  							continue;
  						}
  
  						if (char === "/") {
  							body = body.substr(0, body.length - 1);
  							terminated = true;
  							index += 1;
  							break;
  						}
  
  						index += 1;
  					}
  
  					if (!terminated) {
  						this.trigger("error", {
  							code: "E015",
  							line: this.line,
  							character: this.from
  						});
  
  						return void this.trigger("fatal", {
  							line: this.line,
  							from: this.from
  						});
  					}
  
  					while (index < length) {
  						char = this.peek(index);
  						if (!/[gim]/.test(char)) {
  							break;
  						}
  						flags.push(char);
  						value += char;
  						index += 1;
  					}
  
  					try {
  						new RegExp(body, flags.join(""));
  					} catch (err) {
  						malformed = true;
  						this.trigger("error", {
  							code: "E016",
  							line: this.line,
  							character: this.char,
  							data: [err.message] // Platform dependent!
  						});
  					}
  
  					return {
  						type: Token.RegExp,
  						value: value,
  						flags: flags,
  						isMalformed: malformed
  					};
  				},
  				scanMixedSpacesAndTabs: function scanMixedSpacesAndTabs() {
  					var at, match;
  
  					if (state.option.smarttabs) {
  						match = this.input.match(/(\/\/|^\s?\*)? \t/);
  						at = match && !match[1] ? 0 : -1;
  					} else {
  						at = this.input.search(/ \t|\t [^\*]/);
  					}
  
  					return at;
  				},
  				scanUnsafeChars: function scanUnsafeChars() {
  					return this.input.search(reg.unsafeChars);
  				},
  				next: function next(checks) {
  					this.from = this.char;
  					var start;
  					if (/\s/.test(this.peek())) {
  						start = this.char;
  
  						while (/\s/.test(this.peek())) {
  							this.from += 1;
  							this.skip();
  						}
  
  						if (this.peek() === "") {
  							// EOL
  							if (!/^\s*$/.test(this.getLines()[this.line - 1]) && state.option.trailing) {
  								this.trigger("warning", { code: "W102", line: this.line, character: start });
  							}
  						}
  					}
  
  					var match = this.scanComments() || this.scanStringLiteral(checks);
  
  					if (match) {
  						return match;
  					}
  
  					match = this.scanRegExp() || this.scanPunctuator() || this.scanKeyword() || this.scanIdentifier() || this.scanNumericLiteral();
  
  					if (match) {
  						this.skip(match.value.length);
  						return match;
  					}
  
  					return null;
  				},
  				nextLine: function nextLine() {
  					var char;
  
  					if (this.line >= this.getLines().length) {
  						return false;
  					}
  
  					this.input = this.getLines()[this.line];
  					this.line += 1;
  					this.char = 1;
  					this.from = 1;
  
  					char = this.scanMixedSpacesAndTabs();
  					if (char >= 0) {
  						this.trigger("warning", { code: "W099", line: this.line, character: char + 1 });
  					}
  
  					this.input = this.input.replace(/\t/g, state.tab);
  					char = this.scanUnsafeChars();
  
  					if (char >= 0) {
  						this.trigger("warning", { code: "W100", line: this.line, character: char });
  					}
  
  					if (state.option.maxlen && state.option.maxlen < this.input.length) {
  						this.trigger("warning", { code: "W101", line: this.line, character: this.input.length });
  					}
  
  					return true;
  				},
  				start: function start() {
  					this.nextLine();
  				},
  				token: function token() {
  					var checks = asyncTrigger();
  					var token;
  
  					function isReserved(token, isProperty) {
  						if (!token.reserved) {
  							return false;
  						}
  						var meta = token.meta;
  
  						if (meta && meta.isFutureReservedWord && state.option.inES5()) {
  							if (!meta.es5) {
  								return false;
  							}
  							if (meta.strictOnly) {
  								if (!state.option.strict && !state.directive["use strict"]) {
  									return false;
  								}
  							}
  
  							if (isProperty) {
  								return false;
  							}
  						}
  
  						return true;
  					}
  					var create = function (type, value, isProperty) {
  						var obj;
  
  						if (type !== "(endline)" && type !== "(end)") {
  							this.prereg = false;
  						}
  
  						if (type === "(punctuator)") {
  							switch (value) {
  								case ".":
  								case ")":
  								case "~":
  								case "#":
  								case "]":
  									this.prereg = false;
  									break;
  								default:
  									this.prereg = true;
  							}
  
  							obj = Object.create(state.syntax[value] || state.syntax["(error)"]);
  						}
  
  						if (type === "(identifier)") {
  							if (value === "return" || value === "case" || value === "typeof") {
  								this.prereg = true;
  							}
  
  							if (_.has(state.syntax, value)) {
  								obj = Object.create(state.syntax[value] || state.syntax["(error)"]);
  								if (!isReserved(obj, isProperty && type === "(identifier)")) {
  									obj = null;
  								}
  							}
  						}
  
  						if (!obj) {
  							obj = Object.create(state.syntax[type]);
  						}
  
  						obj.identifier = type === "(identifier)";
  						obj.type = obj.type || type;
  						obj.value = value;
  						obj.line = this.line;
  						obj.character = this.char;
  						obj.from = this.from;
  
  						if (isProperty && obj.identifier) {
  							obj.isProperty = isProperty;
  						}
  
  						obj.check = checks.check;
  
  						return obj;
  					}.bind(this);
  
  					for (;;) {
  						if (!this.input.length) {
  							return create(this.nextLine() ? "(endline)" : "(end)", "");
  						}
  
  						token = this.next(checks);
  
  						if (!token) {
  							if (this.input.length) {
  								this.trigger("error", {
  									code: "E024",
  									line: this.line,
  									character: this.char,
  									data: [this.peek()]
  								});
  
  								this.input = "";
  							}
  
  							continue;
  						}
  
  						switch (token.type) {
  							case Token.StringLiteral:
  								this.triggerAsync("String", {
  									line: this.line,
  									char: this.char,
  									from: this.from,
  									value: token.value,
  									quote: token.quote
  								}, checks, function () {
  									return true;
  								});
  
  								return create("(string)", token.value);
  							case Token.Identifier:
  								this.trigger("Identifier", {
  									line: this.line,
  									char: this.char,
  									from: this.form,
  									name: token.value,
  									isProperty: state.tokens.curr.id === "."
  								});
  							case Token.Keyword:
  							case Token.NullLiteral:
  							case Token.BooleanLiteral:
  								return create("(identifier)", token.value, state.tokens.curr.id === ".");
  
  							case Token.NumericLiteral:
  								if (token.isMalformed) {
  									this.trigger("warning", {
  										code: "W045",
  										line: this.line,
  										character: this.char,
  										data: [token.value]
  									});
  								}
  
  								this.triggerAsync("warning", {
  									code: "W114",
  									line: this.line,
  									character: this.char,
  									data: ["0x-"]
  								}, checks, function () {
  									return token.base === 16 && state.jsonMode;
  								});
  
  								this.triggerAsync("warning", {
  									code: "W115",
  									line: this.line,
  									character: this.char
  								}, checks, function () {
  									return state.directive["use strict"] && token.base === 8;
  								});
  
  								this.trigger("Number", {
  									line: this.line,
  									char: this.char,
  									from: this.from,
  									value: token.value,
  									base: token.base,
  									isMalformed: token.malformed
  								});
  
  								return create("(number)", token.value);
  
  							case Token.RegExp:
  								return create("(regexp)", token.value);
  
  							case Token.Comment:
  								state.tokens.curr.comment = true;
  
  								if (token.isSpecial) {
  									return {
  										value: token.value,
  										body: token.body,
  										type: token.commentType,
  										isSpecial: token.isSpecial,
  										line: this.line,
  										character: this.char,
  										from: this.from
  									};
  								}
  
  								break;
  
  							case "":
  								break;
  
  							default:
  								return create("(punctuator)", token.value);
  						}
  					}
  				}
  			};
  
  			exports.Lexer = Lexer;
  		}, { "./reg.js": 6, "./state.js": 7, "events": 10, "underscore": 1 }],
  		6: [function (req, module, exports) {
  
  			"use string";
  
  			exports.unsafeString = /@cc|<\/?|script|\]\s*\]|<\s*!|&lt/i;
  			exports.unsafeChars = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
  			exports.needEsc = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
  
  			exports.needEscGlobal = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
  			exports.starSlash = /\*\//;
  			exports.identifier = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/;
  			exports.javascriptURL = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i;
  			exports.fallsThrough = /^\s*\/\*\s*falls?\sthrough\s*\*\/\s*$/;
  		}, {}],
  		7: [function (req, module, exports) {
  
  			var state = {
  				syntax: {},
  
  				reset: function reset() {
  					this.tokens = {
  						prev: null,
  						next: null,
  						curr: null
  					};
  
  					this.option = {};
  					this.ignored = {};
  					this.directive = {};
  					this.jsonMode = false;
  					this.jsonWarnings = [];
  					this.lines = [];
  					this.tab = "";
  					this.cache = {}; // Node.JS doesn't have Map. Sniff.
  				}
  			};
  
  			exports.state = state;
  		}, {}],
  		8: [function (req, module, exports) {
  
  			exports.register = function (linter) {
  
  				linter.on("Identifier", function style_scanProto(data) {
  					if (linter.getOption("proto")) {
  						return;
  					}
  
  					if (data.name === "__proto__") {
  						linter.warn("W103", {
  							line: data.line,
  							char: data.char,
  							data: [data.name]
  						});
  					}
  				});
  
  				linter.on("Identifier", function style_scanIterator(data) {
  					if (linter.getOption("iterator")) {
  						return;
  					}
  
  					if (data.name === "__iterator__") {
  						linter.warn("W104", {
  							line: data.line,
  							char: data.char,
  							data: [data.name]
  						});
  					}
  				});
  
  				linter.on("Identifier", function style_scanDangling(data) {
  					if (!linter.getOption("nomen")) {
  						return;
  					}
  					if (data.name === "_") {
  						return;
  					}
  					if (linter.getOption("node")) {
  						if (/^(__dirname|__filename)$/.test(data.name) && !data.isProperty) {
  							return;
  						}
  					}
  
  					if (/^(_+.*|.*_+)$/.test(data.name)) {
  						linter.warn("W105", {
  							line: data.line,
  							char: data.from,
  							data: ["dangling '_'", data.name]
  						});
  					}
  				});
  
  				linter.on("Identifier", function style_scanCamelCase(data) {
  					if (!linter.getOption("camelcase")) {
  						return;
  					}
  
  					if (data.name.replace(/^_+/, "").indexOf("_") > -1 && !data.name.match(/^[A-Z0-9_]*$/)) {
  						linter.warn("W106", {
  							line: data.line,
  							char: data.from,
  							data: [data.name]
  						});
  					}
  				});
  
  				linter.on("String", function style_scanQuotes(data) {
  					var quotmark = linter.getOption("quotmark");
  					var code;
  
  					if (!quotmark) {
  						return;
  					}
  
  					if (quotmark === "single" && data.quote !== "'") {
  						code = "W109";
  					}
  
  					if (quotmark === "double" && data.quote !== "\"") {
  						code = "W108";
  					}
  
  					if (quotmark === true) {
  						if (!linter.getCache("quotmark")) {
  							linter.setCache("quotmark", data.quote);
  						}
  
  						if (linter.getCache("quotmark") !== data.quote) {
  							code = "W110";
  						}
  					}
  
  					if (code) {
  						linter.warn(code, {
  							line: data.line,
  							char: data.char
  						});
  					}
  				});
  
  				linter.on("Number", function style_scanNumbers(data) {
  					if (data.value.charAt(0) === ".") {
  						linter.warn("W008", {
  							line: data.line,
  							char: data.char,
  							data: [data.value]
  						});
  					}
  
  					if (data.value.substr(data.value.length - 1) === ".") {
  						linter.warn("W047", {
  							line: data.line,
  							char: data.char,
  							data: [data.value]
  						});
  					}
  
  					if (/^00+/.test(data.value)) {
  						linter.warn("W046", {
  							line: data.line,
  							char: data.char,
  							data: [data.value]
  						});
  					}
  				});
  
  				linter.on("String", function style_scanJavaScriptURLs(data) {
  					var re = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i;
  
  					if (linter.getOption("scripturl")) {
  						return;
  					}
  
  					if (re.test(data.value)) {
  						linter.warn("W107", {
  							line: data.line,
  							char: data.char
  						});
  					}
  				});
  			};
  		}, {}]
  	}, _defineProperty(_ref, "9", [function (req, module, exports) {}, {}]), _defineProperty(_ref, 10, [function (req, module, exports) {
  		var process = req("__browserify_process");if (!process.EventEmitter) process.EventEmitter = function () {};
  
  		var EventEmitter = exports.EventEmitter = process.EventEmitter;
  		var isArray = typeof Array.isArray === 'function' ? Array.isArray : function (xs) {
  			return Object.prototype.toString.call(xs) === '[object Array]';
  		};
  		function indexOf(xs, x) {
  			if (xs.indexOf) return xs.indexOf(x);
  			for (var i = 0; i < xs.length; i++) {
  				if (x === xs[i]) return i;
  			}
  			return -1;
  		}
  		var defaultMaxListeners = 200;
  		EventEmitter.prototype.setMaxListeners = function (n) {
  			if (!this._events) this._events = {};
  			this._events.maxListeners = n;
  		};
  
  		EventEmitter.prototype.emit = function (type) {
  			if (type === 'error') {
  				if (!this._events || !this._events.error || isArray(this._events.error) && !this._events.error.length) {
  					if (arguments[1] instanceof Error) {
  						throw arguments[1]; // Unhandled 'error' event
  					} else {
  						throw new Error("Uncaught, unspecified 'error' event.");
  					}
  					return false;
  				}
  			}
  
  			if (!this._events) return false;
  			var handler = this._events[type];
  			if (!handler) return false;
  
  			if (typeof handler == 'function') {
  				switch (arguments.length) {
  					case 1:
  						handler.call(this);
  						break;
  					case 2:
  						handler.call(this, arguments[1]);
  						break;
  					case 3:
  						handler.call(this, arguments[1], arguments[2]);
  						break;
  					default:
  						var args = Array.prototype.slice.call(arguments, 1);
  						handler.apply(this, args);
  				}
  				return true;
  			} else if (isArray(handler)) {
  				var args = Array.prototype.slice.call(arguments, 1);
  
  				var listeners = handler.slice();
  				for (var i = 0, l = listeners.length; i < l; i++) {
  					listeners[i].apply(this, args);
  				}
  				return true;
  			} else {
  				return false;
  			}
  		};
  		EventEmitter.prototype.addListener = function (type, listener) {
  			if ('function' !== typeof listener) {
  				throw new Error('addListener only takes instances of Function');
  			}
  
  			if (!this._events) this._events = {};
  			this.emit('newListener', type, listener);
  
  			if (!this._events[type]) {
  				this._events[type] = listener;
  			} else if (isArray(this._events[type])) {
  				if (!this._events[type].warned) {
  					var m;
  					if (this._events.maxListeners !== undefined) {
  						m = this._events.maxListeners;
  					} else {
  						m = defaultMaxListeners;
  					}
  
  					if (m && m > 0 && this._events[type].length > m) {
  						this._events[type].warned = true;
  						console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length);
  						console.trace();
  					}
  				}
  				this._events[type].push(listener);
  			} else {
  				this._events[type] = [this._events[type], listener];
  			}
  
  			return this;
  		};
  
  		EventEmitter.prototype.on = EventEmitter.prototype.addListener;
  
  		EventEmitter.prototype.once = function (type, listener) {
  			var self = this;
  			self.on(type, function g() {
  				self.removeListener(type, g);
  				listener.apply(this, arguments);
  			});
  
  			return this;
  		};
  
  		EventEmitter.prototype.removeListener = function (type, listener) {
  			if ('function' !== typeof listener) {
  				throw new Error('removeListener only takes instances of Function');
  			}
  			if (!this._events || !this._events[type]) return this;
  
  			var list = this._events[type];
  
  			if (isArray(list)) {
  				var i = indexOf(list, listener);
  				if (i < 0) return this;
  				list.splice(i, 1);
  				if (list.length == 0) delete this._events[type];
  			} else if (this._events[type] === listener) {
  				delete this._events[type];
  			}
  
  			return this;
  		};
  
  		EventEmitter.prototype.removeAllListeners = function (type) {
  			if (arguments.length === 0) {
  				this._events = {};
  				return this;
  			}
  			if (type && this._events && this._events[type]) this._events[type] = null;
  			return this;
  		};
  
  		EventEmitter.prototype.listeners = function (type) {
  			if (!this._events) this._events = {};
  			if (!this._events[type]) this._events[type] = [];
  			if (!isArray(this._events[type])) {
  				this._events[type] = [this._events[type]];
  			}
  			return this._events[type];
  		};
  
  		EventEmitter.listenerCount = function (emitter, type) {
  			var ret;
  			if (!emitter._events || !emitter._events[type]) ret = 0;else if (typeof emitter._events[type] === 'function') ret = 1;else ret = emitter._events[type].length;
  			return ret;
  		};
  	}, { "__browserify_process": 11 }]), _defineProperty(_ref, 11, [function (req, module, exports) {
  
  		var process = module.exports = {};
  
  		process.nextTick = function () {
  			var canSetImmediate = typeof window !== 'undefined' && window.setImmediate;
  			var canPost = typeof window !== 'undefined' && window.postMessage && window.addEventListener;
  
  			if (canSetImmediate) {
  				return function (f) {
  					return window.setImmediate(f);
  				};
  			}
  
  			if (canPost) {
  				var queue = [];
  				window.addEventListener('message', function (ev) {
  					if (ev.source === window && ev.data === 'process-tick') {
  						ev.stopPropagation();
  						if (queue.length > 0) {
  							var fn = queue.shift();
  							fn();
  						}
  					}
  				}, true);
  
  				return function nextTick(fn) {
  					queue.push(fn);
  					window.postMessage('process-tick', '*');
  				};
  			}
  
  			return function nextTick(fn) {
  				setTimeout(fn, 0);
  			};
  		}();
  
  		process.title = 'browser';
  		process.browser = true;
  		process.env = {};
  		process.argv = [];
  
  		process.binding = function (name) {
  			throw new Error('process.binding is not supported');
  		};
  		process.cwd = function () {
  			return '/';
  		};
  		process.chdir = function (dir) {
  			throw new Error('process.chdir is not supported');
  		};
  	}, {}]), _defineProperty(_ref, "jshint", [function (req, module, exports) {
  		module.exports = req('n4bKNg');
  	}, {}]), _ref), {}, ["n4bKNg"]);
  
  	function req() {
  		return require.apply(this, arguments);
  	}
  	module.exports = req("jshint");
  });
  
  define('ace/document', ['require', 'exports', 'module', 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/range', 'ace/anchor'], function (require, exports, module) {
  
  	var oop = require("./lib/oop");
  	var EventEmitter = require("./lib/event_emitter").EventEmitter;
  	var Range = require("./range").Range;
  	var Anchor = require("./anchor").Anchor;
  
  	var Document = function Document(text) {
  		this.$lines = [];
  		if (text.length === 0) {
  			this.$lines = [""];
  		} else if (Array.isArray(text)) {
  			this._insertLines(0, text);
  		} else {
  			this.insert({ row: 0, column: 0 }, text);
  		}
  	};
  
  	(function () {
  
  		oop.implement(this, EventEmitter);
  		this.setValue = function (text) {
  			var len = this.getLength();
  			this.remove(new Range(0, 0, len, this.getLine(len - 1).length));
  			this.insert({ row: 0, column: 0 }, text);
  		};
  		this.getValue = function () {
  			return this.getAllLines().join(this.getNewLineCharacter());
  		};
  		this.createAnchor = function (row, column) {
  			return new Anchor(this, row, column);
  		};
  		if ("aaa".split(/a/).length === 0) this.$split = function (text) {
  			return text.replace(/\r\n|\r/g, "\n").split("\n");
  		};else this.$split = function (text) {
  			return text.split(/\r\n|\r|\n/);
  		};
  
  		this.$detectNewLine = function (text) {
  			var match = text.match(/^.*?(\r\n|\r|\n)/m);
  			this.$autoNewLine = match ? match[1] : "\n";
  			this._signal("changeNewLineMode");
  		};
  		this.getNewLineCharacter = function () {
  			switch (this.$newLineMode) {
  				case "windows":
  					return "\r\n";
  				case "unix":
  					return "\n";
  				default:
  					return this.$autoNewLine || "\n";
  			}
  		};
  
  		this.$autoNewLine = "";
  		this.$newLineMode = "auto";
  		this.setNewLineMode = function (newLineMode) {
  			if (this.$newLineMode === newLineMode) return;
  
  			this.$newLineMode = newLineMode;
  			this._signal("changeNewLineMode");
  		};
  		this.getNewLineMode = function () {
  			return this.$newLineMode;
  		};
  		this.isNewLine = function (text) {
  			return text == "\r\n" || text == "\r" || text == "\n";
  		};
  		this.getLine = function (row) {
  			return this.$lines[row] || "";
  		};
  		this.getLines = function (firstRow, lastRow) {
  			return this.$lines.slice(firstRow, lastRow + 1);
  		};
  		this.getAllLines = function () {
  			return this.getLines(0, this.getLength());
  		};
  		this.getLength = function () {
  			return this.$lines.length;
  		};
  		this.getTextRange = function (range) {
  			if (range.start.row == range.end.row) {
  				return this.getLine(range.start.row).substring(range.start.column, range.end.column);
  			}
  			var lines = this.getLines(range.start.row, range.end.row);
  			lines[0] = (lines[0] || "").substring(range.start.column);
  			var l = lines.length - 1;
  			if (range.end.row - range.start.row == l) lines[l] = lines[l].substring(0, range.end.column);
  			return lines.join(this.getNewLineCharacter());
  		};
  
  		this.$clipPosition = function (position) {
  			var length = this.getLength();
  			if (position.row >= length) {
  				position.row = Math.max(0, length - 1);
  				position.column = this.getLine(length - 1).length;
  			} else if (position.row < 0) position.row = 0;
  			return position;
  		};
  		this.insert = function (position, text) {
  			if (!text || text.length === 0) return position;
  
  			position = this.$clipPosition(position);
  			if (this.getLength() <= 1) this.$detectNewLine(text);
  
  			var lines = this.$split(text);
  			var firstLine = lines.splice(0, 1)[0];
  			var lastLine = lines.length == 0 ? null : lines.splice(lines.length - 1, 1)[0];
  
  			position = this.insertInLine(position, firstLine);
  			if (lastLine !== null) {
  				position = this.insertNewLine(position); // terminate first line
  				position = this._insertLines(position.row, lines);
  				position = this.insertInLine(position, lastLine || "");
  			}
  			return position;
  		};
  		this.insertLines = function (row, lines) {
  			if (row >= this.getLength()) return this.insert({ row: row, column: 0 }, "\n" + lines.join("\n"));
  			return this._insertLines(Math.max(row, 0), lines);
  		};
  		this._insertLines = function (row, lines) {
  			if (lines.length == 0) return { row: row, column: 0 };
  			while (lines.length > 0xF000) {
  				var end = this._insertLines(row, lines.slice(0, 0xF000));
  				lines = lines.slice(0xF000);
  				row = end.row;
  			}
  
  			var args = [row, 0];
  			args.push.apply(args, lines);
  			this.$lines.splice.apply(this.$lines, args);
  
  			var range = new Range(row, 0, row + lines.length, 0);
  			var delta = {
  				action: "insertLines",
  				range: range,
  				lines: lines
  			};
  			this._signal("change", { data: delta });
  			return range.end;
  		};
  		this.insertNewLine = function (position) {
  			position = this.$clipPosition(position);
  			var line = this.$lines[position.row] || "";
  
  			this.$lines[position.row] = line.substring(0, position.column);
  			this.$lines.splice(position.row + 1, 0, line.substring(position.column, line.length));
  
  			var end = {
  				row: position.row + 1,
  				column: 0
  			};
  
  			var delta = {
  				action: "insertText",
  				range: Range.fromPoints(position, end),
  				text: this.getNewLineCharacter()
  			};
  			this._signal("change", { data: delta });
  
  			return end;
  		};
  		this.insertInLine = function (position, text) {
  			if (text.length == 0) return position;
  
  			var line = this.$lines[position.row] || "";
  
  			this.$lines[position.row] = line.substring(0, position.column) + text + line.substring(position.column);
  
  			var end = {
  				row: position.row,
  				column: position.column + text.length
  			};
  
  			var delta = {
  				action: "insertText",
  				range: Range.fromPoints(position, end),
  				text: text
  			};
  			this._signal("change", { data: delta });
  
  			return end;
  		};
  		this.remove = function (range) {
  			if (!(range instanceof Range)) range = Range.fromPoints(range.start, range.end);
  			range.start = this.$clipPosition(range.start);
  			range.end = this.$clipPosition(range.end);
  
  			if (range.isEmpty()) return range.start;
  
  			var firstRow = range.start.row;
  			var lastRow = range.end.row;
  
  			if (range.isMultiLine()) {
  				var firstFullRow = range.start.column == 0 ? firstRow : firstRow + 1;
  				var lastFullRow = lastRow - 1;
  
  				if (range.end.column > 0) this.removeInLine(lastRow, 0, range.end.column);
  
  				if (lastFullRow >= firstFullRow) this._removeLines(firstFullRow, lastFullRow);
  
  				if (firstFullRow != firstRow) {
  					this.removeInLine(firstRow, range.start.column, this.getLine(firstRow).length);
  					this.removeNewLine(range.start.row);
  				}
  			} else {
  				this.removeInLine(firstRow, range.start.column, range.end.column);
  			}
  			return range.start;
  		};
  		this.removeInLine = function (row, startColumn, endColumn) {
  			if (startColumn == endColumn) return;
  
  			var range = new Range(row, startColumn, row, endColumn);
  			var line = this.getLine(row);
  			var removed = line.substring(startColumn, endColumn);
  			var newLine = line.substring(0, startColumn) + line.substring(endColumn, line.length);
  			this.$lines.splice(row, 1, newLine);
  
  			var delta = {
  				action: "removeText",
  				range: range,
  				text: removed
  			};
  			this._signal("change", { data: delta });
  			return range.start;
  		};
  		this.removeLines = function (firstRow, lastRow) {
  			if (firstRow < 0 || lastRow >= this.getLength()) return this.remove(new Range(firstRow, 0, lastRow + 1, 0));
  			return this._removeLines(firstRow, lastRow);
  		};
  
  		this._removeLines = function (firstRow, lastRow) {
  			var range = new Range(firstRow, 0, lastRow + 1, 0);
  			var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);
  
  			var delta = {
  				action: "removeLines",
  				range: range,
  				nl: this.getNewLineCharacter(),
  				lines: removed
  			};
  			this._signal("change", { data: delta });
  			return removed;
  		};
  		this.removeNewLine = function (row) {
  			var firstLine = this.getLine(row);
  			var secondLine = this.getLine(row + 1);
  
  			var range = new Range(row, firstLine.length, row + 1, 0);
  			var line = firstLine + secondLine;
  
  			this.$lines.splice(row, 2, line);
  
  			var delta = {
  				action: "removeText",
  				range: range,
  				text: this.getNewLineCharacter()
  			};
  			this._signal("change", { data: delta });
  		};
  		this.replace = function (range, text) {
  			if (!(range instanceof Range)) range = Range.fromPoints(range.start, range.end);
  			if (text.length == 0 && range.isEmpty()) return range.start;
  			if (text == this.getTextRange(range)) return range.end;
  
  			this.remove(range);
  			if (text) {
  				var end = this.insert(range.start, text);
  			} else {
  				end = range.start;
  			}
  
  			return end;
  		};
  		this.applyDeltas = function (deltas) {
  			for (var i = 0; i < deltas.length; i++) {
  				var delta = deltas[i];
  				var range = Range.fromPoints(delta.range.start, delta.range.end);
  
  				if (delta.action == "insertLines") this.insertLines(range.start.row, delta.lines);else if (delta.action == "insertText") this.insert(range.start, delta.text);else if (delta.action == "removeLines") this._removeLines(range.start.row, range.end.row - 1);else if (delta.action == "removeText") this.remove(range);
  			}
  		};
  		this.revertDeltas = function (deltas) {
  			for (var i = deltas.length - 1; i >= 0; i--) {
  				var delta = deltas[i];
  
  				var range = Range.fromPoints(delta.range.start, delta.range.end);
  
  				if (delta.action == "insertLines") this._removeLines(range.start.row, range.end.row - 1);else if (delta.action == "insertText") this.remove(range);else if (delta.action == "removeLines") this._insertLines(range.start.row, delta.lines);else if (delta.action == "removeText") this.insert(range.start, delta.text);
  			}
  		};
  		this.indexToPosition = function (index, startRow) {
  			var lines = this.$lines || this.getAllLines();
  			var newlineLength = this.getNewLineCharacter().length;
  			for (var i = startRow || 0, l = lines.length; i < l; i++) {
  				index -= lines[i].length + newlineLength;
  				if (index < 0) return { row: i, column: index + lines[i].length + newlineLength };
  			}
  			return { row: l - 1, column: lines[l - 1].length };
  		};
  		this.positionToIndex = function (pos, startRow) {
  			var lines = this.$lines || this.getAllLines();
  			var newlineLength = this.getNewLineCharacter().length;
  			var index = 0;
  			var row = Math.min(pos.row, lines.length);
  			for (var i = startRow || 0; i < row; ++i) {
  				index += lines[i].length + newlineLength;
  			}return index + pos.column;
  		};
  	}).call(Document.prototype);
  
  	exports.Document = Document;
  });