dom/system/gonk/tests/marionette/ril_jshint/jshint.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 //2.1.3
     2 var JSHINT;
     3 (function () {
     4 var require;
     5 require=(function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i})({1:[function(require,module,exports){
     6 // shim for using process in browser
     8 var process = module.exports = {};
    10 process.nextTick = (function () {
    11     var canSetImmediate = typeof window !== 'undefined'
    12     && window.setImmediate;
    13     var canPost = typeof window !== 'undefined'
    14     && window.postMessage && window.addEventListener
    15     ;
    17     if (canSetImmediate) {
    18         return function (f) { return window.setImmediate(f) };
    19     }
    21     if (canPost) {
    22         var queue = [];
    23         window.addEventListener('message', function (ev) {
    24             if (ev.source === window && ev.data === 'process-tick') {
    25                 ev.stopPropagation();
    26                 if (queue.length > 0) {
    27                     var fn = queue.shift();
    28                     fn();
    29                 }
    30             }
    31         }, true);
    33         return function nextTick(fn) {
    34             queue.push(fn);
    35             window.postMessage('process-tick', '*');
    36         };
    37     }
    39     return function nextTick(fn) {
    40         setTimeout(fn, 0);
    41     };
    42 })();
    44 process.title = 'browser';
    45 process.browser = true;
    46 process.env = {};
    47 process.argv = [];
    49 process.binding = function (name) {
    50     throw new Error('process.binding is not supported');
    51 }
    53 // TODO(shtylman)
    54 process.cwd = function () { return '/' };
    55 process.chdir = function (dir) {
    56     throw new Error('process.chdir is not supported');
    57 };
    59 },{}],2:[function(require,module,exports){
    60 (function(process){if (!process.EventEmitter) process.EventEmitter = function () {};
    62 var EventEmitter = exports.EventEmitter = process.EventEmitter;
    63 var isArray = typeof Array.isArray === 'function'
    64     ? Array.isArray
    65     : function (xs) {
    66         return Object.prototype.toString.call(xs) === '[object Array]'
    67     }
    68 ;
    69 function indexOf (xs, x) {
    70     if (xs.indexOf) return xs.indexOf(x);
    71     for (var i = 0; i < xs.length; i++) {
    72         if (x === xs[i]) return i;
    73     }
    74     return -1;
    75 }
    77 // By default EventEmitters will print a warning if more than
    78 // 10 listeners are added to it. This is a useful default which
    79 // helps finding memory leaks.
    80 //
    81 // Obviously not all Emitters should be limited to 10. This function allows
    82 // that to be increased. Set to zero for unlimited.
    83 var defaultMaxListeners = 10;
    84 EventEmitter.prototype.setMaxListeners = function(n) {
    85   if (!this._events) this._events = {};
    86   this._events.maxListeners = n;
    87 };
    90 EventEmitter.prototype.emit = function(type) {
    91   // If there is no 'error' event listener then throw.
    92   if (type === 'error') {
    93     if (!this._events || !this._events.error ||
    94         (isArray(this._events.error) && !this._events.error.length))
    95     {
    96       if (arguments[1] instanceof Error) {
    97         throw arguments[1]; // Unhandled 'error' event
    98       } else {
    99         throw new Error("Uncaught, unspecified 'error' event.");
   100       }
   101       return false;
   102     }
   103   }
   105   if (!this._events) return false;
   106   var handler = this._events[type];
   107   if (!handler) return false;
   109   if (typeof handler == 'function') {
   110     switch (arguments.length) {
   111       // fast cases
   112       case 1:
   113         handler.call(this);
   114         break;
   115       case 2:
   116         handler.call(this, arguments[1]);
   117         break;
   118       case 3:
   119         handler.call(this, arguments[1], arguments[2]);
   120         break;
   121       // slower
   122       default:
   123         var args = Array.prototype.slice.call(arguments, 1);
   124         handler.apply(this, args);
   125     }
   126     return true;
   128   } else if (isArray(handler)) {
   129     var args = Array.prototype.slice.call(arguments, 1);
   131     var listeners = handler.slice();
   132     for (var i = 0, l = listeners.length; i < l; i++) {
   133       listeners[i].apply(this, args);
   134     }
   135     return true;
   137   } else {
   138     return false;
   139   }
   140 };
   142 // EventEmitter is defined in src/node_events.cc
   143 // EventEmitter.prototype.emit() is also defined there.
   144 EventEmitter.prototype.addListener = function(type, listener) {
   145   if ('function' !== typeof listener) {
   146     throw new Error('addListener only takes instances of Function');
   147   }
   149   if (!this._events) this._events = {};
   151   // To avoid recursion in the case that type == "newListeners"! Before
   152   // adding it to the listeners, first emit "newListeners".
   153   this.emit('newListener', type, listener);
   155   if (!this._events[type]) {
   156     // Optimize the case of one listener. Don't need the extra array object.
   157     this._events[type] = listener;
   158   } else if (isArray(this._events[type])) {
   160     // Check for listener leak
   161     if (!this._events[type].warned) {
   162       var m;
   163       if (this._events.maxListeners !== undefined) {
   164         m = this._events.maxListeners;
   165       } else {
   166         m = defaultMaxListeners;
   167       }
   169       if (m && m > 0 && this._events[type].length > m) {
   170         this._events[type].warned = true;
   171         console.error('(node) warning: possible EventEmitter memory ' +
   172                       'leak detected. %d listeners added. ' +
   173                       'Use emitter.setMaxListeners() to increase limit.',
   174                       this._events[type].length);
   175         console.trace();
   176       }
   177     }
   179     // If we've already got an array, just append.
   180     this._events[type].push(listener);
   181   } else {
   182     // Adding the second element, need to change to array.
   183     this._events[type] = [this._events[type], listener];
   184   }
   186   return this;
   187 };
   189 EventEmitter.prototype.on = EventEmitter.prototype.addListener;
   191 EventEmitter.prototype.once = function(type, listener) {
   192   var self = this;
   193   self.on(type, function g() {
   194     self.removeListener(type, g);
   195     listener.apply(this, arguments);
   196   });
   198   return this;
   199 };
   201 EventEmitter.prototype.removeListener = function(type, listener) {
   202   if ('function' !== typeof listener) {
   203     throw new Error('removeListener only takes instances of Function');
   204   }
   206   // does not use listeners(), so no side effect of creating _events[type]
   207   if (!this._events || !this._events[type]) return this;
   209   var list = this._events[type];
   211   if (isArray(list)) {
   212     var i = indexOf(list, listener);
   213     if (i < 0) return this;
   214     list.splice(i, 1);
   215     if (list.length == 0)
   216       delete this._events[type];
   217   } else if (this._events[type] === listener) {
   218     delete this._events[type];
   219   }
   221   return this;
   222 };
   224 EventEmitter.prototype.removeAllListeners = function(type) {
   225   if (arguments.length === 0) {
   226     this._events = {};
   227     return this;
   228   }
   230   // does not use listeners(), so no side effect of creating _events[type]
   231   if (type && this._events && this._events[type]) this._events[type] = null;
   232   return this;
   233 };
   235 EventEmitter.prototype.listeners = function(type) {
   236   if (!this._events) this._events = {};
   237   if (!this._events[type]) this._events[type] = [];
   238   if (!isArray(this._events[type])) {
   239     this._events[type] = [this._events[type]];
   240   }
   241   return this._events[type];
   242 };
   244 })(require("__browserify_process"))
   245 },{"__browserify_process":1}],3:[function(require,module,exports){
   246 (function(){// jshint -W001
   248 "use strict";
   250 // Identifiers provided by the ECMAScript standard.
   252 exports.reservedVars = {
   253 	arguments : false,
   254 	NaN       : false
   255 };
   257 exports.ecmaIdentifiers = {
   258 	Array              : false,
   259 	Boolean            : false,
   260 	Date               : false,
   261 	decodeURI          : false,
   262 	decodeURIComponent : false,
   263 	encodeURI          : false,
   264 	encodeURIComponent : false,
   265 	Error              : false,
   266 	"eval"             : false,
   267 	EvalError          : false,
   268 	Function           : false,
   269 	hasOwnProperty     : false,
   270 	isFinite           : false,
   271 	isNaN              : false,
   272 	JSON               : false,
   273 	Math               : false,
   274 	Map                : false,
   275 	Number             : false,
   276 	Object             : false,
   277 	parseInt           : false,
   278 	parseFloat         : false,
   279 	RangeError         : false,
   280 	ReferenceError     : false,
   281 	RegExp             : false,
   282 	Set                : false,
   283 	String             : false,
   284 	SyntaxError        : false,
   285 	TypeError          : false,
   286 	URIError           : false,
   287 	WeakMap            : false
   288 };
   290 // Global variables commonly provided by a web browser environment.
   292 exports.browser = {
   293 	ArrayBuffer          : false,
   294 	ArrayBufferView      : false,
   295 	Audio                : false,
   296 	Blob                 : false,
   297 	addEventListener     : false,
   298 	applicationCache     : false,
   299 	atob                 : false,
   300 	blur                 : false,
   301 	btoa                 : false,
   302 	clearInterval        : false,
   303 	clearTimeout         : false,
   304 	close                : false,
   305 	closed               : false,
   306 	DataView             : false,
   307 	DOMParser            : false,
   308 	defaultStatus        : false,
   309 	document             : false,
   310 	Element              : false,
   311 	ElementTimeControl   : false,
   312 	event                : false,
   313 	FileReader           : false,
   314 	Float32Array         : false,
   315 	Float64Array         : false,
   316 	FormData             : false,
   317 	focus                : false,
   318 	frames               : false,
   319 	getComputedStyle     : false,
   320 	HTMLElement          : false,
   321 	HTMLAnchorElement    : false,
   322 	HTMLBaseElement      : false,
   323 	HTMLBlockquoteElement: false,
   324 	HTMLBodyElement      : false,
   325 	HTMLBRElement        : false,
   326 	HTMLButtonElement    : false,
   327 	HTMLCanvasElement    : false,
   328 	HTMLDirectoryElement : false,
   329 	HTMLDivElement       : false,
   330 	HTMLDListElement     : false,
   331 	HTMLFieldSetElement  : false,
   332 	HTMLFontElement      : false,
   333 	HTMLFormElement      : false,
   334 	HTMLFrameElement     : false,
   335 	HTMLFrameSetElement  : false,
   336 	HTMLHeadElement      : false,
   337 	HTMLHeadingElement   : false,
   338 	HTMLHRElement        : false,
   339 	HTMLHtmlElement      : false,
   340 	HTMLIFrameElement    : false,
   341 	HTMLImageElement     : false,
   342 	HTMLInputElement     : false,
   343 	HTMLIsIndexElement   : false,
   344 	HTMLLabelElement     : false,
   345 	HTMLLayerElement     : false,
   346 	HTMLLegendElement    : false,
   347 	HTMLLIElement        : false,
   348 	HTMLLinkElement      : false,
   349 	HTMLMapElement       : false,
   350 	HTMLMenuElement      : false,
   351 	HTMLMetaElement      : false,
   352 	HTMLModElement       : false,
   353 	HTMLObjectElement    : false,
   354 	HTMLOListElement     : false,
   355 	HTMLOptGroupElement  : false,
   356 	HTMLOptionElement    : false,
   357 	HTMLParagraphElement : false,
   358 	HTMLParamElement     : false,
   359 	HTMLPreElement       : false,
   360 	HTMLQuoteElement     : false,
   361 	HTMLScriptElement    : false,
   362 	HTMLSelectElement    : false,
   363 	HTMLStyleElement     : false,
   364 	HTMLTableCaptionElement: false,
   365 	HTMLTableCellElement : false,
   366 	HTMLTableColElement  : false,
   367 	HTMLTableElement     : false,
   368 	HTMLTableRowElement  : false,
   369 	HTMLTableSectionElement: false,
   370 	HTMLTextAreaElement  : false,
   371 	HTMLTitleElement     : false,
   372 	HTMLUListElement     : false,
   373 	HTMLVideoElement     : false,
   374 	history              : false,
   375 	Int16Array           : false,
   376 	Int32Array           : false,
   377 	Int8Array            : false,
   378 	Image                : false,
   379 	length               : false,
   380 	localStorage         : false,
   381 	location             : false,
   382 	MessageChannel       : false,
   383 	MessageEvent         : false,
   384 	MessagePort          : false,
   385 	moveBy               : false,
   386 	moveTo               : false,
   387 	MutationObserver     : false,
   388 	name                 : false,
   389 	Node                 : false,
   390 	NodeFilter           : false,
   391 	navigator            : false,
   392 	onbeforeunload       : true,
   393 	onblur               : true,
   394 	onerror              : true,
   395 	onfocus              : true,
   396 	onload               : true,
   397 	onresize             : true,
   398 	onunload             : true,
   399 	open                 : false,
   400 	openDatabase         : false,
   401 	opener               : false,
   402 	Option               : false,
   403 	parent               : false,
   404 	print                : false,
   405 	removeEventListener  : false,
   406 	resizeBy             : false,
   407 	resizeTo             : false,
   408 	screen               : false,
   409 	scroll               : false,
   410 	scrollBy             : false,
   411 	scrollTo             : false,
   412 	sessionStorage       : false,
   413 	setInterval          : false,
   414 	setTimeout           : false,
   415 	SharedWorker         : false,
   416 	status               : false,
   417 	SVGAElement          : false,
   418 	SVGAltGlyphDefElement: false,
   419 	SVGAltGlyphElement   : false,
   420 	SVGAltGlyphItemElement: false,
   421 	SVGAngle             : false,
   422 	SVGAnimateColorElement: false,
   423 	SVGAnimateElement    : false,
   424 	SVGAnimateMotionElement: false,
   425 	SVGAnimateTransformElement: false,
   426 	SVGAnimatedAngle     : false,
   427 	SVGAnimatedBoolean   : false,
   428 	SVGAnimatedEnumeration: false,
   429 	SVGAnimatedInteger   : false,
   430 	SVGAnimatedLength    : false,
   431 	SVGAnimatedLengthList: false,
   432 	SVGAnimatedNumber    : false,
   433 	SVGAnimatedNumberList: false,
   434 	SVGAnimatedPathData  : false,
   435 	SVGAnimatedPoints    : false,
   436 	SVGAnimatedPreserveAspectRatio: false,
   437 	SVGAnimatedRect      : false,
   438 	SVGAnimatedString    : false,
   439 	SVGAnimatedTransformList: false,
   440 	SVGAnimationElement  : false,
   441 	SVGCSSRule           : false,
   442 	SVGCircleElement     : false,
   443 	SVGClipPathElement   : false,
   444 	SVGColor             : false,
   445 	SVGColorProfileElement: false,
   446 	SVGColorProfileRule  : false,
   447 	SVGComponentTransferFunctionElement: false,
   448 	SVGCursorElement     : false,
   449 	SVGDefsElement       : false,
   450 	SVGDescElement       : false,
   451 	SVGDocument          : false,
   452 	SVGElement           : false,
   453 	SVGElementInstance   : false,
   454 	SVGElementInstanceList: false,
   455 	SVGEllipseElement    : false,
   456 	SVGExternalResourcesRequired: false,
   457 	SVGFEBlendElement    : false,
   458 	SVGFEColorMatrixElement: false,
   459 	SVGFEComponentTransferElement: false,
   460 	SVGFECompositeElement: false,
   461 	SVGFEConvolveMatrixElement: false,
   462 	SVGFEDiffuseLightingElement: false,
   463 	SVGFEDisplacementMapElement: false,
   464 	SVGFEDistantLightElement: false,
   465 	SVGFEDropShadowElement: false,
   466 	SVGFEFloodElement    : false,
   467 	SVGFEFuncAElement    : false,
   468 	SVGFEFuncBElement    : false,
   469 	SVGFEFuncGElement    : false,
   470 	SVGFEFuncRElement    : false,
   471 	SVGFEGaussianBlurElement: false,
   472 	SVGFEImageElement    : false,
   473 	SVGFEMergeElement    : false,
   474 	SVGFEMergeNodeElement: false,
   475 	SVGFEMorphologyElement: false,
   476 	SVGFEOffsetElement   : false,
   477 	SVGFEPointLightElement: false,
   478 	SVGFESpecularLightingElement: false,
   479 	SVGFESpotLightElement: false,
   480 	SVGFETileElement     : false,
   481 	SVGFETurbulenceElement: false,
   482 	SVGFilterElement     : false,
   483 	SVGFilterPrimitiveStandardAttributes: false,
   484 	SVGFitToViewBox      : false,
   485 	SVGFontElement       : false,
   486 	SVGFontFaceElement   : false,
   487 	SVGFontFaceFormatElement: false,
   488 	SVGFontFaceNameElement: false,
   489 	SVGFontFaceSrcElement: false,
   490 	SVGFontFaceUriElement: false,
   491 	SVGForeignObjectElement: false,
   492 	SVGGElement          : false,
   493 	SVGGlyphElement      : false,
   494 	SVGGlyphRefElement   : false,
   495 	SVGGradientElement   : false,
   496 	SVGHKernElement      : false,
   497 	SVGICCColor          : false,
   498 	SVGImageElement      : false,
   499 	SVGLangSpace         : false,
   500 	SVGLength            : false,
   501 	SVGLengthList        : false,
   502 	SVGLineElement       : false,
   503 	SVGLinearGradientElement: false,
   504 	SVGLocatable         : false,
   505 	SVGMPathElement      : false,
   506 	SVGMarkerElement     : false,
   507 	SVGMaskElement       : false,
   508 	SVGMatrix            : false,
   509 	SVGMetadataElement   : false,
   510 	SVGMissingGlyphElement: false,
   511 	SVGNumber            : false,
   512 	SVGNumberList        : false,
   513 	SVGPaint             : false,
   514 	SVGPathElement       : false,
   515 	SVGPathSeg           : false,
   516 	SVGPathSegArcAbs     : false,
   517 	SVGPathSegArcRel     : false,
   518 	SVGPathSegClosePath  : false,
   519 	SVGPathSegCurvetoCubicAbs: false,
   520 	SVGPathSegCurvetoCubicRel: false,
   521 	SVGPathSegCurvetoCubicSmoothAbs: false,
   522 	SVGPathSegCurvetoCubicSmoothRel: false,
   523 	SVGPathSegCurvetoQuadraticAbs: false,
   524 	SVGPathSegCurvetoQuadraticRel: false,
   525 	SVGPathSegCurvetoQuadraticSmoothAbs: false,
   526 	SVGPathSegCurvetoQuadraticSmoothRel: false,
   527 	SVGPathSegLinetoAbs  : false,
   528 	SVGPathSegLinetoHorizontalAbs: false,
   529 	SVGPathSegLinetoHorizontalRel: false,
   530 	SVGPathSegLinetoRel  : false,
   531 	SVGPathSegLinetoVerticalAbs: false,
   532 	SVGPathSegLinetoVerticalRel: false,
   533 	SVGPathSegList       : false,
   534 	SVGPathSegMovetoAbs  : false,
   535 	SVGPathSegMovetoRel  : false,
   536 	SVGPatternElement    : false,
   537 	SVGPoint             : false,
   538 	SVGPointList         : false,
   539 	SVGPolygonElement    : false,
   540 	SVGPolylineElement   : false,
   541 	SVGPreserveAspectRatio: false,
   542 	SVGRadialGradientElement: false,
   543 	SVGRect              : false,
   544 	SVGRectElement       : false,
   545 	SVGRenderingIntent   : false,
   546 	SVGSVGElement        : false,
   547 	SVGScriptElement     : false,
   548 	SVGSetElement        : false,
   549 	SVGStopElement       : false,
   550 	SVGStringList        : false,
   551 	SVGStylable          : false,
   552 	SVGStyleElement      : false,
   553 	SVGSwitchElement     : false,
   554 	SVGSymbolElement     : false,
   555 	SVGTRefElement       : false,
   556 	SVGTSpanElement      : false,
   557 	SVGTests             : false,
   558 	SVGTextContentElement: false,
   559 	SVGTextElement       : false,
   560 	SVGTextPathElement   : false,
   561 	SVGTextPositioningElement: false,
   562 	SVGTitleElement      : false,
   563 	SVGTransform         : false,
   564 	SVGTransformList     : false,
   565 	SVGTransformable     : false,
   566 	SVGURIReference      : false,
   567 	SVGUnitTypes         : false,
   568 	SVGUseElement        : false,
   569 	SVGVKernElement      : false,
   570 	SVGViewElement       : false,
   571 	SVGViewSpec          : false,
   572 	SVGZoomAndPan        : false,
   573 	TimeEvent            : false,
   574 	top                  : false,
   575 	Uint16Array          : false,
   576 	Uint32Array          : false,
   577 	Uint8Array           : false,
   578 	Uint8ClampedArray    : false,
   579 	WebSocket            : false,
   580 	window               : false,
   581 	Worker               : false,
   582 	XMLHttpRequest       : false,
   583 	XMLSerializer        : false,
   584 	XPathEvaluator       : false,
   585 	XPathException       : false,
   586 	XPathExpression      : false,
   587 	XPathNSResolver      : false,
   588 	XPathResult          : false
   589 };
   591 exports.devel = {
   592 	alert  : false,
   593 	confirm: false,
   594 	console: false,
   595 	Debug  : false,
   596 	opera  : false,
   597 	prompt : false
   598 };
   600 exports.worker = {
   601 	importScripts: true,
   602 	postMessage  : true,
   603 	self         : true
   604 };
   606 // Widely adopted global names that are not part of ECMAScript standard
   607 exports.nonstandard = {
   608 	escape  : false,
   609 	unescape: false
   610 };
   612 // Globals provided by popular JavaScript environments.
   614 exports.couch = {
   615 	"require" : false,
   616 	respond   : false,
   617 	getRow    : false,
   618 	emit      : false,
   619 	send      : false,
   620 	start     : false,
   621 	sum       : false,
   622 	log       : false,
   623 	exports   : false,
   624 	module    : false,
   625 	provides  : false
   626 };
   628 exports.node = {
   629 	__filename    : false,
   630 	__dirname     : false,
   631 	Buffer        : false,
   632 	DataView      : false,
   633 	console       : false,
   634 	exports       : true,  // In Node it is ok to exports = module.exports = foo();
   635 	GLOBAL        : false,
   636 	global        : false,
   637 	module        : false,
   638 	process       : false,
   639 	require       : false,
   640 	setTimeout    : false,
   641 	clearTimeout  : false,
   642 	setInterval   : false,
   643 	clearInterval : false,
   644 	setImmediate  : false, // v0.9.1+
   645 	clearImmediate: false  // v0.9.1+
   646 };
   648 exports.phantom = {
   649 	phantom      : true,
   650 	require      : true,
   651 	WebPage      : true
   652 };
   654 exports.rhino = {
   655 	defineClass  : false,
   656 	deserialize  : false,
   657 	gc           : false,
   658 	help         : false,
   659 	importPackage: false,
   660 	"java"       : false,
   661 	load         : false,
   662 	loadClass    : false,
   663 	print        : false,
   664 	quit         : false,
   665 	readFile     : false,
   666 	readUrl      : false,
   667 	runCommand   : false,
   668 	seal         : false,
   669 	serialize    : false,
   670 	spawn        : false,
   671 	sync         : false,
   672 	toint32      : false,
   673 	version      : false
   674 };
   676 exports.wsh = {
   677 	ActiveXObject            : true,
   678 	Enumerator               : true,
   679 	GetObject                : true,
   680 	ScriptEngine             : true,
   681 	ScriptEngineBuildVersion : true,
   682 	ScriptEngineMajorVersion : true,
   683 	ScriptEngineMinorVersion : true,
   684 	VBArray                  : true,
   685 	WSH                      : true,
   686 	WScript                  : true,
   687 	XDomainRequest           : true
   688 };
   690 // Globals provided by popular JavaScript libraries.
   692 exports.dojo = {
   693 	dojo     : false,
   694 	dijit    : false,
   695 	dojox    : false,
   696 	define	 : false,
   697 	"require": false
   698 };
   700 exports.jquery = {
   701 	"$"    : false,
   702 	jQuery : false
   703 };
   705 exports.mootools = {
   706 	"$"           : false,
   707 	"$$"          : false,
   708 	Asset         : false,
   709 	Browser       : false,
   710 	Chain         : false,
   711 	Class         : false,
   712 	Color         : false,
   713 	Cookie        : false,
   714 	Core          : false,
   715 	Document      : false,
   716 	DomReady      : false,
   717 	DOMEvent      : false,
   718 	DOMReady      : false,
   719 	Drag          : false,
   720 	Element       : false,
   721 	Elements      : false,
   722 	Event         : false,
   723 	Events        : false,
   724 	Fx            : false,
   725 	Group         : false,
   726 	Hash          : false,
   727 	HtmlTable     : false,
   728 	Iframe        : false,
   729 	IframeShim    : false,
   730 	InputValidator: false,
   731 	instanceOf    : false,
   732 	Keyboard      : false,
   733 	Locale        : false,
   734 	Mask          : false,
   735 	MooTools      : false,
   736 	Native        : false,
   737 	Options       : false,
   738 	OverText      : false,
   739 	Request       : false,
   740 	Scroller      : false,
   741 	Slick         : false,
   742 	Slider        : false,
   743 	Sortables     : false,
   744 	Spinner       : false,
   745 	Swiff         : false,
   746 	Tips          : false,
   747 	Type          : false,
   748 	typeOf        : false,
   749 	URI           : false,
   750 	Window        : false
   751 };
   753 exports.prototypejs = {
   754 	"$"               : false,
   755 	"$$"              : false,
   756 	"$A"              : false,
   757 	"$F"              : false,
   758 	"$H"              : false,
   759 	"$R"              : false,
   760 	"$break"          : false,
   761 	"$continue"       : false,
   762 	"$w"              : false,
   763 	Abstract          : false,
   764 	Ajax              : false,
   765 	Class             : false,
   766 	Enumerable        : false,
   767 	Element           : false,
   768 	Event             : false,
   769 	Field             : false,
   770 	Form              : false,
   771 	Hash              : false,
   772 	Insertion         : false,
   773 	ObjectRange       : false,
   774 	PeriodicalExecuter: false,
   775 	Position          : false,
   776 	Prototype         : false,
   777 	Selector          : false,
   778 	Template          : false,
   779 	Toggle            : false,
   780 	Try               : false,
   781 	Autocompleter     : false,
   782 	Builder           : false,
   783 	Control           : false,
   784 	Draggable         : false,
   785 	Draggables        : false,
   786 	Droppables        : false,
   787 	Effect            : false,
   788 	Sortable          : false,
   789 	SortableObserver  : false,
   790 	Sound             : false,
   791 	Scriptaculous     : false
   792 };
   794 exports.yui = {
   795 	YUI       : false,
   796 	Y         : false,
   797 	YUI_config: false
   798 };
   801 })()
   802 },{}],4:[function(require,module,exports){
   803 "use strict";
   805 var state = {
   806 	syntax: {},
   808 	reset: function () {
   809 		this.tokens = {
   810 			prev: null,
   811 			next: null,
   812 			curr: null
   813 		};
   815 		this.option = {};
   816 		this.ignored = {};
   817 		this.directive = {};
   818 		this.jsonMode = false;
   819 		this.jsonWarnings = [];
   820 		this.lines = [];
   821 		this.tab = "";
   822 		this.cache = {}; // Node.JS doesn't have Map. Sniff.
   823 	}
   824 };
   826 exports.state = state;
   828 },{}],5:[function(require,module,exports){
   829 (function(){"use strict";
   831 exports.register = function (linter) {
   832 	// Check for properties named __proto__. This special property was
   833 	// deprecated and then re-introduced for ES6.
   835 	linter.on("Identifier", function style_scanProto(data) {
   836 		if (linter.getOption("proto")) {
   837 			return;
   838 		}
   840 		if (data.name === "__proto__") {
   841 			linter.warn("W103", {
   842 				line: data.line,
   843 				char: data.char,
   844 				data: [ data.name ]
   845 			});
   846 		}
   847 	});
   849 	// Check for properties named __iterator__. This is a special property
   850 	// available only in browsers with JavaScript 1.7 implementation.
   852 	linter.on("Identifier", function style_scanIterator(data) {
   853 		if (linter.getOption("iterator")) {
   854 			return;
   855 		}
   857 		if (data.name === "__iterator__") {
   858 			linter.warn("W104", {
   859 				line: data.line,
   860 				char: data.char,
   861 				data: [ data.name ]
   862 			});
   863 		}
   864 	});
   866 	// Check for dangling underscores.
   868 	linter.on("Identifier", function style_scanDangling(data) {
   869 		if (!linter.getOption("nomen")) {
   870 			return;
   871 		}
   873 		// Underscore.js
   874 		if (data.name === "_") {
   875 			return;
   876 		}
   878 		// In Node, __dirname and __filename should be ignored.
   879 		if (linter.getOption("node")) {
   880 			if (/^(__dirname|__filename)$/.test(data.name) && !data.isProperty) {
   881 				return;
   882 			}
   883 		}
   885 		if (/^(_+.*|.*_+)$/.test(data.name)) {
   886 			linter.warn("W105", {
   887 				line: data.line,
   888 				char: data.from,
   889 				data: [ "dangling '_'", data.name ]
   890 			});
   891 		}
   892 	});
   894 	// Check that all identifiers are using camelCase notation.
   895 	// Exceptions: names like MY_VAR and _myVar.
   897 	linter.on("Identifier", function style_scanCamelCase(data) {
   898 		if (!linter.getOption("camelcase")) {
   899 			return;
   900 		}
   902 		if (data.name.replace(/^_+/, "").indexOf("_") > -1 && !data.name.match(/^[A-Z0-9_]*$/)) {
   903 			linter.warn("W106", {
   904 				line: data.line,
   905 				char: data.from,
   906 				data: [ data.name ]
   907 			});
   908 		}
   909 	});
   911 	// Enforce consistency in style of quoting.
   913 	linter.on("String", function style_scanQuotes(data) {
   914 		var quotmark = linter.getOption("quotmark");
   915 		var code;
   917 		if (!quotmark) {
   918 			return;
   919 		}
   921 		// If quotmark is set to 'single' warn about all double-quotes.
   923 		if (quotmark === "single" && data.quote !== "'") {
   924 			code = "W109";
   925 		}
   927 		// If quotmark is set to 'double' warn about all single-quotes.
   929 		if (quotmark === "double" && data.quote !== "\"") {
   930 			code = "W108";
   931 		}
   933 		// If quotmark is set to true, remember the first quotation style
   934 		// and then warn about all others.
   936 		if (quotmark === true) {
   937 			if (!linter.getCache("quotmark")) {
   938 				linter.setCache("quotmark", data.quote);
   939 			}
   941 			if (linter.getCache("quotmark") !== data.quote) {
   942 				code = "W110";
   943 			}
   944 		}
   946 		if (code) {
   947 			linter.warn(code, {
   948 				line: data.line,
   949 				char: data.char,
   950 			});
   951 		}
   952 	});
   954 	linter.on("Number", function style_scanNumbers(data) {
   955 		if (data.value.charAt(0) === ".") {
   956 			// Warn about a leading decimal point.
   957 			linter.warn("W008", {
   958 				line: data.line,
   959 				char: data.char,
   960 				data: [ data.value ]
   961 			});
   962 		}
   964 		if (data.value.substr(data.value.length - 1) === ".") {
   965 			// Warn about a trailing decimal point.
   966 			linter.warn("W047", {
   967 				line: data.line,
   968 				char: data.char,
   969 				data: [ data.value ]
   970 			});
   971 		}
   973 		if (/^00+/.test(data.value)) {
   974 			// Multiple leading zeroes.
   975 			linter.warn("W046", {
   976 				line: data.line,
   977 				char: data.char,
   978 				data: [ data.value ]
   979 			});
   980 		}
   981 	});
   983 	// Warn about script URLs.
   985 	linter.on("String", function style_scanJavaScriptURLs(data) {
   986 		var re = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i;
   988 		if (linter.getOption("scripturl")) {
   989 			return;
   990 		}
   992 		if (re.test(data.value)) {
   993 			linter.warn("W107", {
   994 				line: data.line,
   995 				char: data.char
   996 			});
   997 		}
   998 	});
   999 };
  1000 })()
  1001 },{}],6:[function(require,module,exports){
  1002 /*
  1003  * Regular expressions. Some of these are stupidly long.
  1004  */
  1006 /*jshint maxlen:1000 */
  1008 "use string";
  1010 // Unsafe comment or string (ax)
  1011 exports.unsafeString =
  1012 	/@cc|<\/?|script|\]\s*\]|<\s*!|&lt/i;
  1014 // Unsafe characters that are silently deleted by one or more browsers (cx)
  1015 exports.unsafeChars =
  1016 	/[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
  1018 // Characters in strings that need escaping (nx and nxg)
  1019 exports.needEsc =
  1020 	/[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
  1022 exports.needEscGlobal =
  1023 	/[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
  1025 // Star slash (lx)
  1026 exports.starSlash = /\*\//;
  1028 // Identifier (ix)
  1029 exports.identifier = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/;
  1031 // JavaScript URL (jx)
  1032 exports.javascriptURL = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i;
  1034 // Catches /* falls through */ comments (ft)
  1035 //exports.fallsThrough = /^\s*\/\*\s*falls?\sthrough\s*\*\/\s*$/;
  1036 exports.fallsThrough = /^\s*\/\/\s*Falls?\sthrough.*\s*$/;
  1038 },{}],7:[function(require,module,exports){
  1039 (function(global){/*global window, global*/
  1040 var util = require("util")
  1041 var assert = require("assert")
  1043 var slice = Array.prototype.slice
  1044 var console
  1045 var times = {}
  1047 if (typeof global !== "undefined" && global.console) {
  1048     console = global.console
  1049 } else if (typeof window !== "undefined" && window.console) {
  1050     console = window.console
  1051 } else {
  1052     console = window.console = {}
  1055 var functions = [
  1056     [log, "log"]
  1057     , [info, "info"]
  1058     , [warn, "warn"]
  1059     , [error, "error"]
  1060     , [time, "time"]
  1061     , [timeEnd, "timeEnd"]
  1062     , [trace, "trace"]
  1063     , [dir, "dir"]
  1064     , [assert, "assert"]
  1067 for (var i = 0; i < functions.length; i++) {
  1068     var tuple = functions[i]
  1069     var f = tuple[0]
  1070     var name = tuple[1]
  1072     if (!console[name]) {
  1073         console[name] = f
  1077 module.exports = console
  1079 function log() {}
  1081 function info() {
  1082     console.log.apply(console, arguments)
  1085 function warn() {
  1086     console.log.apply(console, arguments)
  1089 function error() {
  1090     console.warn.apply(console, arguments)
  1093 function time(label) {
  1094     times[label] = Date.now()
  1097 function timeEnd(label) {
  1098     var time = times[label]
  1099     if (!time) {
  1100         throw new Error("No such label: " + label)
  1103     var duration = Date.now() - time
  1104     console.log(label + ": " + duration + "ms")
  1107 function trace() {
  1108     var err = new Error()
  1109     err.name = "Trace"
  1110     err.message = util.format.apply(null, arguments)
  1111     console.error(err.stack)
  1114 function dir(object) {
  1115     console.log(util.inspect(object) + "\n")
  1118 function assert(expression) {
  1119     if (!expression) {
  1120         var arr = slice.call(arguments, 1)
  1121         assert.ok(false, util.format.apply(null, arr))
  1125 })(window)
  1126 },{"util":8,"assert":9}],10:[function(require,module,exports){
  1127 (function(){/*
  1128  * Lexical analysis and token construction.
  1129  */
  1131 "use strict";
  1133 var _      = require("underscore");
  1134 var events = require("events");
  1135 var reg    = require("./reg.js");
  1136 var state  = require("./state.js").state;
  1138 // Some of these token types are from JavaScript Parser API
  1139 // while others are specific to JSHint parser.
  1140 // JS Parser API: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
  1142 var Token = {
  1143 	Identifier: 1,
  1144 	Punctuator: 2,
  1145 	NumericLiteral: 3,
  1146 	StringLiteral: 4,
  1147 	Comment: 5,
  1148 	Keyword: 6,
  1149 	NullLiteral: 7,
  1150 	BooleanLiteral: 8,
  1151 	RegExp: 9
  1152 };
  1154 // This is auto generated from the unicode tables.
  1155 // The tables are at:
  1156 // http://www.fileformat.info/info/unicode/category/Lu/list.htm
  1157 // http://www.fileformat.info/info/unicode/category/Ll/list.htm
  1158 // http://www.fileformat.info/info/unicode/category/Lt/list.htm
  1159 // http://www.fileformat.info/info/unicode/category/Lm/list.htm
  1160 // http://www.fileformat.info/info/unicode/category/Lo/list.htm
  1161 // http://www.fileformat.info/info/unicode/category/Nl/list.htm
  1163 var unicodeLetterTable = [
  1164 	170, 170, 181, 181, 186, 186, 192, 214,
  1165 	216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750,
  1166 	880, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908,
  1167 	910, 929, 931, 1013, 1015, 1153, 1162, 1319, 1329, 1366,
  1168 	1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1568, 1610,
  1169 	1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775,
  1170 	1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957,
  1171 	1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069,
  1172 	2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2308, 2361,
  1173 	2365, 2365, 2384, 2384, 2392, 2401, 2417, 2423, 2425, 2431,
  1174 	2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482,
  1175 	2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529,
  1176 	2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608,
  1177 	2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654,
  1178 	2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736,
  1179 	2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785,
  1180 	2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867,
  1181 	2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929,
  1182 	2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970,
  1183 	2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001,
  1184 	3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123,
  1185 	3125, 3129, 3133, 3133, 3160, 3161, 3168, 3169, 3205, 3212,
  1186 	3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261,
  1187 	3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344,
  1188 	3346, 3386, 3389, 3389, 3406, 3406, 3424, 3425, 3450, 3455,
  1189 	3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526,
  1190 	3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716,
  1191 	3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743,
  1192 	3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760,
  1193 	3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805,
  1194 	3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138,
  1195 	4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198,
  1196 	4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4304, 4346,
  1197 	4348, 4348, 4352, 4680, 4682, 4685, 4688, 4694, 4696, 4696,
  1198 	4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789,
  1199 	4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880,
  1200 	4882, 4885, 4888, 4954, 4992, 5007, 5024, 5108, 5121, 5740,
  1201 	5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900,
  1202 	5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000,
  1203 	6016, 6067, 6103, 6103, 6108, 6108, 6176, 6263, 6272, 6312,
  1204 	6314, 6314, 6320, 6389, 6400, 6428, 6480, 6509, 6512, 6516,
  1205 	6528, 6571, 6593, 6599, 6656, 6678, 6688, 6740, 6823, 6823,
  1206 	6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7104, 7141,
  1207 	7168, 7203, 7245, 7247, 7258, 7293, 7401, 7404, 7406, 7409,
  1208 	7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013,
  1209 	8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061,
  1210 	8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140,
  1211 	8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188,
  1212 	8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455,
  1213 	8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486,
  1214 	8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521,
  1215 	8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358,
  1216 	11360, 11492, 11499, 11502, 11520, 11557, 11568, 11621,
  1217 	11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694,
  1218 	11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726,
  1219 	11728, 11734, 11736, 11742, 11823, 11823, 12293, 12295,
  1220 	12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438,
  1221 	12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589,
  1222 	12593, 12686, 12704, 12730, 12784, 12799, 13312, 13312,
  1223 	19893, 19893, 19968, 19968, 40907, 40907, 40960, 42124,
  1224 	42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539,
  1225 	42560, 42606, 42623, 42647, 42656, 42735, 42775, 42783,
  1226 	42786, 42888, 42891, 42894, 42896, 42897, 42912, 42921,
  1227 	43002, 43009, 43011, 43013, 43015, 43018, 43020, 43042,
  1228 	43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259,
  1229 	43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442,
  1230 	43471, 43471, 43520, 43560, 43584, 43586, 43588, 43595,
  1231 	43616, 43638, 43642, 43642, 43648, 43695, 43697, 43697,
  1232 	43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714,
  1233 	43739, 43741, 43777, 43782, 43785, 43790, 43793, 43798,
  1234 	43808, 43814, 43816, 43822, 43968, 44002, 44032, 44032,
  1235 	55203, 55203, 55216, 55238, 55243, 55291, 63744, 64045,
  1236 	64048, 64109, 64112, 64217, 64256, 64262, 64275, 64279,
  1237 	64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316,
  1238 	64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433,
  1239 	64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019,
  1240 	65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370,
  1241 	65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495,
  1242 	65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594,
  1243 	65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786,
  1244 	65856, 65908, 66176, 66204, 66208, 66256, 66304, 66334,
  1245 	66352, 66378, 66432, 66461, 66464, 66499, 66504, 66511,
  1246 	66513, 66517, 66560, 66717, 67584, 67589, 67592, 67592,
  1247 	67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669,
  1248 	67840, 67861, 67872, 67897, 68096, 68096, 68112, 68115,
  1249 	68117, 68119, 68121, 68147, 68192, 68220, 68352, 68405,
  1250 	68416, 68437, 68448, 68466, 68608, 68680, 69635, 69687,
  1251 	69763, 69807, 73728, 74606, 74752, 74850, 77824, 78894,
  1252 	92160, 92728, 110592, 110593, 119808, 119892, 119894, 119964,
  1253 	119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980,
  1254 	119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069,
  1255 	120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121,
  1256 	120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144,
  1257 	120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570,
  1258 	120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686,
  1259 	120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779,
  1260 	131072, 131072, 173782, 173782, 173824, 173824, 177972, 177972,
  1261 	177984, 177984, 178205, 178205, 194560, 195101
  1262 ];
  1264 var identifierStartTable = [];
  1266 for (var i = 0; i < 128; i++) {
  1267 	identifierStartTable[i] =
  1268 		i === 36 ||           // $
  1269 		i >= 65 && i <= 90 || // A-Z
  1270 		i === 95 ||           // _
  1271 		i >= 97 && i <= 122;  // a-z
  1274 var identifierPartTable = [];
  1276 for (var i = 0; i < 128; i++) {
  1277 	identifierPartTable[i] =
  1278 		identifierStartTable[i] || // $, _, A-Z, a-z
  1279 		i >= 48 && i <= 57;        // 0-9
  1282 // Object that handles postponed lexing verifications that checks the parsed
  1283 // environment state.
  1285 function asyncTrigger() {
  1286 	var _checks = [];
  1288 	return {
  1289 		push: function (fn) {
  1290 			_checks.push(fn);
  1291 		},
  1293 		check: function () {
  1294 			for (var check in _checks) {
  1295 				_checks[check]();
  1298 			_checks.splice(0, _checks.length);
  1300 	};
  1303 /*
  1304  * Lexer for JSHint.
  1306  * This object does a char-by-char scan of the provided source code
  1307  * and produces a sequence of tokens.
  1309  *   var lex = new Lexer("var i = 0;");
  1310  *   lex.start();
  1311  *   lex.token(); // returns the next token
  1313  * You have to use the token() method to move the lexer forward
  1314  * but you don't have to use its return value to get tokens. In addition
  1315  * to token() method returning the next token, the Lexer object also
  1316  * emits events.
  1318  *   lex.on("Identifier", function (data) {
  1319  *     if (data.name.indexOf("_") >= 0) {
  1320  *       // Produce a warning.
  1321  *     }
  1322  *   });
  1324  * Note that the token() method returns tokens in a JSLint-compatible
  1325  * format while the event emitter uses a slightly modified version of
  1326  * Mozilla's JavaScript Parser API. Eventually, we will move away from
  1327  * JSLint format.
  1328  */
  1329 function Lexer(source) {
  1330 	var lines = source;
  1332 	if (typeof lines === "string") {
  1333 		lines = lines
  1334 			.replace(/\r\n/g, "\n")
  1335 			.replace(/\r/g, "\n")
  1336 			.split("\n");
  1339 	// If the first line is a shebang (#!), make it a blank and move on.
  1340 	// Shebangs are used by Node scripts.
  1342 	if (lines[0] && lines[0].substr(0, 2) === "#!") {
  1343 		lines[0] = "";
  1346 	this.emitter = new events.EventEmitter();
  1347 	this.source = source;
  1348 	this.lines = lines;
  1349 	this.prereg = true;
  1351 	this.line = 0;
  1352 	this.char = 1;
  1353 	this.from = 1;
  1354 	this.input = "";
  1356 	for (var i = 0; i < state.option.indent; i += 1) {
  1357 		state.tab += " ";
  1361 Lexer.prototype = {
  1362 	_lines: [],
  1364 	get lines() {
  1365 		this._lines = state.lines;
  1366 		return this._lines;
  1367 	},
  1369 	set lines(val) {
  1370 		this._lines = val;
  1371 		state.lines = this._lines;
  1372 	},
  1374 	/*
  1375 	 * Return the next i character without actually moving the
  1376 	 * char pointer.
  1377 	 */
  1378 	peek: function (i) {
  1379 		return this.input.charAt(i || 0);
  1380 	},
  1382 	/*
  1383 	 * Move the char pointer forward i times.
  1384 	 */
  1385 	skip: function (i) {
  1386 		i = i || 1;
  1387 		this.char += i;
  1388 		this.input = this.input.slice(i);
  1389 	},
  1391 	/*
  1392 	 * Subscribe to a token event. The API for this method is similar
  1393 	 * Underscore.js i.e. you can subscribe to multiple events with
  1394 	 * one call:
  1396 	 *   lex.on("Identifier Number", function (data) {
  1397 	 *     // ...
  1398 	 *   });
  1399 	 */
  1400 	on: function (names, listener) {
  1401 		names.split(" ").forEach(function (name) {
  1402 			this.emitter.on(name, listener);
  1403 		}.bind(this));
  1404 	},
  1406 	/*
  1407 	 * Trigger a token event. All arguments will be passed to each
  1408 	 * listener.
  1409 	 */
  1410 	trigger: function () {
  1411 		this.emitter.emit.apply(this.emitter, Array.prototype.slice.call(arguments));
  1412 	},
  1414 	/*
  1415 	 * Postpone a token event. the checking condition is set as
  1416 	 * last parameter, and the trigger function is called in a
  1417 	 * stored callback. To be later called using the check() function
  1418 	 * by the parser. This avoids parser's peek() to give the lexer
  1419 	 * a false context.
  1420 	 */
  1421 	triggerAsync: function (type, args, checks, fn) {
  1422 		checks.push(function () {
  1423 			if (fn()) {
  1424 				this.trigger(type, args);
  1426 		}.bind(this));
  1427 	},
  1429 	/*
  1430 	 * Extract a punctuator out of the next sequence of characters
  1431 	 * or return 'null' if its not possible.
  1433 	 * This method's implementation was heavily influenced by the
  1434 	 * scanPunctuator function in the Esprima parser's source code.
  1435 	 */
  1436 	scanPunctuator: function () {
  1437 		var ch1 = this.peek();
  1438 		var ch2, ch3, ch4;
  1440 		switch (ch1) {
  1441 		// Most common single-character punctuators
  1442 		case ".":
  1443 			if ((/^[0-9]$/).test(this.peek(1))) {
  1444 				return null;
  1446 			if (this.peek(1) === "." && this.peek(2) === ".") {
  1447 				return {
  1448 					type: Token.Punctuator,
  1449 					value: "..."
  1450 				};
  1452 			/* falls through */
  1453 		case "(":
  1454 		case ")":
  1455 		case ";":
  1456 		case ",":
  1457 		case "{":
  1458 		case "}":
  1459 		case "[":
  1460 		case "]":
  1461 		case ":":
  1462 		case "~":
  1463 		case "?":
  1464 			return {
  1465 				type: Token.Punctuator,
  1466 				value: ch1
  1467 			};
  1469 		// A pound sign (for Node shebangs)
  1470 		case "#":
  1471 			return {
  1472 				type: Token.Punctuator,
  1473 				value: ch1
  1474 			};
  1476 		// We're at the end of input
  1477 		case "":
  1478 			return null;
  1481 		// Peek more characters
  1483 		ch2 = this.peek(1);
  1484 		ch3 = this.peek(2);
  1485 		ch4 = this.peek(3);
  1487 		// 4-character punctuator: >>>=
  1489 		if (ch1 === ">" && ch2 === ">" && ch3 === ">" && ch4 === "=") {
  1490 			return {
  1491 				type: Token.Punctuator,
  1492 				value: ">>>="
  1493 			};
  1496 		// 3-character punctuators: === !== >>> <<= >>=
  1498 		if (ch1 === "=" && ch2 === "=" && ch3 === "=") {
  1499 			return {
  1500 				type: Token.Punctuator,
  1501 				value: "==="
  1502 			};
  1505 		if (ch1 === "!" && ch2 === "=" && ch3 === "=") {
  1506 			return {
  1507 				type: Token.Punctuator,
  1508 				value: "!=="
  1509 			};
  1512 		if (ch1 === ">" && ch2 === ">" && ch3 === ">") {
  1513 			return {
  1514 				type: Token.Punctuator,
  1515 				value: ">>>"
  1516 			};
  1519 		if (ch1 === "<" && ch2 === "<" && ch3 === "=") {
  1520 			return {
  1521 				type: Token.Punctuator,
  1522 				value: "<<="
  1523 			};
  1526 		if (ch1 === ">" && ch2 === ">" && ch3 === "=") {
  1527 			return {
  1528 				type: Token.Punctuator,
  1529 				value: ">>="
  1530 			};
  1533 		// Fat arrow punctuator
  1534 		if (ch1 === "=" && ch2 === ">") {
  1535 			return {
  1536 				type: Token.Punctuator,
  1537 				value: ch1 + ch2
  1538 			};
  1541 		// 2-character punctuators: <= >= == != ++ -- << >> && ||
  1542 		// += -= *= %= &= |= ^= (but not /=, see below)
  1543 		if (ch1 === ch2 && ("+-<>&|".indexOf(ch1) >= 0)) {
  1544 			return {
  1545 				type: Token.Punctuator,
  1546 				value: ch1 + ch2
  1547 			};
  1550 		if ("<>=!+-*%&|^".indexOf(ch1) >= 0) {
  1551 			if (ch2 === "=") {
  1552 				return {
  1553 					type: Token.Punctuator,
  1554 					value: ch1 + ch2
  1555 				};
  1558 			return {
  1559 				type: Token.Punctuator,
  1560 				value: ch1
  1561 			};
  1564 		// Special case: /=. We need to make sure that this is an
  1565 		// operator and not a regular expression.
  1567 		if (ch1 === "/") {
  1568 			if (ch2 === "=" && /\/=(?!(\S*\/[gim]?))/.test(this.input)) {
  1569 				// /= is not a part of a regular expression, return it as a
  1570 				// punctuator.
  1571 				return {
  1572 					type: Token.Punctuator,
  1573 					value: "/="
  1574 				};
  1577 			return {
  1578 				type: Token.Punctuator,
  1579 				value: "/"
  1580 			};
  1583 		return null;
  1584 	},
  1586 	/*
  1587 	 * Extract a comment out of the next sequence of characters and/or
  1588 	 * lines or return 'null' if its not possible. Since comments can
  1589 	 * span across multiple lines this method has to move the char
  1590 	 * pointer.
  1592 	 * In addition to normal JavaScript comments (// and /*) this method
  1593 	 * also recognizes JSHint- and JSLint-specific comments such as
  1594 	 * /*jshint, /*jslint, /*globals and so on.
  1595 	 */
  1596 	scanComments: function () {
  1597 		var ch1 = this.peek();
  1598 		var ch2 = this.peek(1);
  1599 		var rest = this.input.substr(2);
  1600 		var startLine = this.line;
  1601 		var startChar = this.char;
  1603 		// Create a comment token object and make sure it
  1604 		// has all the data JSHint needs to work with special
  1605 		// comments.
  1607 		function commentToken(label, body, opt) {
  1608 			var special = ["jshint", "jslint", "members", "member", "globals", "global", "exported"];
  1609 			var isSpecial = false;
  1610 			var value = label + body;
  1611 			var commentType = "plain";
  1612 			opt = opt || {};
  1614 			if (opt.isMultiline) {
  1615 				value += "*/";
  1618 			special.forEach(function (str) {
  1619 				if (isSpecial) {
  1620 					return;
  1623 				// Don't recognize any special comments other than jshint for single-line
  1624 				// comments. This introduced many problems with legit comments.
  1625 				if (label === "//" && str !== "jshint") {
  1626 					return;
  1629 				if (body.substr(0, str.length) === str) {
  1630 					isSpecial = true;
  1631 					label = label + str;
  1632 					body = body.substr(str.length);
  1635 				if (!isSpecial && body.charAt(0) === " " && body.substr(1, str.length) === str) {
  1636 					isSpecial = true;
  1637 					label = label + " " + str;
  1638 					body = body.substr(str.length + 1);
  1641 				if (!isSpecial) {
  1642 					return;
  1645 				switch (str) {
  1646 				case "member":
  1647 					commentType = "members";
  1648 					break;
  1649 				case "global":
  1650 					commentType = "globals";
  1651 					break;
  1652 				default:
  1653 					commentType = str;
  1655 			});
  1657 			return {
  1658 				type: Token.Comment,
  1659 				commentType: commentType,
  1660 				value: value,
  1661 				body: body,
  1662 				isSpecial: isSpecial,
  1663 				isMultiline: opt.isMultiline || false,
  1664 				isMalformed: opt.isMalformed || false
  1665 			};
  1668 		// End of unbegun comment. Raise an error and skip that input.
  1669 		if (ch1 === "*" && ch2 === "/") {
  1670 			this.trigger("error", {
  1671 				code: "E018",
  1672 				line: startLine,
  1673 				character: startChar
  1674 			});
  1676 			this.skip(2);
  1677 			return null;
  1680 		// Comments must start either with // or /*
  1681 		if (ch1 !== "/" || (ch2 !== "*" && ch2 !== "/")) {
  1682 			return null;
  1685 		// One-line comment
  1686 		if (ch2 === "/") {
  1687 			this.skip(this.input.length); // Skip to the EOL.
  1688 			return commentToken("//", rest);
  1691 		var body = "";
  1693 		/* Multi-line comment */
  1694 		if (ch2 === "*") {
  1695 			this.skip(2);
  1697 			while (this.peek() !== "*" || this.peek(1) !== "/") {
  1698 				if (this.peek() === "") { // End of Line
  1699 					body += "\n";
  1701 					// If we hit EOF and our comment is still unclosed,
  1702 					// trigger an error and end the comment implicitly.
  1703 					if (!this.nextLine()) {
  1704 						this.trigger("error", {
  1705 							code: "E017",
  1706 							line: startLine,
  1707 							character: startChar
  1708 						});
  1710 						return commentToken("/*", body, {
  1711 							isMultiline: true,
  1712 							isMalformed: true
  1713 						});
  1715 				} else {
  1716 					body += this.peek();
  1717 					this.skip();
  1721 			this.skip(2);
  1722 			return commentToken("/*", body, { isMultiline: true });
  1724 	},
  1726 	/*
  1727 	 * Extract a keyword out of the next sequence of characters or
  1728 	 * return 'null' if its not possible.
  1729 	 */
  1730 	scanKeyword: function () {
  1731 		var result = /^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input);
  1732 		var keywords = [
  1733 			"if", "in", "do", "var", "for", "new",
  1734 			"try", "let", "this", "else", "case",
  1735 			"void", "with", "enum", "while", "break",
  1736 			"catch", "throw", "const", "yield", "class",
  1737 			"super", "return", "typeof", "delete",
  1738 			"switch", "export", "import", "default",
  1739 			"finally", "extends", "function", "continue",
  1740 			"debugger", "instanceof"
  1741 		];
  1743 		if (result && keywords.indexOf(result[0]) >= 0) {
  1744 			return {
  1745 				type: Token.Keyword,
  1746 				value: result[0]
  1747 			};
  1750 		return null;
  1751 	},
  1753 	/*
  1754 	 * Extract a JavaScript identifier out of the next sequence of
  1755 	 * characters or return 'null' if its not possible. In addition,
  1756 	 * to Identifier this method can also produce BooleanLiteral
  1757 	 * (true/false) and NullLiteral (null).
  1758 	 */
  1759 	scanIdentifier: function () {
  1760 		var id = "";
  1761 		var index = 0;
  1762 		var type, char;
  1764 		// Detects any character in the Unicode categories "Uppercase
  1765 		// letter (Lu)", "Lowercase letter (Ll)", "Titlecase letter
  1766 		// (Lt)", "Modifier letter (Lm)", "Other letter (Lo)", or
  1767 		// "Letter number (Nl)".
  1768 		//
  1769 		// Both approach and unicodeLetterTable were borrowed from
  1770 		// Google's Traceur.
  1772 		function isUnicodeLetter(code) {
  1773 			for (var i = 0; i < unicodeLetterTable.length;) {
  1774 				if (code < unicodeLetterTable[i++]) {
  1775 					return false;
  1778 				if (code <= unicodeLetterTable[i++]) {
  1779 					return true;
  1783 			return false;
  1786 		function isHexDigit(str) {
  1787 			return (/^[0-9a-fA-F]$/).test(str);
  1790 		var readUnicodeEscapeSequence = function () {
  1791 			/*jshint validthis:true */
  1792 			index += 1;
  1794 			if (this.peek(index) !== "u") {
  1795 				return null;
  1798 			var ch1 = this.peek(index + 1);
  1799 			var ch2 = this.peek(index + 2);
  1800 			var ch3 = this.peek(index + 3);
  1801 			var ch4 = this.peek(index + 4);
  1802 			var code;
  1804 			if (isHexDigit(ch1) && isHexDigit(ch2) && isHexDigit(ch3) && isHexDigit(ch4)) {
  1805 				code = parseInt(ch1 + ch2 + ch3 + ch4, 16);
  1807 				if (isUnicodeLetter(code)) {
  1808 					index += 5;
  1809 					return "\\u" + ch1 + ch2 + ch3 + ch4;
  1812 				return null;
  1815 			return null;
  1816 		}.bind(this);
  1818 		var getIdentifierStart = function () {
  1819 			/*jshint validthis:true */
  1820 			var chr = this.peek(index);
  1821 			var code = chr.charCodeAt(0);
  1823 			if (code === 92) {
  1824 				return readUnicodeEscapeSequence();
  1827 			if (code < 128) {
  1828 				if (identifierStartTable[code]) {
  1829 					index += 1;
  1830 					return chr;
  1833 				return null;
  1836 			if (isUnicodeLetter(code)) {
  1837 				index += 1;
  1838 				return chr;
  1841 			return null;
  1842 		}.bind(this);
  1844 		var getIdentifierPart = function () {
  1845 			/*jshint validthis:true */
  1846 			var chr = this.peek(index);
  1847 			var code = chr.charCodeAt(0);
  1849 			if (code === 92) {
  1850 				return readUnicodeEscapeSequence();
  1853 			if (code < 128) {
  1854 				if (identifierPartTable[code]) {
  1855 					index += 1;
  1856 					return chr;
  1859 				return null;
  1862 			if (isUnicodeLetter(code)) {
  1863 				index += 1;
  1864 				return chr;
  1867 			return null;
  1868 		}.bind(this);
  1870 		char = getIdentifierStart();
  1871 		if (char === null) {
  1872 			return null;
  1875 		id = char;
  1876 		for (;;) {
  1877 			char = getIdentifierPart();
  1879 			if (char === null) {
  1880 				break;
  1883 			id += char;
  1886 		switch (id) {
  1887 		case "true":
  1888 		case "false":
  1889 			type = Token.BooleanLiteral;
  1890 			break;
  1891 		case "null":
  1892 			type = Token.NullLiteral;
  1893 			break;
  1894 		default:
  1895 			type = Token.Identifier;
  1898 		return {
  1899 			type: type,
  1900 			value: id
  1901 		};
  1902 	},
  1904 	/*
  1905 	 * Extract a numeric literal out of the next sequence of
  1906 	 * characters or return 'null' if its not possible. This method
  1907 	 * supports all numeric literals described in section 7.8.3
  1908 	 * of the EcmaScript 5 specification.
  1910 	 * This method's implementation was heavily influenced by the
  1911 	 * scanNumericLiteral function in the Esprima parser's source code.
  1912 	 */
  1913 	scanNumericLiteral: function () {
  1914 		var index = 0;
  1915 		var value = "";
  1916 		var length = this.input.length;
  1917 		var char = this.peek(index);
  1918 		var bad;
  1920 		function isDecimalDigit(str) {
  1921 			return (/^[0-9]$/).test(str);
  1924 		function isOctalDigit(str) {
  1925 			return (/^[0-7]$/).test(str);
  1928 		function isHexDigit(str) {
  1929 			return (/^[0-9a-fA-F]$/).test(str);
  1932 		function isIdentifierStart(ch) {
  1933 			return (ch === "$") || (ch === "_") || (ch === "\\") ||
  1934 				(ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z");
  1937 		// Numbers must start either with a decimal digit or a point.
  1939 		if (char !== "." && !isDecimalDigit(char)) {
  1940 			return null;
  1943 		if (char !== ".") {
  1944 			value = this.peek(index);
  1945 			index += 1;
  1946 			char = this.peek(index);
  1948 			if (value === "0") {
  1949 				// Base-16 numbers.
  1950 				if (char === "x" || char === "X") {
  1951 					index += 1;
  1952 					value += char;
  1954 					while (index < length) {
  1955 						char = this.peek(index);
  1956 						if (!isHexDigit(char)) {
  1957 							break;
  1959 						value += char;
  1960 						index += 1;
  1963 					if (value.length <= 2) { // 0x
  1964 						return {
  1965 							type: Token.NumericLiteral,
  1966 							value: value,
  1967 							isMalformed: true
  1968 						};
  1971 					if (index < length) {
  1972 						char = this.peek(index);
  1973 						if (isIdentifierStart(char)) {
  1974 							return null;
  1978 					return {
  1979 						type: Token.NumericLiteral,
  1980 						value: value,
  1981 						base: 16,
  1982 						isMalformed: false
  1983 					};
  1986 				// Base-8 numbers.
  1987 				if (isOctalDigit(char)) {
  1988 					index += 1;
  1989 					value += char;
  1990 					bad = false;
  1992 					while (index < length) {
  1993 						char = this.peek(index);
  1995 						// Numbers like '019' (note the 9) are not valid octals
  1996 						// but we still parse them and mark as malformed.
  1998 						if (isDecimalDigit(char)) {
  1999 							bad = true;
  2000 						} else if (!isOctalDigit(char)) {
  2001 							break;
  2003 						value += char;
  2004 						index += 1;
  2007 					if (index < length) {
  2008 						char = this.peek(index);
  2009 						if (isIdentifierStart(char)) {
  2010 							return null;
  2014 					return {
  2015 						type: Token.NumericLiteral,
  2016 						value: value,
  2017 						base: 8,
  2018 						isMalformed: false
  2019 					};
  2022 				// Decimal numbers that start with '0' such as '09' are illegal
  2023 				// but we still parse them and return as malformed.
  2025 				if (isDecimalDigit(char)) {
  2026 					index += 1;
  2027 					value += char;
  2031 			while (index < length) {
  2032 				char = this.peek(index);
  2033 				if (!isDecimalDigit(char)) {
  2034 					break;
  2036 				value += char;
  2037 				index += 1;
  2041 		// Decimal digits.
  2043 		if (char === ".") {
  2044 			value += char;
  2045 			index += 1;
  2047 			while (index < length) {
  2048 				char = this.peek(index);
  2049 				if (!isDecimalDigit(char)) {
  2050 					break;
  2052 				value += char;
  2053 				index += 1;
  2057 		// Exponent part.
  2059 		if (char === "e" || char === "E") {
  2060 			value += char;
  2061 			index += 1;
  2062 			char = this.peek(index);
  2064 			if (char === "+" || char === "-") {
  2065 				value += this.peek(index);
  2066 				index += 1;
  2069 			char = this.peek(index);
  2070 			if (isDecimalDigit(char)) {
  2071 				value += char;
  2072 				index += 1;
  2074 				while (index < length) {
  2075 					char = this.peek(index);
  2076 					if (!isDecimalDigit(char)) {
  2077 						break;
  2079 					value += char;
  2080 					index += 1;
  2082 			} else {
  2083 				return null;
  2087 		if (index < length) {
  2088 			char = this.peek(index);
  2089 			if (isIdentifierStart(char)) {
  2090 				return null;
  2094 		return {
  2095 			type: Token.NumericLiteral,
  2096 			value: value,
  2097 			base: 10,
  2098 			isMalformed: !isFinite(value)
  2099 		};
  2100 	},
  2102 	/*
  2103 	 * Extract a string out of the next sequence of characters and/or
  2104 	 * lines or return 'null' if its not possible. Since strings can
  2105 	 * span across multiple lines this method has to move the char
  2106 	 * pointer.
  2108 	 * This method recognizes pseudo-multiline JavaScript strings:
  2110 	 *   var str = "hello\
  2111 	 *   world";
  2112 	 */
  2113 	scanStringLiteral: function (checks) {
  2114 		/*jshint loopfunc:true */
  2115 		var quote = this.peek();
  2117 		// String must start with a quote.
  2118 		if (quote !== "\"" && quote !== "'") {
  2119 			return null;
  2122 		// In JSON strings must always use double quotes.
  2123 		this.triggerAsync("warning", {
  2124 			code: "W108",
  2125 			line: this.line,
  2126 			character: this.char // +1?
  2127 		}, checks, function () { return state.jsonMode && quote !== "\""; });
  2129 		var value = "";
  2130 		var startLine = this.line;
  2131 		var startChar = this.char;
  2132 		var allowNewLine = false;
  2134 		this.skip();
  2136 		while (this.peek() !== quote) {
  2137 			while (this.peek() === "") { // End Of Line
  2139 				// If an EOL is not preceded by a backslash, show a warning
  2140 				// and proceed like it was a legit multi-line string where
  2141 				// author simply forgot to escape the newline symbol.
  2142 				//
  2143 				// Another approach is to implicitly close a string on EOL
  2144 				// but it generates too many false positives.
  2146 				if (!allowNewLine) {
  2147 					this.trigger("warning", {
  2148 						code: "W112",
  2149 						line: this.line,
  2150 						character: this.char
  2151 					});
  2152 				} else {
  2153 					allowNewLine = false;
  2155 					// Otherwise show a warning if multistr option was not set.
  2156 					// For JSON, show warning no matter what.
  2158 					this.triggerAsync("warning", {
  2159 						code: "W043",
  2160 						line: this.line,
  2161 						character: this.char
  2162 					}, checks, function () { return !state.option.multistr; });
  2164 					this.triggerAsync("warning", {
  2165 						code: "W042",
  2166 						line: this.line,
  2167 						character: this.char
  2168 					}, checks, function () { return state.jsonMode && state.option.multistr; });
  2171 				// If we get an EOF inside of an unclosed string, show an
  2172 				// error and implicitly close it at the EOF point.
  2174 				if (!this.nextLine()) {
  2175 					this.trigger("error", {
  2176 						code: "E029",
  2177 						line: startLine,
  2178 						character: startChar
  2179 					});
  2181 					return {
  2182 						type: Token.StringLiteral,
  2183 						value: value,
  2184 						isUnclosed: true,
  2185 						quote: quote
  2186 					};
  2190 			allowNewLine = false;
  2191 			var char = this.peek();
  2192 			var jump = 1; // A length of a jump, after we're done
  2193 			              // parsing this character.
  2195 			if (char < " ") {
  2196 				// Warn about a control character in a string.
  2197 				this.trigger("warning", {
  2198 					code: "W113",
  2199 					line: this.line,
  2200 					character: this.char,
  2201 					data: [ "<non-printable>" ]
  2202 				});
  2205 			// Special treatment for some escaped characters.
  2207 			if (char === "\\") {
  2208 				this.skip();
  2209 				char = this.peek();
  2211 				switch (char) {
  2212 				case "'":
  2213 					this.triggerAsync("warning", {
  2214 						code: "W114",
  2215 						line: this.line,
  2216 						character: this.char,
  2217 						data: [ "\\'" ]
  2218 					}, checks, function () {return state.jsonMode; });
  2219 					break;
  2220 				case "b":
  2221 					char = "\b";
  2222 					break;
  2223 				case "f":
  2224 					char = "\f";
  2225 					break;
  2226 				case "n":
  2227 					char = "\n";
  2228 					break;
  2229 				case "r":
  2230 					char = "\r";
  2231 					break;
  2232 				case "t":
  2233 					char = "\t";
  2234 					break;
  2235 				case "0":
  2236 					char = "\0";
  2238 					// Octal literals fail in strict mode.
  2239 					// Check if the number is between 00 and 07.
  2240 					var n = parseInt(this.peek(1), 10);
  2241 					this.triggerAsync("warning", {
  2242 						code: "W115",
  2243 						line: this.line,
  2244 						character: this.char
  2245 					}, checks,
  2246 					function () { return n >= 0 && n <= 7 && state.directive["use strict"]; });
  2247 					break;
  2248 				case "u":
  2249 					char = String.fromCharCode(parseInt(this.input.substr(1, 4), 16));
  2250 					jump = 5;
  2251 					break;
  2252 				case "v":
  2253 					this.triggerAsync("warning", {
  2254 						code: "W114",
  2255 						line: this.line,
  2256 						character: this.char,
  2257 						data: [ "\\v" ]
  2258 					}, checks, function () { return state.jsonMode; });
  2260 					char = "\v";
  2261 					break;
  2262 				case "x":
  2263 					var	x = parseInt(this.input.substr(1, 2), 16);
  2265 					this.triggerAsync("warning", {
  2266 						code: "W114",
  2267 						line: this.line,
  2268 						character: this.char,
  2269 						data: [ "\\x-" ]
  2270 					}, checks, function () { return state.jsonMode; });
  2272 					char = String.fromCharCode(x);
  2273 					jump = 3;
  2274 					break;
  2275 				case "\\":
  2276 				case "\"":
  2277 				case "/":
  2278 					break;
  2279 				case "":
  2280 					allowNewLine = true;
  2281 					char = "";
  2282 					break;
  2283 				case "!":
  2284 					if (value.slice(value.length - 2) === "<") {
  2285 						break;
  2288 					/*falls through */
  2289 				default:
  2290 					// Weird escaping.
  2291 					this.trigger("warning", {
  2292 						code: "W044",
  2293 						line: this.line,
  2294 						character: this.char
  2295 					});
  2299 			value += char;
  2300 			this.skip(jump);
  2303 		this.skip();
  2304 		return {
  2305 			type: Token.StringLiteral,
  2306 			value: value,
  2307 			isUnclosed: false,
  2308 			quote: quote
  2309 		};
  2310 	},
  2312 	/*
  2313 	 * Extract a regular expression out of the next sequence of
  2314 	 * characters and/or lines or return 'null' if its not possible.
  2316 	 * This method is platform dependent: it accepts almost any
  2317 	 * regular expression values but then tries to compile and run
  2318 	 * them using system's RegExp object. This means that there are
  2319 	 * rare edge cases where one JavaScript engine complains about
  2320 	 * your regular expression while others don't.
  2321 	 */
  2322 	scanRegExp: function () {
  2323 		var index = 0;
  2324 		var length = this.input.length;
  2325 		var char = this.peek();
  2326 		var value = char;
  2327 		var body = "";
  2328 		var flags = [];
  2329 		var malformed = false;
  2330 		var isCharSet = false;
  2331 		var terminated;
  2333 		var scanUnexpectedChars = function () {
  2334 			// Unexpected control character
  2335 			if (char < " ") {
  2336 				malformed = true;
  2337 				this.trigger("warning", {
  2338 					code: "W048",
  2339 					line: this.line,
  2340 					character: this.char
  2341 				});
  2344 			// Unexpected escaped character
  2345 			if (char === "<") {
  2346 				malformed = true;
  2347 				this.trigger("warning", {
  2348 					code: "W049",
  2349 					line: this.line,
  2350 					character: this.char,
  2351 					data: [ char ]
  2352 				});
  2354 		}.bind(this);
  2356 		// Regular expressions must start with '/'
  2357 		if (!this.prereg || char !== "/") {
  2358 			return null;
  2361 		index += 1;
  2362 		terminated = false;
  2364 		// Try to get everything in between slashes. A couple of
  2365 		// cases aside (see scanUnexpectedChars) we don't really
  2366 		// care whether the resulting expression is valid or not.
  2367 		// We will check that later using the RegExp object.
  2369 		while (index < length) {
  2370 			char = this.peek(index);
  2371 			value += char;
  2372 			body += char;
  2374 			if (isCharSet) {
  2375 				if (char === "]") {
  2376 					if (this.peek(index - 1) !== "\\" || this.peek(index - 2) === "\\") {
  2377 						isCharSet = false;
  2381 				if (char === "\\") {
  2382 					index += 1;
  2383 					char = this.peek(index);
  2384 					body += char;
  2385 					value += char;
  2387 					scanUnexpectedChars();
  2390 				index += 1;
  2391 				continue;
  2394 			if (char === "\\") {
  2395 				index += 1;
  2396 				char = this.peek(index);
  2397 				body += char;
  2398 				value += char;
  2400 				scanUnexpectedChars();
  2402 				if (char === "/") {
  2403 					index += 1;
  2404 					continue;
  2407 				if (char === "[") {
  2408 					index += 1;
  2409 					continue;
  2413 			if (char === "[") {
  2414 				isCharSet = true;
  2415 				index += 1;
  2416 				continue;
  2419 			if (char === "/") {
  2420 				body = body.substr(0, body.length - 1);
  2421 				terminated = true;
  2422 				index += 1;
  2423 				break;
  2426 			index += 1;
  2429 		// A regular expression that was never closed is an
  2430 		// error from which we cannot recover.
  2432 		if (!terminated) {
  2433 			this.trigger("error", {
  2434 				code: "E015",
  2435 				line: this.line,
  2436 				character: this.from
  2437 			});
  2439 			return void this.trigger("fatal", {
  2440 				line: this.line,
  2441 				from: this.from
  2442 			});
  2445 		// Parse flags (if any).
  2447 		while (index < length) {
  2448 			char = this.peek(index);
  2449 			if (!/[gim]/.test(char)) {
  2450 				break;
  2452 			flags.push(char);
  2453 			value += char;
  2454 			index += 1;
  2457 		// Check regular expression for correctness.
  2459 		try {
  2460 			new RegExp(body, flags.join(""));
  2461 		} catch (err) {
  2462 			malformed = true;
  2463 			this.trigger("error", {
  2464 				code: "E016",
  2465 				line: this.line,
  2466 				character: this.char,
  2467 				data: [ err.message ] // Platform dependent!
  2468 			});
  2471 		return {
  2472 			type: Token.RegExp,
  2473 			value: value,
  2474 			flags: flags,
  2475 			isMalformed: malformed
  2476 		};
  2477 	},
  2479 	/*
  2480 	 * Scan for any occurence of mixed tabs and spaces. If smarttabs option
  2481 	 * is on, ignore tabs followed by spaces.
  2483 	 * Tabs followed by one space followed by a block comment are allowed.
  2484 	 */
  2485 	scanMixedSpacesAndTabs: function () {
  2486 		var at, match;
  2488 		if (state.option.smarttabs) {
  2489 			// Negative look-behind for "//"
  2490 			match = this.input.match(/(\/\/|^\s?\*)? \t/);
  2491 			at = match && !match[1] ? 0 : -1;
  2492 		} else {
  2493 			at = this.input.search(/ \t|\t [^\*]/);
  2496 		return at;
  2497 	},
  2499 	/*
  2500 	 * Scan for characters that get silently deleted by one or more browsers.
  2501 	 */
  2502 	scanUnsafeChars: function () {
  2503 		return this.input.search(reg.unsafeChars);
  2504 	},
  2506 	/*
  2507 	 * Produce the next raw token or return 'null' if no tokens can be matched.
  2508 	 * This method skips over all space characters.
  2509 	 */
  2510 	next: function (checks) {
  2511 		this.from = this.char;
  2513 		// Move to the next non-space character.
  2514 		var start;
  2515 		if (/\s/.test(this.peek())) {
  2516 			start = this.char;
  2518 			while (/\s/.test(this.peek())) {
  2519 				this.from += 1;
  2520 				this.skip();
  2523 			if (this.peek() === "") { // EOL
  2524 				if (!/^\s*$/.test(this.lines[this.line - 1]) && state.option.trailing) {
  2525 					this.trigger("warning", { code: "W102", line: this.line, character: start });
  2530 		// Methods that work with multi-line structures and move the
  2531 		// character pointer.
  2533 		var match = this.scanComments() ||
  2534 			this.scanStringLiteral(checks);
  2536 		if (match) {
  2537 			return match;
  2540 		// Methods that don't move the character pointer.
  2542 		match =
  2543 			this.scanRegExp() ||
  2544 			this.scanPunctuator() ||
  2545 			this.scanKeyword() ||
  2546 			this.scanIdentifier() ||
  2547 			this.scanNumericLiteral();
  2549 		if (match) {
  2550 			this.skip(match.value.length);
  2551 			return match;
  2554 		// No token could be matched, give up.
  2556 		return null;
  2557 	},
  2559 	/*
  2560 	 * Switch to the next line and reset all char pointers. Once
  2561 	 * switched, this method also checks for mixed spaces and tabs
  2562 	 * and other minor warnings.
  2563 	 */
  2564 	nextLine: function () {
  2565 		var char;
  2567 		if (this.line >= this.lines.length) {
  2568 			return false;
  2571 		this.input = this.lines[this.line];
  2572 		this.line += 1;
  2573 		this.char = 1;
  2574 		this.from = 1;
  2576 		char = this.scanMixedSpacesAndTabs();
  2577 		if (char >= 0) {
  2578 			this.trigger("warning", { code: "W099", line: this.line, character: char + 1 });
  2581 		this.input = this.input.replace(/\t/g, state.tab);
  2582 		char = this.scanUnsafeChars();
  2584 		if (char >= 0) {
  2585 			this.trigger("warning", { code: "W100", line: this.line, character: char });
  2588 		// If there is a limit on line length, warn when lines get too
  2589 		// long.
  2591 		if (state.option.maxlen && state.option.maxlen < this.input.length) {
  2592 			this.trigger("warning", { code: "W101", line: this.line, character: this.input.length });
  2595 		return true;
  2596 	},
  2598 	/*
  2599 	 * This is simply a synonym for nextLine() method with a friendlier
  2600 	 * public name.
  2601 	 */
  2602 	start: function () {
  2603 		this.nextLine();
  2604 	},
  2606 	/*
  2607 	 * Produce the next token. This function is called by advance() to get
  2608 	 * the next token. It retuns a token in a JSLint-compatible format.
  2609 	 */
  2610 	token: function () {
  2611 		/*jshint loopfunc:true */
  2612 		var checks = asyncTrigger();
  2613 		var token;
  2616 		function isReserved(token, isProperty) {
  2617 			if (!token.reserved) {
  2618 				return false;
  2621 			if (token.meta && token.meta.isFutureReservedWord) {
  2622 				// ES3 FutureReservedWord in an ES5 environment.
  2623 				if (state.option.inES5(true) && !token.meta.es5) {
  2624 					return false;
  2627 				// Some ES5 FutureReservedWord identifiers are active only
  2628 				// within a strict mode environment.
  2629 				if (token.meta.strictOnly) {
  2630 					if (!state.option.strict && !state.directive["use strict"]) {
  2631 						return false;
  2635 				if (isProperty) {
  2636 					return false;
  2640 			return true;
  2643 		// Produce a token object.
  2644 		var create = function (type, value, isProperty) {
  2645 			/*jshint validthis:true */
  2646 			var obj;
  2648 			if (type !== "(endline)" && type !== "(end)") {
  2649 				this.prereg = false;
  2652 			if (type === "(punctuator)") {
  2653 				switch (value) {
  2654 				case ".":
  2655 				case ")":
  2656 				case "~":
  2657 				case "#":
  2658 				case "]":
  2659 					this.prereg = false;
  2660 					break;
  2661 				default:
  2662 					this.prereg = true;
  2665 				obj = Object.create(state.syntax[value] || state.syntax["(error)"]);
  2668 			if (type === "(identifier)") {
  2669 				if (value === "return" || value === "case" || value === "typeof") {
  2670 					this.prereg = true;
  2673 				if (_.has(state.syntax, value)) {
  2674 					obj = Object.create(state.syntax[value] || state.syntax["(error)"]);
  2676 					// If this can't be a reserved keyword, reset the object.
  2677 					if (!isReserved(obj, isProperty && type === "(identifier)")) {
  2678 						obj = null;
  2683 			if (!obj) {
  2684 				obj = Object.create(state.syntax[type]);
  2687 			obj.identifier = (type === "(identifier)");
  2688 			obj.type = obj.type || type;
  2689 			obj.value = value;
  2690 			obj.line = this.line;
  2691 			obj.character = this.char;
  2692 			obj.from = this.from;
  2694 			if (isProperty && obj.identifier) {
  2695 				obj.isProperty = isProperty;
  2698 			obj.check = checks.check;
  2700 			return obj;
  2701 		}.bind(this);
  2703 		for (;;) {
  2704 			if (!this.input.length) {
  2705 				return create(this.nextLine() ? "(endline)" : "(end)", "");
  2708 			token = this.next(checks);
  2710 			if (!token) {
  2711 				if (this.input.length) {
  2712 					// Unexpected character.
  2713 					this.trigger("error", {
  2714 						code: "E024",
  2715 						line: this.line,
  2716 						character: this.char,
  2717 						data: [ this.peek() ]
  2718 					});
  2720 					this.input = "";
  2723 				continue;
  2726 			switch (token.type) {
  2727 			case Token.StringLiteral:
  2728 				this.triggerAsync("String", {
  2729 					line: this.line,
  2730 					char: this.char,
  2731 					from: this.from,
  2732 					value: token.value,
  2733 					quote: token.quote
  2734 				}, checks, function () { return true; });
  2736 				return create("(string)", token.value);
  2737 			case Token.Identifier:
  2738 				this.trigger("Identifier", {
  2739 					line: this.line,
  2740 					char: this.char,
  2741 					from: this.form,
  2742 					name: token.value,
  2743 					isProperty: state.tokens.curr.id === "."
  2744 				});
  2746 				/* falls through */
  2747 			case Token.Keyword:
  2748 			case Token.NullLiteral:
  2749 			case Token.BooleanLiteral:
  2750 				return create("(identifier)", token.value, state.tokens.curr.id === ".");
  2752 			case Token.NumericLiteral:
  2753 				if (token.isMalformed) {
  2754 					this.trigger("warning", {
  2755 						code: "W045",
  2756 						line: this.line,
  2757 						character: this.char,
  2758 						data: [ token.value ]
  2759 					});
  2762 				this.triggerAsync("warning", {
  2763 					code: "W114",
  2764 					line: this.line,
  2765 					character: this.char,
  2766 					data: [ "0x-" ]
  2767 				}, checks, function () { return token.base === 16 && state.jsonMode; });
  2769 				this.triggerAsync("warning", {
  2770 					code: "W115",
  2771 					line: this.line,
  2772 					character: this.char
  2773 				}, checks, function () {
  2774 					return state.directive["use strict"] && token.base === 8;
  2775 				});
  2777 				this.trigger("Number", {
  2778 					line: this.line,
  2779 					char: this.char,
  2780 					from: this.from,
  2781 					value: token.value,
  2782 					base: token.base,
  2783 					isMalformed: token.malformed
  2784 				});
  2786 				return create("(number)", token.value);
  2788 			case Token.RegExp:
  2789 				return create("(regexp)", token.value);
  2791 			case Token.Comment:
  2792 				state.tokens.curr.comment = true;
  2794 				if (token.isSpecial) {
  2795 					return {
  2796 						value: token.value,
  2797 						body: token.body,
  2798 						type: token.commentType,
  2799 						isSpecial: token.isSpecial,
  2800 						line: this.line,
  2801 						character: this.char,
  2802 						from: this.from
  2803 					};
  2806 				break;
  2808 			case "":
  2809 				break;
  2811 			default:
  2812 				return create("(punctuator)", token.value);
  2816 };
  2818 exports.Lexer = Lexer;
  2820 })()
  2821 },{"events":2,"./reg.js":6,"./state.js":4,"underscore":11}],"jshint":[function(require,module,exports){
  2822 module.exports=require('E/GbHF');
  2823 },{}],"E/GbHF":[function(require,module,exports){
  2824 (function(){/*!
  2825  * JSHint, by JSHint Community.
  2827  * This file (and this file only) is licensed under the same slightly modified
  2828  * MIT license that JSLint is. It stops evil-doers everywhere:
  2830  *	 Copyright (c) 2002 Douglas Crockford  (www.JSLint.com)
  2832  *	 Permission is hereby granted, free of charge, to any person obtaining
  2833  *	 a copy of this software and associated documentation files (the "Software"),
  2834  *	 to deal in the Software without restriction, including without limitation
  2835  *	 the rights to use, copy, modify, merge, publish, distribute, sublicense,
  2836  *	 and/or sell copies of the Software, and to permit persons to whom
  2837  *	 the Software is furnished to do so, subject to the following conditions:
  2839  *	 The above copyright notice and this permission notice shall be included
  2840  *	 in all copies or substantial portions of the Software.
  2842  *	 The Software shall be used for Good, not Evil.
  2844  *	 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  2845  *	 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  2846  *	 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  2847  *	 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  2848  *	 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  2849  *	 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  2850  *	 DEALINGS IN THE SOFTWARE.
  2852  */
  2854 /*jshint quotmark:double */
  2855 /*global console:true */
  2856 /*exported console */
  2858 var _        = require("underscore");
  2859 var events   = require("events");
  2860 var vars     = require("../shared/vars.js");
  2861 var messages = require("../shared/messages.js");
  2862 var Lexer    = require("./lex.js").Lexer;
  2863 var reg      = require("./reg.js");
  2864 var state    = require("./state.js").state;
  2865 var style    = require("./style.js");
  2867 // We need this module here because environments such as IE and Rhino
  2868 // don't necessarilly expose the 'console' API and browserify uses
  2869 // it to log things. It's a sad state of affair, really.
  2870 var console = require("console-browserify");
  2872 // We build the application inside a function so that we produce only a singleton
  2873 // variable. That function will be invoked immediately, and its return value is
  2874 // the JSHINT function itself.
  2876 var JSHINT = (function () {
  2877 	"use strict";
  2879 	var anonname, // The guessed name for anonymous functions.
  2880 		api, // Extension API
  2882 		// These are operators that should not be used with the ! operator.
  2883 		bang = {
  2884 			"<"  : true,
  2885 			"<=" : true,
  2886 			"==" : true,
  2887 			"===": true,
  2888 			"!==": true,
  2889 			"!=" : true,
  2890 			">"  : true,
  2891 			">=" : true,
  2892 			"+"  : true,
  2893 			"-"  : true,
  2894 			"*"  : true,
  2895 			"/"  : true,
  2896 			"%"  : true
  2897 		},
  2899 		// These are the JSHint boolean options.
  2900 		boolOptions = {
  2901 			asi         : true, // if automatic semicolon insertion should be tolerated
  2902 			bitwise     : true, // if bitwise operators should not be allowed
  2903 			boss        : true, // if advanced usage of assignments should be allowed
  2904 			browser     : true, // if the standard browser globals should be predefined
  2905 			camelcase   : true, // if identifiers should be required in camel case
  2906 			couch       : true, // if CouchDB globals should be predefined
  2907 			curly       : true, // if curly braces around all blocks should be required
  2908 			debug       : true, // if debugger statements should be allowed
  2909 			devel       : true, // if logging globals should be predefined (console, alert, etc.)
  2910 			dojo        : true, // if Dojo Toolkit globals should be predefined
  2911 			eqeqeq      : true, // if === should be required
  2912 			eqnull      : true, // if == null comparisons should be tolerated
  2913 			es3         : true, // if ES3 syntax should be allowed
  2914 			es5         : true, // if ES5 syntax should be allowed (is now set per default)
  2915 			esnext      : true, // if es.next specific syntax should be allowed
  2916 			moz         : true, // if mozilla specific syntax should be allowed
  2917 			evil        : true, // if eval should be allowed
  2918 			expr        : true, // if ExpressionStatement should be allowed as Programs
  2919 			forin       : true, // if for in statements must filter
  2920 			funcscope   : true, // if only function scope should be used for scope tests
  2921 			gcl         : true, // if JSHint should be compatible with Google Closure Linter
  2922 			globalstrict: true, // if global "use strict"; should be allowed (also enables 'strict')
  2923 			immed       : true, // if immediate invocations must be wrapped in parens
  2924 			iterator    : true, // if the `__iterator__` property should be allowed
  2925 			jquery      : true, // if jQuery globals should be predefined
  2926 			lastsemic   : true, // if semicolons may be ommitted for the trailing
  2927 			                    // statements inside of a one-line blocks.
  2928 			laxbreak    : true, // if line breaks should not be checked
  2929 			laxcomma    : true, // if line breaks should not be checked around commas
  2930 			loopfunc    : true, // if functions should be allowed to be defined within
  2931 			                    // loops
  2932 			mootools    : true, // if MooTools globals should be predefined
  2933 			multistr    : true, // allow multiline strings
  2934 			newcap      : true, // if constructor names must be capitalized
  2935 			noarg       : true, // if arguments.caller and arguments.callee should be
  2936 			                    // disallowed
  2937 			node        : true, // if the Node.js environment globals should be
  2938 			                    // predefined
  2939 			noempty     : true, // if empty blocks should be disallowed
  2940 			nonew       : true, // if using `new` for side-effects should be disallowed
  2941 			nonstandard : true, // if non-standard (but widely adopted) globals should
  2942 			                    // be predefined
  2943 			nomen       : true, // if names should be checked
  2944 			onevar      : true, // if only one var statement per function should be
  2945 			                    // allowed
  2946 			passfail    : true, // if the scan should stop on first error
  2947 			phantom     : true, // if PhantomJS symbols should be allowed
  2948 			plusplus    : true, // if increment/decrement should not be allowed
  2949 			proto       : true, // if the `__proto__` property should be allowed
  2950 			prototypejs : true, // if Prototype and Scriptaculous globals should be
  2951 			                    // predefined
  2952 			rhino       : true, // if the Rhino environment globals should be predefined
  2953 			undef       : true, // if variables should be declared before used
  2954 			scripturl   : true, // if script-targeted URLs should be tolerated
  2955 			shadow      : true, // if variable shadowing should be tolerated
  2956 			smarttabs   : true, // if smarttabs should be tolerated
  2957 			                    // (http://www.emacswiki.org/emacs/SmartTabs)
  2958 			strict      : true, // require the "use strict"; pragma
  2959 			sub         : true, // if all forms of subscript notation are tolerated
  2960 			supernew    : true, // if `new function () { ... };` and `new Object;`
  2961 			                    // should be tolerated
  2962 			trailing    : true, // if trailing whitespace rules apply
  2963 			validthis   : true, // if 'this' inside a non-constructor function is valid.
  2964 			                    // This is a function scoped option only.
  2965 			withstmt    : true, // if with statements should be allowed
  2966 			white       : true, // if strict whitespace rules apply
  2967 			worker      : true, // if Web Worker script symbols should be allowed
  2968 			wsh         : true, // if the Windows Scripting Host environment globals
  2969 			                    // should be predefined
  2970 			yui         : true, // YUI variables should be predefined
  2972 			// Obsolete options
  2973 			onecase     : true, // if one case switch statements should be allowed
  2974 			regexp      : true, // if the . should not be allowed in regexp literals
  2975 			regexdash   : true  // if unescaped first/last dash (-) inside brackets
  2976 			                    // should be tolerated
  2977 		},
  2979 		// These are the JSHint options that can take any value
  2980 		// (we use this object to detect invalid options)
  2981 		valOptions = {
  2982 			maxlen       : false,
  2983 			indent       : false,
  2984 			maxerr       : false,
  2985 			predef       : false,
  2986 			quotmark     : false, //'single'|'double'|true
  2987 			scope        : false,
  2988 			maxstatements: false, // {int} max statements per function
  2989 			maxdepth     : false, // {int} max nested block depth per function
  2990 			maxparams    : false, // {int} max params per function
  2991 			maxcomplexity: false, // {int} max cyclomatic complexity per function
  2992 			unused       : true,  // warn if variables are unused. Available options:
  2993 			                      //   false    - don't check for unused variables
  2994 			                      //   true     - "vars" + check last function param
  2995 			                      //   "vars"   - skip checking unused function params
  2996 			                      //   "strict" - "vars" + check all function params
  2997 			latedef      : false  // warn if the variable is used before its definition
  2998 			                      //   false    - don't emit any warnings
  2999 			                      //   true     - warn if any variable is used before its definition
  3000 			                      //   "nofunc" - warn for any variable but function declarations
  3001 		},
  3003 		// These are JSHint boolean options which are shared with JSLint
  3004 		// where the definition in JSHint is opposite JSLint
  3005 		invertedOptions = {
  3006 			bitwise : true,
  3007 			forin   : true,
  3008 			newcap  : true,
  3009 			nomen   : true,
  3010 			plusplus: true,
  3011 			regexp  : true,
  3012 			undef   : true,
  3013 			white   : true,
  3015 			// Inverted and renamed, use JSHint name here
  3016 			eqeqeq  : true,
  3017 			onevar  : true,
  3018 			strict  : true
  3019 		},
  3021 		// These are JSHint boolean options which are shared with JSLint
  3022 		// where the name has been changed but the effect is unchanged
  3023 		renamedOptions = {
  3024 			eqeq   : "eqeqeq",
  3025 			vars   : "onevar",
  3026 			windows: "wsh",
  3027 			sloppy : "strict"
  3028 		},
  3030 		declared, // Globals that were declared using /*global ... */ syntax.
  3031 		exported, // Variables that are used outside of the current file.
  3033 		functionicity = [
  3034 			"closure", "exception", "global", "label",
  3035 			"outer", "unused", "var"
  3036 		],
  3038 		funct, // The current function
  3039 		functions, // All of the functions
  3041 		global, // The global scope
  3042 		implied, // Implied globals
  3043 		inblock,
  3044 		indent,
  3045 		lookahead,
  3046 		lex,
  3047 		member,
  3048 		membersOnly,
  3049 		noreach,
  3050 		predefined,		// Global variables defined by option
  3052 		scope,  // The current scope
  3053 		stack,
  3054 		unuseds,
  3055 		urls,
  3056 		warnings,
  3058 		extraModules = [],
  3059 		emitter = new events.EventEmitter();
  3061 	function checkOption(name, t) {
  3062 		name = name.trim();
  3064 		if (/^[+-]W\d{3}$/g.test(name)) {
  3065 			return true;
  3068 		if (valOptions[name] === undefined && boolOptions[name] === undefined) {
  3069 			if (t.type !== "jslint") {
  3070 				error("E001", t, name);
  3071 				return false;
  3075 		return true;
  3078 	function isString(obj) {
  3079 		return Object.prototype.toString.call(obj) === "[object String]";
  3082 	function isIdentifier(tkn, value) {
  3083 		if (!tkn)
  3084 			return false;
  3086 		if (!tkn.identifier || tkn.value !== value)
  3087 			return false;
  3089 		return true;
  3092 	function isReserved(token) {
  3093 		if (!token.reserved) {
  3094 			return false;
  3097 		if (token.meta && token.meta.isFutureReservedWord) {
  3098 			// ES3 FutureReservedWord in an ES5 environment.
  3099 			if (state.option.inES5(true) && !token.meta.es5) {
  3100 				return false;
  3103 			// Some ES5 FutureReservedWord identifiers are active only
  3104 			// within a strict mode environment.
  3105 			if (token.meta.strictOnly) {
  3106 				if (!state.option.strict && !state.directive["use strict"]) {
  3107 					return false;
  3111 			if (token.isProperty) {
  3112 				return false;
  3116 		return true;
  3119 	function supplant(str, data) {
  3120 		return str.replace(/\{([^{}]*)\}/g, function (a, b) {
  3121 			var r = data[b];
  3122 			return typeof r === "string" || typeof r === "number" ? r : a;
  3123 		});
  3126 	function combine(t, o) {
  3127 		var n;
  3128 		for (n in o) {
  3129 			if (_.has(o, n) && !_.has(JSHINT.blacklist, n)) {
  3130 				t[n] = o[n];
  3135 	function updatePredefined() {
  3136 		Object.keys(JSHINT.blacklist).forEach(function (key) {
  3137 			delete predefined[key];
  3138 		});
  3141 	function assume() {
  3142 		if (state.option.es5) {
  3143 			warning("I003");
  3145 		if (state.option.couch) {
  3146 			combine(predefined, vars.couch);
  3149 		if (state.option.rhino) {
  3150 			combine(predefined, vars.rhino);
  3153 		if (state.option.phantom) {
  3154 			combine(predefined, vars.phantom);
  3157 		if (state.option.prototypejs) {
  3158 			combine(predefined, vars.prototypejs);
  3161 		if (state.option.node) {
  3162 			combine(predefined, vars.node);
  3165 		if (state.option.devel) {
  3166 			combine(predefined, vars.devel);
  3169 		if (state.option.dojo) {
  3170 			combine(predefined, vars.dojo);
  3173 		if (state.option.browser) {
  3174 			combine(predefined, vars.browser);
  3177 		if (state.option.nonstandard) {
  3178 			combine(predefined, vars.nonstandard);
  3181 		if (state.option.jquery) {
  3182 			combine(predefined, vars.jquery);
  3185 		if (state.option.mootools) {
  3186 			combine(predefined, vars.mootools);
  3189 		if (state.option.worker) {
  3190 			combine(predefined, vars.worker);
  3193 		if (state.option.wsh) {
  3194 			combine(predefined, vars.wsh);
  3197 		if (state.option.globalstrict && state.option.strict !== false) {
  3198 			state.option.strict = true;
  3201 		if (state.option.yui) {
  3202 			combine(predefined, vars.yui);
  3205 		// Let's assume that chronologically ES3 < ES5 < ES6/ESNext < Moz
  3207 		state.option.inMoz = function (strict) {
  3208 			if (strict) {
  3209 				return state.option.moz && !state.option.esnext;
  3211 			return state.option.moz;
  3212 		};
  3214 		state.option.inESNext = function (strict) {
  3215 			if (strict) {
  3216 				return !state.option.moz && state.option.esnext;
  3218 			return state.option.moz || state.option.esnext;
  3219 		};
  3221 		state.option.inES5 = function (/* strict */) {
  3222 			return !state.option.es3;
  3223 		};
  3225 		state.option.inES3 = function (strict) {
  3226 			if (strict) {
  3227 				return !state.option.moz && !state.option.esnext && state.option.es3;
  3229 			return state.option.es3;
  3230 		};
  3233 	// Produce an error warning.
  3234 	function quit(code, line, chr) {
  3235 		var percentage = Math.floor((line / state.lines.length) * 100);
  3236 		var message = messages.errors[code].desc;
  3238 		throw {
  3239 			name: "JSHintError",
  3240 			line: line,
  3241 			character: chr,
  3242 			message: message + " (" + percentage + "% scanned).",
  3243 			raw: message
  3244 		};
  3247 	function isundef(scope, code, token, a) {
  3248 		return JSHINT.undefs.push([scope, code, token, a]);
  3251 	function warning(code, t, a, b, c, d) {
  3252 		var ch, l, w, msg;
  3254 		if (/^W\d{3}$/.test(code)) {
  3255 			if (state.ignored[code])
  3256 				return;
  3258 			msg = messages.warnings[code];
  3259 		} else if (/E\d{3}/.test(code)) {
  3260 			msg = messages.errors[code];
  3261 		} else if (/I\d{3}/.test(code)) {
  3262 			msg = messages.info[code];
  3265 		t = t || state.tokens.next;
  3266 		if (t.id === "(end)") {  // `~
  3267 			t = state.tokens.curr;
  3270 		l = t.line || 0;
  3271 		ch = t.from || 0;
  3273 		w = {
  3274 			id: "(error)",
  3275 			raw: msg.desc,
  3276 			code: msg.code,
  3277 			evidence: state.lines[l - 1] || "",
  3278 			line: l,
  3279 			character: ch,
  3280 			scope: JSHINT.scope,
  3281 			a: a,
  3282 			b: b,
  3283 			c: c,
  3284 			d: d
  3285 		};
  3287 		w.reason = supplant(msg.desc, w);
  3288 		JSHINT.errors.push(w);
  3290 		if (state.option.passfail) {
  3291 			quit("E042", l, ch);
  3294 		warnings += 1;
  3295 		if (warnings >= state.option.maxerr) {
  3296 			quit("E043", l, ch);
  3299 		return w;
  3302 	function warningAt(m, l, ch, a, b, c, d) {
  3303 		return warning(m, {
  3304 			line: l,
  3305 			from: ch
  3306 		}, a, b, c, d);
  3309 	function error(m, t, a, b, c, d) {
  3310 		warning(m, t, a, b, c, d);
  3313 	function errorAt(m, l, ch, a, b, c, d) {
  3314 		return error(m, {
  3315 			line: l,
  3316 			from: ch
  3317 		}, a, b, c, d);
  3320 	// Tracking of "internal" scripts, like eval containing a static string
  3321 	function addInternalSrc(elem, src) {
  3322 		var i;
  3323 		i = {
  3324 			id: "(internal)",
  3325 			elem: elem,
  3326 			value: src
  3327 		};
  3328 		JSHINT.internals.push(i);
  3329 		return i;
  3332 	function addlabel(t, type, tkn, islet) {
  3333 		// Define t in the current function in the current scope.
  3334 		if (type === "exception") {
  3335 			if (_.has(funct["(context)"], t)) {
  3336 				if (funct[t] !== true && !state.option.node) {
  3337 					warning("W002", state.tokens.next, t);
  3342 		if (_.has(funct, t) && !funct["(global)"]) {
  3343 			if (funct[t] === true) {
  3344 				if (state.option.latedef) {
  3345 					if ((state.option.latedef === true && _.contains([funct[t], type], "unction")) ||
  3346 							!_.contains([funct[t], type], "unction")) {
  3347 						warning("W003", state.tokens.next, t);
  3350 			} else {
  3351 				if (!state.option.shadow && type !== "exception" ||
  3352 							(funct["(blockscope)"].getlabel(t))) {
  3353 					warning("W004", state.tokens.next, t);
  3358 		// a double definition of a let variable in same block throws a TypeError
  3359 		//if (funct["(blockscope)"] && funct["(blockscope)"].current.has(t)) {
  3360 		//	error("E044", state.tokens.next, t);
  3361 		//}
  3363 		// if the identifier is from a let, adds it only to the current blockscope
  3364 		if (islet) {
  3365 			funct["(blockscope)"].current.add(t, type, state.tokens.curr);
  3366 		} else {
  3368 			funct[t] = type;
  3370 			if (tkn) {
  3371 				funct["(tokens)"][t] = tkn;
  3374 			if (funct["(global)"]) {
  3375 				global[t] = funct;
  3376 				if (_.has(implied, t)) {
  3377 					if (state.option.latedef) {
  3378 						if ((state.option.latedef === true && _.contains([funct[t], type], "unction")) ||
  3379 								!_.contains([funct[t], type], "unction")) {
  3380 							warning("W003", state.tokens.next, t);
  3384 					delete implied[t];
  3386 			} else {
  3387 				scope[t] = funct;
  3392 	function doOption() {
  3393 		var nt = state.tokens.next;
  3394 		var body = nt.body.split(",").map(function (s) { return s.trim(); });
  3395 		var predef = {};
  3397 		if (nt.type === "globals") {
  3398 			body.forEach(function (g) {
  3399 				g = g.split(":");
  3400 				var key = g[0];
  3401 				var val = g[1];
  3403 				if (key.charAt(0) === "-") {
  3404 					key = key.slice(1);
  3405 					val = false;
  3407 					JSHINT.blacklist[key] = key;
  3408 					updatePredefined();
  3409 				} else {
  3410 					predef[key] = (val === "true");
  3412 			});
  3414 			combine(predefined, predef);
  3416 			for (var key in predef) {
  3417 				if (_.has(predef, key)) {
  3418 					declared[key] = nt;
  3423 		if (nt.type === "exported") {
  3424 			body.forEach(function (e) {
  3425 				exported[e] = true;
  3426 			});
  3429 		if (nt.type === "members") {
  3430 			membersOnly = membersOnly || {};
  3432 			body.forEach(function (m) {
  3433 				var ch1 = m.charAt(0);
  3434 				var ch2 = m.charAt(m.length - 1);
  3436 				if (ch1 === ch2 && (ch1 === "\"" || ch1 === "'")) {
  3437 					m = m
  3438 						.substr(1, m.length - 2)
  3439 						.replace("\\b", "\b")
  3440 						.replace("\\t", "\t")
  3441 						.replace("\\n", "\n")
  3442 						.replace("\\v", "\v")
  3443 						.replace("\\f", "\f")
  3444 						.replace("\\r", "\r")
  3445 						.replace("\\\\", "\\")
  3446 						.replace("\\\"", "\"");
  3449 				membersOnly[m] = false;
  3450 			});
  3453 		var numvals = [
  3454 			"maxstatements",
  3455 			"maxparams",
  3456 			"maxdepth",
  3457 			"maxcomplexity",
  3458 			"maxerr",
  3459 			"maxlen",
  3460 			"indent"
  3461 		];
  3463 		if (nt.type === "jshint" || nt.type === "jslint") {
  3464 			body.forEach(function (g) {
  3465 				g = g.split(":");
  3466 				var key = (g[0] || "").trim();
  3467 				var val = (g[1] || "").trim();
  3469 				if (!checkOption(key, nt)) {
  3470 					return;
  3473 				if (numvals.indexOf(key) >= 0) {
  3475 					// GH988 - numeric options can be disabled by setting them to `false`
  3476 					if (val !== "false") {
  3477 						val = +val;
  3479 						if (typeof val !== "number" || !isFinite(val) || val <= 0 || Math.floor(val) !== val) {
  3480 							error("E032", nt, g[1].trim());
  3481 							return;
  3484 						if (key === "indent") {
  3485 							state.option["(explicitIndent)"] = true;
  3487 						state.option[key] = val;
  3488 					} else {
  3489 						if (key === "indent") {
  3490 							state.option["(explicitIndent)"] = false;
  3491 						} else {
  3492 							state.option[key] = false;
  3496 					return;
  3499 				if (key === "validthis") {
  3500 					// `validthis` is valid only within a function scope.
  3501 					if (funct["(global)"]) {
  3502 						error("E009");
  3503 					} else {
  3504 						if (val === "true" || val === "false") {
  3505 							state.option.validthis = (val === "true");
  3506 						} else {
  3507 							error("E002", nt);
  3510 					return;
  3513 				if (key === "quotmark") {
  3514 					switch (val) {
  3515 					case "true":
  3516 					case "false":
  3517 						state.option.quotmark = (val === "true");
  3518 						break;
  3519 					case "double":
  3520 					case "single":
  3521 						state.option.quotmark = val;
  3522 						break;
  3523 					default:
  3524 						error("E002", nt);
  3526 					return;
  3529 				if (key === "unused") {
  3530 					switch (val) {
  3531 					case "true":
  3532 						state.option.unused = true;
  3533 						break;
  3534 					case "false":
  3535 						state.option.unused = false;
  3536 						break;
  3537 					case "vars":
  3538 					case "strict":
  3539 						state.option.unused = val;
  3540 						break;
  3541 					default:
  3542 						error("E002", nt);
  3544 					return;
  3547 				if (key === "latedef") {
  3548 					switch (val) {
  3549 					case "true":
  3550 						state.option.latedef = true;
  3551 						break;
  3552 					case "false":
  3553 						state.option.latedef = false;
  3554 						break;
  3555 					case "nofunc":
  3556 						state.option.latedef = "nofunc";
  3557 						break;
  3558 					default:
  3559 						error("E002", nt);
  3561 					return;
  3564 				var match = /^([+-])(W\d{3})$/g.exec(key);
  3565 				if (match) {
  3566 					// ignore for -W..., unignore for +W...
  3567 					state.ignored[match[2]] = (match[1] === "-");
  3568 					return;
  3571 				var tn;
  3572 				if (val === "true" || val === "false") {
  3573 					if (nt.type === "jslint") {
  3574 						tn = renamedOptions[key] || key;
  3575 						state.option[tn] = (val === "true");
  3577 						if (invertedOptions[tn] !== undefined) {
  3578 							state.option[tn] = !state.option[tn];
  3580 					} else {
  3581 						state.option[key] = (val === "true");
  3584 					if (key === "newcap") {
  3585 						state.option["(explicitNewcap)"] = true;
  3587 					return;
  3590 				error("E002", nt);
  3591 			});
  3593 			assume();
  3597 	// We need a peek function. If it has an argument, it peeks that much farther
  3598 	// ahead. It is used to distinguish
  3599 	//	   for ( var i in ...
  3600 	// from
  3601 	//	   for ( var i = ...
  3603 	function peek(p) {
  3604 		var i = p || 0, j = 0, t;
  3606 		while (j <= i) {
  3607 			t = lookahead[j];
  3608 			if (!t) {
  3609 				t = lookahead[j] = lex.token();
  3611 			j += 1;
  3613 		return t;
  3616 	// Produce the next token. It looks for programming errors.
  3618 	function advance(id, t) {
  3619 		switch (state.tokens.curr.id) {
  3620 		case "(number)":
  3621 			if (state.tokens.next.id === ".") {
  3622 				warning("W005", state.tokens.curr);
  3624 			break;
  3625 		case "-":
  3626 			if (state.tokens.next.id === "-" || state.tokens.next.id === "--") {
  3627 				warning("W006");
  3629 			break;
  3630 		case "+":
  3631 			if (state.tokens.next.id === "+" || state.tokens.next.id === "++") {
  3632 				warning("W007");
  3634 			break;
  3637 		if (state.tokens.curr.type === "(string)" || state.tokens.curr.identifier) {
  3638 			anonname = state.tokens.curr.value;
  3641 		if (id && state.tokens.next.id !== id) {
  3642 			if (t) {
  3643 				if (state.tokens.next.id === "(end)") {
  3644 					error("E019", t, t.id);
  3645 				} else {
  3646 					error("E020", state.tokens.next, id, t.id, t.line, state.tokens.next.value);
  3648 			} else if (state.tokens.next.type !== "(identifier)" || state.tokens.next.value !== id) {
  3649 				warning("W116", state.tokens.next, id, state.tokens.next.value);
  3653 		state.tokens.prev = state.tokens.curr;
  3654 		state.tokens.curr = state.tokens.next;
  3655 		for (;;) {
  3656 			state.tokens.next = lookahead.shift() || lex.token();
  3658 			if (!state.tokens.next) { // No more tokens left, give up
  3659 				quit("E041", state.tokens.curr.line);
  3662 			if (state.tokens.next.id === "(end)" || state.tokens.next.id === "(error)") {
  3663 				return;
  3666 			if (state.tokens.next.check) {
  3667 				state.tokens.next.check();
  3670 			if (state.tokens.next.isSpecial) {
  3671 				doOption();
  3672 			} else {
  3673 				if (state.tokens.next.id !== "(endline)") {
  3674 					break;
  3680 	// This is the heart of JSHINT, the Pratt parser. In addition to parsing, it
  3681 	// is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is
  3682 	// like .nud except that it is only used on the first token of a statement.
  3683 	// Having .fud makes it much easier to define statement-oriented languages like
  3684 	// JavaScript. I retained Pratt's nomenclature.
  3686 	// .nud  Null denotation
  3687 	// .fud  First null denotation
  3688 	// .led  Left denotation
  3689 	//  lbp  Left binding power
  3690 	//  rbp  Right binding power
  3692 	// They are elements of the parsing method called Top Down Operator Precedence.
  3694 	function expression(rbp, initial) {
  3695 		var left, isArray = false, isObject = false, isLetExpr = false;
  3697 		// if current expression is a let expression
  3698 		if (!initial && state.tokens.next.value === "let" && peek(0).value === "(") {
  3699 			if (!state.option.inMoz(true)) {
  3700 				warning("W118", state.tokens.next, "let expressions");
  3702 			isLetExpr = true;
  3703 			// create a new block scope we use only for the current expression
  3704 			funct["(blockscope)"].stack();
  3705 			advance("let");
  3706 			advance("(");
  3707 			state.syntax["let"].fud.call(state.syntax["let"].fud, false);
  3708 			advance(")");
  3711 		if (state.tokens.next.id === "(end)")
  3712 			error("E006", state.tokens.curr);
  3714 		advance();
  3716 		if (initial) {
  3717 			anonname = "anonymous";
  3718 			funct["(verb)"] = state.tokens.curr.value;
  3721 		if (initial === true && state.tokens.curr.fud) {
  3722 			left = state.tokens.curr.fud();
  3723 		} else {
  3724 			if (state.tokens.curr.nud) {
  3725 				left = state.tokens.curr.nud();
  3726 			} else {
  3727 				error("E030", state.tokens.curr, state.tokens.curr.id);
  3730 			var end_of_expr = state.tokens.next.identifier &&
  3731 									!state.tokens.curr.led &&
  3732 									state.tokens.curr.line !== state.tokens.next.line;
  3733 			while (rbp < state.tokens.next.lbp && !end_of_expr) {
  3734 				isArray = state.tokens.curr.value === "Array";
  3735 				isObject = state.tokens.curr.value === "Object";
  3737 				// #527, new Foo.Array(), Foo.Array(), new Foo.Object(), Foo.Object()
  3738 				// Line breaks in IfStatement heads exist to satisfy the checkJSHint
  3739 				// "Line too long." error.
  3740 				if (left && (left.value || (left.first && left.first.value))) {
  3741 					// If the left.value is not "new", or the left.first.value is a "."
  3742 					// then safely assume that this is not "new Array()" and possibly
  3743 					// not "new Object()"...
  3744 					if (left.value !== "new" ||
  3745 					  (left.first && left.first.value && left.first.value === ".")) {
  3746 						isArray = false;
  3747 						// ...In the case of Object, if the left.value and state.tokens.curr.value
  3748 						// are not equal, then safely assume that this not "new Object()"
  3749 						if (left.value !== state.tokens.curr.value) {
  3750 							isObject = false;
  3755 				advance();
  3757 				if (isArray && state.tokens.curr.id === "(" && state.tokens.next.id === ")") {
  3758 					warning("W009", state.tokens.curr);
  3761 				if (isObject && state.tokens.curr.id === "(" && state.tokens.next.id === ")") {
  3762 					warning("W010", state.tokens.curr);
  3765 				if (left && state.tokens.curr.led) {
  3766 					left = state.tokens.curr.led(left);
  3767 				} else {
  3768 					error("E033", state.tokens.curr, state.tokens.curr.id);
  3772 		if (isLetExpr) {
  3773 			funct["(blockscope)"].unstack();
  3775 		return left;
  3779 // Functions for conformance of style.
  3781 	function adjacent(left, right) {
  3782 		left = left || state.tokens.curr;
  3783 		right = right || state.tokens.next;
  3784 		if (state.option.white) {
  3785 			if (left.character !== right.from && left.line === right.line) {
  3786 				left.from += (left.character - left.from);
  3787 				warning("W011", left, left.value);
  3792 	function nobreak(left, right) {
  3793 		left = left || state.tokens.curr;
  3794 		right = right || state.tokens.next;
  3795 		if (state.option.white && (left.character !== right.from || left.line !== right.line)) {
  3796 			warning("W012", right, right.value);
  3800 	function nospace(left, right) {
  3801 		left = left || state.tokens.curr;
  3802 		right = right || state.tokens.next;
  3803 		if (state.option.white && !left.comment) {
  3804 			if (left.line === right.line) {
  3805 				adjacent(left, right);
  3810 	function nonadjacent(left, right) {
  3811 		if (state.option.white) {
  3812 			left = left || state.tokens.curr;
  3813 			right = right || state.tokens.next;
  3815 			if (left.value === ";" && right.value === ";") {
  3816 				return;
  3819 			if (left.line === right.line && left.character === right.from) {
  3820 				left.from += (left.character - left.from);
  3821 				warning("W013", left, left.value);
  3826 	function nobreaknonadjacent(left, right) {
  3827 		left = left || state.tokens.curr;
  3828 		right = right || state.tokens.next;
  3829 		if (!state.option.laxbreak && left.line !== right.line) {
  3830 			warning("W014", right, right.id);
  3831 		} else if (state.option.white) {
  3832 			left = left || state.tokens.curr;
  3833 			right = right || state.tokens.next;
  3834 			if (left.character === right.from) {
  3835 				left.from += (left.character - left.from);
  3836 				warning("W013", left, left.value);
  3841 	function indentation(bias) {
  3842 		if (!state.option.white && !state.option["(explicitIndent)"]) {
  3843 			return;
  3846 		if (state.tokens.next.id === "(end)") {
  3847 			return;
  3850 		var i = indent + (bias || 0);
  3851 		if (state.tokens.next.from !== i) {
  3852 			warning("W015", state.tokens.next, state.tokens.next.value, i, state.tokens.next.from);
  3856 	function nolinebreak(t) {
  3857 		t = t || state.tokens.curr;
  3858 		if (t.line !== state.tokens.next.line) {
  3859 			warning("E022", t, t.value);
  3864 	function comma(opts) {
  3865 		opts = opts || {};
  3867 		if (!opts.peek) {
  3868 			if (state.tokens.curr.line !== state.tokens.next.line) {
  3869 				if (!state.option.laxcomma) {
  3870 					if (comma.first) {
  3871 						warning("I001");
  3872 						comma.first = false;
  3874 					warning("W014", state.tokens.curr, state.tokens.next.value);
  3876 			} else if (!state.tokens.curr.comment &&
  3877 					state.tokens.curr.character !== state.tokens.next.from && state.option.white) {
  3878 				state.tokens.curr.from += (state.tokens.curr.character - state.tokens.curr.from);
  3879 				warning("W011", state.tokens.curr, state.tokens.curr.value);
  3882 			advance(",");
  3885 		// TODO: This is a temporary solution to fight against false-positives in
  3886 		// arrays and objects with trailing commas (see GH-363). The best solution
  3887 		// would be to extract all whitespace rules out of parser.
  3889 		if (state.tokens.next.value !== "]" && state.tokens.next.value !== "}") {
  3890 			nonadjacent(state.tokens.curr, state.tokens.next);
  3893 		if (state.tokens.next.identifier && !(opts.property && state.option.inES5())) {
  3894 			// Keywords that cannot follow a comma operator.
  3895 			switch (state.tokens.next.value) {
  3896 			case "break":
  3897 			case "case":
  3898 			case "catch":
  3899 			case "continue":
  3900 			case "default":
  3901 			case "do":
  3902 			case "else":
  3903 			case "finally":
  3904 			case "for":
  3905 			case "if":
  3906 			case "in":
  3907 			case "instanceof":
  3908 			case "return":
  3909 			case "yield":
  3910 			case "switch":
  3911 			case "throw":
  3912 			case "try":
  3913 			case "var":
  3914 			case "let":
  3915 			case "while":
  3916 			case "with":
  3917 				error("E024", state.tokens.next, state.tokens.next.value);
  3918 				return false;
  3922 		if (state.tokens.next.type === "(punctuator)") {
  3923 			switch (state.tokens.next.value) {
  3924 			case "}":
  3925 			case "]":
  3926 			case ",":
  3927 				if (opts.allowTrailing) {
  3928 					return true;
  3931 				/* falls through */
  3932 			case ")":
  3933 				error("E024", state.tokens.next, state.tokens.next.value);
  3934 				return false;
  3937 		return true;
  3940 	// Functional constructors for making the symbols that will be inherited by
  3941 	// tokens.
  3943 	function symbol(s, p) {
  3944 		var x = state.syntax[s];
  3945 		if (!x || typeof x !== "object") {
  3946 			state.syntax[s] = x = {
  3947 				id: s,
  3948 				lbp: p,
  3949 				value: s
  3950 			};
  3952 		return x;
  3955 	function delim(s) {
  3956 		return symbol(s, 0);
  3959 	function stmt(s, f) {
  3960 		var x = delim(s);
  3961 		x.identifier = x.reserved = true;
  3962 		x.fud = f;
  3963 		return x;
  3966 	function blockstmt(s, f) {
  3967 		var x = stmt(s, f);
  3968 		x.block = true;
  3969 		return x;
  3972 	function reserveName(x) {
  3973 		var c = x.id.charAt(0);
  3974 		if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z")) {
  3975 			x.identifier = x.reserved = true;
  3977 		return x;
  3980 	function prefix(s, f) {
  3981 		var x = symbol(s, 150);
  3982 		reserveName(x);
  3983 		x.nud = (typeof f === "function") ? f : function () {
  3984 			this.right = expression(150);
  3985 			this.arity = "unary";
  3986 			if (this.id === "++" || this.id === "--") {
  3987 				if (state.option.plusplus) {
  3988 					warning("W016", this, this.id);
  3989 				} else if ((!this.right.identifier || isReserved(this.right)) &&
  3990 						this.right.id !== "." && this.right.id !== "[") {
  3991 					warning("W017", this);
  3994 			return this;
  3995 		};
  3996 		return x;
  3999 	function type(s, f) {
  4000 		var x = delim(s);
  4001 		x.type = s;
  4002 		x.nud = f;
  4003 		return x;
  4006 	function reserve(name, func) {
  4007 		var x = type(name, func);
  4008 		x.identifier = true;
  4009 		x.reserved = true;
  4010 		return x;
  4013 	function FutureReservedWord(name, meta) {
  4014 		var x = type(name, (meta && meta.nud) || function () {
  4015 			return this;
  4016 		});
  4018 		meta = meta || {};
  4019 		meta.isFutureReservedWord = true;
  4021 		x.value = name;
  4022 		x.identifier = true;
  4023 		x.reserved = true;
  4024 		x.meta = meta;
  4026 		return x;
  4029 	function reservevar(s, v) {
  4030 		return reserve(s, function () {
  4031 			if (typeof v === "function") {
  4032 				v(this);
  4034 			return this;
  4035 		});
  4038 	function infix(s, f, p, w) {
  4039 		var x = symbol(s, p);
  4040 		reserveName(x);
  4041 		x.led = function (left) {
  4042 			if (!w) {
  4043 				nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
  4044 				nonadjacent(state.tokens.curr, state.tokens.next);
  4046 			if (s === "in" && left.id === "!") {
  4047 				warning("W018", left, "!");
  4049 			if (typeof f === "function") {
  4050 				return f(left, this);
  4051 			} else {
  4052 				this.left = left;
  4053 				this.right = expression(p);
  4054 				return this;
  4056 		};
  4057 		return x;
  4061 	function application(s) {
  4062 		var x = symbol(s, 42);
  4064 		x.led = function (left) {
  4065 			if (!state.option.inESNext()) {
  4066 				warning("W104", state.tokens.curr, "arrow function syntax (=>)");
  4069 			nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
  4070 			nonadjacent(state.tokens.curr, state.tokens.next);
  4072 			this.left = left;
  4073 			this.right = doFunction(undefined, undefined, false, left);
  4074 			return this;
  4075 		};
  4076 		return x;
  4079 	function relation(s, f) {
  4080 		var x = symbol(s, 100);
  4082 		x.led = function (left) {
  4083 			nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
  4084 			nonadjacent(state.tokens.curr, state.tokens.next);
  4085 			var right = expression(100);
  4087 			if (isIdentifier(left, "NaN") || isIdentifier(right, "NaN")) {
  4088 				warning("W019", this);
  4089 			} else if (f) {
  4090 				f.apply(this, [left, right]);
  4093 			if (!left || !right) {
  4094 				quit("E041", state.tokens.curr.line);
  4097 			if (left.id === "!") {
  4098 				warning("W018", left, "!");
  4101 			if (right.id === "!") {
  4102 				warning("W018", right, "!");
  4105 			this.left = left;
  4106 			this.right = right;
  4107 			return this;
  4108 		};
  4109 		return x;
  4112 	function isPoorRelation(node) {
  4113 		return node &&
  4114 			  ((node.type === "(number)" && +node.value === 0) ||
  4115 			   (node.type === "(string)" && node.value === "") ||
  4116 			   (node.type === "null" && !state.option.eqnull) ||
  4117 				node.type === "true" ||
  4118 				node.type === "false" ||
  4119 				node.type === "undefined");
  4122 	function assignop(s) {
  4123 		symbol(s, 20).exps = true;
  4125 		return infix(s, function (left, that) {
  4126 			that.left = left;
  4128 			if (left) {
  4129 				if (predefined[left.value] === false &&
  4130 						scope[left.value]["(global)"] === true) {
  4131 					warning("W020", left);
  4132 				} else if (left["function"]) {
  4133 					warning("W021", left, left.value);
  4136 				if (funct[left.value] === "const") {
  4137 					error("E013", left, left.value);
  4140 				if (left.id === ".") {
  4141 					if (!left.left) {
  4142 						warning("E031", that);
  4143 					} else if (left.left.value === "arguments" && !state.directive["use strict"]) {
  4144 						warning("E031", that);
  4147 					that.right = expression(19);
  4148 					return that;
  4149 				} else if (left.id === "[") {
  4150 					if (state.tokens.curr.left.first) {
  4151 						state.tokens.curr.left.first.forEach(function (t) {
  4152 							if (funct[t.value] === "const") {
  4153 								error("E013", t, t.value);
  4155 						});
  4156 					} else if (!left.left) {
  4157 						warning("E031", that);
  4158 					} else if (left.left.value === "arguments" && !state.directive["use strict"]) {
  4159 						warning("E031", that);
  4161 					that.right = expression(19);
  4162 					return that;
  4163 				} else if (left.identifier && !isReserved(left)) {
  4164 					if (funct[left.value] === "exception") {
  4165 						warning("W022", left);
  4167 					that.right = expression(19);
  4168 					return that;
  4171 				if (left === state.syntax["function"]) {
  4172 					warning("W023", state.tokens.curr);
  4176 			error("E031", that);
  4177 		}, 20);
  4181 	function bitwise(s, f, p) {
  4182 		var x = symbol(s, p);
  4183 		reserveName(x);
  4184 		x.led = (typeof f === "function") ? f : function (left) {
  4185 			if (state.option.bitwise) {
  4186 				warning("W016", this, this.id);
  4188 			this.left = left;
  4189 			this.right = expression(p);
  4190 			return this;
  4191 		};
  4192 		return x;
  4196 	function bitwiseassignop(s) {
  4197 		symbol(s, 20).exps = true;
  4198 		return infix(s, function (left, that) {
  4199 			if (state.option.bitwise) {
  4200 				warning("W016", that, that.id);
  4202 			nonadjacent(state.tokens.prev, state.tokens.curr);
  4203 			nonadjacent(state.tokens.curr, state.tokens.next);
  4204 			if (left) {
  4205 				if (left.id === "." || left.id === "[" ||
  4206 						(left.identifier && !isReserved(left))) {
  4207 					expression(19);
  4208 					return that;
  4210 				if (left === state.syntax["function"]) {
  4211 					warning("W023", state.tokens.curr);
  4213 				return that;
  4215 			error("E031", that);
  4216 		}, 20);
  4220 	function suffix(s) {
  4221 		var x = symbol(s, 150);
  4223 		x.led = function (left) {
  4224 			if (state.option.plusplus) {
  4225 				warning("W016", this, this.id);
  4226 			} else if ((!left.identifier || isReserved(left)) && left.id !== "." && left.id !== "[") {
  4227 				warning("W017", this);
  4230 			this.left = left;
  4231 			return this;
  4232 		};
  4233 		return x;
  4236 	// fnparam means that this identifier is being defined as a function
  4237 	// argument (see identifier())
  4238 	// prop means that this identifier is that of an object property
  4240 	function optionalidentifier(fnparam, prop) {
  4241 		if (!state.tokens.next.identifier) {
  4242 			return;
  4245 		advance();
  4247 		var curr = state.tokens.curr;
  4248 		var meta = curr.meta || {};
  4249 		var val  = state.tokens.curr.value;
  4251 		if (!isReserved(curr)) {
  4252 			return val;
  4255 		if (prop) {
  4256 			if (state.option.inES5() || meta.isFutureReservedWord) {
  4257 				return val;
  4261 		if (fnparam && val === "undefined") {
  4262 			return val;
  4265 		// Display an info message about reserved words as properties
  4266 		// and ES5 but do it only once.
  4267 		if (prop && !api.getCache("displayed:I002")) {
  4268 			api.setCache("displayed:I002", true);
  4269 			warning("I002");
  4272 		warning("W024", state.tokens.curr, state.tokens.curr.id);
  4273 		return val;
  4276 	// fnparam means that this identifier is being defined as a function
  4277 	// argument
  4278 	// prop means that this identifier is that of an object property
  4279 	function identifier(fnparam, prop) {
  4280 		var i = optionalidentifier(fnparam, prop);
  4281 		if (i) {
  4282 			return i;
  4284 		if (state.tokens.curr.id === "function" && state.tokens.next.id === "(") {
  4285 			warning("W025");
  4286 		} else {
  4287 			error("E030", state.tokens.next, state.tokens.next.value);
  4292 	function reachable(s) {
  4293 		var i = 0, t;
  4294 		if (state.tokens.next.id !== ";" || noreach) {
  4295 			return;
  4297 		for (;;) {
  4298 			t = peek(i);
  4299 			if (t.reach) {
  4300 				return;
  4302 			if (t.id !== "(endline)") {
  4303 				if (t.id === "function") {
  4304 					if (!state.option.latedef) {
  4305 						break;
  4308 					warning("W026", t);
  4309 					break;
  4312 				warning("W027", t, t.value, s);
  4313 				break;
  4315 			i += 1;
  4320 	function statement(noindent) {
  4321 		var values;
  4322 		var i = indent, r, s = scope, t = state.tokens.next;
  4324 		if (t.id === ";") {
  4325 			advance(";");
  4326 			return;
  4329 		// Is this a labelled statement?
  4330 		var res = isReserved(t);
  4332 		// We're being more tolerant here: if someone uses
  4333 		// a FutureReservedWord as a label, we warn but proceed
  4334 		// anyway.
  4336 		if (res && t.meta && t.meta.isFutureReservedWord && peek().id === ":") {
  4337 			warning("W024", t, t.id);
  4338 			res = false;
  4341 		// detect a destructuring assignment
  4342 		if (_.has(["[", "{"], t.value)) {
  4343 			if (lookupBlockType().isDestAssign) {
  4344 				if (!state.option.inESNext()) {
  4345 					warning("W104", state.tokens.curr, "destructuring expression");
  4347 				values = destructuringExpression();
  4348 				values.forEach(function (tok) {
  4349 					isundef(funct, "W117", tok.token, tok.id);
  4350 				});
  4351 				advance("=");
  4352 				destructuringExpressionMatch(values, expression(5, true));
  4353 				advance(";");
  4354 				return;
  4357 		if (t.identifier && !res && peek().id === ":") {
  4358 			advance();
  4359 			advance(":");
  4360 			scope = Object.create(s);
  4361 			addlabel(t.value, "label");
  4363 			if (!state.tokens.next.labelled && state.tokens.next.value !== "{") {
  4364 				warning("W028", state.tokens.next, t.value, state.tokens.next.value);
  4367 			state.tokens.next.label = t.value;
  4368 			t = state.tokens.next;
  4371 		// Is it a lonely block?
  4373 		if (t.id === "{") {
  4374 	                // Is it a switch case block?
  4375 	                //
  4376 	                //      switch (foo) {
  4377 	                //              case bar: { <= here.
  4378 	                //                      ...
  4379 	                //              }
  4380 	                //      }
  4381 	                var iscase = (funct["(verb)"] === "case" && state.tokens.curr.value === ":");
  4382 	                block(true, true, false, false, iscase);
  4383 			return;
  4386 		// Parse the statement.
  4388 		if (!noindent) {
  4389 			indentation();
  4391 		r = expression(0, true);
  4393 		// Look for the final semicolon.
  4395 		if (!t.block) {
  4396 			if (!state.option.expr && (!r || !r.exps)) {
  4397 				warning("W030", state.tokens.curr);
  4398 			} else if (state.option.nonew && r && r.left && r.id === "(" && r.left.id === "new") {
  4399 				warning("W031", t);
  4402 			if (state.tokens.next.id !== ";") {
  4403 				if (!state.option.asi) {
  4404 					// If this is the last statement in a block that ends on
  4405 					// the same line *and* option lastsemic is on, ignore the warning.
  4406 					// Otherwise, complain about missing semicolon.
  4407 					if (!state.option.lastsemic || state.tokens.next.id !== "}" ||
  4408 						state.tokens.next.line !== state.tokens.curr.line) {
  4409 						warningAt("W033", state.tokens.curr.line, state.tokens.curr.character);
  4412 			} else {
  4413 				adjacent(state.tokens.curr, state.tokens.next);
  4414 				advance(";");
  4415 				nonadjacent(state.tokens.curr, state.tokens.next);
  4419 		// Restore the indentation.
  4421 		indent = i;
  4422 		scope = s;
  4423 		return r;
  4427 	function statements(startLine) {
  4428 		var a = [], p;
  4430 		while (!state.tokens.next.reach && state.tokens.next.id !== "(end)") {
  4431 			if (state.tokens.next.id === ";") {
  4432 				p = peek();
  4434 				if (!p || (p.id !== "(" && p.id !== "[")) {
  4435 					warning("W032");
  4438 				advance(";");
  4439 			} else {
  4440 				a.push(statement(startLine === state.tokens.next.line));
  4443 		return a;
  4447 	/*
  4448 	 * read all directives
  4449 	 * recognizes a simple form of asi, but always
  4450 	 * warns, if it is used
  4451 	 */
  4452 	function directives() {
  4453 		var i, p, pn;
  4455 		for (;;) {
  4456 			if (state.tokens.next.id === "(string)") {
  4457 				p = peek(0);
  4458 				if (p.id === "(endline)") {
  4459 					i = 1;
  4460 					do {
  4461 						pn = peek(i);
  4462 						i = i + 1;
  4463 					} while (pn.id === "(endline)");
  4465 					if (pn.id !== ";") {
  4466 						if (pn.id !== "(string)" && pn.id !== "(number)" &&
  4467 							pn.id !== "(regexp)" && pn.identifier !== true &&
  4468 							pn.id !== "}") {
  4469 							break;
  4471 						warning("W033", state.tokens.next);
  4472 					} else {
  4473 						p = pn;
  4475 				} else if (p.id === "}") {
  4476 					// Directive with no other statements, warn about missing semicolon
  4477 					warning("W033", p);
  4478 				} else if (p.id !== ";") {
  4479 					break;
  4482 				indentation();
  4483 				advance();
  4484 				if (state.directive[state.tokens.curr.value]) {
  4485 					warning("W034", state.tokens.curr, state.tokens.curr.value);
  4488 				if (state.tokens.curr.value === "use strict") {
  4489 					if (!state.option["(explicitNewcap)"])
  4490 						state.option.newcap = true;
  4491 					state.option.undef = true;
  4494 				// there's no directive negation, so always set to true
  4495 				state.directive[state.tokens.curr.value] = true;
  4497 				if (p.id === ";") {
  4498 					advance(";");
  4500 				continue;
  4502 			break;
  4507 	/*
  4508 	 * Parses a single block. A block is a sequence of statements wrapped in
  4509 	 * braces.
  4511 	 * ordinary     - true for everything but function bodies and try blocks.
  4512 	 * stmt         - true if block can be a single statement (e.g. in if/for/while).
  4513 	 * isfunc       - true if block is a function body
  4514 	 * isfatarrow   -
  4515 	 * iscase       - true if block is a switch case block
  4516 	 */
  4517 	function block(ordinary, stmt, isfunc, isfatarrow, iscase) {
  4518 		var a,
  4519 			b = inblock,
  4520 			old_indent = indent,
  4521 			m,
  4522 			s = scope,
  4523 			t,
  4524 			line,
  4525 			d;
  4527 		inblock = ordinary;
  4529 		if (!ordinary || !state.option.funcscope)
  4530 			scope = Object.create(scope);
  4532 		nonadjacent(state.tokens.curr, state.tokens.next);
  4533 		t = state.tokens.next;
  4535 		var metrics = funct["(metrics)"];
  4536 		metrics.nestedBlockDepth += 1;
  4537 		metrics.verifyMaxNestedBlockDepthPerFunction();
  4539 		if (state.tokens.next.id === "{") {
  4540 			advance("{");
  4542 			// create a new block scope
  4543 			funct["(blockscope)"].stack();
  4545 			line = state.tokens.curr.line;
  4546 			if (state.tokens.next.id !== "}") {
  4547 				indent += state.option.indent;
  4548 				while (!ordinary && state.tokens.next.from > indent) {
  4549 					indent += state.option.indent;
  4552 				if (isfunc) {
  4553 					m = {};
  4554 					for (d in state.directive) {
  4555 						if (_.has(state.directive, d)) {
  4556 							m[d] = state.directive[d];
  4559 					directives();
  4561 					if (state.option.strict && funct["(context)"]["(global)"]) {
  4562 						if (!m["use strict"] && !state.directive["use strict"]) {
  4563 							warning("E007");
  4568 				a = statements(line);
  4570 				metrics.statementCount += a.length;
  4572 				if (isfunc) {
  4573 					state.directive = m;
  4576 				indent -= state.option.indent;
  4577 				if (line !== state.tokens.next.line) {
  4578 					indentation();
  4580 			} else if (line !== state.tokens.next.line) {
  4581 				indentation();
  4583 			advance("}", t);
  4585 			funct["(blockscope)"].unstack();
  4587 			indent = old_indent;
  4588 		} else if (!ordinary) {
  4589 			if (isfunc) {
  4590 				m = {};
  4591 				if (stmt && !isfatarrow && !state.option.inMoz(true)) {
  4592 					error("W118", state.tokens.curr, "function closure expressions");
  4595 				if (!stmt) {
  4596 					for (d in state.directive) {
  4597 						if (_.has(state.directive, d)) {
  4598 							m[d] = state.directive[d];
  4602 				expression(5);
  4604 				if (state.option.strict && funct["(context)"]["(global)"]) {
  4605 					if (!m["use strict"] && !state.directive["use strict"]) {
  4606 						warning("E007");
  4609 			} else {
  4610 				error("E021", state.tokens.next, "{", state.tokens.next.value);
  4612 		} else {
  4614 			// check to avoid let declaration not within a block
  4615 			funct["(nolet)"] = true;
  4617 			if (!stmt || state.option.curly) {
  4618 				warning("W116", state.tokens.next, "{", state.tokens.next.value);
  4621 			noreach = true;
  4622 			indent += state.option.indent;
  4623 			// test indentation only if statement is in new line
  4624 			a = [statement(state.tokens.next.line === state.tokens.curr.line)];
  4625 			indent -= state.option.indent;
  4626 			noreach = false;
  4628 			delete funct["(nolet)"];
  4630 		// If it is a "break" in switch case, don't clear and let it propagate out.
  4631 		if (!(iscase && funct["(verb)"] === "break")) funct["(verb)"] = null;
  4633 		if (!ordinary || !state.option.funcscope) scope = s;
  4634 		inblock = b;
  4635 		if (ordinary && state.option.noempty && (!a || a.length === 0)) {
  4636 			warning("W035");
  4638 		metrics.nestedBlockDepth -= 1;
  4639 		return a;
  4643 	function countMember(m) {
  4644 		if (membersOnly && typeof membersOnly[m] !== "boolean") {
  4645 			warning("W036", state.tokens.curr, m);
  4647 		if (typeof member[m] === "number") {
  4648 			member[m] += 1;
  4649 		} else {
  4650 			member[m] = 1;
  4655 	function note_implied(tkn) {
  4656 		var name = tkn.value, line = tkn.line, a = implied[name];
  4657 		if (typeof a === "function") {
  4658 			a = false;
  4661 		if (!a) {
  4662 			a = [line];
  4663 			implied[name] = a;
  4664 		} else if (a[a.length - 1] !== line) {
  4665 			a.push(line);
  4670 	// Build the syntax table by declaring the syntactic elements of the language.
  4672 	type("(number)", function () {
  4673 		return this;
  4674 	});
  4676 	type("(string)", function () {
  4677 		return this;
  4678 	});
  4680 	state.syntax["(identifier)"] = {
  4681 		type: "(identifier)",
  4682 		lbp: 0,
  4683 		identifier: true,
  4684 		nud: function () {
  4685 			var v = this.value,
  4686 				s = scope[v],
  4687 				f;
  4689 			if (typeof s === "function") {
  4690 				// Protection against accidental inheritance.
  4691 				s = undefined;
  4692 			} else if (typeof s === "boolean") {
  4693 				f = funct;
  4694 				funct = functions[0];
  4695 				addlabel(v, "var");
  4696 				s = funct;
  4697 				funct = f;
  4699 			var block;
  4700 			if (_.has(funct, "(blockscope)")) {
  4701 				block = funct["(blockscope)"].getlabel(v);
  4704 			// The name is in scope and defined in the current function.
  4705 			if (funct === s || block) {
  4706 				// Change 'unused' to 'var', and reject labels.
  4707 				// the name is in a block scope
  4708 				switch (block ? block[v]["(type)"] : funct[v]) {
  4709 				case "unused":
  4710 					if (block) block[v]["(type)"] = "var";
  4711 					else funct[v] = "var";
  4712 					break;
  4713 				case "unction":
  4714 					if (block) block[v]["(type)"] = "function";
  4715 					else funct[v] = "function";
  4716 					this["function"] = true;
  4717 					break;
  4718 				case "function":
  4719 					this["function"] = true;
  4720 					break;
  4721 				case "label":
  4722 					warning("W037", state.tokens.curr, v);
  4723 					break;
  4725 			} else if (funct["(global)"]) {
  4726 				// The name is not defined in the function.  If we are in the global
  4727 				// scope, then we have an undefined variable.
  4728 				//
  4729 				// Operators typeof and delete do not raise runtime errors even if
  4730 				// the base object of a reference is null so no need to display warning
  4731 				// if we're inside of typeof or delete.
  4733 				if (typeof predefined[v] !== "boolean") {
  4734 					// Attempting to subscript a null reference will throw an
  4735 					// error, even within the typeof and delete operators
  4736 					if (!(anonname === "typeof" || anonname === "delete") ||
  4737 						(state.tokens.next && (state.tokens.next.value === "." ||
  4738 							state.tokens.next.value === "["))) {
  4740 						// if we're in a list comprehension, variables are declared
  4741 						// locally and used before being defined. So we check
  4742 						// the presence of the given variable in the comp array
  4743 						// before declaring it undefined.
  4745 						if (!funct["(comparray)"].check(v)) {
  4746 							isundef(funct, "W117", state.tokens.curr, v);
  4751 				note_implied(state.tokens.curr);
  4752 			} else {
  4753 				// If the name is already defined in the current
  4754 				// function, but not as outer, then there is a scope error.
  4756 				switch (funct[v]) {
  4757 				case "closure":
  4758 				case "function":
  4759 				case "var":
  4760 				case "unused":
  4761 					warning("W038", state.tokens.curr, v);
  4762 					break;
  4763 				case "label":
  4764 					warning("W037", state.tokens.curr, v);
  4765 					break;
  4766 				case "outer":
  4767 				case "global":
  4768 					break;
  4769 				default:
  4770 					// If the name is defined in an outer function, make an outer entry,
  4771 					// and if it was unused, make it var.
  4772 					if (s === true) {
  4773 						funct[v] = true;
  4774 					} else if (s === null) {
  4775 						warning("W039", state.tokens.curr, v);
  4776 						note_implied(state.tokens.curr);
  4777 					} else if (typeof s !== "object") {
  4778 						// Operators typeof and delete do not raise runtime errors even
  4779 						// if the base object of a reference is null so no need to
  4780 						//
  4781 						// display warning if we're inside of typeof or delete.
  4782 						// Attempting to subscript a null reference will throw an
  4783 						// error, even within the typeof and delete operators
  4784 						if (!(anonname === "typeof" || anonname === "delete") ||
  4785 							(state.tokens.next &&
  4786 								(state.tokens.next.value === "." || state.tokens.next.value === "["))) {
  4788 							isundef(funct, "W117", state.tokens.curr, v);
  4790 						funct[v] = true;
  4791 						note_implied(state.tokens.curr);
  4792 					} else {
  4793 						switch (s[v]) {
  4794 						case "function":
  4795 						case "unction":
  4796 							this["function"] = true;
  4797 							s[v] = "closure";
  4798 							funct[v] = s["(global)"] ? "global" : "outer";
  4799 							break;
  4800 						case "var":
  4801 						case "unused":
  4802 							s[v] = "closure";
  4803 							funct[v] = s["(global)"] ? "global" : "outer";
  4804 							break;
  4805 						case "closure":
  4806 							funct[v] = s["(global)"] ? "global" : "outer";
  4807 							break;
  4808 						case "label":
  4809 							warning("W037", state.tokens.curr, v);
  4814 			return this;
  4815 		},
  4816 		led: function () {
  4817 			error("E033", state.tokens.next, state.tokens.next.value);
  4819 	};
  4821 	type("(regexp)", function () {
  4822 		return this;
  4823 	});
  4825 	// ECMAScript parser
  4827 	delim("(endline)");
  4828 	delim("(begin)");
  4829 	delim("(end)").reach = true;
  4830 	delim("(error)").reach = true;
  4831 	delim("}").reach = true;
  4832 	delim(")");
  4833 	delim("]");
  4834 	delim("\"").reach = true;
  4835 	delim("'").reach = true;
  4836 	delim(";");
  4837 	delim(":").reach = true;
  4838 	delim("#");
  4840 	reserve("else");
  4841 	reserve("case").reach = true;
  4842 	reserve("catch");
  4843 	reserve("default").reach = true;
  4844 	reserve("finally");
  4845 	reservevar("arguments", function (x) {
  4846 		if (state.directive["use strict"] && funct["(global)"]) {
  4847 			warning("E008", x);
  4849 	});
  4850 	reservevar("eval");
  4851 	reservevar("false");
  4852 	reservevar("Infinity");
  4853 	reservevar("null");
  4854 	reservevar("this", function (x) {
  4855 		if (state.directive["use strict"] && !state.option.validthis && ((funct["(statement)"] &&
  4856 				funct["(name)"].charAt(0) > "Z") || funct["(global)"])) {
  4857 			warning("W040", x);
  4859 	});
  4860 	reservevar("true");
  4861 	reservevar("undefined");
  4863 	assignop("=", "assign", 20);
  4864 	assignop("+=", "assignadd", 20);
  4865 	assignop("-=", "assignsub", 20);
  4866 	assignop("*=", "assignmult", 20);
  4867 	assignop("/=", "assigndiv", 20).nud = function () {
  4868 		error("E014");
  4869 	};
  4870 	assignop("%=", "assignmod", 20);
  4872 	bitwiseassignop("&=", "assignbitand", 20);
  4873 	bitwiseassignop("|=", "assignbitor", 20);
  4874 	bitwiseassignop("^=", "assignbitxor", 20);
  4875 	bitwiseassignop("<<=", "assignshiftleft", 20);
  4876 	bitwiseassignop(">>=", "assignshiftright", 20);
  4877 	bitwiseassignop(">>>=", "assignshiftrightunsigned", 20);
  4878 	infix(",", function (left, that) {
  4879 		var expr;
  4880 		that.exprs = [left];
  4881 		if (!comma({peek: true})) {
  4882 			return that;
  4884 		while (true) {
  4885 			if (!(expr = expression(5)))  {
  4886 				break;
  4888 			that.exprs.push(expr);
  4889 			if (state.tokens.next.value !== "," || !comma()) {
  4890 				break;
  4893 		return that;
  4894 	}, 5, true);
  4895 	infix("?", function (left, that) {
  4896 		that.left = left;
  4897 		that.right = expression(10);
  4898 		advance(":");
  4899 		that["else"] = expression(10);
  4900 		return that;
  4901 	}, 30);
  4903 	infix("||", "or", 40);
  4904 	infix("&&", "and", 50);
  4905 	bitwise("|", "bitor", 70);
  4906 	bitwise("^", "bitxor", 80);
  4907 	bitwise("&", "bitand", 90);
  4908 	relation("==", function (left, right) {
  4909 		var eqnull = state.option.eqnull && (left.value === "null" || right.value === "null");
  4911 		if (!eqnull && state.option.eqeqeq)
  4912 			warning("W116", this, "===", "==");
  4913 		else if (isPoorRelation(left))
  4914 			warning("W041", this, "===", left.value);
  4915 		else if (isPoorRelation(right))
  4916 			warning("W041", this, "===", right.value);
  4918 		return this;
  4919 	});
  4920 	relation("===");
  4921 	relation("!=", function (left, right) {
  4922 		var eqnull = state.option.eqnull &&
  4923 				(left.value === "null" || right.value === "null");
  4925 		if (!eqnull && state.option.eqeqeq) {
  4926 			warning("W116", this, "!==", "!=");
  4927 		} else if (isPoorRelation(left)) {
  4928 			warning("W041", this, "!==", left.value);
  4929 		} else if (isPoorRelation(right)) {
  4930 			warning("W041", this, "!==", right.value);
  4932 		return this;
  4933 	});
  4934 	relation("!==");
  4935 	relation("<");
  4936 	relation(">");
  4937 	relation("<=");
  4938 	relation(">=");
  4939 	bitwise("<<", "shiftleft", 120);
  4940 	bitwise(">>", "shiftright", 120);
  4941 	bitwise(">>>", "shiftrightunsigned", 120);
  4942 	infix("in", "in", 120);
  4943 	infix("instanceof", "instanceof", 120);
  4944 	infix("+", function (left, that) {
  4945 		var right = expression(130);
  4946 		if (left && right && left.id === "(string)" && right.id === "(string)") {
  4947 			left.value += right.value;
  4948 			left.character = right.character;
  4949 			if (!state.option.scripturl && reg.javascriptURL.test(left.value)) {
  4950 				warning("W050", left);
  4952 			return left;
  4954 		that.left = left;
  4955 		that.right = right;
  4956 		return that;
  4957 	}, 130);
  4958 	prefix("+", "num");
  4959 	prefix("+++", function () {
  4960 		warning("W007");
  4961 		this.right = expression(150);
  4962 		this.arity = "unary";
  4963 		return this;
  4964 	});
  4965 	infix("+++", function (left) {
  4966 		warning("W007");
  4967 		this.left = left;
  4968 		this.right = expression(130);
  4969 		return this;
  4970 	}, 130);
  4971 	infix("-", "sub", 130);
  4972 	prefix("-", "neg");
  4973 	prefix("---", function () {
  4974 		warning("W006");
  4975 		this.right = expression(150);
  4976 		this.arity = "unary";
  4977 		return this;
  4978 	});
  4979 	infix("---", function (left) {
  4980 		warning("W006");
  4981 		this.left = left;
  4982 		this.right = expression(130);
  4983 		return this;
  4984 	}, 130);
  4985 	infix("*", "mult", 140);
  4986 	infix("/", "div", 140);
  4987 	infix("%", "mod", 140);
  4989 	suffix("++", "postinc");
  4990 	prefix("++", "preinc");
  4991 	state.syntax["++"].exps = true;
  4993 	suffix("--", "postdec");
  4994 	prefix("--", "predec");
  4995 	state.syntax["--"].exps = true;
  4996 	prefix("delete", function () {
  4997 		var p = expression(5);
  4998 		if (!p || (p.id !== "." && p.id !== "[")) {
  4999 			warning("W051");
  5001 		this.first = p;
  5002 		return this;
  5003 	}).exps = true;
  5005 	prefix("~", function () {
  5006 		if (state.option.bitwise) {
  5007 			warning("W052", this, "~");
  5009 		expression(150);
  5010 		return this;
  5011 	});
  5013 	prefix("...", function () {
  5014 		if (!state.option.inESNext()) {
  5015 			warning("W104", this, "spread/rest operator");
  5017 		if (!state.tokens.next.identifier) {
  5018 			error("E030", state.tokens.next, state.tokens.next.value);
  5020 		expression(150);
  5021 		return this;
  5022 	});
  5024 	prefix("!", function () {
  5025 		this.right = expression(150);
  5026 		this.arity = "unary";
  5028 		if (!this.right) { // '!' followed by nothing? Give up.
  5029 			quit("E041", this.line || 0);
  5032 		if (bang[this.right.id] === true) {
  5033 			warning("W018", this, "!");
  5035 		return this;
  5036 	});
  5038 	prefix("typeof", "typeof");
  5039 	prefix("new", function () {
  5040 		var c = expression(155), i;
  5041 		if (c && c.id !== "function") {
  5042 			if (c.identifier) {
  5043 				c["new"] = true;
  5044 				switch (c.value) {
  5045 				case "Number":
  5046 				case "String":
  5047 				case "Boolean":
  5048 				case "Math":
  5049 				case "JSON":
  5050 					warning("W053", state.tokens.prev, c.value);
  5051 					break;
  5052 				case "Function":
  5053 					if (!state.option.evil) {
  5054 						warning("W054");
  5056 					break;
  5057 				case "Date":
  5058 				case "RegExp":
  5059 					break;
  5060 				default:
  5061 					if (c.id !== "function") {
  5062 						i = c.value.substr(0, 1);
  5063 						if (state.option.newcap && (i < "A" || i > "Z") && !_.has(global, c.value)) {
  5064 							warning("W055", state.tokens.curr);
  5068 			} else {
  5069 				if (c.id !== "." && c.id !== "[" && c.id !== "(") {
  5070 					warning("W056", state.tokens.curr);
  5073 		} else {
  5074 			if (!state.option.supernew)
  5075 				warning("W057", this);
  5077 		adjacent(state.tokens.curr, state.tokens.next);
  5078 		if (state.tokens.next.id !== "(" && !state.option.supernew) {
  5079 			warning("W058", state.tokens.curr, state.tokens.curr.value);
  5081 		this.first = c;
  5082 		return this;
  5083 	});
  5084 	state.syntax["new"].exps = true;
  5086 	prefix("void").exps = true;
  5088 	infix(".", function (left, that) {
  5089 		adjacent(state.tokens.prev, state.tokens.curr);
  5090 		nobreak();
  5091 		var m = identifier(false, true);
  5093 		if (typeof m === "string") {
  5094 			countMember(m);
  5097 		that.left = left;
  5098 		that.right = m;
  5100 		if (m && m === "hasOwnProperty" && state.tokens.next.value === "=") {
  5101 			warning("W001");
  5104 		if (left && left.value === "arguments" && (m === "callee" || m === "caller")) {
  5105 			if (state.option.noarg)
  5106 				warning("W059", left, m);
  5107 			else if (state.directive["use strict"])
  5108 				error("E008");
  5109 		} else if (!state.option.evil && left && left.value === "document" &&
  5110 				(m === "write" || m === "writeln")) {
  5111 			warning("W060", left);
  5114 		if (!state.option.evil && (m === "eval" || m === "execScript")) {
  5115 			warning("W061");
  5118 		return that;
  5119 	}, 160, true);
  5121 	infix("(", function (left, that) {
  5122 		if (state.tokens.prev.id !== "}" && state.tokens.prev.id !== ")") {
  5123 			nobreak(state.tokens.prev, state.tokens.curr);
  5126 		nospace();
  5127 		if (state.option.immed && left && !left.immed && left.id === "function") {
  5128 			warning("W062");
  5131 		var n = 0;
  5132 		var p = [];
  5134 		if (left) {
  5135 			if (left.type === "(identifier)") {
  5136 				if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) {
  5137 					if ("Number String Boolean Date Object".indexOf(left.value) === -1) {
  5138 						if (left.value === "Math") {
  5139 							warning("W063", left);
  5140 						} else if (state.option.newcap) {
  5141 							warning("W064", left);
  5148 		if (state.tokens.next.id !== ")") {
  5149 			for (;;) {
  5150 				p[p.length] = expression(10);
  5151 				n += 1;
  5152 				if (state.tokens.next.id !== ",") {
  5153 					break;
  5155 				comma();
  5159 		advance(")");
  5160 		nospace(state.tokens.prev, state.tokens.curr);
  5162 		if (typeof left === "object") {
  5163 			if (left.value === "parseInt" && n === 1) {
  5164 				warning("W065", state.tokens.curr);
  5166 			if (!state.option.evil) {
  5167 				if (left.value === "eval" || left.value === "Function" ||
  5168 						left.value === "execScript") {
  5169 					warning("W061", left);
  5171 					if (p[0] && [0].id === "(string)") {
  5172 						addInternalSrc(left, p[0].value);
  5174 				} else if (p[0] && p[0].id === "(string)" &&
  5175 					   (left.value === "setTimeout" ||
  5176 						left.value === "setInterval")) {
  5177 					warning("W066", left);
  5178 					addInternalSrc(left, p[0].value);
  5180 				// window.setTimeout/setInterval
  5181 				} else if (p[0] && p[0].id === "(string)" &&
  5182 					   left.value === "." &&
  5183 					   left.left.value === "window" &&
  5184 					   (left.right === "setTimeout" ||
  5185 						left.right === "setInterval")) {
  5186 					warning("W066", left);
  5187 					addInternalSrc(left, p[0].value);
  5190 			if (!left.identifier && left.id !== "." && left.id !== "[" &&
  5191 					left.id !== "(" && left.id !== "&&" && left.id !== "||" &&
  5192 					left.id !== "?") {
  5193 				warning("W067", left);
  5197 		that.left = left;
  5198 		return that;
  5199 	}, 155, true).exps = true;
  5201 	prefix("(", function () {
  5202 		nospace();
  5203 		var bracket, brackets = [];
  5204 		var pn, pn1, i = 0;
  5206 		do {
  5207 			pn = peek(i);
  5208 			i += 1;
  5209 			pn1 = peek(i);
  5210 			i += 1;
  5211 		} while (pn.value !== ")" && pn1.value !== "=>" && pn1.value !== ";" && pn1.type !== "(end)");
  5213 		if (state.tokens.next.id === "function") {
  5214 			state.tokens.next.immed = true;
  5217 		var exprs = [];
  5219 		if (state.tokens.next.id !== ")") {
  5220 			for (;;) {
  5221 				if (pn1.value === "=>" && state.tokens.next.value === "{") {
  5222 					bracket = state.tokens.next;
  5223 					bracket.left = destructuringExpression();
  5224 					brackets.push(bracket);
  5225 					for (var t in bracket.left) {
  5226 						exprs.push(bracket.left[t].token);
  5228 				} else {
  5229 					exprs.push(expression(5));
  5231 				if (state.tokens.next.id !== ",") {
  5232 					break;
  5234 				comma();
  5238 		advance(")", this);
  5239 		nospace(state.tokens.prev, state.tokens.curr);
  5240 		if (state.option.immed && exprs[0] && exprs[0].id === "function") {
  5241 			if (state.tokens.next.id !== "(" &&
  5242 			  (state.tokens.next.id !== "." || (peek().value !== "call" && peek().value !== "apply"))) {
  5243 				warning("W068", this);
  5247 		if (state.tokens.next.value === "=>") {
  5248 			return exprs;
  5250 		if (!exprs.length) {
  5251 			return;
  5253 		exprs[exprs.length - 1].paren = true;
  5254 		if (exprs.length > 1) {
  5255 			return Object.create(state.syntax[","], { exprs: { value: exprs } });
  5257 		return exprs[0];
  5258 	});
  5260 	application("=>");
  5262 	infix("[", function (left, that) {
  5263 		nobreak(state.tokens.prev, state.tokens.curr);
  5264 		nospace();
  5265 		var e = expression(5), s;
  5266 		if (e && e.type === "(string)") {
  5267 			if (!state.option.evil && (e.value === "eval" || e.value === "execScript")) {
  5268 				warning("W061", that);
  5271 			countMember(e.value);
  5272 			if (!state.option.sub && reg.identifier.test(e.value)) {
  5273 				s = state.syntax[e.value];
  5274 				if (!s || !isReserved(s)) {
  5275 					warning("W069", state.tokens.prev, e.value);
  5279 		advance("]", that);
  5281 		if (e && e.value === "hasOwnProperty" && state.tokens.next.value === "=") {
  5282 			warning("W001");
  5285 		nospace(state.tokens.prev, state.tokens.curr);
  5286 		that.left = left;
  5287 		that.right = e;
  5288 		return that;
  5289 	}, 160, true);
  5291 	function comprehensiveArrayExpression() {
  5292 		var res = {};
  5293 		res.exps = true;
  5294 		funct["(comparray)"].stack();
  5296 		res.right = expression(5);
  5297 		advance("for");
  5298 		if (state.tokens.next.value === "each") {
  5299 			advance("each");
  5300 			if (!state.option.inMoz(true)) {
  5301 				warning("W118", state.tokens.curr, "for each");
  5304 		advance("(");
  5305 		funct["(comparray)"].setState("define");
  5306 		res.left = expression(5);
  5307 		advance(")");
  5308 		if (state.tokens.next.value === "if") {
  5309 			advance("if");
  5310 			advance("(");
  5311 			funct["(comparray)"].setState("filter");
  5312 			res.filter = expression(5);
  5313 			advance(")");
  5315 		advance("]");
  5316 		funct["(comparray)"].unstack();
  5317 		return res;
  5320 	prefix("[", function () {
  5321 		var blocktype = lookupBlockType(true);
  5322 		if (blocktype.isCompArray) {
  5323 			if (!state.option.inMoz(true)) {
  5324 				warning("W118", state.tokens.curr, "array comprehension");
  5326 			return comprehensiveArrayExpression();
  5327 		} else if (blocktype.isDestAssign && !state.option.inESNext()) {
  5328 			warning("W104", state.tokens.curr, "destructuring assignment");
  5330 		var b = state.tokens.curr.line !== state.tokens.next.line;
  5331 		this.first = [];
  5332 		if (b) {
  5333 			indent += state.option.indent;
  5334 			if (state.tokens.next.from === indent + state.option.indent) {
  5335 				indent += state.option.indent;
  5338 		while (state.tokens.next.id !== "(end)") {
  5339 			while (state.tokens.next.id === ",") {
  5340 				if (!state.option.inES5())
  5341 					warning("W070");
  5342 				advance(",");
  5344 			if (state.tokens.next.id === "]") {
  5345 				break;
  5347 			if (b && state.tokens.curr.line !== state.tokens.next.line) {
  5348 				indentation();
  5350 			this.first.push(expression(10));
  5351 			if (state.tokens.next.id === ",") {
  5352 				comma({ allowTrailing: true });
  5353 				if (state.tokens.next.id === "]" && !state.option.inES5(true)) {
  5354 					warning("W070", state.tokens.curr);
  5355 					break;
  5357 			} else {
  5358 				break;
  5361 		if (b) {
  5362 			indent -= state.option.indent;
  5363 			indentation();
  5365 		advance("]", this);
  5366 		return this;
  5367 	}, 160);
  5370 	function property_name() {
  5371 		var id = optionalidentifier(false, true);
  5373 		if (!id) {
  5374 			if (state.tokens.next.id === "(string)") {
  5375 				id = state.tokens.next.value;
  5376 				advance();
  5377 			} else if (state.tokens.next.id === "(number)") {
  5378 				id = state.tokens.next.value.toString();
  5379 				advance();
  5383 		if (id === "hasOwnProperty") {
  5384 			warning("W001");
  5387 		return id;
  5391 	function functionparams(parsed) {
  5392 		var curr, next;
  5393 		var params = [];
  5394 		var ident;
  5395 		var tokens = [];
  5396 		var t;
  5398 		if (parsed) {
  5399 			if (parsed instanceof Array) {
  5400 				for (var i in parsed) {
  5401 					curr = parsed[i];
  5402 					if (_.contains(["{", "["], curr.id)) {
  5403 						for (t in curr.left) {
  5404 							t = tokens[t];
  5405 							if (t.id) {
  5406 								params.push(t.id);
  5407 								addlabel(t.id, "unused", t.token);
  5410 					} else if (curr.value === "...") {
  5411 						if (!state.option.inESNext()) {
  5412 							warning("W104", curr, "spread/rest operator");
  5414 						continue;
  5415 					} else {
  5416 						addlabel(curr.value, "unused", curr);
  5419 				return params;
  5420 			} else {
  5421 				if (parsed.identifier === true) {
  5422 					addlabel(parsed.value, "unused", parsed);
  5423 					return [parsed];
  5428 		next = state.tokens.next;
  5430 		advance("(");
  5431 		nospace();
  5433 		if (state.tokens.next.id === ")") {
  5434 			advance(")");
  5435 			return;
  5438 		for (;;) {
  5439 			if (_.contains(["{", "["], state.tokens.next.id)) {
  5440 				tokens = destructuringExpression();
  5441 				for (t in tokens) {
  5442 					t = tokens[t];
  5443 					if (t.id) {
  5444 						params.push(t.id);
  5445 						addlabel(t.id, "unused", t.token);
  5448 			} else if (state.tokens.next.value === "...") {
  5449 				if (!state.option.inESNext()) {
  5450 					warning("W104", state.tokens.next, "spread/rest operator");
  5452 				advance("...");
  5453 				nospace();
  5454 				ident = identifier(true);
  5455 				params.push(ident);
  5456 				addlabel(ident, "unused", state.tokens.curr);
  5457 			} else {
  5458 				ident = identifier(true);
  5459 				params.push(ident);
  5460 				addlabel(ident, "unused", state.tokens.curr);
  5462 			if (state.tokens.next.id === ",") {
  5463 				comma();
  5464 			} else {
  5465 				advance(")", next);
  5466 				nospace(state.tokens.prev, state.tokens.curr);
  5467 				return params;
  5473 	function doFunction(name, statement, generator, fatarrowparams) {
  5474 		var f;
  5475 		var oldOption = state.option;
  5476 		var oldIgnored = state.ignored;
  5477 		var oldScope  = scope;
  5479 		state.option = Object.create(state.option);
  5480 		state.ignored = Object.create(state.ignored);
  5481 		scope  = Object.create(scope);
  5483 		funct = {
  5484 			"(name)"      : name || "\"" + anonname + "\"",
  5485 			"(line)"      : state.tokens.next.line,
  5486 			"(character)" : state.tokens.next.character,
  5487 			"(context)"   : funct,
  5488 			"(breakage)"  : 0,
  5489 			"(loopage)"   : 0,
  5490 			"(metrics)"   : createMetrics(state.tokens.next),
  5491 			"(scope)"     : scope,
  5492 			"(statement)" : statement,
  5493 			"(tokens)"    : {},
  5494 			"(blockscope)": funct["(blockscope)"],
  5495 			"(comparray)" : funct["(comparray)"]
  5496 		};
  5498 		if (generator) {
  5499 			funct["(generator)"] = true;
  5502 		f = funct;
  5503 		state.tokens.curr.funct = funct;
  5505 		functions.push(funct);
  5507 		if (name) {
  5508 			addlabel(name, "function");
  5511 		funct["(params)"] = functionparams(fatarrowparams);
  5513 		funct["(metrics)"].verifyMaxParametersPerFunction(funct["(params)"]);
  5515 		block(false, true, true, fatarrowparams ? true:false);
  5517 		if (generator && funct["(generator)"] !== "yielded") {
  5518 			error("E047", state.tokens.curr);
  5521 		funct["(metrics)"].verifyMaxStatementsPerFunction();
  5522 		funct["(metrics)"].verifyMaxComplexityPerFunction();
  5523 		funct["(unusedOption)"] = state.option.unused;
  5525 		scope = oldScope;
  5526 		state.option = oldOption;
  5527 		state.ignored = oldIgnored;
  5528 		funct["(last)"] = state.tokens.curr.line;
  5529 		funct["(lastcharacter)"] = state.tokens.curr.character;
  5530 		funct = funct["(context)"];
  5532 		return f;
  5535 	function createMetrics(functionStartToken) {
  5536 		return {
  5537 			statementCount: 0,
  5538 			nestedBlockDepth: -1,
  5539 			ComplexityCount: 1,
  5540 			verifyMaxStatementsPerFunction: function () {
  5541 				if (state.option.maxstatements &&
  5542 					this.statementCount > state.option.maxstatements) {
  5543 					warning("W071", functionStartToken, this.statementCount);
  5545 			},
  5547 			verifyMaxParametersPerFunction: function (params) {
  5548 				params = params || [];
  5550 				if (state.option.maxparams && params.length > state.option.maxparams) {
  5551 					warning("W072", functionStartToken, params.length);
  5553 			},
  5555 			verifyMaxNestedBlockDepthPerFunction: function () {
  5556 				if (state.option.maxdepth &&
  5557 					this.nestedBlockDepth > 0 &&
  5558 					this.nestedBlockDepth === state.option.maxdepth + 1) {
  5559 					warning("W073", null, this.nestedBlockDepth);
  5561 			},
  5563 			verifyMaxComplexityPerFunction: function () {
  5564 				var max = state.option.maxcomplexity;
  5565 				var cc = this.ComplexityCount;
  5566 				if (max && cc > max) {
  5567 					warning("W074", functionStartToken, cc);
  5570 		};
  5573 	function increaseComplexityCount() {
  5574 		funct["(metrics)"].ComplexityCount += 1;
  5577 	// Parse assignments that were found instead of conditionals.
  5578 	// For example: if (a = 1) { ... }
  5580 	function checkCondAssignment(expr) {
  5581 		var id = expr.id;
  5582 		if (id === ",") {
  5583 			expr = expr.exprs[expr.exprs.length - 1];
  5584 			id = expr.id;
  5586 		switch (id) {
  5587 		case "=":
  5588 		case "+=":
  5589 		case "-=":
  5590 		case "*=":
  5591 		case "%=":
  5592 		case "&=":
  5593 		case "|=":
  5594 		case "^=":
  5595 		case "/=":
  5596 			if (!expr.paren && !state.option.boss) {
  5597 				warning("W084");
  5603 	(function (x) {
  5604 		x.nud = function (isclassdef) {
  5605 			var b, f, i, p, t, g;
  5606 			var props = {}; // All properties, including accessors
  5607 			var tag = "";
  5609 			function saveProperty(name, tkn) {
  5610 				if (props[name] && _.has(props, name))
  5611 					warning("W075", state.tokens.next, i);
  5612 				else
  5613 					props[name] = {};
  5615 				props[name].basic = true;
  5616 				props[name].basictkn = tkn;
  5619 			function saveSetter(name, tkn) {
  5620 				if (props[name] && _.has(props, name)) {
  5621 					if (props[name].basic || props[name].setter)
  5622 						warning("W075", state.tokens.next, i);
  5623 				} else {
  5624 					props[name] = {};
  5627 				props[name].setter = true;
  5628 				props[name].setterToken = tkn;
  5631 			function saveGetter(name) {
  5632 				if (props[name] && _.has(props, name)) {
  5633 					if (props[name].basic || props[name].getter)
  5634 						warning("W075", state.tokens.next, i);
  5635 				} else {
  5636 					props[name] = {};
  5639 				props[name].getter = true;
  5640 				props[name].getterToken = state.tokens.curr;
  5643 			b = state.tokens.curr.line !== state.tokens.next.line;
  5644 			if (b) {
  5645 				indent += state.option.indent;
  5646 				if (state.tokens.next.from === indent + state.option.indent) {
  5647 					indent += state.option.indent;
  5651 			for (;;) {
  5652 				if (state.tokens.next.id === "}") {
  5653 					break;
  5656 				if (b) {
  5657 					indentation();
  5660 				if (isclassdef && state.tokens.next.value === "static") {
  5661 					advance("static");
  5662 					tag = "static ";
  5665 				if (state.tokens.next.value === "get" && peek().id !== ":") {
  5666 					advance("get");
  5668 					if (!state.option.inES5(!isclassdef)) {
  5669 						error("E034");
  5672 					i = property_name();
  5673 					if (!i) {
  5674 						error("E035");
  5677 					// It is a Syntax Error if PropName of MethodDefinition is
  5678 					// "constructor" and SpecialMethod of MethodDefinition is true.
  5679 					if (isclassdef && i === "constructor") {
  5680 						error("E049", state.tokens.next, "class getter method", i);
  5683 					saveGetter(tag + i);
  5684 					t = state.tokens.next;
  5685 					adjacent(state.tokens.curr, state.tokens.next);
  5686 					f = doFunction();
  5687 					p = f["(params)"];
  5689 					if (p) {
  5690 						warning("W076", t, p[0], i);
  5693 					adjacent(state.tokens.curr, state.tokens.next);
  5694 				} else if (state.tokens.next.value === "set" && peek().id !== ":") {
  5695 					advance("set");
  5697 					if (!state.option.inES5(!isclassdef)) {
  5698 						error("E034");
  5701 					i = property_name();
  5702 					if (!i) {
  5703 						error("E035");
  5706 					// It is a Syntax Error if PropName of MethodDefinition is
  5707 					// "constructor" and SpecialMethod of MethodDefinition is true.
  5708 					if (isclassdef && i === "constructor") {
  5709 						error("E049", state.tokens.next, "class setter method", i);
  5712 					saveSetter(tag + i, state.tokens.next);
  5713 					t = state.tokens.next;
  5714 					adjacent(state.tokens.curr, state.tokens.next);
  5715 					f = doFunction();
  5716 					p = f["(params)"];
  5718 					if (!p || p.length !== 1) {
  5719 						warning("W077", t, i);
  5721 				} else {
  5722 					g = false;
  5723 					if (state.tokens.next.value === "*" && state.tokens.next.type === "(punctuator)") {
  5724 						if (!state.option.inESNext()) {
  5725 							warning("W104", state.tokens.next, "generator functions");
  5727 						advance("*");
  5728 						g = true;
  5730 					i = property_name();
  5731 					saveProperty(tag + i, state.tokens.next);
  5733 					if (typeof i !== "string") {
  5734 						break;
  5737 					if (state.tokens.next.value === "(") {
  5738 						if (!state.option.inESNext()) {
  5739 							warning("W104", state.tokens.curr, "concise methods");
  5741 						doFunction(i, undefined, g);
  5742 					} else if (!isclassdef) {
  5743 						advance(":");
  5744 						nonadjacent(state.tokens.curr, state.tokens.next);
  5745 						expression(10);
  5748 				// It is a Syntax Error if PropName of MethodDefinition is "prototype".
  5749 				if (isclassdef && i === "prototype") {
  5750 					error("E049", state.tokens.next, "class method", i);
  5753 				countMember(i);
  5754 				if (isclassdef) {
  5755 					tag = "";
  5756 					continue;
  5758 				if (state.tokens.next.id === ",") {
  5759 					comma({ allowTrailing: true, property: true });
  5760 					if (state.tokens.next.id === ",") {
  5761 						warning("W070", state.tokens.curr);
  5762 					} else if (state.tokens.next.id === "}" && !state.option.inES5(true)) {
  5763 						warning("W070", state.tokens.curr);
  5765 				} else {
  5766 					break;
  5769 			if (b) {
  5770 				indent -= state.option.indent;
  5771 				indentation();
  5773 			advance("}", this);
  5775 			// Check for lonely setters if in the ES5 mode.
  5776 			if (state.option.inES5()) {
  5777 				for (var name in props) {
  5778 					if (_.has(props, name) && props[name].setter && !props[name].getter) {
  5779 						warning("W078", props[name].setterToken);
  5783 			return this;
  5784 		};
  5785 		x.fud = function () {
  5786 			error("E036", state.tokens.curr);
  5787 		};
  5788 	}(delim("{")));
  5790 	function destructuringExpression() {
  5791 		var id, ids;
  5792 		var identifiers = [];
  5793 		if (!state.option.inESNext()) {
  5794 			warning("W104", state.tokens.curr, "destructuring expression");
  5796 		var nextInnerDE = function () {
  5797 			var ident;
  5798 			if (_.contains(["[", "{"], state.tokens.next.value)) {
  5799 				ids = destructuringExpression();
  5800 				for (var id in ids) {
  5801 					id = ids[id];
  5802 					identifiers.push({ id: id.id, token: id.token });
  5804 			} else if (state.tokens.next.value === ",") {
  5805 				identifiers.push({ id: null, token: state.tokens.curr });
  5806 			} else {
  5807 				ident = identifier();
  5808 				if (ident)
  5809 					identifiers.push({ id: ident, token: state.tokens.curr });
  5811 		};
  5812 		if (state.tokens.next.value === "[") {
  5813 			advance("[");
  5814 			nextInnerDE();
  5815 			while (state.tokens.next.value !== "]") {
  5816 				advance(",");
  5817 				nextInnerDE();
  5819 			advance("]");
  5820 		} else if (state.tokens.next.value === "{") {
  5821 			advance("{");
  5822 			id = identifier();
  5823 			if (state.tokens.next.value === ":") {
  5824 				advance(":");
  5825 				nextInnerDE();
  5826 			} else {
  5827 				identifiers.push({ id: id, token: state.tokens.curr });
  5829 			while (state.tokens.next.value !== "}") {
  5830 				advance(",");
  5831 				id = identifier();
  5832 				if (state.tokens.next.value === ":") {
  5833 					advance(":");
  5834 					nextInnerDE();
  5835 				} else {
  5836 					identifiers.push({ id: id, token: state.tokens.curr });
  5839 			advance("}");
  5841 		return identifiers;
  5843 	function destructuringExpressionMatch(tokens, value) {
  5844 		if (value.first) {
  5845 			_.zip(tokens, value.first).forEach(function (val) {
  5846 				var token = val[0];
  5847 				var value = val[1];
  5848 				if (token && value) {
  5849 					token.first = value;
  5850 				} else if (token && token.first && !value) {
  5851 					warning("W080", token.first, token.first.value);
  5852 				} /* else {
  5853 					XXX value is discarded: wouldn't it need a warning ?
  5854 				} */
  5855 			});
  5859 	var conststatement = stmt("const", function (prefix) {
  5860 		var tokens, value;
  5861 		// state variable to know if it is a lone identifier, or a destructuring statement.
  5862 		var lone;
  5864 		if (!state.option.inESNext()) {
  5865 			warning("W104", state.tokens.curr, "const");
  5868 		this.first = [];
  5869 		for (;;) {
  5870 			var names = [];
  5871 			nonadjacent(state.tokens.curr, state.tokens.next);
  5872 			if (_.contains(["{", "["], state.tokens.next.value)) {
  5873 				tokens = destructuringExpression();
  5874 				lone = false;
  5875 			} else {
  5876 				tokens = [ { id: identifier(), token: state.tokens.curr } ];
  5877 				lone = true;
  5879 			for (var t in tokens) {
  5880 				t = tokens[t];
  5881 				if (funct[t.id] === "const") {
  5882 					warning("E011", null, t.id);
  5884 				if (funct["(global)"] && predefined[t.id] === false) {
  5885 					warning("W079", t.token, t.id);
  5887 				if (t.id) {
  5888 					addlabel(t.id, "const");
  5889 					names.push(t.token);
  5892 			if (prefix) {
  5893 				break;
  5896 			this.first = this.first.concat(names);
  5898 			if (state.tokens.next.id !== "=") {
  5899 				warning("E012", state.tokens.curr, state.tokens.curr.value);
  5902 			if (state.tokens.next.id === "=") {
  5903 				nonadjacent(state.tokens.curr, state.tokens.next);
  5904 				advance("=");
  5905 				nonadjacent(state.tokens.curr, state.tokens.next);
  5906 				if (state.tokens.next.id === "undefined") {
  5907 					warning("W080", state.tokens.prev, state.tokens.prev.value);
  5909 				if (peek(0).id === "=" && state.tokens.next.identifier) {
  5910 					error("E037", state.tokens.next, state.tokens.next.value);
  5912 				value = expression(5);
  5913 				if (lone) {
  5914 					tokens[0].first = value;
  5915 				} else {
  5916 					destructuringExpressionMatch(names, value);
  5920 			if (state.tokens.next.id !== ",") {
  5921 				break;
  5923 			comma();
  5925 		return this;
  5926 	});
  5927 	conststatement.exps = true;
  5928 	var varstatement = stmt("var", function (prefix) {
  5929 		// JavaScript does not have block scope. It only has function scope. So,
  5930 		// declaring a variable in a block can have unexpected consequences.
  5931 		var tokens, lone, value;
  5933 		if (funct["(onevar)"] && state.option.onevar) {
  5934 			warning("W081");
  5935 		} else if (!funct["(global)"]) {
  5936 			funct["(onevar)"] = true;
  5939 		this.first = [];
  5940 		for (;;) {
  5941 			var names = [];
  5942 			nonadjacent(state.tokens.curr, state.tokens.next);
  5943 			if (_.contains(["{", "["], state.tokens.next.value)) {
  5944 				tokens = destructuringExpression();
  5945 				lone = false;
  5946 			} else {
  5947 				tokens = [ { id: identifier(), token: state.tokens.curr } ];
  5948 				lone = true;
  5950 			for (var t in tokens) {
  5951 				t = tokens[t];
  5952 				if (state.option.inESNext() && funct[t.id] === "const") {
  5953 					warning("E011", null, t.id);
  5955 				if (funct["(global)"] && predefined[t.id] === false) {
  5956 					warning("W079", t.token, t.id);
  5958 				if (t.id) {
  5959 					addlabel(t.id, "unused", t.token);
  5960 					names.push(t.token);
  5963 			if (prefix) {
  5964 				break;
  5967 			this.first = this.first.concat(names);
  5969 			if (state.tokens.next.id === "=") {
  5970 				nonadjacent(state.tokens.curr, state.tokens.next);
  5971 				advance("=");
  5972 				nonadjacent(state.tokens.curr, state.tokens.next);
  5973 				if (state.tokens.next.id === "undefined") {
  5974 					warning("W080", state.tokens.prev, state.tokens.prev.value);
  5976 				if (peek(0).id === "=" && state.tokens.next.identifier) {
  5977 					error("E038", state.tokens.next, state.tokens.next.value);
  5979 				value = expression(5);
  5980 				if (lone) {
  5981 					tokens[0].first = value;
  5982 				} else {
  5983 					destructuringExpressionMatch(names, value);
  5987 			if (state.tokens.next.id !== ",") {
  5988 				break;
  5990 			comma();
  5992 		return this;
  5993 	});
  5994 	varstatement.exps = true;
  5995 	var letstatement = stmt("let", function (prefix) {
  5996 		var tokens, lone, value, letblock;
  5998 		if (!state.option.inESNext()) {
  5999 			warning("W104", state.tokens.curr, "let");
  6002 		if (state.tokens.next.value === "(") {
  6003 			if (!state.option.inMoz(true)) {
  6004 				warning("W118", state.tokens.next, "let block");
  6006 			advance("(");
  6007 			funct["(blockscope)"].stack();
  6008 			letblock = true;
  6009 		} else if (funct["(nolet)"]) {
  6010 			error("E048", state.tokens.curr);
  6013 		if (funct["(onevar)"] && state.option.onevar) {
  6014 			warning("W081");
  6015 		} else if (!funct["(global)"]) {
  6016 			funct["(onevar)"] = true;
  6019 		this.first = [];
  6020 		for (;;) {
  6021 			var names = [];
  6022 			nonadjacent(state.tokens.curr, state.tokens.next);
  6023 			if (_.contains(["{", "["], state.tokens.next.value)) {
  6024 				tokens = destructuringExpression();
  6025 				lone = false;
  6026 			} else {
  6027 				tokens = [ { id: identifier(), token: state.tokens.curr.value } ];
  6028 				lone = true;
  6030 			for (var t in tokens) {
  6031 				t = tokens[t];
  6032 				if (state.option.inESNext() && funct[t.id] === "const") {
  6033 					warning("E011", null, t.id);
  6035 				if (funct["(global)"] && predefined[t.id] === false) {
  6036 					warning("W079", t.token, t.id);
  6038 				if (t.id && !funct["(nolet)"]) {
  6039 					addlabel(t.id, "unused", t.token, true);
  6040 					names.push(t.token);
  6043 			if (prefix) {
  6044 				break;
  6047 			this.first = this.first.concat(names);
  6049 			if (state.tokens.next.id === "=") {
  6050 				nonadjacent(state.tokens.curr, state.tokens.next);
  6051 				advance("=");
  6052 				nonadjacent(state.tokens.curr, state.tokens.next);
  6053 				if (state.tokens.next.id === "undefined") {
  6054 					warning("W080", state.tokens.prev, state.tokens.prev.value);
  6056 				if (peek(0).id === "=" && state.tokens.next.identifier) {
  6057 					error("E037", state.tokens.next, state.tokens.next.value);
  6059 				value = expression(5);
  6060 				if (lone) {
  6061 					tokens[0].first = value;
  6062 				} else {
  6063 					destructuringExpressionMatch(names, value);
  6067 			if (state.tokens.next.id !== ",") {
  6068 				break;
  6070 			comma();
  6072 		if (letblock) {
  6073 			advance(")");
  6074 			block(true, true);
  6075 			this.block = true;
  6076 			funct["(blockscope)"].unstack();
  6079 		return this;
  6080 	});
  6081 	letstatement.exps = true;
  6083 	blockstmt("class", function () {
  6084 		return classdef.call(this, true);
  6085 	});
  6087 	function classdef(stmt) {
  6088 		/*jshint validthis:true */
  6089 		if (!state.option.inESNext()) {
  6090 			warning("W104", state.tokens.curr, "class");
  6092 		if (stmt) {
  6093 			// BindingIdentifier
  6094 			this.name = identifier();
  6095 			addlabel(this.name, "unused", state.tokens.curr);
  6096 		} else if (state.tokens.next.identifier && state.tokens.next.value !== "extends") {
  6097 			// BindingIdentifier(opt)
  6098 			this.name = identifier();
  6100 		classtail(this);
  6101 		return this;
  6104 	function classtail(c) {
  6105 		var strictness = state.directive["use strict"];
  6107 		// ClassHeritage(opt)
  6108 		if (state.tokens.next.value === "extends") {
  6109 			advance("extends");
  6110 			c.heritage = expression(10);
  6113 		// A ClassBody is always strict code.
  6114 		state.directive["use strict"] = true;
  6115 		advance("{");
  6116 		// ClassBody(opt)
  6117 		c.body = state.syntax["{"].nud(true);
  6118 		state.directive["use strict"] = strictness;
  6121 	blockstmt("function", function () {
  6122 		var generator = false;
  6123 		if (state.tokens.next.value === "*") {
  6124 			advance("*");
  6125 			if (state.option.inESNext(true)) {
  6126 				generator = true;
  6127 			} else {
  6128 				warning("W119", state.tokens.curr, "function*");
  6131 		if (inblock) {
  6132 			warning("W082", state.tokens.curr);
  6135 		var i = identifier();
  6136 		if (funct[i] === "const") {
  6137 			warning("E011", null, i);
  6139 		adjacent(state.tokens.curr, state.tokens.next);
  6140 		addlabel(i, "unction", state.tokens.curr);
  6142 		doFunction(i, { statement: true }, generator);
  6143 		if (state.tokens.next.id === "(" && state.tokens.next.line === state.tokens.curr.line) {
  6144 			error("E039");
  6146 		return this;
  6147 	});
  6149 	prefix("function", function () {
  6150 		var generator = false;
  6151 		if (state.tokens.next.value === "*") {
  6152 			if (!state.option.inESNext()) {
  6153 				warning("W119", state.tokens.curr, "function*");
  6155 			advance("*");
  6156 			generator = true;
  6158 		var i = optionalidentifier();
  6159 		if (i || state.option.gcl) {
  6160 			adjacent(state.tokens.curr, state.tokens.next);
  6161 		} else {
  6162 			nonadjacent(state.tokens.curr, state.tokens.next);
  6164 		doFunction(i, undefined, generator);
  6165 		if (!state.option.loopfunc && funct["(loopage)"]) {
  6166 			warning("W083");
  6168 		return this;
  6169 	});
  6171 	blockstmt("if", function () {
  6172 		var t = state.tokens.next;
  6173 		increaseComplexityCount();
  6174 		state.condition = true;
  6175 		advance("(");
  6176 		nonadjacent(this, t);
  6177 		nospace();
  6178 		checkCondAssignment(expression(0));
  6179 		advance(")", t);
  6180 		state.condition = false;
  6181 		nospace(state.tokens.prev, state.tokens.curr);
  6182 		block(true, true);
  6183 		if (state.tokens.next.id === "else") {
  6184 			nonadjacent(state.tokens.curr, state.tokens.next);
  6185 			advance("else");
  6186 			if (state.tokens.next.id === "if" || state.tokens.next.id === "switch") {
  6187 				statement(true);
  6188 			} else {
  6189 				block(true, true);
  6192 		return this;
  6193 	});
  6195 	blockstmt("try", function () {
  6196 		var b;
  6198 		function doCatch() {
  6199 			var oldScope = scope;
  6200 			var e;
  6202 			advance("catch");
  6203 			nonadjacent(state.tokens.curr, state.tokens.next);
  6204 			advance("(");
  6206 			scope = Object.create(oldScope);
  6208 			e = state.tokens.next.value;
  6209 			if (state.tokens.next.type !== "(identifier)") {
  6210 				e = null;
  6211 				warning("E030", state.tokens.next, e);
  6214 			advance();
  6216 			funct = {
  6217 				"(name)"     : "(catch)",
  6218 				"(line)"     : state.tokens.next.line,
  6219 				"(character)": state.tokens.next.character,
  6220 				"(context)"  : funct,
  6221 				"(breakage)" : funct["(breakage)"],
  6222 				"(loopage)"  : funct["(loopage)"],
  6223 				"(scope)"    : scope,
  6224 				"(statement)": false,
  6225 				"(metrics)"  : createMetrics(state.tokens.next),
  6226 				"(catch)"    : true,
  6227 				"(tokens)"   : {},
  6228 				"(blockscope)": funct["(blockscope)"],
  6229 				"(comparray)": funct["(comparray)"]
  6230 			};
  6232 			if (e) {
  6233 				addlabel(e, "exception");
  6236 			if (state.tokens.next.value === "if") {
  6237 				if (!state.option.inMoz(true)) {
  6238 					warning("W118", state.tokens.curr, "catch filter");
  6240 				advance("if");
  6241 				expression(0);
  6244 			advance(")");
  6246 			state.tokens.curr.funct = funct;
  6247 			functions.push(funct);
  6249 			block(false);
  6251 			scope = oldScope;
  6253 			funct["(last)"] = state.tokens.curr.line;
  6254 			funct["(lastcharacter)"] = state.tokens.curr.character;
  6255 			funct = funct["(context)"];
  6258 		block(false);
  6260 		while (state.tokens.next.id === "catch") {
  6261 			increaseComplexityCount();
  6262 			if (b && (!state.option.inMoz(true))) {
  6263 				warning("W118", state.tokens.next, "multiple catch blocks");
  6265 			doCatch();
  6266 			b = true;
  6269 		if (state.tokens.next.id === "finally") {
  6270 			advance("finally");
  6271 			block(false);
  6272 			return;
  6275 		if (!b) {
  6276 			error("E021", state.tokens.next, "catch", state.tokens.next.value);
  6279 		return this;
  6280 	});
  6282 	blockstmt("while", function () {
  6283 		var t = state.tokens.next;
  6284 		funct["(breakage)"] += 1;
  6285 		funct["(loopage)"] += 1;
  6286 		increaseComplexityCount();
  6287 		advance("(");
  6288 		nonadjacent(this, t);
  6289 		nospace();
  6290 		checkCondAssignment(expression(0));
  6291 		advance(")", t);
  6292 		nospace(state.tokens.prev, state.tokens.curr);
  6293 		block(true, true);
  6294 		funct["(breakage)"] -= 1;
  6295 		funct["(loopage)"] -= 1;
  6296 		return this;
  6297 	}).labelled = true;
  6299 	blockstmt("with", function () {
  6300 		var t = state.tokens.next;
  6301 		if (state.directive["use strict"]) {
  6302 			error("E010", state.tokens.curr);
  6303 		} else if (!state.option.withstmt) {
  6304 			warning("W085", state.tokens.curr);
  6307 		advance("(");
  6308 		nonadjacent(this, t);
  6309 		nospace();
  6310 		expression(0);
  6311 		advance(")", t);
  6312 		nospace(state.tokens.prev, state.tokens.curr);
  6313 		block(true, true);
  6315 		return this;
  6316 	});
  6318 	blockstmt("switch", function () {
  6319 		var t = state.tokens.next,
  6320 			g = false;
  6321 		funct["(breakage)"] += 1;
  6322 		advance("(");
  6323 		nonadjacent(this, t);
  6324 		nospace();
  6325 		checkCondAssignment(expression(0));
  6326 		advance(")", t);
  6327 		nospace(state.tokens.prev, state.tokens.curr);
  6328 		nonadjacent(state.tokens.curr, state.tokens.next);
  6329 		t = state.tokens.next;
  6330 		advance("{");
  6331 		nonadjacent(state.tokens.curr, state.tokens.next);
  6332 		indent += state.option.indent;
  6333 		this.cases = [];
  6335 		for (;;) {
  6336 			switch (state.tokens.next.id) {
  6337 			case "case":
  6338 				switch (funct["(verb)"]) {
  6339 				case "yield":
  6340 				case "break":
  6341 				case "case":
  6342 				case "continue":
  6343 				case "return":
  6344 				case "switch":
  6345 				case "throw":
  6346 					break;
  6347 				default:
  6348 					// You can tell JSHint that you don't use break intentionally by
  6349 					// adding a comment /* falls through */ on a line just before
  6350 					// the next `case`.
  6351 					if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) {
  6352 						warning("W086", state.tokens.curr, "case");
  6355 				indentation(-state.option.indent);
  6356 				advance("case");
  6357 				this.cases.push(expression(20));
  6358 				increaseComplexityCount();
  6359 				g = true;
  6360 				advance(":");
  6361 				funct["(verb)"] = "case";
  6362 				break;
  6363 			case "default":
  6364 				switch (funct["(verb)"]) {
  6365 				case "yield":
  6366 				case "break":
  6367 				case "continue":
  6368 				case "return":
  6369 				case "throw":
  6370 					break;
  6371 				default:
  6372 					// Do not display a warning if 'default' is the first statement or if
  6373 					// there is a special /* falls through */ comment.
  6374 					if (this.cases.length) {
  6375 						if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) {
  6376 							warning("W086", state.tokens.curr, "default");
  6380 				indentation(-state.option.indent);
  6381 				advance("default");
  6382 				g = true;
  6383 				advance(":");
  6384 				break;
  6385 			case "}":
  6386 				indent -= state.option.indent;
  6387 				indentation();
  6388 				advance("}", t);
  6389 				funct["(breakage)"] -= 1;
  6390 				funct["(verb)"] = undefined;
  6391 				return;
  6392 			case "(end)":
  6393 				error("E023", state.tokens.next, "}");
  6394 				return;
  6395 			default:
  6396 				if (g) {
  6397 					switch (state.tokens.curr.id) {
  6398 					case ",":
  6399 						error("E040");
  6400 						return;
  6401 					case ":":
  6402 						g = false;
  6403 						statements();
  6404 						break;
  6405 					default:
  6406 						error("E025", state.tokens.curr);
  6407 						return;
  6409 				} else {
  6410 					if (state.tokens.curr.id === ":") {
  6411 						advance(":");
  6412 						error("E024", state.tokens.curr, ":");
  6413 						statements();
  6414 					} else {
  6415 						error("E021", state.tokens.next, "case", state.tokens.next.value);
  6416 						return;
  6421 	}).labelled = true;
  6423 	stmt("debugger", function () {
  6424 		if (!state.option.debug) {
  6425 			warning("W087");
  6427 		return this;
  6428 	}).exps = true;
  6430 	(function () {
  6431 		var x = stmt("do", function () {
  6432 			funct["(breakage)"] += 1;
  6433 			funct["(loopage)"] += 1;
  6434 			increaseComplexityCount();
  6436 			this.first = block(true, true);
  6437 			advance("while");
  6438 			var t = state.tokens.next;
  6439 			nonadjacent(state.tokens.curr, t);
  6440 			advance("(");
  6441 			nospace();
  6442 			checkCondAssignment(expression(0));
  6443 			advance(")", t);
  6444 			nospace(state.tokens.prev, state.tokens.curr);
  6445 			funct["(breakage)"] -= 1;
  6446 			funct["(loopage)"] -= 1;
  6447 			return this;
  6448 		});
  6449 		x.labelled = true;
  6450 		x.exps = true;
  6451 	}());
  6453 	blockstmt("for", function () {
  6454 		var s, t = state.tokens.next;
  6455 		var letscope = false;
  6456 		var foreachtok = null;
  6458 		if (t.value === "each") {
  6459 			foreachtok = t;
  6460 			advance("each");
  6461 			if (!state.option.inMoz(true)) {
  6462 				warning("W118", state.tokens.curr, "for each");
  6466 		funct["(breakage)"] += 1;
  6467 		funct["(loopage)"] += 1;
  6468 		increaseComplexityCount();
  6469 		advance("(");
  6470 		nonadjacent(this, t);
  6471 		nospace();
  6473 		// what kind of for(…) statement it is? for(…of…)? for(…in…)? for(…;…;…)?
  6474 		var nextop; // contains the token of the "in" or "of" operator
  6475 		var i = 0;
  6476 		var inof = ["in", "of"];
  6477 		do {
  6478 			nextop = peek(i);
  6479 			++i;
  6480 		} while (!_.contains(inof, nextop.value) && nextop.value !== ";" &&
  6481 					nextop.type !== "(end)");
  6483 		// if we're in a for (… in|of …) statement
  6484 		if (_.contains(inof, nextop.value)) {
  6485 			if (!state.option.inESNext() && nextop.value === "of") {
  6486 				error("W104", nextop, "for of");
  6488 			if (state.tokens.next.id === "var") {
  6489 				advance("var");
  6490 				state.syntax["var"].fud.call(state.syntax["var"].fud, true);
  6491 			} else if (state.tokens.next.id === "let") {
  6492 				advance("let");
  6493 				// create a new block scope
  6494 				letscope = true;
  6495 				funct["(blockscope)"].stack();
  6496 				state.syntax["let"].fud.call(state.syntax["let"].fud, true);
  6497 			} else {
  6498 				switch (funct[state.tokens.next.value]) {
  6499 				case "unused":
  6500 					funct[state.tokens.next.value] = "var";
  6501 					break;
  6502 				case "var":
  6503 					break;
  6504 				default:
  6505 					if (!funct["(blockscope)"].getlabel(state.tokens.next.value))
  6506 						warning("W088", state.tokens.next, state.tokens.next.value);
  6508 				advance();
  6510 			advance(nextop.value);
  6511 			expression(20);
  6512 			advance(")", t);
  6513 			s = block(true, true);
  6514 			if (state.option.forin && s && (s.length > 1 || typeof s[0] !== "object" ||
  6515 					s[0].value !== "if")) {
  6516 				warning("W089", this);
  6518 			funct["(breakage)"] -= 1;
  6519 			funct["(loopage)"] -= 1;
  6520 		} else {
  6521 			if (foreachtok) {
  6522 				error("E045", foreachtok);
  6524 			if (state.tokens.next.id !== ";") {
  6525 				if (state.tokens.next.id === "var") {
  6526 					advance("var");
  6527 					state.syntax["var"].fud.call(state.syntax["var"].fud);
  6528 				} else if (state.tokens.next.id === "let") {
  6529 					advance("let");
  6530 					// create a new block scope
  6531 					letscope = true;
  6532 					funct["(blockscope)"].stack();
  6533 					state.syntax["let"].fud.call(state.syntax["let"].fud);
  6534 				} else {
  6535 					for (;;) {
  6536 						expression(0, "for");
  6537 						if (state.tokens.next.id !== ",") {
  6538 							break;
  6540 						comma();
  6544 			nolinebreak(state.tokens.curr);
  6545 			advance(";");
  6546 			if (state.tokens.next.id !== ";") {
  6547 				checkCondAssignment(expression(0));
  6549 			nolinebreak(state.tokens.curr);
  6550 			advance(";");
  6551 			if (state.tokens.next.id === ";") {
  6552 				error("E021", state.tokens.next, ")", ";");
  6554 			if (state.tokens.next.id !== ")") {
  6555 				for (;;) {
  6556 					expression(0, "for");
  6557 					if (state.tokens.next.id !== ",") {
  6558 						break;
  6560 					comma();
  6563 			advance(")", t);
  6564 			nospace(state.tokens.prev, state.tokens.curr);
  6565 			block(true, true);
  6566 			funct["(breakage)"] -= 1;
  6567 			funct["(loopage)"] -= 1;
  6570 		// unstack loop blockscope
  6571 		if (letscope) {
  6572 			funct["(blockscope)"].unstack();
  6574 		return this;
  6575 	}).labelled = true;
  6578 	stmt("break", function () {
  6579 		var v = state.tokens.next.value;
  6581 		if (funct["(breakage)"] === 0)
  6582 			warning("W052", state.tokens.next, this.value);
  6584 		if (!state.option.asi)
  6585 			nolinebreak(this);
  6587 		if (state.tokens.next.id !== ";") {
  6588 			if (state.tokens.curr.line === state.tokens.next.line) {
  6589 				if (funct[v] !== "label") {
  6590 					warning("W090", state.tokens.next, v);
  6591 				} else if (scope[v] !== funct) {
  6592 					warning("W091", state.tokens.next, v);
  6594 				this.first = state.tokens.next;
  6595 				advance();
  6598 		reachable("break");
  6599 		return this;
  6600 	}).exps = true;
  6603 	stmt("continue", function () {
  6604 		var v = state.tokens.next.value;
  6606 		if (funct["(breakage)"] === 0)
  6607 			warning("W052", state.tokens.next, this.value);
  6609 		if (!state.option.asi)
  6610 			nolinebreak(this);
  6612 		if (state.tokens.next.id !== ";") {
  6613 			if (state.tokens.curr.line === state.tokens.next.line) {
  6614 				if (funct[v] !== "label") {
  6615 					warning("W090", state.tokens.next, v);
  6616 				} else if (scope[v] !== funct) {
  6617 					warning("W091", state.tokens.next, v);
  6619 				this.first = state.tokens.next;
  6620 				advance();
  6622 		} else if (!funct["(loopage)"]) {
  6623 			warning("W052", state.tokens.next, this.value);
  6625 		reachable("continue");
  6626 		return this;
  6627 	}).exps = true;
  6630 	stmt("return", function () {
  6631 		if (this.line === state.tokens.next.line) {
  6632 			if (state.tokens.next.id === "(regexp)")
  6633 				warning("W092");
  6635 			if (state.tokens.next.id !== ";" && !state.tokens.next.reach) {
  6636 				nonadjacent(state.tokens.curr, state.tokens.next);
  6637 				this.first = expression(0);
  6639 				if (this.first &&
  6640 						this.first.type === "(punctuator)" && this.first.value === "=" && !state.option.boss) {
  6641 					warningAt("W093", this.first.line, this.first.character);
  6644 		} else {
  6645 			if (state.tokens.next.type === "(punctuator)" &&
  6646 				["[", "{", "+", "-"].indexOf(state.tokens.next.value) > -1) {
  6647 				nolinebreak(this); // always warn (Line breaking error)
  6650 		reachable("return");
  6651 		return this;
  6652 	}).exps = true;
  6654 	stmt("yield", function () {
  6655 		if (state.option.inESNext(true) && funct["(generator)"] !== true) {
  6656 			error("E046", state.tokens.curr, "yield");
  6657 		} else if (!state.option.inESNext()) {
  6658 			warning("W104", state.tokens.curr, "yield");
  6660 		funct["(generator)"] = "yielded";
  6661 		if (this.line === state.tokens.next.line) {
  6662 			if (state.tokens.next.id === "(regexp)")
  6663 				warning("W092");
  6665 			if (state.tokens.next.id !== ";" && !state.tokens.next.reach) {
  6666 				nonadjacent(state.tokens.curr, state.tokens.next);
  6667 				this.first = expression(0);
  6669 				if (this.first.type === "(punctuator)" && this.first.value === "=" && !state.option.boss) {
  6670 					warningAt("W093", this.first.line, this.first.character);
  6673 		} else if (!state.option.asi) {
  6674 			nolinebreak(this); // always warn (Line breaking error)
  6676 		return this;
  6677 	}).exps = true;
  6680 	stmt("throw", function () {
  6681 		nolinebreak(this);
  6682 		nonadjacent(state.tokens.curr, state.tokens.next);
  6683 		this.first = expression(20);
  6684 		reachable("throw");
  6685 		return this;
  6686 	}).exps = true;
  6688 	// Future Reserved Words
  6690 	FutureReservedWord("abstract");
  6691 	FutureReservedWord("boolean");
  6692 	FutureReservedWord("byte");
  6693 	FutureReservedWord("char");
  6694 	FutureReservedWord("class", { es5: true, nud: classdef });
  6695 	FutureReservedWord("double");
  6696 	FutureReservedWord("enum", { es5: true });
  6697 	FutureReservedWord("export", { es5: true });
  6698 	FutureReservedWord("extends", { es5: true });
  6699 	FutureReservedWord("final");
  6700 	FutureReservedWord("float");
  6701 	FutureReservedWord("goto");
  6702 	FutureReservedWord("implements", { es5: true, strictOnly: true });
  6703 	FutureReservedWord("import", { es5: true });
  6704 	FutureReservedWord("int");
  6705 	FutureReservedWord("interface", { es5: true, strictOnly: true });
  6706 	FutureReservedWord("long");
  6707 	FutureReservedWord("native");
  6708 	FutureReservedWord("package", { es5: true, strictOnly: true });
  6709 	FutureReservedWord("private", { es5: true, strictOnly: true });
  6710 	FutureReservedWord("protected", { es5: true, strictOnly: true });
  6711 	FutureReservedWord("public", { es5: true, strictOnly: true });
  6712 	FutureReservedWord("short");
  6713 	FutureReservedWord("static", { es5: true, strictOnly: true });
  6714 	FutureReservedWord("super", { es5: true });
  6715 	FutureReservedWord("synchronized");
  6716 	FutureReservedWord("throws");
  6717 	FutureReservedWord("transient");
  6718 	FutureReservedWord("volatile");
  6720 	// this function is used to determine wether a squarebracket or a curlybracket
  6721 	// expression is a comprehension array, destructuring assignment or a json value.
  6723 	var lookupBlockType = function () {
  6724 		var pn, pn1;
  6725 		var i = 0;
  6726 		var bracketStack = 0;
  6727 		var ret = {};
  6728 		if (_.contains(["[", "{"], state.tokens.curr.value))
  6729 			bracketStack += 1;
  6730 		if (_.contains(["[", "{"], state.tokens.next.value))
  6731 			bracketStack += 1;
  6732 		if (_.contains(["]", "}"], state.tokens.next.value))
  6733 			bracketStack -= 1;
  6734 		do {
  6735 			pn = peek(i);
  6736 			pn1 = peek(i + 1);
  6737 			i = i + 1;
  6738 			if (_.contains(["[", "{"], pn.value)) {
  6739 				bracketStack += 1;
  6740 			} else if (_.contains(["]", "}"], pn.value)) {
  6741 				bracketStack -= 1;
  6743 			if (pn.identifier && pn.value === "for" && bracketStack === 1) {
  6744 				ret.isCompArray = true;
  6745 				ret.notJson = true;
  6746 				break;
  6748 			if (_.contains(["}", "]"], pn.value) && pn1.value === "=") {
  6749 				ret.isDestAssign = true;
  6750 				ret.notJson = true;
  6751 				break;
  6753 			if (pn.value === ";") {
  6754 				ret.isBlock = true;
  6755 				ret.notJson = true;
  6757 		} while (bracketStack > 0 && pn.id !== "(end)" && i < 15);
  6758 		return ret;
  6759 	};
  6761 	// Check whether this function has been reached for a destructuring assign with undeclared values
  6762 	function destructuringAssignOrJsonValue() {
  6763 		// lookup for the assignment (esnext only)
  6764 		// if it has semicolons, it is a block, so go parse it as a block
  6765 		// or it's not a block, but there are assignments, check for undeclared variables
  6767 		var block = lookupBlockType();
  6768 		if (block.notJson) {
  6769 			if (!state.option.inESNext() && block.isDestAssign) {
  6770 				warning("W104", state.tokens.curr, "destructuring assignment");
  6772 			statements();
  6773 		// otherwise parse json value
  6774 		} else {
  6775 			state.option.laxbreak = true;
  6776 			state.jsonMode = true;
  6777 			jsonValue();
  6781 	// array comprehension parsing function
  6782 	// parses and defines the three states of the list comprehension in order
  6783 	// to avoid defining global variables, but keeping them to the list comprehension scope
  6784 	// only. The order of the states are as follows:
  6785 	//  * "use" which will be the returned iterative part of the list comprehension
  6786 	//  * "define" which will define the variables local to the list comprehension
  6787 	//  * "filter" which will help filter out values
  6789 	var arrayComprehension = function () {
  6790 		var CompArray = function () {
  6791 			this.mode = "use";
  6792 			this.variables = [];
  6793 		};
  6794 		var _carrays = [];
  6795 		var _current;
  6796 		function declare(v) {
  6797 			var l = _current.variables.filter(function (elt) {
  6798 				// if it has, change its undef state
  6799 				if (elt.value === v) {
  6800 					elt.undef = false;
  6801 					return v;
  6803 			}).length;
  6804 			return l !== 0;
  6806 		function use(v) {
  6807 			var l = _current.variables.filter(function (elt) {
  6808 				// and if it has been defined
  6809 				if (elt.value === v && !elt.undef) {
  6810 					if (elt.unused === true) {
  6811 						elt.unused = false;
  6813 					return v;
  6815 			}).length;
  6816 			// otherwise we warn about it
  6817 			return (l === 0);
  6819 		return {stack: function () {
  6820 					_current = new CompArray();
  6821 					_carrays.push(_current);
  6822 				},
  6823 				unstack: function () {
  6824 					_current.variables.filter(function (v) {
  6825 						if (v.unused)
  6826 							warning("W098", v.token, v.value);
  6827 						if (v.undef)
  6828 							isundef(v.funct, "W117", v.token, v.value);
  6829 					});
  6830 					_carrays.splice(_carrays[_carrays.length - 1], 1);
  6831 					_current = _carrays[_carrays.length - 1];
  6832 				},
  6833 				setState: function (s) {
  6834 					if (_.contains(["use", "define", "filter"], s))
  6835 						_current.mode = s;
  6836 				},
  6837 				check: function (v) {
  6838 					// When we are in "use" state of the list comp, we enqueue that var
  6839 					if (_current && _current.mode === "use") {
  6840 						_current.variables.push({funct: funct,
  6841 													token: state.tokens.curr,
  6842 													value: v,
  6843 													undef: true,
  6844 													unused: false});
  6845 						return true;
  6846 					// When we are in "define" state of the list comp,
  6847 					} else if (_current && _current.mode === "define") {
  6848 						// check if the variable has been used previously
  6849 						if (!declare(v)) {
  6850 							_current.variables.push({funct: funct,
  6851 														token: state.tokens.curr,
  6852 														value: v,
  6853 														undef: false,
  6854 														unused: true});
  6856 						return true;
  6857 					// When we are in "filter" state,
  6858 					} else if (_current && _current.mode === "filter") {
  6859 						// we check whether current variable has been declared
  6860 						if (use(v)) {
  6861 							// if not we warn about it
  6862 							isundef(funct, "W117", state.tokens.curr, v);
  6864 						return true;
  6866 					return false;
  6868 				};
  6869 	};
  6872 	// Parse JSON
  6874 	function jsonValue() {
  6876 		function jsonObject() {
  6877 			var o = {}, t = state.tokens.next;
  6878 			advance("{");
  6879 			if (state.tokens.next.id !== "}") {
  6880 				for (;;) {
  6881 					if (state.tokens.next.id === "(end)") {
  6882 						error("E026", state.tokens.next, t.line);
  6883 					} else if (state.tokens.next.id === "}") {
  6884 						warning("W094", state.tokens.curr);
  6885 						break;
  6886 					} else if (state.tokens.next.id === ",") {
  6887 						error("E028", state.tokens.next);
  6888 					} else if (state.tokens.next.id !== "(string)") {
  6889 						warning("W095", state.tokens.next, state.tokens.next.value);
  6891 					if (o[state.tokens.next.value] === true) {
  6892 						warning("W075", state.tokens.next, state.tokens.next.value);
  6893 					} else if ((state.tokens.next.value === "__proto__" &&
  6894 						!state.option.proto) || (state.tokens.next.value === "__iterator__" &&
  6895 						!state.option.iterator)) {
  6896 						warning("W096", state.tokens.next, state.tokens.next.value);
  6897 					} else {
  6898 						o[state.tokens.next.value] = true;
  6900 					advance();
  6901 					advance(":");
  6902 					jsonValue();
  6903 					if (state.tokens.next.id !== ",") {
  6904 						break;
  6906 					advance(",");
  6909 			advance("}");
  6912 		function jsonArray() {
  6913 			var t = state.tokens.next;
  6914 			advance("[");
  6915 			if (state.tokens.next.id !== "]") {
  6916 				for (;;) {
  6917 					if (state.tokens.next.id === "(end)") {
  6918 						error("E027", state.tokens.next, t.line);
  6919 					} else if (state.tokens.next.id === "]") {
  6920 						warning("W094", state.tokens.curr);
  6921 						break;
  6922 					} else if (state.tokens.next.id === ",") {
  6923 						error("E028", state.tokens.next);
  6925 					jsonValue();
  6926 					if (state.tokens.next.id !== ",") {
  6927 						break;
  6929 					advance(",");
  6932 			advance("]");
  6935 		switch (state.tokens.next.id) {
  6936 		case "{":
  6937 			jsonObject();
  6938 			break;
  6939 		case "[":
  6940 			jsonArray();
  6941 			break;
  6942 		case "true":
  6943 		case "false":
  6944 		case "null":
  6945 		case "(number)":
  6946 		case "(string)":
  6947 			advance();
  6948 			break;
  6949 		case "-":
  6950 			advance("-");
  6951 			if (state.tokens.curr.character !== state.tokens.next.from) {
  6952 				warning("W011", state.tokens.curr);
  6954 			adjacent(state.tokens.curr, state.tokens.next);
  6955 			advance("(number)");
  6956 			break;
  6957 		default:
  6958 			error("E003", state.tokens.next);
  6962 	var blockScope = function () {
  6963 		var _current = {};
  6964 		var _variables = [_current];
  6966 		function _checkBlockLabels() {
  6967 			for (var t in _current) {
  6968 				if (_current[t]["(type)"] === "unused") {
  6969 					if (state.option.unused) {
  6970 						var tkn = _current[t]["(token)"];
  6971 						var line = tkn.line;
  6972 						var chr  = tkn.character;
  6973 						warningAt("W098", line, chr, t);
  6979 		return {
  6980 			stack: function () {
  6981 				_current = {};
  6982 				_variables.push(_current);
  6983 			},
  6985 			unstack: function () {
  6986 				_checkBlockLabels();
  6987 				_variables.splice(_variables.length - 1, 1);
  6988 				_current = _.last(_variables);
  6989 			},
  6991 			getlabel: function (l) {
  6992 				for (var i = _variables.length - 1 ; i >= 0; --i) {
  6993 					if (_.has(_variables[i], l)) {
  6994 						return _variables[i];
  6997 			},
  6999 			current: {
  7000 				has: function (t) {
  7001 					return _.has(_current, t);
  7002 				},
  7003 				add: function (t, type, tok) {
  7004 					_current[t] = { "(type)" : type,
  7005 									"(token)": tok };
  7008 		};
  7009 	};
  7011 	// The actual JSHINT function itself.
  7012 	var itself = function (s, o, g) {
  7013 		var a, i, k, x;
  7014 		var optionKeys;
  7015 		var newOptionObj = {};
  7016 		var newIgnoredObj = {};
  7018 		state.reset();
  7020 		if (o && o.scope) {
  7021 			JSHINT.scope = o.scope;
  7022 		} else {
  7023 			JSHINT.errors = [];
  7024 			JSHINT.undefs = [];
  7025 			JSHINT.internals = [];
  7026 			JSHINT.blacklist = {};
  7027 			JSHINT.scope = "(main)";
  7030 		predefined = Object.create(null);
  7031 		combine(predefined, vars.ecmaIdentifiers);
  7032 		combine(predefined, vars.reservedVars);
  7034 		combine(predefined, g || {});
  7036 		declared = Object.create(null);
  7037 		exported = Object.create(null);
  7039 		if (o) {
  7040 			a = o.predef;
  7041 			if (a) {
  7042 				if (!Array.isArray(a) && typeof a === "object") {
  7043 					a = Object.keys(a);
  7046 				a.forEach(function (item) {
  7047 					var slice, prop;
  7049 					if (item[0] === "-") {
  7050 						slice = item.slice(1);
  7051 						JSHINT.blacklist[slice] = slice;
  7052 					} else {
  7053 						prop = Object.getOwnPropertyDescriptor(o.predef, item);
  7054 						predefined[item] = prop ? prop.value : false;
  7056 				});
  7059 			optionKeys = Object.keys(o);
  7060 			for (x = 0; x < optionKeys.length; x++) {
  7061 				if (/^-W\d{3}$/g.test(optionKeys[x])) {
  7062 					newIgnoredObj[optionKeys[x].slice(1)] = true;
  7063 				} else {
  7064 					newOptionObj[optionKeys[x]] = o[optionKeys[x]];
  7066 					if (optionKeys[x] === "newcap" && o[optionKeys[x]] === false)
  7067 						newOptionObj["(explicitNewcap)"] = true;
  7069 					if (optionKeys[x] === "indent")
  7070 						newOptionObj["(explicitIndent)"] = o[optionKeys[x]] === false ? false : true;
  7075 		state.option = newOptionObj;
  7076 		state.ignored = newIgnoredObj;
  7078 		state.option.indent = state.option.indent || 4;
  7079 		state.option.maxerr = state.option.maxerr || 50;
  7081 		indent = 1;
  7082 		global = Object.create(predefined);
  7083 		scope = global;
  7084 		funct = {
  7085 			"(global)":   true,
  7086 			"(name)":	  "(global)",
  7087 			"(scope)":	  scope,
  7088 			"(breakage)": 0,
  7089 			"(loopage)":  0,
  7090 			"(tokens)":   {},
  7091 			"(metrics)":   createMetrics(state.tokens.next),
  7092 			"(blockscope)": blockScope(),
  7093 			"(comparray)": arrayComprehension()
  7094 		};
  7095 		functions = [funct];
  7096 		urls = [];
  7097 		stack = null;
  7098 		member = {};
  7099 		membersOnly = null;
  7100 		implied = {};
  7101 		inblock = false;
  7102 		lookahead = [];
  7103 		warnings = 0;
  7104 		unuseds = [];
  7106 		if (!isString(s) && !Array.isArray(s)) {
  7107 			errorAt("E004", 0);
  7108 			return false;
  7111 		api = {
  7112 			get isJSON() {
  7113 				return state.jsonMode;
  7114 			},
  7116 			getOption: function (name) {
  7117 				return state.option[name] || null;
  7118 			},
  7120 			getCache: function (name) {
  7121 				return state.cache[name];
  7122 			},
  7124 			setCache: function (name, value) {
  7125 				state.cache[name] = value;
  7126 			},
  7128 			warn: function (code, data) {
  7129 				warningAt.apply(null, [ code, data.line, data.char ].concat(data.data));
  7130 			},
  7132 			on: function (names, listener) {
  7133 				names.split(" ").forEach(function (name) {
  7134 					emitter.on(name, listener);
  7135 				}.bind(this));
  7137 		};
  7139 		emitter.removeAllListeners();
  7140 		(extraModules || []).forEach(function (func) {
  7141 			func(api);
  7142 		});
  7144 		state.tokens.prev = state.tokens.curr = state.tokens.next = state.syntax["(begin)"];
  7146 		lex = new Lexer(s);
  7148 		lex.on("warning", function (ev) {
  7149 			warningAt.apply(null, [ ev.code, ev.line, ev.character].concat(ev.data));
  7150 		});
  7152 		lex.on("error", function (ev) {
  7153 			errorAt.apply(null, [ ev.code, ev.line, ev.character ].concat(ev.data));
  7154 		});
  7156 		lex.on("fatal", function (ev) {
  7157 			quit("E041", ev.line, ev.from);
  7158 		});
  7160 		lex.on("Identifier", function (ev) {
  7161 			emitter.emit("Identifier", ev);
  7162 		});
  7164 		lex.on("String", function (ev) {
  7165 			emitter.emit("String", ev);
  7166 		});
  7168 		lex.on("Number", function (ev) {
  7169 			emitter.emit("Number", ev);
  7170 		});
  7172 		lex.start();
  7174 		// Check options
  7175 		for (var name in o) {
  7176 			if (_.has(o, name)) {
  7177 				checkOption(name, state.tokens.curr);
  7181 		assume();
  7183 		// combine the passed globals after we've assumed all our options
  7184 		combine(predefined, g || {});
  7186 		//reset values
  7187 		comma.first = true;
  7189 		try {
  7190 			advance();
  7191 			switch (state.tokens.next.id) {
  7192 			case "{":
  7193 			case "[":
  7194 				destructuringAssignOrJsonValue();
  7195 				break;
  7196 			default:
  7197 				directives();
  7199 				if (state.directive["use strict"]) {
  7200 					if (!state.option.globalstrict && !state.option.node) {
  7201 						warning("W097", state.tokens.prev);
  7205 				statements();
  7207 			advance((state.tokens.next && state.tokens.next.value !== ".")	? "(end)" : undefined);
  7208 			funct["(blockscope)"].unstack();
  7210 			var markDefined = function (name, context) {
  7211 				do {
  7212 					if (typeof context[name] === "string") {
  7213 						// JSHINT marks unused variables as 'unused' and
  7214 						// unused function declaration as 'unction'. This
  7215 						// code changes such instances back 'var' and
  7216 						// 'closure' so that the code in JSHINT.data()
  7217 						// doesn't think they're unused.
  7219 						if (context[name] === "unused")
  7220 							context[name] = "var";
  7221 						else if (context[name] === "unction")
  7222 							context[name] = "closure";
  7224 						return true;
  7227 					context = context["(context)"];
  7228 				} while (context);
  7230 				return false;
  7231 			};
  7233 			var clearImplied = function (name, line) {
  7234 				if (!implied[name])
  7235 					return;
  7237 				var newImplied = [];
  7238 				for (var i = 0; i < implied[name].length; i += 1) {
  7239 					if (implied[name][i] !== line)
  7240 						newImplied.push(implied[name][i]);
  7243 				if (newImplied.length === 0)
  7244 					delete implied[name];
  7245 				else
  7246 					implied[name] = newImplied;
  7247 			};
  7249 			var warnUnused = function (name, tkn, type, unused_opt) {
  7250 				var line = tkn.line;
  7251 				var chr  = tkn.character;
  7253 				if (unused_opt === undefined) {
  7254 					unused_opt = state.option.unused;
  7257 				if (unused_opt === true) {
  7258 					unused_opt = "last-param";
  7261 				var warnable_types = {
  7262 					"vars": ["var"],
  7263 					"last-param": ["var", "param"],
  7264 					"strict": ["var", "param", "last-param"]
  7265 				};
  7267 				if (unused_opt) {
  7268 					if (warnable_types[unused_opt] && warnable_types[unused_opt].indexOf(type) !== -1) {
  7269 						warningAt("W098", line, chr, name);
  7273 				unuseds.push({
  7274 					name: name,
  7275 					line: line,
  7276 					character: chr
  7277 				});
  7278 			};
  7280 			var checkUnused = function (func, key) {
  7281 				var type = func[key];
  7282 				var tkn = func["(tokens)"][key];
  7284 				if (key.charAt(0) === "(")
  7285 					return;
  7287 				if (type !== "unused" && type !== "unction")
  7288 					return;
  7290 				// Params are checked separately from other variables.
  7291 				if (func["(params)"] && func["(params)"].indexOf(key) !== -1)
  7292 					return;
  7294 				// Variable is in global scope and defined as exported.
  7295 				if (func["(global)"] && _.has(exported, key)) {
  7296 					return;
  7299 				warnUnused(key, tkn, "var");
  7300 			};
  7302 			// Check queued 'x is not defined' instances to see if they're still undefined.
  7303 			for (i = 0; i < JSHINT.undefs.length; i += 1) {
  7304 				k = JSHINT.undefs[i].slice(0);
  7306 				if (markDefined(k[2].value, k[0])) {
  7307 					clearImplied(k[2].value, k[2].line);
  7308 				} else if (state.option.undef) {
  7309 					warning.apply(warning, k.slice(1));
  7313 			functions.forEach(function (func) {
  7314 				if (func["(unusedOption)"] === false) {
  7315 					return;
  7318 				for (var key in func) {
  7319 					if (_.has(func, key)) {
  7320 						checkUnused(func, key);
  7324 				if (!func["(params)"])
  7325 					return;
  7327 				var params = func["(params)"].slice();
  7328 				var param  = params.pop();
  7329 				var type, unused_opt;
  7331 				while (param) {
  7332 					type = func[param];
  7333 					unused_opt = func["(unusedOption)"] || state.option.unused;
  7334 					unused_opt = unused_opt === true ? "last-param" : unused_opt;
  7336 					// 'undefined' is a special case for (function (window, undefined) { ... })();
  7337 					// patterns.
  7339 					if (param === "undefined")
  7340 						return;
  7342 					if (type === "unused" || type === "unction") {
  7343 						warnUnused(param, func["(tokens)"][param], "param", func["(unusedOption)"]);
  7344 					} else if (unused_opt === "last-param") {
  7345 						return;
  7348 					param = params.pop();
  7350 			});
  7352 			for (var key in declared) {
  7353 				if (_.has(declared, key) && !_.has(global, key)) {
  7354 					warnUnused(key, declared[key], "var");
  7358 		} catch (err) {
  7359 			if (err && err.name === "JSHintError") {
  7360 				var nt = state.tokens.next || {};
  7361 				JSHINT.errors.push({
  7362 					scope     : "(main)",
  7363 					raw       : err.raw,
  7364 					reason    : err.message,
  7365 					line      : err.line || nt.line,
  7366 					character : err.character || nt.from
  7367 				}, null);
  7368 			} else {
  7369 				throw err;
  7373 		// Loop over the listed "internals", and check them as well.
  7375 		if (JSHINT.scope === "(main)") {
  7376 			o = o || {};
  7378 			for (i = 0; i < JSHINT.internals.length; i += 1) {
  7379 				k = JSHINT.internals[i];
  7380 				o.scope = k.elem;
  7381 				itself(k.value, o, g);
  7385 		return JSHINT.errors.length === 0;
  7386 	};
  7388 	// Modules.
  7389 	itself.addModule = function (func) {
  7390 		extraModules.push(func);
  7391 	};
  7393 	itself.addModule(style.register);
  7395 	// Data summary.
  7396 	itself.data = function () {
  7397 		var data = {
  7398 			functions: [],
  7399 			options: state.option
  7400 		};
  7401 		var implieds = [];
  7402 		var members = [];
  7403 		var fu, f, i, j, n, globals;
  7405 		if (itself.errors.length) {
  7406 			data.errors = itself.errors;
  7409 		if (state.jsonMode) {
  7410 			data.json = true;
  7413 		for (n in implied) {
  7414 			if (_.has(implied, n)) {
  7415 				implieds.push({
  7416 					name: n,
  7417 					line: implied[n]
  7418 				});
  7422 		if (implieds.length > 0) {
  7423 			data.implieds = implieds;
  7426 		if (urls.length > 0) {
  7427 			data.urls = urls;
  7430 		globals = Object.keys(scope);
  7431 		if (globals.length > 0) {
  7432 			data.globals = globals;
  7435 		for (i = 1; i < functions.length; i += 1) {
  7436 			f = functions[i];
  7437 			fu = {};
  7439 			for (j = 0; j < functionicity.length; j += 1) {
  7440 				fu[functionicity[j]] = [];
  7443 			for (j = 0; j < functionicity.length; j += 1) {
  7444 				if (fu[functionicity[j]].length === 0) {
  7445 					delete fu[functionicity[j]];
  7449 			fu.name = f["(name)"];
  7450 			fu.param = f["(params)"];
  7451 			fu.line = f["(line)"];
  7452 			fu.character = f["(character)"];
  7453 			fu.last = f["(last)"];
  7454 			fu.lastcharacter = f["(lastcharacter)"];
  7455 			data.functions.push(fu);
  7458 		if (unuseds.length > 0) {
  7459 			data.unused = unuseds;
  7462 		members = [];
  7463 		for (n in member) {
  7464 			if (typeof member[n] === "number") {
  7465 				data.member = member;
  7466 				break;
  7470 		return data;
  7471 	};
  7473 	itself.jshint = itself;
  7475 	return itself;
  7476 }());
  7478 // Make JSHINT a Node module, if possible.
  7479 if (typeof exports === "object" && exports) {
  7480 	exports.JSHINT = JSHINT;
  7483 })()
  7484 },{"events":2,"../shared/vars.js":3,"./lex.js":10,"./reg.js":6,"./state.js":4,"../shared/messages.js":12,"./style.js":5,"console-browserify":7,"underscore":11}],12:[function(require,module,exports){
  7485 (function(){"use strict";
  7487 var _ = require("underscore");
  7489 var errors = {
  7490 	// JSHint options
  7491 	E001: "Bad option: '{a}'.",
  7492 	E002: "Bad option value.",
  7494 	// JSHint input
  7495 	E003: "Expected a JSON value.",
  7496 	E004: "Input is neither a string nor an array of strings.",
  7497 	E005: "Input is empty.",
  7498 	E006: "Unexpected early end of program.",
  7500 	// Strict mode
  7501 	E007: "Missing \"use strict\" statement.",
  7502 	E008: "Strict violation.",
  7503 	E009: "Option 'validthis' can't be used in a global scope.",
  7504 	E010: "'with' is not allowed in strict mode.",
  7506 	// Constants
  7507 	E011: "const '{a}' has already been declared.",
  7508 	E012: "const '{a}' is initialized to 'undefined'.",
  7509 	E013: "Attempting to override '{a}' which is a constant.",
  7511 	// Regular expressions
  7512 	E014: "A regular expression literal can be confused with '/='.",
  7513 	E015: "Unclosed regular expression.",
  7514 	E016: "Invalid regular expression.",
  7516 	// Tokens
  7517 	E017: "Unclosed comment.",
  7518 	E018: "Unbegun comment.",
  7519 	E019: "Unmatched '{a}'.",
  7520 	E020: "Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
  7521 	E021: "Expected '{a}' and instead saw '{b}'.",
  7522 	E022: "Line breaking error '{a}'.",
  7523 	E023: "Missing '{a}'.",
  7524 	E024: "Unexpected '{a}'.",
  7525 	E025: "Missing ':' on a case clause.",
  7526 	E026: "Missing '}' to match '{' from line {a}.",
  7527 	E027: "Missing ']' to match '[' form line {a}.",
  7528 	E028: "Illegal comma.",
  7529 	E029: "Unclosed string.",
  7531 	// Everything else
  7532 	E030: "Expected an identifier and instead saw '{a}'.",
  7533 	E031: "Bad assignment.", // FIXME: Rephrase
  7534 	E032: "Expected a small integer or 'false' and instead saw '{a}'.",
  7535 	E033: "Expected an operator and instead saw '{a}'.",
  7536 	E034: "get/set are ES5 features.",
  7537 	E035: "Missing property name.",
  7538 	E036: "Expected to see a statement and instead saw a block.",
  7539 	E037: "Constant {a} was not declared correctly.",
  7540 	E038: "Variable {a} was not declared correctly.",
  7541 	E039: "Function declarations are not invocable. Wrap the whole function invocation in parens.",
  7542 	E040: "Each value should have its own case label.",
  7543 	E041: "Unrecoverable syntax error.",
  7544 	E042: "Stopping.",
  7545 	E043: "Too many errors.",
  7546 	E044: "'{a}' is already defined and can't be redefined.",
  7547 	E045: "Invalid for each loop.",
  7548 	E046: "A yield statement shall be within a generator function (with syntax: `function*`)",
  7549 	E047: "A generator function shall contain a yield statement.",
  7550 	E048: "Let declaration not directly within block.",
  7551 	E049: "A {a} cannot be named '{b}'."
  7552 };
  7554 var warnings = {
  7555 	W001: "'hasOwnProperty' is a really bad name.",
  7556 	W002: "Value of '{a}' may be overwritten in IE.",
  7557 	W003: "'{a}' was used before it was defined.",
  7558 	W004: "'{a}' is already defined.",
  7559 	W005: "A dot following a number can be confused with a decimal point.",
  7560 	W006: "Confusing minuses.",
  7561 	W007: "Confusing pluses.",
  7562 	W008: "A leading decimal point can be confused with a dot: '{a}'.",
  7563 	W009: "The array literal notation [] is preferrable.",
  7564 	W010: "The object literal notation {} is preferrable.",
  7565 	W011: "Unexpected space after '{a}'.",
  7566 	W012: "Unexpected space before '{a}'.",
  7567 	W013: "Missing space after '{a}'.",
  7568 	W014: "Bad line breaking before '{a}'.",
  7569 	W015: "Expected '{a}' to have an indentation at {b} instead at {c}.",
  7570 	W016: "Unexpected use of '{a}'.",
  7571 	W017: "Bad operand.",
  7572 	W018: "Confusing use of '{a}'.",
  7573 	W019: "Use the isNaN function to compare with NaN.",
  7574 	W020: "Read only.",
  7575 	W021: "'{a}' is a function.",
  7576 	W022: "Do not assign to the exception parameter.",
  7577 	W023: "Expected an identifier in an assignment and instead saw a function invocation.",
  7578 	W024: "Expected an identifier and instead saw '{a}' (a reserved word).",
  7579 	W025: "Missing name in function declaration.",
  7580 	W026: "Inner functions should be listed at the top of the outer function.",
  7581 	W027: "Unreachable '{a}' after '{b}'.",
  7582 	W028: "Label '{a}' on {b} statement.",
  7583 	W030: "Expected an assignment or function call and instead saw an expression.",
  7584 	W031: "Do not use 'new' for side effects.",
  7585 	W032: "Unnecessary semicolon.",
  7586 	W033: "Missing semicolon.",
  7587 	W034: "Unnecessary directive \"{a}\".",
  7588 	W035: "Empty block.",
  7589 	W036: "Unexpected /*member '{a}'.",
  7590 	W037: "'{a}' is a statement label.",
  7591 	W038: "'{a}' used out of scope.",
  7592 	W039: "'{a}' is not allowed.",
  7593 	W040: "Possible strict violation.",
  7594 	W041: "Use '{a}' to compare with '{b}'.",
  7595 	W042: "Avoid EOL escaping.",
  7596 	W043: "Bad escaping of EOL. Use option multistr if needed.",
  7597 	W044: "Bad or unnecessary escaping.",
  7598 	W045: "Bad number '{a}'.",
  7599 	W046: "Don't use extra leading zeros '{a}'.",
  7600 	W047: "A trailing decimal point can be confused with a dot: '{a}'.",
  7601 	W048: "Unexpected control character in regular expression.",
  7602 	W049: "Unexpected escaped character '{a}' in regular expression.",
  7603 	W050: "JavaScript URL.",
  7604 	W051: "Variables should not be deleted.",
  7605 	W052: "Unexpected '{a}'.",
  7606 	W053: "Do not use {a} as a constructor.",
  7607 	W054: "The Function constructor is a form of eval.",
  7608 	W055: "A constructor name should start with an uppercase letter.",
  7609 	W056: "Bad constructor.",
  7610 	W057: "Weird construction. Is 'new' unnecessary?",
  7611 	W058: "Missing '()' invoking a constructor.",
  7612 	W059: "Avoid arguments.{a}.",
  7613 	W060: "document.write can be a form of eval.",
  7614 	W061: "eval can be harmful.",
  7615 	W062: "Wrap an immediate function invocation in parens " +
  7616 		"to assist the reader in understanding that the expression " +
  7617 		"is the result of a function, and not the function itself.",
  7618 	W063: "Math is not a function.",
  7619 	W064: "Missing 'new' prefix when invoking a constructor.",
  7620 	W065: "Missing radix parameter.",
  7621 	W066: "Implied eval. Consider passing a function instead of a string.",
  7622 	W067: "Bad invocation.",
  7623 	W068: "Wrapping non-IIFE function literals in parens is unnecessary.",
  7624 	W069: "['{a}'] is better written in dot notation.",
  7625 	W070: "Extra comma. (it breaks older versions of IE)",
  7626 	W071: "This function has too many statements. ({a})",
  7627 	W072: "This function has too many parameters. ({a})",
  7628 	W073: "Blocks are nested too deeply. ({a})",
  7629 	W074: "This function's cyclomatic complexity is too high. ({a})",
  7630 	W075: "Duplicate key '{a}'.",
  7631 	W076: "Unexpected parameter '{a}' in get {b} function.",
  7632 	W077: "Expected a single parameter in set {a} function.",
  7633 	W078: "Setter is defined without getter.",
  7634 	W079: "Redefinition of '{a}'.",
  7635 	W080: "It's not necessary to initialize '{a}' to 'undefined'.",
  7636 	W081: "Too many var statements.",
  7637 	W082: "Function declarations should not be placed in blocks. " +
  7638 		"Use a function expression or move the statement to the top of " +
  7639 		"the outer function.",
  7640 	W083: "Don't make functions within a loop.",
  7641 	W084: "Expected a conditional expression and instead saw an assignment.",
  7642 	W085: "Don't use 'with'.",
  7643 	W086: "Expected a 'break' statement before '{a}'.",
  7644 	W087: "Forgotten 'debugger' statement?",
  7645 	W088: "Creating global 'for' variable. Should be 'for (var {a} ...'.",
  7646 	W089: "The body of a for in should be wrapped in an if statement to filter " +
  7647 		"unwanted properties from the prototype.",
  7648 	W090: "'{a}' is not a statement label.",
  7649 	W091: "'{a}' is out of scope.",
  7650 	W092: "Wrap the /regexp/ literal in parens to disambiguate the slash operator.",
  7651 	W093: "Did you mean to return a conditional instead of an assignment?",
  7652 	W094: "Unexpected comma.",
  7653 	W095: "Expected a string and instead saw {a}.",
  7654 	W096: "The '{a}' key may produce unexpected results.",
  7655 	W097: "Use the function form of \"use strict\".",
  7656 	W098: "'{a}' is defined but never used.",
  7657 	W099: "Mixed spaces and tabs.",
  7658 	W100: "This character may get silently deleted by one or more browsers.",
  7659 	W101: "Line is too long.",
  7660 	W102: "Trailing whitespace.",
  7661 	W103: "The '{a}' property is deprecated.",
  7662 	W104: "'{a}' is only available in JavaScript 1.7.",
  7663 	W105: "Unexpected {a} in '{b}'.",
  7664 	W106: "Identifier '{a}' is not in camel case.",
  7665 	W107: "Script URL.",
  7666 	W108: "Strings must use doublequote.",
  7667 	W109: "Strings must use singlequote.",
  7668 	W110: "Mixed double and single quotes.",
  7669 	W112: "Unclosed string.",
  7670 	W113: "Control character in string: {a}.",
  7671 	W114: "Avoid {a}.",
  7672 	W115: "Octal literals are not allowed in strict mode.",
  7673 	W116: "Expected '{a}' and instead saw '{b}'.",
  7674 	W117: "'{a}' is not defined.",
  7675 	W118: "'{a}' is only available in Mozilla JavaScript extensions (use moz option).",
  7676 	W119: "'{a}' is only available in ES6 (use esnext option)."
  7677 };
  7679 var info = {
  7680 	I001: "Comma warnings can be turned off with 'laxcomma'.",
  7681 	I002: "Reserved words as properties can be used under the 'es5' option.",
  7682 	I003: "ES5 option is now set per default"
  7683 };
  7685 exports.errors = {};
  7686 exports.warnings = {};
  7687 exports.info = {};
  7689 _.each(errors, function (desc, code) {
  7690 	exports.errors[code] = { code: code, desc: desc };
  7691 });
  7693 _.each(warnings, function (desc, code) {
  7694 	exports.warnings[code] = { code: code, desc: desc };
  7695 });
  7697 _.each(info, function (desc, code) {
  7698 	exports.info[code] = { code: code, desc: desc };
  7699 });
  7701 })()
  7702 },{"underscore":11}],8:[function(require,module,exports){
  7703 var events = require('events');
  7705 exports.isArray = isArray;
  7706 exports.isDate = function(obj){return Object.prototype.toString.call(obj) === '[object Date]'};
  7707 exports.isRegExp = function(obj){return Object.prototype.toString.call(obj) === '[object RegExp]'};
  7710 exports.print = function () {};
  7711 exports.puts = function () {};
  7712 exports.debug = function() {};
  7714 exports.inspect = function(obj, showHidden, depth, colors) {
  7715   var seen = [];
  7717   var stylize = function(str, styleType) {
  7718     // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
  7719     var styles =
  7720         { 'bold' : [1, 22],
  7721           'italic' : [3, 23],
  7722           'underline' : [4, 24],
  7723           'inverse' : [7, 27],
  7724           'white' : [37, 39],
  7725           'grey' : [90, 39],
  7726           'black' : [30, 39],
  7727           'blue' : [34, 39],
  7728           'cyan' : [36, 39],
  7729           'green' : [32, 39],
  7730           'magenta' : [35, 39],
  7731           'red' : [31, 39],
  7732           'yellow' : [33, 39] };
  7734     var style =
  7735         { 'special': 'cyan',
  7736           'number': 'blue',
  7737           'boolean': 'yellow',
  7738           'undefined': 'grey',
  7739           'null': 'bold',
  7740           'string': 'green',
  7741           'date': 'magenta',
  7742           // "name": intentionally not styling
  7743           'regexp': 'red' }[styleType];
  7745     if (style) {
  7746       return '\033[' + styles[style][0] + 'm' + str +
  7747              '\033[' + styles[style][1] + 'm';
  7748     } else {
  7749       return str;
  7751   };
  7752   if (! colors) {
  7753     stylize = function(str, styleType) { return str; };
  7756   function format(value, recurseTimes) {
  7757     // Provide a hook for user-specified inspect functions.
  7758     // Check that value is an object with an inspect function on it
  7759     if (value && typeof value.inspect === 'function' &&
  7760         // Filter out the util module, it's inspect function is special
  7761         value !== exports &&
  7762         // Also filter out any prototype objects using the circular check.
  7763         !(value.constructor && value.constructor.prototype === value)) {
  7764       return value.inspect(recurseTimes);
  7767     // Primitive types cannot have properties
  7768     switch (typeof value) {
  7769       case 'undefined':
  7770         return stylize('undefined', 'undefined');
  7772       case 'string':
  7773         var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
  7774                                                  .replace(/'/g, "\\'")
  7775                                                  .replace(/\\"/g, '"') + '\'';
  7776         return stylize(simple, 'string');
  7778       case 'number':
  7779         return stylize('' + value, 'number');
  7781       case 'boolean':
  7782         return stylize('' + value, 'boolean');
  7784     // For some reason typeof null is "object", so special case here.
  7785     if (value === null) {
  7786       return stylize('null', 'null');
  7789     // Look up the keys of the object.
  7790     var visible_keys = Object_keys(value);
  7791     var keys = showHidden ? Object_getOwnPropertyNames(value) : visible_keys;
  7793     // Functions without properties can be shortcutted.
  7794     if (typeof value === 'function' && keys.length === 0) {
  7795       if (isRegExp(value)) {
  7796         return stylize('' + value, 'regexp');
  7797       } else {
  7798         var name = value.name ? ': ' + value.name : '';
  7799         return stylize('[Function' + name + ']', 'special');
  7803     // Dates without properties can be shortcutted
  7804     if (isDate(value) && keys.length === 0) {
  7805       return stylize(value.toUTCString(), 'date');
  7808     var base, type, braces;
  7809     // Determine the object type
  7810     if (isArray(value)) {
  7811       type = 'Array';
  7812       braces = ['[', ']'];
  7813     } else {
  7814       type = 'Object';
  7815       braces = ['{', '}'];
  7818     // Make functions say that they are functions
  7819     if (typeof value === 'function') {
  7820       var n = value.name ? ': ' + value.name : '';
  7821       base = (isRegExp(value)) ? ' ' + value : ' [Function' + n + ']';
  7822     } else {
  7823       base = '';
  7826     // Make dates with properties first say the date
  7827     if (isDate(value)) {
  7828       base = ' ' + value.toUTCString();
  7831     if (keys.length === 0) {
  7832       return braces[0] + base + braces[1];
  7835     if (recurseTimes < 0) {
  7836       if (isRegExp(value)) {
  7837         return stylize('' + value, 'regexp');
  7838       } else {
  7839         return stylize('[Object]', 'special');
  7843     seen.push(value);
  7845     var output = keys.map(function(key) {
  7846       var name, str;
  7847       if (value.__lookupGetter__) {
  7848         if (value.__lookupGetter__(key)) {
  7849           if (value.__lookupSetter__(key)) {
  7850             str = stylize('[Getter/Setter]', 'special');
  7851           } else {
  7852             str = stylize('[Getter]', 'special');
  7854         } else {
  7855           if (value.__lookupSetter__(key)) {
  7856             str = stylize('[Setter]', 'special');
  7860       if (visible_keys.indexOf(key) < 0) {
  7861         name = '[' + key + ']';
  7863       if (!str) {
  7864         if (seen.indexOf(value[key]) < 0) {
  7865           if (recurseTimes === null) {
  7866             str = format(value[key]);
  7867           } else {
  7868             str = format(value[key], recurseTimes - 1);
  7870           if (str.indexOf('\n') > -1) {
  7871             if (isArray(value)) {
  7872               str = str.split('\n').map(function(line) {
  7873                 return '  ' + line;
  7874               }).join('\n').substr(2);
  7875             } else {
  7876               str = '\n' + str.split('\n').map(function(line) {
  7877                 return '   ' + line;
  7878               }).join('\n');
  7881         } else {
  7882           str = stylize('[Circular]', 'special');
  7885       if (typeof name === 'undefined') {
  7886         if (type === 'Array' && key.match(/^\d+$/)) {
  7887           return str;
  7889         name = JSON.stringify('' + key);
  7890         if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
  7891           name = name.substr(1, name.length - 2);
  7892           name = stylize(name, 'name');
  7893         } else {
  7894           name = name.replace(/'/g, "\\'")
  7895                      .replace(/\\"/g, '"')
  7896                      .replace(/(^"|"$)/g, "'");
  7897           name = stylize(name, 'string');
  7901       return name + ': ' + str;
  7902     });
  7904     seen.pop();
  7906     var numLinesEst = 0;
  7907     var length = output.reduce(function(prev, cur) {
  7908       numLinesEst++;
  7909       if (cur.indexOf('\n') >= 0) numLinesEst++;
  7910       return prev + cur.length + 1;
  7911     }, 0);
  7913     if (length > 50) {
  7914       output = braces[0] +
  7915                (base === '' ? '' : base + '\n ') +
  7916                ' ' +
  7917                output.join(',\n  ') +
  7918                ' ' +
  7919                braces[1];
  7921     } else {
  7922       output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
  7925     return output;
  7927   return format(obj, (typeof depth === 'undefined' ? 2 : depth));
  7928 };
  7931 function isArray(ar) {
  7932   return ar instanceof Array ||
  7933          Array.isArray(ar) ||
  7934          (ar && ar !== Object.prototype && isArray(ar.__proto__));
  7938 function isRegExp(re) {
  7939   return re instanceof RegExp ||
  7940     (typeof re === 'object' && Object.prototype.toString.call(re) === '[object RegExp]');
  7944 function isDate(d) {
  7945   if (d instanceof Date) return true;
  7946   if (typeof d !== 'object') return false;
  7947   var properties = Date.prototype && Object_getOwnPropertyNames(Date.prototype);
  7948   var proto = d.__proto__ && Object_getOwnPropertyNames(d.__proto__);
  7949   return JSON.stringify(proto) === JSON.stringify(properties);
  7952 function pad(n) {
  7953   return n < 10 ? '0' + n.toString(10) : n.toString(10);
  7956 var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
  7957               'Oct', 'Nov', 'Dec'];
  7959 // 26 Feb 16:19:34
  7960 function timestamp() {
  7961   var d = new Date();
  7962   var time = [pad(d.getHours()),
  7963               pad(d.getMinutes()),
  7964               pad(d.getSeconds())].join(':');
  7965   return [d.getDate(), months[d.getMonth()], time].join(' ');
  7968 exports.log = function (msg) {};
  7970 exports.pump = null;
  7972 var Object_keys = Object.keys || function (obj) {
  7973     var res = [];
  7974     for (var key in obj) res.push(key);
  7975     return res;
  7976 };
  7978 var Object_getOwnPropertyNames = Object.getOwnPropertyNames || function (obj) {
  7979     var res = [];
  7980     for (var key in obj) {
  7981         if (Object.hasOwnProperty.call(obj, key)) res.push(key);
  7983     return res;
  7984 };
  7986 var Object_create = Object.create || function (prototype, properties) {
  7987     // from es5-shim
  7988     var object;
  7989     if (prototype === null) {
  7990         object = { '__proto__' : null };
  7992     else {
  7993         if (typeof prototype !== 'object') {
  7994             throw new TypeError(
  7995                 'typeof prototype[' + (typeof prototype) + '] != \'object\''
  7996             );
  7998         var Type = function () {};
  7999         Type.prototype = prototype;
  8000         object = new Type();
  8001         object.__proto__ = prototype;
  8003     if (typeof properties !== 'undefined' && Object.defineProperties) {
  8004         Object.defineProperties(object, properties);
  8006     return object;
  8007 };
  8009 exports.inherits = function(ctor, superCtor) {
  8010   ctor.super_ = superCtor;
  8011   ctor.prototype = Object_create(superCtor.prototype, {
  8012     constructor: {
  8013       value: ctor,
  8014       enumerable: false,
  8015       writable: true,
  8016       configurable: true
  8018   });
  8019 };
  8021 var formatRegExp = /%[sdj%]/g;
  8022 exports.format = function(f) {
  8023   if (typeof f !== 'string') {
  8024     var objects = [];
  8025     for (var i = 0; i < arguments.length; i++) {
  8026       objects.push(exports.inspect(arguments[i]));
  8028     return objects.join(' ');
  8031   var i = 1;
  8032   var args = arguments;
  8033   var len = args.length;
  8034   var str = String(f).replace(formatRegExp, function(x) {
  8035     if (x === '%%') return '%';
  8036     if (i >= len) return x;
  8037     switch (x) {
  8038       case '%s': return String(args[i++]);
  8039       case '%d': return Number(args[i++]);
  8040       case '%j': return JSON.stringify(args[i++]);
  8041       default:
  8042         return x;
  8044   });
  8045   for(var x = args[i]; i < len; x = args[++i]){
  8046     if (x === null || typeof x !== 'object') {
  8047       str += ' ' + x;
  8048     } else {
  8049       str += ' ' + exports.inspect(x);
  8052   return str;
  8053 };
  8055 },{"events":2}],9:[function(require,module,exports){
  8056 (function(){// UTILITY
  8057 var util = require('util');
  8058 var Buffer = require("buffer").Buffer;
  8059 var pSlice = Array.prototype.slice;
  8061 function objectKeys(object) {
  8062   if (Object.keys) return Object.keys(object);
  8063   var result = [];
  8064   for (var name in object) {
  8065     if (Object.prototype.hasOwnProperty.call(object, name)) {
  8066       result.push(name);
  8069   return result;
  8072 // 1. The assert module provides functions that throw
  8073 // AssertionError's when particular conditions are not met. The
  8074 // assert module must conform to the following interface.
  8076 var assert = module.exports = ok;
  8078 // 2. The AssertionError is defined in assert.
  8079 // new assert.AssertionError({ message: message,
  8080 //                             actual: actual,
  8081 //                             expected: expected })
  8083 assert.AssertionError = function AssertionError(options) {
  8084   this.name = 'AssertionError';
  8085   this.message = options.message;
  8086   this.actual = options.actual;
  8087   this.expected = options.expected;
  8088   this.operator = options.operator;
  8089   var stackStartFunction = options.stackStartFunction || fail;
  8091   if (Error.captureStackTrace) {
  8092     Error.captureStackTrace(this, stackStartFunction);
  8094 };
  8095 util.inherits(assert.AssertionError, Error);
  8097 function replacer(key, value) {
  8098   if (value === undefined) {
  8099     return '' + value;
  8101   if (typeof value === 'number' && (isNaN(value) || !isFinite(value))) {
  8102     return value.toString();
  8104   if (typeof value === 'function' || value instanceof RegExp) {
  8105     return value.toString();
  8107   return value;
  8110 function truncate(s, n) {
  8111   if (typeof s == 'string') {
  8112     return s.length < n ? s : s.slice(0, n);
  8113   } else {
  8114     return s;
  8118 assert.AssertionError.prototype.toString = function() {
  8119   if (this.message) {
  8120     return [this.name + ':', this.message].join(' ');
  8121   } else {
  8122     return [
  8123       this.name + ':',
  8124       truncate(JSON.stringify(this.actual, replacer), 128),
  8125       this.operator,
  8126       truncate(JSON.stringify(this.expected, replacer), 128)
  8127     ].join(' ');
  8129 };
  8131 // assert.AssertionError instanceof Error
  8133 assert.AssertionError.__proto__ = Error.prototype;
  8135 // At present only the three keys mentioned above are used and
  8136 // understood by the spec. Implementations or sub modules can pass
  8137 // other keys to the AssertionError's constructor - they will be
  8138 // ignored.
  8140 // 3. All of the following functions must throw an AssertionError
  8141 // when a corresponding condition is not met, with a message that
  8142 // may be undefined if not provided.  All assertion methods provide
  8143 // both the actual and expected values to the assertion error for
  8144 // display purposes.
  8146 function fail(actual, expected, message, operator, stackStartFunction) {
  8147   throw new assert.AssertionError({
  8148     message: message,
  8149     actual: actual,
  8150     expected: expected,
  8151     operator: operator,
  8152     stackStartFunction: stackStartFunction
  8153   });
  8156 // EXTENSION! allows for well behaved errors defined elsewhere.
  8157 assert.fail = fail;
  8159 // 4. Pure assertion tests whether a value is truthy, as determined
  8160 // by !!guard.
  8161 // assert.ok(guard, message_opt);
  8162 // This statement is equivalent to assert.equal(true, guard,
  8163 // message_opt);. To test strictly for the value true, use
  8164 // assert.strictEqual(true, guard, message_opt);.
  8166 function ok(value, message) {
  8167   if (!!!value) fail(value, true, message, '==', assert.ok);
  8169 assert.ok = ok;
  8171 // 5. The equality assertion tests shallow, coercive equality with
  8172 // ==.
  8173 // assert.equal(actual, expected, message_opt);
  8175 assert.equal = function equal(actual, expected, message) {
  8176   if (actual != expected) fail(actual, expected, message, '==', assert.equal);
  8177 };
  8179 // 6. The non-equality assertion tests for whether two objects are not equal
  8180 // with != assert.notEqual(actual, expected, message_opt);
  8182 assert.notEqual = function notEqual(actual, expected, message) {
  8183   if (actual == expected) {
  8184     fail(actual, expected, message, '!=', assert.notEqual);
  8186 };
  8188 // 7. The equivalence assertion tests a deep equality relation.
  8189 // assert.deepEqual(actual, expected, message_opt);
  8191 assert.deepEqual = function deepEqual(actual, expected, message) {
  8192   if (!_deepEqual(actual, expected)) {
  8193     fail(actual, expected, message, 'deepEqual', assert.deepEqual);
  8195 };
  8197 function _deepEqual(actual, expected) {
  8198   // 7.1. All identical values are equivalent, as determined by ===.
  8199   if (actual === expected) {
  8200     return true;
  8202   } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
  8203     if (actual.length != expected.length) return false;
  8205     for (var i = 0; i < actual.length; i++) {
  8206       if (actual[i] !== expected[i]) return false;
  8209     return true;
  8211   // 7.2. If the expected value is a Date object, the actual value is
  8212   // equivalent if it is also a Date object that refers to the same time.
  8213   } else if (actual instanceof Date && expected instanceof Date) {
  8214     return actual.getTime() === expected.getTime();
  8216   // 7.3. Other pairs that do not both pass typeof value == 'object',
  8217   // equivalence is determined by ==.
  8218   } else if (typeof actual != 'object' && typeof expected != 'object') {
  8219     return actual == expected;
  8221   // 7.4. For all other Object pairs, including Array objects, equivalence is
  8222   // determined by having the same number of owned properties (as verified
  8223   // with Object.prototype.hasOwnProperty.call), the same set of keys
  8224   // (although not necessarily the same order), equivalent values for every
  8225   // corresponding key, and an identical 'prototype' property. Note: this
  8226   // accounts for both named and indexed properties on Arrays.
  8227   } else {
  8228     return objEquiv(actual, expected);
  8232 function isUndefinedOrNull(value) {
  8233   return value === null || value === undefined;
  8236 function isArguments(object) {
  8237   return Object.prototype.toString.call(object) == '[object Arguments]';
  8240 function objEquiv(a, b) {
  8241   if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
  8242     return false;
  8243   // an identical 'prototype' property.
  8244   if (a.prototype !== b.prototype) return false;
  8245   //~~~I've managed to break Object.keys through screwy arguments passing.
  8246   //   Converting to array solves the problem.
  8247   if (isArguments(a)) {
  8248     if (!isArguments(b)) {
  8249       return false;
  8251     a = pSlice.call(a);
  8252     b = pSlice.call(b);
  8253     return _deepEqual(a, b);
  8255   try {
  8256     var ka = objectKeys(a),
  8257         kb = objectKeys(b),
  8258         key, i;
  8259   } catch (e) {//happens when one is a string literal and the other isn't
  8260     return false;
  8262   // having the same number of owned properties (keys incorporates
  8263   // hasOwnProperty)
  8264   if (ka.length != kb.length)
  8265     return false;
  8266   //the same set of keys (although not necessarily the same order),
  8267   ka.sort();
  8268   kb.sort();
  8269   //~~~cheap key test
  8270   for (i = ka.length - 1; i >= 0; i--) {
  8271     if (ka[i] != kb[i])
  8272       return false;
  8274   //equivalent values for every corresponding key, and
  8275   //~~~possibly expensive deep test
  8276   for (i = ka.length - 1; i >= 0; i--) {
  8277     key = ka[i];
  8278     if (!_deepEqual(a[key], b[key])) return false;
  8280   return true;
  8283 // 8. The non-equivalence assertion tests for any deep inequality.
  8284 // assert.notDeepEqual(actual, expected, message_opt);
  8286 assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
  8287   if (_deepEqual(actual, expected)) {
  8288     fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
  8290 };
  8292 // 9. The strict equality assertion tests strict equality, as determined by ===.
  8293 // assert.strictEqual(actual, expected, message_opt);
  8295 assert.strictEqual = function strictEqual(actual, expected, message) {
  8296   if (actual !== expected) {
  8297     fail(actual, expected, message, '===', assert.strictEqual);
  8299 };
  8301 // 10. The strict non-equality assertion tests for strict inequality, as
  8302 // determined by !==.  assert.notStrictEqual(actual, expected, message_opt);
  8304 assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
  8305   if (actual === expected) {
  8306     fail(actual, expected, message, '!==', assert.notStrictEqual);
  8308 };
  8310 function expectedException(actual, expected) {
  8311   if (!actual || !expected) {
  8312     return false;
  8315   if (expected instanceof RegExp) {
  8316     return expected.test(actual);
  8317   } else if (actual instanceof expected) {
  8318     return true;
  8319   } else if (expected.call({}, actual) === true) {
  8320     return true;
  8323   return false;
  8326 function _throws(shouldThrow, block, expected, message) {
  8327   var actual;
  8329   if (typeof expected === 'string') {
  8330     message = expected;
  8331     expected = null;
  8334   try {
  8335     block();
  8336   } catch (e) {
  8337     actual = e;
  8340   message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
  8341             (message ? ' ' + message : '.');
  8343   if (shouldThrow && !actual) {
  8344     fail('Missing expected exception' + message);
  8347   if (!shouldThrow && expectedException(actual, expected)) {
  8348     fail('Got unwanted exception' + message);
  8351   if ((shouldThrow && actual && expected &&
  8352       !expectedException(actual, expected)) || (!shouldThrow && actual)) {
  8353     throw actual;
  8357 // 11. Expected to throw an error:
  8358 // assert.throws(block, Error_opt, message_opt);
  8360 assert.throws = function(block, /*optional*/error, /*optional*/message) {
  8361   _throws.apply(this, [true].concat(pSlice.call(arguments)));
  8362 };
  8364 // EXTENSION! This is annoying to write outside this module.
  8365 assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
  8366   _throws.apply(this, [false].concat(pSlice.call(arguments)));
  8367 };
  8369 assert.ifError = function(err) { if (err) {throw err;}};
  8371 })()
  8372 },{"util":8,"buffer":13}],11:[function(require,module,exports){
  8373 (function(){//     Underscore.js 1.4.4
  8374 //     http://underscorejs.org
  8375 //     (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
  8376 //     Underscore may be freely distributed under the MIT license.
  8378 (function() {
  8380   // Baseline setup
  8381   // --------------
  8383   // Establish the root object, `window` in the browser, or `global` on the server.
  8384   var root = this;
  8386   // Save the previous value of the `_` variable.
  8387   var previousUnderscore = root._;
  8389   // Establish the object that gets returned to break out of a loop iteration.
  8390   var breaker = {};
  8392   // Save bytes in the minified (but not gzipped) version:
  8393   var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
  8395   // Create quick reference variables for speed access to core prototypes.
  8396   var push             = ArrayProto.push,
  8397       slice            = ArrayProto.slice,
  8398       concat           = ArrayProto.concat,
  8399       toString         = ObjProto.toString,
  8400       hasOwnProperty   = ObjProto.hasOwnProperty;
  8402   // All **ECMAScript 5** native function implementations that we hope to use
  8403   // are declared here.
  8404   var
  8405     nativeForEach      = ArrayProto.forEach,
  8406     nativeMap          = ArrayProto.map,
  8407     nativeReduce       = ArrayProto.reduce,
  8408     nativeReduceRight  = ArrayProto.reduceRight,
  8409     nativeFilter       = ArrayProto.filter,
  8410     nativeEvery        = ArrayProto.every,
  8411     nativeSome         = ArrayProto.some,
  8412     nativeIndexOf      = ArrayProto.indexOf,
  8413     nativeLastIndexOf  = ArrayProto.lastIndexOf,
  8414     nativeIsArray      = Array.isArray,
  8415     nativeKeys         = Object.keys,
  8416     nativeBind         = FuncProto.bind;
  8418   // Create a safe reference to the Underscore object for use below.
  8419   var _ = function(obj) {
  8420     if (obj instanceof _) return obj;
  8421     if (!(this instanceof _)) return new _(obj);
  8422     this._wrapped = obj;
  8423   };
  8425   // Export the Underscore object for **Node.js**, with
  8426   // backwards-compatibility for the old `require()` API. If we're in
  8427   // the browser, add `_` as a global object via a string identifier,
  8428   // for Closure Compiler "advanced" mode.
  8429   if (typeof exports !== 'undefined') {
  8430     if (typeof module !== 'undefined' && module.exports) {
  8431       exports = module.exports = _;
  8433     exports._ = _;
  8434   } else {
  8435     root._ = _;
  8438   // Current version.
  8439   _.VERSION = '1.4.4';
  8441   // Collection Functions
  8442   // --------------------
  8444   // The cornerstone, an `each` implementation, aka `forEach`.
  8445   // Handles objects with the built-in `forEach`, arrays, and raw objects.
  8446   // Delegates to **ECMAScript 5**'s native `forEach` if available.
  8447   var each = _.each = _.forEach = function(obj, iterator, context) {
  8448     if (obj == null) return;
  8449     if (nativeForEach && obj.forEach === nativeForEach) {
  8450       obj.forEach(iterator, context);
  8451     } else if (obj.length === +obj.length) {
  8452       for (var i = 0, l = obj.length; i < l; i++) {
  8453         if (iterator.call(context, obj[i], i, obj) === breaker) return;
  8455     } else {
  8456       for (var key in obj) {
  8457         if (_.has(obj, key)) {
  8458           if (iterator.call(context, obj[key], key, obj) === breaker) return;
  8462   };
  8464   // Return the results of applying the iterator to each element.
  8465   // Delegates to **ECMAScript 5**'s native `map` if available.
  8466   _.map = _.collect = function(obj, iterator, context) {
  8467     var results = [];
  8468     if (obj == null) return results;
  8469     if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
  8470     each(obj, function(value, index, list) {
  8471       results[results.length] = iterator.call(context, value, index, list);
  8472     });
  8473     return results;
  8474   };
  8476   var reduceError = 'Reduce of empty array with no initial value';
  8478   // **Reduce** builds up a single result from a list of values, aka `inject`,
  8479   // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
  8480   _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
  8481     var initial = arguments.length > 2;
  8482     if (obj == null) obj = [];
  8483     if (nativeReduce && obj.reduce === nativeReduce) {
  8484       if (context) iterator = _.bind(iterator, context);
  8485       return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
  8487     each(obj, function(value, index, list) {
  8488       if (!initial) {
  8489         memo = value;
  8490         initial = true;
  8491       } else {
  8492         memo = iterator.call(context, memo, value, index, list);
  8494     });
  8495     if (!initial) throw new TypeError(reduceError);
  8496     return memo;
  8497   };
  8499   // The right-associative version of reduce, also known as `foldr`.
  8500   // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
  8501   _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
  8502     var initial = arguments.length > 2;
  8503     if (obj == null) obj = [];
  8504     if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
  8505       if (context) iterator = _.bind(iterator, context);
  8506       return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
  8508     var length = obj.length;
  8509     if (length !== +length) {
  8510       var keys = _.keys(obj);
  8511       length = keys.length;
  8513     each(obj, function(value, index, list) {
  8514       index = keys ? keys[--length] : --length;
  8515       if (!initial) {
  8516         memo = obj[index];
  8517         initial = true;
  8518       } else {
  8519         memo = iterator.call(context, memo, obj[index], index, list);
  8521     });
  8522     if (!initial) throw new TypeError(reduceError);
  8523     return memo;
  8524   };
  8526   // Return the first value which passes a truth test. Aliased as `detect`.
  8527   _.find = _.detect = function(obj, iterator, context) {
  8528     var result;
  8529     any(obj, function(value, index, list) {
  8530       if (iterator.call(context, value, index, list)) {
  8531         result = value;
  8532         return true;
  8534     });
  8535     return result;
  8536   };
  8538   // Return all the elements that pass a truth test.
  8539   // Delegates to **ECMAScript 5**'s native `filter` if available.
  8540   // Aliased as `select`.
  8541   _.filter = _.select = function(obj, iterator, context) {
  8542     var results = [];
  8543     if (obj == null) return results;
  8544     if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
  8545     each(obj, function(value, index, list) {
  8546       if (iterator.call(context, value, index, list)) results[results.length] = value;
  8547     });
  8548     return results;
  8549   };
  8551   // Return all the elements for which a truth test fails.
  8552   _.reject = function(obj, iterator, context) {
  8553     return _.filter(obj, function(value, index, list) {
  8554       return !iterator.call(context, value, index, list);
  8555     }, context);
  8556   };
  8558   // Determine whether all of the elements match a truth test.
  8559   // Delegates to **ECMAScript 5**'s native `every` if available.
  8560   // Aliased as `all`.
  8561   _.every = _.all = function(obj, iterator, context) {
  8562     iterator || (iterator = _.identity);
  8563     var result = true;
  8564     if (obj == null) return result;
  8565     if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
  8566     each(obj, function(value, index, list) {
  8567       if (!(result = result && iterator.call(context, value, index, list))) return breaker;
  8568     });
  8569     return !!result;
  8570   };
  8572   // Determine if at least one element in the object matches a truth test.
  8573   // Delegates to **ECMAScript 5**'s native `some` if available.
  8574   // Aliased as `any`.
  8575   var any = _.some = _.any = function(obj, iterator, context) {
  8576     iterator || (iterator = _.identity);
  8577     var result = false;
  8578     if (obj == null) return result;
  8579     if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
  8580     each(obj, function(value, index, list) {
  8581       if (result || (result = iterator.call(context, value, index, list))) return breaker;
  8582     });
  8583     return !!result;
  8584   };
  8586   // Determine if the array or object contains a given value (using `===`).
  8587   // Aliased as `include`.
  8588   _.contains = _.include = function(obj, target) {
  8589     if (obj == null) return false;
  8590     if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
  8591     return any(obj, function(value) {
  8592       return value === target;
  8593     });
  8594   };
  8596   // Invoke a method (with arguments) on every item in a collection.
  8597   _.invoke = function(obj, method) {
  8598     var args = slice.call(arguments, 2);
  8599     var isFunc = _.isFunction(method);
  8600     return _.map(obj, function(value) {
  8601       return (isFunc ? method : value[method]).apply(value, args);
  8602     });
  8603   };
  8605   // Convenience version of a common use case of `map`: fetching a property.
  8606   _.pluck = function(obj, key) {
  8607     return _.map(obj, function(value){ return value[key]; });
  8608   };
  8610   // Convenience version of a common use case of `filter`: selecting only objects
  8611   // containing specific `key:value` pairs.
  8612   _.where = function(obj, attrs, first) {
  8613     if (_.isEmpty(attrs)) return first ? null : [];
  8614     return _[first ? 'find' : 'filter'](obj, function(value) {
  8615       for (var key in attrs) {
  8616         if (attrs[key] !== value[key]) return false;
  8618       return true;
  8619     });
  8620   };
  8622   // Convenience version of a common use case of `find`: getting the first object
  8623   // containing specific `key:value` pairs.
  8624   _.findWhere = function(obj, attrs) {
  8625     return _.where(obj, attrs, true);
  8626   };
  8628   // Return the maximum element or (element-based computation).
  8629   // Can't optimize arrays of integers longer than 65,535 elements.
  8630   // See: https://bugs.webkit.org/show_bug.cgi?id=80797
  8631   _.max = function(obj, iterator, context) {
  8632     if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
  8633       return Math.max.apply(Math, obj);
  8635     if (!iterator && _.isEmpty(obj)) return -Infinity;
  8636     var result = {computed : -Infinity, value: -Infinity};
  8637     each(obj, function(value, index, list) {
  8638       var computed = iterator ? iterator.call(context, value, index, list) : value;
  8639       computed >= result.computed && (result = {value : value, computed : computed});
  8640     });
  8641     return result.value;
  8642   };
  8644   // Return the minimum element (or element-based computation).
  8645   _.min = function(obj, iterator, context) {
  8646     if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
  8647       return Math.min.apply(Math, obj);
  8649     if (!iterator && _.isEmpty(obj)) return Infinity;
  8650     var result = {computed : Infinity, value: Infinity};
  8651     each(obj, function(value, index, list) {
  8652       var computed = iterator ? iterator.call(context, value, index, list) : value;
  8653       computed < result.computed && (result = {value : value, computed : computed});
  8654     });
  8655     return result.value;
  8656   };
  8658   // Shuffle an array.
  8659   _.shuffle = function(obj) {
  8660     var rand;
  8661     var index = 0;
  8662     var shuffled = [];
  8663     each(obj, function(value) {
  8664       rand = _.random(index++);
  8665       shuffled[index - 1] = shuffled[rand];
  8666       shuffled[rand] = value;
  8667     });
  8668     return shuffled;
  8669   };
  8671   // An internal function to generate lookup iterators.
  8672   var lookupIterator = function(value) {
  8673     return _.isFunction(value) ? value : function(obj){ return obj[value]; };
  8674   };
  8676   // Sort the object's values by a criterion produced by an iterator.
  8677   _.sortBy = function(obj, value, context) {
  8678     var iterator = lookupIterator(value);
  8679     return _.pluck(_.map(obj, function(value, index, list) {
  8680       return {
  8681         value : value,
  8682         index : index,
  8683         criteria : iterator.call(context, value, index, list)
  8684       };
  8685     }).sort(function(left, right) {
  8686       var a = left.criteria;
  8687       var b = right.criteria;
  8688       if (a !== b) {
  8689         if (a > b || a === void 0) return 1;
  8690         if (a < b || b === void 0) return -1;
  8692       return left.index < right.index ? -1 : 1;
  8693     }), 'value');
  8694   };
  8696   // An internal function used for aggregate "group by" operations.
  8697   var group = function(obj, value, context, behavior) {
  8698     var result = {};
  8699     var iterator = lookupIterator(value || _.identity);
  8700     each(obj, function(value, index) {
  8701       var key = iterator.call(context, value, index, obj);
  8702       behavior(result, key, value);
  8703     });
  8704     return result;
  8705   };
  8707   // Groups the object's values by a criterion. Pass either a string attribute
  8708   // to group by, or a function that returns the criterion.
  8709   _.groupBy = function(obj, value, context) {
  8710     return group(obj, value, context, function(result, key, value) {
  8711       (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
  8712     });
  8713   };
  8715   // Counts instances of an object that group by a certain criterion. Pass
  8716   // either a string attribute to count by, or a function that returns the
  8717   // criterion.
  8718   _.countBy = function(obj, value, context) {
  8719     return group(obj, value, context, function(result, key) {
  8720       if (!_.has(result, key)) result[key] = 0;
  8721       result[key]++;
  8722     });
  8723   };
  8725   // Use a comparator function to figure out the smallest index at which
  8726   // an object should be inserted so as to maintain order. Uses binary search.
  8727   _.sortedIndex = function(array, obj, iterator, context) {
  8728     iterator = iterator == null ? _.identity : lookupIterator(iterator);
  8729     var value = iterator.call(context, obj);
  8730     var low = 0, high = array.length;
  8731     while (low < high) {
  8732       var mid = (low + high) >>> 1;
  8733       iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
  8735     return low;
  8736   };
  8738   // Safely convert anything iterable into a real, live array.
  8739   _.toArray = function(obj) {
  8740     if (!obj) return [];
  8741     if (_.isArray(obj)) return slice.call(obj);
  8742     if (obj.length === +obj.length) return _.map(obj, _.identity);
  8743     return _.values(obj);
  8744   };
  8746   // Return the number of elements in an object.
  8747   _.size = function(obj) {
  8748     if (obj == null) return 0;
  8749     return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
  8750   };
  8752   // Array Functions
  8753   // ---------------
  8755   // Get the first element of an array. Passing **n** will return the first N
  8756   // values in the array. Aliased as `head` and `take`. The **guard** check
  8757   // allows it to work with `_.map`.
  8758   _.first = _.head = _.take = function(array, n, guard) {
  8759     if (array == null) return void 0;
  8760     return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
  8761   };
  8763   // Returns everything but the last entry of the array. Especially useful on
  8764   // the arguments object. Passing **n** will return all the values in
  8765   // the array, excluding the last N. The **guard** check allows it to work with
  8766   // `_.map`.
  8767   _.initial = function(array, n, guard) {
  8768     return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
  8769   };
  8771   // Get the last element of an array. Passing **n** will return the last N
  8772   // values in the array. The **guard** check allows it to work with `_.map`.
  8773   _.last = function(array, n, guard) {
  8774     if (array == null) return void 0;
  8775     if ((n != null) && !guard) {
  8776       return slice.call(array, Math.max(array.length - n, 0));
  8777     } else {
  8778       return array[array.length - 1];
  8780   };
  8782   // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
  8783   // Especially useful on the arguments object. Passing an **n** will return
  8784   // the rest N values in the array. The **guard**
  8785   // check allows it to work with `_.map`.
  8786   _.rest = _.tail = _.drop = function(array, n, guard) {
  8787     return slice.call(array, (n == null) || guard ? 1 : n);
  8788   };
  8790   // Trim out all falsy values from an array.
  8791   _.compact = function(array) {
  8792     return _.filter(array, _.identity);
  8793   };
  8795   // Internal implementation of a recursive `flatten` function.
  8796   var flatten = function(input, shallow, output) {
  8797     each(input, function(value) {
  8798       if (_.isArray(value)) {
  8799         shallow ? push.apply(output, value) : flatten(value, shallow, output);
  8800       } else {
  8801         output.push(value);
  8803     });
  8804     return output;
  8805   };
  8807   // Return a completely flattened version of an array.
  8808   _.flatten = function(array, shallow) {
  8809     return flatten(array, shallow, []);
  8810   };
  8812   // Return a version of the array that does not contain the specified value(s).
  8813   _.without = function(array) {
  8814     return _.difference(array, slice.call(arguments, 1));
  8815   };
  8817   // Produce a duplicate-free version of the array. If the array has already
  8818   // been sorted, you have the option of using a faster algorithm.
  8819   // Aliased as `unique`.
  8820   _.uniq = _.unique = function(array, isSorted, iterator, context) {
  8821     if (_.isFunction(isSorted)) {
  8822       context = iterator;
  8823       iterator = isSorted;
  8824       isSorted = false;
  8826     var initial = iterator ? _.map(array, iterator, context) : array;
  8827     var results = [];
  8828     var seen = [];
  8829     each(initial, function(value, index) {
  8830       if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
  8831         seen.push(value);
  8832         results.push(array[index]);
  8834     });
  8835     return results;
  8836   };
  8838   // Produce an array that contains the union: each distinct element from all of
  8839   // the passed-in arrays.
  8840   _.union = function() {
  8841     return _.uniq(concat.apply(ArrayProto, arguments));
  8842   };
  8844   // Produce an array that contains every item shared between all the
  8845   // passed-in arrays.
  8846   _.intersection = function(array) {
  8847     var rest = slice.call(arguments, 1);
  8848     return _.filter(_.uniq(array), function(item) {
  8849       return _.every(rest, function(other) {
  8850         return _.indexOf(other, item) >= 0;
  8851       });
  8852     });
  8853   };
  8855   // Take the difference between one array and a number of other arrays.
  8856   // Only the elements present in just the first array will remain.
  8857   _.difference = function(array) {
  8858     var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
  8859     return _.filter(array, function(value){ return !_.contains(rest, value); });
  8860   };
  8862   // Zip together multiple lists into a single array -- elements that share
  8863   // an index go together.
  8864   _.zip = function() {
  8865     var args = slice.call(arguments);
  8866     var length = _.max(_.pluck(args, 'length'));
  8867     var results = new Array(length);
  8868     for (var i = 0; i < length; i++) {
  8869       results[i] = _.pluck(args, "" + i);
  8871     return results;
  8872   };
  8874   // Converts lists into objects. Pass either a single array of `[key, value]`
  8875   // pairs, or two parallel arrays of the same length -- one of keys, and one of
  8876   // the corresponding values.
  8877   _.object = function(list, values) {
  8878     if (list == null) return {};
  8879     var result = {};
  8880     for (var i = 0, l = list.length; i < l; i++) {
  8881       if (values) {
  8882         result[list[i]] = values[i];
  8883       } else {
  8884         result[list[i][0]] = list[i][1];
  8887     return result;
  8888   };
  8890   // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
  8891   // we need this function. Return the position of the first occurrence of an
  8892   // item in an array, or -1 if the item is not included in the array.
  8893   // Delegates to **ECMAScript 5**'s native `indexOf` if available.
  8894   // If the array is large and already in sort order, pass `true`
  8895   // for **isSorted** to use binary search.
  8896   _.indexOf = function(array, item, isSorted) {
  8897     if (array == null) return -1;
  8898     var i = 0, l = array.length;
  8899     if (isSorted) {
  8900       if (typeof isSorted == 'number') {
  8901         i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
  8902       } else {
  8903         i = _.sortedIndex(array, item);
  8904         return array[i] === item ? i : -1;
  8907     if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
  8908     for (; i < l; i++) if (array[i] === item) return i;
  8909     return -1;
  8910   };
  8912   // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
  8913   _.lastIndexOf = function(array, item, from) {
  8914     if (array == null) return -1;
  8915     var hasIndex = from != null;
  8916     if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
  8917       return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
  8919     var i = (hasIndex ? from : array.length);
  8920     while (i--) if (array[i] === item) return i;
  8921     return -1;
  8922   };
  8924   // Generate an integer Array containing an arithmetic progression. A port of
  8925   // the native Python `range()` function. See
  8926   // [the Python documentation](http://docs.python.org/library/functions.html#range).
  8927   _.range = function(start, stop, step) {
  8928     if (arguments.length <= 1) {
  8929       stop = start || 0;
  8930       start = 0;
  8932     step = arguments[2] || 1;
  8934     var len = Math.max(Math.ceil((stop - start) / step), 0);
  8935     var idx = 0;
  8936     var range = new Array(len);
  8938     while(idx < len) {
  8939       range[idx++] = start;
  8940       start += step;
  8943     return range;
  8944   };
  8946   // Function (ahem) Functions
  8947   // ------------------
  8949   // Create a function bound to a given object (assigning `this`, and arguments,
  8950   // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
  8951   // available.
  8952   _.bind = function(func, context) {
  8953     if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
  8954     var args = slice.call(arguments, 2);
  8955     return function() {
  8956       return func.apply(context, args.concat(slice.call(arguments)));
  8957     };
  8958   };
  8960   // Partially apply a function by creating a version that has had some of its
  8961   // arguments pre-filled, without changing its dynamic `this` context.
  8962   _.partial = function(func) {
  8963     var args = slice.call(arguments, 1);
  8964     return function() {
  8965       return func.apply(this, args.concat(slice.call(arguments)));
  8966     };
  8967   };
  8969   // Bind all of an object's methods to that object. Useful for ensuring that
  8970   // all callbacks defined on an object belong to it.
  8971   _.bindAll = function(obj) {
  8972     var funcs = slice.call(arguments, 1);
  8973     if (funcs.length === 0) funcs = _.functions(obj);
  8974     each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
  8975     return obj;
  8976   };
  8978   // Memoize an expensive function by storing its results.
  8979   _.memoize = function(func, hasher) {
  8980     var memo = {};
  8981     hasher || (hasher = _.identity);
  8982     return function() {
  8983       var key = hasher.apply(this, arguments);
  8984       return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
  8985     };
  8986   };
  8988   // Delays a function for the given number of milliseconds, and then calls
  8989   // it with the arguments supplied.
  8990   _.delay = function(func, wait) {
  8991     var args = slice.call(arguments, 2);
  8992     return setTimeout(function(){ return func.apply(null, args); }, wait);
  8993   };
  8995   // Defers a function, scheduling it to run after the current call stack has
  8996   // cleared.
  8997   _.defer = function(func) {
  8998     return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
  8999   };
  9001   // Returns a function, that, when invoked, will only be triggered at most once
  9002   // during a given window of time.
  9003   _.throttle = function(func, wait) {
  9004     var context, args, timeout, result;
  9005     var previous = 0;
  9006     var later = function() {
  9007       previous = new Date;
  9008       timeout = null;
  9009       result = func.apply(context, args);
  9010     };
  9011     return function() {
  9012       var now = new Date;
  9013       var remaining = wait - (now - previous);
  9014       context = this;
  9015       args = arguments;
  9016       if (remaining <= 0) {
  9017         clearTimeout(timeout);
  9018         timeout = null;
  9019         previous = now;
  9020         result = func.apply(context, args);
  9021       } else if (!timeout) {
  9022         timeout = setTimeout(later, remaining);
  9024       return result;
  9025     };
  9026   };
  9028   // Returns a function, that, as long as it continues to be invoked, will not
  9029   // be triggered. The function will be called after it stops being called for
  9030   // N milliseconds. If `immediate` is passed, trigger the function on the
  9031   // leading edge, instead of the trailing.
  9032   _.debounce = function(func, wait, immediate) {
  9033     var timeout, result;
  9034     return function() {
  9035       var context = this, args = arguments;
  9036       var later = function() {
  9037         timeout = null;
  9038         if (!immediate) result = func.apply(context, args);
  9039       };
  9040       var callNow = immediate && !timeout;
  9041       clearTimeout(timeout);
  9042       timeout = setTimeout(later, wait);
  9043       if (callNow) result = func.apply(context, args);
  9044       return result;
  9045     };
  9046   };
  9048   // Returns a function that will be executed at most one time, no matter how
  9049   // often you call it. Useful for lazy initialization.
  9050   _.once = function(func) {
  9051     var ran = false, memo;
  9052     return function() {
  9053       if (ran) return memo;
  9054       ran = true;
  9055       memo = func.apply(this, arguments);
  9056       func = null;
  9057       return memo;
  9058     };
  9059   };
  9061   // Returns the first function passed as an argument to the second,
  9062   // allowing you to adjust arguments, run code before and after, and
  9063   // conditionally execute the original function.
  9064   _.wrap = function(func, wrapper) {
  9065     return function() {
  9066       var args = [func];
  9067       push.apply(args, arguments);
  9068       return wrapper.apply(this, args);
  9069     };
  9070   };
  9072   // Returns a function that is the composition of a list of functions, each
  9073   // consuming the return value of the function that follows.
  9074   _.compose = function() {
  9075     var funcs = arguments;
  9076     return function() {
  9077       var args = arguments;
  9078       for (var i = funcs.length - 1; i >= 0; i--) {
  9079         args = [funcs[i].apply(this, args)];
  9081       return args[0];
  9082     };
  9083   };
  9085   // Returns a function that will only be executed after being called N times.
  9086   _.after = function(times, func) {
  9087     if (times <= 0) return func();
  9088     return function() {
  9089       if (--times < 1) {
  9090         return func.apply(this, arguments);
  9092     };
  9093   };
  9095   // Object Functions
  9096   // ----------------
  9098   // Retrieve the names of an object's properties.
  9099   // Delegates to **ECMAScript 5**'s native `Object.keys`
  9100   _.keys = nativeKeys || function(obj) {
  9101     if (obj !== Object(obj)) throw new TypeError('Invalid object');
  9102     var keys = [];
  9103     for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
  9104     return keys;
  9105   };
  9107   // Retrieve the values of an object's properties.
  9108   _.values = function(obj) {
  9109     var values = [];
  9110     for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
  9111     return values;
  9112   };
  9114   // Convert an object into a list of `[key, value]` pairs.
  9115   _.pairs = function(obj) {
  9116     var pairs = [];
  9117     for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
  9118     return pairs;
  9119   };
  9121   // Invert the keys and values of an object. The values must be serializable.
  9122   _.invert = function(obj) {
  9123     var result = {};
  9124     for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
  9125     return result;
  9126   };
  9128   // Return a sorted list of the function names available on the object.
  9129   // Aliased as `methods`
  9130   _.functions = _.methods = function(obj) {
  9131     var names = [];
  9132     for (var key in obj) {
  9133       if (_.isFunction(obj[key])) names.push(key);
  9135     return names.sort();
  9136   };
  9138   // Extend a given object with all the properties in passed-in object(s).
  9139   _.extend = function(obj) {
  9140     each(slice.call(arguments, 1), function(source) {
  9141       if (source) {
  9142         for (var prop in source) {
  9143           obj[prop] = source[prop];
  9146     });
  9147     return obj;
  9148   };
  9150   // Return a copy of the object only containing the whitelisted properties.
  9151   _.pick = function(obj) {
  9152     var copy = {};
  9153     var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
  9154     each(keys, function(key) {
  9155       if (key in obj) copy[key] = obj[key];
  9156     });
  9157     return copy;
  9158   };
  9160    // Return a copy of the object without the blacklisted properties.
  9161   _.omit = function(obj) {
  9162     var copy = {};
  9163     var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
  9164     for (var key in obj) {
  9165       if (!_.contains(keys, key)) copy[key] = obj[key];
  9167     return copy;
  9168   };
  9170   // Fill in a given object with default properties.
  9171   _.defaults = function(obj) {
  9172     each(slice.call(arguments, 1), function(source) {
  9173       if (source) {
  9174         for (var prop in source) {
  9175           if (obj[prop] == null) obj[prop] = source[prop];
  9178     });
  9179     return obj;
  9180   };
  9182   // Create a (shallow-cloned) duplicate of an object.
  9183   _.clone = function(obj) {
  9184     if (!_.isObject(obj)) return obj;
  9185     return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
  9186   };
  9188   // Invokes interceptor with the obj, and then returns obj.
  9189   // The primary purpose of this method is to "tap into" a method chain, in
  9190   // order to perform operations on intermediate results within the chain.
  9191   _.tap = function(obj, interceptor) {
  9192     interceptor(obj);
  9193     return obj;
  9194   };
  9196   // Internal recursive comparison function for `isEqual`.
  9197   var eq = function(a, b, aStack, bStack) {
  9198     // Identical objects are equal. `0 === -0`, but they aren't identical.
  9199     // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
  9200     if (a === b) return a !== 0 || 1 / a == 1 / b;
  9201     // A strict comparison is necessary because `null == undefined`.
  9202     if (a == null || b == null) return a === b;
  9203     // Unwrap any wrapped objects.
  9204     if (a instanceof _) a = a._wrapped;
  9205     if (b instanceof _) b = b._wrapped;
  9206     // Compare `[[Class]]` names.
  9207     var className = toString.call(a);
  9208     if (className != toString.call(b)) return false;
  9209     switch (className) {
  9210       // Strings, numbers, dates, and booleans are compared by value.
  9211       case '[object String]':
  9212         // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
  9213         // equivalent to `new String("5")`.
  9214         return a == String(b);
  9215       case '[object Number]':
  9216         // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
  9217         // other numeric values.
  9218         return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
  9219       case '[object Date]':
  9220       case '[object Boolean]':
  9221         // Coerce dates and booleans to numeric primitive values. Dates are compared by their
  9222         // millisecond representations. Note that invalid dates with millisecond representations
  9223         // of `NaN` are not equivalent.
  9224         return +a == +b;
  9225       // RegExps are compared by their source patterns and flags.
  9226       case '[object RegExp]':
  9227         return a.source == b.source &&
  9228                a.global == b.global &&
  9229                a.multiline == b.multiline &&
  9230                a.ignoreCase == b.ignoreCase;
  9232     if (typeof a != 'object' || typeof b != 'object') return false;
  9233     // Assume equality for cyclic structures. The algorithm for detecting cyclic
  9234     // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
  9235     var length = aStack.length;
  9236     while (length--) {
  9237       // Linear search. Performance is inversely proportional to the number of
  9238       // unique nested structures.
  9239       if (aStack[length] == a) return bStack[length] == b;
  9241     // Add the first object to the stack of traversed objects.
  9242     aStack.push(a);
  9243     bStack.push(b);
  9244     var size = 0, result = true;
  9245     // Recursively compare objects and arrays.
  9246     if (className == '[object Array]') {
  9247       // Compare array lengths to determine if a deep comparison is necessary.
  9248       size = a.length;
  9249       result = size == b.length;
  9250       if (result) {
  9251         // Deep compare the contents, ignoring non-numeric properties.
  9252         while (size--) {
  9253           if (!(result = eq(a[size], b[size], aStack, bStack))) break;
  9256     } else {
  9257       // Objects with different constructors are not equivalent, but `Object`s
  9258       // from different frames are.
  9259       var aCtor = a.constructor, bCtor = b.constructor;
  9260       if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
  9261                                _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
  9262         return false;
  9264       // Deep compare objects.
  9265       for (var key in a) {
  9266         if (_.has(a, key)) {
  9267           // Count the expected number of properties.
  9268           size++;
  9269           // Deep compare each member.
  9270           if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
  9273       // Ensure that both objects contain the same number of properties.
  9274       if (result) {
  9275         for (key in b) {
  9276           if (_.has(b, key) && !(size--)) break;
  9278         result = !size;
  9281     // Remove the first object from the stack of traversed objects.
  9282     aStack.pop();
  9283     bStack.pop();
  9284     return result;
  9285   };
  9287   // Perform a deep comparison to check if two objects are equal.
  9288   _.isEqual = function(a, b) {
  9289     return eq(a, b, [], []);
  9290   };
  9292   // Is a given array, string, or object empty?
  9293   // An "empty" object has no enumerable own-properties.
  9294   _.isEmpty = function(obj) {
  9295     if (obj == null) return true;
  9296     if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
  9297     for (var key in obj) if (_.has(obj, key)) return false;
  9298     return true;
  9299   };
  9301   // Is a given value a DOM element?
  9302   _.isElement = function(obj) {
  9303     return !!(obj && obj.nodeType === 1);
  9304   };
  9306   // Is a given value an array?
  9307   // Delegates to ECMA5's native Array.isArray
  9308   _.isArray = nativeIsArray || function(obj) {
  9309     return toString.call(obj) == '[object Array]';
  9310   };
  9312   // Is a given variable an object?
  9313   _.isObject = function(obj) {
  9314     return obj === Object(obj);
  9315   };
  9317   // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
  9318   each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
  9319     _['is' + name] = function(obj) {
  9320       return toString.call(obj) == '[object ' + name + ']';
  9321     };
  9322   });
  9324   // Define a fallback version of the method in browsers (ahem, IE), where
  9325   // there isn't any inspectable "Arguments" type.
  9326   if (!_.isArguments(arguments)) {
  9327     _.isArguments = function(obj) {
  9328       return !!(obj && _.has(obj, 'callee'));
  9329     };
  9332   // Optimize `isFunction` if appropriate.
  9333   if (typeof (/./) !== 'function') {
  9334     _.isFunction = function(obj) {
  9335       return typeof obj === 'function';
  9336     };
  9339   // Is a given object a finite number?
  9340   _.isFinite = function(obj) {
  9341     return isFinite(obj) && !isNaN(parseFloat(obj));
  9342   };
  9344   // Is the given value `NaN`? (NaN is the only number which does not equal itself).
  9345   _.isNaN = function(obj) {
  9346     return _.isNumber(obj) && obj != +obj;
  9347   };
  9349   // Is a given value a boolean?
  9350   _.isBoolean = function(obj) {
  9351     return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
  9352   };
  9354   // Is a given value equal to null?
  9355   _.isNull = function(obj) {
  9356     return obj === null;
  9357   };
  9359   // Is a given variable undefined?
  9360   _.isUndefined = function(obj) {
  9361     return obj === void 0;
  9362   };
  9364   // Shortcut function for checking if an object has a given property directly
  9365   // on itself (in other words, not on a prototype).
  9366   _.has = function(obj, key) {
  9367     return hasOwnProperty.call(obj, key);
  9368   };
  9370   // Utility Functions
  9371   // -----------------
  9373   // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
  9374   // previous owner. Returns a reference to the Underscore object.
  9375   _.noConflict = function() {
  9376     root._ = previousUnderscore;
  9377     return this;
  9378   };
  9380   // Keep the identity function around for default iterators.
  9381   _.identity = function(value) {
  9382     return value;
  9383   };
  9385   // Run a function **n** times.
  9386   _.times = function(n, iterator, context) {
  9387     var accum = Array(n);
  9388     for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
  9389     return accum;
  9390   };
  9392   // Return a random integer between min and max (inclusive).
  9393   _.random = function(min, max) {
  9394     if (max == null) {
  9395       max = min;
  9396       min = 0;
  9398     return min + Math.floor(Math.random() * (max - min + 1));
  9399   };
  9401   // List of HTML entities for escaping.
  9402   var entityMap = {
  9403     escape: {
  9404       '&': '&amp;',
  9405       '<': '&lt;',
  9406       '>': '&gt;',
  9407       '"': '&quot;',
  9408       "'": '&#x27;',
  9409       '/': '&#x2F;'
  9411   };
  9412   entityMap.unescape = _.invert(entityMap.escape);
  9414   // Regexes containing the keys and values listed immediately above.
  9415   var entityRegexes = {
  9416     escape:   new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
  9417     unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
  9418   };
  9420   // Functions for escaping and unescaping strings to/from HTML interpolation.
  9421   _.each(['escape', 'unescape'], function(method) {
  9422     _[method] = function(string) {
  9423       if (string == null) return '';
  9424       return ('' + string).replace(entityRegexes[method], function(match) {
  9425         return entityMap[method][match];
  9426       });
  9427     };
  9428   });
  9430   // If the value of the named property is a function then invoke it;
  9431   // otherwise, return it.
  9432   _.result = function(object, property) {
  9433     if (object == null) return null;
  9434     var value = object[property];
  9435     return _.isFunction(value) ? value.call(object) : value;
  9436   };
  9438   // Add your own custom functions to the Underscore object.
  9439   _.mixin = function(obj) {
  9440     each(_.functions(obj), function(name){
  9441       var func = _[name] = obj[name];
  9442       _.prototype[name] = function() {
  9443         var args = [this._wrapped];
  9444         push.apply(args, arguments);
  9445         return result.call(this, func.apply(_, args));
  9446       };
  9447     });
  9448   };
  9450   // Generate a unique integer id (unique within the entire client session).
  9451   // Useful for temporary DOM ids.
  9452   var idCounter = 0;
  9453   _.uniqueId = function(prefix) {
  9454     var id = ++idCounter + '';
  9455     return prefix ? prefix + id : id;
  9456   };
  9458   // By default, Underscore uses ERB-style template delimiters, change the
  9459   // following template settings to use alternative delimiters.
  9460   _.templateSettings = {
  9461     evaluate    : /<%([\s\S]+?)%>/g,
  9462     interpolate : /<%=([\s\S]+?)%>/g,
  9463     escape      : /<%-([\s\S]+?)%>/g
  9464   };
  9466   // When customizing `templateSettings`, if you don't want to define an
  9467   // interpolation, evaluation or escaping regex, we need one that is
  9468   // guaranteed not to match.
  9469   var noMatch = /(.)^/;
  9471   // Certain characters need to be escaped so that they can be put into a
  9472   // string literal.
  9473   var escapes = {
  9474     "'":      "'",
  9475     '\\':     '\\',
  9476     '\r':     'r',
  9477     '\n':     'n',
  9478     '\t':     't',
  9479     '\u2028': 'u2028',
  9480     '\u2029': 'u2029'
  9481   };
  9483   var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
  9485   // JavaScript micro-templating, similar to John Resig's implementation.
  9486   // Underscore templating handles arbitrary delimiters, preserves whitespace,
  9487   // and correctly escapes quotes within interpolated code.
  9488   _.template = function(text, data, settings) {
  9489     var render;
  9490     settings = _.defaults({}, settings, _.templateSettings);
  9492     // Combine delimiters into one regular expression via alternation.
  9493     var matcher = new RegExp([
  9494       (settings.escape || noMatch).source,
  9495       (settings.interpolate || noMatch).source,
  9496       (settings.evaluate || noMatch).source
  9497     ].join('|') + '|$', 'g');
  9499     // Compile the template source, escaping string literals appropriately.
  9500     var index = 0;
  9501     var source = "__p+='";
  9502     text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
  9503       source += text.slice(index, offset)
  9504         .replace(escaper, function(match) { return '\\' + escapes[match]; });
  9506       if (escape) {
  9507         source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
  9509       if (interpolate) {
  9510         source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
  9512       if (evaluate) {
  9513         source += "';\n" + evaluate + "\n__p+='";
  9515       index = offset + match.length;
  9516       return match;
  9517     });
  9518     source += "';\n";
  9520     // If a variable is not specified, place data values in local scope.
  9521     if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
  9523     source = "var __t,__p='',__j=Array.prototype.join," +
  9524       "print=function(){__p+=__j.call(arguments,'');};\n" +
  9525       source + "return __p;\n";
  9527     try {
  9528       render = new Function(settings.variable || 'obj', '_', source);
  9529     } catch (e) {
  9530       e.source = source;
  9531       throw e;
  9534     if (data) return render(data, _);
  9535     var template = function(data) {
  9536       return render.call(this, data, _);
  9537     };
  9539     // Provide the compiled function source as a convenience for precompilation.
  9540     template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
  9542     return template;
  9543   };
  9545   // Add a "chain" function, which will delegate to the wrapper.
  9546   _.chain = function(obj) {
  9547     return _(obj).chain();
  9548   };
  9550   // OOP
  9551   // ---------------
  9552   // If Underscore is called as a function, it returns a wrapped object that
  9553   // can be used OO-style. This wrapper holds altered versions of all the
  9554   // underscore functions. Wrapped objects may be chained.
  9556   // Helper function to continue chaining intermediate results.
  9557   var result = function(obj) {
  9558     return this._chain ? _(obj).chain() : obj;
  9559   };
  9561   // Add all of the Underscore functions to the wrapper object.
  9562   _.mixin(_);
  9564   // Add all mutator Array functions to the wrapper.
  9565   each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
  9566     var method = ArrayProto[name];
  9567     _.prototype[name] = function() {
  9568       var obj = this._wrapped;
  9569       method.apply(obj, arguments);
  9570       if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
  9571       return result.call(this, obj);
  9572     };
  9573   });
  9575   // Add all accessor Array functions to the wrapper.
  9576   each(['concat', 'join', 'slice'], function(name) {
  9577     var method = ArrayProto[name];
  9578     _.prototype[name] = function() {
  9579       return result.call(this, method.apply(this._wrapped, arguments));
  9580     };
  9581   });
  9583   _.extend(_.prototype, {
  9585     // Start chaining a wrapped Underscore object.
  9586     chain: function() {
  9587       this._chain = true;
  9588       return this;
  9589     },
  9591     // Extracts the result from a wrapped and chained object.
  9592     value: function() {
  9593       return this._wrapped;
  9596   });
  9598 }).call(this);
  9600 })()
  9601 },{}],14:[function(require,module,exports){
  9602 exports.readIEEE754 = function(buffer, offset, isBE, mLen, nBytes) {
  9603   var e, m,
  9604       eLen = nBytes * 8 - mLen - 1,
  9605       eMax = (1 << eLen) - 1,
  9606       eBias = eMax >> 1,
  9607       nBits = -7,
  9608       i = isBE ? 0 : (nBytes - 1),
  9609       d = isBE ? 1 : -1,
  9610       s = buffer[offset + i];
  9612   i += d;
  9614   e = s & ((1 << (-nBits)) - 1);
  9615   s >>= (-nBits);
  9616   nBits += eLen;
  9617   for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8);
  9619   m = e & ((1 << (-nBits)) - 1);
  9620   e >>= (-nBits);
  9621   nBits += mLen;
  9622   for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8);
  9624   if (e === 0) {
  9625     e = 1 - eBias;
  9626   } else if (e === eMax) {
  9627     return m ? NaN : ((s ? -1 : 1) * Infinity);
  9628   } else {
  9629     m = m + Math.pow(2, mLen);
  9630     e = e - eBias;
  9632   return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
  9633 };
  9635 exports.writeIEEE754 = function(buffer, value, offset, isBE, mLen, nBytes) {
  9636   var e, m, c,
  9637       eLen = nBytes * 8 - mLen - 1,
  9638       eMax = (1 << eLen) - 1,
  9639       eBias = eMax >> 1,
  9640       rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
  9641       i = isBE ? (nBytes - 1) : 0,
  9642       d = isBE ? -1 : 1,
  9643       s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
  9645   value = Math.abs(value);
  9647   if (isNaN(value) || value === Infinity) {
  9648     m = isNaN(value) ? 1 : 0;
  9649     e = eMax;
  9650   } else {
  9651     e = Math.floor(Math.log(value) / Math.LN2);
  9652     if (value * (c = Math.pow(2, -e)) < 1) {
  9653       e--;
  9654       c *= 2;
  9656     if (e + eBias >= 1) {
  9657       value += rt / c;
  9658     } else {
  9659       value += rt * Math.pow(2, 1 - eBias);
  9661     if (value * c >= 2) {
  9662       e++;
  9663       c /= 2;
  9666     if (e + eBias >= eMax) {
  9667       m = 0;
  9668       e = eMax;
  9669     } else if (e + eBias >= 1) {
  9670       m = (value * c - 1) * Math.pow(2, mLen);
  9671       e = e + eBias;
  9672     } else {
  9673       m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
  9674       e = 0;
  9678   for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8);
  9680   e = (e << mLen) | m;
  9681   eLen += mLen;
  9682   for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8);
  9684   buffer[offset + i - d] |= s * 128;
  9685 };
  9687 },{}],13:[function(require,module,exports){
  9688 (function(){function SlowBuffer (size) {
  9689     this.length = size;
  9690 };
  9692 var assert = require('assert');
  9694 exports.INSPECT_MAX_BYTES = 50;
  9697 function toHex(n) {
  9698   if (n < 16) return '0' + n.toString(16);
  9699   return n.toString(16);
  9702 function utf8ToBytes(str) {
  9703   var byteArray = [];
  9704   for (var i = 0; i < str.length; i++)
  9705     if (str.charCodeAt(i) <= 0x7F)
  9706       byteArray.push(str.charCodeAt(i));
  9707     else {
  9708       var h = encodeURIComponent(str.charAt(i)).substr(1).split('%');
  9709       for (var j = 0; j < h.length; j++)
  9710         byteArray.push(parseInt(h[j], 16));
  9713   return byteArray;
  9716 function asciiToBytes(str) {
  9717   var byteArray = []
  9718   for (var i = 0; i < str.length; i++ )
  9719     // Node's code seems to be doing this and not & 0x7F..
  9720     byteArray.push( str.charCodeAt(i) & 0xFF );
  9722   return byteArray;
  9725 function base64ToBytes(str) {
  9726   return require("base64-js").toByteArray(str);
  9729 SlowBuffer.byteLength = function (str, encoding) {
  9730   switch (encoding || "utf8") {
  9731     case 'hex':
  9732       return str.length / 2;
  9734     case 'utf8':
  9735     case 'utf-8':
  9736       return utf8ToBytes(str).length;
  9738     case 'ascii':
  9739     case 'binary':
  9740       return str.length;
  9742     case 'base64':
  9743       return base64ToBytes(str).length;
  9745     default:
  9746       throw new Error('Unknown encoding');
  9748 };
  9750 function blitBuffer(src, dst, offset, length) {
  9751   var pos, i = 0;
  9752   while (i < length) {
  9753     if ((i+offset >= dst.length) || (i >= src.length))
  9754       break;
  9756     dst[i + offset] = src[i];
  9757     i++;
  9759   return i;
  9762 SlowBuffer.prototype.utf8Write = function (string, offset, length) {
  9763   var bytes, pos;
  9764   return SlowBuffer._charsWritten =  blitBuffer(utf8ToBytes(string), this, offset, length);
  9765 };
  9767 SlowBuffer.prototype.asciiWrite = function (string, offset, length) {
  9768   var bytes, pos;
  9769   return SlowBuffer._charsWritten =  blitBuffer(asciiToBytes(string), this, offset, length);
  9770 };
  9772 SlowBuffer.prototype.binaryWrite = SlowBuffer.prototype.asciiWrite;
  9774 SlowBuffer.prototype.base64Write = function (string, offset, length) {
  9775   var bytes, pos;
  9776   return SlowBuffer._charsWritten = blitBuffer(base64ToBytes(string), this, offset, length);
  9777 };
  9779 SlowBuffer.prototype.base64Slice = function (start, end) {
  9780   var bytes = Array.prototype.slice.apply(this, arguments)
  9781   return require("base64-js").fromByteArray(bytes);
  9784 function decodeUtf8Char(str) {
  9785   try {
  9786     return decodeURIComponent(str);
  9787   } catch (err) {
  9788     return String.fromCharCode(0xFFFD); // UTF 8 invalid char
  9792 SlowBuffer.prototype.utf8Slice = function () {
  9793   var bytes = Array.prototype.slice.apply(this, arguments);
  9794   var res = "";
  9795   var tmp = "";
  9796   var i = 0;
  9797   while (i < bytes.length) {
  9798     if (bytes[i] <= 0x7F) {
  9799       res += decodeUtf8Char(tmp) + String.fromCharCode(bytes[i]);
  9800       tmp = "";
  9801     } else
  9802       tmp += "%" + bytes[i].toString(16);
  9804     i++;
  9807   return res + decodeUtf8Char(tmp);
  9810 SlowBuffer.prototype.asciiSlice = function () {
  9811   var bytes = Array.prototype.slice.apply(this, arguments);
  9812   var ret = "";
  9813   for (var i = 0; i < bytes.length; i++)
  9814     ret += String.fromCharCode(bytes[i]);
  9815   return ret;
  9818 SlowBuffer.prototype.binarySlice = SlowBuffer.prototype.asciiSlice;
  9820 SlowBuffer.prototype.inspect = function() {
  9821   var out = [],
  9822       len = this.length;
  9823   for (var i = 0; i < len; i++) {
  9824     out[i] = toHex(this[i]);
  9825     if (i == exports.INSPECT_MAX_BYTES) {
  9826       out[i + 1] = '...';
  9827       break;
  9830   return '<SlowBuffer ' + out.join(' ') + '>';
  9831 };
  9834 SlowBuffer.prototype.hexSlice = function(start, end) {
  9835   var len = this.length;
  9837   if (!start || start < 0) start = 0;
  9838   if (!end || end < 0 || end > len) end = len;
  9840   var out = '';
  9841   for (var i = start; i < end; i++) {
  9842     out += toHex(this[i]);
  9844   return out;
  9845 };
  9848 SlowBuffer.prototype.toString = function(encoding, start, end) {
  9849   encoding = String(encoding || 'utf8').toLowerCase();
  9850   start = +start || 0;
  9851   if (typeof end == 'undefined') end = this.length;
  9853   // Fastpath empty strings
  9854   if (+end == start) {
  9855     return '';
  9858   switch (encoding) {
  9859     case 'hex':
  9860       return this.hexSlice(start, end);
  9862     case 'utf8':
  9863     case 'utf-8':
  9864       return this.utf8Slice(start, end);
  9866     case 'ascii':
  9867       return this.asciiSlice(start, end);
  9869     case 'binary':
  9870       return this.binarySlice(start, end);
  9872     case 'base64':
  9873       return this.base64Slice(start, end);
  9875     case 'ucs2':
  9876     case 'ucs-2':
  9877       return this.ucs2Slice(start, end);
  9879     default:
  9880       throw new Error('Unknown encoding');
  9882 };
  9885 SlowBuffer.prototype.hexWrite = function(string, offset, length) {
  9886   offset = +offset || 0;
  9887   var remaining = this.length - offset;
  9888   if (!length) {
  9889     length = remaining;
  9890   } else {
  9891     length = +length;
  9892     if (length > remaining) {
  9893       length = remaining;
  9897   // must be an even number of digits
  9898   var strLen = string.length;
  9899   if (strLen % 2) {
  9900     throw new Error('Invalid hex string');
  9902   if (length > strLen / 2) {
  9903     length = strLen / 2;
  9905   for (var i = 0; i < length; i++) {
  9906     var byte = parseInt(string.substr(i * 2, 2), 16);
  9907     if (isNaN(byte)) throw new Error('Invalid hex string');
  9908     this[offset + i] = byte;
  9910   SlowBuffer._charsWritten = i * 2;
  9911   return i;
  9912 };
  9915 SlowBuffer.prototype.write = function(string, offset, length, encoding) {
  9916   // Support both (string, offset, length, encoding)
  9917   // and the legacy (string, encoding, offset, length)
  9918   if (isFinite(offset)) {
  9919     if (!isFinite(length)) {
  9920       encoding = length;
  9921       length = undefined;
  9923   } else {  // legacy
  9924     var swap = encoding;
  9925     encoding = offset;
  9926     offset = length;
  9927     length = swap;
  9930   offset = +offset || 0;
  9931   var remaining = this.length - offset;
  9932   if (!length) {
  9933     length = remaining;
  9934   } else {
  9935     length = +length;
  9936     if (length > remaining) {
  9937       length = remaining;
  9940   encoding = String(encoding || 'utf8').toLowerCase();
  9942   switch (encoding) {
  9943     case 'hex':
  9944       return this.hexWrite(string, offset, length);
  9946     case 'utf8':
  9947     case 'utf-8':
  9948       return this.utf8Write(string, offset, length);
  9950     case 'ascii':
  9951       return this.asciiWrite(string, offset, length);
  9953     case 'binary':
  9954       return this.binaryWrite(string, offset, length);
  9956     case 'base64':
  9957       return this.base64Write(string, offset, length);
  9959     case 'ucs2':
  9960     case 'ucs-2':
  9961       return this.ucs2Write(string, offset, length);
  9963     default:
  9964       throw new Error('Unknown encoding');
  9966 };
  9969 // slice(start, end)
  9970 SlowBuffer.prototype.slice = function(start, end) {
  9971   if (end === undefined) end = this.length;
  9973   if (end > this.length) {
  9974     throw new Error('oob');
  9976   if (start > end) {
  9977     throw new Error('oob');
  9980   return new Buffer(this, end - start, +start);
  9981 };
  9983 SlowBuffer.prototype.copy = function(target, targetstart, sourcestart, sourceend) {
  9984   var temp = [];
  9985   for (var i=sourcestart; i<sourceend; i++) {
  9986     assert.ok(typeof this[i] !== 'undefined', "copying undefined buffer bytes!");
  9987     temp.push(this[i]);
  9990   for (var i=targetstart; i<targetstart+temp.length; i++) {
  9991     target[i] = temp[i-targetstart];
  9993 };
  9995 SlowBuffer.prototype.fill = function(value, start, end) {
  9996   if (end > this.length) {
  9997     throw new Error('oob');
  9999   if (start > end) {
 10000     throw new Error('oob');
 10003   for (var i = start; i < end; i++) {
 10004     this[i] = value;
 10008 function coerce(length) {
 10009   // Coerce length to a number (possibly NaN), round up
 10010   // in case it's fractional (e.g. 123.456) then do a
 10011   // double negate to coerce a NaN to 0. Easy, right?
 10012   length = ~~Math.ceil(+length);
 10013   return length < 0 ? 0 : length;
 10017 // Buffer
 10019 function Buffer(subject, encoding, offset) {
 10020   if (!(this instanceof Buffer)) {
 10021     return new Buffer(subject, encoding, offset);
 10024   var type;
 10026   // Are we slicing?
 10027   if (typeof offset === 'number') {
 10028     this.length = coerce(encoding);
 10029     this.parent = subject;
 10030     this.offset = offset;
 10031   } else {
 10032     // Find the length
 10033     switch (type = typeof subject) {
 10034       case 'number':
 10035         this.length = coerce(subject);
 10036         break;
 10038       case 'string':
 10039         this.length = Buffer.byteLength(subject, encoding);
 10040         break;
 10042       case 'object': // Assume object is an array
 10043         this.length = coerce(subject.length);
 10044         break;
 10046       default:
 10047         throw new Error('First argument needs to be a number, ' +
 10048                         'array or string.');
 10051     if (this.length > Buffer.poolSize) {
 10052       // Big buffer, just alloc one.
 10053       this.parent = new SlowBuffer(this.length);
 10054       this.offset = 0;
 10056     } else {
 10057       // Small buffer.
 10058       if (!pool || pool.length - pool.used < this.length) allocPool();
 10059       this.parent = pool;
 10060       this.offset = pool.used;
 10061       pool.used += this.length;
 10064     // Treat array-ish objects as a byte array.
 10065     if (isArrayIsh(subject)) {
 10066       for (var i = 0; i < this.length; i++) {
 10067         if (subject instanceof Buffer) {
 10068           this.parent[i + this.offset] = subject.readUInt8(i);
 10070         else {
 10071           this.parent[i + this.offset] = subject[i];
 10074     } else if (type == 'string') {
 10075       // We are a string
 10076       this.length = this.write(subject, 0, encoding);
 10082 function isArrayIsh(subject) {
 10083   return Array.isArray(subject) || Buffer.isBuffer(subject) ||
 10084          subject && typeof subject === 'object' &&
 10085          typeof subject.length === 'number';
 10088 exports.SlowBuffer = SlowBuffer;
 10089 exports.Buffer = Buffer;
 10091 Buffer.poolSize = 8 * 1024;
 10092 var pool;
 10094 function allocPool() {
 10095   pool = new SlowBuffer(Buffer.poolSize);
 10096   pool.used = 0;
 10100 // Static methods
 10101 Buffer.isBuffer = function isBuffer(b) {
 10102   return b instanceof Buffer || b instanceof SlowBuffer;
 10103 };
 10105 Buffer.concat = function (list, totalLength) {
 10106   if (!Array.isArray(list)) {
 10107     throw new Error("Usage: Buffer.concat(list, [totalLength])\n \
 10108       list should be an Array.");
 10111   if (list.length === 0) {
 10112     return new Buffer(0);
 10113   } else if (list.length === 1) {
 10114     return list[0];
 10117   if (typeof totalLength !== 'number') {
 10118     totalLength = 0;
 10119     for (var i = 0; i < list.length; i++) {
 10120       var buf = list[i];
 10121       totalLength += buf.length;
 10125   var buffer = new Buffer(totalLength);
 10126   var pos = 0;
 10127   for (var i = 0; i < list.length; i++) {
 10128     var buf = list[i];
 10129     buf.copy(buffer, pos);
 10130     pos += buf.length;
 10132   return buffer;
 10133 };
 10135 // Inspect
 10136 Buffer.prototype.inspect = function inspect() {
 10137   var out = [],
 10138       len = this.length;
 10140   for (var i = 0; i < len; i++) {
 10141     out[i] = toHex(this.parent[i + this.offset]);
 10142     if (i == exports.INSPECT_MAX_BYTES) {
 10143       out[i + 1] = '...';
 10144       break;
 10148   return '<Buffer ' + out.join(' ') + '>';
 10149 };
 10152 Buffer.prototype.get = function get(i) {
 10153   if (i < 0 || i >= this.length) throw new Error('oob');
 10154   return this.parent[this.offset + i];
 10155 };
 10158 Buffer.prototype.set = function set(i, v) {
 10159   if (i < 0 || i >= this.length) throw new Error('oob');
 10160   return this.parent[this.offset + i] = v;
 10161 };
 10164 // write(string, offset = 0, length = buffer.length-offset, encoding = 'utf8')
 10165 Buffer.prototype.write = function(string, offset, length, encoding) {
 10166   // Support both (string, offset, length, encoding)
 10167   // and the legacy (string, encoding, offset, length)
 10168   if (isFinite(offset)) {
 10169     if (!isFinite(length)) {
 10170       encoding = length;
 10171       length = undefined;
 10173   } else {  // legacy
 10174     var swap = encoding;
 10175     encoding = offset;
 10176     offset = length;
 10177     length = swap;
 10180   offset = +offset || 0;
 10181   var remaining = this.length - offset;
 10182   if (!length) {
 10183     length = remaining;
 10184   } else {
 10185     length = +length;
 10186     if (length > remaining) {
 10187       length = remaining;
 10190   encoding = String(encoding || 'utf8').toLowerCase();
 10192   var ret;
 10193   switch (encoding) {
 10194     case 'hex':
 10195       ret = this.parent.hexWrite(string, this.offset + offset, length);
 10196       break;
 10198     case 'utf8':
 10199     case 'utf-8':
 10200       ret = this.parent.utf8Write(string, this.offset + offset, length);
 10201       break;
 10203     case 'ascii':
 10204       ret = this.parent.asciiWrite(string, this.offset + offset, length);
 10205       break;
 10207     case 'binary':
 10208       ret = this.parent.binaryWrite(string, this.offset + offset, length);
 10209       break;
 10211     case 'base64':
 10212       // Warning: maxLength not taken into account in base64Write
 10213       ret = this.parent.base64Write(string, this.offset + offset, length);
 10214       break;
 10216     case 'ucs2':
 10217     case 'ucs-2':
 10218       ret = this.parent.ucs2Write(string, this.offset + offset, length);
 10219       break;
 10221     default:
 10222       throw new Error('Unknown encoding');
 10225   Buffer._charsWritten = SlowBuffer._charsWritten;
 10227   return ret;
 10228 };
 10231 // toString(encoding, start=0, end=buffer.length)
 10232 Buffer.prototype.toString = function(encoding, start, end) {
 10233   encoding = String(encoding || 'utf8').toLowerCase();
 10235   if (typeof start == 'undefined' || start < 0) {
 10236     start = 0;
 10237   } else if (start > this.length) {
 10238     start = this.length;
 10241   if (typeof end == 'undefined' || end > this.length) {
 10242     end = this.length;
 10243   } else if (end < 0) {
 10244     end = 0;
 10247   start = start + this.offset;
 10248   end = end + this.offset;
 10250   switch (encoding) {
 10251     case 'hex':
 10252       return this.parent.hexSlice(start, end);
 10254     case 'utf8':
 10255     case 'utf-8':
 10256       return this.parent.utf8Slice(start, end);
 10258     case 'ascii':
 10259       return this.parent.asciiSlice(start, end);
 10261     case 'binary':
 10262       return this.parent.binarySlice(start, end);
 10264     case 'base64':
 10265       return this.parent.base64Slice(start, end);
 10267     case 'ucs2':
 10268     case 'ucs-2':
 10269       return this.parent.ucs2Slice(start, end);
 10271     default:
 10272       throw new Error('Unknown encoding');
 10274 };
 10277 // byteLength
 10278 Buffer.byteLength = SlowBuffer.byteLength;
 10281 // fill(value, start=0, end=buffer.length)
 10282 Buffer.prototype.fill = function fill(value, start, end) {
 10283   value || (value = 0);
 10284   start || (start = 0);
 10285   end || (end = this.length);
 10287   if (typeof value === 'string') {
 10288     value = value.charCodeAt(0);
 10290   if (!(typeof value === 'number') || isNaN(value)) {
 10291     throw new Error('value is not a number');
 10294   if (end < start) throw new Error('end < start');
 10296   // Fill 0 bytes; we're done
 10297   if (end === start) return 0;
 10298   if (this.length == 0) return 0;
 10300   if (start < 0 || start >= this.length) {
 10301     throw new Error('start out of bounds');
 10304   if (end < 0 || end > this.length) {
 10305     throw new Error('end out of bounds');
 10308   return this.parent.fill(value,
 10309                           start + this.offset,
 10310                           end + this.offset);
 10311 };
 10314 // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
 10315 Buffer.prototype.copy = function(target, target_start, start, end) {
 10316   var source = this;
 10317   start || (start = 0);
 10318   end || (end = this.length);
 10319   target_start || (target_start = 0);
 10321   if (end < start) throw new Error('sourceEnd < sourceStart');
 10323   // Copy 0 bytes; we're done
 10324   if (end === start) return 0;
 10325   if (target.length == 0 || source.length == 0) return 0;
 10327   if (target_start < 0 || target_start >= target.length) {
 10328     throw new Error('targetStart out of bounds');
 10331   if (start < 0 || start >= source.length) {
 10332     throw new Error('sourceStart out of bounds');
 10335   if (end < 0 || end > source.length) {
 10336     throw new Error('sourceEnd out of bounds');
 10339   // Are we oob?
 10340   if (end > this.length) {
 10341     end = this.length;
 10344   if (target.length - target_start < end - start) {
 10345     end = target.length - target_start + start;
 10348   return this.parent.copy(target.parent,
 10349                           target_start + target.offset,
 10350                           start + this.offset,
 10351                           end + this.offset);
 10352 };
 10355 // slice(start, end)
 10356 Buffer.prototype.slice = function(start, end) {
 10357   if (end === undefined) end = this.length;
 10358   if (end > this.length) throw new Error('oob');
 10359   if (start > end) throw new Error('oob');
 10361   return new Buffer(this.parent, end - start, +start + this.offset);
 10362 };
 10365 // Legacy methods for backwards compatibility.
 10367 Buffer.prototype.utf8Slice = function(start, end) {
 10368   return this.toString('utf8', start, end);
 10369 };
 10371 Buffer.prototype.binarySlice = function(start, end) {
 10372   return this.toString('binary', start, end);
 10373 };
 10375 Buffer.prototype.asciiSlice = function(start, end) {
 10376   return this.toString('ascii', start, end);
 10377 };
 10379 Buffer.prototype.utf8Write = function(string, offset) {
 10380   return this.write(string, offset, 'utf8');
 10381 };
 10383 Buffer.prototype.binaryWrite = function(string, offset) {
 10384   return this.write(string, offset, 'binary');
 10385 };
 10387 Buffer.prototype.asciiWrite = function(string, offset) {
 10388   return this.write(string, offset, 'ascii');
 10389 };
 10391 Buffer.prototype.readUInt8 = function(offset, noAssert) {
 10392   var buffer = this;
 10394   if (!noAssert) {
 10395     assert.ok(offset !== undefined && offset !== null,
 10396         'missing offset');
 10398     assert.ok(offset < buffer.length,
 10399         'Trying to read beyond buffer length');
 10402   if (offset >= buffer.length) return;
 10404   return buffer.parent[buffer.offset + offset];
 10405 };
 10407 function readUInt16(buffer, offset, isBigEndian, noAssert) {
 10408   var val = 0;
 10411   if (!noAssert) {
 10412     assert.ok(typeof (isBigEndian) === 'boolean',
 10413         'missing or invalid endian');
 10415     assert.ok(offset !== undefined && offset !== null,
 10416         'missing offset');
 10418     assert.ok(offset + 1 < buffer.length,
 10419         'Trying to read beyond buffer length');
 10422   if (offset >= buffer.length) return 0;
 10424   if (isBigEndian) {
 10425     val = buffer.parent[buffer.offset + offset] << 8;
 10426     if (offset + 1 < buffer.length) {
 10427       val |= buffer.parent[buffer.offset + offset + 1];
 10429   } else {
 10430     val = buffer.parent[buffer.offset + offset];
 10431     if (offset + 1 < buffer.length) {
 10432       val |= buffer.parent[buffer.offset + offset + 1] << 8;
 10436   return val;
 10439 Buffer.prototype.readUInt16LE = function(offset, noAssert) {
 10440   return readUInt16(this, offset, false, noAssert);
 10441 };
 10443 Buffer.prototype.readUInt16BE = function(offset, noAssert) {
 10444   return readUInt16(this, offset, true, noAssert);
 10445 };
 10447 function readUInt32(buffer, offset, isBigEndian, noAssert) {
 10448   var val = 0;
 10450   if (!noAssert) {
 10451     assert.ok(typeof (isBigEndian) === 'boolean',
 10452         'missing or invalid endian');
 10454     assert.ok(offset !== undefined && offset !== null,
 10455         'missing offset');
 10457     assert.ok(offset + 3 < buffer.length,
 10458         'Trying to read beyond buffer length');
 10461   if (offset >= buffer.length) return 0;
 10463   if (isBigEndian) {
 10464     if (offset + 1 < buffer.length)
 10465       val = buffer.parent[buffer.offset + offset + 1] << 16;
 10466     if (offset + 2 < buffer.length)
 10467       val |= buffer.parent[buffer.offset + offset + 2] << 8;
 10468     if (offset + 3 < buffer.length)
 10469       val |= buffer.parent[buffer.offset + offset + 3];
 10470     val = val + (buffer.parent[buffer.offset + offset] << 24 >>> 0);
 10471   } else {
 10472     if (offset + 2 < buffer.length)
 10473       val = buffer.parent[buffer.offset + offset + 2] << 16;
 10474     if (offset + 1 < buffer.length)
 10475       val |= buffer.parent[buffer.offset + offset + 1] << 8;
 10476     val |= buffer.parent[buffer.offset + offset];
 10477     if (offset + 3 < buffer.length)
 10478       val = val + (buffer.parent[buffer.offset + offset + 3] << 24 >>> 0);
 10481   return val;
 10484 Buffer.prototype.readUInt32LE = function(offset, noAssert) {
 10485   return readUInt32(this, offset, false, noAssert);
 10486 };
 10488 Buffer.prototype.readUInt32BE = function(offset, noAssert) {
 10489   return readUInt32(this, offset, true, noAssert);
 10490 };
 10493 /*
 10494  * Signed integer types, yay team! A reminder on how two's complement actually
 10495  * works. The first bit is the signed bit, i.e. tells us whether or not the
 10496  * number should be positive or negative. If the two's complement value is
 10497  * positive, then we're done, as it's equivalent to the unsigned representation.
 10499  * Now if the number is positive, you're pretty much done, you can just leverage
 10500  * the unsigned translations and return those. Unfortunately, negative numbers
 10501  * aren't quite that straightforward.
 10503  * At first glance, one might be inclined to use the traditional formula to
 10504  * translate binary numbers between the positive and negative values in two's
 10505  * complement. (Though it doesn't quite work for the most negative value)
 10506  * Mainly:
 10507  *  - invert all the bits
 10508  *  - add one to the result
 10510  * Of course, this doesn't quite work in Javascript. Take for example the value
 10511  * of -128. This could be represented in 16 bits (big-endian) as 0xff80. But of
 10512  * course, Javascript will do the following:
 10514  * > ~0xff80
 10515  * -65409
 10517  * Whoh there, Javascript, that's not quite right. But wait, according to
 10518  * Javascript that's perfectly correct. When Javascript ends up seeing the
 10519  * constant 0xff80, it has no notion that it is actually a signed number. It
 10520  * assumes that we've input the unsigned value 0xff80. Thus, when it does the
 10521  * binary negation, it casts it into a signed value, (positive 0xff80). Then
 10522  * when you perform binary negation on that, it turns it into a negative number.
 10524  * Instead, we're going to have to use the following general formula, that works
 10525  * in a rather Javascript friendly way. I'm glad we don't support this kind of
 10526  * weird numbering scheme in the kernel.
 10528  * (BIT-MAX - (unsigned)val + 1) * -1
 10530  * The astute observer, may think that this doesn't make sense for 8-bit numbers
 10531  * (really it isn't necessary for them). However, when you get 16-bit numbers,
 10532  * you do. Let's go back to our prior example and see how this will look:
 10534  * (0xffff - 0xff80 + 1) * -1
 10535  * (0x007f + 1) * -1
 10536  * (0x0080) * -1
 10537  */
 10538 Buffer.prototype.readInt8 = function(offset, noAssert) {
 10539   var buffer = this;
 10540   var neg;
 10542   if (!noAssert) {
 10543     assert.ok(offset !== undefined && offset !== null,
 10544         'missing offset');
 10546     assert.ok(offset < buffer.length,
 10547         'Trying to read beyond buffer length');
 10550   if (offset >= buffer.length) return;
 10552   neg = buffer.parent[buffer.offset + offset] & 0x80;
 10553   if (!neg) {
 10554     return (buffer.parent[buffer.offset + offset]);
 10557   return ((0xff - buffer.parent[buffer.offset + offset] + 1) * -1);
 10558 };
 10560 function readInt16(buffer, offset, isBigEndian, noAssert) {
 10561   var neg, val;
 10563   if (!noAssert) {
 10564     assert.ok(typeof (isBigEndian) === 'boolean',
 10565         'missing or invalid endian');
 10567     assert.ok(offset !== undefined && offset !== null,
 10568         'missing offset');
 10570     assert.ok(offset + 1 < buffer.length,
 10571         'Trying to read beyond buffer length');
 10574   val = readUInt16(buffer, offset, isBigEndian, noAssert);
 10575   neg = val & 0x8000;
 10576   if (!neg) {
 10577     return val;
 10580   return (0xffff - val + 1) * -1;
 10583 Buffer.prototype.readInt16LE = function(offset, noAssert) {
 10584   return readInt16(this, offset, false, noAssert);
 10585 };
 10587 Buffer.prototype.readInt16BE = function(offset, noAssert) {
 10588   return readInt16(this, offset, true, noAssert);
 10589 };
 10591 function readInt32(buffer, offset, isBigEndian, noAssert) {
 10592   var neg, val;
 10594   if (!noAssert) {
 10595     assert.ok(typeof (isBigEndian) === 'boolean',
 10596         'missing or invalid endian');
 10598     assert.ok(offset !== undefined && offset !== null,
 10599         'missing offset');
 10601     assert.ok(offset + 3 < buffer.length,
 10602         'Trying to read beyond buffer length');
 10605   val = readUInt32(buffer, offset, isBigEndian, noAssert);
 10606   neg = val & 0x80000000;
 10607   if (!neg) {
 10608     return (val);
 10611   return (0xffffffff - val + 1) * -1;
 10614 Buffer.prototype.readInt32LE = function(offset, noAssert) {
 10615   return readInt32(this, offset, false, noAssert);
 10616 };
 10618 Buffer.prototype.readInt32BE = function(offset, noAssert) {
 10619   return readInt32(this, offset, true, noAssert);
 10620 };
 10622 function readFloat(buffer, offset, isBigEndian, noAssert) {
 10623   if (!noAssert) {
 10624     assert.ok(typeof (isBigEndian) === 'boolean',
 10625         'missing or invalid endian');
 10627     assert.ok(offset + 3 < buffer.length,
 10628         'Trying to read beyond buffer length');
 10631   return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian,
 10632       23, 4);
 10635 Buffer.prototype.readFloatLE = function(offset, noAssert) {
 10636   return readFloat(this, offset, false, noAssert);
 10637 };
 10639 Buffer.prototype.readFloatBE = function(offset, noAssert) {
 10640   return readFloat(this, offset, true, noAssert);
 10641 };
 10643 function readDouble(buffer, offset, isBigEndian, noAssert) {
 10644   if (!noAssert) {
 10645     assert.ok(typeof (isBigEndian) === 'boolean',
 10646         'missing or invalid endian');
 10648     assert.ok(offset + 7 < buffer.length,
 10649         'Trying to read beyond buffer length');
 10652   return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian,
 10653       52, 8);
 10656 Buffer.prototype.readDoubleLE = function(offset, noAssert) {
 10657   return readDouble(this, offset, false, noAssert);
 10658 };
 10660 Buffer.prototype.readDoubleBE = function(offset, noAssert) {
 10661   return readDouble(this, offset, true, noAssert);
 10662 };
 10665 /*
 10666  * We have to make sure that the value is a valid integer. This means that it is
 10667  * non-negative. It has no fractional component and that it does not exceed the
 10668  * maximum allowed value.
 10670  *      value           The number to check for validity
 10672  *      max             The maximum value
 10673  */
 10674 function verifuint(value, max) {
 10675   assert.ok(typeof (value) == 'number',
 10676       'cannot write a non-number as a number');
 10678   assert.ok(value >= 0,
 10679       'specified a negative value for writing an unsigned value');
 10681   assert.ok(value <= max, 'value is larger than maximum value for type');
 10683   assert.ok(Math.floor(value) === value, 'value has a fractional component');
 10686 Buffer.prototype.writeUInt8 = function(value, offset, noAssert) {
 10687   var buffer = this;
 10689   if (!noAssert) {
 10690     assert.ok(value !== undefined && value !== null,
 10691         'missing value');
 10693     assert.ok(offset !== undefined && offset !== null,
 10694         'missing offset');
 10696     assert.ok(offset < buffer.length,
 10697         'trying to write beyond buffer length');
 10699     verifuint(value, 0xff);
 10702   if (offset < buffer.length) {
 10703     buffer.parent[buffer.offset + offset] = value;
 10705 };
 10707 function writeUInt16(buffer, value, offset, isBigEndian, noAssert) {
 10708   if (!noAssert) {
 10709     assert.ok(value !== undefined && value !== null,
 10710         'missing value');
 10712     assert.ok(typeof (isBigEndian) === 'boolean',
 10713         'missing or invalid endian');
 10715     assert.ok(offset !== undefined && offset !== null,
 10716         'missing offset');
 10718     assert.ok(offset + 1 < buffer.length,
 10719         'trying to write beyond buffer length');
 10721     verifuint(value, 0xffff);
 10724   for (var i = 0; i < Math.min(buffer.length - offset, 2); i++) {
 10725     buffer.parent[buffer.offset + offset + i] =
 10726         (value & (0xff << (8 * (isBigEndian ? 1 - i : i)))) >>>
 10727             (isBigEndian ? 1 - i : i) * 8;
 10732 Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) {
 10733   writeUInt16(this, value, offset, false, noAssert);
 10734 };
 10736 Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) {
 10737   writeUInt16(this, value, offset, true, noAssert);
 10738 };
 10740 function writeUInt32(buffer, value, offset, isBigEndian, noAssert) {
 10741   if (!noAssert) {
 10742     assert.ok(value !== undefined && value !== null,
 10743         'missing value');
 10745     assert.ok(typeof (isBigEndian) === 'boolean',
 10746         'missing or invalid endian');
 10748     assert.ok(offset !== undefined && offset !== null,
 10749         'missing offset');
 10751     assert.ok(offset + 3 < buffer.length,
 10752         'trying to write beyond buffer length');
 10754     verifuint(value, 0xffffffff);
 10757   for (var i = 0; i < Math.min(buffer.length - offset, 4); i++) {
 10758     buffer.parent[buffer.offset + offset + i] =
 10759         (value >>> (isBigEndian ? 3 - i : i) * 8) & 0xff;
 10763 Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) {
 10764   writeUInt32(this, value, offset, false, noAssert);
 10765 };
 10767 Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) {
 10768   writeUInt32(this, value, offset, true, noAssert);
 10769 };
 10772 /*
 10773  * We now move onto our friends in the signed number category. Unlike unsigned
 10774  * numbers, we're going to have to worry a bit more about how we put values into
 10775  * arrays. Since we are only worrying about signed 32-bit values, we're in
 10776  * slightly better shape. Unfortunately, we really can't do our favorite binary
 10777  * & in this system. It really seems to do the wrong thing. For example:
 10779  * > -32 & 0xff
 10780  * 224
 10782  * What's happening above is really: 0xe0 & 0xff = 0xe0. However, the results of
 10783  * this aren't treated as a signed number. Ultimately a bad thing.
 10785  * What we're going to want to do is basically create the unsigned equivalent of
 10786  * our representation and pass that off to the wuint* functions. To do that
 10787  * we're going to do the following:
 10789  *  - if the value is positive
 10790  *      we can pass it directly off to the equivalent wuint
 10791  *  - if the value is negative
 10792  *      we do the following computation:
 10793  *         mb + val + 1, where
 10794  *         mb   is the maximum unsigned value in that byte size
 10795  *         val  is the Javascript negative integer
 10798  * As a concrete value, take -128. In signed 16 bits this would be 0xff80. If
 10799  * you do out the computations:
 10801  * 0xffff - 128 + 1
 10802  * 0xffff - 127
 10803  * 0xff80
 10805  * You can then encode this value as the signed version. This is really rather
 10806  * hacky, but it should work and get the job done which is our goal here.
 10807  */
 10809 /*
 10810  * A series of checks to make sure we actually have a signed 32-bit number
 10811  */
 10812 function verifsint(value, max, min) {
 10813   assert.ok(typeof (value) == 'number',
 10814       'cannot write a non-number as a number');
 10816   assert.ok(value <= max, 'value larger than maximum allowed value');
 10818   assert.ok(value >= min, 'value smaller than minimum allowed value');
 10820   assert.ok(Math.floor(value) === value, 'value has a fractional component');
 10823 function verifIEEE754(value, max, min) {
 10824   assert.ok(typeof (value) == 'number',
 10825       'cannot write a non-number as a number');
 10827   assert.ok(value <= max, 'value larger than maximum allowed value');
 10829   assert.ok(value >= min, 'value smaller than minimum allowed value');
 10832 Buffer.prototype.writeInt8 = function(value, offset, noAssert) {
 10833   var buffer = this;
 10835   if (!noAssert) {
 10836     assert.ok(value !== undefined && value !== null,
 10837         'missing value');
 10839     assert.ok(offset !== undefined && offset !== null,
 10840         'missing offset');
 10842     assert.ok(offset < buffer.length,
 10843         'Trying to write beyond buffer length');
 10845     verifsint(value, 0x7f, -0x80);
 10848   if (value >= 0) {
 10849     buffer.writeUInt8(value, offset, noAssert);
 10850   } else {
 10851     buffer.writeUInt8(0xff + value + 1, offset, noAssert);
 10853 };
 10855 function writeInt16(buffer, value, offset, isBigEndian, noAssert) {
 10856   if (!noAssert) {
 10857     assert.ok(value !== undefined && value !== null,
 10858         'missing value');
 10860     assert.ok(typeof (isBigEndian) === 'boolean',
 10861         'missing or invalid endian');
 10863     assert.ok(offset !== undefined && offset !== null,
 10864         'missing offset');
 10866     assert.ok(offset + 1 < buffer.length,
 10867         'Trying to write beyond buffer length');
 10869     verifsint(value, 0x7fff, -0x8000);
 10872   if (value >= 0) {
 10873     writeUInt16(buffer, value, offset, isBigEndian, noAssert);
 10874   } else {
 10875     writeUInt16(buffer, 0xffff + value + 1, offset, isBigEndian, noAssert);
 10879 Buffer.prototype.writeInt16LE = function(value, offset, noAssert) {
 10880   writeInt16(this, value, offset, false, noAssert);
 10881 };
 10883 Buffer.prototype.writeInt16BE = function(value, offset, noAssert) {
 10884   writeInt16(this, value, offset, true, noAssert);
 10885 };
 10887 function writeInt32(buffer, value, offset, isBigEndian, noAssert) {
 10888   if (!noAssert) {
 10889     assert.ok(value !== undefined && value !== null,
 10890         'missing value');
 10892     assert.ok(typeof (isBigEndian) === 'boolean',
 10893         'missing or invalid endian');
 10895     assert.ok(offset !== undefined && offset !== null,
 10896         'missing offset');
 10898     assert.ok(offset + 3 < buffer.length,
 10899         'Trying to write beyond buffer length');
 10901     verifsint(value, 0x7fffffff, -0x80000000);
 10904   if (value >= 0) {
 10905     writeUInt32(buffer, value, offset, isBigEndian, noAssert);
 10906   } else {
 10907     writeUInt32(buffer, 0xffffffff + value + 1, offset, isBigEndian, noAssert);
 10911 Buffer.prototype.writeInt32LE = function(value, offset, noAssert) {
 10912   writeInt32(this, value, offset, false, noAssert);
 10913 };
 10915 Buffer.prototype.writeInt32BE = function(value, offset, noAssert) {
 10916   writeInt32(this, value, offset, true, noAssert);
 10917 };
 10919 function writeFloat(buffer, value, offset, isBigEndian, noAssert) {
 10920   if (!noAssert) {
 10921     assert.ok(value !== undefined && value !== null,
 10922         'missing value');
 10924     assert.ok(typeof (isBigEndian) === 'boolean',
 10925         'missing or invalid endian');
 10927     assert.ok(offset !== undefined && offset !== null,
 10928         'missing offset');
 10930     assert.ok(offset + 3 < buffer.length,
 10931         'Trying to write beyond buffer length');
 10933     verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38);
 10936   require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian,
 10937       23, 4);
 10940 Buffer.prototype.writeFloatLE = function(value, offset, noAssert) {
 10941   writeFloat(this, value, offset, false, noAssert);
 10942 };
 10944 Buffer.prototype.writeFloatBE = function(value, offset, noAssert) {
 10945   writeFloat(this, value, offset, true, noAssert);
 10946 };
 10948 function writeDouble(buffer, value, offset, isBigEndian, noAssert) {
 10949   if (!noAssert) {
 10950     assert.ok(value !== undefined && value !== null,
 10951         'missing value');
 10953     assert.ok(typeof (isBigEndian) === 'boolean',
 10954         'missing or invalid endian');
 10956     assert.ok(offset !== undefined && offset !== null,
 10957         'missing offset');
 10959     assert.ok(offset + 7 < buffer.length,
 10960         'Trying to write beyond buffer length');
 10962     verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308);
 10965   require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian,
 10966       52, 8);
 10969 Buffer.prototype.writeDoubleLE = function(value, offset, noAssert) {
 10970   writeDouble(this, value, offset, false, noAssert);
 10971 };
 10973 Buffer.prototype.writeDoubleBE = function(value, offset, noAssert) {
 10974   writeDouble(this, value, offset, true, noAssert);
 10975 };
 10977 SlowBuffer.prototype.readUInt8 = Buffer.prototype.readUInt8;
 10978 SlowBuffer.prototype.readUInt16LE = Buffer.prototype.readUInt16LE;
 10979 SlowBuffer.prototype.readUInt16BE = Buffer.prototype.readUInt16BE;
 10980 SlowBuffer.prototype.readUInt32LE = Buffer.prototype.readUInt32LE;
 10981 SlowBuffer.prototype.readUInt32BE = Buffer.prototype.readUInt32BE;
 10982 SlowBuffer.prototype.readInt8 = Buffer.prototype.readInt8;
 10983 SlowBuffer.prototype.readInt16LE = Buffer.prototype.readInt16LE;
 10984 SlowBuffer.prototype.readInt16BE = Buffer.prototype.readInt16BE;
 10985 SlowBuffer.prototype.readInt32LE = Buffer.prototype.readInt32LE;
 10986 SlowBuffer.prototype.readInt32BE = Buffer.prototype.readInt32BE;
 10987 SlowBuffer.prototype.readFloatLE = Buffer.prototype.readFloatLE;
 10988 SlowBuffer.prototype.readFloatBE = Buffer.prototype.readFloatBE;
 10989 SlowBuffer.prototype.readDoubleLE = Buffer.prototype.readDoubleLE;
 10990 SlowBuffer.prototype.readDoubleBE = Buffer.prototype.readDoubleBE;
 10991 SlowBuffer.prototype.writeUInt8 = Buffer.prototype.writeUInt8;
 10992 SlowBuffer.prototype.writeUInt16LE = Buffer.prototype.writeUInt16LE;
 10993 SlowBuffer.prototype.writeUInt16BE = Buffer.prototype.writeUInt16BE;
 10994 SlowBuffer.prototype.writeUInt32LE = Buffer.prototype.writeUInt32LE;
 10995 SlowBuffer.prototype.writeUInt32BE = Buffer.prototype.writeUInt32BE;
 10996 SlowBuffer.prototype.writeInt8 = Buffer.prototype.writeInt8;
 10997 SlowBuffer.prototype.writeInt16LE = Buffer.prototype.writeInt16LE;
 10998 SlowBuffer.prototype.writeInt16BE = Buffer.prototype.writeInt16BE;
 10999 SlowBuffer.prototype.writeInt32LE = Buffer.prototype.writeInt32LE;
 11000 SlowBuffer.prototype.writeInt32BE = Buffer.prototype.writeInt32BE;
 11001 SlowBuffer.prototype.writeFloatLE = Buffer.prototype.writeFloatLE;
 11002 SlowBuffer.prototype.writeFloatBE = Buffer.prototype.writeFloatBE;
 11003 SlowBuffer.prototype.writeDoubleLE = Buffer.prototype.writeDoubleLE;
 11004 SlowBuffer.prototype.writeDoubleBE = Buffer.prototype.writeDoubleBE;
 11006 })()
 11007 },{"assert":9,"./buffer_ieee754":14,"base64-js":15}],15:[function(require,module,exports){
 11008 (function (exports) {
 11009 	'use strict';
 11011 	var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
 11013 	function b64ToByteArray(b64) {
 11014 		var i, j, l, tmp, placeHolders, arr;
 11016 		if (b64.length % 4 > 0) {
 11017 			throw 'Invalid string. Length must be a multiple of 4';
 11020 		// the number of equal signs (place holders)
 11021 		// if there are two placeholders, than the two characters before it
 11022 		// represent one byte
 11023 		// if there is only one, then the three characters before it represent 2 bytes
 11024 		// this is just a cheap hack to not do indexOf twice
 11025 		placeHolders = b64.indexOf('=');
 11026 		placeHolders = placeHolders > 0 ? b64.length - placeHolders : 0;
 11028 		// base64 is 4/3 + up to two characters of the original data
 11029 		arr = [];//new Uint8Array(b64.length * 3 / 4 - placeHolders);
 11031 		// if there are placeholders, only get up to the last complete 4 chars
 11032 		l = placeHolders > 0 ? b64.length - 4 : b64.length;
 11034 		for (i = 0, j = 0; i < l; i += 4, j += 3) {
 11035 			tmp = (lookup.indexOf(b64[i]) << 18) | (lookup.indexOf(b64[i + 1]) << 12) | (lookup.indexOf(b64[i + 2]) << 6) | lookup.indexOf(b64[i + 3]);
 11036 			arr.push((tmp & 0xFF0000) >> 16);
 11037 			arr.push((tmp & 0xFF00) >> 8);
 11038 			arr.push(tmp & 0xFF);
 11041 		if (placeHolders === 2) {
 11042 			tmp = (lookup.indexOf(b64[i]) << 2) | (lookup.indexOf(b64[i + 1]) >> 4);
 11043 			arr.push(tmp & 0xFF);
 11044 		} else if (placeHolders === 1) {
 11045 			tmp = (lookup.indexOf(b64[i]) << 10) | (lookup.indexOf(b64[i + 1]) << 4) | (lookup.indexOf(b64[i + 2]) >> 2);
 11046 			arr.push((tmp >> 8) & 0xFF);
 11047 			arr.push(tmp & 0xFF);
 11050 		return arr;
 11053 	function uint8ToBase64(uint8) {
 11054 		var i,
 11055 			extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
 11056 			output = "",
 11057 			temp, length;
 11059 		function tripletToBase64 (num) {
 11060 			return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F];
 11061 		};
 11063 		// go through the array every three bytes, we'll deal with trailing stuff later
 11064 		for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
 11065 			temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]);
 11066 			output += tripletToBase64(temp);
 11069 		// pad the end with zeros, but make sure to not forget the extra bytes
 11070 		switch (extraBytes) {
 11071 			case 1:
 11072 				temp = uint8[uint8.length - 1];
 11073 				output += lookup[temp >> 2];
 11074 				output += lookup[(temp << 4) & 0x3F];
 11075 				output += '==';
 11076 				break;
 11077 			case 2:
 11078 				temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]);
 11079 				output += lookup[temp >> 10];
 11080 				output += lookup[(temp >> 4) & 0x3F];
 11081 				output += lookup[(temp << 2) & 0x3F];
 11082 				output += '=';
 11083 				break;
 11086 		return output;
 11089 	module.exports.toByteArray = b64ToByteArray;
 11090 	module.exports.fromByteArray = uint8ToBase64;
 11091 }());
 11093 },{}]},{},["E/GbHF"])
 11095 JSHINT = require('jshint').JSHINT;
 11096 }());

mercurial