]> git.proxmox.com Git - pve-eslint.git/blob - eslint/tests/performance/jshint.js
first commit
[pve-eslint.git] / eslint / tests / performance / jshint.js
1 //2.1.8
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
7
8 var process = module.exports = {};
9
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 ;
16
17 if (canSetImmediate) {
18 return function (f) { return window.setImmediate(f) };
19 }
20
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);
32
33 return function nextTick(fn) {
34 queue.push(fn);
35 window.postMessage('process-tick', '*');
36 };
37 }
38
39 return function nextTick(fn) {
40 setTimeout(fn, 0);
41 };
42 })();
43
44 process.title = 'browser';
45 process.browser = true;
46 process.env = {};
47 process.argv = [];
48
49 process.binding = function (name) {
50 throw new Error('process.binding is not supported');
51 }
52
53 // TODO(shtylman)
54 process.cwd = function () { return '/' };
55 process.chdir = function (dir) {
56 throw new Error('process.chdir is not supported');
57 };
58
59 },{}],2:[function(require,module,exports){
60 (function(process){if (!process.EventEmitter) process.EventEmitter = function () {};
61
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 }
76
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 };
88
89
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 }
104
105 if (!this._events) return false;
106 var handler = this._events[type];
107 if (!handler) return false;
108
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;
127
128 } else if (isArray(handler)) {
129 var args = Array.prototype.slice.call(arguments, 1);
130
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;
136
137 } else {
138 return false;
139 }
140 };
141
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 }
148
149 if (!this._events) this._events = {};
150
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);
154
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])) {
159
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 }
168
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 }
178
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 }
185
186 return this;
187 };
188
189 EventEmitter.prototype.on = EventEmitter.prototype.addListener;
190
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 });
197
198 return this;
199 };
200
201 EventEmitter.prototype.removeListener = function(type, listener) {
202 if ('function' !== typeof listener) {
203 throw new Error('removeListener only takes instances of Function');
204 }
205
206 // does not use listeners(), so no side effect of creating _events[type]
207 if (!this._events || !this._events[type]) return this;
208
209 var list = this._events[type];
210
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 }
220
221 return this;
222 };
223
224 EventEmitter.prototype.removeAllListeners = function(type) {
225 if (arguments.length === 0) {
226 this._events = {};
227 return this;
228 }
229
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 };
234
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 };
243
244 })(require("__browserify_process"))
245 },{"__browserify_process":1}],3:[function(require,module,exports){
246 (function(){// jshint -W001
247
248 "use strict";
249
250 // Identifiers provided by the ECMAScript standard.
251
252 exports.reservedVars = {
253 arguments : false,
254 NaN : false
255 };
256
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 };
289
290 // Global variables commonly provided by a web browser environment.
291
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 CustomEvent : false,
307 DataView : false,
308 DOMParser : false,
309 defaultStatus : false,
310 document : false,
311 Element : false,
312 ElementTimeControl : false,
313 event : false,
314 FileReader : false,
315 Float32Array : false,
316 Float64Array : false,
317 FormData : false,
318 focus : false,
319 frames : false,
320 getComputedStyle : false,
321 HTMLElement : false,
322 HTMLAnchorElement : false,
323 HTMLBaseElement : false,
324 HTMLBlockquoteElement: false,
325 HTMLBodyElement : false,
326 HTMLBRElement : false,
327 HTMLButtonElement : false,
328 HTMLCanvasElement : false,
329 HTMLDirectoryElement : false,
330 HTMLDivElement : false,
331 HTMLDListElement : false,
332 HTMLFieldSetElement : false,
333 HTMLFontElement : false,
334 HTMLFormElement : false,
335 HTMLFrameElement : false,
336 HTMLFrameSetElement : false,
337 HTMLHeadElement : false,
338 HTMLHeadingElement : false,
339 HTMLHRElement : false,
340 HTMLHtmlElement : false,
341 HTMLIFrameElement : false,
342 HTMLImageElement : false,
343 HTMLInputElement : false,
344 HTMLIsIndexElement : false,
345 HTMLLabelElement : false,
346 HTMLLayerElement : false,
347 HTMLLegendElement : false,
348 HTMLLIElement : false,
349 HTMLLinkElement : false,
350 HTMLMapElement : false,
351 HTMLMenuElement : false,
352 HTMLMetaElement : false,
353 HTMLModElement : false,
354 HTMLObjectElement : false,
355 HTMLOListElement : false,
356 HTMLOptGroupElement : false,
357 HTMLOptionElement : false,
358 HTMLParagraphElement : false,
359 HTMLParamElement : false,
360 HTMLPreElement : false,
361 HTMLQuoteElement : false,
362 HTMLScriptElement : false,
363 HTMLSelectElement : false,
364 HTMLStyleElement : false,
365 HTMLTableCaptionElement: false,
366 HTMLTableCellElement : false,
367 HTMLTableColElement : false,
368 HTMLTableElement : false,
369 HTMLTableRowElement : false,
370 HTMLTableSectionElement: false,
371 HTMLTextAreaElement : false,
372 HTMLTitleElement : false,
373 HTMLUListElement : false,
374 HTMLVideoElement : false,
375 history : false,
376 Int16Array : false,
377 Int32Array : false,
378 Int8Array : false,
379 Image : false,
380 length : false,
381 localStorage : false,
382 location : false,
383 MessageChannel : false,
384 MessageEvent : false,
385 MessagePort : false,
386 MouseEvent : false,
387 moveBy : false,
388 moveTo : false,
389 MutationObserver : false,
390 name : false,
391 Node : false,
392 NodeFilter : false,
393 navigator : false,
394 onbeforeunload : true,
395 onblur : true,
396 onerror : true,
397 onfocus : true,
398 onload : true,
399 onresize : true,
400 onunload : true,
401 open : false,
402 openDatabase : false,
403 opener : false,
404 Option : false,
405 parent : false,
406 print : false,
407 removeEventListener : false,
408 resizeBy : false,
409 resizeTo : false,
410 screen : false,
411 scroll : false,
412 scrollBy : false,
413 scrollTo : false,
414 sessionStorage : false,
415 setInterval : false,
416 setTimeout : false,
417 SharedWorker : false,
418 status : false,
419 SVGAElement : false,
420 SVGAltGlyphDefElement: false,
421 SVGAltGlyphElement : false,
422 SVGAltGlyphItemElement: false,
423 SVGAngle : false,
424 SVGAnimateColorElement: false,
425 SVGAnimateElement : false,
426 SVGAnimateMotionElement: false,
427 SVGAnimateTransformElement: false,
428 SVGAnimatedAngle : false,
429 SVGAnimatedBoolean : false,
430 SVGAnimatedEnumeration: false,
431 SVGAnimatedInteger : false,
432 SVGAnimatedLength : false,
433 SVGAnimatedLengthList: false,
434 SVGAnimatedNumber : false,
435 SVGAnimatedNumberList: false,
436 SVGAnimatedPathData : false,
437 SVGAnimatedPoints : false,
438 SVGAnimatedPreserveAspectRatio: false,
439 SVGAnimatedRect : false,
440 SVGAnimatedString : false,
441 SVGAnimatedTransformList: false,
442 SVGAnimationElement : false,
443 SVGCSSRule : false,
444 SVGCircleElement : false,
445 SVGClipPathElement : false,
446 SVGColor : false,
447 SVGColorProfileElement: false,
448 SVGColorProfileRule : false,
449 SVGComponentTransferFunctionElement: false,
450 SVGCursorElement : false,
451 SVGDefsElement : false,
452 SVGDescElement : false,
453 SVGDocument : false,
454 SVGElement : false,
455 SVGElementInstance : false,
456 SVGElementInstanceList: false,
457 SVGEllipseElement : false,
458 SVGExternalResourcesRequired: false,
459 SVGFEBlendElement : false,
460 SVGFEColorMatrixElement: false,
461 SVGFEComponentTransferElement: false,
462 SVGFECompositeElement: false,
463 SVGFEConvolveMatrixElement: false,
464 SVGFEDiffuseLightingElement: false,
465 SVGFEDisplacementMapElement: false,
466 SVGFEDistantLightElement: false,
467 SVGFEFloodElement : false,
468 SVGFEFuncAElement : false,
469 SVGFEFuncBElement : false,
470 SVGFEFuncGElement : false,
471 SVGFEFuncRElement : false,
472 SVGFEGaussianBlurElement: false,
473 SVGFEImageElement : false,
474 SVGFEMergeElement : false,
475 SVGFEMergeNodeElement: false,
476 SVGFEMorphologyElement: false,
477 SVGFEOffsetElement : false,
478 SVGFEPointLightElement: false,
479 SVGFESpecularLightingElement: false,
480 SVGFESpotLightElement: false,
481 SVGFETileElement : false,
482 SVGFETurbulenceElement: false,
483 SVGFilterElement : false,
484 SVGFilterPrimitiveStandardAttributes: false,
485 SVGFitToViewBox : false,
486 SVGFontElement : false,
487 SVGFontFaceElement : false,
488 SVGFontFaceFormatElement: false,
489 SVGFontFaceNameElement: false,
490 SVGFontFaceSrcElement: false,
491 SVGFontFaceUriElement: false,
492 SVGForeignObjectElement: false,
493 SVGGElement : false,
494 SVGGlyphElement : false,
495 SVGGlyphRefElement : false,
496 SVGGradientElement : false,
497 SVGHKernElement : false,
498 SVGICCColor : false,
499 SVGImageElement : false,
500 SVGLangSpace : false,
501 SVGLength : false,
502 SVGLengthList : false,
503 SVGLineElement : false,
504 SVGLinearGradientElement: false,
505 SVGLocatable : false,
506 SVGMPathElement : false,
507 SVGMarkerElement : false,
508 SVGMaskElement : false,
509 SVGMatrix : false,
510 SVGMetadataElement : false,
511 SVGMissingGlyphElement: false,
512 SVGNumber : false,
513 SVGNumberList : false,
514 SVGPaint : false,
515 SVGPathElement : false,
516 SVGPathSeg : false,
517 SVGPathSegArcAbs : false,
518 SVGPathSegArcRel : false,
519 SVGPathSegClosePath : false,
520 SVGPathSegCurvetoCubicAbs: false,
521 SVGPathSegCurvetoCubicRel: false,
522 SVGPathSegCurvetoCubicSmoothAbs: false,
523 SVGPathSegCurvetoCubicSmoothRel: false,
524 SVGPathSegCurvetoQuadraticAbs: false,
525 SVGPathSegCurvetoQuadraticRel: false,
526 SVGPathSegCurvetoQuadraticSmoothAbs: false,
527 SVGPathSegCurvetoQuadraticSmoothRel: false,
528 SVGPathSegLinetoAbs : false,
529 SVGPathSegLinetoHorizontalAbs: false,
530 SVGPathSegLinetoHorizontalRel: false,
531 SVGPathSegLinetoRel : false,
532 SVGPathSegLinetoVerticalAbs: false,
533 SVGPathSegLinetoVerticalRel: false,
534 SVGPathSegList : false,
535 SVGPathSegMovetoAbs : false,
536 SVGPathSegMovetoRel : false,
537 SVGPatternElement : false,
538 SVGPoint : false,
539 SVGPointList : false,
540 SVGPolygonElement : false,
541 SVGPolylineElement : false,
542 SVGPreserveAspectRatio: false,
543 SVGRadialGradientElement: false,
544 SVGRect : false,
545 SVGRectElement : false,
546 SVGRenderingIntent : false,
547 SVGSVGElement : false,
548 SVGScriptElement : false,
549 SVGSetElement : false,
550 SVGStopElement : false,
551 SVGStringList : false,
552 SVGStylable : false,
553 SVGStyleElement : false,
554 SVGSwitchElement : false,
555 SVGSymbolElement : false,
556 SVGTRefElement : false,
557 SVGTSpanElement : false,
558 SVGTests : false,
559 SVGTextContentElement: false,
560 SVGTextElement : false,
561 SVGTextPathElement : false,
562 SVGTextPositioningElement: false,
563 SVGTitleElement : false,
564 SVGTransform : false,
565 SVGTransformList : false,
566 SVGTransformable : false,
567 SVGURIReference : false,
568 SVGUnitTypes : false,
569 SVGUseElement : false,
570 SVGVKernElement : false,
571 SVGViewElement : false,
572 SVGViewSpec : false,
573 SVGZoomAndPan : false,
574 TimeEvent : false,
575 top : false,
576 Uint16Array : false,
577 Uint32Array : false,
578 Uint8Array : false,
579 Uint8ClampedArray : false,
580 WebSocket : false,
581 window : false,
582 Worker : false,
583 XMLHttpRequest : false,
584 XMLSerializer : false,
585 XPathEvaluator : false,
586 XPathException : false,
587 XPathExpression : false,
588 XPathNamespace : false,
589 XPathNSResolver : false,
590 XPathResult : false
591 };
592
593 exports.devel = {
594 alert : false,
595 confirm: false,
596 console: false,
597 Debug : false,
598 opera : false,
599 prompt : false
600 };
601
602 exports.worker = {
603 importScripts: true,
604 postMessage : true,
605 self : true
606 };
607
608 // Widely adopted global names that are not part of ECMAScript standard
609 exports.nonstandard = {
610 escape : false,
611 unescape: false
612 };
613
614 // Globals provided by popular JavaScript environments.
615
616 exports.couch = {
617 "require" : false,
618 respond : false,
619 getRow : false,
620 emit : false,
621 send : false,
622 start : false,
623 sum : false,
624 log : false,
625 exports : false,
626 module : false,
627 provides : false
628 };
629
630 exports.node = {
631 __filename : false,
632 __dirname : false,
633 Buffer : false,
634 DataView : false,
635 console : false,
636 exports : true, // In Node it is ok to exports = module.exports = foo();
637 GLOBAL : false,
638 global : false,
639 module : false,
640 process : false,
641 require : false,
642 setTimeout : false,
643 clearTimeout : false,
644 setInterval : false,
645 clearInterval : false,
646 setImmediate : false, // v0.9.1+
647 clearImmediate: false // v0.9.1+
648 };
649
650 exports.phantom = {
651 phantom : true,
652 require : true,
653 WebPage : true
654 };
655
656 exports.rhino = {
657 defineClass : false,
658 deserialize : false,
659 gc : false,
660 help : false,
661 importPackage: false,
662 "java" : false,
663 load : false,
664 loadClass : false,
665 print : false,
666 quit : false,
667 readFile : false,
668 readUrl : false,
669 runCommand : false,
670 seal : false,
671 serialize : false,
672 spawn : false,
673 sync : false,
674 toint32 : false,
675 version : false
676 };
677
678 exports.shelljs = {
679 target : false,
680 echo : false,
681 exit : false,
682 cd : false,
683 pwd : false,
684 ls : false,
685 find : false,
686 cp : false,
687 rm : false,
688 mv : false,
689 mkdir : false,
690 test : false,
691 cat : false,
692 sed : false,
693 grep : false,
694 which : false,
695 dirs : false,
696 pushd : false,
697 popd : false,
698 env : false,
699 exec : false,
700 chmod : false,
701 config : false,
702 error : false,
703 tempdir : false
704 };
705
706 exports.wsh = {
707 ActiveXObject : true,
708 Enumerator : true,
709 GetObject : true,
710 ScriptEngine : true,
711 ScriptEngineBuildVersion : true,
712 ScriptEngineMajorVersion : true,
713 ScriptEngineMinorVersion : true,
714 VBArray : true,
715 WSH : true,
716 WScript : true,
717 XDomainRequest : true
718 };
719
720 // Globals provided by popular JavaScript libraries.
721
722 exports.dojo = {
723 dojo : false,
724 dijit : false,
725 dojox : false,
726 define : false,
727 "require": false
728 };
729
730 exports.jquery = {
731 "$" : false,
732 jQuery : false
733 };
734
735 exports.mootools = {
736 "$" : false,
737 "$$" : false,
738 Asset : false,
739 Browser : false,
740 Chain : false,
741 Class : false,
742 Color : false,
743 Cookie : false,
744 Core : false,
745 Document : false,
746 DomReady : false,
747 DOMEvent : false,
748 DOMReady : false,
749 Drag : false,
750 Element : false,
751 Elements : false,
752 Event : false,
753 Events : false,
754 Fx : false,
755 Group : false,
756 Hash : false,
757 HtmlTable : false,
758 Iframe : false,
759 IframeShim : false,
760 InputValidator: false,
761 instanceOf : false,
762 Keyboard : false,
763 Locale : false,
764 Mask : false,
765 MooTools : false,
766 Native : false,
767 Options : false,
768 OverText : false,
769 Request : false,
770 Scroller : false,
771 Slick : false,
772 Slider : false,
773 Sortables : false,
774 Spinner : false,
775 Swiff : false,
776 Tips : false,
777 Type : false,
778 typeOf : false,
779 URI : false,
780 Window : false
781 };
782
783 exports.prototypejs = {
784 "$" : false,
785 "$$" : false,
786 "$A" : false,
787 "$F" : false,
788 "$H" : false,
789 "$R" : false,
790 "$break" : false,
791 "$continue" : false,
792 "$w" : false,
793 Abstract : false,
794 Ajax : false,
795 Class : false,
796 Enumerable : false,
797 Element : false,
798 Event : false,
799 Field : false,
800 Form : false,
801 Hash : false,
802 Insertion : false,
803 ObjectRange : false,
804 PeriodicalExecuter: false,
805 Position : false,
806 Prototype : false,
807 Selector : false,
808 Template : false,
809 Toggle : false,
810 Try : false,
811 Autocompleter : false,
812 Builder : false,
813 Control : false,
814 Draggable : false,
815 Draggables : false,
816 Droppables : false,
817 Effect : false,
818 Sortable : false,
819 SortableObserver : false,
820 Sound : false,
821 Scriptaculous : false
822 };
823
824 exports.yui = {
825 YUI : false,
826 Y : false,
827 YUI_config: false
828 };
829
830
831 })()
832 },{}],4:[function(require,module,exports){
833 /*
834 * Regular expressions. Some of these are stupidly long.
835 */
836
837 /*jshint maxlen:1000 */
838
839 "use string";
840
841 // Unsafe comment or string (ax)
842 exports.unsafeString =
843 /@cc|<\/?|script|\]\s*\]|<\s*!|&lt/i;
844
845 // Unsafe characters that are silently deleted by one or more browsers (cx)
846 exports.unsafeChars =
847 /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
848
849 // Characters in strings that need escaping (nx and nxg)
850 exports.needEsc =
851 /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
852
853 exports.needEscGlobal =
854 /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
855
856 // Star slash (lx)
857 exports.starSlash = /\*\//;
858
859 // Identifier (ix)
860 exports.identifier = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/;
861
862 // JavaScript URL (jx)
863 exports.javascriptURL = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i;
864
865 // Catches /* falls through */ comments (ft)
866 exports.fallsThrough = /^\s*\/\*\s*falls?\sthrough\s*\*\/\s*$/;
867
868 },{}],5:[function(require,module,exports){
869 (function(){"use strict";
870
871 exports.register = function (linter) {
872 // Check for properties named __proto__. This special property was
873 // deprecated and then re-introduced for ES6.
874
875 linter.on("Identifier", function style_scanProto(data) {
876 if (linter.getOption("proto")) {
877 return;
878 }
879
880 if (data.name === "__proto__") {
881 linter.warn("W103", {
882 line: data.line,
883 char: data.char,
884 data: [ data.name ]
885 });
886 }
887 });
888
889 // Check for properties named __iterator__. This is a special property
890 // available only in browsers with JavaScript 1.7 implementation.
891
892 linter.on("Identifier", function style_scanIterator(data) {
893 if (linter.getOption("iterator")) {
894 return;
895 }
896
897 if (data.name === "__iterator__") {
898 linter.warn("W104", {
899 line: data.line,
900 char: data.char,
901 data: [ data.name ]
902 });
903 }
904 });
905
906 // Check for dangling underscores.
907
908 linter.on("Identifier", function style_scanDangling(data) {
909 if (!linter.getOption("nomen")) {
910 return;
911 }
912
913 // Underscore.js
914 if (data.name === "_") {
915 return;
916 }
917
918 // In Node, __dirname and __filename should be ignored.
919 if (linter.getOption("node")) {
920 if (/^(__dirname|__filename)$/.test(data.name) && !data.isProperty) {
921 return;
922 }
923 }
924
925 if (/^(_+.*|.*_+)$/.test(data.name)) {
926 linter.warn("W105", {
927 line: data.line,
928 char: data.from,
929 data: [ "dangling '_'", data.name ]
930 });
931 }
932 });
933
934 // Check that all identifiers are using camelCase notation.
935 // Exceptions: names like MY_VAR and _myVar.
936
937 linter.on("Identifier", function style_scanCamelCase(data) {
938 if (!linter.getOption("camelcase")) {
939 return;
940 }
941
942 if (data.name.replace(/^_+/, "").indexOf("_") > -1 && !data.name.match(/^[A-Z0-9_]*$/)) {
943 linter.warn("W106", {
944 line: data.line,
945 char: data.from,
946 data: [ data.name ]
947 });
948 }
949 });
950
951 // Enforce consistency in style of quoting.
952
953 linter.on("String", function style_scanQuotes(data) {
954 var quotmark = linter.getOption("quotmark");
955 var code;
956
957 if (!quotmark) {
958 return;
959 }
960
961 // If quotmark is set to 'single' warn about all double-quotes.
962
963 if (quotmark === "single" && data.quote !== "'") {
964 code = "W109";
965 }
966
967 // If quotmark is set to 'double' warn about all single-quotes.
968
969 if (quotmark === "double" && data.quote !== "\"") {
970 code = "W108";
971 }
972
973 // If quotmark is set to true, remember the first quotation style
974 // and then warn about all others.
975
976 if (quotmark === true) {
977 if (!linter.getCache("quotmark")) {
978 linter.setCache("quotmark", data.quote);
979 }
980
981 if (linter.getCache("quotmark") !== data.quote) {
982 code = "W110";
983 }
984 }
985
986 if (code) {
987 linter.warn(code, {
988 line: data.line,
989 char: data.char,
990 });
991 }
992 });
993
994 linter.on("Number", function style_scanNumbers(data) {
995 if (data.value.charAt(0) === ".") {
996 // Warn about a leading decimal point.
997 linter.warn("W008", {
998 line: data.line,
999 char: data.char,
1000 data: [ data.value ]
1001 });
1002 }
1003
1004 if (data.value.substr(data.value.length - 1) === ".") {
1005 // Warn about a trailing decimal point.
1006 linter.warn("W047", {
1007 line: data.line,
1008 char: data.char,
1009 data: [ data.value ]
1010 });
1011 }
1012
1013 if (/^00+/.test(data.value)) {
1014 // Multiple leading zeroes.
1015 linter.warn("W046", {
1016 line: data.line,
1017 char: data.char,
1018 data: [ data.value ]
1019 });
1020 }
1021 });
1022
1023 // Warn about script URLs.
1024
1025 linter.on("String", function style_scanJavaScriptURLs(data) {
1026 var re = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i;
1027
1028 if (linter.getOption("scripturl")) {
1029 return;
1030 }
1031
1032 if (re.test(data.value)) {
1033 linter.warn("W107", {
1034 line: data.line,
1035 char: data.char
1036 });
1037 }
1038 });
1039 };
1040 })()
1041 },{}],6:[function(require,module,exports){
1042 "use strict";
1043
1044 var state = {
1045 syntax: {},
1046
1047 reset: function () {
1048 this.tokens = {
1049 prev: null,
1050 next: null,
1051 curr: null
1052 };
1053
1054 this.option = {};
1055 this.ignored = {};
1056 this.directive = {};
1057 this.jsonMode = false;
1058 this.jsonWarnings = [];
1059 this.lines = [];
1060 this.tab = "";
1061 this.cache = {}; // Node.JS doesn't have Map. Sniff.
1062 }
1063 };
1064
1065 exports.state = state;
1066
1067 },{}],"jshint":[function(require,module,exports){
1068 module.exports=require('E/GbHF');
1069 },{}],"E/GbHF":[function(require,module,exports){
1070 (function(){/*!
1071 * JSHint, by JSHint Community.
1072 *
1073 * This file (and this file only) is licensed under the same slightly modified
1074 * MIT license that JSLint is. It stops evil-doers everywhere:
1075 *
1076 * Copyright (c) 2002 Douglas Crockford (www.JSLint.com)
1077 *
1078 * Permission is hereby granted, free of charge, to any person obtaining
1079 * a copy of this software and associated documentation files (the "Software"),
1080 * to deal in the Software without restriction, including without limitation
1081 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1082 * and/or sell copies of the Software, and to permit persons to whom
1083 * the Software is furnished to do so, subject to the following conditions:
1084 *
1085 * The above copyright notice and this permission notice shall be included
1086 * in all copies or substantial portions of the Software.
1087 *
1088 * The Software shall be used for Good, not Evil.
1089 *
1090 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1091 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1092 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1093 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1094 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1095 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
1096 * DEALINGS IN THE SOFTWARE.
1097 *
1098 */
1099
1100 /*jshint quotmark:double */
1101 /*global console:true */
1102 /*exported console */
1103
1104 var _ = require("underscore");
1105 var events = require("events");
1106 var vars = require("../shared/vars.js");
1107 var messages = require("../shared/messages.js");
1108 var Lexer = require("./lex.js").Lexer;
1109 var reg = require("./reg.js");
1110 var state = require("./state.js").state;
1111 var style = require("./style.js");
1112
1113 // We need this module here because environments such as IE and Rhino
1114 // don't necessarilly expose the 'console' API and browserify uses
1115 // it to log things. It's a sad state of affair, really.
1116 var console = require("console-browserify");
1117
1118 // We build the application inside a function so that we produce only a singleton
1119 // variable. That function will be invoked immediately, and its return value is
1120 // the JSHINT function itself.
1121
1122 var JSHINT = (function () {
1123 "use strict";
1124
1125 var anonname, // The guessed name for anonymous functions.
1126 api, // Extension API
1127
1128 // These are operators that should not be used with the ! operator.
1129 bang = {
1130 "<" : true,
1131 "<=" : true,
1132 "==" : true,
1133 "===": true,
1134 "!==": true,
1135 "!=" : true,
1136 ">" : true,
1137 ">=" : true,
1138 "+" : true,
1139 "-" : true,
1140 "*" : true,
1141 "/" : true,
1142 "%" : true
1143 },
1144
1145 // These are the JSHint boolean options.
1146 boolOptions = {
1147 asi : true, // if automatic semicolon insertion should be tolerated
1148 bitwise : true, // if bitwise operators should not be allowed
1149 boss : true, // if advanced usage of assignments should be allowed
1150 browser : true, // if the standard browser globals should be predefined
1151 camelcase : true, // if identifiers should be required in camel case
1152 couch : true, // if CouchDB globals should be predefined
1153 curly : true, // if curly braces around all blocks should be required
1154 debug : true, // if debugger statements should be allowed
1155 devel : true, // if logging globals should be predefined (console, alert, etc.)
1156 dojo : true, // if Dojo Toolkit globals should be predefined
1157 eqeqeq : true, // if === should be required
1158 eqnull : true, // if == null comparisons should be tolerated
1159 es3 : true, // if ES3 syntax should be allowed
1160 es5 : true, // if ES5 syntax should be allowed (is now set per default)
1161 esnext : true, // if es.next specific syntax should be allowed
1162 moz : true, // if mozilla specific syntax should be allowed
1163 evil : true, // if eval should be allowed
1164 expr : true, // if ExpressionStatement should be allowed as Programs
1165 forin : true, // if for in statements must filter
1166 funcscope : true, // if only function scope should be used for scope tests
1167 gcl : true, // if JSHint should be compatible with Google Closure Linter
1168 globalstrict: true, // if global "use strict"; should be allowed (also enables 'strict')
1169 immed : true, // if immediate invocations must be wrapped in parens
1170 iterator : true, // if the `__iterator__` property should be allowed
1171 jquery : true, // if jQuery globals should be predefined
1172 lastsemic : true, // if semicolons may be ommitted for the trailing
1173 // statements inside of a one-line blocks.
1174 laxbreak : true, // if line breaks should not be checked
1175 laxcomma : true, // if line breaks should not be checked around commas
1176 loopfunc : true, // if functions should be allowed to be defined within
1177 // loops
1178 mootools : true, // if MooTools globals should be predefined
1179 multistr : true, // allow multiline strings
1180 newcap : true, // if constructor names must be capitalized
1181 noarg : true, // if arguments.caller and arguments.callee should be
1182 // disallowed
1183 node : true, // if the Node.js environment globals should be
1184 // predefined
1185 noempty : true, // if empty blocks should be disallowed
1186 nonew : true, // if using `new` for side-effects should be disallowed
1187 nonstandard : true, // if non-standard (but widely adopted) globals should
1188 // be predefined
1189 nomen : true, // if names should be checked
1190 onevar : true, // if only one var statement per function should be
1191 // allowed
1192 passfail : true, // if the scan should stop on first error
1193 phantom : true, // if PhantomJS symbols should be allowed
1194 plusplus : true, // if increment/decrement should not be allowed
1195 proto : true, // if the `__proto__` property should be allowed
1196 prototypejs : true, // if Prototype and Scriptaculous globals should be
1197 // predefined
1198 rhino : true, // if the Rhino environment globals should be predefined
1199 shelljs : true, // if ShellJS globals should be predefined
1200 undef : true, // if variables should be declared before used
1201 scripturl : true, // if script-targeted URLs should be tolerated
1202 shadow : true, // if variable shadowing should be tolerated
1203 smarttabs : true, // if smarttabs should be tolerated
1204 // (http://www.emacswiki.org/emacs/SmartTabs)
1205 strict : true, // require the "use strict"; pragma
1206 sub : true, // if all forms of subscript notation are tolerated
1207 supernew : true, // if `new function () { ... };` and `new Object;`
1208 // should be tolerated
1209 trailing : true, // if trailing whitespace rules apply
1210 validthis : true, // if 'this' inside a non-constructor function is valid.
1211 // This is a function scoped option only.
1212 withstmt : true, // if with statements should be allowed
1213 white : true, // if strict whitespace rules apply
1214 worker : true, // if Web Worker script symbols should be allowed
1215 wsh : true, // if the Windows Scripting Host environment globals
1216 // should be predefined
1217 yui : true, // YUI variables should be predefined
1218
1219 // Obsolete options
1220 onecase : true, // if one case switch statements should be allowed
1221 regexp : true, // if the . should not be allowed in regexp literals
1222 regexdash : true // if unescaped first/last dash (-) inside brackets
1223 // should be tolerated
1224 },
1225
1226 // These are the JSHint options that can take any value
1227 // (we use this object to detect invalid options)
1228 valOptions = {
1229 maxlen : false,
1230 indent : false,
1231 maxerr : false,
1232 predef : false,
1233 quotmark : false, //'single'|'double'|true
1234 scope : false,
1235 maxstatements: false, // {int} max statements per function
1236 maxdepth : false, // {int} max nested block depth per function
1237 maxparams : false, // {int} max params per function
1238 maxcomplexity: false, // {int} max cyclomatic complexity per function
1239 unused : true, // warn if variables are unused. Available options:
1240 // false - don't check for unused variables
1241 // true - "vars" + check last function param
1242 // "vars" - skip checking unused function params
1243 // "strict" - "vars" + check all function params
1244 latedef : false // warn if the variable is used before its definition
1245 // false - don't emit any warnings
1246 // true - warn if any variable is used before its definition
1247 // "nofunc" - warn for any variable but function declarations
1248 },
1249
1250 // These are JSHint boolean options which are shared with JSLint
1251 // where the definition in JSHint is opposite JSLint
1252 invertedOptions = {
1253 bitwise : true,
1254 forin : true,
1255 newcap : true,
1256 nomen : true,
1257 plusplus: true,
1258 regexp : true,
1259 undef : true,
1260 white : true,
1261
1262 // Inverted and renamed, use JSHint name here
1263 eqeqeq : true,
1264 onevar : true,
1265 strict : true
1266 },
1267
1268 // These are JSHint boolean options which are shared with JSLint
1269 // where the name has been changed but the effect is unchanged
1270 renamedOptions = {
1271 eqeq : "eqeqeq",
1272 vars : "onevar",
1273 windows: "wsh",
1274 sloppy : "strict"
1275 },
1276
1277 declared, // Globals that were declared using /*global ... */ syntax.
1278 exported, // Variables that are used outside of the current file.
1279
1280 functionicity = [
1281 "closure", "exception", "global", "label",
1282 "outer", "unused", "var"
1283 ],
1284
1285 funct, // The current function
1286 functions, // All of the functions
1287
1288 global, // The global scope
1289 implied, // Implied globals
1290 inblock,
1291 indent,
1292 lookahead,
1293 lex,
1294 member,
1295 membersOnly,
1296 noreach,
1297 predefined, // Global variables defined by option
1298
1299 scope, // The current scope
1300 stack,
1301 unuseds,
1302 urls,
1303 warnings,
1304
1305 extraModules = [],
1306 emitter = new events.EventEmitter();
1307
1308 function checkOption(name, t) {
1309 name = name.trim();
1310
1311 if (/^[+-]W\d{3}$/g.test(name)) {
1312 return true;
1313 }
1314
1315 if (valOptions[name] === undefined && boolOptions[name] === undefined) {
1316 if (t.type !== "jslint") {
1317 error("E001", t, name);
1318 return false;
1319 }
1320 }
1321
1322 return true;
1323 }
1324
1325 function isString(obj) {
1326 return Object.prototype.toString.call(obj) === "[object String]";
1327 }
1328
1329 function isIdentifier(tkn, value) {
1330 if (!tkn)
1331 return false;
1332
1333 if (!tkn.identifier || tkn.value !== value)
1334 return false;
1335
1336 return true;
1337 }
1338
1339 function isReserved(token) {
1340 if (!token.reserved) {
1341 return false;
1342 }
1343 var meta = token.meta;
1344
1345 if (meta && meta.isFutureReservedWord && state.option.inES5()) {
1346 // ES3 FutureReservedWord in an ES5 environment.
1347 if (!meta.es5) {
1348 return false;
1349 }
1350
1351 // Some ES5 FutureReservedWord identifiers are active only
1352 // within a strict mode environment.
1353 if (meta.strictOnly) {
1354 if (!state.option.strict && !state.directive["use strict"]) {
1355 return false;
1356 }
1357 }
1358
1359 if (token.isProperty) {
1360 return false;
1361 }
1362 }
1363
1364 return true;
1365 }
1366
1367 function supplant(str, data) {
1368 return str.replace(/\{([^{}]*)\}/g, function (a, b) {
1369 var r = data[b];
1370 return typeof r === "string" || typeof r === "number" ? r : a;
1371 });
1372 }
1373
1374 function combine(t, o) {
1375 var n;
1376 for (n in o) {
1377 if (_.has(o, n) && !_.has(JSHINT.blacklist, n)) {
1378 t[n] = o[n];
1379 }
1380 }
1381 }
1382
1383 function updatePredefined() {
1384 Object.keys(JSHINT.blacklist).forEach(function (key) {
1385 delete predefined[key];
1386 });
1387 }
1388
1389 function assume() {
1390 if (state.option.es5) {
1391 warning("I003");
1392 }
1393 if (state.option.couch) {
1394 combine(predefined, vars.couch);
1395 }
1396
1397 if (state.option.rhino) {
1398 combine(predefined, vars.rhino);
1399 }
1400
1401 if (state.option.shelljs) {
1402 combine(predefined, vars.shelljs);
1403 combine(predefined, vars.node);
1404 }
1405
1406 if (state.option.phantom) {
1407 combine(predefined, vars.phantom);
1408 }
1409
1410 if (state.option.prototypejs) {
1411 combine(predefined, vars.prototypejs);
1412 }
1413
1414 if (state.option.node) {
1415 combine(predefined, vars.node);
1416 }
1417
1418 if (state.option.devel) {
1419 combine(predefined, vars.devel);
1420 }
1421
1422 if (state.option.dojo) {
1423 combine(predefined, vars.dojo);
1424 }
1425
1426 if (state.option.browser) {
1427 combine(predefined, vars.browser);
1428 }
1429
1430 if (state.option.nonstandard) {
1431 combine(predefined, vars.nonstandard);
1432 }
1433
1434 if (state.option.jquery) {
1435 combine(predefined, vars.jquery);
1436 }
1437
1438 if (state.option.mootools) {
1439 combine(predefined, vars.mootools);
1440 }
1441
1442 if (state.option.worker) {
1443 combine(predefined, vars.worker);
1444 }
1445
1446 if (state.option.wsh) {
1447 combine(predefined, vars.wsh);
1448 }
1449
1450 if (state.option.globalstrict && state.option.strict !== false) {
1451 state.option.strict = true;
1452 }
1453
1454 if (state.option.yui) {
1455 combine(predefined, vars.yui);
1456 }
1457
1458 // Let's assume that chronologically ES3 < ES5 < ES6/ESNext < Moz
1459
1460 state.option.inMoz = function (strict) {
1461 if (strict) {
1462 return state.option.moz && !state.option.esnext;
1463 }
1464 return state.option.moz;
1465 };
1466
1467 state.option.inESNext = function (strict) {
1468 if (strict) {
1469 return !state.option.moz && state.option.esnext;
1470 }
1471 return state.option.moz || state.option.esnext;
1472 };
1473
1474 state.option.inES5 = function (/* strict */) {
1475 return !state.option.es3;
1476 };
1477
1478 state.option.inES3 = function (strict) {
1479 if (strict) {
1480 return !state.option.moz && !state.option.esnext && state.option.es3;
1481 }
1482 return state.option.es3;
1483 };
1484 }
1485
1486 // Produce an error warning.
1487 function quit(code, line, chr) {
1488 var percentage = Math.floor((line / state.lines.length) * 100);
1489 var message = messages.errors[code].desc;
1490
1491 throw {
1492 name: "JSHintError",
1493 line: line,
1494 character: chr,
1495 message: message + " (" + percentage + "% scanned).",
1496 raw: message,
1497 code: code
1498 };
1499 }
1500
1501 function isundef(scope, code, token, a) {
1502 return JSHINT.undefs.push([scope, code, token, a]);
1503 }
1504
1505 function warning(code, t, a, b, c, d) {
1506 var ch, l, w, msg;
1507
1508 if (/^W\d{3}$/.test(code)) {
1509 if (state.ignored[code])
1510 return;
1511
1512 msg = messages.warnings[code];
1513 } else if (/E\d{3}/.test(code)) {
1514 msg = messages.errors[code];
1515 } else if (/I\d{3}/.test(code)) {
1516 msg = messages.info[code];
1517 }
1518
1519 t = t || state.tokens.next;
1520 if (t.id === "(end)") { // `~
1521 t = state.tokens.curr;
1522 }
1523
1524 l = t.line || 0;
1525 ch = t.from || 0;
1526
1527 w = {
1528 id: "(error)",
1529 raw: msg.desc,
1530 code: msg.code,
1531 evidence: state.lines[l - 1] || "",
1532 line: l,
1533 character: ch,
1534 scope: JSHINT.scope,
1535 a: a,
1536 b: b,
1537 c: c,
1538 d: d
1539 };
1540
1541 w.reason = supplant(msg.desc, w);
1542 JSHINT.errors.push(w);
1543
1544 if (state.option.passfail) {
1545 quit("E042", l, ch);
1546 }
1547
1548 warnings += 1;
1549 if (warnings >= state.option.maxerr) {
1550 quit("E043", l, ch);
1551 }
1552
1553 return w;
1554 }
1555
1556 function warningAt(m, l, ch, a, b, c, d) {
1557 return warning(m, {
1558 line: l,
1559 from: ch
1560 }, a, b, c, d);
1561 }
1562
1563 function error(m, t, a, b, c, d) {
1564 warning(m, t, a, b, c, d);
1565 }
1566
1567 function errorAt(m, l, ch, a, b, c, d) {
1568 return error(m, {
1569 line: l,
1570 from: ch
1571 }, a, b, c, d);
1572 }
1573
1574 // Tracking of "internal" scripts, like eval containing a static string
1575 function addInternalSrc(elem, src) {
1576 var i;
1577 i = {
1578 id: "(internal)",
1579 elem: elem,
1580 value: src
1581 };
1582 JSHINT.internals.push(i);
1583 return i;
1584 }
1585
1586 function addlabel(t, type, tkn, islet) {
1587 // Define t in the current function in the current scope.
1588 if (type === "exception") {
1589 if (_.has(funct["(context)"], t)) {
1590 if (funct[t] !== true && !state.option.node) {
1591 warning("W002", state.tokens.next, t);
1592 }
1593 }
1594 }
1595
1596 if (_.has(funct, t) && !funct["(global)"]) {
1597 if (funct[t] === true) {
1598 if (state.option.latedef) {
1599 if ((state.option.latedef === true && _.contains([funct[t], type], "unction")) ||
1600 !_.contains([funct[t], type], "unction")) {
1601 warning("W003", state.tokens.next, t);
1602 }
1603 }
1604 } else {
1605 if (!state.option.shadow && type !== "exception" ||
1606 (funct["(blockscope)"].getlabel(t))) {
1607 warning("W004", state.tokens.next, t);
1608 }
1609 }
1610 }
1611
1612 // a double definition of a let variable in same block throws a TypeError
1613 if (funct["(blockscope)"] && funct["(blockscope)"].current.has(t)) {
1614 error("E044", state.tokens.next, t);
1615 }
1616
1617 // if the identifier is from a let, adds it only to the current blockscope
1618 if (islet) {
1619 funct["(blockscope)"].current.add(t, type, state.tokens.curr);
1620 } else {
1621
1622 funct[t] = type;
1623
1624 if (tkn) {
1625 funct["(tokens)"][t] = tkn;
1626 }
1627
1628 if (funct["(global)"]) {
1629 global[t] = funct;
1630 if (_.has(implied, t)) {
1631 if (state.option.latedef) {
1632 if ((state.option.latedef === true && _.contains([funct[t], type], "unction")) ||
1633 !_.contains([funct[t], type], "unction")) {
1634 warning("W003", state.tokens.next, t);
1635 }
1636 }
1637
1638 delete implied[t];
1639 }
1640 } else {
1641 scope[t] = funct;
1642 }
1643 }
1644 }
1645
1646 function doOption() {
1647 var nt = state.tokens.next;
1648 var body = nt.body.split(",").map(function (s) { return s.trim(); });
1649 var predef = {};
1650
1651 if (nt.type === "globals") {
1652 body.forEach(function (g) {
1653 g = g.split(":");
1654 var key = g[0];
1655 var val = g[1];
1656
1657 if (key.charAt(0) === "-") {
1658 key = key.slice(1);
1659 val = false;
1660
1661 JSHINT.blacklist[key] = key;
1662 updatePredefined();
1663 } else {
1664 predef[key] = (val === "true");
1665 }
1666 });
1667
1668 combine(predefined, predef);
1669
1670 for (var key in predef) {
1671 if (_.has(predef, key)) {
1672 declared[key] = nt;
1673 }
1674 }
1675 }
1676
1677 if (nt.type === "exported") {
1678 body.forEach(function (e) {
1679 exported[e] = true;
1680 });
1681 }
1682
1683 if (nt.type === "members") {
1684 membersOnly = membersOnly || {};
1685
1686 body.forEach(function (m) {
1687 var ch1 = m.charAt(0);
1688 var ch2 = m.charAt(m.length - 1);
1689
1690 if (ch1 === ch2 && (ch1 === "\"" || ch1 === "'")) {
1691 m = m
1692 .substr(1, m.length - 2)
1693 .replace("\\b", "\b")
1694 .replace("\\t", "\t")
1695 .replace("\\n", "\n")
1696 .replace("\\v", "\v")
1697 .replace("\\f", "\f")
1698 .replace("\\r", "\r")
1699 .replace("\\\\", "\\")
1700 .replace("\\\"", "\"");
1701 }
1702
1703 membersOnly[m] = false;
1704 });
1705 }
1706
1707 var numvals = [
1708 "maxstatements",
1709 "maxparams",
1710 "maxdepth",
1711 "maxcomplexity",
1712 "maxerr",
1713 "maxlen",
1714 "indent"
1715 ];
1716
1717 if (nt.type === "jshint" || nt.type === "jslint") {
1718 body.forEach(function (g) {
1719 g = g.split(":");
1720 var key = (g[0] || "").trim();
1721 var val = (g[1] || "").trim();
1722
1723 if (!checkOption(key, nt)) {
1724 return;
1725 }
1726
1727 if (numvals.indexOf(key) >= 0) {
1728
1729 // GH988 - numeric options can be disabled by setting them to `false`
1730 if (val !== "false") {
1731 val = +val;
1732
1733 if (typeof val !== "number" || !isFinite(val) || val <= 0 || Math.floor(val) !== val) {
1734 error("E032", nt, g[1].trim());
1735 return;
1736 }
1737
1738 if (key === "indent") {
1739 state.option["(explicitIndent)"] = true;
1740 }
1741 state.option[key] = val;
1742 } else {
1743 if (key === "indent") {
1744 state.option["(explicitIndent)"] = false;
1745 } else {
1746 state.option[key] = false;
1747 }
1748 }
1749
1750 return;
1751 }
1752
1753 if (key === "validthis") {
1754 // `validthis` is valid only within a function scope.
1755 if (funct["(global)"]) {
1756 error("E009");
1757 } else {
1758 if (val === "true" || val === "false") {
1759 state.option.validthis = (val === "true");
1760 } else {
1761 error("E002", nt);
1762 }
1763 }
1764 return;
1765 }
1766
1767 if (key === "quotmark") {
1768 switch (val) {
1769 case "true":
1770 case "false":
1771 state.option.quotmark = (val === "true");
1772 break;
1773 case "double":
1774 case "single":
1775 state.option.quotmark = val;
1776 break;
1777 default:
1778 error("E002", nt);
1779 }
1780 return;
1781 }
1782
1783 if (key === "unused") {
1784 switch (val) {
1785 case "true":
1786 state.option.unused = true;
1787 break;
1788 case "false":
1789 state.option.unused = false;
1790 break;
1791 case "vars":
1792 case "strict":
1793 state.option.unused = val;
1794 break;
1795 default:
1796 error("E002", nt);
1797 }
1798 return;
1799 }
1800
1801 if (key === "latedef") {
1802 switch (val) {
1803 case "true":
1804 state.option.latedef = true;
1805 break;
1806 case "false":
1807 state.option.latedef = false;
1808 break;
1809 case "nofunc":
1810 state.option.latedef = "nofunc";
1811 break;
1812 default:
1813 error("E002", nt);
1814 }
1815 return;
1816 }
1817
1818 var match = /^([+-])(W\d{3})$/g.exec(key);
1819 if (match) {
1820 // ignore for -W..., unignore for +W...
1821 state.ignored[match[2]] = (match[1] === "-");
1822 return;
1823 }
1824
1825 var tn;
1826 if (val === "true" || val === "false") {
1827 if (nt.type === "jslint") {
1828 tn = renamedOptions[key] || key;
1829 state.option[tn] = (val === "true");
1830
1831 if (invertedOptions[tn] !== undefined) {
1832 state.option[tn] = !state.option[tn];
1833 }
1834 } else {
1835 state.option[key] = (val === "true");
1836 }
1837
1838 if (key === "newcap") {
1839 state.option["(explicitNewcap)"] = true;
1840 }
1841 return;
1842 }
1843
1844 error("E002", nt);
1845 });
1846
1847 assume();
1848 }
1849 }
1850
1851 // We need a peek function. If it has an argument, it peeks that much farther
1852 // ahead. It is used to distinguish
1853 // for ( var i in ...
1854 // from
1855 // for ( var i = ...
1856
1857 function peek(p) {
1858 var i = p || 0, j = 0, t;
1859
1860 while (j <= i) {
1861 t = lookahead[j];
1862 if (!t) {
1863 t = lookahead[j] = lex.token();
1864 }
1865 j += 1;
1866 }
1867 return t;
1868 }
1869
1870 // Produce the next token. It looks for programming errors.
1871
1872 function advance(id, t) {
1873 switch (state.tokens.curr.id) {
1874 case "(number)":
1875 if (state.tokens.next.id === ".") {
1876 warning("W005", state.tokens.curr);
1877 }
1878 break;
1879 case "-":
1880 if (state.tokens.next.id === "-" || state.tokens.next.id === "--") {
1881 warning("W006");
1882 }
1883 break;
1884 case "+":
1885 if (state.tokens.next.id === "+" || state.tokens.next.id === "++") {
1886 warning("W007");
1887 }
1888 break;
1889 }
1890
1891 if (state.tokens.curr.type === "(string)" || state.tokens.curr.identifier) {
1892 anonname = state.tokens.curr.value;
1893 }
1894
1895 if (id && state.tokens.next.id !== id) {
1896 if (t) {
1897 if (state.tokens.next.id === "(end)") {
1898 error("E019", t, t.id);
1899 } else {
1900 error("E020", state.tokens.next, id, t.id, t.line, state.tokens.next.value);
1901 }
1902 } else if (state.tokens.next.type !== "(identifier)" || state.tokens.next.value !== id) {
1903 warning("W116", state.tokens.next, id, state.tokens.next.value);
1904 }
1905 }
1906
1907 state.tokens.prev = state.tokens.curr;
1908 state.tokens.curr = state.tokens.next;
1909 for (;;) {
1910 state.tokens.next = lookahead.shift() || lex.token();
1911
1912 if (!state.tokens.next) { // No more tokens left, give up
1913 quit("E041", state.tokens.curr.line);
1914 }
1915
1916 if (state.tokens.next.id === "(end)" || state.tokens.next.id === "(error)") {
1917 return;
1918 }
1919
1920 if (state.tokens.next.check) {
1921 state.tokens.next.check();
1922 }
1923
1924 if (state.tokens.next.isSpecial) {
1925 doOption();
1926 } else {
1927 if (state.tokens.next.id !== "(endline)") {
1928 break;
1929 }
1930 }
1931 }
1932 }
1933
1934 function isInfix(token) {
1935 return token.infix || (!token.identifier && !!token.led);
1936 }
1937
1938 function isEndOfExpr() {
1939 var curr = state.tokens.curr;
1940 var next = state.tokens.next;
1941 if (next.id === ";" || next.id === "}" || next.id === ":") {
1942 return true;
1943 }
1944 if (isInfix(next) === isInfix(curr) || (curr.id === "yield" && state.option.inMoz(true))) {
1945 return curr.line !== next.line;
1946 }
1947 return false;
1948 }
1949
1950 // This is the heart of JSHINT, the Pratt parser. In addition to parsing, it
1951 // is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is
1952 // like .nud except that it is only used on the first token of a statement.
1953 // Having .fud makes it much easier to define statement-oriented languages like
1954 // JavaScript. I retained Pratt's nomenclature.
1955
1956 // .nud Null denotation
1957 // .fud First null denotation
1958 // .led Left denotation
1959 // lbp Left binding power
1960 // rbp Right binding power
1961
1962 // They are elements of the parsing method called Top Down Operator Precedence.
1963
1964 function expression(rbp, initial) {
1965 var left, isArray = false, isObject = false, isLetExpr = false;
1966
1967 // if current expression is a let expression
1968 if (!initial && state.tokens.next.value === "let" && peek(0).value === "(") {
1969 if (!state.option.inMoz(true)) {
1970 warning("W118", state.tokens.next, "let expressions");
1971 }
1972 isLetExpr = true;
1973 // create a new block scope we use only for the current expression
1974 funct["(blockscope)"].stack();
1975 advance("let");
1976 advance("(");
1977 state.syntax["let"].fud.call(state.syntax["let"].fud, false);
1978 advance(")");
1979 }
1980
1981 if (state.tokens.next.id === "(end)")
1982 error("E006", state.tokens.curr);
1983
1984 advance();
1985
1986 if (initial) {
1987 anonname = "anonymous";
1988 funct["(verb)"] = state.tokens.curr.value;
1989 }
1990
1991 if (initial === true && state.tokens.curr.fud) {
1992 left = state.tokens.curr.fud();
1993 } else {
1994 if (state.tokens.curr.nud) {
1995 left = state.tokens.curr.nud();
1996 } else {
1997 error("E030", state.tokens.curr, state.tokens.curr.id);
1998 }
1999
2000 while (rbp < state.tokens.next.lbp && !isEndOfExpr()) {
2001 isArray = state.tokens.curr.value === "Array";
2002 isObject = state.tokens.curr.value === "Object";
2003
2004 // #527, new Foo.Array(), Foo.Array(), new Foo.Object(), Foo.Object()
2005 // Line breaks in IfStatement heads exist to satisfy the checkJSHint
2006 // "Line too long." error.
2007 if (left && (left.value || (left.first && left.first.value))) {
2008 // If the left.value is not "new", or the left.first.value is a "."
2009 // then safely assume that this is not "new Array()" and possibly
2010 // not "new Object()"...
2011 if (left.value !== "new" ||
2012 (left.first && left.first.value && left.first.value === ".")) {
2013 isArray = false;
2014 // ...In the case of Object, if the left.value and state.tokens.curr.value
2015 // are not equal, then safely assume that this not "new Object()"
2016 if (left.value !== state.tokens.curr.value) {
2017 isObject = false;
2018 }
2019 }
2020 }
2021
2022 advance();
2023
2024 if (isArray && state.tokens.curr.id === "(" && state.tokens.next.id === ")") {
2025 warning("W009", state.tokens.curr);
2026 }
2027
2028 if (isObject && state.tokens.curr.id === "(" && state.tokens.next.id === ")") {
2029 warning("W010", state.tokens.curr);
2030 }
2031
2032 if (left && state.tokens.curr.led) {
2033 left = state.tokens.curr.led(left);
2034 } else {
2035 error("E033", state.tokens.curr, state.tokens.curr.id);
2036 }
2037 }
2038 }
2039 if (isLetExpr) {
2040 funct["(blockscope)"].unstack();
2041 }
2042 return left;
2043 }
2044
2045
2046 // Functions for conformance of style.
2047
2048 function adjacent(left, right) {
2049 left = left || state.tokens.curr;
2050 right = right || state.tokens.next;
2051 if (state.option.white) {
2052 if (left.character !== right.from && left.line === right.line) {
2053 left.from += (left.character - left.from);
2054 warning("W011", left, left.value);
2055 }
2056 }
2057 }
2058
2059 function nobreak(left, right) {
2060 left = left || state.tokens.curr;
2061 right = right || state.tokens.next;
2062 if (state.option.white && (left.character !== right.from || left.line !== right.line)) {
2063 warning("W012", right, right.value);
2064 }
2065 }
2066
2067 function nospace(left, right) {
2068 left = left || state.tokens.curr;
2069 right = right || state.tokens.next;
2070 if (state.option.white && !left.comment) {
2071 if (left.line === right.line) {
2072 adjacent(left, right);
2073 }
2074 }
2075 }
2076
2077 function nonadjacent(left, right) {
2078 if (state.option.white) {
2079 left = left || state.tokens.curr;
2080 right = right || state.tokens.next;
2081
2082 if (left.value === ";" && right.value === ";") {
2083 return;
2084 }
2085
2086 if (left.line === right.line && left.character === right.from) {
2087 left.from += (left.character - left.from);
2088 warning("W013", left, left.value);
2089 }
2090 }
2091 }
2092
2093 function nobreaknonadjacent(left, right) {
2094 left = left || state.tokens.curr;
2095 right = right || state.tokens.next;
2096 if (!state.option.laxbreak && left.line !== right.line) {
2097 warning("W014", right, right.value);
2098 } else if (state.option.white) {
2099 left = left || state.tokens.curr;
2100 right = right || state.tokens.next;
2101 if (left.character === right.from) {
2102 left.from += (left.character - left.from);
2103 warning("W013", left, left.value);
2104 }
2105 }
2106 }
2107
2108 function indentation(bias) {
2109 if (!state.option.white && !state.option["(explicitIndent)"]) {
2110 return;
2111 }
2112
2113 if (state.tokens.next.id === "(end)") {
2114 return;
2115 }
2116
2117 var i = indent + (bias || 0);
2118 if (state.tokens.next.from !== i) {
2119 warning("W015", state.tokens.next, state.tokens.next.value, i, state.tokens.next.from);
2120 }
2121 }
2122
2123 function nolinebreak(t) {
2124 t = t || state.tokens.curr;
2125 if (t.line !== state.tokens.next.line) {
2126 warning("E022", t, t.value);
2127 }
2128 }
2129
2130 function nobreakcomma(left, right) {
2131 if (left.line !== right.line) {
2132 if (!state.option.laxcomma) {
2133 if (comma.first) {
2134 warning("I001");
2135 comma.first = false;
2136 }
2137 warning("W014", left, right.value);
2138 }
2139 } else if (!left.comment && left.character !== right.from && state.option.white) {
2140 left.from += (left.character - left.from);
2141 warning("W011", left, left.value);
2142 }
2143 }
2144
2145 function comma(opts) {
2146 opts = opts || {};
2147
2148 if (!opts.peek) {
2149 nobreakcomma(state.tokens.curr, state.tokens.next);
2150 advance(",");
2151 } else {
2152 nobreakcomma(state.tokens.prev, state.tokens.curr);
2153 }
2154
2155 // TODO: This is a temporary solution to fight against false-positives in
2156 // arrays and objects with trailing commas (see GH-363). The best solution
2157 // would be to extract all whitespace rules out of parser.
2158
2159 if (state.tokens.next.value !== "]" && state.tokens.next.value !== "}") {
2160 nonadjacent(state.tokens.curr, state.tokens.next);
2161 }
2162
2163 if (state.tokens.next.identifier && !(opts.property && state.option.inES5())) {
2164 // Keywords that cannot follow a comma operator.
2165 switch (state.tokens.next.value) {
2166 case "break":
2167 case "case":
2168 case "catch":
2169 case "continue":
2170 case "default":
2171 case "do":
2172 case "else":
2173 case "finally":
2174 case "for":
2175 case "if":
2176 case "in":
2177 case "instanceof":
2178 case "return":
2179 case "switch":
2180 case "throw":
2181 case "try":
2182 case "var":
2183 case "let":
2184 case "while":
2185 case "with":
2186 error("E024", state.tokens.next, state.tokens.next.value);
2187 return false;
2188 }
2189 }
2190
2191 if (state.tokens.next.type === "(punctuator)") {
2192 switch (state.tokens.next.value) {
2193 case "}":
2194 case "]":
2195 case ",":
2196 if (opts.allowTrailing) {
2197 return true;
2198 }
2199
2200 /* falls through */
2201 case ")":
2202 error("E024", state.tokens.next, state.tokens.next.value);
2203 return false;
2204 }
2205 }
2206 return true;
2207 }
2208
2209 // Functional constructors for making the symbols that will be inherited by
2210 // tokens.
2211
2212 function symbol(s, p) {
2213 var x = state.syntax[s];
2214 if (!x || typeof x !== "object") {
2215 state.syntax[s] = x = {
2216 id: s,
2217 lbp: p,
2218 value: s
2219 };
2220 }
2221 return x;
2222 }
2223
2224 function delim(s) {
2225 return symbol(s, 0);
2226 }
2227
2228 function stmt(s, f) {
2229 var x = delim(s);
2230 x.identifier = x.reserved = true;
2231 x.fud = f;
2232 return x;
2233 }
2234
2235 function blockstmt(s, f) {
2236 var x = stmt(s, f);
2237 x.block = true;
2238 return x;
2239 }
2240
2241 function reserveName(x) {
2242 var c = x.id.charAt(0);
2243 if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z")) {
2244 x.identifier = x.reserved = true;
2245 }
2246 return x;
2247 }
2248
2249 function prefix(s, f) {
2250 var x = symbol(s, 150);
2251 reserveName(x);
2252 x.nud = (typeof f === "function") ? f : function () {
2253 this.right = expression(150);
2254 this.arity = "unary";
2255 if (this.id === "++" || this.id === "--") {
2256 if (state.option.plusplus) {
2257 warning("W016", this, this.id);
2258 } else if ((!this.right.identifier || isReserved(this.right)) &&
2259 this.right.id !== "." && this.right.id !== "[") {
2260 warning("W017", this);
2261 }
2262 }
2263 return this;
2264 };
2265 return x;
2266 }
2267
2268 function type(s, f) {
2269 var x = delim(s);
2270 x.type = s;
2271 x.nud = f;
2272 return x;
2273 }
2274
2275 function reserve(name, func) {
2276 var x = type(name, func);
2277 x.identifier = true;
2278 x.reserved = true;
2279 return x;
2280 }
2281
2282 function FutureReservedWord(name, meta) {
2283 var x = type(name, (meta && meta.nud) || function () {
2284 return this;
2285 });
2286
2287 meta = meta || {};
2288 meta.isFutureReservedWord = true;
2289
2290 x.value = name;
2291 x.identifier = true;
2292 x.reserved = true;
2293 x.meta = meta;
2294
2295 return x;
2296 }
2297
2298 function reservevar(s, v) {
2299 return reserve(s, function () {
2300 if (typeof v === "function") {
2301 v(this);
2302 }
2303 return this;
2304 });
2305 }
2306
2307 function infix(s, f, p, w) {
2308 var x = symbol(s, p);
2309 reserveName(x);
2310 x.infix = true;
2311 x.led = function (left) {
2312 if (!w) {
2313 nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
2314 nonadjacent(state.tokens.curr, state.tokens.next);
2315 }
2316 if (s === "in" && left.id === "!") {
2317 warning("W018", left, "!");
2318 }
2319 if (typeof f === "function") {
2320 return f(left, this);
2321 } else {
2322 this.left = left;
2323 this.right = expression(p);
2324 return this;
2325 }
2326 };
2327 return x;
2328 }
2329
2330
2331 function application(s) {
2332 var x = symbol(s, 42);
2333
2334 x.led = function (left) {
2335 if (!state.option.inESNext()) {
2336 warning("W104", state.tokens.curr, "arrow function syntax (=>)");
2337 }
2338
2339 nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
2340 nonadjacent(state.tokens.curr, state.tokens.next);
2341
2342 this.left = left;
2343 this.right = doFunction(undefined, undefined, false, left);
2344 return this;
2345 };
2346 return x;
2347 }
2348
2349 function relation(s, f) {
2350 var x = symbol(s, 100);
2351
2352 x.led = function (left) {
2353 nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
2354 nonadjacent(state.tokens.curr, state.tokens.next);
2355 var right = expression(100);
2356
2357 if (isIdentifier(left, "NaN") || isIdentifier(right, "NaN")) {
2358 warning("W019", this);
2359 } else if (f) {
2360 f.apply(this, [left, right]);
2361 }
2362
2363 if (!left || !right) {
2364 quit("E041", state.tokens.curr.line);
2365 }
2366
2367 if (left.id === "!") {
2368 warning("W018", left, "!");
2369 }
2370
2371 if (right.id === "!") {
2372 warning("W018", right, "!");
2373 }
2374
2375 this.left = left;
2376 this.right = right;
2377 return this;
2378 };
2379 return x;
2380 }
2381
2382 function isPoorRelation(node) {
2383 return node &&
2384 ((node.type === "(number)" && +node.value === 0) ||
2385 (node.type === "(string)" && node.value === "") ||
2386 (node.type === "null" && !state.option.eqnull) ||
2387 node.type === "true" ||
2388 node.type === "false" ||
2389 node.type === "undefined");
2390 }
2391
2392 function assignop(s, f, p) {
2393 var x = infix(s, typeof f === "function" ? f : function (left, that) {
2394 that.left = left;
2395
2396 if (left) {
2397 if (predefined[left.value] === false &&
2398 scope[left.value]["(global)"] === true) {
2399 warning("W020", left);
2400 } else if (left["function"]) {
2401 warning("W021", left, left.value);
2402 }
2403
2404 if (funct[left.value] === "const") {
2405 error("E013", left, left.value);
2406 }
2407
2408 if (left.id === ".") {
2409 if (!left.left) {
2410 warning("E031", that);
2411 } else if (left.left.value === "arguments" && !state.directive["use strict"]) {
2412 warning("E031", that);
2413 }
2414
2415 that.right = expression(10);
2416 return that;
2417 } else if (left.id === "[") {
2418 if (state.tokens.curr.left.first) {
2419 state.tokens.curr.left.first.forEach(function (t) {
2420 if (funct[t.value] === "const") {
2421 error("E013", t, t.value);
2422 }
2423 });
2424 } else if (!left.left) {
2425 warning("E031", that);
2426 } else if (left.left.value === "arguments" && !state.directive["use strict"]) {
2427 warning("E031", that);
2428 }
2429 that.right = expression(10);
2430 return that;
2431 } else if (left.identifier && !isReserved(left)) {
2432 if (funct[left.value] === "exception") {
2433 warning("W022", left);
2434 }
2435 that.right = expression(10);
2436 return that;
2437 }
2438
2439 if (left === state.syntax["function"]) {
2440 warning("W023", state.tokens.curr);
2441 }
2442 }
2443
2444 error("E031", that);
2445 }, p);
2446
2447 x.exps = true;
2448 x.assign = true;
2449 return x;
2450 }
2451
2452
2453 function bitwise(s, f, p) {
2454 var x = symbol(s, p);
2455 reserveName(x);
2456 x.led = (typeof f === "function") ? f : function (left) {
2457 if (state.option.bitwise) {
2458 warning("W016", this, this.id);
2459 }
2460 this.left = left;
2461 this.right = expression(p);
2462 return this;
2463 };
2464 return x;
2465 }
2466
2467
2468 function bitwiseassignop(s) {
2469 return assignop(s, function (left, that) {
2470 if (state.option.bitwise) {
2471 warning("W016", that, that.id);
2472 }
2473 nonadjacent(state.tokens.prev, state.tokens.curr);
2474 nonadjacent(state.tokens.curr, state.tokens.next);
2475 if (left) {
2476 if (left.id === "." || left.id === "[" ||
2477 (left.identifier && !isReserved(left))) {
2478 expression(10);
2479 return that;
2480 }
2481 if (left === state.syntax["function"]) {
2482 warning("W023", state.tokens.curr);
2483 }
2484 return that;
2485 }
2486 error("E031", that);
2487 }, 20);
2488 }
2489
2490
2491 function suffix(s) {
2492 var x = symbol(s, 150);
2493
2494 x.led = function (left) {
2495 if (state.option.plusplus) {
2496 warning("W016", this, this.id);
2497 } else if ((!left.identifier || isReserved(left)) && left.id !== "." && left.id !== "[") {
2498 warning("W017", this);
2499 }
2500
2501 this.left = left;
2502 return this;
2503 };
2504 return x;
2505 }
2506
2507 // fnparam means that this identifier is being defined as a function
2508 // argument (see identifier())
2509 // prop means that this identifier is that of an object property
2510
2511 function optionalidentifier(fnparam, prop) {
2512 if (!state.tokens.next.identifier) {
2513 return;
2514 }
2515
2516 advance();
2517
2518 var curr = state.tokens.curr;
2519 var val = state.tokens.curr.value;
2520
2521 if (!isReserved(curr)) {
2522 return val;
2523 }
2524
2525 if (prop) {
2526 if (state.option.inES5()) {
2527 return val;
2528 }
2529 }
2530
2531 if (fnparam && val === "undefined") {
2532 return val;
2533 }
2534
2535 // Display an info message about reserved words as properties
2536 // and ES5 but do it only once.
2537 if (prop && !api.getCache("displayed:I002")) {
2538 api.setCache("displayed:I002", true);
2539 warning("I002");
2540 }
2541
2542 warning("W024", state.tokens.curr, state.tokens.curr.id);
2543 return val;
2544 }
2545
2546 // fnparam means that this identifier is being defined as a function
2547 // argument
2548 // prop means that this identifier is that of an object property
2549 function identifier(fnparam, prop) {
2550 var i = optionalidentifier(fnparam, prop);
2551 if (i) {
2552 return i;
2553 }
2554 if (state.tokens.curr.id === "function" && state.tokens.next.id === "(") {
2555 warning("W025");
2556 } else {
2557 error("E030", state.tokens.next, state.tokens.next.value);
2558 }
2559 }
2560
2561
2562 function reachable(s) {
2563 var i = 0, t;
2564 if (state.tokens.next.id !== ";" || noreach) {
2565 return;
2566 }
2567 for (;;) {
2568 t = peek(i);
2569 if (t.reach) {
2570 return;
2571 }
2572 if (t.id !== "(endline)") {
2573 if (t.id === "function") {
2574 if (!state.option.latedef) {
2575 break;
2576 }
2577
2578 warning("W026", t);
2579 break;
2580 }
2581
2582 warning("W027", t, t.value, s);
2583 break;
2584 }
2585 i += 1;
2586 }
2587 }
2588
2589
2590 function statement(noindent) {
2591 var values;
2592 var i = indent, r, s = scope, t = state.tokens.next;
2593
2594 if (t.id === ";") {
2595 advance(";");
2596 return;
2597 }
2598
2599 // Is this a labelled statement?
2600 var res = isReserved(t);
2601
2602 // We're being more tolerant here: if someone uses
2603 // a FutureReservedWord as a label, we warn but proceed
2604 // anyway.
2605
2606 if (res && t.meta && t.meta.isFutureReservedWord && peek().id === ":") {
2607 warning("W024", t, t.id);
2608 res = false;
2609 }
2610
2611 // detect a destructuring assignment
2612 if (_.has(["[", "{"], t.value)) {
2613 if (lookupBlockType().isDestAssign) {
2614 if (!state.option.inESNext()) {
2615 warning("W104", state.tokens.curr, "destructuring expression");
2616 }
2617 values = destructuringExpression();
2618 values.forEach(function (tok) {
2619 isundef(funct, "W117", tok.token, tok.id);
2620 });
2621 advance("=");
2622 destructuringExpressionMatch(values, expression(10, true));
2623 advance(";");
2624 return;
2625 }
2626 }
2627 if (t.identifier && !res && peek().id === ":") {
2628 advance();
2629 advance(":");
2630 scope = Object.create(s);
2631 addlabel(t.value, "label");
2632
2633 if (!state.tokens.next.labelled && state.tokens.next.value !== "{") {
2634 warning("W028", state.tokens.next, t.value, state.tokens.next.value);
2635 }
2636
2637 state.tokens.next.label = t.value;
2638 t = state.tokens.next;
2639 }
2640
2641 // Is it a lonely block?
2642
2643 if (t.id === "{") {
2644 block(true, true);
2645 return;
2646 }
2647
2648 // Parse the statement.
2649
2650 if (!noindent) {
2651 indentation();
2652 }
2653 r = expression(0, true);
2654
2655 // Look for the final semicolon.
2656
2657 if (!t.block) {
2658 if (!state.option.expr && (!r || !r.exps)) {
2659 warning("W030", state.tokens.curr);
2660 } else if (state.option.nonew && r && r.left && r.id === "(" && r.left.id === "new") {
2661 warning("W031", t);
2662 }
2663
2664 if (state.tokens.next.id !== ";") {
2665 if (!state.option.asi) {
2666 // If this is the last statement in a block that ends on
2667 // the same line *and* option lastsemic is on, ignore the warning.
2668 // Otherwise, complain about missing semicolon.
2669 if (!state.option.lastsemic || state.tokens.next.id !== "}" ||
2670 state.tokens.next.line !== state.tokens.curr.line) {
2671 warningAt("W033", state.tokens.curr.line, state.tokens.curr.character);
2672 }
2673 }
2674 } else {
2675 adjacent(state.tokens.curr, state.tokens.next);
2676 advance(";");
2677 nonadjacent(state.tokens.curr, state.tokens.next);
2678 }
2679 }
2680
2681 // Restore the indentation.
2682
2683 indent = i;
2684 scope = s;
2685 return r;
2686 }
2687
2688
2689 function statements(startLine) {
2690 var a = [], p;
2691
2692 while (!state.tokens.next.reach && state.tokens.next.id !== "(end)") {
2693 if (state.tokens.next.id === ";") {
2694 p = peek();
2695
2696 if (!p || (p.id !== "(" && p.id !== "[")) {
2697 warning("W032");
2698 }
2699
2700 advance(";");
2701 } else {
2702 a.push(statement(startLine === state.tokens.next.line));
2703 }
2704 }
2705 return a;
2706 }
2707
2708
2709 /*
2710 * read all directives
2711 * recognizes a simple form of asi, but always
2712 * warns, if it is used
2713 */
2714 function directives() {
2715 var i, p, pn;
2716
2717 for (;;) {
2718 if (state.tokens.next.id === "(string)") {
2719 p = peek(0);
2720 if (p.id === "(endline)") {
2721 i = 1;
2722 do {
2723 pn = peek(i);
2724 i = i + 1;
2725 } while (pn.id === "(endline)");
2726
2727 if (pn.id !== ";") {
2728 if (pn.id !== "(string)" && pn.id !== "(number)" &&
2729 pn.id !== "(regexp)" && pn.identifier !== true &&
2730 pn.id !== "}") {
2731 break;
2732 }
2733 warning("W033", state.tokens.next);
2734 } else {
2735 p = pn;
2736 }
2737 } else if (p.id === "}") {
2738 // Directive with no other statements, warn about missing semicolon
2739 warning("W033", p);
2740 } else if (p.id !== ";") {
2741 break;
2742 }
2743
2744 indentation();
2745 advance();
2746 if (state.directive[state.tokens.curr.value]) {
2747 warning("W034", state.tokens.curr, state.tokens.curr.value);
2748 }
2749
2750 if (state.tokens.curr.value === "use strict") {
2751 if (!state.option["(explicitNewcap)"])
2752 state.option.newcap = true;
2753 state.option.undef = true;
2754 }
2755
2756 // there's no directive negation, so always set to true
2757 state.directive[state.tokens.curr.value] = true;
2758
2759 if (p.id === ";") {
2760 advance(";");
2761 }
2762 continue;
2763 }
2764 break;
2765 }
2766 }
2767
2768
2769 /*
2770 * Parses a single block. A block is a sequence of statements wrapped in
2771 * braces.
2772 *
2773 * ordinary - true for everything but function bodies and try blocks.
2774 * stmt - true if block can be a single statement (e.g. in if/for/while).
2775 * isfunc - true if block is a function body
2776 */
2777 function block(ordinary, stmt, isfunc, isfatarrow) {
2778 var a,
2779 b = inblock,
2780 old_indent = indent,
2781 m,
2782 s = scope,
2783 t,
2784 line,
2785 d;
2786
2787 inblock = ordinary;
2788
2789 if (!ordinary || !state.option.funcscope)
2790 scope = Object.create(scope);
2791
2792 nonadjacent(state.tokens.curr, state.tokens.next);
2793 t = state.tokens.next;
2794
2795 var metrics = funct["(metrics)"];
2796 metrics.nestedBlockDepth += 1;
2797 metrics.verifyMaxNestedBlockDepthPerFunction();
2798
2799 if (state.tokens.next.id === "{") {
2800 advance("{");
2801
2802 // create a new block scope
2803 funct["(blockscope)"].stack();
2804
2805 line = state.tokens.curr.line;
2806 if (state.tokens.next.id !== "}") {
2807 indent += state.option.indent;
2808 while (!ordinary && state.tokens.next.from > indent) {
2809 indent += state.option.indent;
2810 }
2811
2812 if (isfunc) {
2813 m = {};
2814 for (d in state.directive) {
2815 if (_.has(state.directive, d)) {
2816 m[d] = state.directive[d];
2817 }
2818 }
2819 directives();
2820
2821 if (state.option.strict && funct["(context)"]["(global)"]) {
2822 if (!m["use strict"] && !state.directive["use strict"]) {
2823 warning("E007");
2824 }
2825 }
2826 }
2827
2828 a = statements(line);
2829
2830 metrics.statementCount += a.length;
2831
2832 if (isfunc) {
2833 state.directive = m;
2834 }
2835
2836 indent -= state.option.indent;
2837 if (line !== state.tokens.next.line) {
2838 indentation();
2839 }
2840 } else if (line !== state.tokens.next.line) {
2841 indentation();
2842 }
2843 advance("}", t);
2844
2845 funct["(blockscope)"].unstack();
2846
2847 indent = old_indent;
2848 } else if (!ordinary) {
2849 if (isfunc) {
2850 m = {};
2851 if (stmt && !isfatarrow && !state.option.inMoz(true)) {
2852 error("W118", state.tokens.curr, "function closure expressions");
2853 }
2854
2855 if (!stmt) {
2856 for (d in state.directive) {
2857 if (_.has(state.directive, d)) {
2858 m[d] = state.directive[d];
2859 }
2860 }
2861 }
2862 expression(10);
2863
2864 if (state.option.strict && funct["(context)"]["(global)"]) {
2865 if (!m["use strict"] && !state.directive["use strict"]) {
2866 warning("E007");
2867 }
2868 }
2869 } else {
2870 error("E021", state.tokens.next, "{", state.tokens.next.value);
2871 }
2872 } else {
2873
2874 // check to avoid let declaration not within a block
2875 funct["(nolet)"] = true;
2876
2877 if (!stmt || state.option.curly) {
2878 warning("W116", state.tokens.next, "{", state.tokens.next.value);
2879 }
2880
2881 noreach = true;
2882 indent += state.option.indent;
2883 // test indentation only if statement is in new line
2884 a = [statement(state.tokens.next.line === state.tokens.curr.line)];
2885 indent -= state.option.indent;
2886 noreach = false;
2887
2888 delete funct["(nolet)"];
2889 }
2890 funct["(verb)"] = null;
2891 if (!ordinary || !state.option.funcscope) scope = s;
2892 inblock = b;
2893 if (ordinary && state.option.noempty && (!a || a.length === 0)) {
2894 warning("W035");
2895 }
2896 metrics.nestedBlockDepth -= 1;
2897 return a;
2898 }
2899
2900
2901 function countMember(m) {
2902 if (membersOnly && typeof membersOnly[m] !== "boolean") {
2903 warning("W036", state.tokens.curr, m);
2904 }
2905 if (typeof member[m] === "number") {
2906 member[m] += 1;
2907 } else {
2908 member[m] = 1;
2909 }
2910 }
2911
2912
2913 function note_implied(tkn) {
2914 var name = tkn.value, line = tkn.line, a = implied[name];
2915 if (typeof a === "function") {
2916 a = false;
2917 }
2918
2919 if (!a) {
2920 a = [line];
2921 implied[name] = a;
2922 } else if (a[a.length - 1] !== line) {
2923 a.push(line);
2924 }
2925 }
2926
2927
2928 // Build the syntax table by declaring the syntactic elements of the language.
2929
2930 type("(number)", function () {
2931 return this;
2932 });
2933
2934 type("(string)", function () {
2935 return this;
2936 });
2937
2938 state.syntax["(identifier)"] = {
2939 type: "(identifier)",
2940 lbp: 0,
2941 identifier: true,
2942 nud: function () {
2943 var v = this.value,
2944 s = scope[v],
2945 f;
2946
2947 if (typeof s === "function") {
2948 // Protection against accidental inheritance.
2949 s = undefined;
2950 } else if (typeof s === "boolean") {
2951 f = funct;
2952 funct = functions[0];
2953 addlabel(v, "var");
2954 s = funct;
2955 funct = f;
2956 }
2957 var block;
2958 if (_.has(funct, "(blockscope)")) {
2959 block = funct["(blockscope)"].getlabel(v);
2960 }
2961
2962 // The name is in scope and defined in the current function.
2963 if (funct === s || block) {
2964 // Change 'unused' to 'var', and reject labels.
2965 // the name is in a block scope
2966 switch (block ? block[v]["(type)"] : funct[v]) {
2967 case "unused":
2968 if (block) block[v]["(type)"] = "var";
2969 else funct[v] = "var";
2970 break;
2971 case "unction":
2972 if (block) block[v]["(type)"] = "function";
2973 else funct[v] = "function";
2974 this["function"] = true;
2975 break;
2976 case "function":
2977 this["function"] = true;
2978 break;
2979 case "label":
2980 warning("W037", state.tokens.curr, v);
2981 break;
2982 }
2983 } else if (funct["(global)"]) {
2984 // The name is not defined in the function. If we are in the global
2985 // scope, then we have an undefined variable.
2986 //
2987 // Operators typeof and delete do not raise runtime errors even if
2988 // the base object of a reference is null so no need to display warning
2989 // if we're inside of typeof or delete.
2990
2991 if (typeof predefined[v] !== "boolean") {
2992 // Attempting to subscript a null reference will throw an
2993 // error, even within the typeof and delete operators
2994 if (!(anonname === "typeof" || anonname === "delete") ||
2995 (state.tokens.next && (state.tokens.next.value === "." ||
2996 state.tokens.next.value === "["))) {
2997
2998 // if we're in a list comprehension, variables are declared
2999 // locally and used before being defined. So we check
3000 // the presence of the given variable in the comp array
3001 // before declaring it undefined.
3002
3003 if (!funct["(comparray)"].check(v)) {
3004 isundef(funct, "W117", state.tokens.curr, v);
3005 }
3006 }
3007 }
3008
3009 note_implied(state.tokens.curr);
3010 } else {
3011 // If the name is already defined in the current
3012 // function, but not as outer, then there is a scope error.
3013
3014 switch (funct[v]) {
3015 case "closure":
3016 case "function":
3017 case "var":
3018 case "unused":
3019 warning("W038", state.tokens.curr, v);
3020 break;
3021 case "label":
3022 warning("W037", state.tokens.curr, v);
3023 break;
3024 case "outer":
3025 case "global":
3026 break;
3027 default:
3028 // If the name is defined in an outer function, make an outer entry,
3029 // and if it was unused, make it var.
3030 if (s === true) {
3031 funct[v] = true;
3032 } else if (s === null) {
3033 warning("W039", state.tokens.curr, v);
3034 note_implied(state.tokens.curr);
3035 } else if (typeof s !== "object") {
3036 // Operators typeof and delete do not raise runtime errors even
3037 // if the base object of a reference is null so no need to
3038 //
3039 // display warning if we're inside of typeof or delete.
3040 // Attempting to subscript a null reference will throw an
3041 // error, even within the typeof and delete operators
3042 if (!(anonname === "typeof" || anonname === "delete") ||
3043 (state.tokens.next &&
3044 (state.tokens.next.value === "." || state.tokens.next.value === "["))) {
3045
3046 isundef(funct, "W117", state.tokens.curr, v);
3047 }
3048 funct[v] = true;
3049 note_implied(state.tokens.curr);
3050 } else {
3051 switch (s[v]) {
3052 case "function":
3053 case "unction":
3054 this["function"] = true;
3055 s[v] = "closure";
3056 funct[v] = s["(global)"] ? "global" : "outer";
3057 break;
3058 case "var":
3059 case "unused":
3060 s[v] = "closure";
3061 funct[v] = s["(global)"] ? "global" : "outer";
3062 break;
3063 case "closure":
3064 funct[v] = s["(global)"] ? "global" : "outer";
3065 break;
3066 case "label":
3067 warning("W037", state.tokens.curr, v);
3068 }
3069 }
3070 }
3071 }
3072 return this;
3073 },
3074 led: function () {
3075 error("E033", state.tokens.next, state.tokens.next.value);
3076 }
3077 };
3078
3079 type("(regexp)", function () {
3080 return this;
3081 });
3082
3083 // ECMAScript parser
3084
3085 delim("(endline)");
3086 delim("(begin)");
3087 delim("(end)").reach = true;
3088 delim("(error)").reach = true;
3089 delim("}").reach = true;
3090 delim(")");
3091 delim("]");
3092 delim("\"").reach = true;
3093 delim("'").reach = true;
3094 delim(";");
3095 delim(":").reach = true;
3096 delim("#");
3097
3098 reserve("else");
3099 reserve("case").reach = true;
3100 reserve("catch");
3101 reserve("default").reach = true;
3102 reserve("finally");
3103 reservevar("arguments", function (x) {
3104 if (state.directive["use strict"] && funct["(global)"]) {
3105 warning("E008", x);
3106 }
3107 });
3108 reservevar("eval");
3109 reservevar("false");
3110 reservevar("Infinity");
3111 reservevar("null");
3112 reservevar("this", function (x) {
3113 if (state.directive["use strict"] && !state.option.validthis && ((funct["(statement)"] &&
3114 funct["(name)"].charAt(0) > "Z") || funct["(global)"])) {
3115 warning("W040", x);
3116 }
3117 });
3118 reservevar("true");
3119 reservevar("undefined");
3120
3121 assignop("=", "assign", 20);
3122 assignop("+=", "assignadd", 20);
3123 assignop("-=", "assignsub", 20);
3124 assignop("*=", "assignmult", 20);
3125 assignop("/=", "assigndiv", 20).nud = function () {
3126 error("E014");
3127 };
3128 assignop("%=", "assignmod", 20);
3129
3130 bitwiseassignop("&=", "assignbitand", 20);
3131 bitwiseassignop("|=", "assignbitor", 20);
3132 bitwiseassignop("^=", "assignbitxor", 20);
3133 bitwiseassignop("<<=", "assignshiftleft", 20);
3134 bitwiseassignop(">>=", "assignshiftright", 20);
3135 bitwiseassignop(">>>=", "assignshiftrightunsigned", 20);
3136 infix(",", function (left, that) {
3137 var expr;
3138 that.exprs = [left];
3139 if (!comma({peek: true})) {
3140 return that;
3141 }
3142 while (true) {
3143 if (!(expr = expression(10))) {
3144 break;
3145 }
3146 that.exprs.push(expr);
3147 if (state.tokens.next.value !== "," || !comma()) {
3148 break;
3149 }
3150 }
3151 return that;
3152 }, 10, true);
3153
3154 infix("?", function (left, that) {
3155 increaseComplexityCount();
3156 that.left = left;
3157 that.right = expression(10);
3158 advance(":");
3159 that["else"] = expression(10);
3160 return that;
3161 }, 30);
3162
3163 var orPrecendence = 40;
3164 infix("||", function (left, that) {
3165 increaseComplexityCount();
3166 that.left = left;
3167 that.right = expression(orPrecendence);
3168 return that;
3169 }, orPrecendence);
3170 infix("&&", "and", 50);
3171 bitwise("|", "bitor", 70);
3172 bitwise("^", "bitxor", 80);
3173 bitwise("&", "bitand", 90);
3174 relation("==", function (left, right) {
3175 var eqnull = state.option.eqnull && (left.value === "null" || right.value === "null");
3176
3177 if (!eqnull && state.option.eqeqeq)
3178 warning("W116", this, "===", "==");
3179 else if (isPoorRelation(left))
3180 warning("W041", this, "===", left.value);
3181 else if (isPoorRelation(right))
3182 warning("W041", this, "===", right.value);
3183
3184 return this;
3185 });
3186 relation("===");
3187 relation("!=", function (left, right) {
3188 var eqnull = state.option.eqnull &&
3189 (left.value === "null" || right.value === "null");
3190
3191 if (!eqnull && state.option.eqeqeq) {
3192 warning("W116", this, "!==", "!=");
3193 } else if (isPoorRelation(left)) {
3194 warning("W041", this, "!==", left.value);
3195 } else if (isPoorRelation(right)) {
3196 warning("W041", this, "!==", right.value);
3197 }
3198 return this;
3199 });
3200 relation("!==");
3201 relation("<");
3202 relation(">");
3203 relation("<=");
3204 relation(">=");
3205 bitwise("<<", "shiftleft", 120);
3206 bitwise(">>", "shiftright", 120);
3207 bitwise(">>>", "shiftrightunsigned", 120);
3208 infix("in", "in", 120);
3209 infix("instanceof", "instanceof", 120);
3210 infix("+", function (left, that) {
3211 var right = expression(130);
3212 if (left && right && left.id === "(string)" && right.id === "(string)") {
3213 left.value += right.value;
3214 left.character = right.character;
3215 if (!state.option.scripturl && reg.javascriptURL.test(left.value)) {
3216 warning("W050", left);
3217 }
3218 return left;
3219 }
3220 that.left = left;
3221 that.right = right;
3222 return that;
3223 }, 130);
3224 prefix("+", "num");
3225 prefix("+++", function () {
3226 warning("W007");
3227 this.right = expression(150);
3228 this.arity = "unary";
3229 return this;
3230 });
3231 infix("+++", function (left) {
3232 warning("W007");
3233 this.left = left;
3234 this.right = expression(130);
3235 return this;
3236 }, 130);
3237 infix("-", "sub", 130);
3238 prefix("-", "neg");
3239 prefix("---", function () {
3240 warning("W006");
3241 this.right = expression(150);
3242 this.arity = "unary";
3243 return this;
3244 });
3245 infix("---", function (left) {
3246 warning("W006");
3247 this.left = left;
3248 this.right = expression(130);
3249 return this;
3250 }, 130);
3251 infix("*", "mult", 140);
3252 infix("/", "div", 140);
3253 infix("%", "mod", 140);
3254
3255 suffix("++", "postinc");
3256 prefix("++", "preinc");
3257 state.syntax["++"].exps = true;
3258
3259 suffix("--", "postdec");
3260 prefix("--", "predec");
3261 state.syntax["--"].exps = true;
3262 prefix("delete", function () {
3263 var p = expression(10);
3264 if (!p || (p.id !== "." && p.id !== "[")) {
3265 warning("W051");
3266 }
3267 this.first = p;
3268 return this;
3269 }).exps = true;
3270
3271 prefix("~", function () {
3272 if (state.option.bitwise) {
3273 warning("W052", this, "~");
3274 }
3275 expression(150);
3276 return this;
3277 });
3278
3279 prefix("...", function () {
3280 if (!state.option.inESNext()) {
3281 warning("W104", this, "spread/rest operator");
3282 }
3283 if (!state.tokens.next.identifier) {
3284 error("E030", state.tokens.next, state.tokens.next.value);
3285 }
3286 expression(150);
3287 return this;
3288 });
3289
3290 prefix("!", function () {
3291 this.right = expression(150);
3292 this.arity = "unary";
3293
3294 if (!this.right) { // '!' followed by nothing? Give up.
3295 quit("E041", this.line || 0);
3296 }
3297
3298 if (bang[this.right.id] === true) {
3299 warning("W018", this, "!");
3300 }
3301 return this;
3302 });
3303
3304 prefix("typeof", "typeof");
3305 prefix("new", function () {
3306 var c = expression(155), i;
3307 if (c && c.id !== "function") {
3308 if (c.identifier) {
3309 c["new"] = true;
3310 switch (c.value) {
3311 case "Number":
3312 case "String":
3313 case "Boolean":
3314 case "Math":
3315 case "JSON":
3316 warning("W053", state.tokens.prev, c.value);
3317 break;
3318 case "Function":
3319 if (!state.option.evil) {
3320 warning("W054");
3321 }
3322 break;
3323 case "Date":
3324 case "RegExp":
3325 break;
3326 default:
3327 if (c.id !== "function") {
3328 i = c.value.substr(0, 1);
3329 if (state.option.newcap && (i < "A" || i > "Z") && !_.has(global, c.value)) {
3330 warning("W055", state.tokens.curr);
3331 }
3332 }
3333 }
3334 } else {
3335 if (c.id !== "." && c.id !== "[" && c.id !== "(") {
3336 warning("W056", state.tokens.curr);
3337 }
3338 }
3339 } else {
3340 if (!state.option.supernew)
3341 warning("W057", this);
3342 }
3343 adjacent(state.tokens.curr, state.tokens.next);
3344 if (state.tokens.next.id !== "(" && !state.option.supernew) {
3345 warning("W058", state.tokens.curr, state.tokens.curr.value);
3346 }
3347 this.first = c;
3348 return this;
3349 });
3350 state.syntax["new"].exps = true;
3351
3352 prefix("void").exps = true;
3353
3354 infix(".", function (left, that) {
3355 adjacent(state.tokens.prev, state.tokens.curr);
3356 nobreak();
3357 var m = identifier(false, true);
3358
3359 if (typeof m === "string") {
3360 countMember(m);
3361 }
3362
3363 that.left = left;
3364 that.right = m;
3365
3366 if (m && m === "hasOwnProperty" && state.tokens.next.value === "=") {
3367 warning("W001");
3368 }
3369
3370 if (left && left.value === "arguments" && (m === "callee" || m === "caller")) {
3371 if (state.option.noarg)
3372 warning("W059", left, m);
3373 else if (state.directive["use strict"])
3374 error("E008");
3375 } else if (!state.option.evil && left && left.value === "document" &&
3376 (m === "write" || m === "writeln")) {
3377 warning("W060", left);
3378 }
3379
3380 if (!state.option.evil && (m === "eval" || m === "execScript")) {
3381 warning("W061");
3382 }
3383
3384 return that;
3385 }, 160, true);
3386
3387 infix("(", function (left, that) {
3388 if (state.tokens.prev.id !== "}" && state.tokens.prev.id !== ")") {
3389 nobreak(state.tokens.prev, state.tokens.curr);
3390 }
3391
3392 nospace();
3393 if (state.option.immed && left && !left.immed && left.id === "function") {
3394 warning("W062");
3395 }
3396
3397 var n = 0;
3398 var p = [];
3399
3400 if (left) {
3401 if (left.type === "(identifier)") {
3402 if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) {
3403 if ("Number String Boolean Date Object".indexOf(left.value) === -1) {
3404 if (left.value === "Math") {
3405 warning("W063", left);
3406 } else if (state.option.newcap) {
3407 warning("W064", left);
3408 }
3409 }
3410 }
3411 }
3412 }
3413
3414 if (state.tokens.next.id !== ")") {
3415 for (;;) {
3416 p[p.length] = expression(10);
3417 n += 1;
3418 if (state.tokens.next.id !== ",") {
3419 break;
3420 }
3421 comma();
3422 }
3423 }
3424
3425 advance(")");
3426 nospace(state.tokens.prev, state.tokens.curr);
3427
3428 if (typeof left === "object") {
3429 if (left.value === "parseInt" && n === 1) {
3430 warning("W065", state.tokens.curr);
3431 }
3432 if (!state.option.evil) {
3433 if (left.value === "eval" || left.value === "Function" ||
3434 left.value === "execScript") {
3435 warning("W061", left);
3436
3437 if (p[0] && [0].id === "(string)") {
3438 addInternalSrc(left, p[0].value);
3439 }
3440 } else if (p[0] && p[0].id === "(string)" &&
3441 (left.value === "setTimeout" ||
3442 left.value === "setInterval")) {
3443 warning("W066", left);
3444 addInternalSrc(left, p[0].value);
3445
3446 // window.setTimeout/setInterval
3447 } else if (p[0] && p[0].id === "(string)" &&
3448 left.value === "." &&
3449 left.left.value === "window" &&
3450 (left.right === "setTimeout" ||
3451 left.right === "setInterval")) {
3452 warning("W066", left);
3453 addInternalSrc(left, p[0].value);
3454 }
3455 }
3456 if (!left.identifier && left.id !== "." && left.id !== "[" &&
3457 left.id !== "(" && left.id !== "&&" && left.id !== "||" &&
3458 left.id !== "?") {
3459 warning("W067", left);
3460 }
3461 }
3462
3463 that.left = left;
3464 return that;
3465 }, 155, true).exps = true;
3466
3467 prefix("(", function () {
3468 nospace();
3469 var bracket, brackets = [];
3470 var pn, pn1, i = 0;
3471 var ret;
3472
3473 do {
3474 pn = peek(i);
3475 i += 1;
3476 pn1 = peek(i);
3477 i += 1;
3478 } while (pn.value !== ")" && pn1.value !== "=>" && pn1.value !== ";" && pn1.type !== "(end)");
3479
3480 if (state.tokens.next.id === "function") {
3481 state.tokens.next.immed = true;
3482 }
3483
3484 var exprs = [];
3485
3486 if (state.tokens.next.id !== ")") {
3487 for (;;) {
3488 if (pn1.value === "=>" && state.tokens.next.value === "{") {
3489 bracket = state.tokens.next;
3490 bracket.left = destructuringExpression();
3491 brackets.push(bracket);
3492 for (var t in bracket.left) {
3493 exprs.push(bracket.left[t].token);
3494 }
3495 } else {
3496 exprs.push(expression(10));
3497 }
3498 if (state.tokens.next.id !== ",") {
3499 break;
3500 }
3501 comma();
3502 }
3503 }
3504
3505 advance(")", this);
3506 nospace(state.tokens.prev, state.tokens.curr);
3507 if (state.option.immed && exprs[0] && exprs[0].id === "function") {
3508 if (state.tokens.next.id !== "(" &&
3509 (state.tokens.next.id !== "." || (peek().value !== "call" && peek().value !== "apply"))) {
3510 warning("W068", this);
3511 }
3512 }
3513
3514 if (state.tokens.next.value === "=>") {
3515 return exprs;
3516 }
3517 if (!exprs.length) {
3518 return;
3519 }
3520 if (exprs.length > 1) {
3521 ret = Object.create(state.syntax[","]);
3522 ret.exprs = exprs;
3523 } else {
3524 ret = exprs[0];
3525 }
3526 if (ret) {
3527 ret.paren = true;
3528 }
3529 return ret;
3530 });
3531
3532 application("=>");
3533
3534 infix("[", function (left, that) {
3535 nobreak(state.tokens.prev, state.tokens.curr);
3536 nospace();
3537 var e = expression(10), s;
3538 if (e && e.type === "(string)") {
3539 if (!state.option.evil && (e.value === "eval" || e.value === "execScript")) {
3540 warning("W061", that);
3541 }
3542
3543 countMember(e.value);
3544 if (!state.option.sub && reg.identifier.test(e.value)) {
3545 s = state.syntax[e.value];
3546 if (!s || !isReserved(s)) {
3547 warning("W069", state.tokens.prev, e.value);
3548 }
3549 }
3550 }
3551 advance("]", that);
3552
3553 if (e && e.value === "hasOwnProperty" && state.tokens.next.value === "=") {
3554 warning("W001");
3555 }
3556
3557 nospace(state.tokens.prev, state.tokens.curr);
3558 that.left = left;
3559 that.right = e;
3560 return that;
3561 }, 160, true);
3562
3563 function comprehensiveArrayExpression() {
3564 var res = {};
3565 res.exps = true;
3566 funct["(comparray)"].stack();
3567
3568 res.right = expression(10);
3569 advance("for");
3570 if (state.tokens.next.value === "each") {
3571 advance("each");
3572 if (!state.option.inMoz(true)) {
3573 warning("W118", state.tokens.curr, "for each");
3574 }
3575 }
3576 advance("(");
3577 funct["(comparray)"].setState("define");
3578 res.left = expression(10);
3579 advance(")");
3580 if (state.tokens.next.value === "if") {
3581 advance("if");
3582 advance("(");
3583 funct["(comparray)"].setState("filter");
3584 res.filter = expression(10);
3585 advance(")");
3586 }
3587 advance("]");
3588 funct["(comparray)"].unstack();
3589 return res;
3590 }
3591
3592 prefix("[", function () {
3593 var blocktype = lookupBlockType(true);
3594 if (blocktype.isCompArray) {
3595 if (!state.option.inMoz(true)) {
3596 warning("W118", state.tokens.curr, "array comprehension");
3597 }
3598 return comprehensiveArrayExpression();
3599 } else if (blocktype.isDestAssign && !state.option.inESNext()) {
3600 warning("W104", state.tokens.curr, "destructuring assignment");
3601 }
3602 var b = state.tokens.curr.line !== state.tokens.next.line;
3603 this.first = [];
3604 if (b) {
3605 indent += state.option.indent;
3606 if (state.tokens.next.from === indent + state.option.indent) {
3607 indent += state.option.indent;
3608 }
3609 }
3610 while (state.tokens.next.id !== "(end)") {
3611 while (state.tokens.next.id === ",") {
3612 if (!state.option.inES5())
3613 warning("W070");
3614 advance(",");
3615 }
3616 if (state.tokens.next.id === "]") {
3617 break;
3618 }
3619 if (b && state.tokens.curr.line !== state.tokens.next.line) {
3620 indentation();
3621 }
3622 this.first.push(expression(10));
3623 if (state.tokens.next.id === ",") {
3624 comma({ allowTrailing: true });
3625 if (state.tokens.next.id === "]" && !state.option.inES5(true)) {
3626 warning("W070", state.tokens.curr);
3627 break;
3628 }
3629 } else {
3630 break;
3631 }
3632 }
3633 if (b) {
3634 indent -= state.option.indent;
3635 indentation();
3636 }
3637 advance("]", this);
3638 return this;
3639 }, 160);
3640
3641
3642 function property_name() {
3643 var id = optionalidentifier(false, true);
3644
3645 if (!id) {
3646 if (state.tokens.next.id === "(string)") {
3647 id = state.tokens.next.value;
3648 advance();
3649 } else if (state.tokens.next.id === "(number)") {
3650 id = state.tokens.next.value.toString();
3651 advance();
3652 }
3653 }
3654
3655 if (id === "hasOwnProperty") {
3656 warning("W001");
3657 }
3658
3659 return id;
3660 }
3661
3662
3663 function functionparams(parsed) {
3664 var curr, next;
3665 var params = [];
3666 var ident;
3667 var tokens = [];
3668 var t;
3669 var pastDefault = false;
3670
3671 if (parsed) {
3672 if (parsed instanceof Array) {
3673 for (var i in parsed) {
3674 curr = parsed[i];
3675 if (_.contains(["{", "["], curr.id)) {
3676 for (t in curr.left) {
3677 t = tokens[t];
3678 if (t.id) {
3679 params.push(t.id);
3680 addlabel(t.id, "unused", t.token);
3681 }
3682 }
3683 } else if (curr.value === "...") {
3684 if (!state.option.inESNext()) {
3685 warning("W104", curr, "spread/rest operator");
3686 }
3687 continue;
3688 } else {
3689 addlabel(curr.value, "unused", curr);
3690 }
3691 }
3692 return params;
3693 } else {
3694 if (parsed.identifier === true) {
3695 addlabel(parsed.value, "unused", parsed);
3696 return [parsed];
3697 }
3698 }
3699 }
3700
3701 next = state.tokens.next;
3702
3703 advance("(");
3704 nospace();
3705
3706 if (state.tokens.next.id === ")") {
3707 advance(")");
3708 return;
3709 }
3710
3711 for (;;) {
3712 if (_.contains(["{", "["], state.tokens.next.id)) {
3713 tokens = destructuringExpression();
3714 for (t in tokens) {
3715 t = tokens[t];
3716 if (t.id) {
3717 params.push(t.id);
3718 addlabel(t.id, "unused", t.token);
3719 }
3720 }
3721 } else if (state.tokens.next.value === "...") {
3722 if (!state.option.inESNext()) {
3723 warning("W104", state.tokens.next, "spread/rest operator");
3724 }
3725 advance("...");
3726 nospace();
3727 ident = identifier(true);
3728 params.push(ident);
3729 addlabel(ident, "unused", state.tokens.curr);
3730 } else {
3731 ident = identifier(true);
3732 params.push(ident);
3733 addlabel(ident, "unused", state.tokens.curr);
3734 }
3735
3736 // it is a syntax error to have a regular argument after a default argument
3737 if (pastDefault) {
3738 if (state.tokens.next.id !== "=") {
3739 error("E051", state.tokens.current);
3740 }
3741 }
3742 if (state.tokens.next.id === "=") {
3743 if (!state.option.inESNext()) {
3744 warning("W119", state.tokens.next, "default parameters");
3745 }
3746 advance("=");
3747 pastDefault = true;
3748 expression(10);
3749 }
3750 if (state.tokens.next.id === ",") {
3751 comma();
3752 } else {
3753 advance(")", next);
3754 nospace(state.tokens.prev, state.tokens.curr);
3755 return params;
3756 }
3757 }
3758 }
3759
3760
3761 function doFunction(name, statement, generator, fatarrowparams) {
3762 var f;
3763 var oldOption = state.option;
3764 var oldIgnored = state.ignored;
3765 var oldScope = scope;
3766
3767 state.option = Object.create(state.option);
3768 state.ignored = Object.create(state.ignored);
3769 scope = Object.create(scope);
3770
3771 funct = {
3772 "(name)" : name || "\"" + anonname + "\"",
3773 "(line)" : state.tokens.next.line,
3774 "(character)" : state.tokens.next.character,
3775 "(context)" : funct,
3776 "(breakage)" : 0,
3777 "(loopage)" : 0,
3778 "(metrics)" : createMetrics(state.tokens.next),
3779 "(scope)" : scope,
3780 "(statement)" : statement,
3781 "(tokens)" : {},
3782 "(blockscope)": funct["(blockscope)"],
3783 "(comparray)" : funct["(comparray)"]
3784 };
3785
3786 if (generator) {
3787 funct["(generator)"] = true;
3788 }
3789
3790 f = funct;
3791 state.tokens.curr.funct = funct;
3792
3793 functions.push(funct);
3794
3795 if (name) {
3796 addlabel(name, "function");
3797 }
3798
3799 funct["(params)"] = functionparams(fatarrowparams);
3800
3801 funct["(metrics)"].verifyMaxParametersPerFunction(funct["(params)"]);
3802
3803 block(false, true, true, fatarrowparams ? true:false);
3804
3805 if (generator && funct["(generator)"] !== "yielded") {
3806 error("E047", state.tokens.curr);
3807 }
3808
3809 funct["(metrics)"].verifyMaxStatementsPerFunction();
3810 funct["(metrics)"].verifyMaxComplexityPerFunction();
3811 funct["(unusedOption)"] = state.option.unused;
3812
3813 scope = oldScope;
3814 state.option = oldOption;
3815 state.ignored = oldIgnored;
3816 funct["(last)"] = state.tokens.curr.line;
3817 funct["(lastcharacter)"] = state.tokens.curr.character;
3818 funct = funct["(context)"];
3819
3820 return f;
3821 }
3822
3823 function createMetrics(functionStartToken) {
3824 return {
3825 statementCount: 0,
3826 nestedBlockDepth: -1,
3827 ComplexityCount: 1,
3828 verifyMaxStatementsPerFunction: function () {
3829 if (state.option.maxstatements &&
3830 this.statementCount > state.option.maxstatements) {
3831 warning("W071", functionStartToken, this.statementCount);
3832 }
3833 },
3834
3835 verifyMaxParametersPerFunction: function (params) {
3836 params = params || [];
3837
3838 if (state.option.maxparams && params.length > state.option.maxparams) {
3839 warning("W072", functionStartToken, params.length);
3840 }
3841 },
3842
3843 verifyMaxNestedBlockDepthPerFunction: function () {
3844 if (state.option.maxdepth &&
3845 this.nestedBlockDepth > 0 &&
3846 this.nestedBlockDepth === state.option.maxdepth + 1) {
3847 warning("W073", null, this.nestedBlockDepth);
3848 }
3849 },
3850
3851 verifyMaxComplexityPerFunction: function () {
3852 var max = state.option.maxcomplexity;
3853 var cc = this.ComplexityCount;
3854 if (max && cc > max) {
3855 warning("W074", functionStartToken, cc);
3856 }
3857 }
3858 };
3859 }
3860
3861 function increaseComplexityCount() {
3862 funct["(metrics)"].ComplexityCount += 1;
3863 }
3864
3865 // Parse assignments that were found instead of conditionals.
3866 // For example: if (a = 1) { ... }
3867
3868 function checkCondAssignment(expr) {
3869 var id, paren;
3870 if (expr) {
3871 id = expr.id;
3872 paren = expr.paren;
3873 if (id === "," && (expr = expr.exprs[expr.exprs.length - 1])) {
3874 id = expr.id;
3875 paren = paren || expr.paren;
3876 }
3877 }
3878 switch (id) {
3879 case "=":
3880 case "+=":
3881 case "-=":
3882 case "*=":
3883 case "%=":
3884 case "&=":
3885 case "|=":
3886 case "^=":
3887 case "/=":
3888 if (!paren && !state.option.boss) {
3889 warning("W084");
3890 }
3891 }
3892 }
3893
3894
3895 (function (x) {
3896 x.nud = function (isclassdef) {
3897 var b, f, i, p, t, g;
3898 var props = {}; // All properties, including accessors
3899 var tag = "";
3900
3901 function saveProperty(name, tkn) {
3902 if (props[name] && _.has(props, name))
3903 warning("W075", state.tokens.next, i);
3904 else
3905 props[name] = {};
3906
3907 props[name].basic = true;
3908 props[name].basictkn = tkn;
3909 }
3910
3911 function saveSetter(name, tkn) {
3912 if (props[name] && _.has(props, name)) {
3913 if (props[name].basic || props[name].setter)
3914 warning("W075", state.tokens.next, i);
3915 } else {
3916 props[name] = {};
3917 }
3918
3919 props[name].setter = true;
3920 props[name].setterToken = tkn;
3921 }
3922
3923 function saveGetter(name) {
3924 if (props[name] && _.has(props, name)) {
3925 if (props[name].basic || props[name].getter)
3926 warning("W075", state.tokens.next, i);
3927 } else {
3928 props[name] = {};
3929 }
3930
3931 props[name].getter = true;
3932 props[name].getterToken = state.tokens.curr;
3933 }
3934
3935 b = state.tokens.curr.line !== state.tokens.next.line;
3936 if (b) {
3937 indent += state.option.indent;
3938 if (state.tokens.next.from === indent + state.option.indent) {
3939 indent += state.option.indent;
3940 }
3941 }
3942
3943 for (;;) {
3944 if (state.tokens.next.id === "}") {
3945 break;
3946 }
3947
3948 if (b) {
3949 indentation();
3950 }
3951
3952 if (isclassdef && state.tokens.next.value === "static") {
3953 advance("static");
3954 tag = "static ";
3955 }
3956
3957 if (state.tokens.next.value === "get" && peek().id !== ":") {
3958 advance("get");
3959
3960 if (!state.option.inES5(!isclassdef)) {
3961 error("E034");
3962 }
3963
3964 i = property_name();
3965 if (!i) {
3966 error("E035");
3967 }
3968
3969 // It is a Syntax Error if PropName of MethodDefinition is
3970 // "constructor" and SpecialMethod of MethodDefinition is true.
3971 if (isclassdef && i === "constructor") {
3972 error("E049", state.tokens.next, "class getter method", i);
3973 }
3974
3975 saveGetter(tag + i);
3976 t = state.tokens.next;
3977 adjacent(state.tokens.curr, state.tokens.next);
3978 f = doFunction();
3979 p = f["(params)"];
3980
3981 if (p) {
3982 warning("W076", t, p[0], i);
3983 }
3984
3985 adjacent(state.tokens.curr, state.tokens.next);
3986 } else if (state.tokens.next.value === "set" && peek().id !== ":") {
3987 advance("set");
3988
3989 if (!state.option.inES5(!isclassdef)) {
3990 error("E034");
3991 }
3992
3993 i = property_name();
3994 if (!i) {
3995 error("E035");
3996 }
3997
3998 // It is a Syntax Error if PropName of MethodDefinition is
3999 // "constructor" and SpecialMethod of MethodDefinition is true.
4000 if (isclassdef && i === "constructor") {
4001 error("E049", state.tokens.next, "class setter method", i);
4002 }
4003
4004 saveSetter(tag + i, state.tokens.next);
4005 t = state.tokens.next;
4006 adjacent(state.tokens.curr, state.tokens.next);
4007 f = doFunction();
4008 p = f["(params)"];
4009
4010 if (!p || p.length !== 1) {
4011 warning("W077", t, i);
4012 }
4013 } else {
4014 g = false;
4015 if (state.tokens.next.value === "*" && state.tokens.next.type === "(punctuator)") {
4016 if (!state.option.inESNext()) {
4017 warning("W104", state.tokens.next, "generator functions");
4018 }
4019 advance("*");
4020 g = true;
4021 }
4022 i = property_name();
4023 saveProperty(tag + i, state.tokens.next);
4024
4025 if (typeof i !== "string") {
4026 break;
4027 }
4028
4029 if (state.tokens.next.value === "(") {
4030 if (!state.option.inESNext()) {
4031 warning("W104", state.tokens.curr, "concise methods");
4032 }
4033 doFunction(i, undefined, g);
4034 } else if (!isclassdef) {
4035 advance(":");
4036 nonadjacent(state.tokens.curr, state.tokens.next);
4037 expression(10);
4038 }
4039 }
4040 // It is a Syntax Error if PropName of MethodDefinition is "prototype".
4041 if (isclassdef && i === "prototype") {
4042 error("E049", state.tokens.next, "class method", i);
4043 }
4044
4045 countMember(i);
4046 if (isclassdef) {
4047 tag = "";
4048 continue;
4049 }
4050 if (state.tokens.next.id === ",") {
4051 comma({ allowTrailing: true, property: true });
4052 if (state.tokens.next.id === ",") {
4053 warning("W070", state.tokens.curr);
4054 } else if (state.tokens.next.id === "}" && !state.option.inES5(true)) {
4055 warning("W070", state.tokens.curr);
4056 }
4057 } else {
4058 break;
4059 }
4060 }
4061 if (b) {
4062 indent -= state.option.indent;
4063 indentation();
4064 }
4065 advance("}", this);
4066
4067 // Check for lonely setters if in the ES5 mode.
4068 if (state.option.inES5()) {
4069 for (var name in props) {
4070 if (_.has(props, name) && props[name].setter && !props[name].getter) {
4071 warning("W078", props[name].setterToken);
4072 }
4073 }
4074 }
4075 return this;
4076 };
4077 x.fud = function () {
4078 error("E036", state.tokens.curr);
4079 };
4080 }(delim("{")));
4081
4082 function destructuringExpression() {
4083 var id, ids;
4084 var identifiers = [];
4085 if (!state.option.inESNext()) {
4086 warning("W104", state.tokens.curr, "destructuring expression");
4087 }
4088 var nextInnerDE = function () {
4089 var ident;
4090 if (_.contains(["[", "{"], state.tokens.next.value)) {
4091 ids = destructuringExpression();
4092 for (var id in ids) {
4093 id = ids[id];
4094 identifiers.push({ id: id.id, token: id.token });
4095 }
4096 } else if (state.tokens.next.value === ",") {
4097 identifiers.push({ id: null, token: state.tokens.curr });
4098 } else {
4099 ident = identifier();
4100 if (ident)
4101 identifiers.push({ id: ident, token: state.tokens.curr });
4102 }
4103 };
4104 if (state.tokens.next.value === "[") {
4105 advance("[");
4106 nextInnerDE();
4107 while (state.tokens.next.value !== "]") {
4108 advance(",");
4109 nextInnerDE();
4110 }
4111 advance("]");
4112 } else if (state.tokens.next.value === "{") {
4113 advance("{");
4114 id = identifier();
4115 if (state.tokens.next.value === ":") {
4116 advance(":");
4117 nextInnerDE();
4118 } else {
4119 identifiers.push({ id: id, token: state.tokens.curr });
4120 }
4121 while (state.tokens.next.value !== "}") {
4122 advance(",");
4123 id = identifier();
4124 if (state.tokens.next.value === ":") {
4125 advance(":");
4126 nextInnerDE();
4127 } else {
4128 identifiers.push({ id: id, token: state.tokens.curr });
4129 }
4130 }
4131 advance("}");
4132 }
4133 return identifiers;
4134 }
4135 function destructuringExpressionMatch(tokens, value) {
4136 if (value.first) {
4137 _.zip(tokens, value.first).forEach(function (val) {
4138 var token = val[0];
4139 var value = val[1];
4140 if (token && value) {
4141 token.first = value;
4142 } else if (token && token.first && !value) {
4143 warning("W080", token.first, token.first.value);
4144 } /* else {
4145 XXX value is discarded: wouldn't it need a warning ?
4146 } */
4147 });
4148 }
4149 }
4150
4151 var conststatement = stmt("const", function (prefix) {
4152 var tokens, value;
4153 // state variable to know if it is a lone identifier, or a destructuring statement.
4154 var lone;
4155
4156 if (!state.option.inESNext()) {
4157 warning("W104", state.tokens.curr, "const");
4158 }
4159
4160 this.first = [];
4161 for (;;) {
4162 var names = [];
4163 nonadjacent(state.tokens.curr, state.tokens.next);
4164 if (_.contains(["{", "["], state.tokens.next.value)) {
4165 tokens = destructuringExpression();
4166 lone = false;
4167 } else {
4168 tokens = [ { id: identifier(), token: state.tokens.curr } ];
4169 lone = true;
4170 }
4171 for (var t in tokens) {
4172 t = tokens[t];
4173 if (funct[t.id] === "const") {
4174 warning("E011", null, t.id);
4175 }
4176 if (funct["(global)"] && predefined[t.id] === false) {
4177 warning("W079", t.token, t.id);
4178 }
4179 if (t.id) {
4180 addlabel(t.id, "const");
4181 names.push(t.token);
4182 }
4183 }
4184 if (prefix) {
4185 break;
4186 }
4187
4188 this.first = this.first.concat(names);
4189
4190 if (state.tokens.next.id !== "=") {
4191 warning("E012", state.tokens.curr, state.tokens.curr.value);
4192 }
4193
4194 if (state.tokens.next.id === "=") {
4195 nonadjacent(state.tokens.curr, state.tokens.next);
4196 advance("=");
4197 nonadjacent(state.tokens.curr, state.tokens.next);
4198 if (state.tokens.next.id === "undefined") {
4199 warning("W080", state.tokens.prev, state.tokens.prev.value);
4200 }
4201 if (peek(0).id === "=" && state.tokens.next.identifier) {
4202 warning("W120", state.tokens.next, state.tokens.next.value);
4203 }
4204 value = expression(10);
4205 if (lone) {
4206 tokens[0].first = value;
4207 } else {
4208 destructuringExpressionMatch(names, value);
4209 }
4210 }
4211
4212 if (state.tokens.next.id !== ",") {
4213 break;
4214 }
4215 comma();
4216 }
4217 return this;
4218 });
4219 conststatement.exps = true;
4220 var varstatement = stmt("var", function (prefix) {
4221 // JavaScript does not have block scope. It only has function scope. So,
4222 // declaring a variable in a block can have unexpected consequences.
4223 var tokens, lone, value;
4224
4225 if (funct["(onevar)"] && state.option.onevar) {
4226 warning("W081");
4227 } else if (!funct["(global)"]) {
4228 funct["(onevar)"] = true;
4229 }
4230
4231 this.first = [];
4232 for (;;) {
4233 var names = [];
4234 nonadjacent(state.tokens.curr, state.tokens.next);
4235 if (_.contains(["{", "["], state.tokens.next.value)) {
4236 tokens = destructuringExpression();
4237 lone = false;
4238 } else {
4239 tokens = [ { id: identifier(), token: state.tokens.curr } ];
4240 lone = true;
4241 }
4242 for (var t in tokens) {
4243 t = tokens[t];
4244 if (state.option.inESNext() && funct[t.id] === "const") {
4245 warning("E011", null, t.id);
4246 }
4247 if (funct["(global)"] && predefined[t.id] === false) {
4248 warning("W079", t.token, t.id);
4249 }
4250 if (t.id) {
4251 addlabel(t.id, "unused", t.token);
4252 names.push(t.token);
4253 }
4254 }
4255 if (prefix) {
4256 break;
4257 }
4258
4259 this.first = this.first.concat(names);
4260
4261 if (state.tokens.next.id === "=") {
4262 nonadjacent(state.tokens.curr, state.tokens.next);
4263 advance("=");
4264 nonadjacent(state.tokens.curr, state.tokens.next);
4265 if (state.tokens.next.id === "undefined") {
4266 warning("W080", state.tokens.prev, state.tokens.prev.value);
4267 }
4268 if (peek(0).id === "=" && state.tokens.next.identifier) {
4269 warning("W120", state.tokens.next, state.tokens.next.value);
4270 }
4271 value = expression(10);
4272 if (lone) {
4273 tokens[0].first = value;
4274 } else {
4275 destructuringExpressionMatch(names, value);
4276 }
4277 }
4278
4279 if (state.tokens.next.id !== ",") {
4280 break;
4281 }
4282 comma();
4283 }
4284 return this;
4285 });
4286 varstatement.exps = true;
4287 var letstatement = stmt("let", function (prefix) {
4288 var tokens, lone, value, letblock;
4289
4290 if (!state.option.inESNext()) {
4291 warning("W104", state.tokens.curr, "let");
4292 }
4293
4294 if (state.tokens.next.value === "(") {
4295 if (!state.option.inMoz(true)) {
4296 warning("W118", state.tokens.next, "let block");
4297 }
4298 advance("(");
4299 funct["(blockscope)"].stack();
4300 letblock = true;
4301 } else if (funct["(nolet)"]) {
4302 error("E048", state.tokens.curr);
4303 }
4304
4305 if (funct["(onevar)"] && state.option.onevar) {
4306 warning("W081");
4307 } else if (!funct["(global)"]) {
4308 funct["(onevar)"] = true;
4309 }
4310
4311 this.first = [];
4312 for (;;) {
4313 var names = [];
4314 nonadjacent(state.tokens.curr, state.tokens.next);
4315 if (_.contains(["{", "["], state.tokens.next.value)) {
4316 tokens = destructuringExpression();
4317 lone = false;
4318 } else {
4319 tokens = [ { id: identifier(), token: state.tokens.curr.value } ];
4320 lone = true;
4321 }
4322 for (var t in tokens) {
4323 t = tokens[t];
4324 if (state.option.inESNext() && funct[t.id] === "const") {
4325 warning("E011", null, t.id);
4326 }
4327 if (funct["(global)"] && predefined[t.id] === false) {
4328 warning("W079", t.token, t.id);
4329 }
4330 if (t.id && !funct["(nolet)"]) {
4331 addlabel(t.id, "unused", t.token, true);
4332 names.push(t.token);
4333 }
4334 }
4335 if (prefix) {
4336 break;
4337 }
4338
4339 this.first = this.first.concat(names);
4340
4341 if (state.tokens.next.id === "=") {
4342 nonadjacent(state.tokens.curr, state.tokens.next);
4343 advance("=");
4344 nonadjacent(state.tokens.curr, state.tokens.next);
4345 if (state.tokens.next.id === "undefined") {
4346 warning("W080", state.tokens.prev, state.tokens.prev.value);
4347 }
4348 if (peek(0).id === "=" && state.tokens.next.identifier) {
4349 warning("W120", state.tokens.next, state.tokens.next.value);
4350 }
4351 value = expression(10);
4352 if (lone) {
4353 tokens[0].first = value;
4354 } else {
4355 destructuringExpressionMatch(names, value);
4356 }
4357 }
4358
4359 if (state.tokens.next.id !== ",") {
4360 break;
4361 }
4362 comma();
4363 }
4364 if (letblock) {
4365 advance(")");
4366 block(true, true);
4367 this.block = true;
4368 funct["(blockscope)"].unstack();
4369 }
4370
4371 return this;
4372 });
4373 letstatement.exps = true;
4374
4375 blockstmt("class", function () {
4376 return classdef.call(this, true);
4377 });
4378
4379 function classdef(stmt) {
4380 /*jshint validthis:true */
4381 if (!state.option.inESNext()) {
4382 warning("W104", state.tokens.curr, "class");
4383 }
4384 if (stmt) {
4385 // BindingIdentifier
4386 this.name = identifier();
4387 addlabel(this.name, "unused", state.tokens.curr);
4388 } else if (state.tokens.next.identifier && state.tokens.next.value !== "extends") {
4389 // BindingIdentifier(opt)
4390 this.name = identifier();
4391 }
4392 classtail(this);
4393 return this;
4394 }
4395
4396 function classtail(c) {
4397 var strictness = state.directive["use strict"];
4398
4399 // ClassHeritage(opt)
4400 if (state.tokens.next.value === "extends") {
4401 advance("extends");
4402 c.heritage = expression(10);
4403 }
4404
4405 // A ClassBody is always strict code.
4406 state.directive["use strict"] = true;
4407 advance("{");
4408 // ClassBody(opt)
4409 c.body = state.syntax["{"].nud(true);
4410 state.directive["use strict"] = strictness;
4411 }
4412
4413 blockstmt("function", function () {
4414 var generator = false;
4415 if (state.tokens.next.value === "*") {
4416 advance("*");
4417 if (state.option.inESNext(true)) {
4418 generator = true;
4419 } else {
4420 warning("W119", state.tokens.curr, "function*");
4421 }
4422 }
4423 if (inblock) {
4424 warning("W082", state.tokens.curr);
4425
4426 }
4427 var i = identifier();
4428 if (funct[i] === "const") {
4429 warning("E011", null, i);
4430 }
4431 adjacent(state.tokens.curr, state.tokens.next);
4432 addlabel(i, "unction", state.tokens.curr);
4433
4434 doFunction(i, { statement: true }, generator);
4435 if (state.tokens.next.id === "(" && state.tokens.next.line === state.tokens.curr.line) {
4436 error("E039");
4437 }
4438 return this;
4439 });
4440
4441 prefix("function", function () {
4442 var generator = false;
4443 if (state.tokens.next.value === "*") {
4444 if (!state.option.inESNext()) {
4445 warning("W119", state.tokens.curr, "function*");
4446 }
4447 advance("*");
4448 generator = true;
4449 }
4450 var i = optionalidentifier();
4451 if (i || state.option.gcl) {
4452 adjacent(state.tokens.curr, state.tokens.next);
4453 } else {
4454 nonadjacent(state.tokens.curr, state.tokens.next);
4455 }
4456 doFunction(i, undefined, generator);
4457 if (!state.option.loopfunc && funct["(loopage)"]) {
4458 warning("W083");
4459 }
4460 return this;
4461 });
4462
4463 blockstmt("if", function () {
4464 var t = state.tokens.next;
4465 increaseComplexityCount();
4466 state.condition = true;
4467 advance("(");
4468 nonadjacent(this, t);
4469 nospace();
4470 checkCondAssignment(expression(0));
4471 advance(")", t);
4472 state.condition = false;
4473 nospace(state.tokens.prev, state.tokens.curr);
4474 block(true, true);
4475 if (state.tokens.next.id === "else") {
4476 nonadjacent(state.tokens.curr, state.tokens.next);
4477 advance("else");
4478 if (state.tokens.next.id === "if" || state.tokens.next.id === "switch") {
4479 statement(true);
4480 } else {
4481 block(true, true);
4482 }
4483 }
4484 return this;
4485 });
4486
4487 blockstmt("try", function () {
4488 var b;
4489
4490 function doCatch() {
4491 var oldScope = scope;
4492 var e;
4493
4494 advance("catch");
4495 nonadjacent(state.tokens.curr, state.tokens.next);
4496 advance("(");
4497
4498 scope = Object.create(oldScope);
4499
4500 e = state.tokens.next.value;
4501 if (state.tokens.next.type !== "(identifier)") {
4502 e = null;
4503 warning("E030", state.tokens.next, e);
4504 }
4505
4506 advance();
4507
4508 funct = {
4509 "(name)" : "(catch)",
4510 "(line)" : state.tokens.next.line,
4511 "(character)": state.tokens.next.character,
4512 "(context)" : funct,
4513 "(breakage)" : funct["(breakage)"],
4514 "(loopage)" : funct["(loopage)"],
4515 "(scope)" : scope,
4516 "(statement)": false,
4517 "(metrics)" : createMetrics(state.tokens.next),
4518 "(catch)" : true,
4519 "(tokens)" : {},
4520 "(blockscope)": funct["(blockscope)"],
4521 "(comparray)": funct["(comparray)"]
4522 };
4523
4524 if (e) {
4525 addlabel(e, "exception");
4526 }
4527
4528 if (state.tokens.next.value === "if") {
4529 if (!state.option.inMoz(true)) {
4530 warning("W118", state.tokens.curr, "catch filter");
4531 }
4532 advance("if");
4533 expression(0);
4534 }
4535
4536 advance(")");
4537
4538 state.tokens.curr.funct = funct;
4539 functions.push(funct);
4540
4541 block(false);
4542
4543 scope = oldScope;
4544
4545 funct["(last)"] = state.tokens.curr.line;
4546 funct["(lastcharacter)"] = state.tokens.curr.character;
4547 funct = funct["(context)"];
4548 }
4549
4550 block(false);
4551
4552 while (state.tokens.next.id === "catch") {
4553 increaseComplexityCount();
4554 if (b && (!state.option.inMoz(true))) {
4555 warning("W118", state.tokens.next, "multiple catch blocks");
4556 }
4557 doCatch();
4558 b = true;
4559 }
4560
4561 if (state.tokens.next.id === "finally") {
4562 advance("finally");
4563 block(false);
4564 return;
4565 }
4566
4567 if (!b) {
4568 error("E021", state.tokens.next, "catch", state.tokens.next.value);
4569 }
4570
4571 return this;
4572 });
4573
4574 blockstmt("while", function () {
4575 var t = state.tokens.next;
4576 funct["(breakage)"] += 1;
4577 funct["(loopage)"] += 1;
4578 increaseComplexityCount();
4579 advance("(");
4580 nonadjacent(this, t);
4581 nospace();
4582 checkCondAssignment(expression(0));
4583 advance(")", t);
4584 nospace(state.tokens.prev, state.tokens.curr);
4585 block(true, true);
4586 funct["(breakage)"] -= 1;
4587 funct["(loopage)"] -= 1;
4588 return this;
4589 }).labelled = true;
4590
4591 blockstmt("with", function () {
4592 var t = state.tokens.next;
4593 if (state.directive["use strict"]) {
4594 error("E010", state.tokens.curr);
4595 } else if (!state.option.withstmt) {
4596 warning("W085", state.tokens.curr);
4597 }
4598
4599 advance("(");
4600 nonadjacent(this, t);
4601 nospace();
4602 expression(0);
4603 advance(")", t);
4604 nospace(state.tokens.prev, state.tokens.curr);
4605 block(true, true);
4606
4607 return this;
4608 });
4609
4610 blockstmt("switch", function () {
4611 var t = state.tokens.next,
4612 g = false;
4613 funct["(breakage)"] += 1;
4614 advance("(");
4615 nonadjacent(this, t);
4616 nospace();
4617 checkCondAssignment(expression(0));
4618 advance(")", t);
4619 nospace(state.tokens.prev, state.tokens.curr);
4620 nonadjacent(state.tokens.curr, state.tokens.next);
4621 t = state.tokens.next;
4622 advance("{");
4623 nonadjacent(state.tokens.curr, state.tokens.next);
4624 indent += state.option.indent;
4625 this.cases = [];
4626
4627 for (;;) {
4628 switch (state.tokens.next.id) {
4629 case "case":
4630 switch (funct["(verb)"]) {
4631 case "yield":
4632 case "break":
4633 case "case":
4634 case "continue":
4635 case "return":
4636 case "switch":
4637 case "throw":
4638 break;
4639 default:
4640 // You can tell JSHint that you don't use break intentionally by
4641 // adding a comment /* falls through */ on a line just before
4642 // the next `case`.
4643 if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) {
4644 warning("W086", state.tokens.curr, "case");
4645 }
4646 }
4647 indentation(-state.option.indent);
4648 advance("case");
4649 this.cases.push(expression(20));
4650 increaseComplexityCount();
4651 g = true;
4652 advance(":");
4653 funct["(verb)"] = "case";
4654 break;
4655 case "default":
4656 switch (funct["(verb)"]) {
4657 case "yield":
4658 case "break":
4659 case "continue":
4660 case "return":
4661 case "throw":
4662 break;
4663 default:
4664 // Do not display a warning if 'default' is the first statement or if
4665 // there is a special /* falls through */ comment.
4666 if (this.cases.length) {
4667 if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) {
4668 warning("W086", state.tokens.curr, "default");
4669 }
4670 }
4671 }
4672 indentation(-state.option.indent);
4673 advance("default");
4674 g = true;
4675 advance(":");
4676 break;
4677 case "}":
4678 indent -= state.option.indent;
4679 indentation();
4680 advance("}", t);
4681 funct["(breakage)"] -= 1;
4682 funct["(verb)"] = undefined;
4683 return;
4684 case "(end)":
4685 error("E023", state.tokens.next, "}");
4686 return;
4687 default:
4688 if (g) {
4689 switch (state.tokens.curr.id) {
4690 case ",":
4691 error("E040");
4692 return;
4693 case ":":
4694 g = false;
4695 statements();
4696 break;
4697 default:
4698 error("E025", state.tokens.curr);
4699 return;
4700 }
4701 } else {
4702 if (state.tokens.curr.id === ":") {
4703 advance(":");
4704 error("E024", state.tokens.curr, ":");
4705 statements();
4706 } else {
4707 error("E021", state.tokens.next, "case", state.tokens.next.value);
4708 return;
4709 }
4710 }
4711 }
4712 }
4713 }).labelled = true;
4714
4715 stmt("debugger", function () {
4716 if (!state.option.debug) {
4717 warning("W087");
4718 }
4719 return this;
4720 }).exps = true;
4721
4722 (function () {
4723 var x = stmt("do", function () {
4724 funct["(breakage)"] += 1;
4725 funct["(loopage)"] += 1;
4726 increaseComplexityCount();
4727
4728 this.first = block(true, true);
4729 advance("while");
4730 var t = state.tokens.next;
4731 nonadjacent(state.tokens.curr, t);
4732 advance("(");
4733 nospace();
4734 checkCondAssignment(expression(0));
4735 advance(")", t);
4736 nospace(state.tokens.prev, state.tokens.curr);
4737 funct["(breakage)"] -= 1;
4738 funct["(loopage)"] -= 1;
4739 return this;
4740 });
4741 x.labelled = true;
4742 x.exps = true;
4743 }());
4744
4745 blockstmt("for", function () {
4746 var s, t = state.tokens.next;
4747 var letscope = false;
4748 var foreachtok = null;
4749
4750 if (t.value === "each") {
4751 foreachtok = t;
4752 advance("each");
4753 if (!state.option.inMoz(true)) {
4754 warning("W118", state.tokens.curr, "for each");
4755 }
4756 }
4757
4758 funct["(breakage)"] += 1;
4759 funct["(loopage)"] += 1;
4760 increaseComplexityCount();
4761 advance("(");
4762 nonadjacent(this, t);
4763 nospace();
4764
4765 // what kind of for(…) statement it is? for(…of…)? for(…in…)? for(…;…;…)?
4766 var nextop; // contains the token of the "in" or "of" operator
4767 var i = 0;
4768 var inof = ["in", "of"];
4769 do {
4770 nextop = peek(i);
4771 ++i;
4772 } while (!_.contains(inof, nextop.value) && nextop.value !== ";" &&
4773 nextop.type !== "(end)");
4774
4775 // if we're in a for (… in|of …) statement
4776 if (_.contains(inof, nextop.value)) {
4777 if (!state.option.inESNext() && nextop.value === "of") {
4778 error("W104", nextop, "for of");
4779 }
4780 if (state.tokens.next.id === "var") {
4781 advance("var");
4782 state.syntax["var"].fud.call(state.syntax["var"].fud, true);
4783 } else if (state.tokens.next.id === "let") {
4784 advance("let");
4785 // create a new block scope
4786 letscope = true;
4787 funct["(blockscope)"].stack();
4788 state.syntax["let"].fud.call(state.syntax["let"].fud, true);
4789 } else {
4790 switch (funct[state.tokens.next.value]) {
4791 case "unused":
4792 funct[state.tokens.next.value] = "var";
4793 break;
4794 case "var":
4795 break;
4796 default:
4797 if (!funct["(blockscope)"].getlabel(state.tokens.next.value))
4798 warning("W088", state.tokens.next, state.tokens.next.value);
4799 }
4800 advance();
4801 }
4802 advance(nextop.value);
4803 expression(20);
4804 advance(")", t);
4805 s = block(true, true);
4806 if (state.option.forin && s && (s.length > 1 || typeof s[0] !== "object" ||
4807 s[0].value !== "if")) {
4808 warning("W089", this);
4809 }
4810 funct["(breakage)"] -= 1;
4811 funct["(loopage)"] -= 1;
4812 } else {
4813 if (foreachtok) {
4814 error("E045", foreachtok);
4815 }
4816 if (state.tokens.next.id !== ";") {
4817 if (state.tokens.next.id === "var") {
4818 advance("var");
4819 state.syntax["var"].fud.call(state.syntax["var"].fud);
4820 } else if (state.tokens.next.id === "let") {
4821 advance("let");
4822 // create a new block scope
4823 letscope = true;
4824 funct["(blockscope)"].stack();
4825 state.syntax["let"].fud.call(state.syntax["let"].fud);
4826 } else {
4827 for (;;) {
4828 expression(0, "for");
4829 if (state.tokens.next.id !== ",") {
4830 break;
4831 }
4832 comma();
4833 }
4834 }
4835 }
4836 nolinebreak(state.tokens.curr);
4837 advance(";");
4838 if (state.tokens.next.id !== ";") {
4839 checkCondAssignment(expression(0));
4840 }
4841 nolinebreak(state.tokens.curr);
4842 advance(";");
4843 if (state.tokens.next.id === ";") {
4844 error("E021", state.tokens.next, ")", ";");
4845 }
4846 if (state.tokens.next.id !== ")") {
4847 for (;;) {
4848 expression(0, "for");
4849 if (state.tokens.next.id !== ",") {
4850 break;
4851 }
4852 comma();
4853 }
4854 }
4855 advance(")", t);
4856 nospace(state.tokens.prev, state.tokens.curr);
4857 block(true, true);
4858 funct["(breakage)"] -= 1;
4859 funct["(loopage)"] -= 1;
4860
4861 }
4862 // unstack loop blockscope
4863 if (letscope) {
4864 funct["(blockscope)"].unstack();
4865 }
4866 return this;
4867 }).labelled = true;
4868
4869
4870 stmt("break", function () {
4871 var v = state.tokens.next.value;
4872
4873 if (funct["(breakage)"] === 0)
4874 warning("W052", state.tokens.next, this.value);
4875
4876 if (!state.option.asi)
4877 nolinebreak(this);
4878
4879 if (state.tokens.next.id !== ";" && !state.tokens.next.reach) {
4880 if (state.tokens.curr.line === state.tokens.next.line) {
4881 if (funct[v] !== "label") {
4882 warning("W090", state.tokens.next, v);
4883 } else if (scope[v] !== funct) {
4884 warning("W091", state.tokens.next, v);
4885 }
4886 this.first = state.tokens.next;
4887 advance();
4888 }
4889 }
4890 reachable("break");
4891 return this;
4892 }).exps = true;
4893
4894
4895 stmt("continue", function () {
4896 var v = state.tokens.next.value;
4897
4898 if (funct["(breakage)"] === 0)
4899 warning("W052", state.tokens.next, this.value);
4900
4901 if (!state.option.asi)
4902 nolinebreak(this);
4903
4904 if (state.tokens.next.id !== ";" && !state.tokens.next.reach) {
4905 if (state.tokens.curr.line === state.tokens.next.line) {
4906 if (funct[v] !== "label") {
4907 warning("W090", state.tokens.next, v);
4908 } else if (scope[v] !== funct) {
4909 warning("W091", state.tokens.next, v);
4910 }
4911 this.first = state.tokens.next;
4912 advance();
4913 }
4914 } else if (!funct["(loopage)"]) {
4915 warning("W052", state.tokens.next, this.value);
4916 }
4917 reachable("continue");
4918 return this;
4919 }).exps = true;
4920
4921
4922 stmt("return", function () {
4923 if (this.line === state.tokens.next.line) {
4924 if (state.tokens.next.id === "(regexp)")
4925 warning("W092");
4926
4927 if (state.tokens.next.id !== ";" && !state.tokens.next.reach) {
4928 nonadjacent(state.tokens.curr, state.tokens.next);
4929 this.first = expression(0);
4930
4931 if (this.first &&
4932 this.first.type === "(punctuator)" && this.first.value === "=" && !state.option.boss) {
4933 warningAt("W093", this.first.line, this.first.character);
4934 }
4935 }
4936 } else {
4937 if (state.tokens.next.type === "(punctuator)" &&
4938 ["[", "{", "+", "-"].indexOf(state.tokens.next.value) > -1) {
4939 nolinebreak(this); // always warn (Line breaking error)
4940 }
4941 }
4942 reachable("return");
4943 return this;
4944 }).exps = true;
4945
4946 (function (x) {
4947 x.exps = true;
4948 x.lbp = 25;
4949 }(prefix("yield", function () {
4950 var prev = state.tokens.prev;
4951 if (state.option.inESNext(true) && !funct["(generator)"]) {
4952 error("E046", state.tokens.curr, "yield");
4953 } else if (!state.option.inESNext()) {
4954 warning("W104", state.tokens.curr, "yield");
4955 }
4956 funct["(generator)"] = "yielded";
4957 if (this.line === state.tokens.next.line || !state.option.inMoz(true)) {
4958 if (state.tokens.next.id === "(regexp)")
4959 warning("W092");
4960
4961 if (state.tokens.next.id !== ";" && !state.tokens.next.reach && state.tokens.next.nud) {
4962 nobreaknonadjacent(state.tokens.curr, state.tokens.next);
4963 this.first = expression(10);
4964
4965 if (this.first.type === "(punctuator)" && this.first.value === "=" && !state.option.boss) {
4966 warningAt("W093", this.first.line, this.first.character);
4967 }
4968 }
4969
4970 if (state.option.inMoz(true) && state.tokens.next.id !== ")" &&
4971 (prev.lbp > 30 || (!prev.assign && !isEndOfExpr()) || prev.id === "yield")) {
4972 error("E050", this);
4973 }
4974 } else if (!state.option.asi) {
4975 nolinebreak(this); // always warn (Line breaking error)
4976 }
4977 return this;
4978 })));
4979
4980
4981 stmt("throw", function () {
4982 nolinebreak(this);
4983 nonadjacent(state.tokens.curr, state.tokens.next);
4984 this.first = expression(20);
4985 reachable("throw");
4986 return this;
4987 }).exps = true;
4988
4989 stmt("import", function () {
4990 if (!state.option.inESNext()) {
4991 warning("W119", state.tokens.curr, "import");
4992 }
4993
4994 if (state.tokens.next.identifier) {
4995 this.name = identifier();
4996 addlabel(this.name, "unused", state.tokens.curr);
4997 } else {
4998 advance("{");
4999 for (;;) {
5000 var importName;
5001 if (state.tokens.next.type === "default") {
5002 importName = "default";
5003 advance("default");
5004 } else {
5005 importName = identifier();
5006 }
5007 if (state.tokens.next.value === "as") {
5008 advance("as");
5009 importName = identifier();
5010 }
5011 addlabel(importName, "unused", state.tokens.curr);
5012
5013 if (state.tokens.next.value === ",") {
5014 advance(",");
5015 } else if (state.tokens.next.value === "}") {
5016 advance("}");
5017 break;
5018 } else {
5019 error("E024", state.tokens.next, state.tokens.next.value);
5020 break;
5021 }
5022 }
5023 }
5024
5025 advance("from");
5026 advance("(string)");
5027 return this;
5028 }).exps = true;
5029
5030 stmt("export", function () {
5031 if (!state.option.inESNext()) {
5032 warning("W119", state.tokens.curr, "export");
5033 }
5034
5035 if (state.tokens.next.type === "default") {
5036 advance("default");
5037 if (state.tokens.next.id === "function" || state.tokens.next.id === "class") {
5038 this.block = true;
5039 }
5040 this.exportee = expression(10);
5041
5042 return this;
5043 }
5044
5045 if (state.tokens.next.value === "{") {
5046 advance("{");
5047 for (;;) {
5048 identifier();
5049
5050 if (state.tokens.next.value === ",") {
5051 advance(",");
5052 } else if (state.tokens.next.value === "}") {
5053 advance("}");
5054 break;
5055 } else {
5056 error("E024", state.tokens.next, state.tokens.next.value);
5057 break;
5058 }
5059 }
5060 return this;
5061 }
5062
5063 if (state.tokens.next.id === "var") {
5064 advance("var");
5065 state.syntax["var"].fud.call(state.syntax["var"].fud);
5066 } else if (state.tokens.next.id === "let") {
5067 advance("let");
5068 state.syntax["let"].fud.call(state.syntax["let"].fud);
5069 } else if (state.tokens.next.id === "const") {
5070 advance("const");
5071 state.syntax["const"].fud.call(state.syntax["const"].fud);
5072 } else if (state.tokens.next.id === "function") {
5073 this.block = true;
5074 advance("function");
5075 state.syntax["function"].fud();
5076 } else if (state.tokens.next.id === "class") {
5077 this.block = true;
5078 advance("class");
5079 state.syntax["class"].fud();
5080 } else {
5081 error("E024", state.tokens.next, state.tokens.next.value);
5082 }
5083
5084 return this;
5085 }).exps = true;
5086
5087 // Future Reserved Words
5088
5089 FutureReservedWord("abstract");
5090 FutureReservedWord("boolean");
5091 FutureReservedWord("byte");
5092 FutureReservedWord("char");
5093 FutureReservedWord("class", { es5: true, nud: classdef });
5094 FutureReservedWord("double");
5095 FutureReservedWord("enum", { es5: true });
5096 FutureReservedWord("export", { es5: true });
5097 FutureReservedWord("extends", { es5: true });
5098 FutureReservedWord("final");
5099 FutureReservedWord("float");
5100 FutureReservedWord("goto");
5101 FutureReservedWord("implements", { es5: true, strictOnly: true });
5102 FutureReservedWord("import", { es5: true });
5103 FutureReservedWord("int");
5104 FutureReservedWord("interface", { es5: true, strictOnly: true });
5105 FutureReservedWord("long");
5106 FutureReservedWord("native");
5107 FutureReservedWord("package", { es5: true, strictOnly: true });
5108 FutureReservedWord("private", { es5: true, strictOnly: true });
5109 FutureReservedWord("protected", { es5: true, strictOnly: true });
5110 FutureReservedWord("public", { es5: true, strictOnly: true });
5111 FutureReservedWord("short");
5112 FutureReservedWord("static", { es5: true, strictOnly: true });
5113 FutureReservedWord("super", { es5: true });
5114 FutureReservedWord("synchronized");
5115 FutureReservedWord("throws");
5116 FutureReservedWord("transient");
5117 FutureReservedWord("volatile");
5118
5119 // this function is used to determine wether a squarebracket or a curlybracket
5120 // expression is a comprehension array, destructuring assignment or a json value.
5121
5122 var lookupBlockType = function () {
5123 var pn, pn1;
5124 var i = 0;
5125 var bracketStack = 0;
5126 var ret = {};
5127 if (_.contains(["[", "{"], state.tokens.curr.value))
5128 bracketStack += 1;
5129 if (_.contains(["[", "{"], state.tokens.next.value))
5130 bracketStack += 1;
5131 if (_.contains(["]", "}"], state.tokens.next.value))
5132 bracketStack -= 1;
5133 do {
5134 pn = peek(i);
5135 pn1 = peek(i + 1);
5136 i = i + 1;
5137 if (_.contains(["[", "{"], pn.value)) {
5138 bracketStack += 1;
5139 } else if (_.contains(["]", "}"], pn.value)) {
5140 bracketStack -= 1;
5141 }
5142 if (pn.identifier && pn.value === "for" && bracketStack === 1) {
5143 ret.isCompArray = true;
5144 ret.notJson = true;
5145 break;
5146 }
5147 if (_.contains(["}", "]"], pn.value) && pn1.value === "=") {
5148 ret.isDestAssign = true;
5149 ret.notJson = true;
5150 break;
5151 }
5152 if (pn.value === ";") {
5153 ret.isBlock = true;
5154 ret.notJson = true;
5155 }
5156 } while (bracketStack > 0 && pn.id !== "(end)" && i < 15);
5157 return ret;
5158 };
5159
5160 // Check whether this function has been reached for a destructuring assign with undeclared values
5161 function destructuringAssignOrJsonValue() {
5162 // lookup for the assignment (esnext only)
5163 // if it has semicolons, it is a block, so go parse it as a block
5164 // or it's not a block, but there are assignments, check for undeclared variables
5165
5166 var block = lookupBlockType();
5167 if (block.notJson) {
5168 if (!state.option.inESNext() && block.isDestAssign) {
5169 warning("W104", state.tokens.curr, "destructuring assignment");
5170 }
5171 statements();
5172 // otherwise parse json value
5173 } else {
5174 state.option.laxbreak = true;
5175 state.jsonMode = true;
5176 jsonValue();
5177 }
5178 }
5179
5180 // array comprehension parsing function
5181 // parses and defines the three states of the list comprehension in order
5182 // to avoid defining global variables, but keeping them to the list comprehension scope
5183 // only. The order of the states are as follows:
5184 // * "use" which will be the returned iterative part of the list comprehension
5185 // * "define" which will define the variables local to the list comprehension
5186 // * "filter" which will help filter out values
5187
5188 var arrayComprehension = function () {
5189 var CompArray = function () {
5190 this.mode = "use";
5191 this.variables = [];
5192 };
5193 var _carrays = [];
5194 var _current;
5195 function declare(v) {
5196 var l = _current.variables.filter(function (elt) {
5197 // if it has, change its undef state
5198 if (elt.value === v) {
5199 elt.undef = false;
5200 return v;
5201 }
5202 }).length;
5203 return l !== 0;
5204 }
5205 function use(v) {
5206 var l = _current.variables.filter(function (elt) {
5207 // and if it has been defined
5208 if (elt.value === v && !elt.undef) {
5209 if (elt.unused === true) {
5210 elt.unused = false;
5211 }
5212 return v;
5213 }
5214 }).length;
5215 // otherwise we warn about it
5216 return (l === 0);
5217 }
5218 return {stack: function () {
5219 _current = new CompArray();
5220 _carrays.push(_current);
5221 },
5222 unstack: function () {
5223 _current.variables.filter(function (v) {
5224 if (v.unused)
5225 warning("W098", v.token, v.value);
5226 if (v.undef)
5227 isundef(v.funct, "W117", v.token, v.value);
5228 });
5229 _carrays.splice(_carrays[_carrays.length - 1], 1);
5230 _current = _carrays[_carrays.length - 1];
5231 },
5232 setState: function (s) {
5233 if (_.contains(["use", "define", "filter"], s))
5234 _current.mode = s;
5235 },
5236 check: function (v) {
5237 // When we are in "use" state of the list comp, we enqueue that var
5238 if (_current && _current.mode === "use") {
5239 _current.variables.push({funct: funct,
5240 token: state.tokens.curr,
5241 value: v,
5242 undef: true,
5243 unused: false});
5244 return true;
5245 // When we are in "define" state of the list comp,
5246 } else if (_current && _current.mode === "define") {
5247 // check if the variable has been used previously
5248 if (!declare(v)) {
5249 _current.variables.push({funct: funct,
5250 token: state.tokens.curr,
5251 value: v,
5252 undef: false,
5253 unused: true});
5254 }
5255 return true;
5256 // When we are in "filter" state,
5257 } else if (_current && _current.mode === "filter") {
5258 // we check whether current variable has been declared
5259 if (use(v)) {
5260 // if not we warn about it
5261 isundef(funct, "W117", state.tokens.curr, v);
5262 }
5263 return true;
5264 }
5265 return false;
5266 }
5267 };
5268 };
5269
5270
5271 // Parse JSON
5272
5273 function jsonValue() {
5274
5275 function jsonObject() {
5276 var o = {}, t = state.tokens.next;
5277 advance("{");
5278 if (state.tokens.next.id !== "}") {
5279 for (;;) {
5280 if (state.tokens.next.id === "(end)") {
5281 error("E026", state.tokens.next, t.line);
5282 } else if (state.tokens.next.id === "}") {
5283 warning("W094", state.tokens.curr);
5284 break;
5285 } else if (state.tokens.next.id === ",") {
5286 error("E028", state.tokens.next);
5287 } else if (state.tokens.next.id !== "(string)") {
5288 warning("W095", state.tokens.next, state.tokens.next.value);
5289 }
5290 if (o[state.tokens.next.value] === true) {
5291 warning("W075", state.tokens.next, state.tokens.next.value);
5292 } else if ((state.tokens.next.value === "__proto__" &&
5293 !state.option.proto) || (state.tokens.next.value === "__iterator__" &&
5294 !state.option.iterator)) {
5295 warning("W096", state.tokens.next, state.tokens.next.value);
5296 } else {
5297 o[state.tokens.next.value] = true;
5298 }
5299 advance();
5300 advance(":");
5301 jsonValue();
5302 if (state.tokens.next.id !== ",") {
5303 break;
5304 }
5305 advance(",");
5306 }
5307 }
5308 advance("}");
5309 }
5310
5311 function jsonArray() {
5312 var t = state.tokens.next;
5313 advance("[");
5314 if (state.tokens.next.id !== "]") {
5315 for (;;) {
5316 if (state.tokens.next.id === "(end)") {
5317 error("E027", state.tokens.next, t.line);
5318 } else if (state.tokens.next.id === "]") {
5319 warning("W094", state.tokens.curr);
5320 break;
5321 } else if (state.tokens.next.id === ",") {
5322 error("E028", state.tokens.next);
5323 }
5324 jsonValue();
5325 if (state.tokens.next.id !== ",") {
5326 break;
5327 }
5328 advance(",");
5329 }
5330 }
5331 advance("]");
5332 }
5333
5334 switch (state.tokens.next.id) {
5335 case "{":
5336 jsonObject();
5337 break;
5338 case "[":
5339 jsonArray();
5340 break;
5341 case "true":
5342 case "false":
5343 case "null":
5344 case "(number)":
5345 case "(string)":
5346 advance();
5347 break;
5348 case "-":
5349 advance("-");
5350 if (state.tokens.curr.character !== state.tokens.next.from) {
5351 warning("W011", state.tokens.curr);
5352 }
5353 adjacent(state.tokens.curr, state.tokens.next);
5354 advance("(number)");
5355 break;
5356 default:
5357 error("E003", state.tokens.next);
5358 }
5359 }
5360
5361 var blockScope = function () {
5362 var _current = {};
5363 var _variables = [_current];
5364
5365 function _checkBlockLabels() {
5366 for (var t in _current) {
5367 if (_current[t]["(type)"] === "unused") {
5368 if (state.option.unused) {
5369 var tkn = _current[t]["(token)"];
5370 var line = tkn.line;
5371 var chr = tkn.character;
5372 warningAt("W098", line, chr, t);
5373 }
5374 }
5375 }
5376 }
5377
5378 return {
5379 stack: function () {
5380 _current = {};
5381 _variables.push(_current);
5382 },
5383
5384 unstack: function () {
5385 _checkBlockLabels();
5386 _variables.splice(_variables.length - 1, 1);
5387 _current = _.last(_variables);
5388 },
5389
5390 getlabel: function (l) {
5391 for (var i = _variables.length - 1 ; i >= 0; --i) {
5392 if (_.has(_variables[i], l)) {
5393 return _variables[i];
5394 }
5395 }
5396 },
5397
5398 current: {
5399 has: function (t) {
5400 return _.has(_current, t);
5401 },
5402 add: function (t, type, tok) {
5403 _current[t] = { "(type)" : type,
5404 "(token)": tok };
5405 }
5406 }
5407 };
5408 };
5409
5410 // The actual JSHINT function itself.
5411 var itself = function (s, o, g) {
5412 var i, k, x;
5413 var optionKeys;
5414 var newOptionObj = {};
5415 var newIgnoredObj = {};
5416
5417 state.reset();
5418
5419 if (o && o.scope) {
5420 JSHINT.scope = o.scope;
5421 } else {
5422 JSHINT.errors = [];
5423 JSHINT.undefs = [];
5424 JSHINT.internals = [];
5425 JSHINT.blacklist = {};
5426 JSHINT.scope = "(main)";
5427 }
5428
5429 predefined = Object.create(null);
5430 combine(predefined, vars.ecmaIdentifiers);
5431 combine(predefined, vars.reservedVars);
5432
5433 combine(predefined, g || {});
5434
5435 declared = Object.create(null);
5436 exported = Object.create(null);
5437
5438 function each(obj, cb) {
5439 if (!obj)
5440 return;
5441
5442 if (!Array.isArray(obj) && typeof obj === "object")
5443 obj = Object.keys(obj);
5444
5445 obj.forEach(cb);
5446 }
5447
5448 if (o) {
5449 each(o.predef || null, function (item) {
5450 var slice, prop;
5451
5452 if (item[0] === "-") {
5453 slice = item.slice(1);
5454 JSHINT.blacklist[slice] = slice;
5455 } else {
5456 prop = Object.getOwnPropertyDescriptor(o.predef, item);
5457 predefined[item] = prop ? prop.value : false;
5458 }
5459 });
5460
5461 each(o.exported || null, function (item) {
5462 exported[item] = true;
5463 });
5464
5465 delete o.predef;
5466 delete o.exported;
5467
5468 optionKeys = Object.keys(o);
5469 for (x = 0; x < optionKeys.length; x++) {
5470 if (/^-W\d{3}$/g.test(optionKeys[x])) {
5471 newIgnoredObj[optionKeys[x].slice(1)] = true;
5472 } else {
5473 newOptionObj[optionKeys[x]] = o[optionKeys[x]];
5474
5475 if (optionKeys[x] === "newcap" && o[optionKeys[x]] === false)
5476 newOptionObj["(explicitNewcap)"] = true;
5477
5478 if (optionKeys[x] === "indent")
5479 newOptionObj["(explicitIndent)"] = o[optionKeys[x]] === false ? false : true;
5480 }
5481 }
5482 }
5483
5484 state.option = newOptionObj;
5485 state.ignored = newIgnoredObj;
5486
5487 state.option.indent = state.option.indent || 4;
5488 state.option.maxerr = state.option.maxerr || 50;
5489
5490 indent = 1;
5491 global = Object.create(predefined);
5492 scope = global;
5493 funct = {
5494 "(global)": true,
5495 "(name)": "(global)",
5496 "(scope)": scope,
5497 "(breakage)": 0,
5498 "(loopage)": 0,
5499 "(tokens)": {},
5500 "(metrics)": createMetrics(state.tokens.next),
5501 "(blockscope)": blockScope(),
5502 "(comparray)": arrayComprehension()
5503 };
5504 functions = [funct];
5505 urls = [];
5506 stack = null;
5507 member = {};
5508 membersOnly = null;
5509 implied = {};
5510 inblock = false;
5511 lookahead = [];
5512 warnings = 0;
5513 unuseds = [];
5514
5515 if (!isString(s) && !Array.isArray(s)) {
5516 errorAt("E004", 0);
5517 return false;
5518 }
5519
5520 api = {
5521 get isJSON() {
5522 return state.jsonMode;
5523 },
5524
5525 getOption: function (name) {
5526 return state.option[name] || null;
5527 },
5528
5529 getCache: function (name) {
5530 return state.cache[name];
5531 },
5532
5533 setCache: function (name, value) {
5534 state.cache[name] = value;
5535 },
5536
5537 warn: function (code, data) {
5538 warningAt.apply(null, [ code, data.line, data.char ].concat(data.data));
5539 },
5540
5541 on: function (names, listener) {
5542 names.split(" ").forEach(function (name) {
5543 emitter.on(name, listener);
5544 }.bind(this));
5545 }
5546 };
5547
5548 emitter.removeAllListeners();
5549 (extraModules || []).forEach(function (func) {
5550 func(api);
5551 });
5552
5553 state.tokens.prev = state.tokens.curr = state.tokens.next = state.syntax["(begin)"];
5554
5555 lex = new Lexer(s);
5556
5557 lex.on("warning", function (ev) {
5558 warningAt.apply(null, [ ev.code, ev.line, ev.character].concat(ev.data));
5559 });
5560
5561 lex.on("error", function (ev) {
5562 errorAt.apply(null, [ ev.code, ev.line, ev.character ].concat(ev.data));
5563 });
5564
5565 lex.on("fatal", function (ev) {
5566 quit("E041", ev.line, ev.from);
5567 });
5568
5569 lex.on("Identifier", function (ev) {
5570 emitter.emit("Identifier", ev);
5571 });
5572
5573 lex.on("String", function (ev) {
5574 emitter.emit("String", ev);
5575 });
5576
5577 lex.on("Number", function (ev) {
5578 emitter.emit("Number", ev);
5579 });
5580
5581 lex.start();
5582
5583 // Check options
5584 for (var name in o) {
5585 if (_.has(o, name)) {
5586 checkOption(name, state.tokens.curr);
5587 }
5588 }
5589
5590 assume();
5591
5592 // combine the passed globals after we've assumed all our options
5593 combine(predefined, g || {});
5594
5595 //reset values
5596 comma.first = true;
5597
5598 try {
5599 advance();
5600 switch (state.tokens.next.id) {
5601 case "{":
5602 case "[":
5603 destructuringAssignOrJsonValue();
5604 break;
5605 default:
5606 directives();
5607
5608 if (state.directive["use strict"]) {
5609 if (!state.option.globalstrict && !state.option.node) {
5610 warning("W097", state.tokens.prev);
5611 }
5612 }
5613
5614 statements();
5615 }
5616 advance((state.tokens.next && state.tokens.next.value !== ".") ? "(end)" : undefined);
5617 funct["(blockscope)"].unstack();
5618
5619 var markDefined = function (name, context) {
5620 do {
5621 if (typeof context[name] === "string") {
5622 // JSHINT marks unused variables as 'unused' and
5623 // unused function declaration as 'unction'. This
5624 // code changes such instances back 'var' and
5625 // 'closure' so that the code in JSHINT.data()
5626 // doesn't think they're unused.
5627
5628 if (context[name] === "unused")
5629 context[name] = "var";
5630 else if (context[name] === "unction")
5631 context[name] = "closure";
5632
5633 return true;
5634 }
5635
5636 context = context["(context)"];
5637 } while (context);
5638
5639 return false;
5640 };
5641
5642 var clearImplied = function (name, line) {
5643 if (!implied[name])
5644 return;
5645
5646 var newImplied = [];
5647 for (var i = 0; i < implied[name].length; i += 1) {
5648 if (implied[name][i] !== line)
5649 newImplied.push(implied[name][i]);
5650 }
5651
5652 if (newImplied.length === 0)
5653 delete implied[name];
5654 else
5655 implied[name] = newImplied;
5656 };
5657
5658 var warnUnused = function (name, tkn, type, unused_opt) {
5659 var line = tkn.line;
5660 var chr = tkn.character;
5661
5662 if (unused_opt === undefined) {
5663 unused_opt = state.option.unused;
5664 }
5665
5666 if (unused_opt === true) {
5667 unused_opt = "last-param";
5668 }
5669
5670 var warnable_types = {
5671 "vars": ["var"],
5672 "last-param": ["var", "param"],
5673 "strict": ["var", "param", "last-param"]
5674 };
5675
5676 if (unused_opt) {
5677 if (warnable_types[unused_opt] && warnable_types[unused_opt].indexOf(type) !== -1) {
5678 warningAt("W098", line, chr, name);
5679 }
5680 }
5681
5682 unuseds.push({
5683 name: name,
5684 line: line,
5685 character: chr
5686 });
5687 };
5688
5689 var checkUnused = function (func, key) {
5690 var type = func[key];
5691 var tkn = func["(tokens)"][key];
5692
5693 if (key.charAt(0) === "(")
5694 return;
5695
5696 if (type !== "unused" && type !== "unction")
5697 return;
5698
5699 // Params are checked separately from other variables.
5700 if (func["(params)"] && func["(params)"].indexOf(key) !== -1)
5701 return;
5702
5703 // Variable is in global scope and defined as exported.
5704 if (func["(global)"] && _.has(exported, key)) {
5705 return;
5706 }
5707
5708 warnUnused(key, tkn, "var");
5709 };
5710
5711 // Check queued 'x is not defined' instances to see if they're still undefined.
5712 for (i = 0; i < JSHINT.undefs.length; i += 1) {
5713 k = JSHINT.undefs[i].slice(0);
5714
5715 if (markDefined(k[2].value, k[0])) {
5716 clearImplied(k[2].value, k[2].line);
5717 } else if (state.option.undef) {
5718 warning.apply(warning, k.slice(1));
5719 }
5720 }
5721
5722 functions.forEach(function (func) {
5723 if (func["(unusedOption)"] === false) {
5724 return;
5725 }
5726
5727 for (var key in func) {
5728 if (_.has(func, key)) {
5729 checkUnused(func, key);
5730 }
5731 }
5732
5733 if (!func["(params)"])
5734 return;
5735
5736 var params = func["(params)"].slice();
5737 var param = params.pop();
5738 var type, unused_opt;
5739
5740 while (param) {
5741 type = func[param];
5742 unused_opt = func["(unusedOption)"] || state.option.unused;
5743 unused_opt = unused_opt === true ? "last-param" : unused_opt;
5744
5745 // 'undefined' is a special case for (function (window, undefined) { ... })();
5746 // patterns.
5747
5748 if (param === "undefined")
5749 return;
5750
5751 if (type === "unused" || type === "unction") {
5752 warnUnused(param, func["(tokens)"][param], "param", func["(unusedOption)"]);
5753 } else if (unused_opt === "last-param") {
5754 return;
5755 }
5756
5757 param = params.pop();
5758 }
5759 });
5760
5761 for (var key in declared) {
5762 if (_.has(declared, key) && !_.has(global, key)) {
5763 warnUnused(key, declared[key], "var");
5764 }
5765 }
5766
5767 } catch (err) {
5768 if (err && err.name === "JSHintError") {
5769 var nt = state.tokens.next || {};
5770 JSHINT.errors.push({
5771 scope : "(main)",
5772 raw : err.raw,
5773 code : err.code,
5774 reason : err.message,
5775 line : err.line || nt.line,
5776 character : err.character || nt.from
5777 }, null);
5778 } else {
5779 throw err;
5780 }
5781 }
5782
5783 // Loop over the listed "internals", and check them as well.
5784
5785 if (JSHINT.scope === "(main)") {
5786 o = o || {};
5787
5788 for (i = 0; i < JSHINT.internals.length; i += 1) {
5789 k = JSHINT.internals[i];
5790 o.scope = k.elem;
5791 itself(k.value, o, g);
5792 }
5793 }
5794
5795 return JSHINT.errors.length === 0;
5796 };
5797
5798 // Modules.
5799 itself.addModule = function (func) {
5800 extraModules.push(func);
5801 };
5802
5803 itself.addModule(style.register);
5804
5805 // Data summary.
5806 itself.data = function () {
5807 var data = {
5808 functions: [],
5809 options: state.option
5810 };
5811 var implieds = [];
5812 var members = [];
5813 var fu, f, i, j, n, globals;
5814
5815 if (itself.errors.length) {
5816 data.errors = itself.errors;
5817 }
5818
5819 if (state.jsonMode) {
5820 data.json = true;
5821 }
5822
5823 for (n in implied) {
5824 if (_.has(implied, n)) {
5825 implieds.push({
5826 name: n,
5827 line: implied[n]
5828 });
5829 }
5830 }
5831
5832 if (implieds.length > 0) {
5833 data.implieds = implieds;
5834 }
5835
5836 if (urls.length > 0) {
5837 data.urls = urls;
5838 }
5839
5840 globals = Object.keys(scope);
5841 if (globals.length > 0) {
5842 data.globals = globals;
5843 }
5844
5845 for (i = 1; i < functions.length; i += 1) {
5846 f = functions[i];
5847 fu = {};
5848
5849 for (j = 0; j < functionicity.length; j += 1) {
5850 fu[functionicity[j]] = [];
5851 }
5852
5853 for (j = 0; j < functionicity.length; j += 1) {
5854 if (fu[functionicity[j]].length === 0) {
5855 delete fu[functionicity[j]];
5856 }
5857 }
5858
5859 fu.name = f["(name)"];
5860 fu.param = f["(params)"];
5861 fu.line = f["(line)"];
5862 fu.character = f["(character)"];
5863 fu.last = f["(last)"];
5864 fu.lastcharacter = f["(lastcharacter)"];
5865 data.functions.push(fu);
5866 }
5867
5868 if (unuseds.length > 0) {
5869 data.unused = unuseds;
5870 }
5871
5872 members = [];
5873 for (n in member) {
5874 if (typeof member[n] === "number") {
5875 data.member = member;
5876 break;
5877 }
5878 }
5879
5880 return data;
5881 };
5882
5883 itself.jshint = itself;
5884
5885 return itself;
5886 }());
5887
5888 // Make JSHINT a Node module, if possible.
5889 if (typeof exports === "object" && exports) {
5890 exports.JSHINT = JSHINT;
5891 }
5892
5893 })()
5894 },{"events":2,"../shared/vars.js":3,"../shared/messages.js":7,"./reg.js":4,"./state.js":6,"./style.js":5,"./lex.js":8,"console-browserify":9,"underscore":10}],7:[function(require,module,exports){
5895 (function(){"use strict";
5896
5897 var _ = require("underscore");
5898
5899 var errors = {
5900 // JSHint options
5901 E001: "Bad option: '{a}'.",
5902 E002: "Bad option value.",
5903
5904 // JSHint input
5905 E003: "Expected a JSON value.",
5906 E004: "Input is neither a string nor an array of strings.",
5907 E005: "Input is empty.",
5908 E006: "Unexpected early end of program.",
5909
5910 // Strict mode
5911 E007: "Missing \"use strict\" statement.",
5912 E008: "Strict violation.",
5913 E009: "Option 'validthis' can't be used in a global scope.",
5914 E010: "'with' is not allowed in strict mode.",
5915
5916 // Constants
5917 E011: "const '{a}' has already been declared.",
5918 E012: "const '{a}' is initialized to 'undefined'.",
5919 E013: "Attempting to override '{a}' which is a constant.",
5920
5921 // Regular expressions
5922 E014: "A regular expression literal can be confused with '/='.",
5923 E015: "Unclosed regular expression.",
5924 E016: "Invalid regular expression.",
5925
5926 // Tokens
5927 E017: "Unclosed comment.",
5928 E018: "Unbegun comment.",
5929 E019: "Unmatched '{a}'.",
5930 E020: "Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
5931 E021: "Expected '{a}' and instead saw '{b}'.",
5932 E022: "Line breaking error '{a}'.",
5933 E023: "Missing '{a}'.",
5934 E024: "Unexpected '{a}'.",
5935 E025: "Missing ':' on a case clause.",
5936 E026: "Missing '}' to match '{' from line {a}.",
5937 E027: "Missing ']' to match '[' form line {a}.",
5938 E028: "Illegal comma.",
5939 E029: "Unclosed string.",
5940
5941 // Everything else
5942 E030: "Expected an identifier and instead saw '{a}'.",
5943 E031: "Bad assignment.", // FIXME: Rephrase
5944 E032: "Expected a small integer or 'false' and instead saw '{a}'.",
5945 E033: "Expected an operator and instead saw '{a}'.",
5946 E034: "get/set are ES5 features.",
5947 E035: "Missing property name.",
5948 E036: "Expected to see a statement and instead saw a block.",
5949 E037: null, // Vacant
5950 E038: null, // Vacant
5951 E039: "Function declarations are not invocable. Wrap the whole function invocation in parens.",
5952 E040: "Each value should have its own case label.",
5953 E041: "Unrecoverable syntax error.",
5954 E042: "Stopping.",
5955 E043: "Too many errors.",
5956 E044: "'{a}' is already defined and can't be redefined.",
5957 E045: "Invalid for each loop.",
5958 E046: "A yield statement shall be within a generator function (with syntax: `function*`)",
5959 E047: "A generator function shall contain a yield statement.",
5960 E048: "Let declaration not directly within block.",
5961 E049: "A {a} cannot be named '{b}'.",
5962 E050: "Mozilla requires the yield expression to be parenthesized here.",
5963 E051: "Regular parameters cannot come after default parameters."
5964 };
5965
5966 var warnings = {
5967 W001: "'hasOwnProperty' is a really bad name.",
5968 W002: "Value of '{a}' may be overwritten in IE 8 and earlier.",
5969 W003: "'{a}' was used before it was defined.",
5970 W004: "'{a}' is already defined.",
5971 W005: "A dot following a number can be confused with a decimal point.",
5972 W006: "Confusing minuses.",
5973 W007: "Confusing pluses.",
5974 W008: "A leading decimal point can be confused with a dot: '{a}'.",
5975 W009: "The array literal notation [] is preferrable.",
5976 W010: "The object literal notation {} is preferrable.",
5977 W011: "Unexpected space after '{a}'.",
5978 W012: "Unexpected space before '{a}'.",
5979 W013: "Missing space after '{a}'.",
5980 W014: "Bad line breaking before '{a}'.",
5981 W015: "Expected '{a}' to have an indentation at {b} instead at {c}.",
5982 W016: "Unexpected use of '{a}'.",
5983 W017: "Bad operand.",
5984 W018: "Confusing use of '{a}'.",
5985 W019: "Use the isNaN function to compare with NaN.",
5986 W020: "Read only.",
5987 W021: "'{a}' is a function.",
5988 W022: "Do not assign to the exception parameter.",
5989 W023: "Expected an identifier in an assignment and instead saw a function invocation.",
5990 W024: "Expected an identifier and instead saw '{a}' (a reserved word).",
5991 W025: "Missing name in function declaration.",
5992 W026: "Inner functions should be listed at the top of the outer function.",
5993 W027: "Unreachable '{a}' after '{b}'.",
5994 W028: "Label '{a}' on {b} statement.",
5995 W030: "Expected an assignment or function call and instead saw an expression.",
5996 W031: "Do not use 'new' for side effects.",
5997 W032: "Unnecessary semicolon.",
5998 W033: "Missing semicolon.",
5999 W034: "Unnecessary directive \"{a}\".",
6000 W035: "Empty block.",
6001 W036: "Unexpected /*member '{a}'.",
6002 W037: "'{a}' is a statement label.",
6003 W038: "'{a}' used out of scope.",
6004 W039: "'{a}' is not allowed.",
6005 W040: "Possible strict violation.",
6006 W041: "Use '{a}' to compare with '{b}'.",
6007 W042: "Avoid EOL escaping.",
6008 W043: "Bad escaping of EOL. Use option multistr if needed.",
6009 W044: "Bad or unnecessary escaping.",
6010 W045: "Bad number '{a}'.",
6011 W046: "Don't use extra leading zeros '{a}'.",
6012 W047: "A trailing decimal point can be confused with a dot: '{a}'.",
6013 W048: "Unexpected control character in regular expression.",
6014 W049: "Unexpected escaped character '{a}' in regular expression.",
6015 W050: "JavaScript URL.",
6016 W051: "Variables should not be deleted.",
6017 W052: "Unexpected '{a}'.",
6018 W053: "Do not use {a} as a constructor.",
6019 W054: "The Function constructor is a form of eval.",
6020 W055: "A constructor name should start with an uppercase letter.",
6021 W056: "Bad constructor.",
6022 W057: "Weird construction. Is 'new' unnecessary?",
6023 W058: "Missing '()' invoking a constructor.",
6024 W059: "Avoid arguments.{a}.",
6025 W060: "document.write can be a form of eval.",
6026 W061: "eval can be harmful.",
6027 W062: "Wrap an immediate function invocation in parens " +
6028 "to assist the reader in understanding that the expression " +
6029 "is the result of a function, and not the function itself.",
6030 W063: "Math is not a function.",
6031 W064: "Missing 'new' prefix when invoking a constructor.",
6032 W065: "Missing radix parameter.",
6033 W066: "Implied eval. Consider passing a function instead of a string.",
6034 W067: "Bad invocation.",
6035 W068: "Wrapping non-IIFE function literals in parens is unnecessary.",
6036 W069: "['{a}'] is better written in dot notation.",
6037 W070: "Extra comma. (it breaks older versions of IE)",
6038 W071: "This function has too many statements. ({a})",
6039 W072: "This function has too many parameters. ({a})",
6040 W073: "Blocks are nested too deeply. ({a})",
6041 W074: "This function's cyclomatic complexity is too high. ({a})",
6042 W075: "Duplicate key '{a}'.",
6043 W076: "Unexpected parameter '{a}' in get {b} function.",
6044 W077: "Expected a single parameter in set {a} function.",
6045 W078: "Setter is defined without getter.",
6046 W079: "Redefinition of '{a}'.",
6047 W080: "It's not necessary to initialize '{a}' to 'undefined'.",
6048 W081: "Too many var statements.",
6049 W082: "Function declarations should not be placed in blocks. " +
6050 "Use a function expression or move the statement to the top of " +
6051 "the outer function.",
6052 W083: "Don't make functions within a loop.",
6053 W084: "Expected a conditional expression and instead saw an assignment.",
6054 W085: "Don't use 'with'.",
6055 W086: "Expected a 'break' statement before '{a}'.",
6056 W087: "Forgotten 'debugger' statement?",
6057 W088: "Creating global 'for' variable. Should be 'for (var {a} ...'.",
6058 W089: "The body of a for in should be wrapped in an if statement to filter " +
6059 "unwanted properties from the prototype.",
6060 W090: "'{a}' is not a statement label.",
6061 W091: "'{a}' is out of scope.",
6062 W092: "Wrap the /regexp/ literal in parens to disambiguate the slash operator.",
6063 W093: "Did you mean to return a conditional instead of an assignment?",
6064 W094: "Unexpected comma.",
6065 W095: "Expected a string and instead saw {a}.",
6066 W096: "The '{a}' key may produce unexpected results.",
6067 W097: "Use the function form of \"use strict\".",
6068 W098: "'{a}' is defined but never used.",
6069 W099: "Mixed spaces and tabs.",
6070 W100: "This character may get silently deleted by one or more browsers.",
6071 W101: "Line is too long.",
6072 W102: "Trailing whitespace.",
6073 W103: "The '{a}' property is deprecated.",
6074 W104: "'{a}' is only available in JavaScript 1.7.",
6075 W105: "Unexpected {a} in '{b}'.",
6076 W106: "Identifier '{a}' is not in camel case.",
6077 W107: "Script URL.",
6078 W108: "Strings must use doublequote.",
6079 W109: "Strings must use singlequote.",
6080 W110: "Mixed double and single quotes.",
6081 W112: "Unclosed string.",
6082 W113: "Control character in string: {a}.",
6083 W114: "Avoid {a}.",
6084 W115: "Octal literals are not allowed in strict mode.",
6085 W116: "Expected '{a}' and instead saw '{b}'.",
6086 W117: "'{a}' is not defined.",
6087 W118: "'{a}' is only available in Mozilla JavaScript extensions (use moz option).",
6088 W119: "'{a}' is only available in ES6 (use esnext option).",
6089 W120: "You might be leaking a variable ({a}) here."
6090 };
6091
6092 var info = {
6093 I001: "Comma warnings can be turned off with 'laxcomma'.",
6094 I002: "Reserved words as properties can be used under the 'es5' option.",
6095 I003: "ES5 option is now set per default"
6096 };
6097
6098 exports.errors = {};
6099 exports.warnings = {};
6100 exports.info = {};
6101
6102 _.each(errors, function (desc, code) {
6103 exports.errors[code] = { code: code, desc: desc };
6104 });
6105
6106 _.each(warnings, function (desc, code) {
6107 exports.warnings[code] = { code: code, desc: desc };
6108 });
6109
6110 _.each(info, function (desc, code) {
6111 exports.info[code] = { code: code, desc: desc };
6112 });
6113
6114 })()
6115 },{"underscore":10}],8:[function(require,module,exports){
6116 (function(){/*
6117 * Lexical analysis and token construction.
6118 */
6119
6120 "use strict";
6121
6122 var _ = require("underscore");
6123 var events = require("events");
6124 var reg = require("./reg.js");
6125 var state = require("./state.js").state;
6126
6127 // Some of these token types are from JavaScript Parser API
6128 // while others are specific to JSHint parser.
6129 // JS Parser API: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
6130
6131 var Token = {
6132 Identifier: 1,
6133 Punctuator: 2,
6134 NumericLiteral: 3,
6135 StringLiteral: 4,
6136 Comment: 5,
6137 Keyword: 6,
6138 NullLiteral: 7,
6139 BooleanLiteral: 8,
6140 RegExp: 9
6141 };
6142
6143 // This is auto generated from the unicode tables.
6144 // The tables are at:
6145 // http://www.fileformat.info/info/unicode/category/Lu/list.htm
6146 // http://www.fileformat.info/info/unicode/category/Ll/list.htm
6147 // http://www.fileformat.info/info/unicode/category/Lt/list.htm
6148 // http://www.fileformat.info/info/unicode/category/Lm/list.htm
6149 // http://www.fileformat.info/info/unicode/category/Lo/list.htm
6150 // http://www.fileformat.info/info/unicode/category/Nl/list.htm
6151
6152 var unicodeLetterTable = [
6153 170, 170, 181, 181, 186, 186, 192, 214,
6154 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750,
6155 880, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908,
6156 910, 929, 931, 1013, 1015, 1153, 1162, 1319, 1329, 1366,
6157 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1568, 1610,
6158 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775,
6159 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957,
6160 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069,
6161 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2308, 2361,
6162 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2423, 2425, 2431,
6163 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482,
6164 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529,
6165 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608,
6166 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654,
6167 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736,
6168 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785,
6169 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867,
6170 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929,
6171 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970,
6172 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001,
6173 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123,
6174 3125, 3129, 3133, 3133, 3160, 3161, 3168, 3169, 3205, 3212,
6175 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261,
6176 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344,
6177 3346, 3386, 3389, 3389, 3406, 3406, 3424, 3425, 3450, 3455,
6178 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526,
6179 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716,
6180 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743,
6181 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760,
6182 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805,
6183 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138,
6184 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198,
6185 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4304, 4346,
6186 4348, 4348, 4352, 4680, 4682, 4685, 4688, 4694, 4696, 4696,
6187 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789,
6188 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880,
6189 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5108, 5121, 5740,
6190 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900,
6191 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000,
6192 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6263, 6272, 6312,
6193 6314, 6314, 6320, 6389, 6400, 6428, 6480, 6509, 6512, 6516,
6194 6528, 6571, 6593, 6599, 6656, 6678, 6688, 6740, 6823, 6823,
6195 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7104, 7141,
6196 7168, 7203, 7245, 7247, 7258, 7293, 7401, 7404, 7406, 7409,
6197 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013,
6198 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061,
6199 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140,
6200 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188,
6201 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455,
6202 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486,
6203 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521,
6204 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358,
6205 11360, 11492, 11499, 11502, 11520, 11557, 11568, 11621,
6206 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694,
6207 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726,
6208 11728, 11734, 11736, 11742, 11823, 11823, 12293, 12295,
6209 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438,
6210 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589,
6211 12593, 12686, 12704, 12730, 12784, 12799, 13312, 13312,
6212 19893, 19893, 19968, 19968, 40907, 40907, 40960, 42124,
6213 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539,
6214 42560, 42606, 42623, 42647, 42656, 42735, 42775, 42783,
6215 42786, 42888, 42891, 42894, 42896, 42897, 42912, 42921,
6216 43002, 43009, 43011, 43013, 43015, 43018, 43020, 43042,
6217 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259,
6218 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442,
6219 43471, 43471, 43520, 43560, 43584, 43586, 43588, 43595,
6220 43616, 43638, 43642, 43642, 43648, 43695, 43697, 43697,
6221 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714,
6222 43739, 43741, 43777, 43782, 43785, 43790, 43793, 43798,
6223 43808, 43814, 43816, 43822, 43968, 44002, 44032, 44032,
6224 55203, 55203, 55216, 55238, 55243, 55291, 63744, 64045,
6225 64048, 64109, 64112, 64217, 64256, 64262, 64275, 64279,
6226 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316,
6227 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433,
6228 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019,
6229 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370,
6230 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495,
6231 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594,
6232 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786,
6233 65856, 65908, 66176, 66204, 66208, 66256, 66304, 66334,
6234 66352, 66378, 66432, 66461, 66464, 66499, 66504, 66511,
6235 66513, 66517, 66560, 66717, 67584, 67589, 67592, 67592,
6236 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669,
6237 67840, 67861, 67872, 67897, 68096, 68096, 68112, 68115,
6238 68117, 68119, 68121, 68147, 68192, 68220, 68352, 68405,
6239 68416, 68437, 68448, 68466, 68608, 68680, 69635, 69687,
6240 69763, 69807, 73728, 74606, 74752, 74850, 77824, 78894,
6241 92160, 92728, 110592, 110593, 119808, 119892, 119894, 119964,
6242 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980,
6243 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069,
6244 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121,
6245 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144,
6246 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570,
6247 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686,
6248 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779,
6249 131072, 131072, 173782, 173782, 173824, 173824, 177972, 177972,
6250 177984, 177984, 178205, 178205, 194560, 195101
6251 ];
6252
6253 var identifierStartTable = [];
6254
6255 for (var i = 0; i < 128; i++) {
6256 identifierStartTable[i] =
6257 i === 36 || // $
6258 i >= 65 && i <= 90 || // A-Z
6259 i === 95 || // _
6260 i >= 97 && i <= 122; // a-z
6261 }
6262
6263 var identifierPartTable = [];
6264
6265 for (var i = 0; i < 128; i++) {
6266 identifierPartTable[i] =
6267 identifierStartTable[i] || // $, _, A-Z, a-z
6268 i >= 48 && i <= 57; // 0-9
6269 }
6270
6271 // Object that handles postponed lexing verifications that checks the parsed
6272 // environment state.
6273
6274 function asyncTrigger() {
6275 var _checks = [];
6276
6277 return {
6278 push: function (fn) {
6279 _checks.push(fn);
6280 },
6281
6282 check: function () {
6283 for (var check = 0; check < _checks.length; ++check) {
6284 _checks[check]();
6285 }
6286
6287 _checks.splice(0, _checks.length);
6288 }
6289 };
6290 }
6291
6292 /*
6293 * Lexer for JSHint.
6294 *
6295 * This object does a char-by-char scan of the provided source code
6296 * and produces a sequence of tokens.
6297 *
6298 * var lex = new Lexer("var i = 0;");
6299 * lex.start();
6300 * lex.token(); // returns the next token
6301 *
6302 * You have to use the token() method to move the lexer forward
6303 * but you don't have to use its return value to get tokens. In addition
6304 * to token() method returning the next token, the Lexer object also
6305 * emits events.
6306 *
6307 * lex.on("Identifier", function (data) {
6308 * if (data.name.indexOf("_") >= 0) {
6309 * // Produce a warning.
6310 * }
6311 * });
6312 *
6313 * Note that the token() method returns tokens in a JSLint-compatible
6314 * format while the event emitter uses a slightly modified version of
6315 * Mozilla's JavaScript Parser API. Eventually, we will move away from
6316 * JSLint format.
6317 */
6318 function Lexer(source) {
6319 var lines = source;
6320
6321 if (typeof lines === "string") {
6322 lines = lines
6323 .replace(/\r\n/g, "\n")
6324 .replace(/\r/g, "\n")
6325 .split("\n");
6326 }
6327
6328 // If the first line is a shebang (#!), make it a blank and move on.
6329 // Shebangs are used by Node scripts.
6330
6331 if (lines[0] && lines[0].substr(0, 2) === "#!") {
6332 lines[0] = "";
6333 }
6334
6335 this.emitter = new events.EventEmitter();
6336 this.source = source;
6337 this.setLines(lines);
6338 this.prereg = true;
6339
6340 this.line = 0;
6341 this.char = 1;
6342 this.from = 1;
6343 this.input = "";
6344
6345 for (var i = 0; i < state.option.indent; i += 1) {
6346 state.tab += " ";
6347 }
6348 }
6349
6350 Lexer.prototype = {
6351 _lines: [],
6352
6353 getLines: function () {
6354 this._lines = state.lines;
6355 return this._lines;
6356 },
6357
6358 setLines: function (val) {
6359 this._lines = val;
6360 state.lines = this._lines;
6361 },
6362
6363 /*
6364 * Return the next i character without actually moving the
6365 * char pointer.
6366 */
6367 peek: function (i) {
6368 return this.input.charAt(i || 0);
6369 },
6370
6371 /*
6372 * Move the char pointer forward i times.
6373 */
6374 skip: function (i) {
6375 i = i || 1;
6376 this.char += i;
6377 this.input = this.input.slice(i);
6378 },
6379
6380 /*
6381 * Subscribe to a token event. The API for this method is similar
6382 * Underscore.js i.e. you can subscribe to multiple events with
6383 * one call:
6384 *
6385 * lex.on("Identifier Number", function (data) {
6386 * // ...
6387 * });
6388 */
6389 on: function (names, listener) {
6390 names.split(" ").forEach(function (name) {
6391 this.emitter.on(name, listener);
6392 }.bind(this));
6393 },
6394
6395 /*
6396 * Trigger a token event. All arguments will be passed to each
6397 * listener.
6398 */
6399 trigger: function () {
6400 this.emitter.emit.apply(this.emitter, Array.prototype.slice.call(arguments));
6401 },
6402
6403 /*
6404 * Postpone a token event. the checking condition is set as
6405 * last parameter, and the trigger function is called in a
6406 * stored callback. To be later called using the check() function
6407 * by the parser. This avoids parser's peek() to give the lexer
6408 * a false context.
6409 */
6410 triggerAsync: function (type, args, checks, fn) {
6411 checks.push(function () {
6412 if (fn()) {
6413 this.trigger(type, args);
6414 }
6415 }.bind(this));
6416 },
6417
6418 /*
6419 * Extract a punctuator out of the next sequence of characters
6420 * or return 'null' if its not possible.
6421 *
6422 * This method's implementation was heavily influenced by the
6423 * scanPunctuator function in the Esprima parser's source code.
6424 */
6425 scanPunctuator: function () {
6426 var ch1 = this.peek();
6427 var ch2, ch3, ch4;
6428
6429 switch (ch1) {
6430 // Most common single-character punctuators
6431 case ".":
6432 if ((/^[0-9]$/).test(this.peek(1))) {
6433 return null;
6434 }
6435 if (this.peek(1) === "." && this.peek(2) === ".") {
6436 return {
6437 type: Token.Punctuator,
6438 value: "..."
6439 };
6440 }
6441 /* falls through */
6442 case "(":
6443 case ")":
6444 case ";":
6445 case ",":
6446 case "{":
6447 case "}":
6448 case "[":
6449 case "]":
6450 case ":":
6451 case "~":
6452 case "?":
6453 return {
6454 type: Token.Punctuator,
6455 value: ch1
6456 };
6457
6458 // A pound sign (for Node shebangs)
6459 case "#":
6460 return {
6461 type: Token.Punctuator,
6462 value: ch1
6463 };
6464
6465 // We're at the end of input
6466 case "":
6467 return null;
6468 }
6469
6470 // Peek more characters
6471
6472 ch2 = this.peek(1);
6473 ch3 = this.peek(2);
6474 ch4 = this.peek(3);
6475
6476 // 4-character punctuator: >>>=
6477
6478 if (ch1 === ">" && ch2 === ">" && ch3 === ">" && ch4 === "=") {
6479 return {
6480 type: Token.Punctuator,
6481 value: ">>>="
6482 };
6483 }
6484
6485 // 3-character punctuators: === !== >>> <<= >>=
6486
6487 if (ch1 === "=" && ch2 === "=" && ch3 === "=") {
6488 return {
6489 type: Token.Punctuator,
6490 value: "==="
6491 };
6492 }
6493
6494 if (ch1 === "!" && ch2 === "=" && ch3 === "=") {
6495 return {
6496 type: Token.Punctuator,
6497 value: "!=="
6498 };
6499 }
6500
6501 if (ch1 === ">" && ch2 === ">" && ch3 === ">") {
6502 return {
6503 type: Token.Punctuator,
6504 value: ">>>"
6505 };
6506 }
6507
6508 if (ch1 === "<" && ch2 === "<" && ch3 === "=") {
6509 return {
6510 type: Token.Punctuator,
6511 value: "<<="
6512 };
6513 }
6514
6515 if (ch1 === ">" && ch2 === ">" && ch3 === "=") {
6516 return {
6517 type: Token.Punctuator,
6518 value: ">>="
6519 };
6520 }
6521
6522 // Fat arrow punctuator
6523 if (ch1 === "=" && ch2 === ">") {
6524 return {
6525 type: Token.Punctuator,
6526 value: ch1 + ch2
6527 };
6528 }
6529
6530 // 2-character punctuators: <= >= == != ++ -- << >> && ||
6531 // += -= *= %= &= |= ^= (but not /=, see below)
6532 if (ch1 === ch2 && ("+-<>&|".indexOf(ch1) >= 0)) {
6533 return {
6534 type: Token.Punctuator,
6535 value: ch1 + ch2
6536 };
6537 }
6538
6539 if ("<>=!+-*%&|^".indexOf(ch1) >= 0) {
6540 if (ch2 === "=") {
6541 return {
6542 type: Token.Punctuator,
6543 value: ch1 + ch2
6544 };
6545 }
6546
6547 return {
6548 type: Token.Punctuator,
6549 value: ch1
6550 };
6551 }
6552
6553 // Special case: /=. We need to make sure that this is an
6554 // operator and not a regular expression.
6555
6556 if (ch1 === "/") {
6557 if (ch2 === "=" && /\/=(?!(\S*\/[gim]?))/.test(this.input)) {
6558 // /= is not a part of a regular expression, return it as a
6559 // punctuator.
6560 return {
6561 type: Token.Punctuator,
6562 value: "/="
6563 };
6564 }
6565
6566 return {
6567 type: Token.Punctuator,
6568 value: "/"
6569 };
6570 }
6571
6572 return null;
6573 },
6574
6575 /*
6576 * Extract a comment out of the next sequence of characters and/or
6577 * lines or return 'null' if its not possible. Since comments can
6578 * span across multiple lines this method has to move the char
6579 * pointer.
6580 *
6581 * In addition to normal JavaScript comments (// and /*) this method
6582 * also recognizes JSHint- and JSLint-specific comments such as
6583 * /*jshint, /*jslint, /*globals and so on.
6584 */
6585 scanComments: function () {
6586 var ch1 = this.peek();
6587 var ch2 = this.peek(1);
6588 var rest = this.input.substr(2);
6589 var startLine = this.line;
6590 var startChar = this.char;
6591
6592 // Create a comment token object and make sure it
6593 // has all the data JSHint needs to work with special
6594 // comments.
6595
6596 function commentToken(label, body, opt) {
6597 var special = ["jshint", "jslint", "members", "member", "globals", "global", "exported"];
6598 var isSpecial = false;
6599 var value = label + body;
6600 var commentType = "plain";
6601 opt = opt || {};
6602
6603 if (opt.isMultiline) {
6604 value += "*/";
6605 }
6606
6607 special.forEach(function (str) {
6608 if (isSpecial) {
6609 return;
6610 }
6611
6612 // Don't recognize any special comments other than jshint for single-line
6613 // comments. This introduced many problems with legit comments.
6614 if (label === "//" && str !== "jshint") {
6615 return;
6616 }
6617
6618 if (body.substr(0, str.length) === str) {
6619 isSpecial = true;
6620 label = label + str;
6621 body = body.substr(str.length);
6622 }
6623
6624 if (!isSpecial && body.charAt(0) === " " && body.substr(1, str.length) === str) {
6625 isSpecial = true;
6626 label = label + " " + str;
6627 body = body.substr(str.length + 1);
6628 }
6629
6630 if (!isSpecial) {
6631 return;
6632 }
6633
6634 switch (str) {
6635 case "member":
6636 commentType = "members";
6637 break;
6638 case "global":
6639 commentType = "globals";
6640 break;
6641 default:
6642 commentType = str;
6643 }
6644 });
6645
6646 return {
6647 type: Token.Comment,
6648 commentType: commentType,
6649 value: value,
6650 body: body,
6651 isSpecial: isSpecial,
6652 isMultiline: opt.isMultiline || false,
6653 isMalformed: opt.isMalformed || false
6654 };
6655 }
6656
6657 // End of unbegun comment. Raise an error and skip that input.
6658 if (ch1 === "*" && ch2 === "/") {
6659 this.trigger("error", {
6660 code: "E018",
6661 line: startLine,
6662 character: startChar
6663 });
6664
6665 this.skip(2);
6666 return null;
6667 }
6668
6669 // Comments must start either with // or /*
6670 if (ch1 !== "/" || (ch2 !== "*" && ch2 !== "/")) {
6671 return null;
6672 }
6673
6674 // One-line comment
6675 if (ch2 === "/") {
6676 this.skip(this.input.length); // Skip to the EOL.
6677 return commentToken("//", rest);
6678 }
6679
6680 var body = "";
6681
6682 /* Multi-line comment */
6683 if (ch2 === "*") {
6684 this.skip(2);
6685
6686 while (this.peek() !== "*" || this.peek(1) !== "/") {
6687 if (this.peek() === "") { // End of Line
6688 body += "\n";
6689
6690 // If we hit EOF and our comment is still unclosed,
6691 // trigger an error and end the comment implicitly.
6692 if (!this.nextLine()) {
6693 this.trigger("error", {
6694 code: "E017",
6695 line: startLine,
6696 character: startChar
6697 });
6698
6699 return commentToken("/*", body, {
6700 isMultiline: true,
6701 isMalformed: true
6702 });
6703 }
6704 } else {
6705 body += this.peek();
6706 this.skip();
6707 }
6708 }
6709
6710 this.skip(2);
6711 return commentToken("/*", body, { isMultiline: true });
6712 }
6713 },
6714
6715 /*
6716 * Extract a keyword out of the next sequence of characters or
6717 * return 'null' if its not possible.
6718 */
6719 scanKeyword: function () {
6720 var result = /^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input);
6721 var keywords = [
6722 "if", "in", "do", "var", "for", "new",
6723 "try", "let", "this", "else", "case",
6724 "void", "with", "enum", "while", "break",
6725 "catch", "throw", "const", "yield", "class",
6726 "super", "return", "typeof", "delete",
6727 "switch", "export", "import", "default",
6728 "finally", "extends", "function", "continue",
6729 "debugger", "instanceof"
6730 ];
6731
6732 if (result && keywords.indexOf(result[0]) >= 0) {
6733 return {
6734 type: Token.Keyword,
6735 value: result[0]
6736 };
6737 }
6738
6739 return null;
6740 },
6741
6742 /*
6743 * Extract a JavaScript identifier out of the next sequence of
6744 * characters or return 'null' if its not possible. In addition,
6745 * to Identifier this method can also produce BooleanLiteral
6746 * (true/false) and NullLiteral (null).
6747 */
6748 scanIdentifier: function () {
6749 var id = "";
6750 var index = 0;
6751 var type, char;
6752
6753 // Detects any character in the Unicode categories "Uppercase
6754 // letter (Lu)", "Lowercase letter (Ll)", "Titlecase letter
6755 // (Lt)", "Modifier letter (Lm)", "Other letter (Lo)", or
6756 // "Letter number (Nl)".
6757 //
6758 // Both approach and unicodeLetterTable were borrowed from
6759 // Google's Traceur.
6760
6761 function isUnicodeLetter(code) {
6762 for (var i = 0; i < unicodeLetterTable.length;) {
6763 if (code < unicodeLetterTable[i++]) {
6764 return false;
6765 }
6766
6767 if (code <= unicodeLetterTable[i++]) {
6768 return true;
6769 }
6770 }
6771
6772 return false;
6773 }
6774
6775 function isHexDigit(str) {
6776 return (/^[0-9a-fA-F]$/).test(str);
6777 }
6778
6779 var readUnicodeEscapeSequence = function () {
6780 /*jshint validthis:true */
6781 index += 1;
6782
6783 if (this.peek(index) !== "u") {
6784 return null;
6785 }
6786
6787 var ch1 = this.peek(index + 1);
6788 var ch2 = this.peek(index + 2);
6789 var ch3 = this.peek(index + 3);
6790 var ch4 = this.peek(index + 4);
6791 var code;
6792
6793 if (isHexDigit(ch1) && isHexDigit(ch2) && isHexDigit(ch3) && isHexDigit(ch4)) {
6794 code = parseInt(ch1 + ch2 + ch3 + ch4, 16);
6795
6796 if (isUnicodeLetter(code)) {
6797 index += 5;
6798 return "\\u" + ch1 + ch2 + ch3 + ch4;
6799 }
6800
6801 return null;
6802 }
6803
6804 return null;
6805 }.bind(this);
6806
6807 var getIdentifierStart = function () {
6808 /*jshint validthis:true */
6809 var chr = this.peek(index);
6810 var code = chr.charCodeAt(0);
6811
6812 if (code === 92) {
6813 return readUnicodeEscapeSequence();
6814 }
6815
6816 if (code < 128) {
6817 if (identifierStartTable[code]) {
6818 index += 1;
6819 return chr;
6820 }
6821
6822 return null;
6823 }
6824
6825 if (isUnicodeLetter(code)) {
6826 index += 1;
6827 return chr;
6828 }
6829
6830 return null;
6831 }.bind(this);
6832
6833 var getIdentifierPart = function () {
6834 /*jshint validthis:true */
6835 var chr = this.peek(index);
6836 var code = chr.charCodeAt(0);
6837
6838 if (code === 92) {
6839 return readUnicodeEscapeSequence();
6840 }
6841
6842 if (code < 128) {
6843 if (identifierPartTable[code]) {
6844 index += 1;
6845 return chr;
6846 }
6847
6848 return null;
6849 }
6850
6851 if (isUnicodeLetter(code)) {
6852 index += 1;
6853 return chr;
6854 }
6855
6856 return null;
6857 }.bind(this);
6858
6859 char = getIdentifierStart();
6860 if (char === null) {
6861 return null;
6862 }
6863
6864 id = char;
6865 for (;;) {
6866 char = getIdentifierPart();
6867
6868 if (char === null) {
6869 break;
6870 }
6871
6872 id += char;
6873 }
6874
6875 switch (id) {
6876 case "true":
6877 case "false":
6878 type = Token.BooleanLiteral;
6879 break;
6880 case "null":
6881 type = Token.NullLiteral;
6882 break;
6883 default:
6884 type = Token.Identifier;
6885 }
6886
6887 return {
6888 type: type,
6889 value: id
6890 };
6891 },
6892
6893 /*
6894 * Extract a numeric literal out of the next sequence of
6895 * characters or return 'null' if its not possible. This method
6896 * supports all numeric literals described in section 7.8.3
6897 * of the EcmaScript 5 specification.
6898 *
6899 * This method's implementation was heavily influenced by the
6900 * scanNumericLiteral function in the Esprima parser's source code.
6901 */
6902 scanNumericLiteral: function () {
6903 var index = 0;
6904 var value = "";
6905 var length = this.input.length;
6906 var char = this.peek(index);
6907 var bad;
6908
6909 function isDecimalDigit(str) {
6910 return (/^[0-9]$/).test(str);
6911 }
6912
6913 function isOctalDigit(str) {
6914 return (/^[0-7]$/).test(str);
6915 }
6916
6917 function isHexDigit(str) {
6918 return (/^[0-9a-fA-F]$/).test(str);
6919 }
6920
6921 function isIdentifierStart(ch) {
6922 return (ch === "$") || (ch === "_") || (ch === "\\") ||
6923 (ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z");
6924 }
6925
6926 // Numbers must start either with a decimal digit or a point.
6927
6928 if (char !== "." && !isDecimalDigit(char)) {
6929 return null;
6930 }
6931
6932 if (char !== ".") {
6933 value = this.peek(index);
6934 index += 1;
6935 char = this.peek(index);
6936
6937 if (value === "0") {
6938 // Base-16 numbers.
6939 if (char === "x" || char === "X") {
6940 index += 1;
6941 value += char;
6942
6943 while (index < length) {
6944 char = this.peek(index);
6945 if (!isHexDigit(char)) {
6946 break;
6947 }
6948 value += char;
6949 index += 1;
6950 }
6951
6952 if (value.length <= 2) { // 0x
6953 return {
6954 type: Token.NumericLiteral,
6955 value: value,
6956 isMalformed: true
6957 };
6958 }
6959
6960 if (index < length) {
6961 char = this.peek(index);
6962 if (isIdentifierStart(char)) {
6963 return null;
6964 }
6965 }
6966
6967 return {
6968 type: Token.NumericLiteral,
6969 value: value,
6970 base: 16,
6971 isMalformed: false
6972 };
6973 }
6974
6975 // Base-8 numbers.
6976 if (isOctalDigit(char)) {
6977 index += 1;
6978 value += char;
6979 bad = false;
6980
6981 while (index < length) {
6982 char = this.peek(index);
6983
6984 // Numbers like '019' (note the 9) are not valid octals
6985 // but we still parse them and mark as malformed.
6986
6987 if (isDecimalDigit(char)) {
6988 bad = true;
6989 } else if (!isOctalDigit(char)) {
6990 break;
6991 }
6992 value += char;
6993 index += 1;
6994 }
6995
6996 if (index < length) {
6997 char = this.peek(index);
6998 if (isIdentifierStart(char)) {
6999 return null;
7000 }
7001 }
7002
7003 return {
7004 type: Token.NumericLiteral,
7005 value: value,
7006 base: 8,
7007 isMalformed: false
7008 };
7009 }
7010
7011 // Decimal numbers that start with '0' such as '09' are illegal
7012 // but we still parse them and return as malformed.
7013
7014 if (isDecimalDigit(char)) {
7015 index += 1;
7016 value += char;
7017 }
7018 }
7019
7020 while (index < length) {
7021 char = this.peek(index);
7022 if (!isDecimalDigit(char)) {
7023 break;
7024 }
7025 value += char;
7026 index += 1;
7027 }
7028 }
7029
7030 // Decimal digits.
7031
7032 if (char === ".") {
7033 value += char;
7034 index += 1;
7035
7036 while (index < length) {
7037 char = this.peek(index);
7038 if (!isDecimalDigit(char)) {
7039 break;
7040 }
7041 value += char;
7042 index += 1;
7043 }
7044 }
7045
7046 // Exponent part.
7047
7048 if (char === "e" || char === "E") {
7049 value += char;
7050 index += 1;
7051 char = this.peek(index);
7052
7053 if (char === "+" || char === "-") {
7054 value += this.peek(index);
7055 index += 1;
7056 }
7057
7058 char = this.peek(index);
7059 if (isDecimalDigit(char)) {
7060 value += char;
7061 index += 1;
7062
7063 while (index < length) {
7064 char = this.peek(index);
7065 if (!isDecimalDigit(char)) {
7066 break;
7067 }
7068 value += char;
7069 index += 1;
7070 }
7071 } else {
7072 return null;
7073 }
7074 }
7075
7076 if (index < length) {
7077 char = this.peek(index);
7078 if (isIdentifierStart(char)) {
7079 return null;
7080 }
7081 }
7082
7083 return {
7084 type: Token.NumericLiteral,
7085 value: value,
7086 base: 10,
7087 isMalformed: !isFinite(value)
7088 };
7089 },
7090
7091 /*
7092 * Extract a string out of the next sequence of characters and/or
7093 * lines or return 'null' if its not possible. Since strings can
7094 * span across multiple lines this method has to move the char
7095 * pointer.
7096 *
7097 * This method recognizes pseudo-multiline JavaScript strings:
7098 *
7099 * var str = "hello\
7100 * world";
7101 */
7102 scanStringLiteral: function (checks) {
7103 /*jshint loopfunc:true */
7104 var quote = this.peek();
7105
7106 // String must start with a quote.
7107 if (quote !== "\"" && quote !== "'") {
7108 return null;
7109 }
7110
7111 // In JSON strings must always use double quotes.
7112 this.triggerAsync("warning", {
7113 code: "W108",
7114 line: this.line,
7115 character: this.char // +1?
7116 }, checks, function () { return state.jsonMode && quote !== "\""; });
7117
7118 var value = "";
7119 var startLine = this.line;
7120 var startChar = this.char;
7121 var allowNewLine = false;
7122
7123 this.skip();
7124
7125 while (this.peek() !== quote) {
7126 while (this.peek() === "") { // End Of Line
7127
7128 // If an EOL is not preceded by a backslash, show a warning
7129 // and proceed like it was a legit multi-line string where
7130 // author simply forgot to escape the newline symbol.
7131 //
7132 // Another approach is to implicitly close a string on EOL
7133 // but it generates too many false positives.
7134
7135 if (!allowNewLine) {
7136 this.trigger("warning", {
7137 code: "W112",
7138 line: this.line,
7139 character: this.char
7140 });
7141 } else {
7142 allowNewLine = false;
7143
7144 // Otherwise show a warning if multistr option was not set.
7145 // For JSON, show warning no matter what.
7146
7147 this.triggerAsync("warning", {
7148 code: "W043",
7149 line: this.line,
7150 character: this.char
7151 }, checks, function () { return !state.option.multistr; });
7152
7153 this.triggerAsync("warning", {
7154 code: "W042",
7155 line: this.line,
7156 character: this.char
7157 }, checks, function () { return state.jsonMode && state.option.multistr; });
7158 }
7159
7160 // If we get an EOF inside of an unclosed string, show an
7161 // error and implicitly close it at the EOF point.
7162
7163 if (!this.nextLine()) {
7164 this.trigger("error", {
7165 code: "E029",
7166 line: startLine,
7167 character: startChar
7168 });
7169
7170 return {
7171 type: Token.StringLiteral,
7172 value: value,
7173 isUnclosed: true,
7174 quote: quote
7175 };
7176 }
7177 }
7178
7179 allowNewLine = false;
7180 var char = this.peek();
7181 var jump = 1; // A length of a jump, after we're done
7182 // parsing this character.
7183
7184 if (char < " ") {
7185 // Warn about a control character in a string.
7186 this.trigger("warning", {
7187 code: "W113",
7188 line: this.line,
7189 character: this.char,
7190 data: [ "<non-printable>" ]
7191 });
7192 }
7193
7194 // Special treatment for some escaped characters.
7195
7196 if (char === "\\") {
7197 this.skip();
7198 char = this.peek();
7199
7200 switch (char) {
7201 case "'":
7202 this.triggerAsync("warning", {
7203 code: "W114",
7204 line: this.line,
7205 character: this.char,
7206 data: [ "\\'" ]
7207 }, checks, function () {return state.jsonMode; });
7208 break;
7209 case "b":
7210 char = "\b";
7211 break;
7212 case "f":
7213 char = "\f";
7214 break;
7215 case "n":
7216 char = "\n";
7217 break;
7218 case "r":
7219 char = "\r";
7220 break;
7221 case "t":
7222 char = "\t";
7223 break;
7224 case "0":
7225 char = "\0";
7226
7227 // Octal literals fail in strict mode.
7228 // Check if the number is between 00 and 07.
7229 var n = parseInt(this.peek(1), 10);
7230 this.triggerAsync("warning", {
7231 code: "W115",
7232 line: this.line,
7233 character: this.char
7234 }, checks,
7235 function () { return n >= 0 && n <= 7 && state.directive["use strict"]; });
7236 break;
7237 case "u":
7238 char = String.fromCharCode(parseInt(this.input.substr(1, 4), 16));
7239 jump = 5;
7240 break;
7241 case "v":
7242 this.triggerAsync("warning", {
7243 code: "W114",
7244 line: this.line,
7245 character: this.char,
7246 data: [ "\\v" ]
7247 }, checks, function () { return state.jsonMode; });
7248
7249 char = "\v";
7250 break;
7251 case "x":
7252 var x = parseInt(this.input.substr(1, 2), 16);
7253
7254 this.triggerAsync("warning", {
7255 code: "W114",
7256 line: this.line,
7257 character: this.char,
7258 data: [ "\\x-" ]
7259 }, checks, function () { return state.jsonMode; });
7260
7261 char = String.fromCharCode(x);
7262 jump = 3;
7263 break;
7264 case "\\":
7265 case "\"":
7266 case "/":
7267 break;
7268 case "":
7269 allowNewLine = true;
7270 char = "";
7271 break;
7272 case "!":
7273 if (value.slice(value.length - 2) === "<") {
7274 break;
7275 }
7276
7277 /*falls through */
7278 default:
7279 // Weird escaping.
7280 this.trigger("warning", {
7281 code: "W044",
7282 line: this.line,
7283 character: this.char
7284 });
7285 }
7286 }
7287
7288 value += char;
7289 this.skip(jump);
7290 }
7291
7292 this.skip();
7293 return {
7294 type: Token.StringLiteral,
7295 value: value,
7296 isUnclosed: false,
7297 quote: quote
7298 };
7299 },
7300
7301 /*
7302 * Extract a regular expression out of the next sequence of
7303 * characters and/or lines or return 'null' if its not possible.
7304 *
7305 * This method is platform dependent: it accepts almost any
7306 * regular expression values but then tries to compile and run
7307 * them using system's RegExp object. This means that there are
7308 * rare edge cases where one JavaScript engine complains about
7309 * your regular expression while others don't.
7310 */
7311 scanRegExp: function () {
7312 var index = 0;
7313 var length = this.input.length;
7314 var char = this.peek();
7315 var value = char;
7316 var body = "";
7317 var flags = [];
7318 var malformed = false;
7319 var isCharSet = false;
7320 var terminated;
7321
7322 var scanUnexpectedChars = function () {
7323 // Unexpected control character
7324 if (char < " ") {
7325 malformed = true;
7326 this.trigger("warning", {
7327 code: "W048",
7328 line: this.line,
7329 character: this.char
7330 });
7331 }
7332
7333 // Unexpected escaped character
7334 if (char === "<") {
7335 malformed = true;
7336 this.trigger("warning", {
7337 code: "W049",
7338 line: this.line,
7339 character: this.char,
7340 data: [ char ]
7341 });
7342 }
7343 }.bind(this);
7344
7345 // Regular expressions must start with '/'
7346 if (!this.prereg || char !== "/") {
7347 return null;
7348 }
7349
7350 index += 1;
7351 terminated = false;
7352
7353 // Try to get everything in between slashes. A couple of
7354 // cases aside (see scanUnexpectedChars) we don't really
7355 // care whether the resulting expression is valid or not.
7356 // We will check that later using the RegExp object.
7357
7358 while (index < length) {
7359 char = this.peek(index);
7360 value += char;
7361 body += char;
7362
7363 if (isCharSet) {
7364 if (char === "]") {
7365 if (this.peek(index - 1) !== "\\" || this.peek(index - 2) === "\\") {
7366 isCharSet = false;
7367 }
7368 }
7369
7370 if (char === "\\") {
7371 index += 1;
7372 char = this.peek(index);
7373 body += char;
7374 value += char;
7375
7376 scanUnexpectedChars();
7377 }
7378
7379 index += 1;
7380 continue;
7381 }
7382
7383 if (char === "\\") {
7384 index += 1;
7385 char = this.peek(index);
7386 body += char;
7387 value += char;
7388
7389 scanUnexpectedChars();
7390
7391 if (char === "/") {
7392 index += 1;
7393 continue;
7394 }
7395
7396 if (char === "[") {
7397 index += 1;
7398 continue;
7399 }
7400 }
7401
7402 if (char === "[") {
7403 isCharSet = true;
7404 index += 1;
7405 continue;
7406 }
7407
7408 if (char === "/") {
7409 body = body.substr(0, body.length - 1);
7410 terminated = true;
7411 index += 1;
7412 break;
7413 }
7414
7415 index += 1;
7416 }
7417
7418 // A regular expression that was never closed is an
7419 // error from which we cannot recover.
7420
7421 if (!terminated) {
7422 this.trigger("error", {
7423 code: "E015",
7424 line: this.line,
7425 character: this.from
7426 });
7427
7428 return void this.trigger("fatal", {
7429 line: this.line,
7430 from: this.from
7431 });
7432 }
7433
7434 // Parse flags (if any).
7435
7436 while (index < length) {
7437 char = this.peek(index);
7438 if (!/[gim]/.test(char)) {
7439 break;
7440 }
7441 flags.push(char);
7442 value += char;
7443 index += 1;
7444 }
7445
7446 // Check regular expression for correctness.
7447
7448 try {
7449 new RegExp(body, flags.join(""));
7450 } catch (err) {
7451 malformed = true;
7452 this.trigger("error", {
7453 code: "E016",
7454 line: this.line,
7455 character: this.char,
7456 data: [ err.message ] // Platform dependent!
7457 });
7458 }
7459
7460 return {
7461 type: Token.RegExp,
7462 value: value,
7463 flags: flags,
7464 isMalformed: malformed
7465 };
7466 },
7467
7468 /*
7469 * Scan for any occurence of mixed tabs and spaces. If smarttabs option
7470 * is on, ignore tabs followed by spaces.
7471 *
7472 * Tabs followed by one space followed by a block comment are allowed.
7473 */
7474 scanMixedSpacesAndTabs: function () {
7475 var at, match;
7476
7477 if (state.option.smarttabs) {
7478 // Negative look-behind for "//"
7479 match = this.input.match(/(\/\/|^\s?\*)? \t/);
7480 at = match && !match[1] ? 0 : -1;
7481 } else {
7482 at = this.input.search(/ \t|\t [^\*]/);
7483 }
7484
7485 return at;
7486 },
7487
7488 /*
7489 * Scan for characters that get silently deleted by one or more browsers.
7490 */
7491 scanUnsafeChars: function () {
7492 return this.input.search(reg.unsafeChars);
7493 },
7494
7495 /*
7496 * Produce the next raw token or return 'null' if no tokens can be matched.
7497 * This method skips over all space characters.
7498 */
7499 next: function (checks) {
7500 this.from = this.char;
7501
7502 // Move to the next non-space character.
7503 var start;
7504 if (/\s/.test(this.peek())) {
7505 start = this.char;
7506
7507 while (/\s/.test(this.peek())) {
7508 this.from += 1;
7509 this.skip();
7510 }
7511
7512 if (this.peek() === "") { // EOL
7513 if (!/^\s*$/.test(this.getLines()[this.line - 1]) && state.option.trailing) {
7514 this.trigger("warning", { code: "W102", line: this.line, character: start });
7515 }
7516 }
7517 }
7518
7519 // Methods that work with multi-line structures and move the
7520 // character pointer.
7521
7522 var match = this.scanComments() ||
7523 this.scanStringLiteral(checks);
7524
7525 if (match) {
7526 return match;
7527 }
7528
7529 // Methods that don't move the character pointer.
7530
7531 match =
7532 this.scanRegExp() ||
7533 this.scanPunctuator() ||
7534 this.scanKeyword() ||
7535 this.scanIdentifier() ||
7536 this.scanNumericLiteral();
7537
7538 if (match) {
7539 this.skip(match.value.length);
7540 return match;
7541 }
7542
7543 // No token could be matched, give up.
7544
7545 return null;
7546 },
7547
7548 /*
7549 * Switch to the next line and reset all char pointers. Once
7550 * switched, this method also checks for mixed spaces and tabs
7551 * and other minor warnings.
7552 */
7553 nextLine: function () {
7554 var char;
7555
7556 if (this.line >= this.getLines().length) {
7557 return false;
7558 }
7559
7560 this.input = this.getLines()[this.line];
7561 this.line += 1;
7562 this.char = 1;
7563 this.from = 1;
7564
7565 char = this.scanMixedSpacesAndTabs();
7566 if (char >= 0) {
7567 this.trigger("warning", { code: "W099", line: this.line, character: char + 1 });
7568 }
7569
7570 this.input = this.input.replace(/\t/g, state.tab);
7571 char = this.scanUnsafeChars();
7572
7573 if (char >= 0) {
7574 this.trigger("warning", { code: "W100", line: this.line, character: char });
7575 }
7576
7577 // If there is a limit on line length, warn when lines get too
7578 // long.
7579
7580 if (state.option.maxlen && state.option.maxlen < this.input.length) {
7581 this.trigger("warning", { code: "W101", line: this.line, character: this.input.length });
7582 }
7583
7584 return true;
7585 },
7586
7587 /*
7588 * This is simply a synonym for nextLine() method with a friendlier
7589 * public name.
7590 */
7591 start: function () {
7592 this.nextLine();
7593 },
7594
7595 /*
7596 * Produce the next token. This function is called by advance() to get
7597 * the next token. It retuns a token in a JSLint-compatible format.
7598 */
7599 token: function () {
7600 /*jshint loopfunc:true */
7601 var checks = asyncTrigger();
7602 var token;
7603
7604
7605 function isReserved(token, isProperty) {
7606 if (!token.reserved) {
7607 return false;
7608 }
7609 var meta = token.meta;
7610
7611 if (meta && meta.isFutureReservedWord && state.option.inES5()) {
7612 // ES3 FutureReservedWord in an ES5 environment.
7613 if (!meta.es5) {
7614 return false;
7615 }
7616
7617 // Some ES5 FutureReservedWord identifiers are active only
7618 // within a strict mode environment.
7619 if (meta.strictOnly) {
7620 if (!state.option.strict && !state.directive["use strict"]) {
7621 return false;
7622 }
7623 }
7624
7625 if (isProperty) {
7626 return false;
7627 }
7628 }
7629
7630 return true;
7631 }
7632
7633 // Produce a token object.
7634 var create = function (type, value, isProperty) {
7635 /*jshint validthis:true */
7636 var obj;
7637
7638 if (type !== "(endline)" && type !== "(end)") {
7639 this.prereg = false;
7640 }
7641
7642 if (type === "(punctuator)") {
7643 switch (value) {
7644 case ".":
7645 case ")":
7646 case "~":
7647 case "#":
7648 case "]":
7649 this.prereg = false;
7650 break;
7651 default:
7652 this.prereg = true;
7653 }
7654
7655 obj = Object.create(state.syntax[value] || state.syntax["(error)"]);
7656 }
7657
7658 if (type === "(identifier)") {
7659 if (value === "return" || value === "case" || value === "typeof") {
7660 this.prereg = true;
7661 }
7662
7663 if (_.has(state.syntax, value)) {
7664 obj = Object.create(state.syntax[value] || state.syntax["(error)"]);
7665
7666 // If this can't be a reserved keyword, reset the object.
7667 if (!isReserved(obj, isProperty && type === "(identifier)")) {
7668 obj = null;
7669 }
7670 }
7671 }
7672
7673 if (!obj) {
7674 obj = Object.create(state.syntax[type]);
7675 }
7676
7677 obj.identifier = (type === "(identifier)");
7678 obj.type = obj.type || type;
7679 obj.value = value;
7680 obj.line = this.line;
7681 obj.character = this.char;
7682 obj.from = this.from;
7683
7684 if (isProperty && obj.identifier) {
7685 obj.isProperty = isProperty;
7686 }
7687
7688 obj.check = checks.check;
7689
7690 return obj;
7691 }.bind(this);
7692
7693 for (;;) {
7694 if (!this.input.length) {
7695 return create(this.nextLine() ? "(endline)" : "(end)", "");
7696 }
7697
7698 token = this.next(checks);
7699
7700 if (!token) {
7701 if (this.input.length) {
7702 // Unexpected character.
7703 this.trigger("error", {
7704 code: "E024",
7705 line: this.line,
7706 character: this.char,
7707 data: [ this.peek() ]
7708 });
7709
7710 this.input = "";
7711 }
7712
7713 continue;
7714 }
7715
7716 switch (token.type) {
7717 case Token.StringLiteral:
7718 this.triggerAsync("String", {
7719 line: this.line,
7720 char: this.char,
7721 from: this.from,
7722 value: token.value,
7723 quote: token.quote
7724 }, checks, function () { return true; });
7725
7726 return create("(string)", token.value);
7727 case Token.Identifier:
7728 this.trigger("Identifier", {
7729 line: this.line,
7730 char: this.char,
7731 from: this.form,
7732 name: token.value,
7733 isProperty: state.tokens.curr.id === "."
7734 });
7735
7736 /* falls through */
7737 case Token.Keyword:
7738 case Token.NullLiteral:
7739 case Token.BooleanLiteral:
7740 return create("(identifier)", token.value, state.tokens.curr.id === ".");
7741
7742 case Token.NumericLiteral:
7743 if (token.isMalformed) {
7744 this.trigger("warning", {
7745 code: "W045",
7746 line: this.line,
7747 character: this.char,
7748 data: [ token.value ]
7749 });
7750 }
7751
7752 this.triggerAsync("warning", {
7753 code: "W114",
7754 line: this.line,
7755 character: this.char,
7756 data: [ "0x-" ]
7757 }, checks, function () { return token.base === 16 && state.jsonMode; });
7758
7759 this.triggerAsync("warning", {
7760 code: "W115",
7761 line: this.line,
7762 character: this.char
7763 }, checks, function () {
7764 return state.directive["use strict"] && token.base === 8;
7765 });
7766
7767 this.trigger("Number", {
7768 line: this.line,
7769 char: this.char,
7770 from: this.from,
7771 value: token.value,
7772 base: token.base,
7773 isMalformed: token.malformed
7774 });
7775
7776 return create("(number)", token.value);
7777
7778 case Token.RegExp:
7779 return create("(regexp)", token.value);
7780
7781 case Token.Comment:
7782 state.tokens.curr.comment = true;
7783
7784 if (token.isSpecial) {
7785 return {
7786 value: token.value,
7787 body: token.body,
7788 type: token.commentType,
7789 isSpecial: token.isSpecial,
7790 line: this.line,
7791 character: this.char,
7792 from: this.from
7793 };
7794 }
7795
7796 break;
7797
7798 case "":
7799 break;
7800
7801 default:
7802 return create("(punctuator)", token.value);
7803 }
7804 }
7805 }
7806 };
7807
7808 exports.Lexer = Lexer;
7809
7810 })()
7811 },{"events":2,"./state.js":6,"./reg.js":4,"underscore":10}],9:[function(require,module,exports){
7812 (function(global){/*global window, global*/
7813 var util = require("util")
7814 var assert = require("assert")
7815
7816 var slice = Array.prototype.slice
7817 var console
7818 var times = {}
7819
7820 if (typeof global !== "undefined" && global.console) {
7821 console = global.console
7822 } else if (typeof window !== "undefined" && window.console) {
7823 console = window.console
7824 } else {
7825 console = window.console = {}
7826 }
7827
7828 var functions = [
7829 [log, "log"]
7830 , [info, "info"]
7831 , [warn, "warn"]
7832 , [error, "error"]
7833 , [time, "time"]
7834 , [timeEnd, "timeEnd"]
7835 , [trace, "trace"]
7836 , [dir, "dir"]
7837 , [assert, "assert"]
7838 ]
7839
7840 for (var i = 0; i < functions.length; i++) {
7841 var tuple = functions[i]
7842 var f = tuple[0]
7843 var name = tuple[1]
7844
7845 if (!console[name]) {
7846 console[name] = f
7847 }
7848 }
7849
7850 module.exports = console
7851
7852 function log() {}
7853
7854 function info() {
7855 console.log.apply(console, arguments)
7856 }
7857
7858 function warn() {
7859 console.log.apply(console, arguments)
7860 }
7861
7862 function error() {
7863 console.warn.apply(console, arguments)
7864 }
7865
7866 function time(label) {
7867 times[label] = Date.now()
7868 }
7869
7870 function timeEnd(label) {
7871 var time = times[label]
7872 if (!time) {
7873 throw new Error("No such label: " + label)
7874 }
7875
7876 var duration = Date.now() - time
7877 console.log(label + ": " + duration + "ms")
7878 }
7879
7880 function trace() {
7881 var err = new Error()
7882 err.name = "Trace"
7883 err.message = util.format.apply(null, arguments)
7884 console.error(err.stack)
7885 }
7886
7887 function dir(object) {
7888 console.log(util.inspect(object) + "\n")
7889 }
7890
7891 function assert(expression) {
7892 if (!expression) {
7893 var arr = slice.call(arguments, 1)
7894 assert.ok(false, util.format.apply(null, arr))
7895 }
7896 }
7897
7898 })(window)
7899 },{"util":11,"assert":12}],10:[function(require,module,exports){
7900 (function(){// Underscore.js 1.4.4
7901 // http://underscorejs.org
7902 // (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
7903 // Underscore may be freely distributed under the MIT license.
7904
7905 (function() {
7906
7907 // Baseline setup
7908 // --------------
7909
7910 // Establish the root object, `window` in the browser, or `global` on the server.
7911 var root = this;
7912
7913 // Save the previous value of the `_` variable.
7914 var previousUnderscore = root._;
7915
7916 // Establish the object that gets returned to break out of a loop iteration.
7917 var breaker = {};
7918
7919 // Save bytes in the minified (but not gzipped) version:
7920 var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
7921
7922 // Create quick reference variables for speed access to core prototypes.
7923 var push = ArrayProto.push,
7924 slice = ArrayProto.slice,
7925 concat = ArrayProto.concat,
7926 toString = ObjProto.toString,
7927 hasOwnProperty = ObjProto.hasOwnProperty;
7928
7929 // All **ECMAScript 5** native function implementations that we hope to use
7930 // are declared here.
7931 var
7932 nativeForEach = ArrayProto.forEach,
7933 nativeMap = ArrayProto.map,
7934 nativeReduce = ArrayProto.reduce,
7935 nativeReduceRight = ArrayProto.reduceRight,
7936 nativeFilter = ArrayProto.filter,
7937 nativeEvery = ArrayProto.every,
7938 nativeSome = ArrayProto.some,
7939 nativeIndexOf = ArrayProto.indexOf,
7940 nativeLastIndexOf = ArrayProto.lastIndexOf,
7941 nativeIsArray = Array.isArray,
7942 nativeKeys = Object.keys,
7943 nativeBind = FuncProto.bind;
7944
7945 // Create a safe reference to the Underscore object for use below.
7946 var _ = function(obj) {
7947 if (obj instanceof _) return obj;
7948 if (!(this instanceof _)) return new _(obj);
7949 this._wrapped = obj;
7950 };
7951
7952 // Export the Underscore object for **Node.js**, with
7953 // backwards-compatibility for the old `require()` API. If we're in
7954 // the browser, add `_` as a global object via a string identifier,
7955 // for Closure Compiler "advanced" mode.
7956 if (typeof exports !== 'undefined') {
7957 if (typeof module !== 'undefined' && module.exports) {
7958 exports = module.exports = _;
7959 }
7960 exports._ = _;
7961 } else {
7962 root._ = _;
7963 }
7964
7965 // Current version.
7966 _.VERSION = '1.4.4';
7967
7968 // Collection Functions
7969 // --------------------
7970
7971 // The cornerstone, an `each` implementation, aka `forEach`.
7972 // Handles objects with the built-in `forEach`, arrays, and raw objects.
7973 // Delegates to **ECMAScript 5**'s native `forEach` if available.
7974 var each = _.each = _.forEach = function(obj, iterator, context) {
7975 if (obj == null) return;
7976 if (nativeForEach && obj.forEach === nativeForEach) {
7977 obj.forEach(iterator, context);
7978 } else if (obj.length === +obj.length) {
7979 for (var i = 0, l = obj.length; i < l; i++) {
7980 if (iterator.call(context, obj[i], i, obj) === breaker) return;
7981 }
7982 } else {
7983 for (var key in obj) {
7984 if (_.has(obj, key)) {
7985 if (iterator.call(context, obj[key], key, obj) === breaker) return;
7986 }
7987 }
7988 }
7989 };
7990
7991 // Return the results of applying the iterator to each element.
7992 // Delegates to **ECMAScript 5**'s native `map` if available.
7993 _.map = _.collect = function(obj, iterator, context) {
7994 var results = [];
7995 if (obj == null) return results;
7996 if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
7997 each(obj, function(value, index, list) {
7998 results[results.length] = iterator.call(context, value, index, list);
7999 });
8000 return results;
8001 };
8002
8003 var reduceError = 'Reduce of empty array with no initial value';
8004
8005 // **Reduce** builds up a single result from a list of values, aka `inject`,
8006 // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
8007 _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
8008 var initial = arguments.length > 2;
8009 if (obj == null) obj = [];
8010 if (nativeReduce && obj.reduce === nativeReduce) {
8011 if (context) iterator = _.bind(iterator, context);
8012 return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
8013 }
8014 each(obj, function(value, index, list) {
8015 if (!initial) {
8016 memo = value;
8017 initial = true;
8018 } else {
8019 memo = iterator.call(context, memo, value, index, list);
8020 }
8021 });
8022 if (!initial) throw new TypeError(reduceError);
8023 return memo;
8024 };
8025
8026 // The right-associative version of reduce, also known as `foldr`.
8027 // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
8028 _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
8029 var initial = arguments.length > 2;
8030 if (obj == null) obj = [];
8031 if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
8032 if (context) iterator = _.bind(iterator, context);
8033 return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
8034 }
8035 var length = obj.length;
8036 if (length !== +length) {
8037 var keys = _.keys(obj);
8038 length = keys.length;
8039 }
8040 each(obj, function(value, index, list) {
8041 index = keys ? keys[--length] : --length;
8042 if (!initial) {
8043 memo = obj[index];
8044 initial = true;
8045 } else {
8046 memo = iterator.call(context, memo, obj[index], index, list);
8047 }
8048 });
8049 if (!initial) throw new TypeError(reduceError);
8050 return memo;
8051 };
8052
8053 // Return the first value which passes a truth test. Aliased as `detect`.
8054 _.find = _.detect = function(obj, iterator, context) {
8055 var result;
8056 any(obj, function(value, index, list) {
8057 if (iterator.call(context, value, index, list)) {
8058 result = value;
8059 return true;
8060 }
8061 });
8062 return result;
8063 };
8064
8065 // Return all the elements that pass a truth test.
8066 // Delegates to **ECMAScript 5**'s native `filter` if available.
8067 // Aliased as `select`.
8068 _.filter = _.select = function(obj, iterator, context) {
8069 var results = [];
8070 if (obj == null) return results;
8071 if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
8072 each(obj, function(value, index, list) {
8073 if (iterator.call(context, value, index, list)) results[results.length] = value;
8074 });
8075 return results;
8076 };
8077
8078 // Return all the elements for which a truth test fails.
8079 _.reject = function(obj, iterator, context) {
8080 return _.filter(obj, function(value, index, list) {
8081 return !iterator.call(context, value, index, list);
8082 }, context);
8083 };
8084
8085 // Determine whether all of the elements match a truth test.
8086 // Delegates to **ECMAScript 5**'s native `every` if available.
8087 // Aliased as `all`.
8088 _.every = _.all = function(obj, iterator, context) {
8089 iterator || (iterator = _.identity);
8090 var result = true;
8091 if (obj == null) return result;
8092 if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
8093 each(obj, function(value, index, list) {
8094 if (!(result = result && iterator.call(context, value, index, list))) return breaker;
8095 });
8096 return !!result;
8097 };
8098
8099 // Determine if at least one element in the object matches a truth test.
8100 // Delegates to **ECMAScript 5**'s native `some` if available.
8101 // Aliased as `any`.
8102 var any = _.some = _.any = function(obj, iterator, context) {
8103 iterator || (iterator = _.identity);
8104 var result = false;
8105 if (obj == null) return result;
8106 if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
8107 each(obj, function(value, index, list) {
8108 if (result || (result = iterator.call(context, value, index, list))) return breaker;
8109 });
8110 return !!result;
8111 };
8112
8113 // Determine if the array or object contains a given value (using `===`).
8114 // Aliased as `include`.
8115 _.contains = _.include = function(obj, target) {
8116 if (obj == null) return false;
8117 if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
8118 return any(obj, function(value) {
8119 return value === target;
8120 });
8121 };
8122
8123 // Invoke a method (with arguments) on every item in a collection.
8124 _.invoke = function(obj, method) {
8125 var args = slice.call(arguments, 2);
8126 var isFunc = _.isFunction(method);
8127 return _.map(obj, function(value) {
8128 return (isFunc ? method : value[method]).apply(value, args);
8129 });
8130 };
8131
8132 // Convenience version of a common use case of `map`: fetching a property.
8133 _.pluck = function(obj, key) {
8134 return _.map(obj, function(value){ return value[key]; });
8135 };
8136
8137 // Convenience version of a common use case of `filter`: selecting only objects
8138 // containing specific `key:value` pairs.
8139 _.where = function(obj, attrs, first) {
8140 if (_.isEmpty(attrs)) return first ? null : [];
8141 return _[first ? 'find' : 'filter'](obj, function(value) {
8142 for (var key in attrs) {
8143 if (attrs[key] !== value[key]) return false;
8144 }
8145 return true;
8146 });
8147 };
8148
8149 // Convenience version of a common use case of `find`: getting the first object
8150 // containing specific `key:value` pairs.
8151 _.findWhere = function(obj, attrs) {
8152 return _.where(obj, attrs, true);
8153 };
8154
8155 // Return the maximum element or (element-based computation).
8156 // Can't optimize arrays of integers longer than 65,535 elements.
8157 // See: https://bugs.webkit.org/show_bug.cgi?id=80797
8158 _.max = function(obj, iterator, context) {
8159 if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
8160 return Math.max.apply(Math, obj);
8161 }
8162 if (!iterator && _.isEmpty(obj)) return -Infinity;
8163 var result = {computed : -Infinity, value: -Infinity};
8164 each(obj, function(value, index, list) {
8165 var computed = iterator ? iterator.call(context, value, index, list) : value;
8166 computed >= result.computed && (result = {value : value, computed : computed});
8167 });
8168 return result.value;
8169 };
8170
8171 // Return the minimum element (or element-based computation).
8172 _.min = function(obj, iterator, context) {
8173 if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
8174 return Math.min.apply(Math, obj);
8175 }
8176 if (!iterator && _.isEmpty(obj)) return Infinity;
8177 var result = {computed : Infinity, value: Infinity};
8178 each(obj, function(value, index, list) {
8179 var computed = iterator ? iterator.call(context, value, index, list) : value;
8180 computed < result.computed && (result = {value : value, computed : computed});
8181 });
8182 return result.value;
8183 };
8184
8185 // Shuffle an array.
8186 _.shuffle = function(obj) {
8187 var rand;
8188 var index = 0;
8189 var shuffled = [];
8190 each(obj, function(value) {
8191 rand = _.random(index++);
8192 shuffled[index - 1] = shuffled[rand];
8193 shuffled[rand] = value;
8194 });
8195 return shuffled;
8196 };
8197
8198 // An internal function to generate lookup iterators.
8199 var lookupIterator = function(value) {
8200 return _.isFunction(value) ? value : function(obj){ return obj[value]; };
8201 };
8202
8203 // Sort the object's values by a criterion produced by an iterator.
8204 _.sortBy = function(obj, value, context) {
8205 var iterator = lookupIterator(value);
8206 return _.pluck(_.map(obj, function(value, index, list) {
8207 return {
8208 value : value,
8209 index : index,
8210 criteria : iterator.call(context, value, index, list)
8211 };
8212 }).sort(function(left, right) {
8213 var a = left.criteria;
8214 var b = right.criteria;
8215 if (a !== b) {
8216 if (a > b || a === void 0) return 1;
8217 if (a < b || b === void 0) return -1;
8218 }
8219 return left.index < right.index ? -1 : 1;
8220 }), 'value');
8221 };
8222
8223 // An internal function used for aggregate "group by" operations.
8224 var group = function(obj, value, context, behavior) {
8225 var result = {};
8226 var iterator = lookupIterator(value || _.identity);
8227 each(obj, function(value, index) {
8228 var key = iterator.call(context, value, index, obj);
8229 behavior(result, key, value);
8230 });
8231 return result;
8232 };
8233
8234 // Groups the object's values by a criterion. Pass either a string attribute
8235 // to group by, or a function that returns the criterion.
8236 _.groupBy = function(obj, value, context) {
8237 return group(obj, value, context, function(result, key, value) {
8238 (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
8239 });
8240 };
8241
8242 // Counts instances of an object that group by a certain criterion. Pass
8243 // either a string attribute to count by, or a function that returns the
8244 // criterion.
8245 _.countBy = function(obj, value, context) {
8246 return group(obj, value, context, function(result, key) {
8247 if (!_.has(result, key)) result[key] = 0;
8248 result[key]++;
8249 });
8250 };
8251
8252 // Use a comparator function to figure out the smallest index at which
8253 // an object should be inserted so as to maintain order. Uses binary search.
8254 _.sortedIndex = function(array, obj, iterator, context) {
8255 iterator = iterator == null ? _.identity : lookupIterator(iterator);
8256 var value = iterator.call(context, obj);
8257 var low = 0, high = array.length;
8258 while (low < high) {
8259 var mid = (low + high) >>> 1;
8260 iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
8261 }
8262 return low;
8263 };
8264
8265 // Safely convert anything iterable into a real, live array.
8266 _.toArray = function(obj) {
8267 if (!obj) return [];
8268 if (_.isArray(obj)) return slice.call(obj);
8269 if (obj.length === +obj.length) return _.map(obj, _.identity);
8270 return _.values(obj);
8271 };
8272
8273 // Return the number of elements in an object.
8274 _.size = function(obj) {
8275 if (obj == null) return 0;
8276 return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
8277 };
8278
8279 // Array Functions
8280 // ---------------
8281
8282 // Get the first element of an array. Passing **n** will return the first N
8283 // values in the array. Aliased as `head` and `take`. The **guard** check
8284 // allows it to work with `_.map`.
8285 _.first = _.head = _.take = function(array, n, guard) {
8286 if (array == null) return void 0;
8287 return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
8288 };
8289
8290 // Returns everything but the last entry of the array. Especially useful on
8291 // the arguments object. Passing **n** will return all the values in
8292 // the array, excluding the last N. The **guard** check allows it to work with
8293 // `_.map`.
8294 _.initial = function(array, n, guard) {
8295 return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
8296 };
8297
8298 // Get the last element of an array. Passing **n** will return the last N
8299 // values in the array. The **guard** check allows it to work with `_.map`.
8300 _.last = function(array, n, guard) {
8301 if (array == null) return void 0;
8302 if ((n != null) && !guard) {
8303 return slice.call(array, Math.max(array.length - n, 0));
8304 } else {
8305 return array[array.length - 1];
8306 }
8307 };
8308
8309 // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
8310 // Especially useful on the arguments object. Passing an **n** will return
8311 // the rest N values in the array. The **guard**
8312 // check allows it to work with `_.map`.
8313 _.rest = _.tail = _.drop = function(array, n, guard) {
8314 return slice.call(array, (n == null) || guard ? 1 : n);
8315 };
8316
8317 // Trim out all falsy values from an array.
8318 _.compact = function(array) {
8319 return _.filter(array, _.identity);
8320 };
8321
8322 // Internal implementation of a recursive `flatten` function.
8323 var flatten = function(input, shallow, output) {
8324 each(input, function(value) {
8325 if (_.isArray(value)) {
8326 shallow ? push.apply(output, value) : flatten(value, shallow, output);
8327 } else {
8328 output.push(value);
8329 }
8330 });
8331 return output;
8332 };
8333
8334 // Return a completely flattened version of an array.
8335 _.flatten = function(array, shallow) {
8336 return flatten(array, shallow, []);
8337 };
8338
8339 // Return a version of the array that does not contain the specified value(s).
8340 _.without = function(array) {
8341 return _.difference(array, slice.call(arguments, 1));
8342 };
8343
8344 // Produce a duplicate-free version of the array. If the array has already
8345 // been sorted, you have the option of using a faster algorithm.
8346 // Aliased as `unique`.
8347 _.uniq = _.unique = function(array, isSorted, iterator, context) {
8348 if (_.isFunction(isSorted)) {
8349 context = iterator;
8350 iterator = isSorted;
8351 isSorted = false;
8352 }
8353 var initial = iterator ? _.map(array, iterator, context) : array;
8354 var results = [];
8355 var seen = [];
8356 each(initial, function(value, index) {
8357 if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
8358 seen.push(value);
8359 results.push(array[index]);
8360 }
8361 });
8362 return results;
8363 };
8364
8365 // Produce an array that contains the union: each distinct element from all of
8366 // the passed-in arrays.
8367 _.union = function() {
8368 return _.uniq(concat.apply(ArrayProto, arguments));
8369 };
8370
8371 // Produce an array that contains every item shared between all the
8372 // passed-in arrays.
8373 _.intersection = function(array) {
8374 var rest = slice.call(arguments, 1);
8375 return _.filter(_.uniq(array), function(item) {
8376 return _.every(rest, function(other) {
8377 return _.indexOf(other, item) >= 0;
8378 });
8379 });
8380 };
8381
8382 // Take the difference between one array and a number of other arrays.
8383 // Only the elements present in just the first array will remain.
8384 _.difference = function(array) {
8385 var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
8386 return _.filter(array, function(value){ return !_.contains(rest, value); });
8387 };
8388
8389 // Zip together multiple lists into a single array -- elements that share
8390 // an index go together.
8391 _.zip = function() {
8392 var args = slice.call(arguments);
8393 var length = _.max(_.pluck(args, 'length'));
8394 var results = new Array(length);
8395 for (var i = 0; i < length; i++) {
8396 results[i] = _.pluck(args, "" + i);
8397 }
8398 return results;
8399 };
8400
8401 // Converts lists into objects. Pass either a single array of `[key, value]`
8402 // pairs, or two parallel arrays of the same length -- one of keys, and one of
8403 // the corresponding values.
8404 _.object = function(list, values) {
8405 if (list == null) return {};
8406 var result = {};
8407 for (var i = 0, l = list.length; i < l; i++) {
8408 if (values) {
8409 result[list[i]] = values[i];
8410 } else {
8411 result[list[i][0]] = list[i][1];
8412 }
8413 }
8414 return result;
8415 };
8416
8417 // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
8418 // we need this function. Return the position of the first occurrence of an
8419 // item in an array, or -1 if the item is not included in the array.
8420 // Delegates to **ECMAScript 5**'s native `indexOf` if available.
8421 // If the array is large and already in sort order, pass `true`
8422 // for **isSorted** to use binary search.
8423 _.indexOf = function(array, item, isSorted) {
8424 if (array == null) return -1;
8425 var i = 0, l = array.length;
8426 if (isSorted) {
8427 if (typeof isSorted == 'number') {
8428 i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
8429 } else {
8430 i = _.sortedIndex(array, item);
8431 return array[i] === item ? i : -1;
8432 }
8433 }
8434 if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
8435 for (; i < l; i++) if (array[i] === item) return i;
8436 return -1;
8437 };
8438
8439 // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
8440 _.lastIndexOf = function(array, item, from) {
8441 if (array == null) return -1;
8442 var hasIndex = from != null;
8443 if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
8444 return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
8445 }
8446 var i = (hasIndex ? from : array.length);
8447 while (i--) if (array[i] === item) return i;
8448 return -1;
8449 };
8450
8451 // Generate an integer Array containing an arithmetic progression. A port of
8452 // the native Python `range()` function. See
8453 // [the Python documentation](http://docs.python.org/library/functions.html#range).
8454 _.range = function(start, stop, step) {
8455 if (arguments.length <= 1) {
8456 stop = start || 0;
8457 start = 0;
8458 }
8459 step = arguments[2] || 1;
8460
8461 var len = Math.max(Math.ceil((stop - start) / step), 0);
8462 var idx = 0;
8463 var range = new Array(len);
8464
8465 while(idx < len) {
8466 range[idx++] = start;
8467 start += step;
8468 }
8469
8470 return range;
8471 };
8472
8473 // Function (ahem) Functions
8474 // ------------------
8475
8476 // Create a function bound to a given object (assigning `this`, and arguments,
8477 // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
8478 // available.
8479 _.bind = function(func, context) {
8480 if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
8481 var args = slice.call(arguments, 2);
8482 return function() {
8483 return func.apply(context, args.concat(slice.call(arguments)));
8484 };
8485 };
8486
8487 // Partially apply a function by creating a version that has had some of its
8488 // arguments pre-filled, without changing its dynamic `this` context.
8489 _.partial = function(func) {
8490 var args = slice.call(arguments, 1);
8491 return function() {
8492 return func.apply(this, args.concat(slice.call(arguments)));
8493 };
8494 };
8495
8496 // Bind all of an object's methods to that object. Useful for ensuring that
8497 // all callbacks defined on an object belong to it.
8498 _.bindAll = function(obj) {
8499 var funcs = slice.call(arguments, 1);
8500 if (funcs.length === 0) funcs = _.functions(obj);
8501 each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
8502 return obj;
8503 };
8504
8505 // Memoize an expensive function by storing its results.
8506 _.memoize = function(func, hasher) {
8507 var memo = {};
8508 hasher || (hasher = _.identity);
8509 return function() {
8510 var key = hasher.apply(this, arguments);
8511 return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
8512 };
8513 };
8514
8515 // Delays a function for the given number of milliseconds, and then calls
8516 // it with the arguments supplied.
8517 _.delay = function(func, wait) {
8518 var args = slice.call(arguments, 2);
8519 return setTimeout(function(){ return func.apply(null, args); }, wait);
8520 };
8521
8522 // Defers a function, scheduling it to run after the current call stack has
8523 // cleared.
8524 _.defer = function(func) {
8525 return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
8526 };
8527
8528 // Returns a function, that, when invoked, will only be triggered at most once
8529 // during a given window of time.
8530 _.throttle = function(func, wait) {
8531 var context, args, timeout, result;
8532 var previous = 0;
8533 var later = function() {
8534 previous = new Date;
8535 timeout = null;
8536 result = func.apply(context, args);
8537 };
8538 return function() {
8539 var now = new Date;
8540 var remaining = wait - (now - previous);
8541 context = this;
8542 args = arguments;
8543 if (remaining <= 0) {
8544 clearTimeout(timeout);
8545 timeout = null;
8546 previous = now;
8547 result = func.apply(context, args);
8548 } else if (!timeout) {
8549 timeout = setTimeout(later, remaining);
8550 }
8551 return result;
8552 };
8553 };
8554
8555 // Returns a function, that, as long as it continues to be invoked, will not
8556 // be triggered. The function will be called after it stops being called for
8557 // N milliseconds. If `immediate` is passed, trigger the function on the
8558 // leading edge, instead of the trailing.
8559 _.debounce = function(func, wait, immediate) {
8560 var timeout, result;
8561 return function() {
8562 var context = this, args = arguments;
8563 var later = function() {
8564 timeout = null;
8565 if (!immediate) result = func.apply(context, args);
8566 };
8567 var callNow = immediate && !timeout;
8568 clearTimeout(timeout);
8569 timeout = setTimeout(later, wait);
8570 if (callNow) result = func.apply(context, args);
8571 return result;
8572 };
8573 };
8574
8575 // Returns a function that will be executed at most one time, no matter how
8576 // often you call it. Useful for lazy initialization.
8577 _.once = function(func) {
8578 var ran = false, memo;
8579 return function() {
8580 if (ran) return memo;
8581 ran = true;
8582 memo = func.apply(this, arguments);
8583 func = null;
8584 return memo;
8585 };
8586 };
8587
8588 // Returns the first function passed as an argument to the second,
8589 // allowing you to adjust arguments, run code before and after, and
8590 // conditionally execute the original function.
8591 _.wrap = function(func, wrapper) {
8592 return function() {
8593 var args = [func];
8594 push.apply(args, arguments);
8595 return wrapper.apply(this, args);
8596 };
8597 };
8598
8599 // Returns a function that is the composition of a list of functions, each
8600 // consuming the return value of the function that follows.
8601 _.compose = function() {
8602 var funcs = arguments;
8603 return function() {
8604 var args = arguments;
8605 for (var i = funcs.length - 1; i >= 0; i--) {
8606 args = [funcs[i].apply(this, args)];
8607 }
8608 return args[0];
8609 };
8610 };
8611
8612 // Returns a function that will only be executed after being called N times.
8613 _.after = function(times, func) {
8614 if (times <= 0) return func();
8615 return function() {
8616 if (--times < 1) {
8617 return func.apply(this, arguments);
8618 }
8619 };
8620 };
8621
8622 // Object Functions
8623 // ----------------
8624
8625 // Retrieve the names of an object's properties.
8626 // Delegates to **ECMAScript 5**'s native `Object.keys`
8627 _.keys = nativeKeys || function(obj) {
8628 if (obj !== Object(obj)) throw new TypeError('Invalid object');
8629 var keys = [];
8630 for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
8631 return keys;
8632 };
8633
8634 // Retrieve the values of an object's properties.
8635 _.values = function(obj) {
8636 var values = [];
8637 for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
8638 return values;
8639 };
8640
8641 // Convert an object into a list of `[key, value]` pairs.
8642 _.pairs = function(obj) {
8643 var pairs = [];
8644 for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
8645 return pairs;
8646 };
8647
8648 // Invert the keys and values of an object. The values must be serializable.
8649 _.invert = function(obj) {
8650 var result = {};
8651 for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
8652 return result;
8653 };
8654
8655 // Return a sorted list of the function names available on the object.
8656 // Aliased as `methods`
8657 _.functions = _.methods = function(obj) {
8658 var names = [];
8659 for (var key in obj) {
8660 if (_.isFunction(obj[key])) names.push(key);
8661 }
8662 return names.sort();
8663 };
8664
8665 // Extend a given object with all the properties in passed-in object(s).
8666 _.extend = function(obj) {
8667 each(slice.call(arguments, 1), function(source) {
8668 if (source) {
8669 for (var prop in source) {
8670 obj[prop] = source[prop];
8671 }
8672 }
8673 });
8674 return obj;
8675 };
8676
8677 // Return a copy of the object only containing the whitelisted properties.
8678 _.pick = function(obj) {
8679 var copy = {};
8680 var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
8681 each(keys, function(key) {
8682 if (key in obj) copy[key] = obj[key];
8683 });
8684 return copy;
8685 };
8686
8687 // Return a copy of the object without the blacklisted properties.
8688 _.omit = function(obj) {
8689 var copy = {};
8690 var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
8691 for (var key in obj) {
8692 if (!_.contains(keys, key)) copy[key] = obj[key];
8693 }
8694 return copy;
8695 };
8696
8697 // Fill in a given object with default properties.
8698 _.defaults = function(obj) {
8699 each(slice.call(arguments, 1), function(source) {
8700 if (source) {
8701 for (var prop in source) {
8702 if (obj[prop] == null) obj[prop] = source[prop];
8703 }
8704 }
8705 });
8706 return obj;
8707 };
8708
8709 // Create a (shallow-cloned) duplicate of an object.
8710 _.clone = function(obj) {
8711 if (!_.isObject(obj)) return obj;
8712 return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
8713 };
8714
8715 // Invokes interceptor with the obj, and then returns obj.
8716 // The primary purpose of this method is to "tap into" a method chain, in
8717 // order to perform operations on intermediate results within the chain.
8718 _.tap = function(obj, interceptor) {
8719 interceptor(obj);
8720 return obj;
8721 };
8722
8723 // Internal recursive comparison function for `isEqual`.
8724 var eq = function(a, b, aStack, bStack) {
8725 // Identical objects are equal. `0 === -0`, but they aren't identical.
8726 // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
8727 if (a === b) return a !== 0 || 1 / a == 1 / b;
8728 // A strict comparison is necessary because `null == undefined`.
8729 if (a == null || b == null) return a === b;
8730 // Unwrap any wrapped objects.
8731 if (a instanceof _) a = a._wrapped;
8732 if (b instanceof _) b = b._wrapped;
8733 // Compare `[[Class]]` names.
8734 var className = toString.call(a);
8735 if (className != toString.call(b)) return false;
8736 switch (className) {
8737 // Strings, numbers, dates, and booleans are compared by value.
8738 case '[object String]':
8739 // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
8740 // equivalent to `new String("5")`.
8741 return a == String(b);
8742 case '[object Number]':
8743 // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
8744 // other numeric values.
8745 return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
8746 case '[object Date]':
8747 case '[object Boolean]':
8748 // Coerce dates and booleans to numeric primitive values. Dates are compared by their
8749 // millisecond representations. Note that invalid dates with millisecond representations
8750 // of `NaN` are not equivalent.
8751 return +a == +b;
8752 // RegExps are compared by their source patterns and flags.
8753 case '[object RegExp]':
8754 return a.source == b.source &&
8755 a.global == b.global &&
8756 a.multiline == b.multiline &&
8757 a.ignoreCase == b.ignoreCase;
8758 }
8759 if (typeof a != 'object' || typeof b != 'object') return false;
8760 // Assume equality for cyclic structures. The algorithm for detecting cyclic
8761 // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
8762 var length = aStack.length;
8763 while (length--) {
8764 // Linear search. Performance is inversely proportional to the number of
8765 // unique nested structures.
8766 if (aStack[length] == a) return bStack[length] == b;
8767 }
8768 // Add the first object to the stack of traversed objects.
8769 aStack.push(a);
8770 bStack.push(b);
8771 var size = 0, result = true;
8772 // Recursively compare objects and arrays.
8773 if (className == '[object Array]') {
8774 // Compare array lengths to determine if a deep comparison is necessary.
8775 size = a.length;
8776 result = size == b.length;
8777 if (result) {
8778 // Deep compare the contents, ignoring non-numeric properties.
8779 while (size--) {
8780 if (!(result = eq(a[size], b[size], aStack, bStack))) break;
8781 }
8782 }
8783 } else {
8784 // Objects with different constructors are not equivalent, but `Object`s
8785 // from different frames are.
8786 var aCtor = a.constructor, bCtor = b.constructor;
8787 if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
8788 _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
8789 return false;
8790 }
8791 // Deep compare objects.
8792 for (var key in a) {
8793 if (_.has(a, key)) {
8794 // Count the expected number of properties.
8795 size++;
8796 // Deep compare each member.
8797 if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
8798 }
8799 }
8800 // Ensure that both objects contain the same number of properties.
8801 if (result) {
8802 for (key in b) {
8803 if (_.has(b, key) && !(size--)) break;
8804 }
8805 result = !size;
8806 }
8807 }
8808 // Remove the first object from the stack of traversed objects.
8809 aStack.pop();
8810 bStack.pop();
8811 return result;
8812 };
8813
8814 // Perform a deep comparison to check if two objects are equal.
8815 _.isEqual = function(a, b) {
8816 return eq(a, b, [], []);
8817 };
8818
8819 // Is a given array, string, or object empty?
8820 // An "empty" object has no enumerable own-properties.
8821 _.isEmpty = function(obj) {
8822 if (obj == null) return true;
8823 if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
8824 for (var key in obj) if (_.has(obj, key)) return false;
8825 return true;
8826 };
8827
8828 // Is a given value a DOM element?
8829 _.isElement = function(obj) {
8830 return !!(obj && obj.nodeType === 1);
8831 };
8832
8833 // Is a given value an array?
8834 // Delegates to ECMA5's native Array.isArray
8835 _.isArray = nativeIsArray || function(obj) {
8836 return toString.call(obj) == '[object Array]';
8837 };
8838
8839 // Is a given variable an object?
8840 _.isObject = function(obj) {
8841 return obj === Object(obj);
8842 };
8843
8844 // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
8845 each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
8846 _['is' + name] = function(obj) {
8847 return toString.call(obj) == '[object ' + name + ']';
8848 };
8849 });
8850
8851 // Define a fallback version of the method in browsers (ahem, IE), where
8852 // there isn't any inspectable "Arguments" type.
8853 if (!_.isArguments(arguments)) {
8854 _.isArguments = function(obj) {
8855 return !!(obj && _.has(obj, 'callee'));
8856 };
8857 }
8858
8859 // Optimize `isFunction` if appropriate.
8860 if (typeof (/./) !== 'function') {
8861 _.isFunction = function(obj) {
8862 return typeof obj === 'function';
8863 };
8864 }
8865
8866 // Is a given object a finite number?
8867 _.isFinite = function(obj) {
8868 return isFinite(obj) && !isNaN(parseFloat(obj));
8869 };
8870
8871 // Is the given value `NaN`? (NaN is the only number which does not equal itself).
8872 _.isNaN = function(obj) {
8873 return _.isNumber(obj) && obj != +obj;
8874 };
8875
8876 // Is a given value a boolean?
8877 _.isBoolean = function(obj) {
8878 return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
8879 };
8880
8881 // Is a given value equal to null?
8882 _.isNull = function(obj) {
8883 return obj === null;
8884 };
8885
8886 // Is a given variable undefined?
8887 _.isUndefined = function(obj) {
8888 return obj === void 0;
8889 };
8890
8891 // Shortcut function for checking if an object has a given property directly
8892 // on itself (in other words, not on a prototype).
8893 _.has = function(obj, key) {
8894 return hasOwnProperty.call(obj, key);
8895 };
8896
8897 // Utility Functions
8898 // -----------------
8899
8900 // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
8901 // previous owner. Returns a reference to the Underscore object.
8902 _.noConflict = function() {
8903 root._ = previousUnderscore;
8904 return this;
8905 };
8906
8907 // Keep the identity function around for default iterators.
8908 _.identity = function(value) {
8909 return value;
8910 };
8911
8912 // Run a function **n** times.
8913 _.times = function(n, iterator, context) {
8914 var accum = Array(n);
8915 for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
8916 return accum;
8917 };
8918
8919 // Return a random integer between min and max (inclusive).
8920 _.random = function(min, max) {
8921 if (max == null) {
8922 max = min;
8923 min = 0;
8924 }
8925 return min + Math.floor(Math.random() * (max - min + 1));
8926 };
8927
8928 // List of HTML entities for escaping.
8929 var entityMap = {
8930 escape: {
8931 '&': '&amp;',
8932 '<': '&lt;',
8933 '>': '&gt;',
8934 '"': '&quot;',
8935 "'": '&#x27;',
8936 '/': '&#x2F;'
8937 }
8938 };
8939 entityMap.unescape = _.invert(entityMap.escape);
8940
8941 // Regexes containing the keys and values listed immediately above.
8942 var entityRegexes = {
8943 escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
8944 unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
8945 };
8946
8947 // Functions for escaping and unescaping strings to/from HTML interpolation.
8948 _.each(['escape', 'unescape'], function(method) {
8949 _[method] = function(string) {
8950 if (string == null) return '';
8951 return ('' + string).replace(entityRegexes[method], function(match) {
8952 return entityMap[method][match];
8953 });
8954 };
8955 });
8956
8957 // If the value of the named property is a function then invoke it;
8958 // otherwise, return it.
8959 _.result = function(object, property) {
8960 if (object == null) return null;
8961 var value = object[property];
8962 return _.isFunction(value) ? value.call(object) : value;
8963 };
8964
8965 // Add your own custom functions to the Underscore object.
8966 _.mixin = function(obj) {
8967 each(_.functions(obj), function(name){
8968 var func = _[name] = obj[name];
8969 _.prototype[name] = function() {
8970 var args = [this._wrapped];
8971 push.apply(args, arguments);
8972 return result.call(this, func.apply(_, args));
8973 };
8974 });
8975 };
8976
8977 // Generate a unique integer id (unique within the entire client session).
8978 // Useful for temporary DOM ids.
8979 var idCounter = 0;
8980 _.uniqueId = function(prefix) {
8981 var id = ++idCounter + '';
8982 return prefix ? prefix + id : id;
8983 };
8984
8985 // By default, Underscore uses ERB-style template delimiters, change the
8986 // following template settings to use alternative delimiters.
8987 _.templateSettings = {
8988 evaluate : /<%([\s\S]+?)%>/g,
8989 interpolate : /<%=([\s\S]+?)%>/g,
8990 escape : /<%-([\s\S]+?)%>/g
8991 };
8992
8993 // When customizing `templateSettings`, if you don't want to define an
8994 // interpolation, evaluation or escaping regex, we need one that is
8995 // guaranteed not to match.
8996 var noMatch = /(.)^/;
8997
8998 // Certain characters need to be escaped so that they can be put into a
8999 // string literal.
9000 var escapes = {
9001 "'": "'",
9002 '\\': '\\',
9003 '\r': 'r',
9004 '\n': 'n',
9005 '\t': 't',
9006 '\u2028': 'u2028',
9007 '\u2029': 'u2029'
9008 };
9009
9010 var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
9011
9012 // JavaScript micro-templating, similar to John Resig's implementation.
9013 // Underscore templating handles arbitrary delimiters, preserves whitespace,
9014 // and correctly escapes quotes within interpolated code.
9015 _.template = function(text, data, settings) {
9016 var render;
9017 settings = _.defaults({}, settings, _.templateSettings);
9018
9019 // Combine delimiters into one regular expression via alternation.
9020 var matcher = new RegExp([
9021 (settings.escape || noMatch).source,
9022 (settings.interpolate || noMatch).source,
9023 (settings.evaluate || noMatch).source
9024 ].join('|') + '|$', 'g');
9025
9026 // Compile the template source, escaping string literals appropriately.
9027 var index = 0;
9028 var source = "__p+='";
9029 text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
9030 source += text.slice(index, offset)
9031 .replace(escaper, function(match) { return '\\' + escapes[match]; });
9032
9033 if (escape) {
9034 source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
9035 }
9036 if (interpolate) {
9037 source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
9038 }
9039 if (evaluate) {
9040 source += "';\n" + evaluate + "\n__p+='";
9041 }
9042 index = offset + match.length;
9043 return match;
9044 });
9045 source += "';\n";
9046
9047 // If a variable is not specified, place data values in local scope.
9048 if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
9049
9050 source = "var __t,__p='',__j=Array.prototype.join," +
9051 "print=function(){__p+=__j.call(arguments,'');};\n" +
9052 source + "return __p;\n";
9053
9054 try {
9055 render = new Function(settings.variable || 'obj', '_', source);
9056 } catch (e) {
9057 e.source = source;
9058 throw e;
9059 }
9060
9061 if (data) return render(data, _);
9062 var template = function(data) {
9063 return render.call(this, data, _);
9064 };
9065
9066 // Provide the compiled function source as a convenience for precompilation.
9067 template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
9068
9069 return template;
9070 };
9071
9072 // Add a "chain" function, which will delegate to the wrapper.
9073 _.chain = function(obj) {
9074 return _(obj).chain();
9075 };
9076
9077 // OOP
9078 // ---------------
9079 // If Underscore is called as a function, it returns a wrapped object that
9080 // can be used OO-style. This wrapper holds altered versions of all the
9081 // underscore functions. Wrapped objects may be chained.
9082
9083 // Helper function to continue chaining intermediate results.
9084 var result = function(obj) {
9085 return this._chain ? _(obj).chain() : obj;
9086 };
9087
9088 // Add all of the Underscore functions to the wrapper object.
9089 _.mixin(_);
9090
9091 // Add all mutator Array functions to the wrapper.
9092 each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
9093 var method = ArrayProto[name];
9094 _.prototype[name] = function() {
9095 var obj = this._wrapped;
9096 method.apply(obj, arguments);
9097 if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
9098 return result.call(this, obj);
9099 };
9100 });
9101
9102 // Add all accessor Array functions to the wrapper.
9103 each(['concat', 'join', 'slice'], function(name) {
9104 var method = ArrayProto[name];
9105 _.prototype[name] = function() {
9106 return result.call(this, method.apply(this._wrapped, arguments));
9107 };
9108 });
9109
9110 _.extend(_.prototype, {
9111
9112 // Start chaining a wrapped Underscore object.
9113 chain: function() {
9114 this._chain = true;
9115 return this;
9116 },
9117
9118 // Extracts the result from a wrapped and chained object.
9119 value: function() {
9120 return this._wrapped;
9121 }
9122
9123 });
9124
9125 }).call(this);
9126
9127 })()
9128 },{}],11:[function(require,module,exports){
9129 var events = require('events');
9130
9131 exports.isArray = isArray;
9132 exports.isDate = function(obj){return Object.prototype.toString.call(obj) === '[object Date]'};
9133 exports.isRegExp = function(obj){return Object.prototype.toString.call(obj) === '[object RegExp]'};
9134
9135
9136 exports.print = function () {};
9137 exports.puts = function () {};
9138 exports.debug = function() {};
9139
9140 exports.inspect = function(obj, showHidden, depth, colors) {
9141 var seen = [];
9142
9143 var stylize = function(str, styleType) {
9144 // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
9145 var styles =
9146 { 'bold' : [1, 22],
9147 'italic' : [3, 23],
9148 'underline' : [4, 24],
9149 'inverse' : [7, 27],
9150 'white' : [37, 39],
9151 'grey' : [90, 39],
9152 'black' : [30, 39],
9153 'blue' : [34, 39],
9154 'cyan' : [36, 39],
9155 'green' : [32, 39],
9156 'magenta' : [35, 39],
9157 'red' : [31, 39],
9158 'yellow' : [33, 39] };
9159
9160 var style =
9161 { 'special': 'cyan',
9162 'number': 'blue',
9163 'boolean': 'yellow',
9164 'undefined': 'grey',
9165 'null': 'bold',
9166 'string': 'green',
9167 'date': 'magenta',
9168 // "name": intentionally not styling
9169 'regexp': 'red' }[styleType];
9170
9171 if (style) {
9172 return '\033[' + styles[style][0] + 'm' + str +
9173 '\033[' + styles[style][1] + 'm';
9174 } else {
9175 return str;
9176 }
9177 };
9178 if (! colors) {
9179 stylize = function(str, styleType) { return str; };
9180 }
9181
9182 function format(value, recurseTimes) {
9183 // Provide a hook for user-specified inspect functions.
9184 // Check that value is an object with an inspect function on it
9185 if (value && typeof value.inspect === 'function' &&
9186 // Filter out the util module, it's inspect function is special
9187 value !== exports &&
9188 // Also filter out any prototype objects using the circular check.
9189 !(value.constructor && value.constructor.prototype === value)) {
9190 return value.inspect(recurseTimes);
9191 }
9192
9193 // Primitive types cannot have properties
9194 switch (typeof value) {
9195 case 'undefined':
9196 return stylize('undefined', 'undefined');
9197
9198 case 'string':
9199 var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
9200 .replace(/'/g, "\\'")
9201 .replace(/\\"/g, '"') + '\'';
9202 return stylize(simple, 'string');
9203
9204 case 'number':
9205 return stylize('' + value, 'number');
9206
9207 case 'boolean':
9208 return stylize('' + value, 'boolean');
9209 }
9210 // For some reason typeof null is "object", so special case here.
9211 if (value === null) {
9212 return stylize('null', 'null');
9213 }
9214
9215 // Look up the keys of the object.
9216 var visible_keys = Object_keys(value);
9217 var keys = showHidden ? Object_getOwnPropertyNames(value) : visible_keys;
9218
9219 // Functions without properties can be shortcutted.
9220 if (typeof value === 'function' && keys.length === 0) {
9221 if (isRegExp(value)) {
9222 return stylize('' + value, 'regexp');
9223 } else {
9224 var name = value.name ? ': ' + value.name : '';
9225 return stylize('[Function' + name + ']', 'special');
9226 }
9227 }
9228
9229 // Dates without properties can be shortcutted
9230 if (isDate(value) && keys.length === 0) {
9231 return stylize(value.toUTCString(), 'date');
9232 }
9233
9234 var base, type, braces;
9235 // Determine the object type
9236 if (isArray(value)) {
9237 type = 'Array';
9238 braces = ['[', ']'];
9239 } else {
9240 type = 'Object';
9241 braces = ['{', '}'];
9242 }
9243
9244 // Make functions say that they are functions
9245 if (typeof value === 'function') {
9246 var n = value.name ? ': ' + value.name : '';
9247 base = (isRegExp(value)) ? ' ' + value : ' [Function' + n + ']';
9248 } else {
9249 base = '';
9250 }
9251
9252 // Make dates with properties first say the date
9253 if (isDate(value)) {
9254 base = ' ' + value.toUTCString();
9255 }
9256
9257 if (keys.length === 0) {
9258 return braces[0] + base + braces[1];
9259 }
9260
9261 if (recurseTimes < 0) {
9262 if (isRegExp(value)) {
9263 return stylize('' + value, 'regexp');
9264 } else {
9265 return stylize('[Object]', 'special');
9266 }
9267 }
9268
9269 seen.push(value);
9270
9271 var output = keys.map(function(key) {
9272 var name, str;
9273 if (value.__lookupGetter__) {
9274 if (value.__lookupGetter__(key)) {
9275 if (value.__lookupSetter__(key)) {
9276 str = stylize('[Getter/Setter]', 'special');
9277 } else {
9278 str = stylize('[Getter]', 'special');
9279 }
9280 } else {
9281 if (value.__lookupSetter__(key)) {
9282 str = stylize('[Setter]', 'special');
9283 }
9284 }
9285 }
9286 if (visible_keys.indexOf(key) < 0) {
9287 name = '[' + key + ']';
9288 }
9289 if (!str) {
9290 if (seen.indexOf(value[key]) < 0) {
9291 if (recurseTimes === null) {
9292 str = format(value[key]);
9293 } else {
9294 str = format(value[key], recurseTimes - 1);
9295 }
9296 if (str.indexOf('\n') > -1) {
9297 if (isArray(value)) {
9298 str = str.split('\n').map(function(line) {
9299 return ' ' + line;
9300 }).join('\n').substr(2);
9301 } else {
9302 str = '\n' + str.split('\n').map(function(line) {
9303 return ' ' + line;
9304 }).join('\n');
9305 }
9306 }
9307 } else {
9308 str = stylize('[Circular]', 'special');
9309 }
9310 }
9311 if (typeof name === 'undefined') {
9312 if (type === 'Array' && key.match(/^\d+$/)) {
9313 return str;
9314 }
9315 name = JSON.stringify('' + key);
9316 if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
9317 name = name.substr(1, name.length - 2);
9318 name = stylize(name, 'name');
9319 } else {
9320 name = name.replace(/'/g, "\\'")
9321 .replace(/\\"/g, '"')
9322 .replace(/(^"|"$)/g, "'");
9323 name = stylize(name, 'string');
9324 }
9325 }
9326
9327 return name + ': ' + str;
9328 });
9329
9330 seen.pop();
9331
9332 var numLinesEst = 0;
9333 var length = output.reduce(function(prev, cur) {
9334 numLinesEst++;
9335 if (cur.indexOf('\n') >= 0) numLinesEst++;
9336 return prev + cur.length + 1;
9337 }, 0);
9338
9339 if (length > 50) {
9340 output = braces[0] +
9341 (base === '' ? '' : base + '\n ') +
9342 ' ' +
9343 output.join(',\n ') +
9344 ' ' +
9345 braces[1];
9346
9347 } else {
9348 output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
9349 }
9350
9351 return output;
9352 }
9353 return format(obj, (typeof depth === 'undefined' ? 2 : depth));
9354 };
9355
9356
9357 function isArray(ar) {
9358 return ar instanceof Array ||
9359 Array.isArray(ar) ||
9360 (ar && ar !== Object.prototype && isArray(ar.__proto__));
9361 }
9362
9363
9364 function isRegExp(re) {
9365 return re instanceof RegExp ||
9366 (typeof re === 'object' && Object.prototype.toString.call(re) === '[object RegExp]');
9367 }
9368
9369
9370 function isDate(d) {
9371 if (d instanceof Date) return true;
9372 if (typeof d !== 'object') return false;
9373 var properties = Date.prototype && Object_getOwnPropertyNames(Date.prototype);
9374 var proto = d.__proto__ && Object_getOwnPropertyNames(d.__proto__);
9375 return JSON.stringify(proto) === JSON.stringify(properties);
9376 }
9377
9378 function pad(n) {
9379 return n < 10 ? '0' + n.toString(10) : n.toString(10);
9380 }
9381
9382 var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
9383 'Oct', 'Nov', 'Dec'];
9384
9385 // 26 Feb 16:19:34
9386 function timestamp() {
9387 var d = new Date();
9388 var time = [pad(d.getHours()),
9389 pad(d.getMinutes()),
9390 pad(d.getSeconds())].join(':');
9391 return [d.getDate(), months[d.getMonth()], time].join(' ');
9392 }
9393
9394 exports.log = function (msg) {};
9395
9396 exports.pump = null;
9397
9398 var Object_keys = Object.keys || function (obj) {
9399 var res = [];
9400 for (var key in obj) res.push(key);
9401 return res;
9402 };
9403
9404 var Object_getOwnPropertyNames = Object.getOwnPropertyNames || function (obj) {
9405 var res = [];
9406 for (var key in obj) {
9407 if (Object.hasOwnProperty.call(obj, key)) res.push(key);
9408 }
9409 return res;
9410 };
9411
9412 var Object_create = Object.create || function (prototype, properties) {
9413 // from es5-shim
9414 var object;
9415 if (prototype === null) {
9416 object = { '__proto__' : null };
9417 }
9418 else {
9419 if (typeof prototype !== 'object') {
9420 throw new TypeError(
9421 'typeof prototype[' + (typeof prototype) + '] != \'object\''
9422 );
9423 }
9424 var Type = function () {};
9425 Type.prototype = prototype;
9426 object = new Type();
9427 object.__proto__ = prototype;
9428 }
9429 if (typeof properties !== 'undefined' && Object.defineProperties) {
9430 Object.defineProperties(object, properties);
9431 }
9432 return object;
9433 };
9434
9435 exports.inherits = function(ctor, superCtor) {
9436 ctor.super_ = superCtor;
9437 ctor.prototype = Object_create(superCtor.prototype, {
9438 constructor: {
9439 value: ctor,
9440 enumerable: false,
9441 writable: true,
9442 configurable: true
9443 }
9444 });
9445 };
9446
9447 var formatRegExp = /%[sdj%]/g;
9448 exports.format = function(f) {
9449 if (typeof f !== 'string') {
9450 var objects = [];
9451 for (var i = 0; i < arguments.length; i++) {
9452 objects.push(exports.inspect(arguments[i]));
9453 }
9454 return objects.join(' ');
9455 }
9456
9457 var i = 1;
9458 var args = arguments;
9459 var len = args.length;
9460 var str = String(f).replace(formatRegExp, function(x) {
9461 if (x === '%%') return '%';
9462 if (i >= len) return x;
9463 switch (x) {
9464 case '%s': return String(args[i++]);
9465 case '%d': return Number(args[i++]);
9466 case '%j': return JSON.stringify(args[i++]);
9467 default:
9468 return x;
9469 }
9470 });
9471 for(var x = args[i]; i < len; x = args[++i]){
9472 if (x === null || typeof x !== 'object') {
9473 str += ' ' + x;
9474 } else {
9475 str += ' ' + exports.inspect(x);
9476 }
9477 }
9478 return str;
9479 };
9480
9481 },{"events":2}],12:[function(require,module,exports){
9482 (function(){// UTILITY
9483 var util = require('util');
9484 var Buffer = require("buffer").Buffer;
9485 var pSlice = Array.prototype.slice;
9486
9487 function objectKeys(object) {
9488 if (Object.keys) return Object.keys(object);
9489 var result = [];
9490 for (var name in object) {
9491 if (Object.prototype.hasOwnProperty.call(object, name)) {
9492 result.push(name);
9493 }
9494 }
9495 return result;
9496 }
9497
9498 // 1. The assert module provides functions that throw
9499 // AssertionError's when particular conditions are not met. The
9500 // assert module must conform to the following interface.
9501
9502 var assert = module.exports = ok;
9503
9504 // 2. The AssertionError is defined in assert.
9505 // new assert.AssertionError({ message: message,
9506 // actual: actual,
9507 // expected: expected })
9508
9509 assert.AssertionError = function AssertionError(options) {
9510 this.name = 'AssertionError';
9511 this.message = options.message;
9512 this.actual = options.actual;
9513 this.expected = options.expected;
9514 this.operator = options.operator;
9515 var stackStartFunction = options.stackStartFunction || fail;
9516
9517 if (Error.captureStackTrace) {
9518 Error.captureStackTrace(this, stackStartFunction);
9519 }
9520 };
9521 util.inherits(assert.AssertionError, Error);
9522
9523 function replacer(key, value) {
9524 if (value === undefined) {
9525 return '' + value;
9526 }
9527 if (typeof value === 'number' && (isNaN(value) || !isFinite(value))) {
9528 return value.toString();
9529 }
9530 if (typeof value === 'function' || value instanceof RegExp) {
9531 return value.toString();
9532 }
9533 return value;
9534 }
9535
9536 function truncate(s, n) {
9537 if (typeof s == 'string') {
9538 return s.length < n ? s : s.slice(0, n);
9539 } else {
9540 return s;
9541 }
9542 }
9543
9544 assert.AssertionError.prototype.toString = function() {
9545 if (this.message) {
9546 return [this.name + ':', this.message].join(' ');
9547 } else {
9548 return [
9549 this.name + ':',
9550 truncate(JSON.stringify(this.actual, replacer), 128),
9551 this.operator,
9552 truncate(JSON.stringify(this.expected, replacer), 128)
9553 ].join(' ');
9554 }
9555 };
9556
9557 // assert.AssertionError instanceof Error
9558
9559 assert.AssertionError.__proto__ = Error.prototype;
9560
9561 // At present only the three keys mentioned above are used and
9562 // understood by the spec. Implementations or sub modules can pass
9563 // other keys to the AssertionError's constructor - they will be
9564 // ignored.
9565
9566 // 3. All of the following functions must throw an AssertionError
9567 // when a corresponding condition is not met, with a message that
9568 // may be undefined if not provided. All assertion methods provide
9569 // both the actual and expected values to the assertion error for
9570 // display purposes.
9571
9572 function fail(actual, expected, message, operator, stackStartFunction) {
9573 throw new assert.AssertionError({
9574 message: message,
9575 actual: actual,
9576 expected: expected,
9577 operator: operator,
9578 stackStartFunction: stackStartFunction
9579 });
9580 }
9581
9582 // EXTENSION! allows for well behaved errors defined elsewhere.
9583 assert.fail = fail;
9584
9585 // 4. Pure assertion tests whether a value is truthy, as determined
9586 // by !!guard.
9587 // assert.ok(guard, message_opt);
9588 // This statement is equivalent to assert.equal(true, guard,
9589 // message_opt);. To test strictly for the value true, use
9590 // assert.strictEqual(true, guard, message_opt);.
9591
9592 function ok(value, message) {
9593 if (!!!value) fail(value, true, message, '==', assert.ok);
9594 }
9595 assert.ok = ok;
9596
9597 // 5. The equality assertion tests shallow, coercive equality with
9598 // ==.
9599 // assert.equal(actual, expected, message_opt);
9600
9601 assert.equal = function equal(actual, expected, message) {
9602 if (actual != expected) fail(actual, expected, message, '==', assert.equal);
9603 };
9604
9605 // 6. The non-equality assertion tests for whether two objects are not equal
9606 // with != assert.notEqual(actual, expected, message_opt);
9607
9608 assert.notEqual = function notEqual(actual, expected, message) {
9609 if (actual == expected) {
9610 fail(actual, expected, message, '!=', assert.notEqual);
9611 }
9612 };
9613
9614 // 7. The equivalence assertion tests a deep equality relation.
9615 // assert.deepEqual(actual, expected, message_opt);
9616
9617 assert.deepEqual = function deepEqual(actual, expected, message) {
9618 if (!_deepEqual(actual, expected)) {
9619 fail(actual, expected, message, 'deepEqual', assert.deepEqual);
9620 }
9621 };
9622
9623 function _deepEqual(actual, expected) {
9624 // 7.1. All identical values are equivalent, as determined by ===.
9625 if (actual === expected) {
9626 return true;
9627
9628 } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
9629 if (actual.length != expected.length) return false;
9630
9631 for (var i = 0; i < actual.length; i++) {
9632 if (actual[i] !== expected[i]) return false;
9633 }
9634
9635 return true;
9636
9637 // 7.2. If the expected value is a Date object, the actual value is
9638 // equivalent if it is also a Date object that refers to the same time.
9639 } else if (actual instanceof Date && expected instanceof Date) {
9640 return actual.getTime() === expected.getTime();
9641
9642 // 7.3. Other pairs that do not both pass typeof value == 'object',
9643 // equivalence is determined by ==.
9644 } else if (typeof actual != 'object' && typeof expected != 'object') {
9645 return actual == expected;
9646
9647 // 7.4. For all other Object pairs, including Array objects, equivalence is
9648 // determined by having the same number of owned properties (as verified
9649 // with Object.prototype.hasOwnProperty.call), the same set of keys
9650 // (although not necessarily the same order), equivalent values for every
9651 // corresponding key, and an identical 'prototype' property. Note: this
9652 // accounts for both named and indexed properties on Arrays.
9653 } else {
9654 return objEquiv(actual, expected);
9655 }
9656 }
9657
9658 function isUndefinedOrNull(value) {
9659 return value === null || value === undefined;
9660 }
9661
9662 function isArguments(object) {
9663 return Object.prototype.toString.call(object) == '[object Arguments]';
9664 }
9665
9666 function objEquiv(a, b) {
9667 if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
9668 return false;
9669 // an identical 'prototype' property.
9670 if (a.prototype !== b.prototype) return false;
9671 //~~~I've managed to break Object.keys through screwy arguments passing.
9672 // Converting to array solves the problem.
9673 if (isArguments(a)) {
9674 if (!isArguments(b)) {
9675 return false;
9676 }
9677 a = pSlice.call(a);
9678 b = pSlice.call(b);
9679 return _deepEqual(a, b);
9680 }
9681 try {
9682 var ka = objectKeys(a),
9683 kb = objectKeys(b),
9684 key, i;
9685 } catch (e) {//happens when one is a string literal and the other isn't
9686 return false;
9687 }
9688 // having the same number of owned properties (keys incorporates
9689 // hasOwnProperty)
9690 if (ka.length != kb.length)
9691 return false;
9692 //the same set of keys (although not necessarily the same order),
9693 ka.sort();
9694 kb.sort();
9695 //~~~cheap key test
9696 for (i = ka.length - 1; i >= 0; i--) {
9697 if (ka[i] != kb[i])
9698 return false;
9699 }
9700 //equivalent values for every corresponding key, and
9701 //~~~possibly expensive deep test
9702 for (i = ka.length - 1; i >= 0; i--) {
9703 key = ka[i];
9704 if (!_deepEqual(a[key], b[key])) return false;
9705 }
9706 return true;
9707 }
9708
9709 // 8. The non-equivalence assertion tests for any deep inequality.
9710 // assert.notDeepEqual(actual, expected, message_opt);
9711
9712 assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
9713 if (_deepEqual(actual, expected)) {
9714 fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
9715 }
9716 };
9717
9718 // 9. The strict equality assertion tests strict equality, as determined by ===.
9719 // assert.strictEqual(actual, expected, message_opt);
9720
9721 assert.strictEqual = function strictEqual(actual, expected, message) {
9722 if (actual !== expected) {
9723 fail(actual, expected, message, '===', assert.strictEqual);
9724 }
9725 };
9726
9727 // 10. The strict non-equality assertion tests for strict inequality, as
9728 // determined by !==. assert.notStrictEqual(actual, expected, message_opt);
9729
9730 assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
9731 if (actual === expected) {
9732 fail(actual, expected, message, '!==', assert.notStrictEqual);
9733 }
9734 };
9735
9736 function expectedException(actual, expected) {
9737 if (!actual || !expected) {
9738 return false;
9739 }
9740
9741 if (expected instanceof RegExp) {
9742 return expected.test(actual);
9743 } else if (actual instanceof expected) {
9744 return true;
9745 } else if (expected.call({}, actual) === true) {
9746 return true;
9747 }
9748
9749 return false;
9750 }
9751
9752 function _throws(shouldThrow, block, expected, message) {
9753 var actual;
9754
9755 if (typeof expected === 'string') {
9756 message = expected;
9757 expected = null;
9758 }
9759
9760 try {
9761 block();
9762 } catch (e) {
9763 actual = e;
9764 }
9765
9766 message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
9767 (message ? ' ' + message : '.');
9768
9769 if (shouldThrow && !actual) {
9770 fail('Missing expected exception' + message);
9771 }
9772
9773 if (!shouldThrow && expectedException(actual, expected)) {
9774 fail('Got unwanted exception' + message);
9775 }
9776
9777 if ((shouldThrow && actual && expected &&
9778 !expectedException(actual, expected)) || (!shouldThrow && actual)) {
9779 throw actual;
9780 }
9781 }
9782
9783 // 11. Expected to throw an error:
9784 // assert.throws(block, Error_opt, message_opt);
9785
9786 assert.throws = function(block, /*optional*/error, /*optional*/message) {
9787 _throws.apply(this, [true].concat(pSlice.call(arguments)));
9788 };
9789
9790 // EXTENSION! This is annoying to write outside this module.
9791 assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
9792 _throws.apply(this, [false].concat(pSlice.call(arguments)));
9793 };
9794
9795 assert.ifError = function(err) { if (err) {throw err;}};
9796
9797 })()
9798 },{"util":11,"buffer":13}],14:[function(require,module,exports){
9799 exports.readIEEE754 = function(buffer, offset, isBE, mLen, nBytes) {
9800 var e, m,
9801 eLen = nBytes * 8 - mLen - 1,
9802 eMax = (1 << eLen) - 1,
9803 eBias = eMax >> 1,
9804 nBits = -7,
9805 i = isBE ? 0 : (nBytes - 1),
9806 d = isBE ? 1 : -1,
9807 s = buffer[offset + i];
9808
9809 i += d;
9810
9811 e = s & ((1 << (-nBits)) - 1);
9812 s >>= (-nBits);
9813 nBits += eLen;
9814 for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8);
9815
9816 m = e & ((1 << (-nBits)) - 1);
9817 e >>= (-nBits);
9818 nBits += mLen;
9819 for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8);
9820
9821 if (e === 0) {
9822 e = 1 - eBias;
9823 } else if (e === eMax) {
9824 return m ? NaN : ((s ? -1 : 1) * Infinity);
9825 } else {
9826 m = m + Math.pow(2, mLen);
9827 e = e - eBias;
9828 }
9829 return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
9830 };
9831
9832 exports.writeIEEE754 = function(buffer, value, offset, isBE, mLen, nBytes) {
9833 var e, m, c,
9834 eLen = nBytes * 8 - mLen - 1,
9835 eMax = (1 << eLen) - 1,
9836 eBias = eMax >> 1,
9837 rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
9838 i = isBE ? (nBytes - 1) : 0,
9839 d = isBE ? -1 : 1,
9840 s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
9841
9842 value = Math.abs(value);
9843
9844 if (isNaN(value) || value === Infinity) {
9845 m = isNaN(value) ? 1 : 0;
9846 e = eMax;
9847 } else {
9848 e = Math.floor(Math.log(value) / Math.LN2);
9849 if (value * (c = Math.pow(2, -e)) < 1) {
9850 e--;
9851 c *= 2;
9852 }
9853 if (e + eBias >= 1) {
9854 value += rt / c;
9855 } else {
9856 value += rt * Math.pow(2, 1 - eBias);
9857 }
9858 if (value * c >= 2) {
9859 e++;
9860 c /= 2;
9861 }
9862
9863 if (e + eBias >= eMax) {
9864 m = 0;
9865 e = eMax;
9866 } else if (e + eBias >= 1) {
9867 m = (value * c - 1) * Math.pow(2, mLen);
9868 e = e + eBias;
9869 } else {
9870 m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
9871 e = 0;
9872 }
9873 }
9874
9875 for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8);
9876
9877 e = (e << mLen) | m;
9878 eLen += mLen;
9879 for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8);
9880
9881 buffer[offset + i - d] |= s * 128;
9882 };
9883
9884 },{}],13:[function(require,module,exports){
9885 (function(){function SlowBuffer (size) {
9886 this.length = size;
9887 };
9888
9889 var assert = require('assert');
9890
9891 exports.INSPECT_MAX_BYTES = 50;
9892
9893
9894 function toHex(n) {
9895 if (n < 16) return '0' + n.toString(16);
9896 return n.toString(16);
9897 }
9898
9899 function utf8ToBytes(str) {
9900 var byteArray = [];
9901 for (var i = 0; i < str.length; i++)
9902 if (str.charCodeAt(i) <= 0x7F)
9903 byteArray.push(str.charCodeAt(i));
9904 else {
9905 var h = encodeURIComponent(str.charAt(i)).substr(1).split('%');
9906 for (var j = 0; j < h.length; j++)
9907 byteArray.push(parseInt(h[j], 16));
9908 }
9909
9910 return byteArray;
9911 }
9912
9913 function asciiToBytes(str) {
9914 var byteArray = []
9915 for (var i = 0; i < str.length; i++ )
9916 // Node's code seems to be doing this and not & 0x7F..
9917 byteArray.push( str.charCodeAt(i) & 0xFF );
9918
9919 return byteArray;
9920 }
9921
9922 function base64ToBytes(str) {
9923 return require("base64-js").toByteArray(str);
9924 }
9925
9926 SlowBuffer.byteLength = function (str, encoding) {
9927 switch (encoding || "utf8") {
9928 case 'hex':
9929 return str.length / 2;
9930
9931 case 'utf8':
9932 case 'utf-8':
9933 return utf8ToBytes(str).length;
9934
9935 case 'ascii':
9936 case 'binary':
9937 return str.length;
9938
9939 case 'base64':
9940 return base64ToBytes(str).length;
9941
9942 default:
9943 throw new Error('Unknown encoding');
9944 }
9945 };
9946
9947 function blitBuffer(src, dst, offset, length) {
9948 var pos, i = 0;
9949 while (i < length) {
9950 if ((i+offset >= dst.length) || (i >= src.length))
9951 break;
9952
9953 dst[i + offset] = src[i];
9954 i++;
9955 }
9956 return i;
9957 }
9958
9959 SlowBuffer.prototype.utf8Write = function (string, offset, length) {
9960 var bytes, pos;
9961 return SlowBuffer._charsWritten = blitBuffer(utf8ToBytes(string), this, offset, length);
9962 };
9963
9964 SlowBuffer.prototype.asciiWrite = function (string, offset, length) {
9965 var bytes, pos;
9966 return SlowBuffer._charsWritten = blitBuffer(asciiToBytes(string), this, offset, length);
9967 };
9968
9969 SlowBuffer.prototype.binaryWrite = SlowBuffer.prototype.asciiWrite;
9970
9971 SlowBuffer.prototype.base64Write = function (string, offset, length) {
9972 var bytes, pos;
9973 return SlowBuffer._charsWritten = blitBuffer(base64ToBytes(string), this, offset, length);
9974 };
9975
9976 SlowBuffer.prototype.base64Slice = function (start, end) {
9977 var bytes = Array.prototype.slice.apply(this, arguments)
9978 return require("base64-js").fromByteArray(bytes);
9979 }
9980
9981 function decodeUtf8Char(str) {
9982 try {
9983 return decodeURIComponent(str);
9984 } catch (err) {
9985 return String.fromCharCode(0xFFFD); // UTF 8 invalid char
9986 }
9987 }
9988
9989 SlowBuffer.prototype.utf8Slice = function () {
9990 var bytes = Array.prototype.slice.apply(this, arguments);
9991 var res = "";
9992 var tmp = "";
9993 var i = 0;
9994 while (i < bytes.length) {
9995 if (bytes[i] <= 0x7F) {
9996 res += decodeUtf8Char(tmp) + String.fromCharCode(bytes[i]);
9997 tmp = "";
9998 } else
9999 tmp += "%" + bytes[i].toString(16);
10000
10001 i++;
10002 }
10003
10004 return res + decodeUtf8Char(tmp);
10005 }
10006
10007 SlowBuffer.prototype.asciiSlice = function () {
10008 var bytes = Array.prototype.slice.apply(this, arguments);
10009 var ret = "";
10010 for (var i = 0; i < bytes.length; i++)
10011 ret += String.fromCharCode(bytes[i]);
10012 return ret;
10013 }
10014
10015 SlowBuffer.prototype.binarySlice = SlowBuffer.prototype.asciiSlice;
10016
10017 SlowBuffer.prototype.inspect = function() {
10018 var out = [],
10019 len = this.length;
10020 for (var i = 0; i < len; i++) {
10021 out[i] = toHex(this[i]);
10022 if (i == exports.INSPECT_MAX_BYTES) {
10023 out[i + 1] = '...';
10024 break;
10025 }
10026 }
10027 return '<SlowBuffer ' + out.join(' ') + '>';
10028 };
10029
10030
10031 SlowBuffer.prototype.hexSlice = function(start, end) {
10032 var len = this.length;
10033
10034 if (!start || start < 0) start = 0;
10035 if (!end || end < 0 || end > len) end = len;
10036
10037 var out = '';
10038 for (var i = start; i < end; i++) {
10039 out += toHex(this[i]);
10040 }
10041 return out;
10042 };
10043
10044
10045 SlowBuffer.prototype.toString = function(encoding, start, end) {
10046 encoding = String(encoding || 'utf8').toLowerCase();
10047 start = +start || 0;
10048 if (typeof end == 'undefined') end = this.length;
10049
10050 // Fastpath empty strings
10051 if (+end == start) {
10052 return '';
10053 }
10054
10055 switch (encoding) {
10056 case 'hex':
10057 return this.hexSlice(start, end);
10058
10059 case 'utf8':
10060 case 'utf-8':
10061 return this.utf8Slice(start, end);
10062
10063 case 'ascii':
10064 return this.asciiSlice(start, end);
10065
10066 case 'binary':
10067 return this.binarySlice(start, end);
10068
10069 case 'base64':
10070 return this.base64Slice(start, end);
10071
10072 case 'ucs2':
10073 case 'ucs-2':
10074 return this.ucs2Slice(start, end);
10075
10076 default:
10077 throw new Error('Unknown encoding');
10078 }
10079 };
10080
10081
10082 SlowBuffer.prototype.hexWrite = function(string, offset, length) {
10083 offset = +offset || 0;
10084 var remaining = this.length - offset;
10085 if (!length) {
10086 length = remaining;
10087 } else {
10088 length = +length;
10089 if (length > remaining) {
10090 length = remaining;
10091 }
10092 }
10093
10094 // must be an even number of digits
10095 var strLen = string.length;
10096 if (strLen % 2) {
10097 throw new Error('Invalid hex string');
10098 }
10099 if (length > strLen / 2) {
10100 length = strLen / 2;
10101 }
10102 for (var i = 0; i < length; i++) {
10103 var byte = parseInt(string.substr(i * 2, 2), 16);
10104 if (isNaN(byte)) throw new Error('Invalid hex string');
10105 this[offset + i] = byte;
10106 }
10107 SlowBuffer._charsWritten = i * 2;
10108 return i;
10109 };
10110
10111
10112 SlowBuffer.prototype.write = function(string, offset, length, encoding) {
10113 // Support both (string, offset, length, encoding)
10114 // and the legacy (string, encoding, offset, length)
10115 if (isFinite(offset)) {
10116 if (!isFinite(length)) {
10117 encoding = length;
10118 length = undefined;
10119 }
10120 } else { // legacy
10121 var swap = encoding;
10122 encoding = offset;
10123 offset = length;
10124 length = swap;
10125 }
10126
10127 offset = +offset || 0;
10128 var remaining = this.length - offset;
10129 if (!length) {
10130 length = remaining;
10131 } else {
10132 length = +length;
10133 if (length > remaining) {
10134 length = remaining;
10135 }
10136 }
10137 encoding = String(encoding || 'utf8').toLowerCase();
10138
10139 switch (encoding) {
10140 case 'hex':
10141 return this.hexWrite(string, offset, length);
10142
10143 case 'utf8':
10144 case 'utf-8':
10145 return this.utf8Write(string, offset, length);
10146
10147 case 'ascii':
10148 return this.asciiWrite(string, offset, length);
10149
10150 case 'binary':
10151 return this.binaryWrite(string, offset, length);
10152
10153 case 'base64':
10154 return this.base64Write(string, offset, length);
10155
10156 case 'ucs2':
10157 case 'ucs-2':
10158 return this.ucs2Write(string, offset, length);
10159
10160 default:
10161 throw new Error('Unknown encoding');
10162 }
10163 };
10164
10165
10166 // slice(start, end)
10167 SlowBuffer.prototype.slice = function(start, end) {
10168 if (end === undefined) end = this.length;
10169
10170 if (end > this.length) {
10171 throw new Error('oob');
10172 }
10173 if (start > end) {
10174 throw new Error('oob');
10175 }
10176
10177 return new Buffer(this, end - start, +start);
10178 };
10179
10180 SlowBuffer.prototype.copy = function(target, targetstart, sourcestart, sourceend) {
10181 var temp = [];
10182 for (var i=sourcestart; i<sourceend; i++) {
10183 assert.ok(typeof this[i] !== 'undefined', "copying undefined buffer bytes!");
10184 temp.push(this[i]);
10185 }
10186
10187 for (var i=targetstart; i<targetstart+temp.length; i++) {
10188 target[i] = temp[i-targetstart];
10189 }
10190 };
10191
10192 SlowBuffer.prototype.fill = function(value, start, end) {
10193 if (end > this.length) {
10194 throw new Error('oob');
10195 }
10196 if (start > end) {
10197 throw new Error('oob');
10198 }
10199
10200 for (var i = start; i < end; i++) {
10201 this[i] = value;
10202 }
10203 }
10204
10205 function coerce(length) {
10206 // Coerce length to a number (possibly NaN), round up
10207 // in case it's fractional (e.g. 123.456) then do a
10208 // double negate to coerce a NaN to 0. Easy, right?
10209 length = ~~Math.ceil(+length);
10210 return length < 0 ? 0 : length;
10211 }
10212
10213
10214 // Buffer
10215
10216 function Buffer(subject, encoding, offset) {
10217 if (!(this instanceof Buffer)) {
10218 return new Buffer(subject, encoding, offset);
10219 }
10220
10221 var type;
10222
10223 // Are we slicing?
10224 if (typeof offset === 'number') {
10225 this.length = coerce(encoding);
10226 this.parent = subject;
10227 this.offset = offset;
10228 } else {
10229 // Find the length
10230 switch (type = typeof subject) {
10231 case 'number':
10232 this.length = coerce(subject);
10233 break;
10234
10235 case 'string':
10236 this.length = Buffer.byteLength(subject, encoding);
10237 break;
10238
10239 case 'object': // Assume object is an array
10240 this.length = coerce(subject.length);
10241 break;
10242
10243 default:
10244 throw new Error('First argument needs to be a number, ' +
10245 'array or string.');
10246 }
10247
10248 if (this.length > Buffer.poolSize) {
10249 // Big buffer, just alloc one.
10250 this.parent = new SlowBuffer(this.length);
10251 this.offset = 0;
10252
10253 } else {
10254 // Small buffer.
10255 if (!pool || pool.length - pool.used < this.length) allocPool();
10256 this.parent = pool;
10257 this.offset = pool.used;
10258 pool.used += this.length;
10259 }
10260
10261 // Treat array-ish objects as a byte array.
10262 if (isArrayIsh(subject)) {
10263 for (var i = 0; i < this.length; i++) {
10264 if (subject instanceof Buffer) {
10265 this.parent[i + this.offset] = subject.readUInt8(i);
10266 }
10267 else {
10268 this.parent[i + this.offset] = subject[i];
10269 }
10270 }
10271 } else if (type == 'string') {
10272 // We are a string
10273 this.length = this.write(subject, 0, encoding);
10274 }
10275 }
10276
10277 }
10278
10279 function isArrayIsh(subject) {
10280 return Array.isArray(subject) || Buffer.isBuffer(subject) ||
10281 subject && typeof subject === 'object' &&
10282 typeof subject.length === 'number';
10283 }
10284
10285 exports.SlowBuffer = SlowBuffer;
10286 exports.Buffer = Buffer;
10287
10288 Buffer.poolSize = 8 * 1024;
10289 var pool;
10290
10291 function allocPool() {
10292 pool = new SlowBuffer(Buffer.poolSize);
10293 pool.used = 0;
10294 }
10295
10296
10297 // Static methods
10298 Buffer.isBuffer = function isBuffer(b) {
10299 return b instanceof Buffer || b instanceof SlowBuffer;
10300 };
10301
10302 Buffer.concat = function (list, totalLength) {
10303 if (!Array.isArray(list)) {
10304 throw new Error("Usage: Buffer.concat(list, [totalLength])\n \
10305 list should be an Array.");
10306 }
10307
10308 if (list.length === 0) {
10309 return new Buffer(0);
10310 } else if (list.length === 1) {
10311 return list[0];
10312 }
10313
10314 if (typeof totalLength !== 'number') {
10315 totalLength = 0;
10316 for (var i = 0; i < list.length; i++) {
10317 var buf = list[i];
10318 totalLength += buf.length;
10319 }
10320 }
10321
10322 var buffer = new Buffer(totalLength);
10323 var pos = 0;
10324 for (var i = 0; i < list.length; i++) {
10325 var buf = list[i];
10326 buf.copy(buffer, pos);
10327 pos += buf.length;
10328 }
10329 return buffer;
10330 };
10331
10332 // Inspect
10333 Buffer.prototype.inspect = function inspect() {
10334 var out = [],
10335 len = this.length;
10336
10337 for (var i = 0; i < len; i++) {
10338 out[i] = toHex(this.parent[i + this.offset]);
10339 if (i == exports.INSPECT_MAX_BYTES) {
10340 out[i + 1] = '...';
10341 break;
10342 }
10343 }
10344
10345 return '<Buffer ' + out.join(' ') + '>';
10346 };
10347
10348
10349 Buffer.prototype.get = function get(i) {
10350 if (i < 0 || i >= this.length) throw new Error('oob');
10351 return this.parent[this.offset + i];
10352 };
10353
10354
10355 Buffer.prototype.set = function set(i, v) {
10356 if (i < 0 || i >= this.length) throw new Error('oob');
10357 return this.parent[this.offset + i] = v;
10358 };
10359
10360
10361 // write(string, offset = 0, length = buffer.length-offset, encoding = 'utf8')
10362 Buffer.prototype.write = function(string, offset, length, encoding) {
10363 // Support both (string, offset, length, encoding)
10364 // and the legacy (string, encoding, offset, length)
10365 if (isFinite(offset)) {
10366 if (!isFinite(length)) {
10367 encoding = length;
10368 length = undefined;
10369 }
10370 } else { // legacy
10371 var swap = encoding;
10372 encoding = offset;
10373 offset = length;
10374 length = swap;
10375 }
10376
10377 offset = +offset || 0;
10378 var remaining = this.length - offset;
10379 if (!length) {
10380 length = remaining;
10381 } else {
10382 length = +length;
10383 if (length > remaining) {
10384 length = remaining;
10385 }
10386 }
10387 encoding = String(encoding || 'utf8').toLowerCase();
10388
10389 var ret;
10390 switch (encoding) {
10391 case 'hex':
10392 ret = this.parent.hexWrite(string, this.offset + offset, length);
10393 break;
10394
10395 case 'utf8':
10396 case 'utf-8':
10397 ret = this.parent.utf8Write(string, this.offset + offset, length);
10398 break;
10399
10400 case 'ascii':
10401 ret = this.parent.asciiWrite(string, this.offset + offset, length);
10402 break;
10403
10404 case 'binary':
10405 ret = this.parent.binaryWrite(string, this.offset + offset, length);
10406 break;
10407
10408 case 'base64':
10409 // Warning: maxLength not taken into account in base64Write
10410 ret = this.parent.base64Write(string, this.offset + offset, length);
10411 break;
10412
10413 case 'ucs2':
10414 case 'ucs-2':
10415 ret = this.parent.ucs2Write(string, this.offset + offset, length);
10416 break;
10417
10418 default:
10419 throw new Error('Unknown encoding');
10420 }
10421
10422 Buffer._charsWritten = SlowBuffer._charsWritten;
10423
10424 return ret;
10425 };
10426
10427
10428 // toString(encoding, start=0, end=buffer.length)
10429 Buffer.prototype.toString = function(encoding, start, end) {
10430 encoding = String(encoding || 'utf8').toLowerCase();
10431
10432 if (typeof start == 'undefined' || start < 0) {
10433 start = 0;
10434 } else if (start > this.length) {
10435 start = this.length;
10436 }
10437
10438 if (typeof end == 'undefined' || end > this.length) {
10439 end = this.length;
10440 } else if (end < 0) {
10441 end = 0;
10442 }
10443
10444 start = start + this.offset;
10445 end = end + this.offset;
10446
10447 switch (encoding) {
10448 case 'hex':
10449 return this.parent.hexSlice(start, end);
10450
10451 case 'utf8':
10452 case 'utf-8':
10453 return this.parent.utf8Slice(start, end);
10454
10455 case 'ascii':
10456 return this.parent.asciiSlice(start, end);
10457
10458 case 'binary':
10459 return this.parent.binarySlice(start, end);
10460
10461 case 'base64':
10462 return this.parent.base64Slice(start, end);
10463
10464 case 'ucs2':
10465 case 'ucs-2':
10466 return this.parent.ucs2Slice(start, end);
10467
10468 default:
10469 throw new Error('Unknown encoding');
10470 }
10471 };
10472
10473
10474 // byteLength
10475 Buffer.byteLength = SlowBuffer.byteLength;
10476
10477
10478 // fill(value, start=0, end=buffer.length)
10479 Buffer.prototype.fill = function fill(value, start, end) {
10480 value || (value = 0);
10481 start || (start = 0);
10482 end || (end = this.length);
10483
10484 if (typeof value === 'string') {
10485 value = value.charCodeAt(0);
10486 }
10487 if (!(typeof value === 'number') || isNaN(value)) {
10488 throw new Error('value is not a number');
10489 }
10490
10491 if (end < start) throw new Error('end < start');
10492
10493 // Fill 0 bytes; we're done
10494 if (end === start) return 0;
10495 if (this.length == 0) return 0;
10496
10497 if (start < 0 || start >= this.length) {
10498 throw new Error('start out of bounds');
10499 }
10500
10501 if (end < 0 || end > this.length) {
10502 throw new Error('end out of bounds');
10503 }
10504
10505 return this.parent.fill(value,
10506 start + this.offset,
10507 end + this.offset);
10508 };
10509
10510
10511 // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
10512 Buffer.prototype.copy = function(target, target_start, start, end) {
10513 var source = this;
10514 start || (start = 0);
10515 end || (end = this.length);
10516 target_start || (target_start = 0);
10517
10518 if (end < start) throw new Error('sourceEnd < sourceStart');
10519
10520 // Copy 0 bytes; we're done
10521 if (end === start) return 0;
10522 if (target.length == 0 || source.length == 0) return 0;
10523
10524 if (target_start < 0 || target_start >= target.length) {
10525 throw new Error('targetStart out of bounds');
10526 }
10527
10528 if (start < 0 || start >= source.length) {
10529 throw new Error('sourceStart out of bounds');
10530 }
10531
10532 if (end < 0 || end > source.length) {
10533 throw new Error('sourceEnd out of bounds');
10534 }
10535
10536 // Are we oob?
10537 if (end > this.length) {
10538 end = this.length;
10539 }
10540
10541 if (target.length - target_start < end - start) {
10542 end = target.length - target_start + start;
10543 }
10544
10545 return this.parent.copy(target.parent,
10546 target_start + target.offset,
10547 start + this.offset,
10548 end + this.offset);
10549 };
10550
10551
10552 // slice(start, end)
10553 Buffer.prototype.slice = function(start, end) {
10554 if (end === undefined) end = this.length;
10555 if (end > this.length) throw new Error('oob');
10556 if (start > end) throw new Error('oob');
10557
10558 return new Buffer(this.parent, end - start, +start + this.offset);
10559 };
10560
10561
10562 // Legacy methods for backwards compatibility.
10563
10564 Buffer.prototype.utf8Slice = function(start, end) {
10565 return this.toString('utf8', start, end);
10566 };
10567
10568 Buffer.prototype.binarySlice = function(start, end) {
10569 return this.toString('binary', start, end);
10570 };
10571
10572 Buffer.prototype.asciiSlice = function(start, end) {
10573 return this.toString('ascii', start, end);
10574 };
10575
10576 Buffer.prototype.utf8Write = function(string, offset) {
10577 return this.write(string, offset, 'utf8');
10578 };
10579
10580 Buffer.prototype.binaryWrite = function(string, offset) {
10581 return this.write(string, offset, 'binary');
10582 };
10583
10584 Buffer.prototype.asciiWrite = function(string, offset) {
10585 return this.write(string, offset, 'ascii');
10586 };
10587
10588 Buffer.prototype.readUInt8 = function(offset, noAssert) {
10589 var buffer = this;
10590
10591 if (!noAssert) {
10592 assert.ok(offset !== undefined && offset !== null,
10593 'missing offset');
10594
10595 assert.ok(offset < buffer.length,
10596 'Trying to read beyond buffer length');
10597 }
10598
10599 if (offset >= buffer.length) return;
10600
10601 return buffer.parent[buffer.offset + offset];
10602 };
10603
10604 function readUInt16(buffer, offset, isBigEndian, noAssert) {
10605 var val = 0;
10606
10607
10608 if (!noAssert) {
10609 assert.ok(typeof (isBigEndian) === 'boolean',
10610 'missing or invalid endian');
10611
10612 assert.ok(offset !== undefined && offset !== null,
10613 'missing offset');
10614
10615 assert.ok(offset + 1 < buffer.length,
10616 'Trying to read beyond buffer length');
10617 }
10618
10619 if (offset >= buffer.length) return 0;
10620
10621 if (isBigEndian) {
10622 val = buffer.parent[buffer.offset + offset] << 8;
10623 if (offset + 1 < buffer.length) {
10624 val |= buffer.parent[buffer.offset + offset + 1];
10625 }
10626 } else {
10627 val = buffer.parent[buffer.offset + offset];
10628 if (offset + 1 < buffer.length) {
10629 val |= buffer.parent[buffer.offset + offset + 1] << 8;
10630 }
10631 }
10632
10633 return val;
10634 }
10635
10636 Buffer.prototype.readUInt16LE = function(offset, noAssert) {
10637 return readUInt16(this, offset, false, noAssert);
10638 };
10639
10640 Buffer.prototype.readUInt16BE = function(offset, noAssert) {
10641 return readUInt16(this, offset, true, noAssert);
10642 };
10643
10644 function readUInt32(buffer, offset, isBigEndian, noAssert) {
10645 var val = 0;
10646
10647 if (!noAssert) {
10648 assert.ok(typeof (isBigEndian) === 'boolean',
10649 'missing or invalid endian');
10650
10651 assert.ok(offset !== undefined && offset !== null,
10652 'missing offset');
10653
10654 assert.ok(offset + 3 < buffer.length,
10655 'Trying to read beyond buffer length');
10656 }
10657
10658 if (offset >= buffer.length) return 0;
10659
10660 if (isBigEndian) {
10661 if (offset + 1 < buffer.length)
10662 val = buffer.parent[buffer.offset + offset + 1] << 16;
10663 if (offset + 2 < buffer.length)
10664 val |= buffer.parent[buffer.offset + offset + 2] << 8;
10665 if (offset + 3 < buffer.length)
10666 val |= buffer.parent[buffer.offset + offset + 3];
10667 val = val + (buffer.parent[buffer.offset + offset] << 24 >>> 0);
10668 } else {
10669 if (offset + 2 < buffer.length)
10670 val = buffer.parent[buffer.offset + offset + 2] << 16;
10671 if (offset + 1 < buffer.length)
10672 val |= buffer.parent[buffer.offset + offset + 1] << 8;
10673 val |= buffer.parent[buffer.offset + offset];
10674 if (offset + 3 < buffer.length)
10675 val = val + (buffer.parent[buffer.offset + offset + 3] << 24 >>> 0);
10676 }
10677
10678 return val;
10679 }
10680
10681 Buffer.prototype.readUInt32LE = function(offset, noAssert) {
10682 return readUInt32(this, offset, false, noAssert);
10683 };
10684
10685 Buffer.prototype.readUInt32BE = function(offset, noAssert) {
10686 return readUInt32(this, offset, true, noAssert);
10687 };
10688
10689
10690 /*
10691 * Signed integer types, yay team! A reminder on how two's complement actually
10692 * works. The first bit is the signed bit, i.e. tells us whether or not the
10693 * number should be positive or negative. If the two's complement value is
10694 * positive, then we're done, as it's equivalent to the unsigned representation.
10695 *
10696 * Now if the number is positive, you're pretty much done, you can just leverage
10697 * the unsigned translations and return those. Unfortunately, negative numbers
10698 * aren't quite that straightforward.
10699 *
10700 * At first glance, one might be inclined to use the traditional formula to
10701 * translate binary numbers between the positive and negative values in two's
10702 * complement. (Though it doesn't quite work for the most negative value)
10703 * Mainly:
10704 * - invert all the bits
10705 * - add one to the result
10706 *
10707 * Of course, this doesn't quite work in Javascript. Take for example the value
10708 * of -128. This could be represented in 16 bits (big-endian) as 0xff80. But of
10709 * course, Javascript will do the following:
10710 *
10711 * > ~0xff80
10712 * -65409
10713 *
10714 * Whoh there, Javascript, that's not quite right. But wait, according to
10715 * Javascript that's perfectly correct. When Javascript ends up seeing the
10716 * constant 0xff80, it has no notion that it is actually a signed number. It
10717 * assumes that we've input the unsigned value 0xff80. Thus, when it does the
10718 * binary negation, it casts it into a signed value, (positive 0xff80). Then
10719 * when you perform binary negation on that, it turns it into a negative number.
10720 *
10721 * Instead, we're going to have to use the following general formula, that works
10722 * in a rather Javascript friendly way. I'm glad we don't support this kind of
10723 * weird numbering scheme in the kernel.
10724 *
10725 * (BIT-MAX - (unsigned)val + 1) * -1
10726 *
10727 * The astute observer, may think that this doesn't make sense for 8-bit numbers
10728 * (really it isn't necessary for them). However, when you get 16-bit numbers,
10729 * you do. Let's go back to our prior example and see how this will look:
10730 *
10731 * (0xffff - 0xff80 + 1) * -1
10732 * (0x007f + 1) * -1
10733 * (0x0080) * -1
10734 */
10735 Buffer.prototype.readInt8 = function(offset, noAssert) {
10736 var buffer = this;
10737 var neg;
10738
10739 if (!noAssert) {
10740 assert.ok(offset !== undefined && offset !== null,
10741 'missing offset');
10742
10743 assert.ok(offset < buffer.length,
10744 'Trying to read beyond buffer length');
10745 }
10746
10747 if (offset >= buffer.length) return;
10748
10749 neg = buffer.parent[buffer.offset + offset] & 0x80;
10750 if (!neg) {
10751 return (buffer.parent[buffer.offset + offset]);
10752 }
10753
10754 return ((0xff - buffer.parent[buffer.offset + offset] + 1) * -1);
10755 };
10756
10757 function readInt16(buffer, offset, isBigEndian, noAssert) {
10758 var neg, val;
10759
10760 if (!noAssert) {
10761 assert.ok(typeof (isBigEndian) === 'boolean',
10762 'missing or invalid endian');
10763
10764 assert.ok(offset !== undefined && offset !== null,
10765 'missing offset');
10766
10767 assert.ok(offset + 1 < buffer.length,
10768 'Trying to read beyond buffer length');
10769 }
10770
10771 val = readUInt16(buffer, offset, isBigEndian, noAssert);
10772 neg = val & 0x8000;
10773 if (!neg) {
10774 return val;
10775 }
10776
10777 return (0xffff - val + 1) * -1;
10778 }
10779
10780 Buffer.prototype.readInt16LE = function(offset, noAssert) {
10781 return readInt16(this, offset, false, noAssert);
10782 };
10783
10784 Buffer.prototype.readInt16BE = function(offset, noAssert) {
10785 return readInt16(this, offset, true, noAssert);
10786 };
10787
10788 function readInt32(buffer, offset, isBigEndian, noAssert) {
10789 var neg, val;
10790
10791 if (!noAssert) {
10792 assert.ok(typeof (isBigEndian) === 'boolean',
10793 'missing or invalid endian');
10794
10795 assert.ok(offset !== undefined && offset !== null,
10796 'missing offset');
10797
10798 assert.ok(offset + 3 < buffer.length,
10799 'Trying to read beyond buffer length');
10800 }
10801
10802 val = readUInt32(buffer, offset, isBigEndian, noAssert);
10803 neg = val & 0x80000000;
10804 if (!neg) {
10805 return (val);
10806 }
10807
10808 return (0xffffffff - val + 1) * -1;
10809 }
10810
10811 Buffer.prototype.readInt32LE = function(offset, noAssert) {
10812 return readInt32(this, offset, false, noAssert);
10813 };
10814
10815 Buffer.prototype.readInt32BE = function(offset, noAssert) {
10816 return readInt32(this, offset, true, noAssert);
10817 };
10818
10819 function readFloat(buffer, offset, isBigEndian, noAssert) {
10820 if (!noAssert) {
10821 assert.ok(typeof (isBigEndian) === 'boolean',
10822 'missing or invalid endian');
10823
10824 assert.ok(offset + 3 < buffer.length,
10825 'Trying to read beyond buffer length');
10826 }
10827
10828 return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian,
10829 23, 4);
10830 }
10831
10832 Buffer.prototype.readFloatLE = function(offset, noAssert) {
10833 return readFloat(this, offset, false, noAssert);
10834 };
10835
10836 Buffer.prototype.readFloatBE = function(offset, noAssert) {
10837 return readFloat(this, offset, true, noAssert);
10838 };
10839
10840 function readDouble(buffer, offset, isBigEndian, noAssert) {
10841 if (!noAssert) {
10842 assert.ok(typeof (isBigEndian) === 'boolean',
10843 'missing or invalid endian');
10844
10845 assert.ok(offset + 7 < buffer.length,
10846 'Trying to read beyond buffer length');
10847 }
10848
10849 return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian,
10850 52, 8);
10851 }
10852
10853 Buffer.prototype.readDoubleLE = function(offset, noAssert) {
10854 return readDouble(this, offset, false, noAssert);
10855 };
10856
10857 Buffer.prototype.readDoubleBE = function(offset, noAssert) {
10858 return readDouble(this, offset, true, noAssert);
10859 };
10860
10861
10862 /*
10863 * We have to make sure that the value is a valid integer. This means that it is
10864 * non-negative. It has no fractional component and that it does not exceed the
10865 * maximum allowed value.
10866 *
10867 * value The number to check for validity
10868 *
10869 * max The maximum value
10870 */
10871 function verifuint(value, max) {
10872 assert.ok(typeof (value) == 'number',
10873 'cannot write a non-number as a number');
10874
10875 assert.ok(value >= 0,
10876 'specified a negative value for writing an unsigned value');
10877
10878 assert.ok(value <= max, 'value is larger than maximum value for type');
10879
10880 assert.ok(Math.floor(value) === value, 'value has a fractional component');
10881 }
10882
10883 Buffer.prototype.writeUInt8 = function(value, offset, noAssert) {
10884 var buffer = this;
10885
10886 if (!noAssert) {
10887 assert.ok(value !== undefined && value !== null,
10888 'missing value');
10889
10890 assert.ok(offset !== undefined && offset !== null,
10891 'missing offset');
10892
10893 assert.ok(offset < buffer.length,
10894 'trying to write beyond buffer length');
10895
10896 verifuint(value, 0xff);
10897 }
10898
10899 if (offset < buffer.length) {
10900 buffer.parent[buffer.offset + offset] = value;
10901 }
10902 };
10903
10904 function writeUInt16(buffer, value, offset, isBigEndian, noAssert) {
10905 if (!noAssert) {
10906 assert.ok(value !== undefined && value !== null,
10907 'missing value');
10908
10909 assert.ok(typeof (isBigEndian) === 'boolean',
10910 'missing or invalid endian');
10911
10912 assert.ok(offset !== undefined && offset !== null,
10913 'missing offset');
10914
10915 assert.ok(offset + 1 < buffer.length,
10916 'trying to write beyond buffer length');
10917
10918 verifuint(value, 0xffff);
10919 }
10920
10921 for (var i = 0; i < Math.min(buffer.length - offset, 2); i++) {
10922 buffer.parent[buffer.offset + offset + i] =
10923 (value & (0xff << (8 * (isBigEndian ? 1 - i : i)))) >>>
10924 (isBigEndian ? 1 - i : i) * 8;
10925 }
10926
10927 }
10928
10929 Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) {
10930 writeUInt16(this, value, offset, false, noAssert);
10931 };
10932
10933 Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) {
10934 writeUInt16(this, value, offset, true, noAssert);
10935 };
10936
10937 function writeUInt32(buffer, value, offset, isBigEndian, noAssert) {
10938 if (!noAssert) {
10939 assert.ok(value !== undefined && value !== null,
10940 'missing value');
10941
10942 assert.ok(typeof (isBigEndian) === 'boolean',
10943 'missing or invalid endian');
10944
10945 assert.ok(offset !== undefined && offset !== null,
10946 'missing offset');
10947
10948 assert.ok(offset + 3 < buffer.length,
10949 'trying to write beyond buffer length');
10950
10951 verifuint(value, 0xffffffff);
10952 }
10953
10954 for (var i = 0; i < Math.min(buffer.length - offset, 4); i++) {
10955 buffer.parent[buffer.offset + offset + i] =
10956 (value >>> (isBigEndian ? 3 - i : i) * 8) & 0xff;
10957 }
10958 }
10959
10960 Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) {
10961 writeUInt32(this, value, offset, false, noAssert);
10962 };
10963
10964 Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) {
10965 writeUInt32(this, value, offset, true, noAssert);
10966 };
10967
10968
10969 /*
10970 * We now move onto our friends in the signed number category. Unlike unsigned
10971 * numbers, we're going to have to worry a bit more about how we put values into
10972 * arrays. Since we are only worrying about signed 32-bit values, we're in
10973 * slightly better shape. Unfortunately, we really can't do our favorite binary
10974 * & in this system. It really seems to do the wrong thing. For example:
10975 *
10976 * > -32 & 0xff
10977 * 224
10978 *
10979 * What's happening above is really: 0xe0 & 0xff = 0xe0. However, the results of
10980 * this aren't treated as a signed number. Ultimately a bad thing.
10981 *
10982 * What we're going to want to do is basically create the unsigned equivalent of
10983 * our representation and pass that off to the wuint* functions. To do that
10984 * we're going to do the following:
10985 *
10986 * - if the value is positive
10987 * we can pass it directly off to the equivalent wuint
10988 * - if the value is negative
10989 * we do the following computation:
10990 * mb + val + 1, where
10991 * mb is the maximum unsigned value in that byte size
10992 * val is the Javascript negative integer
10993 *
10994 *
10995 * As a concrete value, take -128. In signed 16 bits this would be 0xff80. If
10996 * you do out the computations:
10997 *
10998 * 0xffff - 128 + 1
10999 * 0xffff - 127
11000 * 0xff80
11001 *
11002 * You can then encode this value as the signed version. This is really rather
11003 * hacky, but it should work and get the job done which is our goal here.
11004 */
11005
11006 /*
11007 * A series of checks to make sure we actually have a signed 32-bit number
11008 */
11009 function verifsint(value, max, min) {
11010 assert.ok(typeof (value) == 'number',
11011 'cannot write a non-number as a number');
11012
11013 assert.ok(value <= max, 'value larger than maximum allowed value');
11014
11015 assert.ok(value >= min, 'value smaller than minimum allowed value');
11016
11017 assert.ok(Math.floor(value) === value, 'value has a fractional component');
11018 }
11019
11020 function verifIEEE754(value, max, min) {
11021 assert.ok(typeof (value) == 'number',
11022 'cannot write a non-number as a number');
11023
11024 assert.ok(value <= max, 'value larger than maximum allowed value');
11025
11026 assert.ok(value >= min, 'value smaller than minimum allowed value');
11027 }
11028
11029 Buffer.prototype.writeInt8 = function(value, offset, noAssert) {
11030 var buffer = this;
11031
11032 if (!noAssert) {
11033 assert.ok(value !== undefined && value !== null,
11034 'missing value');
11035
11036 assert.ok(offset !== undefined && offset !== null,
11037 'missing offset');
11038
11039 assert.ok(offset < buffer.length,
11040 'Trying to write beyond buffer length');
11041
11042 verifsint(value, 0x7f, -0x80);
11043 }
11044
11045 if (value >= 0) {
11046 buffer.writeUInt8(value, offset, noAssert);
11047 } else {
11048 buffer.writeUInt8(0xff + value + 1, offset, noAssert);
11049 }
11050 };
11051
11052 function writeInt16(buffer, value, offset, isBigEndian, noAssert) {
11053 if (!noAssert) {
11054 assert.ok(value !== undefined && value !== null,
11055 'missing value');
11056
11057 assert.ok(typeof (isBigEndian) === 'boolean',
11058 'missing or invalid endian');
11059
11060 assert.ok(offset !== undefined && offset !== null,
11061 'missing offset');
11062
11063 assert.ok(offset + 1 < buffer.length,
11064 'Trying to write beyond buffer length');
11065
11066 verifsint(value, 0x7fff, -0x8000);
11067 }
11068
11069 if (value >= 0) {
11070 writeUInt16(buffer, value, offset, isBigEndian, noAssert);
11071 } else {
11072 writeUInt16(buffer, 0xffff + value + 1, offset, isBigEndian, noAssert);
11073 }
11074 }
11075
11076 Buffer.prototype.writeInt16LE = function(value, offset, noAssert) {
11077 writeInt16(this, value, offset, false, noAssert);
11078 };
11079
11080 Buffer.prototype.writeInt16BE = function(value, offset, noAssert) {
11081 writeInt16(this, value, offset, true, noAssert);
11082 };
11083
11084 function writeInt32(buffer, value, offset, isBigEndian, noAssert) {
11085 if (!noAssert) {
11086 assert.ok(value !== undefined && value !== null,
11087 'missing value');
11088
11089 assert.ok(typeof (isBigEndian) === 'boolean',
11090 'missing or invalid endian');
11091
11092 assert.ok(offset !== undefined && offset !== null,
11093 'missing offset');
11094
11095 assert.ok(offset + 3 < buffer.length,
11096 'Trying to write beyond buffer length');
11097
11098 verifsint(value, 0x7fffffff, -0x80000000);
11099 }
11100
11101 if (value >= 0) {
11102 writeUInt32(buffer, value, offset, isBigEndian, noAssert);
11103 } else {
11104 writeUInt32(buffer, 0xffffffff + value + 1, offset, isBigEndian, noAssert);
11105 }
11106 }
11107
11108 Buffer.prototype.writeInt32LE = function(value, offset, noAssert) {
11109 writeInt32(this, value, offset, false, noAssert);
11110 };
11111
11112 Buffer.prototype.writeInt32BE = function(value, offset, noAssert) {
11113 writeInt32(this, value, offset, true, noAssert);
11114 };
11115
11116 function writeFloat(buffer, value, offset, isBigEndian, noAssert) {
11117 if (!noAssert) {
11118 assert.ok(value !== undefined && value !== null,
11119 'missing value');
11120
11121 assert.ok(typeof (isBigEndian) === 'boolean',
11122 'missing or invalid endian');
11123
11124 assert.ok(offset !== undefined && offset !== null,
11125 'missing offset');
11126
11127 assert.ok(offset + 3 < buffer.length,
11128 'Trying to write beyond buffer length');
11129
11130 verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38);
11131 }
11132
11133 require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian,
11134 23, 4);
11135 }
11136
11137 Buffer.prototype.writeFloatLE = function(value, offset, noAssert) {
11138 writeFloat(this, value, offset, false, noAssert);
11139 };
11140
11141 Buffer.prototype.writeFloatBE = function(value, offset, noAssert) {
11142 writeFloat(this, value, offset, true, noAssert);
11143 };
11144
11145 function writeDouble(buffer, value, offset, isBigEndian, noAssert) {
11146 if (!noAssert) {
11147 assert.ok(value !== undefined && value !== null,
11148 'missing value');
11149
11150 assert.ok(typeof (isBigEndian) === 'boolean',
11151 'missing or invalid endian');
11152
11153 assert.ok(offset !== undefined && offset !== null,
11154 'missing offset');
11155
11156 assert.ok(offset + 7 < buffer.length,
11157 'Trying to write beyond buffer length');
11158
11159 verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308);
11160 }
11161
11162 require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian,
11163 52, 8);
11164 }
11165
11166 Buffer.prototype.writeDoubleLE = function(value, offset, noAssert) {
11167 writeDouble(this, value, offset, false, noAssert);
11168 };
11169
11170 Buffer.prototype.writeDoubleBE = function(value, offset, noAssert) {
11171 writeDouble(this, value, offset, true, noAssert);
11172 };
11173
11174 SlowBuffer.prototype.readUInt8 = Buffer.prototype.readUInt8;
11175 SlowBuffer.prototype.readUInt16LE = Buffer.prototype.readUInt16LE;
11176 SlowBuffer.prototype.readUInt16BE = Buffer.prototype.readUInt16BE;
11177 SlowBuffer.prototype.readUInt32LE = Buffer.prototype.readUInt32LE;
11178 SlowBuffer.prototype.readUInt32BE = Buffer.prototype.readUInt32BE;
11179 SlowBuffer.prototype.readInt8 = Buffer.prototype.readInt8;
11180 SlowBuffer.prototype.readInt16LE = Buffer.prototype.readInt16LE;
11181 SlowBuffer.prototype.readInt16BE = Buffer.prototype.readInt16BE;
11182 SlowBuffer.prototype.readInt32LE = Buffer.prototype.readInt32LE;
11183 SlowBuffer.prototype.readInt32BE = Buffer.prototype.readInt32BE;
11184 SlowBuffer.prototype.readFloatLE = Buffer.prototype.readFloatLE;
11185 SlowBuffer.prototype.readFloatBE = Buffer.prototype.readFloatBE;
11186 SlowBuffer.prototype.readDoubleLE = Buffer.prototype.readDoubleLE;
11187 SlowBuffer.prototype.readDoubleBE = Buffer.prototype.readDoubleBE;
11188 SlowBuffer.prototype.writeUInt8 = Buffer.prototype.writeUInt8;
11189 SlowBuffer.prototype.writeUInt16LE = Buffer.prototype.writeUInt16LE;
11190 SlowBuffer.prototype.writeUInt16BE = Buffer.prototype.writeUInt16BE;
11191 SlowBuffer.prototype.writeUInt32LE = Buffer.prototype.writeUInt32LE;
11192 SlowBuffer.prototype.writeUInt32BE = Buffer.prototype.writeUInt32BE;
11193 SlowBuffer.prototype.writeInt8 = Buffer.prototype.writeInt8;
11194 SlowBuffer.prototype.writeInt16LE = Buffer.prototype.writeInt16LE;
11195 SlowBuffer.prototype.writeInt16BE = Buffer.prototype.writeInt16BE;
11196 SlowBuffer.prototype.writeInt32LE = Buffer.prototype.writeInt32LE;
11197 SlowBuffer.prototype.writeInt32BE = Buffer.prototype.writeInt32BE;
11198 SlowBuffer.prototype.writeFloatLE = Buffer.prototype.writeFloatLE;
11199 SlowBuffer.prototype.writeFloatBE = Buffer.prototype.writeFloatBE;
11200 SlowBuffer.prototype.writeDoubleLE = Buffer.prototype.writeDoubleLE;
11201 SlowBuffer.prototype.writeDoubleBE = Buffer.prototype.writeDoubleBE;
11202
11203 })()
11204 },{"assert":12,"./buffer_ieee754":14,"base64-js":15}],15:[function(require,module,exports){
11205 (function (exports) {
11206 'use strict';
11207
11208 var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
11209
11210 function b64ToByteArray(b64) {
11211 var i, j, l, tmp, placeHolders, arr;
11212
11213 if (b64.length % 4 > 0) {
11214 throw 'Invalid string. Length must be a multiple of 4';
11215 }
11216
11217 // the number of equal signs (place holders)
11218 // if there are two placeholders, than the two characters before it
11219 // represent one byte
11220 // if there is only one, then the three characters before it represent 2 bytes
11221 // this is just a cheap hack to not do indexOf twice
11222 placeHolders = b64.indexOf('=');
11223 placeHolders = placeHolders > 0 ? b64.length - placeHolders : 0;
11224
11225 // base64 is 4/3 + up to two characters of the original data
11226 arr = [];//new Uint8Array(b64.length * 3 / 4 - placeHolders);
11227
11228 // if there are placeholders, only get up to the last complete 4 chars
11229 l = placeHolders > 0 ? b64.length - 4 : b64.length;
11230
11231 for (i = 0, j = 0; i < l; i += 4, j += 3) {
11232 tmp = (lookup.indexOf(b64[i]) << 18) | (lookup.indexOf(b64[i + 1]) << 12) | (lookup.indexOf(b64[i + 2]) << 6) | lookup.indexOf(b64[i + 3]);
11233 arr.push((tmp & 0xFF0000) >> 16);
11234 arr.push((tmp & 0xFF00) >> 8);
11235 arr.push(tmp & 0xFF);
11236 }
11237
11238 if (placeHolders === 2) {
11239 tmp = (lookup.indexOf(b64[i]) << 2) | (lookup.indexOf(b64[i + 1]) >> 4);
11240 arr.push(tmp & 0xFF);
11241 } else if (placeHolders === 1) {
11242 tmp = (lookup.indexOf(b64[i]) << 10) | (lookup.indexOf(b64[i + 1]) << 4) | (lookup.indexOf(b64[i + 2]) >> 2);
11243 arr.push((tmp >> 8) & 0xFF);
11244 arr.push(tmp & 0xFF);
11245 }
11246
11247 return arr;
11248 }
11249
11250 function uint8ToBase64(uint8) {
11251 var i,
11252 extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
11253 output = "",
11254 temp, length;
11255
11256 function tripletToBase64 (num) {
11257 return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F];
11258 };
11259
11260 // go through the array every three bytes, we'll deal with trailing stuff later
11261 for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
11262 temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]);
11263 output += tripletToBase64(temp);
11264 }
11265
11266 // pad the end with zeros, but make sure to not forget the extra bytes
11267 switch (extraBytes) {
11268 case 1:
11269 temp = uint8[uint8.length - 1];
11270 output += lookup[temp >> 2];
11271 output += lookup[(temp << 4) & 0x3F];
11272 output += '==';
11273 break;
11274 case 2:
11275 temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]);
11276 output += lookup[temp >> 10];
11277 output += lookup[(temp >> 4) & 0x3F];
11278 output += lookup[(temp << 2) & 0x3F];
11279 output += '=';
11280 break;
11281 }
11282
11283 return output;
11284 }
11285
11286 module.exports.toByteArray = b64ToByteArray;
11287 module.exports.fromByteArray = uint8ToBase64;
11288 }());
11289
11290 },{}]},{},["E/GbHF"])
11291 ;
11292 JSHINT = require('jshint').JSHINT;
11293 }());