removed dependency on built-editor.min.js
[ccsdk/distribution.git] / dgbuilder / public / ace / worker-javascript.js
1 "no use strict";
2 !(function(window) {
3 if (typeof window.window != "undefined" && window.document)
4     return;
5 if (window.require && window.define)
6     return;
7
8 if (!window.console) {
9     window.console = function() {
10         var msgs = Array.prototype.slice.call(arguments, 0);
11         postMessage({type: "log", data: msgs});
12     };
13     window.console.error =
14     window.console.warn = 
15     window.console.log =
16     window.console.trace = window.console;
17 }
18 window.window = window;
19 window.ace = window;
20
21 window.onerror = function(message, file, line, col, err) {
22     postMessage({type: "error", data: {
23         message: message,
24         data: err.data,
25         file: file,
26         line: line, 
27         col: col,
28         stack: err.stack
29     }});
30 };
31
32 window.normalizeModule = function(parentId, moduleName) {
33     // normalize plugin requires
34     if (moduleName.indexOf("!") !== -1) {
35         var chunks = moduleName.split("!");
36         return window.normalizeModule(parentId, chunks[0]) + "!" + window.normalizeModule(parentId, chunks[1]);
37     }
38     // normalize relative requires
39     if (moduleName.charAt(0) == ".") {
40         var base = parentId.split("/").slice(0, -1).join("/");
41         moduleName = (base ? base + "/" : "") + moduleName;
42         
43         while (moduleName.indexOf(".") !== -1 && previous != moduleName) {
44             var previous = moduleName;
45             moduleName = moduleName.replace(/^\.\//, "").replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, "");
46         }
47     }
48     
49     return moduleName;
50 };
51
52 window.require = function require(parentId, id) {
53     if (!id) {
54         id = parentId;
55         parentId = null;
56     }
57     if (!id.charAt)
58         throw new Error("worker.js require() accepts only (parentId, id) as arguments");
59
60     id = window.normalizeModule(parentId, id);
61
62     var module = window.require.modules[id];
63     if (module) {
64         if (!module.initialized) {
65             module.initialized = true;
66             module.exports = module.factory().exports;
67         }
68         return module.exports;
69     }
70    
71     if (!window.require.tlns)
72         return console.log("unable to load " + id);
73     
74     var path = resolveModuleId(id, window.require.tlns);
75     if (path.slice(-3) != ".js") path += ".js";
76     
77     window.require.id = id;
78     window.require.modules[id] = {}; // prevent infinite loop on broken modules
79     importScripts(path);
80     return window.require(parentId, id);
81 };
82 function resolveModuleId(id, paths) {
83     var testPath = id, tail = "";
84     while (testPath) {
85         var alias = paths[testPath];
86         if (typeof alias == "string") {
87             return alias + tail;
88         } else if (alias) {
89             return  alias.location.replace(/\/*$/, "/") + (tail || alias.main || alias.name);
90         } else if (alias === false) {
91             return "";
92         }
93         var i = testPath.lastIndexOf("/");
94         if (i === -1) break;
95         tail = testPath.substr(i) + tail;
96         testPath = testPath.slice(0, i);
97     }
98     return id;
99 }
100 window.require.modules = {};
101 window.require.tlns = {};
102
103 window.define = function(id, deps, factory) {
104     if (arguments.length == 2) {
105         factory = deps;
106         if (typeof id != "string") {
107             deps = id;
108             id = window.require.id;
109         }
110     } else if (arguments.length == 1) {
111         factory = id;
112         deps = [];
113         id = window.require.id;
114     }
115     
116     if (typeof factory != "function") {
117         window.require.modules[id] = {
118             exports: factory,
119             initialized: true
120         };
121         return;
122     }
123
124     if (!deps.length)
125         // If there is no dependencies, we inject "require", "exports" and
126         // "module" as dependencies, to provide CommonJS compatibility.
127         deps = ["require", "exports", "module"];
128
129     var req = function(childId) {
130         return window.require(id, childId);
131     };
132
133     window.require.modules[id] = {
134         exports: {},
135         factory: function() {
136             var module = this;
137             var returnExports = factory.apply(this, deps.map(function(dep) {
138                 switch (dep) {
139                     // Because "require", "exports" and "module" aren't actual
140                     // dependencies, we must handle them seperately.
141                     case "require": return req;
142                     case "exports": return module.exports;
143                     case "module":  return module;
144                     // But for all other dependencies, we can just go ahead and
145                     // require them.
146                     default:        return req(dep);
147                 }
148             }));
149             if (returnExports)
150                 module.exports = returnExports;
151             return module;
152         }
153     };
154 };
155 window.define.amd = {};
156 require.tlns = {};
157 window.initBaseUrls  = function initBaseUrls(topLevelNamespaces) {
158     for (var i in topLevelNamespaces)
159         require.tlns[i] = topLevelNamespaces[i];
160 };
161
162 window.initSender = function initSender() {
163
164     var EventEmitter = window.require("ace/lib/event_emitter").EventEmitter;
165     var oop = window.require("ace/lib/oop");
166     
167     var Sender = function() {};
168     
169     (function() {
170         
171         oop.implement(this, EventEmitter);
172                 
173         this.callback = function(data, callbackId) {
174             postMessage({
175                 type: "call",
176                 id: callbackId,
177                 data: data
178             });
179         };
180     
181         this.emit = function(name, data) {
182             postMessage({
183                 type: "event",
184                 name: name,
185                 data: data
186             });
187         };
188         
189     }).call(Sender.prototype);
190     
191     return new Sender();
192 };
193
194 var main = window.main = null;
195 var sender = window.sender = null;
196
197 window.onmessage = function(e) {
198     var msg = e.data;
199     if (msg.event && sender) {
200         sender._signal(msg.event, msg.data);
201     }
202     else if (msg.command) {
203         if (main[msg.command])
204             main[msg.command].apply(main, msg.args);
205         else if (window[msg.command])
206             window[msg.command].apply(window, msg.args);
207         else
208             throw new Error("Unknown command:" + msg.command);
209     }
210     else if (msg.init) {
211         window.initBaseUrls(msg.tlns);
212         require("ace/lib/es5-shim");
213         sender = window.sender = window.initSender();
214         var clazz = require(msg.module)[msg.classname];
215         main = window.main = new clazz(sender);
216     }
217 };
218 })(this);
219
220 define("ace/lib/oop",["require","exports","module"], function(require, exports, module) {
221 "use strict";
222
223 exports.inherits = function(ctor, superCtor) {
224     ctor.super_ = superCtor;
225     ctor.prototype = Object.create(superCtor.prototype, {
226         constructor: {
227             value: ctor,
228             enumerable: false,
229             writable: true,
230             configurable: true
231         }
232     });
233 };
234
235 exports.mixin = function(obj, mixin) {
236     for (var key in mixin) {
237         obj[key] = mixin[key];
238     }
239     return obj;
240 };
241
242 exports.implement = function(proto, mixin) {
243     exports.mixin(proto, mixin);
244 };
245
246 });
247
248 define("ace/range",["require","exports","module"], function(require, exports, module) {
249 "use strict";
250 var comparePoints = function(p1, p2) {
251     return p1.row - p2.row || p1.column - p2.column;
252 };
253 var Range = function(startRow, startColumn, endRow, endColumn) {
254     this.start = {
255         row: startRow,
256         column: startColumn
257     };
258
259     this.end = {
260         row: endRow,
261         column: endColumn
262     };
263 };
264
265 (function() {
266     this.isEqual = function(range) {
267         return this.start.row === range.start.row &&
268             this.end.row === range.end.row &&
269             this.start.column === range.start.column &&
270             this.end.column === range.end.column;
271     };
272     this.toString = function() {
273         return ("Range: [" + this.start.row + "/" + this.start.column +
274             "] -> [" + this.end.row + "/" + this.end.column + "]");
275     };
276
277     this.contains = function(row, column) {
278         return this.compare(row, column) == 0;
279     };
280     this.compareRange = function(range) {
281         var cmp,
282             end = range.end,
283             start = range.start;
284
285         cmp = this.compare(end.row, end.column);
286         if (cmp == 1) {
287             cmp = this.compare(start.row, start.column);
288             if (cmp == 1) {
289                 return 2;
290             } else if (cmp == 0) {
291                 return 1;
292             } else {
293                 return 0;
294             }
295         } else if (cmp == -1) {
296             return -2;
297         } else {
298             cmp = this.compare(start.row, start.column);
299             if (cmp == -1) {
300                 return -1;
301             } else if (cmp == 1) {
302                 return 42;
303             } else {
304                 return 0;
305             }
306         }
307     };
308     this.comparePoint = function(p) {
309         return this.compare(p.row, p.column);
310     };
311     this.containsRange = function(range) {
312         return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
313     };
314     this.intersects = function(range) {
315         var cmp = this.compareRange(range);
316         return (cmp == -1 || cmp == 0 || cmp == 1);
317     };
318     this.isEnd = function(row, column) {
319         return this.end.row == row && this.end.column == column;
320     };
321     this.isStart = function(row, column) {
322         return this.start.row == row && this.start.column == column;
323     };
324     this.setStart = function(row, column) {
325         if (typeof row == "object") {
326             this.start.column = row.column;
327             this.start.row = row.row;
328         } else {
329             this.start.row = row;
330             this.start.column = column;
331         }
332     };
333     this.setEnd = function(row, column) {
334         if (typeof row == "object") {
335             this.end.column = row.column;
336             this.end.row = row.row;
337         } else {
338             this.end.row = row;
339             this.end.column = column;
340         }
341     };
342     this.inside = function(row, column) {
343         if (this.compare(row, column) == 0) {
344             if (this.isEnd(row, column) || this.isStart(row, column)) {
345                 return false;
346             } else {
347                 return true;
348             }
349         }
350         return false;
351     };
352     this.insideStart = function(row, column) {
353         if (this.compare(row, column) == 0) {
354             if (this.isEnd(row, column)) {
355                 return false;
356             } else {
357                 return true;
358             }
359         }
360         return false;
361     };
362     this.insideEnd = function(row, column) {
363         if (this.compare(row, column) == 0) {
364             if (this.isStart(row, column)) {
365                 return false;
366             } else {
367                 return true;
368             }
369         }
370         return false;
371     };
372     this.compare = function(row, column) {
373         if (!this.isMultiLine()) {
374             if (row === this.start.row) {
375                 return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0);
376             }
377         }
378
379         if (row < this.start.row)
380             return -1;
381
382         if (row > this.end.row)
383             return 1;
384
385         if (this.start.row === row)
386             return column >= this.start.column ? 0 : -1;
387
388         if (this.end.row === row)
389             return column <= this.end.column ? 0 : 1;
390
391         return 0;
392     };
393     this.compareStart = function(row, column) {
394         if (this.start.row == row && this.start.column == column) {
395             return -1;
396         } else {
397             return this.compare(row, column);
398         }
399     };
400     this.compareEnd = function(row, column) {
401         if (this.end.row == row && this.end.column == column) {
402             return 1;
403         } else {
404             return this.compare(row, column);
405         }
406     };
407     this.compareInside = function(row, column) {
408         if (this.end.row == row && this.end.column == column) {
409             return 1;
410         } else if (this.start.row == row && this.start.column == column) {
411             return -1;
412         } else {
413             return this.compare(row, column);
414         }
415     };
416     this.clipRows = function(firstRow, lastRow) {
417         if (this.end.row > lastRow)
418             var end = {row: lastRow + 1, column: 0};
419         else if (this.end.row < firstRow)
420             var end = {row: firstRow, column: 0};
421
422         if (this.start.row > lastRow)
423             var start = {row: lastRow + 1, column: 0};
424         else if (this.start.row < firstRow)
425             var start = {row: firstRow, column: 0};
426
427         return Range.fromPoints(start || this.start, end || this.end);
428     };
429     this.extend = function(row, column) {
430         var cmp = this.compare(row, column);
431
432         if (cmp == 0)
433             return this;
434         else if (cmp == -1)
435             var start = {row: row, column: column};
436         else
437             var end = {row: row, column: column};
438
439         return Range.fromPoints(start || this.start, end || this.end);
440     };
441
442     this.isEmpty = function() {
443         return (this.start.row === this.end.row && this.start.column === this.end.column);
444     };
445     this.isMultiLine = function() {
446         return (this.start.row !== this.end.row);
447     };
448     this.clone = function() {
449         return Range.fromPoints(this.start, this.end);
450     };
451     this.collapseRows = function() {
452         if (this.end.column == 0)
453             return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0);
454         else
455             return new Range(this.start.row, 0, this.end.row, 0);
456     };
457     this.toScreenRange = function(session) {
458         var screenPosStart = session.documentToScreenPosition(this.start);
459         var screenPosEnd = session.documentToScreenPosition(this.end);
460
461         return new Range(
462             screenPosStart.row, screenPosStart.column,
463             screenPosEnd.row, screenPosEnd.column
464         );
465     };
466     this.moveBy = function(row, column) {
467         this.start.row += row;
468         this.start.column += column;
469         this.end.row += row;
470         this.end.column += column;
471     };
472
473 }).call(Range.prototype);
474 Range.fromPoints = function(start, end) {
475     return new Range(start.row, start.column, end.row, end.column);
476 };
477 Range.comparePoints = comparePoints;
478
479 Range.comparePoints = function(p1, p2) {
480     return p1.row - p2.row || p1.column - p2.column;
481 };
482
483
484 exports.Range = Range;
485 });
486
487 define("ace/apply_delta",["require","exports","module"], function(require, exports, module) {
488 "use strict";
489
490 function throwDeltaError(delta, errorText){
491     console.log("Invalid Delta:", delta);
492     throw "Invalid Delta: " + errorText;
493 }
494
495 function positionInDocument(docLines, position) {
496     return position.row    >= 0 && position.row    <  docLines.length &&
497            position.column >= 0 && position.column <= docLines[position.row].length;
498 }
499
500 function validateDelta(docLines, delta) {
501     if (delta.action != "insert" && delta.action != "remove")
502         throwDeltaError(delta, "delta.action must be 'insert' or 'remove'");
503     if (!(delta.lines instanceof Array))
504         throwDeltaError(delta, "delta.lines must be an Array");
505     if (!delta.start || !delta.end)
506        throwDeltaError(delta, "delta.start/end must be an present");
507     var start = delta.start;
508     if (!positionInDocument(docLines, delta.start))
509         throwDeltaError(delta, "delta.start must be contained in document");
510     var end = delta.end;
511     if (delta.action == "remove" && !positionInDocument(docLines, end))
512         throwDeltaError(delta, "delta.end must contained in document for 'remove' actions");
513     var numRangeRows = end.row - start.row;
514     var numRangeLastLineChars = (end.column - (numRangeRows == 0 ? start.column : 0));
515     if (numRangeRows != delta.lines.length - 1 || delta.lines[numRangeRows].length != numRangeLastLineChars)
516         throwDeltaError(delta, "delta.range must match delta lines");
517 }
518
519 exports.applyDelta = function(docLines, delta, doNotValidate) {
520     
521     var row = delta.start.row;
522     var startColumn = delta.start.column;
523     var line = docLines[row] || "";
524     switch (delta.action) {
525         case "insert":
526             var lines = delta.lines;
527             if (lines.length === 1) {
528                 docLines[row] = line.substring(0, startColumn) + delta.lines[0] + line.substring(startColumn);
529             } else {
530                 var args = [row, 1].concat(delta.lines);
531                 docLines.splice.apply(docLines, args);
532                 docLines[row] = line.substring(0, startColumn) + docLines[row];
533                 docLines[row + delta.lines.length - 1] += line.substring(startColumn);
534             }
535             break;
536         case "remove":
537             var endColumn = delta.end.column;
538             var endRow = delta.end.row;
539             if (row === endRow) {
540                 docLines[row] = line.substring(0, startColumn) + line.substring(endColumn);
541             } else {
542                 docLines.splice(
543                     row, endRow - row + 1,
544                     line.substring(0, startColumn) + docLines[endRow].substring(endColumn)
545                 );
546             }
547             break;
548     }
549 };
550 });
551
552 define("ace/lib/event_emitter",["require","exports","module"], function(require, exports, module) {
553 "use strict";
554
555 var EventEmitter = {};
556 var stopPropagation = function() { this.propagationStopped = true; };
557 var preventDefault = function() { this.defaultPrevented = true; };
558
559 EventEmitter._emit =
560 EventEmitter._dispatchEvent = function(eventName, e) {
561     this._eventRegistry || (this._eventRegistry = {});
562     this._defaultHandlers || (this._defaultHandlers = {});
563
564     var listeners = this._eventRegistry[eventName] || [];
565     var defaultHandler = this._defaultHandlers[eventName];
566     if (!listeners.length && !defaultHandler)
567         return;
568
569     if (typeof e != "object" || !e)
570         e = {};
571
572     if (!e.type)
573         e.type = eventName;
574     if (!e.stopPropagation)
575         e.stopPropagation = stopPropagation;
576     if (!e.preventDefault)
577         e.preventDefault = preventDefault;
578
579     listeners = listeners.slice();
580     for (var i=0; i<listeners.length; i++) {
581         listeners[i](e, this);
582         if (e.propagationStopped)
583             break;
584     }
585     
586     if (defaultHandler && !e.defaultPrevented)
587         return defaultHandler(e, this);
588 };
589
590
591 EventEmitter._signal = function(eventName, e) {
592     var listeners = (this._eventRegistry || {})[eventName];
593     if (!listeners)
594         return;
595     listeners = listeners.slice();
596     for (var i=0; i<listeners.length; i++)
597         listeners[i](e, this);
598 };
599
600 EventEmitter.once = function(eventName, callback) {
601     var _self = this;
602     callback && this.addEventListener(eventName, function newCallback() {
603         _self.removeEventListener(eventName, newCallback);
604         callback.apply(null, arguments);
605     });
606 };
607
608
609 EventEmitter.setDefaultHandler = function(eventName, callback) {
610     var handlers = this._defaultHandlers;
611     if (!handlers)
612         handlers = this._defaultHandlers = {_disabled_: {}};
613     
614     if (handlers[eventName]) {
615         var old = handlers[eventName];
616         var disabled = handlers._disabled_[eventName];
617         if (!disabled)
618             handlers._disabled_[eventName] = disabled = [];
619         disabled.push(old);
620         var i = disabled.indexOf(callback);
621         if (i != -1) 
622             disabled.splice(i, 1);
623     }
624     handlers[eventName] = callback;
625 };
626 EventEmitter.removeDefaultHandler = function(eventName, callback) {
627     var handlers = this._defaultHandlers;
628     if (!handlers)
629         return;
630     var disabled = handlers._disabled_[eventName];
631     
632     if (handlers[eventName] == callback) {
633         var old = handlers[eventName];
634         if (disabled)
635             this.setDefaultHandler(eventName, disabled.pop());
636     } else if (disabled) {
637         var i = disabled.indexOf(callback);
638         if (i != -1)
639             disabled.splice(i, 1);
640     }
641 };
642
643 EventEmitter.on =
644 EventEmitter.addEventListener = function(eventName, callback, capturing) {
645     this._eventRegistry = this._eventRegistry || {};
646
647     var listeners = this._eventRegistry[eventName];
648     if (!listeners)
649         listeners = this._eventRegistry[eventName] = [];
650
651     if (listeners.indexOf(callback) == -1)
652         listeners[capturing ? "unshift" : "push"](callback);
653     return callback;
654 };
655
656 EventEmitter.off =
657 EventEmitter.removeListener =
658 EventEmitter.removeEventListener = function(eventName, callback) {
659     this._eventRegistry = this._eventRegistry || {};
660
661     var listeners = this._eventRegistry[eventName];
662     if (!listeners)
663         return;
664
665     var index = listeners.indexOf(callback);
666     if (index !== -1)
667         listeners.splice(index, 1);
668 };
669
670 EventEmitter.removeAllListeners = function(eventName) {
671     if (this._eventRegistry) this._eventRegistry[eventName] = [];
672 };
673
674 exports.EventEmitter = EventEmitter;
675
676 });
677
678 define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(require, exports, module) {
679 "use strict";
680
681 var oop = require("./lib/oop");
682 var EventEmitter = require("./lib/event_emitter").EventEmitter;
683
684 var Anchor = exports.Anchor = function(doc, row, column) {
685     this.$onChange = this.onChange.bind(this);
686     this.attach(doc);
687     
688     if (typeof column == "undefined")
689         this.setPosition(row.row, row.column);
690     else
691         this.setPosition(row, column);
692 };
693
694 (function() {
695
696     oop.implement(this, EventEmitter);
697     this.getPosition = function() {
698         return this.$clipPositionToDocument(this.row, this.column);
699     };
700     this.getDocument = function() {
701         return this.document;
702     };
703     this.$insertRight = false;
704     this.onChange = function(delta) {
705         if (delta.start.row == delta.end.row && delta.start.row != this.row)
706             return;
707
708         if (delta.start.row > this.row)
709             return;
710             
711         var point = $getTransformedPoint(delta, {row: this.row, column: this.column}, this.$insertRight);
712         this.setPosition(point.row, point.column, true);
713     };
714     
715     function $pointsInOrder(point1, point2, equalPointsInOrder) {
716         var bColIsAfter = equalPointsInOrder ? point1.column <= point2.column : point1.column < point2.column;
717         return (point1.row < point2.row) || (point1.row == point2.row && bColIsAfter);
718     }
719             
720     function $getTransformedPoint(delta, point, moveIfEqual) {
721         var deltaIsInsert = delta.action == "insert";
722         var deltaRowShift = (deltaIsInsert ? 1 : -1) * (delta.end.row    - delta.start.row);
723         var deltaColShift = (deltaIsInsert ? 1 : -1) * (delta.end.column - delta.start.column);
724         var deltaStart = delta.start;
725         var deltaEnd = deltaIsInsert ? deltaStart : delta.end; // Collapse insert range.
726         if ($pointsInOrder(point, deltaStart, moveIfEqual)) {
727             return {
728                 row: point.row,
729                 column: point.column
730             };
731         }
732         if ($pointsInOrder(deltaEnd, point, !moveIfEqual)) {
733             return {
734                 row: point.row + deltaRowShift,
735                 column: point.column + (point.row == deltaEnd.row ? deltaColShift : 0)
736             };
737         }
738         
739         return {
740             row: deltaStart.row,
741             column: deltaStart.column
742         };
743     }
744     this.setPosition = function(row, column, noClip) {
745         var pos;
746         if (noClip) {
747             pos = {
748                 row: row,
749                 column: column
750             };
751         } else {
752             pos = this.$clipPositionToDocument(row, column);
753         }
754
755         if (this.row == pos.row && this.column == pos.column)
756             return;
757
758         var old = {
759             row: this.row,
760             column: this.column
761         };
762
763         this.row = pos.row;
764         this.column = pos.column;
765         this._signal("change", {
766             old: old,
767             value: pos
768         });
769     };
770     this.detach = function() {
771         this.document.removeEventListener("change", this.$onChange);
772     };
773     this.attach = function(doc) {
774         this.document = doc || this.document;
775         this.document.on("change", this.$onChange);
776     };
777     this.$clipPositionToDocument = function(row, column) {
778         var pos = {};
779
780         if (row >= this.document.getLength()) {
781             pos.row = Math.max(0, this.document.getLength() - 1);
782             pos.column = this.document.getLine(pos.row).length;
783         }
784         else if (row < 0) {
785             pos.row = 0;
786             pos.column = 0;
787         }
788         else {
789             pos.row = row;
790             pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));
791         }
792
793         if (column < 0)
794             pos.column = 0;
795
796         return pos;
797     };
798
799 }).call(Anchor.prototype);
800
801 });
802
803 define("ace/document",["require","exports","module","ace/lib/oop","ace/apply_delta","ace/lib/event_emitter","ace/range","ace/anchor"], function(require, exports, module) {
804 "use strict";
805
806 var oop = require("./lib/oop");
807 var applyDelta = require("./apply_delta").applyDelta;
808 var EventEmitter = require("./lib/event_emitter").EventEmitter;
809 var Range = require("./range").Range;
810 var Anchor = require("./anchor").Anchor;
811
812 var Document = function(textOrLines) {
813     this.$lines = [""];
814     if (textOrLines.length === 0) {
815         this.$lines = [""];
816     } else if (Array.isArray(textOrLines)) {
817         this.insertMergedLines({row: 0, column: 0}, textOrLines);
818     } else {
819         this.insert({row: 0, column:0}, textOrLines);
820     }
821 };
822
823 (function() {
824
825     oop.implement(this, EventEmitter);
826     this.setValue = function(text) {
827         var len = this.getLength() - 1;
828         this.remove(new Range(0, 0, len, this.getLine(len).length));
829         this.insert({row: 0, column: 0}, text);
830     };
831     this.getValue = function() {
832         return this.getAllLines().join(this.getNewLineCharacter());
833     };
834     this.createAnchor = function(row, column) {
835         return new Anchor(this, row, column);
836     };
837     if ("aaa".split(/a/).length === 0) {
838         this.$split = function(text) {
839             return text.replace(/\r\n|\r/g, "\n").split("\n");
840         };
841     } else {
842         this.$split = function(text) {
843             return text.split(/\r\n|\r|\n/);
844         };
845     }
846
847
848     this.$detectNewLine = function(text) {
849         var match = text.match(/^.*?(\r\n|\r|\n)/m);
850         this.$autoNewLine = match ? match[1] : "\n";
851         this._signal("changeNewLineMode");
852     };
853     this.getNewLineCharacter = function() {
854         switch (this.$newLineMode) {
855           case "windows":
856             return "\r\n";
857           case "unix":
858             return "\n";
859           default:
860             return this.$autoNewLine || "\n";
861         }
862     };
863
864     this.$autoNewLine = "";
865     this.$newLineMode = "auto";
866     this.setNewLineMode = function(newLineMode) {
867         if (this.$newLineMode === newLineMode)
868             return;
869
870         this.$newLineMode = newLineMode;
871         this._signal("changeNewLineMode");
872     };
873     this.getNewLineMode = function() {
874         return this.$newLineMode;
875     };
876     this.isNewLine = function(text) {
877         return (text == "\r\n" || text == "\r" || text == "\n");
878     };
879     this.getLine = function(row) {
880         return this.$lines[row] || "";
881     };
882     this.getLines = function(firstRow, lastRow) {
883         return this.$lines.slice(firstRow, lastRow + 1);
884     };
885     this.getAllLines = function() {
886         return this.getLines(0, this.getLength());
887     };
888     this.getLength = function() {
889         return this.$lines.length;
890     };
891     this.getTextRange = function(range) {
892         return this.getLinesForRange(range).join(this.getNewLineCharacter());
893     };
894     this.getLinesForRange = function(range) {
895         var lines;
896         if (range.start.row === range.end.row) {
897             lines = [this.getLine(range.start.row).substring(range.start.column, range.end.column)];
898         } else {
899             lines = this.getLines(range.start.row, range.end.row);
900             lines[0] = (lines[0] || "").substring(range.start.column);
901             var l = lines.length - 1;
902             if (range.end.row - range.start.row == l)
903                 lines[l] = lines[l].substring(0, range.end.column);
904         }
905         return lines;
906     };
907     this.insertLines = function(row, lines) {
908         console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead.");
909         return this.insertFullLines(row, lines);
910     };
911     this.removeLines = function(firstRow, lastRow) {
912         console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead.");
913         return this.removeFullLines(firstRow, lastRow);
914     };
915     this.insertNewLine = function(position) {
916         console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead.");
917         return this.insertMergedLines(position, ["", ""]);
918     };
919     this.insert = function(position, text) {
920         if (this.getLength() <= 1)
921             this.$detectNewLine(text);
922         
923         return this.insertMergedLines(position, this.$split(text));
924     };
925     this.insertInLine = function(position, text) {
926         var start = this.clippedPos(position.row, position.column);
927         var end = this.pos(position.row, position.column + text.length);
928         
929         this.applyDelta({
930             start: start,
931             end: end,
932             action: "insert",
933             lines: [text]
934         }, true);
935         
936         return this.clonePos(end);
937     };
938     
939     this.clippedPos = function(row, column) {
940         var length = this.getLength();
941         if (row === undefined) {
942             row = length;
943         } else if (row < 0) {
944             row = 0;
945         } else if (row >= length) {
946             row = length - 1;
947             column = undefined;
948         }
949         var line = this.getLine(row);
950         if (column == undefined)
951             column = line.length;
952         column = Math.min(Math.max(column, 0), line.length);
953         return {row: row, column: column};
954     };
955     
956     this.clonePos = function(pos) {
957         return {row: pos.row, column: pos.column};
958     };
959     
960     this.pos = function(row, column) {
961         return {row: row, column: column};
962     };
963     
964     this.$clipPosition = function(position) {
965         var length = this.getLength();
966         if (position.row >= length) {
967             position.row = Math.max(0, length - 1);
968             position.column = this.getLine(length - 1).length;
969         } else {
970             position.row = Math.max(0, position.row);
971             position.column = Math.min(Math.max(position.column, 0), this.getLine(position.row).length);
972         }
973         return position;
974     };
975     this.insertFullLines = function(row, lines) {
976         row = Math.min(Math.max(row, 0), this.getLength());
977         var column = 0;
978         if (row < this.getLength()) {
979             lines = lines.concat([""]);
980             column = 0;
981         } else {
982             lines = [""].concat(lines);
983             row--;
984             column = this.$lines[row].length;
985         }
986         this.insertMergedLines({row: row, column: column}, lines);
987     };    
988     this.insertMergedLines = function(position, lines) {
989         var start = this.clippedPos(position.row, position.column);
990         var end = {
991             row: start.row + lines.length - 1,
992             column: (lines.length == 1 ? start.column : 0) + lines[lines.length - 1].length
993         };
994         
995         this.applyDelta({
996             start: start,
997             end: end,
998             action: "insert",
999             lines: lines
1000         });
1001         
1002         return this.clonePos(end);
1003     };
1004     this.remove = function(range) {
1005         var start = this.clippedPos(range.start.row, range.start.column);
1006         var end = this.clippedPos(range.end.row, range.end.column);
1007         this.applyDelta({
1008             start: start,
1009             end: end,
1010             action: "remove",
1011             lines: this.getLinesForRange({start: start, end: end})
1012         });
1013         return this.clonePos(start);
1014     };
1015     this.removeInLine = function(row, startColumn, endColumn) {
1016         var start = this.clippedPos(row, startColumn);
1017         var end = this.clippedPos(row, endColumn);
1018         
1019         this.applyDelta({
1020             start: start,
1021             end: end,
1022             action: "remove",
1023             lines: this.getLinesForRange({start: start, end: end})
1024         }, true);
1025         
1026         return this.clonePos(start);
1027     };
1028     this.removeFullLines = function(firstRow, lastRow) {
1029         firstRow = Math.min(Math.max(0, firstRow), this.getLength() - 1);
1030         lastRow  = Math.min(Math.max(0, lastRow ), this.getLength() - 1);
1031         var deleteFirstNewLine = lastRow == this.getLength() - 1 && firstRow > 0;
1032         var deleteLastNewLine  = lastRow  < this.getLength() - 1;
1033         var startRow = ( deleteFirstNewLine ? firstRow - 1                  : firstRow                    );
1034         var startCol = ( deleteFirstNewLine ? this.getLine(startRow).length : 0                           );
1035         var endRow   = ( deleteLastNewLine  ? lastRow + 1                   : lastRow                     );
1036         var endCol   = ( deleteLastNewLine  ? 0                             : this.getLine(endRow).length ); 
1037         var range = new Range(startRow, startCol, endRow, endCol);
1038         var deletedLines = this.$lines.slice(firstRow, lastRow + 1);
1039         
1040         this.applyDelta({
1041             start: range.start,
1042             end: range.end,
1043             action: "remove",
1044             lines: this.getLinesForRange(range)
1045         });
1046         return deletedLines;
1047     };
1048     this.removeNewLine = function(row) {
1049         if (row < this.getLength() - 1 && row >= 0) {
1050             this.applyDelta({
1051                 start: this.pos(row, this.getLine(row).length),
1052                 end: this.pos(row + 1, 0),
1053                 action: "remove",
1054                 lines: ["", ""]
1055             });
1056         }
1057     };
1058     this.replace = function(range, text) {
1059         if (!(range instanceof Range))
1060             range = Range.fromPoints(range.start, range.end);
1061         if (text.length === 0 && range.isEmpty())
1062             return range.start;
1063         if (text == this.getTextRange(range))
1064             return range.end;
1065
1066         this.remove(range);
1067         var end;
1068         if (text) {
1069             end = this.insert(range.start, text);
1070         }
1071         else {
1072             end = range.start;
1073         }
1074         
1075         return end;
1076     };
1077     this.applyDeltas = function(deltas) {
1078         for (var i=0; i<deltas.length; i++) {
1079             this.applyDelta(deltas[i]);
1080         }
1081     };
1082     this.revertDeltas = function(deltas) {
1083         for (var i=deltas.length-1; i>=0; i--) {
1084             this.revertDelta(deltas[i]);
1085         }
1086     };
1087     this.applyDelta = function(delta, doNotValidate) {
1088         var isInsert = delta.action == "insert";
1089         if (isInsert ? delta.lines.length <= 1 && !delta.lines[0]
1090             : !Range.comparePoints(delta.start, delta.end)) {
1091             return;
1092         }
1093         
1094         if (isInsert && delta.lines.length > 20000)
1095             this.$splitAndapplyLargeDelta(delta, 20000);
1096         applyDelta(this.$lines, delta, doNotValidate);
1097         this._signal("change", delta);
1098     };
1099     
1100     this.$splitAndapplyLargeDelta = function(delta, MAX) {
1101         var lines = delta.lines;
1102         var l = lines.length;
1103         var row = delta.start.row; 
1104         var column = delta.start.column;
1105         var from = 0, to = 0;
1106         do {
1107             from = to;
1108             to += MAX - 1;
1109             var chunk = lines.slice(from, to);
1110             if (to > l) {
1111                 delta.lines = chunk;
1112                 delta.start.row = row + from;
1113                 delta.start.column = column;
1114                 break;
1115             }
1116             chunk.push("");
1117             this.applyDelta({
1118                 start: this.pos(row + from, column),
1119                 end: this.pos(row + to, column = 0),
1120                 action: delta.action,
1121                 lines: chunk
1122             }, true);
1123         } while(true);
1124     };
1125     this.revertDelta = function(delta) {
1126         this.applyDelta({
1127             start: this.clonePos(delta.start),
1128             end: this.clonePos(delta.end),
1129             action: (delta.action == "insert" ? "remove" : "insert"),
1130             lines: delta.lines.slice()
1131         });
1132     };
1133     this.indexToPosition = function(index, startRow) {
1134         var lines = this.$lines || this.getAllLines();
1135         var newlineLength = this.getNewLineCharacter().length;
1136         for (var i = startRow || 0, l = lines.length; i < l; i++) {
1137             index -= lines[i].length + newlineLength;
1138             if (index < 0)
1139                 return {row: i, column: index + lines[i].length + newlineLength};
1140         }
1141         return {row: l-1, column: lines[l-1].length};
1142     };
1143     this.positionToIndex = function(pos, startRow) {
1144         var lines = this.$lines || this.getAllLines();
1145         var newlineLength = this.getNewLineCharacter().length;
1146         var index = 0;
1147         var row = Math.min(pos.row, lines.length);
1148         for (var i = startRow || 0; i < row; ++i)
1149             index += lines[i].length + newlineLength;
1150
1151         return index + pos.column;
1152     };
1153
1154 }).call(Document.prototype);
1155
1156 exports.Document = Document;
1157 });
1158
1159 define("ace/lib/lang",["require","exports","module"], function(require, exports, module) {
1160 "use strict";
1161
1162 exports.last = function(a) {
1163     return a[a.length - 1];
1164 };
1165
1166 exports.stringReverse = function(string) {
1167     return string.split("").reverse().join("");
1168 };
1169
1170 exports.stringRepeat = function (string, count) {
1171     var result = '';
1172     while (count > 0) {
1173         if (count & 1)
1174             result += string;
1175
1176         if (count >>= 1)
1177             string += string;
1178     }
1179     return result;
1180 };
1181
1182 var trimBeginRegexp = /^\s\s*/;
1183 var trimEndRegexp = /\s\s*$/;
1184
1185 exports.stringTrimLeft = function (string) {
1186     return string.replace(trimBeginRegexp, '');
1187 };
1188
1189 exports.stringTrimRight = function (string) {
1190     return string.replace(trimEndRegexp, '');
1191 };
1192
1193 exports.copyObject = function(obj) {
1194     var copy = {};
1195     for (var key in obj) {
1196         copy[key] = obj[key];
1197     }
1198     return copy;
1199 };
1200
1201 exports.copyArray = function(array){
1202     var copy = [];
1203     for (var i=0, l=array.length; i<l; i++) {
1204         if (array[i] && typeof array[i] == "object")
1205             copy[i] = this.copyObject(array[i]);
1206         else 
1207             copy[i] = array[i];
1208     }
1209     return copy;
1210 };
1211
1212 exports.deepCopy = function deepCopy(obj) {
1213     if (typeof obj !== "object" || !obj)
1214         return obj;
1215     var copy;
1216     if (Array.isArray(obj)) {
1217         copy = [];
1218         for (var key = 0; key < obj.length; key++) {
1219             copy[key] = deepCopy(obj[key]);
1220         }
1221         return copy;
1222     }
1223     if (Object.prototype.toString.call(obj) !== "[object Object]")
1224         return obj;
1225     
1226     copy = {};
1227     for (var key in obj)
1228         copy[key] = deepCopy(obj[key]);
1229     return copy;
1230 };
1231
1232 exports.arrayToMap = function(arr) {
1233     var map = {};
1234     for (var i=0; i<arr.length; i++) {
1235         map[arr[i]] = 1;
1236     }
1237     return map;
1238
1239 };
1240
1241 exports.createMap = function(props) {
1242     var map = Object.create(null);
1243     for (var i in props) {
1244         map[i] = props[i];
1245     }
1246     return map;
1247 };
1248 exports.arrayRemove = function(array, value) {
1249   for (var i = 0; i <= array.length; i++) {
1250     if (value === array[i]) {
1251       array.splice(i, 1);
1252     }
1253   }
1254 };
1255
1256 exports.escapeRegExp = function(str) {
1257     return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
1258 };
1259
1260 exports.escapeHTML = function(str) {
1261     return str.replace(/&/g, "&#38;").replace(/"/g, "&#34;").replace(/'/g, "&#39;").replace(/</g, "&#60;");
1262 };
1263
1264 exports.getMatchOffsets = function(string, regExp) {
1265     var matches = [];
1266
1267     string.replace(regExp, function(str) {
1268         matches.push({
1269             offset: arguments[arguments.length-2],
1270             length: str.length
1271         });
1272     });
1273
1274     return matches;
1275 };
1276 exports.deferredCall = function(fcn) {
1277     var timer = null;
1278     var callback = function() {
1279         timer = null;
1280         fcn();
1281     };
1282
1283     var deferred = function(timeout) {
1284         deferred.cancel();
1285         timer = setTimeout(callback, timeout || 0);
1286         return deferred;
1287     };
1288
1289     deferred.schedule = deferred;
1290
1291     deferred.call = function() {
1292         this.cancel();
1293         fcn();
1294         return deferred;
1295     };
1296
1297     deferred.cancel = function() {
1298         clearTimeout(timer);
1299         timer = null;
1300         return deferred;
1301     };
1302     
1303     deferred.isPending = function() {
1304         return timer;
1305     };
1306
1307     return deferred;
1308 };
1309
1310
1311 exports.delayedCall = function(fcn, defaultTimeout) {
1312     var timer = null;
1313     var callback = function() {
1314         timer = null;
1315         fcn();
1316     };
1317
1318     var _self = function(timeout) {
1319         if (timer == null)
1320             timer = setTimeout(callback, timeout || defaultTimeout);
1321     };
1322
1323     _self.delay = function(timeout) {
1324         timer && clearTimeout(timer);
1325         timer = setTimeout(callback, timeout || defaultTimeout);
1326     };
1327     _self.schedule = _self;
1328
1329     _self.call = function() {
1330         this.cancel();
1331         fcn();
1332     };
1333
1334     _self.cancel = function() {
1335         timer && clearTimeout(timer);
1336         timer = null;
1337     };
1338
1339     _self.isPending = function() {
1340         return timer;
1341     };
1342
1343     return _self;
1344 };
1345 });
1346
1347 define("ace/worker/mirror",["require","exports","module","ace/range","ace/document","ace/lib/lang"], function(require, exports, module) {
1348 "use strict";
1349
1350 var Range = require("../range").Range;
1351 var Document = require("../document").Document;
1352 var lang = require("../lib/lang");
1353     
1354 var Mirror = exports.Mirror = function(sender) {
1355     this.sender = sender;
1356     var doc = this.doc = new Document("");
1357     
1358     var deferredUpdate = this.deferredUpdate = lang.delayedCall(this.onUpdate.bind(this));
1359     
1360     var _self = this;
1361     sender.on("change", function(e) {
1362         var data = e.data;
1363         if (data[0].start) {
1364             doc.applyDeltas(data);
1365         } else {
1366             for (var i = 0; i < data.length; i += 2) {
1367                 if (Array.isArray(data[i+1])) {
1368                     var d = {action: "insert", start: data[i], lines: data[i+1]};
1369                 } else {
1370                     var d = {action: "remove", start: data[i], end: data[i+1]};
1371                 }
1372                 doc.applyDelta(d, true);
1373             }
1374         }
1375         if (_self.$timeout)
1376             return deferredUpdate.schedule(_self.$timeout);
1377         _self.onUpdate();
1378     });
1379 };
1380
1381 (function() {
1382     
1383     this.$timeout = 500;
1384     
1385     this.setTimeout = function(timeout) {
1386         this.$timeout = timeout;
1387     };
1388     
1389     this.setValue = function(value) {
1390         this.doc.setValue(value);
1391         this.deferredUpdate.schedule(this.$timeout);
1392     };
1393     
1394     this.getValue = function(callbackId) {
1395         this.sender.callback(this.doc.getValue(), callbackId);
1396     };
1397     
1398     this.onUpdate = function() {
1399     };
1400     
1401     this.isPending = function() {
1402         return this.deferredUpdate.isPending();
1403     };
1404     
1405 }).call(Mirror.prototype);
1406
1407 });
1408
1409 define("ace/mode/javascript/jshint",["require","exports","module"], function(require, exports, module) {
1410 module.exports = (function outer (modules, cache, entry) {
1411     var previousRequire = typeof require == "function" && require;
1412     function newRequire(name, jumped){
1413         if(!cache[name]) {
1414             if(!modules[name]) {
1415                 var currentRequire = typeof require == "function" && require;
1416                 if (!jumped && currentRequire) return currentRequire(name, true);
1417                 if (previousRequire) return previousRequire(name, true);
1418                 var err = new Error('Cannot find module \'' + name + '\'');
1419                 err.code = 'MODULE_NOT_FOUND';
1420                 throw err;
1421             }
1422             var m = cache[name] = {exports:{}};
1423             modules[name][0].call(m.exports, function(x){
1424                 var id = modules[name][1][x];
1425                 return newRequire(id ? id : x);
1426             },m,m.exports,outer,modules,cache,entry);
1427         }
1428         return cache[name].exports;
1429     }
1430     for(var i=0;i<entry.length;i++) newRequire(entry[i]);
1431     return newRequire(entry[0]);
1432 })
1433 ({"/node_modules/browserify/node_modules/events/events.js":[function(_dereq_,module,exports){
1434
1435 function EventEmitter() {
1436   this._events = this._events || {};
1437   this._maxListeners = this._maxListeners || undefined;
1438 }
1439 module.exports = EventEmitter;
1440 EventEmitter.EventEmitter = EventEmitter;
1441
1442 EventEmitter.prototype._events = undefined;
1443 EventEmitter.prototype._maxListeners = undefined;
1444 EventEmitter.defaultMaxListeners = 10;
1445 EventEmitter.prototype.setMaxListeners = function(n) {
1446   if (!isNumber(n) || n < 0 || isNaN(n))
1447     throw TypeError('n must be a positive number');
1448   this._maxListeners = n;
1449   return this;
1450 };
1451
1452 EventEmitter.prototype.emit = function(type) {
1453   var er, handler, len, args, i, listeners;
1454
1455   if (!this._events)
1456     this._events = {};
1457   if (type === 'error') {
1458     if (!this._events.error ||
1459         (isObject(this._events.error) && !this._events.error.length)) {
1460       er = arguments[1];
1461       if (er instanceof Error) {
1462         throw er; // Unhandled 'error' event
1463       }
1464       throw TypeError('Uncaught, unspecified "error" event.');
1465     }
1466   }
1467
1468   handler = this._events[type];
1469
1470   if (isUndefined(handler))
1471     return false;
1472
1473   if (isFunction(handler)) {
1474     switch (arguments.length) {
1475       case 1:
1476         handler.call(this);
1477         break;
1478       case 2:
1479         handler.call(this, arguments[1]);
1480         break;
1481       case 3:
1482         handler.call(this, arguments[1], arguments[2]);
1483         break;
1484       default:
1485         len = arguments.length;
1486         args = new Array(len - 1);
1487         for (i = 1; i < len; i++)
1488           args[i - 1] = arguments[i];
1489         handler.apply(this, args);
1490     }
1491   } else if (isObject(handler)) {
1492     len = arguments.length;
1493     args = new Array(len - 1);
1494     for (i = 1; i < len; i++)
1495       args[i - 1] = arguments[i];
1496
1497     listeners = handler.slice();
1498     len = listeners.length;
1499     for (i = 0; i < len; i++)
1500       listeners[i].apply(this, args);
1501   }
1502
1503   return true;
1504 };
1505
1506 EventEmitter.prototype.addListener = function(type, listener) {
1507   var m;
1508
1509   if (!isFunction(listener))
1510     throw TypeError('listener must be a function');
1511
1512   if (!this._events)
1513     this._events = {};
1514   if (this._events.newListener)
1515     this.emit('newListener', type,
1516               isFunction(listener.listener) ?
1517               listener.listener : listener);
1518
1519   if (!this._events[type])
1520     this._events[type] = listener;
1521   else if (isObject(this._events[type]))
1522     this._events[type].push(listener);
1523   else
1524     this._events[type] = [this._events[type], listener];
1525   if (isObject(this._events[type]) && !this._events[type].warned) {
1526     var m;
1527     if (!isUndefined(this._maxListeners)) {
1528       m = this._maxListeners;
1529     } else {
1530       m = EventEmitter.defaultMaxListeners;
1531     }
1532
1533     if (m && m > 0 && this._events[type].length > m) {
1534       this._events[type].warned = true;
1535       console.error('(node) warning: possible EventEmitter memory ' +
1536                     'leak detected. %d listeners added. ' +
1537                     'Use emitter.setMaxListeners() to increase limit.',
1538                     this._events[type].length);
1539       if (typeof console.trace === 'function') {
1540         console.trace();
1541       }
1542     }
1543   }
1544
1545   return this;
1546 };
1547
1548 EventEmitter.prototype.on = EventEmitter.prototype.addListener;
1549
1550 EventEmitter.prototype.once = function(type, listener) {
1551   if (!isFunction(listener))
1552     throw TypeError('listener must be a function');
1553
1554   var fired = false;
1555
1556   function g() {
1557     this.removeListener(type, g);
1558
1559     if (!fired) {
1560       fired = true;
1561       listener.apply(this, arguments);
1562     }
1563   }
1564
1565   g.listener = listener;
1566   this.on(type, g);
1567
1568   return this;
1569 };
1570 EventEmitter.prototype.removeListener = function(type, listener) {
1571   var list, position, length, i;
1572
1573   if (!isFunction(listener))
1574     throw TypeError('listener must be a function');
1575
1576   if (!this._events || !this._events[type])
1577     return this;
1578
1579   list = this._events[type];
1580   length = list.length;
1581   position = -1;
1582
1583   if (list === listener ||
1584       (isFunction(list.listener) && list.listener === listener)) {
1585     delete this._events[type];
1586     if (this._events.removeListener)
1587       this.emit('removeListener', type, listener);
1588
1589   } else if (isObject(list)) {
1590     for (i = length; i-- > 0;) {
1591       if (list[i] === listener ||
1592           (list[i].listener && list[i].listener === listener)) {
1593         position = i;
1594         break;
1595       }
1596     }
1597
1598     if (position < 0)
1599       return this;
1600
1601     if (list.length === 1) {
1602       list.length = 0;
1603       delete this._events[type];
1604     } else {
1605       list.splice(position, 1);
1606     }
1607
1608     if (this._events.removeListener)
1609       this.emit('removeListener', type, listener);
1610   }
1611
1612   return this;
1613 };
1614
1615 EventEmitter.prototype.removeAllListeners = function(type) {
1616   var key, listeners;
1617
1618   if (!this._events)
1619     return this;
1620   if (!this._events.removeListener) {
1621     if (arguments.length === 0)
1622       this._events = {};
1623     else if (this._events[type])
1624       delete this._events[type];
1625     return this;
1626   }
1627   if (arguments.length === 0) {
1628     for (key in this._events) {
1629       if (key === 'removeListener') continue;
1630       this.removeAllListeners(key);
1631     }
1632     this.removeAllListeners('removeListener');
1633     this._events = {};
1634     return this;
1635   }
1636
1637   listeners = this._events[type];
1638
1639   if (isFunction(listeners)) {
1640     this.removeListener(type, listeners);
1641   } else {
1642     while (listeners.length)
1643       this.removeListener(type, listeners[listeners.length - 1]);
1644   }
1645   delete this._events[type];
1646
1647   return this;
1648 };
1649
1650 EventEmitter.prototype.listeners = function(type) {
1651   var ret;
1652   if (!this._events || !this._events[type])
1653     ret = [];
1654   else if (isFunction(this._events[type]))
1655     ret = [this._events[type]];
1656   else
1657     ret = this._events[type].slice();
1658   return ret;
1659 };
1660
1661 EventEmitter.listenerCount = function(emitter, type) {
1662   var ret;
1663   if (!emitter._events || !emitter._events[type])
1664     ret = 0;
1665   else if (isFunction(emitter._events[type]))
1666     ret = 1;
1667   else
1668     ret = emitter._events[type].length;
1669   return ret;
1670 };
1671
1672 function isFunction(arg) {
1673   return typeof arg === 'function';
1674 }
1675
1676 function isNumber(arg) {
1677   return typeof arg === 'number';
1678 }
1679
1680 function isObject(arg) {
1681   return typeof arg === 'object' && arg !== null;
1682 }
1683
1684 function isUndefined(arg) {
1685   return arg === void 0;
1686 }
1687
1688 },{}],"/node_modules/jshint/data/ascii-identifier-data.js":[function(_dereq_,module,exports){
1689 var identifierStartTable = [];
1690
1691 for (var i = 0; i < 128; i++) {
1692   identifierStartTable[i] =
1693     i === 36 ||           // $
1694     i >= 65 && i <= 90 || // A-Z
1695     i === 95 ||           // _
1696     i >= 97 && i <= 122;  // a-z
1697 }
1698
1699 var identifierPartTable = [];
1700
1701 for (var i = 0; i < 128; i++) {
1702   identifierPartTable[i] =
1703     identifierStartTable[i] || // $, _, A-Z, a-z
1704     i >= 48 && i <= 57;        // 0-9
1705 }
1706
1707 module.exports = {
1708   asciiIdentifierStartTable: identifierStartTable,
1709   asciiIdentifierPartTable: identifierPartTable
1710 };
1711
1712 },{}],"/node_modules/jshint/lodash.js":[function(_dereq_,module,exports){
1713 (function (global){
1714 ;(function() {
1715
1716   var undefined;
1717
1718   var VERSION = '3.7.0';
1719
1720   var FUNC_ERROR_TEXT = 'Expected a function';
1721
1722   var argsTag = '[object Arguments]',
1723       arrayTag = '[object Array]',
1724       boolTag = '[object Boolean]',
1725       dateTag = '[object Date]',
1726       errorTag = '[object Error]',
1727       funcTag = '[object Function]',
1728       mapTag = '[object Map]',
1729       numberTag = '[object Number]',
1730       objectTag = '[object Object]',
1731       regexpTag = '[object RegExp]',
1732       setTag = '[object Set]',
1733       stringTag = '[object String]',
1734       weakMapTag = '[object WeakMap]';
1735
1736   var arrayBufferTag = '[object ArrayBuffer]',
1737       float32Tag = '[object Float32Array]',
1738       float64Tag = '[object Float64Array]',
1739       int8Tag = '[object Int8Array]',
1740       int16Tag = '[object Int16Array]',
1741       int32Tag = '[object Int32Array]',
1742       uint8Tag = '[object Uint8Array]',
1743       uint8ClampedTag = '[object Uint8ClampedArray]',
1744       uint16Tag = '[object Uint16Array]',
1745       uint32Tag = '[object Uint32Array]';
1746
1747   var reIsDeepProp = /\.|\[(?:[^[\]]+|(["'])(?:(?!\1)[^\n\\]|\\.)*?)\1\]/,
1748       reIsPlainProp = /^\w*$/,
1749       rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;
1750
1751   var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g,
1752       reHasRegExpChars = RegExp(reRegExpChars.source);
1753
1754   var reEscapeChar = /\\(\\)?/g;
1755
1756   var reFlags = /\w*$/;
1757
1758   var reIsHostCtor = /^\[object .+?Constructor\]$/;
1759
1760   var typedArrayTags = {};
1761   typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
1762   typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
1763   typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
1764   typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
1765   typedArrayTags[uint32Tag] = true;
1766   typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
1767   typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
1768   typedArrayTags[dateTag] = typedArrayTags[errorTag] =
1769   typedArrayTags[funcTag] = typedArrayTags[mapTag] =
1770   typedArrayTags[numberTag] = typedArrayTags[objectTag] =
1771   typedArrayTags[regexpTag] = typedArrayTags[setTag] =
1772   typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
1773
1774   var cloneableTags = {};
1775   cloneableTags[argsTag] = cloneableTags[arrayTag] =
1776   cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
1777   cloneableTags[dateTag] = cloneableTags[float32Tag] =
1778   cloneableTags[float64Tag] = cloneableTags[int8Tag] =
1779   cloneableTags[int16Tag] = cloneableTags[int32Tag] =
1780   cloneableTags[numberTag] = cloneableTags[objectTag] =
1781   cloneableTags[regexpTag] = cloneableTags[stringTag] =
1782   cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
1783   cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
1784   cloneableTags[errorTag] = cloneableTags[funcTag] =
1785   cloneableTags[mapTag] = cloneableTags[setTag] =
1786   cloneableTags[weakMapTag] = false;
1787
1788   var objectTypes = {
1789     'function': true,
1790     'object': true
1791   };
1792
1793   var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
1794
1795   var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
1796
1797   var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global;
1798
1799   var freeSelf = objectTypes[typeof self] && self && self.Object && self;
1800
1801   var freeWindow = objectTypes[typeof window] && window && window.Object && window;
1802
1803   var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
1804
1805   var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;
1806
1807   function baseFindIndex(array, predicate, fromRight) {
1808     var length = array.length,
1809         index = fromRight ? length : -1;
1810
1811     while ((fromRight ? index-- : ++index < length)) {
1812       if (predicate(array[index], index, array)) {
1813         return index;
1814       }
1815     }
1816     return -1;
1817   }
1818
1819   function baseIndexOf(array, value, fromIndex) {
1820     if (value !== value) {
1821       return indexOfNaN(array, fromIndex);
1822     }
1823     var index = fromIndex - 1,
1824         length = array.length;
1825
1826     while (++index < length) {
1827       if (array[index] === value) {
1828         return index;
1829       }
1830     }
1831     return -1;
1832   }
1833
1834   function baseIsFunction(value) {
1835     return typeof value == 'function' || false;
1836   }
1837
1838   function baseToString(value) {
1839     if (typeof value == 'string') {
1840       return value;
1841     }
1842     return value == null ? '' : (value + '');
1843   }
1844
1845   function indexOfNaN(array, fromIndex, fromRight) {
1846     var length = array.length,
1847         index = fromIndex + (fromRight ? 0 : -1);
1848
1849     while ((fromRight ? index-- : ++index < length)) {
1850       var other = array[index];
1851       if (other !== other) {
1852         return index;
1853       }
1854     }
1855     return -1;
1856   }
1857
1858   function isObjectLike(value) {
1859     return !!value && typeof value == 'object';
1860   }
1861
1862   var arrayProto = Array.prototype,
1863       objectProto = Object.prototype;
1864
1865   var fnToString = Function.prototype.toString;
1866
1867   var hasOwnProperty = objectProto.hasOwnProperty;
1868
1869   var objToString = objectProto.toString;
1870
1871   var reIsNative = RegExp('^' +
1872     escapeRegExp(objToString)
1873     .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1874   );
1875
1876   var ArrayBuffer = isNative(ArrayBuffer = root.ArrayBuffer) && ArrayBuffer,
1877       bufferSlice = isNative(bufferSlice = ArrayBuffer && new ArrayBuffer(0).slice) && bufferSlice,
1878       floor = Math.floor,
1879       getOwnPropertySymbols = isNative(getOwnPropertySymbols = Object.getOwnPropertySymbols) && getOwnPropertySymbols,
1880       getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
1881       push = arrayProto.push,
1882       preventExtensions = isNative(Object.preventExtensions = Object.preventExtensions) && preventExtensions,
1883       propertyIsEnumerable = objectProto.propertyIsEnumerable,
1884       Uint8Array = isNative(Uint8Array = root.Uint8Array) && Uint8Array;
1885
1886   var Float64Array = (function() {
1887     try {
1888       var func = isNative(func = root.Float64Array) && func,
1889           result = new func(new ArrayBuffer(10), 0, 1) && func;
1890     } catch(e) {}
1891     return result;
1892   }());
1893
1894   var nativeAssign = (function() {
1895     var object = { '1': 0 },
1896         func = preventExtensions && isNative(func = Object.assign) && func;
1897
1898     try { func(preventExtensions(object), 'xo'); } catch(e) {}
1899     return !object[1] && func;
1900   }());
1901
1902   var nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
1903       nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
1904       nativeMax = Math.max,
1905       nativeMin = Math.min;
1906
1907   var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY;
1908
1909   var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1,
1910       MAX_ARRAY_INDEX =  MAX_ARRAY_LENGTH - 1,
1911       HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
1912
1913   var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0;
1914
1915   var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
1916
1917   function lodash() {
1918   }
1919
1920   var support = lodash.support = {};
1921
1922   (function(x) {
1923     var Ctor = function() { this.x = x; },
1924         object = { '0': x, 'length': x },
1925         props = [];
1926
1927     Ctor.prototype = { 'valueOf': x, 'y': x };
1928     for (var key in new Ctor) { props.push(key); }
1929
1930     support.funcDecomp = /\bthis\b/.test(function() { return this; });
1931
1932     support.funcNames = typeof Function.name == 'string';
1933
1934     try {
1935       support.nonEnumArgs = !propertyIsEnumerable.call(arguments, 1);
1936     } catch(e) {
1937       support.nonEnumArgs = true;
1938     }
1939   }(1, 0));
1940
1941   function arrayCopy(source, array) {
1942     var index = -1,
1943         length = source.length;
1944
1945     array || (array = Array(length));
1946     while (++index < length) {
1947       array[index] = source[index];
1948     }
1949     return array;
1950   }
1951
1952   function arrayEach(array, iteratee) {
1953     var index = -1,
1954         length = array.length;
1955
1956     while (++index < length) {
1957       if (iteratee(array[index], index, array) === false) {
1958         break;
1959       }
1960     }
1961     return array;
1962   }
1963
1964   function arrayFilter(array, predicate) {
1965     var index = -1,
1966         length = array.length,
1967         resIndex = -1,
1968         result = [];
1969
1970     while (++index < length) {
1971       var value = array[index];
1972       if (predicate(value, index, array)) {
1973         result[++resIndex] = value;
1974       }
1975     }
1976     return result;
1977   }
1978
1979   function arrayMap(array, iteratee) {
1980     var index = -1,
1981         length = array.length,
1982         result = Array(length);
1983
1984     while (++index < length) {
1985       result[index] = iteratee(array[index], index, array);
1986     }
1987     return result;
1988   }
1989
1990   function arrayMax(array) {
1991     var index = -1,
1992         length = array.length,
1993         result = NEGATIVE_INFINITY;
1994
1995     while (++index < length) {
1996       var value = array[index];
1997       if (value > result) {
1998         result = value;
1999       }
2000     }
2001     return result;
2002   }
2003
2004   function arraySome(array, predicate) {
2005     var index = -1,
2006         length = array.length;
2007
2008     while (++index < length) {
2009       if (predicate(array[index], index, array)) {
2010         return true;
2011       }
2012     }
2013     return false;
2014   }
2015
2016   function assignWith(object, source, customizer) {
2017     var props = keys(source);
2018     push.apply(props, getSymbols(source));
2019
2020     var index = -1,
2021         length = props.length;
2022
2023     while (++index < length) {
2024       var key = props[index],
2025           value = object[key],
2026           result = customizer(value, source[key], key, object, source);
2027
2028       if ((result === result ? (result !== value) : (value === value)) ||
2029           (value === undefined && !(key in object))) {
2030         object[key] = result;
2031       }
2032     }
2033     return object;
2034   }
2035
2036   var baseAssign = nativeAssign || function(object, source) {
2037     return source == null
2038       ? object
2039       : baseCopy(source, getSymbols(source), baseCopy(source, keys(source), object));
2040   };
2041
2042   function baseCopy(source, props, object) {
2043     object || (object = {});
2044
2045     var index = -1,
2046         length = props.length;
2047
2048     while (++index < length) {
2049       var key = props[index];
2050       object[key] = source[key];
2051     }
2052     return object;
2053   }
2054
2055   function baseCallback(func, thisArg, argCount) {
2056     var type = typeof func;
2057     if (type == 'function') {
2058       return thisArg === undefined
2059         ? func
2060         : bindCallback(func, thisArg, argCount);
2061     }
2062     if (func == null) {
2063       return identity;
2064     }
2065     if (type == 'object') {
2066       return baseMatches(func);
2067     }
2068     return thisArg === undefined
2069       ? property(func)
2070       : baseMatchesProperty(func, thisArg);
2071   }
2072
2073   function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
2074     var result;
2075     if (customizer) {
2076       result = object ? customizer(value, key, object) : customizer(value);
2077     }
2078     if (result !== undefined) {
2079       return result;
2080     }
2081     if (!isObject(value)) {
2082       return value;
2083     }
2084     var isArr = isArray(value);
2085     if (isArr) {
2086       result = initCloneArray(value);
2087       if (!isDeep) {
2088         return arrayCopy(value, result);
2089       }
2090     } else {
2091       var tag = objToString.call(value),
2092           isFunc = tag == funcTag;
2093
2094       if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2095         result = initCloneObject(isFunc ? {} : value);
2096         if (!isDeep) {
2097           return baseAssign(result, value);
2098         }
2099       } else {
2100         return cloneableTags[tag]
2101           ? initCloneByTag(value, tag, isDeep)
2102           : (object ? value : {});
2103       }
2104     }
2105     stackA || (stackA = []);
2106     stackB || (stackB = []);
2107
2108     var length = stackA.length;
2109     while (length--) {
2110       if (stackA[length] == value) {
2111         return stackB[length];
2112       }
2113     }
2114     stackA.push(value);
2115     stackB.push(result);
2116
2117     (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
2118       result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);
2119     });
2120     return result;
2121   }
2122
2123   var baseEach = createBaseEach(baseForOwn);
2124
2125   function baseFilter(collection, predicate) {
2126     var result = [];
2127     baseEach(collection, function(value, index, collection) {
2128       if (predicate(value, index, collection)) {
2129         result.push(value);
2130       }
2131     });
2132     return result;
2133   }
2134
2135   var baseFor = createBaseFor();
2136
2137   function baseForIn(object, iteratee) {
2138     return baseFor(object, iteratee, keysIn);
2139   }
2140
2141   function baseForOwn(object, iteratee) {
2142     return baseFor(object, iteratee, keys);
2143   }
2144
2145   function baseGet(object, path, pathKey) {
2146     if (object == null) {
2147       return;
2148     }
2149     if (pathKey !== undefined && pathKey in toObject(object)) {
2150       path = [pathKey];
2151     }
2152     var index = -1,
2153         length = path.length;
2154
2155     while (object != null && ++index < length) {
2156       var result = object = object[path[index]];
2157     }
2158     return result;
2159   }
2160
2161   function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {
2162     if (value === other) {
2163       return value !== 0 || (1 / value == 1 / other);
2164     }
2165     var valType = typeof value,
2166         othType = typeof other;
2167
2168     if ((valType != 'function' && valType != 'object' && othType != 'function' && othType != 'object') ||
2169         value == null || other == null) {
2170       return value !== value && other !== other;
2171     }
2172     return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);
2173   }
2174
2175   function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
2176     var objIsArr = isArray(object),
2177         othIsArr = isArray(other),
2178         objTag = arrayTag,
2179         othTag = arrayTag;
2180
2181     if (!objIsArr) {
2182       objTag = objToString.call(object);
2183       if (objTag == argsTag) {
2184         objTag = objectTag;
2185       } else if (objTag != objectTag) {
2186         objIsArr = isTypedArray(object);
2187       }
2188     }
2189     if (!othIsArr) {
2190       othTag = objToString.call(other);
2191       if (othTag == argsTag) {
2192         othTag = objectTag;
2193       } else if (othTag != objectTag) {
2194         othIsArr = isTypedArray(other);
2195       }
2196     }
2197     var objIsObj = objTag == objectTag,
2198         othIsObj = othTag == objectTag,
2199         isSameTag = objTag == othTag;
2200
2201     if (isSameTag && !(objIsArr || objIsObj)) {
2202       return equalByTag(object, other, objTag);
2203     }
2204     if (!isLoose) {
2205       var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
2206           othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
2207
2208       if (valWrapped || othWrapped) {
2209         return equalFunc(valWrapped ? object.value() : object, othWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);
2210       }
2211     }
2212     if (!isSameTag) {
2213       return false;
2214     }
2215     stackA || (stackA = []);
2216     stackB || (stackB = []);
2217
2218     var length = stackA.length;
2219     while (length--) {
2220       if (stackA[length] == object) {
2221         return stackB[length] == other;
2222       }
2223     }
2224     stackA.push(object);
2225     stackB.push(other);
2226
2227     var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);
2228
2229     stackA.pop();
2230     stackB.pop();
2231
2232     return result;
2233   }
2234
2235   function baseIsMatch(object, props, values, strictCompareFlags, customizer) {
2236     var index = -1,
2237         length = props.length,
2238         noCustomizer = !customizer;
2239
2240     while (++index < length) {
2241       if ((noCustomizer && strictCompareFlags[index])
2242             ? values[index] !== object[props[index]]
2243             : !(props[index] in object)
2244           ) {
2245         return false;
2246       }
2247     }
2248     index = -1;
2249     while (++index < length) {
2250       var key = props[index],
2251           objValue = object[key],
2252           srcValue = values[index];
2253
2254       if (noCustomizer && strictCompareFlags[index]) {
2255         var result = objValue !== undefined || (key in object);
2256       } else {
2257         result = customizer ? customizer(objValue, srcValue, key) : undefined;
2258         if (result === undefined) {
2259           result = baseIsEqual(srcValue, objValue, customizer, true);
2260         }
2261       }
2262       if (!result) {
2263         return false;
2264       }
2265     }
2266     return true;
2267   }
2268
2269   function baseMatches(source) {
2270     var props = keys(source),
2271         length = props.length;
2272
2273     if (!length) {
2274       return constant(true);
2275     }
2276     if (length == 1) {
2277       var key = props[0],
2278           value = source[key];
2279
2280       if (isStrictComparable(value)) {
2281         return function(object) {
2282           if (object == null) {
2283             return false;
2284           }
2285           return object[key] === value && (value !== undefined || (key in toObject(object)));
2286         };
2287       }
2288     }
2289     var values = Array(length),
2290         strictCompareFlags = Array(length);
2291
2292     while (length--) {
2293       value = source[props[length]];
2294       values[length] = value;
2295       strictCompareFlags[length] = isStrictComparable(value);
2296     }
2297     return function(object) {
2298       return object != null && baseIsMatch(toObject(object), props, values, strictCompareFlags);
2299     };
2300   }
2301
2302   function baseMatchesProperty(path, value) {
2303     var isArr = isArray(path),
2304         isCommon = isKey(path) && isStrictComparable(value),
2305         pathKey = (path + '');
2306
2307     path = toPath(path);
2308     return function(object) {
2309       if (object == null) {
2310         return false;
2311       }
2312       var key = pathKey;
2313       object = toObject(object);
2314       if ((isArr || !isCommon) && !(key in object)) {
2315         object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
2316         if (object == null) {
2317           return false;
2318         }
2319         key = last(path);
2320         object = toObject(object);
2321       }
2322       return object[key] === value
2323         ? (value !== undefined || (key in object))
2324         : baseIsEqual(value, object[key], null, true);
2325     };
2326   }
2327
2328   function baseMerge(object, source, customizer, stackA, stackB) {
2329     if (!isObject(object)) {
2330       return object;
2331     }
2332     var isSrcArr = isLength(source.length) && (isArray(source) || isTypedArray(source));
2333     if (!isSrcArr) {
2334       var props = keys(source);
2335       push.apply(props, getSymbols(source));
2336     }
2337     arrayEach(props || source, function(srcValue, key) {
2338       if (props) {
2339         key = srcValue;
2340         srcValue = source[key];
2341       }
2342       if (isObjectLike(srcValue)) {
2343         stackA || (stackA = []);
2344         stackB || (stackB = []);
2345         baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);
2346       }
2347       else {
2348         var value = object[key],
2349             result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
2350             isCommon = result === undefined;
2351
2352         if (isCommon) {
2353           result = srcValue;
2354         }
2355         if ((isSrcArr || result !== undefined) &&
2356             (isCommon || (result === result ? (result !== value) : (value === value)))) {
2357           object[key] = result;
2358         }
2359       }
2360     });
2361     return object;
2362   }
2363
2364   function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) {
2365     var length = stackA.length,
2366         srcValue = source[key];
2367
2368     while (length--) {
2369       if (stackA[length] == srcValue) {
2370         object[key] = stackB[length];
2371         return;
2372       }
2373     }
2374     var value = object[key],
2375         result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
2376         isCommon = result === undefined;
2377
2378     if (isCommon) {
2379       result = srcValue;
2380       if (isLength(srcValue.length) && (isArray(srcValue) || isTypedArray(srcValue))) {
2381         result = isArray(value)
2382           ? value
2383           : (getLength(value) ? arrayCopy(value) : []);
2384       }
2385       else if (isPlainObject(srcValue) || isArguments(srcValue)) {
2386         result = isArguments(value)
2387           ? toPlainObject(value)
2388           : (isPlainObject(value) ? value : {});
2389       }
2390       else {
2391         isCommon = false;
2392       }
2393     }
2394     stackA.push(srcValue);
2395     stackB.push(result);
2396
2397     if (isCommon) {
2398       object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB);
2399     } else if (result === result ? (result !== value) : (value === value)) {
2400       object[key] = result;
2401     }
2402   }
2403
2404   function baseProperty(key) {
2405     return function(object) {
2406       return object == null ? undefined : object[key];
2407     };
2408   }
2409
2410   function basePropertyDeep(path) {
2411     var pathKey = (path + '');
2412     path = toPath(path);
2413     return function(object) {
2414       return baseGet(object, path, pathKey);
2415     };
2416   }
2417
2418   function baseSlice(array, start, end) {
2419     var index = -1,
2420         length = array.length;
2421
2422     start = start == null ? 0 : (+start || 0);
2423     if (start < 0) {
2424       start = -start > length ? 0 : (length + start);
2425     }
2426     end = (end === undefined || end > length) ? length : (+end || 0);
2427     if (end < 0) {
2428       end += length;
2429     }
2430     length = start > end ? 0 : ((end - start) >>> 0);
2431     start >>>= 0;
2432
2433     var result = Array(length);
2434     while (++index < length) {
2435       result[index] = array[index + start];
2436     }
2437     return result;
2438   }
2439
2440   function baseSome(collection, predicate) {
2441     var result;
2442
2443     baseEach(collection, function(value, index, collection) {
2444       result = predicate(value, index, collection);
2445       return !result;
2446     });
2447     return !!result;
2448   }
2449
2450   function baseValues(object, props) {
2451     var index = -1,
2452         length = props.length,
2453         result = Array(length);
2454
2455     while (++index < length) {
2456       result[index] = object[props[index]];
2457     }
2458     return result;
2459   }
2460
2461   function binaryIndex(array, value, retHighest) {
2462     var low = 0,
2463         high = array ? array.length : low;
2464
2465     if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
2466       while (low < high) {
2467         var mid = (low + high) >>> 1,
2468             computed = array[mid];
2469
2470         if (retHighest ? (computed <= value) : (computed < value)) {
2471           low = mid + 1;
2472         } else {
2473           high = mid;
2474         }
2475       }
2476       return high;
2477     }
2478     return binaryIndexBy(array, value, identity, retHighest);
2479   }
2480
2481   function binaryIndexBy(array, value, iteratee, retHighest) {
2482     value = iteratee(value);
2483
2484     var low = 0,
2485         high = array ? array.length : 0,
2486         valIsNaN = value !== value,
2487         valIsUndef = value === undefined;
2488
2489     while (low < high) {
2490       var mid = floor((low + high) / 2),
2491           computed = iteratee(array[mid]),
2492           isReflexive = computed === computed;
2493
2494       if (valIsNaN) {
2495         var setLow = isReflexive || retHighest;
2496       } else if (valIsUndef) {
2497         setLow = isReflexive && (retHighest || computed !== undefined);
2498       } else {
2499         setLow = retHighest ? (computed <= value) : (computed < value);
2500       }
2501       if (setLow) {
2502         low = mid + 1;
2503       } else {
2504         high = mid;
2505       }
2506     }
2507     return nativeMin(high, MAX_ARRAY_INDEX);
2508   }
2509
2510   function bindCallback(func, thisArg, argCount) {
2511     if (typeof func != 'function') {
2512       return identity;
2513     }
2514     if (thisArg === undefined) {
2515       return func;
2516     }
2517     switch (argCount) {
2518       case 1: return function(value) {
2519         return func.call(thisArg, value);
2520       };
2521       case 3: return function(value, index, collection) {
2522         return func.call(thisArg, value, index, collection);
2523       };
2524       case 4: return function(accumulator, value, index, collection) {
2525         return func.call(thisArg, accumulator, value, index, collection);
2526       };
2527       case 5: return function(value, other, key, object, source) {
2528         return func.call(thisArg, value, other, key, object, source);
2529       };
2530     }
2531     return function() {
2532       return func.apply(thisArg, arguments);
2533     };
2534   }
2535
2536   function bufferClone(buffer) {
2537     return bufferSlice.call(buffer, 0);
2538   }
2539   if (!bufferSlice) {
2540     bufferClone = !(ArrayBuffer && Uint8Array) ? constant(null) : function(buffer) {
2541       var byteLength = buffer.byteLength,
2542           floatLength = Float64Array ? floor(byteLength / FLOAT64_BYTES_PER_ELEMENT) : 0,
2543           offset = floatLength * FLOAT64_BYTES_PER_ELEMENT,
2544           result = new ArrayBuffer(byteLength);
2545
2546       if (floatLength) {
2547         var view = new Float64Array(result, 0, floatLength);
2548         view.set(new Float64Array(buffer, 0, floatLength));
2549       }
2550       if (byteLength != offset) {
2551         view = new Uint8Array(result, offset);
2552         view.set(new Uint8Array(buffer, offset));
2553       }
2554       return result;
2555     };
2556   }
2557
2558   function createAssigner(assigner) {
2559     return restParam(function(object, sources) {
2560       var index = -1,
2561           length = object == null ? 0 : sources.length,
2562           customizer = length > 2 && sources[length - 2],
2563           guard = length > 2 && sources[2],
2564           thisArg = length > 1 && sources[length - 1];
2565
2566       if (typeof customizer == 'function') {
2567         customizer = bindCallback(customizer, thisArg, 5);
2568         length -= 2;
2569       } else {
2570         customizer = typeof thisArg == 'function' ? thisArg : null;
2571         length -= (customizer ? 1 : 0);
2572       }
2573       if (guard && isIterateeCall(sources[0], sources[1], guard)) {
2574         customizer = length < 3 ? null : customizer;
2575         length = 1;
2576       }
2577       while (++index < length) {
2578         var source = sources[index];
2579         if (source) {
2580           assigner(object, source, customizer);
2581         }
2582       }
2583       return object;
2584     });
2585   }
2586
2587   function createBaseEach(eachFunc, fromRight) {
2588     return function(collection, iteratee) {
2589       var length = collection ? getLength(collection) : 0;
2590       if (!isLength(length)) {
2591         return eachFunc(collection, iteratee);
2592       }
2593       var index = fromRight ? length : -1,
2594           iterable = toObject(collection);
2595
2596       while ((fromRight ? index-- : ++index < length)) {
2597         if (iteratee(iterable[index], index, iterable) === false) {
2598           break;
2599         }
2600       }
2601       return collection;
2602     };
2603   }
2604
2605   function createBaseFor(fromRight) {
2606     return function(object, iteratee, keysFunc) {
2607       var iterable = toObject(object),
2608           props = keysFunc(object),
2609           length = props.length,
2610           index = fromRight ? length : -1;
2611
2612       while ((fromRight ? index-- : ++index < length)) {
2613         var key = props[index];
2614         if (iteratee(iterable[key], key, iterable) === false) {
2615           break;
2616         }
2617       }
2618       return object;
2619     };
2620   }
2621
2622   function createFindIndex(fromRight) {
2623     return function(array, predicate, thisArg) {
2624       if (!(array && array.length)) {
2625         return -1;
2626       }
2627       predicate = getCallback(predicate, thisArg, 3);
2628       return baseFindIndex(array, predicate, fromRight);
2629     };
2630   }
2631
2632   function createForEach(arrayFunc, eachFunc) {
2633     return function(collection, iteratee, thisArg) {
2634       return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))
2635         ? arrayFunc(collection, iteratee)
2636         : eachFunc(collection, bindCallback(iteratee, thisArg, 3));
2637     };
2638   }
2639
2640   function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {
2641     var index = -1,
2642         arrLength = array.length,
2643         othLength = other.length,
2644         result = true;
2645
2646     if (arrLength != othLength && !(isLoose && othLength > arrLength)) {
2647       return false;
2648     }
2649     while (result && ++index < arrLength) {
2650       var arrValue = array[index],
2651           othValue = other[index];
2652
2653       result = undefined;
2654       if (customizer) {
2655         result = isLoose
2656           ? customizer(othValue, arrValue, index)
2657           : customizer(arrValue, othValue, index);
2658       }
2659       if (result === undefined) {
2660         if (isLoose) {
2661           var othIndex = othLength;
2662           while (othIndex--) {
2663             othValue = other[othIndex];
2664             result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
2665             if (result) {
2666               break;
2667             }
2668           }
2669         } else {
2670           result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
2671         }
2672       }
2673     }
2674     return !!result;
2675   }
2676
2677   function equalByTag(object, other, tag) {
2678     switch (tag) {
2679       case boolTag:
2680       case dateTag:
2681         return +object == +other;
2682
2683       case errorTag:
2684         return object.name == other.name && object.message == other.message;
2685
2686       case numberTag:
2687         return (object != +object)
2688           ? other != +other
2689           : (object == 0 ? ((1 / object) == (1 / other)) : object == +other);
2690
2691       case regexpTag:
2692       case stringTag:
2693         return object == (other + '');
2694     }
2695     return false;
2696   }
2697
2698   function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
2699     var objProps = keys(object),
2700         objLength = objProps.length,
2701         othProps = keys(other),
2702         othLength = othProps.length;
2703
2704     if (objLength != othLength && !isLoose) {
2705       return false;
2706     }
2707     var skipCtor = isLoose,
2708         index = -1;
2709
2710     while (++index < objLength) {
2711       var key = objProps[index],
2712           result = isLoose ? key in other : hasOwnProperty.call(other, key);
2713
2714       if (result) {
2715         var objValue = object[key],
2716             othValue = other[key];
2717
2718         result = undefined;
2719         if (customizer) {
2720           result = isLoose
2721             ? customizer(othValue, objValue, key)
2722             : customizer(objValue, othValue, key);
2723         }
2724         if (result === undefined) {
2725           result = (objValue && objValue === othValue) || equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB);
2726         }
2727       }
2728       if (!result) {
2729         return false;
2730       }
2731       skipCtor || (skipCtor = key == 'constructor');
2732     }
2733     if (!skipCtor) {
2734       var objCtor = object.constructor,
2735           othCtor = other.constructor;
2736
2737       if (objCtor != othCtor &&
2738           ('constructor' in object && 'constructor' in other) &&
2739           !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
2740             typeof othCtor == 'function' && othCtor instanceof othCtor)) {
2741         return false;
2742       }
2743     }
2744     return true;
2745   }
2746
2747   function getCallback(func, thisArg, argCount) {
2748     var result = lodash.callback || callback;
2749     result = result === callback ? baseCallback : result;
2750     return argCount ? result(func, thisArg, argCount) : result;
2751   }
2752
2753   function getIndexOf(collection, target, fromIndex) {
2754     var result = lodash.indexOf || indexOf;
2755     result = result === indexOf ? baseIndexOf : result;
2756     return collection ? result(collection, target, fromIndex) : result;
2757   }
2758
2759   var getLength = baseProperty('length');
2760
2761   var getSymbols = !getOwnPropertySymbols ? constant([]) : function(object) {
2762     return getOwnPropertySymbols(toObject(object));
2763   };
2764
2765   function initCloneArray(array) {
2766     var length = array.length,
2767         result = new array.constructor(length);
2768
2769     if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
2770       result.index = array.index;
2771       result.input = array.input;
2772     }
2773     return result;
2774   }
2775
2776   function initCloneObject(object) {
2777     var Ctor = object.constructor;
2778     if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) {
2779       Ctor = Object;
2780     }
2781     return new Ctor;
2782   }
2783
2784   function initCloneByTag(object, tag, isDeep) {
2785     var Ctor = object.constructor;
2786     switch (tag) {
2787       case arrayBufferTag:
2788         return bufferClone(object);
2789
2790       case boolTag:
2791       case dateTag:
2792         return new Ctor(+object);
2793
2794       case float32Tag: case float64Tag:
2795       case int8Tag: case int16Tag: case int32Tag:
2796       case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
2797         var buffer = object.buffer;
2798         return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);
2799
2800       case numberTag:
2801       case stringTag:
2802         return new Ctor(object);
2803
2804       case regexpTag:
2805         var result = new Ctor(object.source, reFlags.exec(object));
2806         result.lastIndex = object.lastIndex;
2807     }
2808     return result;
2809   }
2810
2811   function isIndex(value, length) {
2812     value = +value;
2813     length = length == null ? MAX_SAFE_INTEGER : length;
2814     return value > -1 && value % 1 == 0 && value < length;
2815   }
2816
2817   function isIterateeCall(value, index, object) {
2818     if (!isObject(object)) {
2819       return false;
2820     }
2821     var type = typeof index;
2822     if (type == 'number') {
2823       var length = getLength(object),
2824           prereq = isLength(length) && isIndex(index, length);
2825     } else {
2826       prereq = type == 'string' && index in object;
2827     }
2828     if (prereq) {
2829       var other = object[index];
2830       return value === value ? (value === other) : (other !== other);
2831     }
2832     return false;
2833   }
2834
2835   function isKey(value, object) {
2836     var type = typeof value;
2837     if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {
2838       return true;
2839     }
2840     if (isArray(value)) {
2841       return false;
2842     }
2843     var result = !reIsDeepProp.test(value);
2844     return result || (object != null && value in toObject(object));
2845   }
2846
2847   function isLength(value) {
2848     return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
2849   }
2850
2851   function isStrictComparable(value) {
2852     return value === value && (value === 0 ? ((1 / value) > 0) : !isObject(value));
2853   }
2854
2855   function shimIsPlainObject(value) {
2856     var Ctor,
2857         support = lodash.support;
2858
2859     if (!(isObjectLike(value) && objToString.call(value) == objectTag) ||
2860         (!hasOwnProperty.call(value, 'constructor') &&
2861           (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
2862       return false;
2863     }
2864     var result;
2865     baseForIn(value, function(subValue, key) {
2866       result = key;
2867     });
2868     return result === undefined || hasOwnProperty.call(value, result);
2869   }
2870
2871   function shimKeys(object) {
2872     var props = keysIn(object),
2873         propsLength = props.length,
2874         length = propsLength && object.length,
2875         support = lodash.support;
2876
2877     var allowIndexes = length && isLength(length) &&
2878       (isArray(object) || (support.nonEnumArgs && isArguments(object)));
2879
2880     var index = -1,
2881         result = [];
2882
2883     while (++index < propsLength) {
2884       var key = props[index];
2885       if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
2886         result.push(key);
2887       }
2888     }
2889     return result;
2890   }
2891
2892   function toObject(value) {
2893     return isObject(value) ? value : Object(value);
2894   }
2895
2896   function toPath(value) {
2897     if (isArray(value)) {
2898       return value;
2899     }
2900     var result = [];
2901     baseToString(value).replace(rePropName, function(match, number, quote, string) {
2902       result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
2903     });
2904     return result;
2905   }
2906
2907   var findLastIndex = createFindIndex(true);
2908
2909   function indexOf(array, value, fromIndex) {
2910     var length = array ? array.length : 0;
2911     if (!length) {
2912       return -1;
2913     }
2914     if (typeof fromIndex == 'number') {
2915       fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;
2916     } else if (fromIndex) {
2917       var index = binaryIndex(array, value),
2918           other = array[index];
2919
2920       if (value === value ? (value === other) : (other !== other)) {
2921         return index;
2922       }
2923       return -1;
2924     }
2925     return baseIndexOf(array, value, fromIndex || 0);
2926   }
2927
2928   function last(array) {
2929     var length = array ? array.length : 0;
2930     return length ? array[length - 1] : undefined;
2931   }
2932
2933   function slice(array, start, end) {
2934     var length = array ? array.length : 0;
2935     if (!length) {
2936       return [];
2937     }
2938     if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
2939       start = 0;
2940       end = length;
2941     }
2942     return baseSlice(array, start, end);
2943   }
2944
2945   function unzip(array) {
2946     var index = -1,
2947         length = (array && array.length && arrayMax(arrayMap(array, getLength))) >>> 0,
2948         result = Array(length);
2949
2950     while (++index < length) {
2951       result[index] = arrayMap(array, baseProperty(index));
2952     }
2953     return result;
2954   }
2955
2956   var zip = restParam(unzip);
2957
2958   var forEach = createForEach(arrayEach, baseEach);
2959
2960   function includes(collection, target, fromIndex, guard) {
2961     var length = collection ? getLength(collection) : 0;
2962     if (!isLength(length)) {
2963       collection = values(collection);
2964       length = collection.length;
2965     }
2966     if (!length) {
2967       return false;
2968     }
2969     if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) {
2970       fromIndex = 0;
2971     } else {
2972       fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);
2973     }
2974     return (typeof collection == 'string' || !isArray(collection) && isString(collection))
2975       ? (fromIndex < length && collection.indexOf(target, fromIndex) > -1)
2976       : (getIndexOf(collection, target, fromIndex) > -1);
2977   }
2978
2979   function reject(collection, predicate, thisArg) {
2980     var func = isArray(collection) ? arrayFilter : baseFilter;
2981     predicate = getCallback(predicate, thisArg, 3);
2982     return func(collection, function(value, index, collection) {
2983       return !predicate(value, index, collection);
2984     });
2985   }
2986
2987   function some(collection, predicate, thisArg) {
2988     var func = isArray(collection) ? arraySome : baseSome;
2989     if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
2990       predicate = null;
2991     }
2992     if (typeof predicate != 'function' || thisArg !== undefined) {
2993       predicate = getCallback(predicate, thisArg, 3);
2994     }
2995     return func(collection, predicate);
2996   }
2997
2998   function restParam(func, start) {
2999     if (typeof func != 'function') {
3000       throw new TypeError(FUNC_ERROR_TEXT);
3001     }
3002     start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
3003     return function() {
3004       var args = arguments,
3005           index = -1,
3006           length = nativeMax(args.length - start, 0),
3007           rest = Array(length);
3008
3009       while (++index < length) {
3010         rest[index] = args[start + index];
3011       }
3012       switch (start) {
3013         case 0: return func.call(this, rest);
3014         case 1: return func.call(this, args[0], rest);
3015         case 2: return func.call(this, args[0], args[1], rest);
3016       }
3017       var otherArgs = Array(start + 1);
3018       index = -1;
3019       while (++index < start) {
3020         otherArgs[index] = args[index];
3021       }
3022       otherArgs[start] = rest;
3023       return func.apply(this, otherArgs);
3024     };
3025   }
3026
3027   function clone(value, isDeep, customizer, thisArg) {
3028     if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) {
3029       isDeep = false;
3030     }
3031     else if (typeof isDeep == 'function') {
3032       thisArg = customizer;
3033       customizer = isDeep;
3034       isDeep = false;
3035     }
3036     customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 1);
3037     return baseClone(value, isDeep, customizer);
3038   }
3039
3040   function isArguments(value) {
3041     var length = isObjectLike(value) ? value.length : undefined;
3042     return isLength(length) && objToString.call(value) == argsTag;
3043   }
3044
3045   var isArray = nativeIsArray || function(value) {
3046     return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
3047   };
3048
3049   function isEmpty(value) {
3050     if (value == null) {
3051       return true;
3052     }
3053     var length = getLength(value);
3054     if (isLength(length) && (isArray(value) || isString(value) || isArguments(value) ||
3055         (isObjectLike(value) && isFunction(value.splice)))) {
3056       return !length;
3057     }
3058     return !keys(value).length;
3059   }
3060
3061   var isFunction = !(baseIsFunction(/x/) || (Uint8Array && !baseIsFunction(Uint8Array))) ? baseIsFunction : function(value) {
3062     return objToString.call(value) == funcTag;
3063   };
3064
3065   function isObject(value) {
3066     var type = typeof value;
3067     return type == 'function' || (!!value && type == 'object');
3068   }
3069
3070   function isNative(value) {
3071     if (value == null) {
3072       return false;
3073     }
3074     if (objToString.call(value) == funcTag) {
3075       return reIsNative.test(fnToString.call(value));
3076     }
3077     return isObjectLike(value) && reIsHostCtor.test(value);
3078   }
3079
3080   function isNumber(value) {
3081     return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag);
3082   }
3083
3084   var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
3085     if (!(value && objToString.call(value) == objectTag)) {
3086       return false;
3087     }
3088     var valueOf = value.valueOf,
3089         objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
3090
3091     return objProto
3092       ? (value == objProto || getPrototypeOf(value) == objProto)
3093       : shimIsPlainObject(value);
3094   };
3095
3096   function isString(value) {
3097     return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
3098   }
3099
3100   function isTypedArray(value) {
3101     return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
3102   }
3103
3104   function toPlainObject(value) {
3105     return baseCopy(value, keysIn(value));
3106   }
3107
3108   var assign = createAssigner(function(object, source, customizer) {
3109     return customizer
3110       ? assignWith(object, source, customizer)
3111       : baseAssign(object, source);
3112   });
3113
3114   function has(object, path) {
3115     if (object == null) {
3116       return false;
3117     }
3118     var result = hasOwnProperty.call(object, path);
3119     if (!result && !isKey(path)) {
3120       path = toPath(path);
3121       object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
3122       path = last(path);
3123       result = object != null && hasOwnProperty.call(object, path);
3124     }
3125     return result;
3126   }
3127
3128   var keys = !nativeKeys ? shimKeys : function(object) {
3129     if (object) {
3130       var Ctor = object.constructor,
3131           length = object.length;
3132     }
3133     if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
3134         (typeof object != 'function' && isLength(length))) {
3135       return shimKeys(object);
3136     }
3137     return isObject(object) ? nativeKeys(object) : [];
3138   };
3139
3140   function keysIn(object) {
3141     if (object == null) {
3142       return [];
3143     }
3144     if (!isObject(object)) {
3145       object = Object(object);
3146     }
3147     var length = object.length;
3148     length = (length && isLength(length) &&
3149       (isArray(object) || (support.nonEnumArgs && isArguments(object))) && length) || 0;
3150
3151     var Ctor = object.constructor,
3152         index = -1,
3153         isProto = typeof Ctor == 'function' && Ctor.prototype === object,
3154         result = Array(length),
3155         skipIndexes = length > 0;
3156
3157     while (++index < length) {
3158       result[index] = (index + '');
3159     }
3160     for (var key in object) {
3161       if (!(skipIndexes && isIndex(key, length)) &&
3162           !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
3163         result.push(key);
3164       }
3165     }
3166     return result;
3167   }
3168
3169   var merge = createAssigner(baseMerge);
3170
3171   function values(object) {
3172     return baseValues(object, keys(object));
3173   }
3174
3175   function escapeRegExp(string) {
3176     string = baseToString(string);
3177     return (string && reHasRegExpChars.test(string))
3178       ? string.replace(reRegExpChars, '\\$&')
3179       : string;
3180   }
3181
3182   function callback(func, thisArg, guard) {
3183     if (guard && isIterateeCall(func, thisArg, guard)) {
3184       thisArg = null;
3185     }
3186     return baseCallback(func, thisArg);
3187   }
3188
3189   function constant(value) {
3190     return function() {
3191       return value;
3192     };
3193   }
3194
3195   function identity(value) {
3196     return value;
3197   }
3198
3199   function property(path) {
3200     return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
3201   }
3202   lodash.assign = assign;
3203   lodash.callback = callback;
3204   lodash.constant = constant;
3205   lodash.forEach = forEach;
3206   lodash.keys = keys;
3207   lodash.keysIn = keysIn;
3208   lodash.merge = merge;
3209   lodash.property = property;
3210   lodash.reject = reject;
3211   lodash.restParam = restParam;
3212   lodash.slice = slice;
3213   lodash.toPlainObject = toPlainObject;
3214   lodash.unzip = unzip;
3215   lodash.values = values;
3216   lodash.zip = zip;
3217
3218   lodash.each = forEach;
3219   lodash.extend = assign;
3220   lodash.iteratee = callback;
3221   lodash.clone = clone;
3222   lodash.escapeRegExp = escapeRegExp;
3223   lodash.findLastIndex = findLastIndex;
3224   lodash.has = has;
3225   lodash.identity = identity;
3226   lodash.includes = includes;
3227   lodash.indexOf = indexOf;
3228   lodash.isArguments = isArguments;
3229   lodash.isArray = isArray;
3230   lodash.isEmpty = isEmpty;
3231   lodash.isFunction = isFunction;
3232   lodash.isNative = isNative;
3233   lodash.isNumber = isNumber;
3234   lodash.isObject = isObject;
3235   lodash.isPlainObject = isPlainObject;
3236   lodash.isString = isString;
3237   lodash.isTypedArray = isTypedArray;
3238   lodash.last = last;
3239   lodash.some = some;
3240
3241   lodash.any = some;
3242   lodash.contains = includes;
3243   lodash.include = includes;
3244
3245   lodash.VERSION = VERSION;
3246   if (freeExports && freeModule) {
3247     if (moduleExports) {
3248       (freeModule.exports = lodash)._ = lodash;
3249     }
3250     else {
3251       freeExports._ = lodash;
3252     }
3253   }
3254   else {
3255     root._ = lodash;
3256   }
3257 }.call(this));
3258
3259 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3260 },{}],"/node_modules/jshint/src/jshint.js":[function(_dereq_,module,exports){
3261
3262 var _            = _dereq_("../lodash");
3263 var events       = _dereq_("events");
3264 var vars         = _dereq_("./vars.js");
3265 var messages     = _dereq_("./messages.js");
3266 var Lexer        = _dereq_("./lex.js").Lexer;
3267 var reg          = _dereq_("./reg.js");
3268 var state        = _dereq_("./state.js").state;
3269 var style        = _dereq_("./style.js");
3270 var options      = _dereq_("./options.js");
3271 var scopeManager = _dereq_("./scope-manager.js");
3272
3273 var JSHINT = (function() {
3274   "use strict";
3275
3276   var api, // Extension API
3277     bang = {
3278       "<"  : true,
3279       "<=" : true,
3280       "==" : true,
3281       "===": true,
3282       "!==": true,
3283       "!=" : true,
3284       ">"  : true,
3285       ">=" : true,
3286       "+"  : true,
3287       "-"  : true,
3288       "*"  : true,
3289       "/"  : true,
3290       "%"  : true
3291     },
3292
3293     declared, // Globals that were declared using /*global ... */ syntax.
3294
3295     functionicity = [
3296       "closure", "exception", "global", "label",
3297       "outer", "unused", "var"
3298     ],
3299
3300     functions, // All of the functions
3301
3302     inblock,
3303     indent,
3304     lookahead,
3305     lex,
3306     member,
3307     membersOnly,
3308     predefined,    // Global variables defined by option
3309
3310     stack,
3311     urls,
3312
3313     extraModules = [],
3314     emitter = new events.EventEmitter();
3315
3316   function checkOption(name, t) {
3317     name = name.trim();
3318
3319     if (/^[+-]W\d{3}$/g.test(name)) {
3320       return true;
3321     }
3322
3323     if (options.validNames.indexOf(name) === -1) {
3324       if (t.type !== "jslint" && !_.has(options.removed, name)) {
3325         error("E001", t, name);
3326         return false;
3327       }
3328     }
3329
3330     return true;
3331   }
3332
3333   function isString(obj) {
3334     return Object.prototype.toString.call(obj) === "[object String]";
3335   }
3336
3337   function isIdentifier(tkn, value) {
3338     if (!tkn)
3339       return false;
3340
3341     if (!tkn.identifier || tkn.value !== value)
3342       return false;
3343
3344     return true;
3345   }
3346
3347   function isReserved(token) {
3348     if (!token.reserved) {
3349       return false;
3350     }
3351     var meta = token.meta;
3352
3353     if (meta && meta.isFutureReservedWord && state.inES5()) {
3354       if (!meta.es5) {
3355         return false;
3356       }
3357       if (meta.strictOnly) {
3358         if (!state.option.strict && !state.isStrict()) {
3359           return false;
3360         }
3361       }
3362
3363       if (token.isProperty) {
3364         return false;
3365       }
3366     }
3367
3368     return true;
3369   }
3370
3371   function supplant(str, data) {
3372     return str.replace(/\{([^{}]*)\}/g, function(a, b) {
3373       var r = data[b];
3374       return typeof r === "string" || typeof r === "number" ? r : a;
3375     });
3376   }
3377
3378   function combine(dest, src) {
3379     Object.keys(src).forEach(function(name) {
3380       if (_.has(JSHINT.blacklist, name)) return;
3381       dest[name] = src[name];
3382     });
3383   }
3384
3385   function processenforceall() {
3386     if (state.option.enforceall) {
3387       for (var enforceopt in options.bool.enforcing) {
3388         if (state.option[enforceopt] === undefined &&
3389             !options.noenforceall[enforceopt]) {
3390           state.option[enforceopt] = true;
3391         }
3392       }
3393       for (var relaxopt in options.bool.relaxing) {
3394         if (state.option[relaxopt] === undefined) {
3395           state.option[relaxopt] = false;
3396         }
3397       }
3398     }
3399   }
3400
3401   function assume() {
3402     processenforceall();
3403     if (!state.option.esversion && !state.option.moz) {
3404       if (state.option.es3) {
3405         state.option.esversion = 3;
3406       } else if (state.option.esnext) {
3407         state.option.esversion = 6;
3408       } else {
3409         state.option.esversion = 5;
3410       }
3411     }
3412
3413     if (state.inES5()) {
3414       combine(predefined, vars.ecmaIdentifiers[5]);
3415     }
3416
3417     if (state.inES6()) {
3418       combine(predefined, vars.ecmaIdentifiers[6]);
3419     }
3420
3421     if (state.option.module) {
3422       if (state.option.strict === true) {
3423         state.option.strict = "global";
3424       }
3425       if (!state.inES6()) {
3426         warning("W134", state.tokens.next, "module", 6);
3427       }
3428     }
3429
3430     if (state.option.couch) {
3431       combine(predefined, vars.couch);
3432     }
3433
3434     if (state.option.qunit) {
3435       combine(predefined, vars.qunit);
3436     }
3437
3438     if (state.option.rhino) {
3439       combine(predefined, vars.rhino);
3440     }
3441
3442     if (state.option.shelljs) {
3443       combine(predefined, vars.shelljs);
3444       combine(predefined, vars.node);
3445     }
3446     if (state.option.typed) {
3447       combine(predefined, vars.typed);
3448     }
3449
3450     if (state.option.phantom) {
3451       combine(predefined, vars.phantom);
3452       if (state.option.strict === true) {
3453         state.option.strict = "global";
3454       }
3455     }
3456
3457     if (state.option.prototypejs) {
3458       combine(predefined, vars.prototypejs);
3459     }
3460
3461     if (state.option.node) {
3462       combine(predefined, vars.node);
3463       combine(predefined, vars.typed);
3464       if (state.option.strict === true) {
3465         state.option.strict = "global";
3466       }
3467     }
3468
3469     if (state.option.devel) {
3470       combine(predefined, vars.devel);
3471     }
3472
3473     if (state.option.dojo) {
3474       combine(predefined, vars.dojo);
3475     }
3476
3477     if (state.option.browser) {
3478       combine(predefined, vars.browser);
3479       combine(predefined, vars.typed);
3480     }
3481
3482     if (state.option.browserify) {
3483       combine(predefined, vars.browser);
3484       combine(predefined, vars.typed);
3485       combine(predefined, vars.browserify);
3486       if (state.option.strict === true) {
3487         state.option.strict = "global";
3488       }
3489     }
3490
3491     if (state.option.nonstandard) {
3492       combine(predefined, vars.nonstandard);
3493     }
3494
3495     if (state.option.jasmine) {
3496       combine(predefined, vars.jasmine);
3497     }
3498
3499     if (state.option.jquery) {
3500       combine(predefined, vars.jquery);
3501     }
3502
3503     if (state.option.mootools) {
3504       combine(predefined, vars.mootools);
3505     }
3506
3507     if (state.option.worker) {
3508       combine(predefined, vars.worker);
3509     }
3510
3511     if (state.option.wsh) {
3512       combine(predefined, vars.wsh);
3513     }
3514
3515     if (state.option.globalstrict && state.option.strict !== false) {
3516       state.option.strict = "global";
3517     }
3518
3519     if (state.option.yui) {
3520       combine(predefined, vars.yui);
3521     }
3522
3523     if (state.option.mocha) {
3524       combine(predefined, vars.mocha);
3525     }
3526   }
3527   function quit(code, line, chr) {
3528     var percentage = Math.floor((line / state.lines.length) * 100);
3529     var message = messages.errors[code].desc;
3530
3531     throw {
3532       name: "JSHintError",
3533       line: line,
3534       character: chr,
3535       message: message + " (" + percentage + "% scanned).",
3536       raw: message,
3537       code: code
3538     };
3539   }
3540
3541   function removeIgnoredMessages() {
3542     var ignored = state.ignoredLines;
3543
3544     if (_.isEmpty(ignored)) return;
3545     JSHINT.errors = _.reject(JSHINT.errors, function(err) { return ignored[err.line] });
3546   }
3547
3548   function warning(code, t, a, b, c, d) {
3549     var ch, l, w, msg;
3550
3551     if (/^W\d{3}$/.test(code)) {
3552       if (state.ignored[code])
3553         return;
3554
3555       msg = messages.warnings[code];
3556     } else if (/E\d{3}/.test(code)) {
3557       msg = messages.errors[code];
3558     } else if (/I\d{3}/.test(code)) {
3559       msg = messages.info[code];
3560     }
3561
3562     t = t || state.tokens.next || {};
3563     if (t.id === "(end)") {  // `~
3564       t = state.tokens.curr;
3565     }
3566
3567     l = t.line || 0;
3568     ch = t.from || 0;
3569
3570     w = {
3571       id: "(error)",
3572       raw: msg.desc,
3573       code: msg.code,
3574       evidence: state.lines[l - 1] || "",
3575       line: l,
3576       character: ch,
3577       scope: JSHINT.scope,
3578       a: a,
3579       b: b,
3580       c: c,
3581       d: d
3582     };
3583
3584     w.reason = supplant(msg.desc, w);
3585     JSHINT.errors.push(w);
3586
3587     removeIgnoredMessages();
3588
3589     if (JSHINT.errors.length >= state.option.maxerr)
3590       quit("E043", l, ch);
3591
3592     return w;
3593   }
3594
3595   function warningAt(m, l, ch, a, b, c, d) {
3596     return warning(m, {
3597       line: l,
3598       from: ch
3599     }, a, b, c, d);
3600   }
3601
3602   function error(m, t, a, b, c, d) {
3603     warning(m, t, a, b, c, d);
3604   }
3605
3606   function errorAt(m, l, ch, a, b, c, d) {
3607     return error(m, {
3608       line: l,
3609       from: ch
3610     }, a, b, c, d);
3611   }
3612   function addInternalSrc(elem, src) {
3613     var i;
3614     i = {
3615       id: "(internal)",
3616       elem: elem,
3617       value: src
3618     };
3619     JSHINT.internals.push(i);
3620     return i;
3621   }
3622
3623   function doOption() {
3624     var nt = state.tokens.next;
3625     var body = nt.body.match(/(-\s+)?[^\s,:]+(?:\s*:\s*(-\s+)?[^\s,]+)?/g) || [];
3626
3627     var predef = {};
3628     if (nt.type === "globals") {
3629       body.forEach(function(g, idx) {
3630         g = g.split(":");
3631         var key = (g[0] || "").trim();
3632         var val = (g[1] || "").trim();
3633
3634         if (key === "-" || !key.length) {
3635           if (idx > 0 && idx === body.length - 1) {
3636             return;
3637           }
3638           error("E002", nt);
3639           return;
3640         }
3641
3642         if (key.charAt(0) === "-") {
3643           key = key.slice(1);
3644           val = false;
3645
3646           JSHINT.blacklist[key] = key;
3647           delete predefined[key];
3648         } else {
3649           predef[key] = (val === "true");
3650         }
3651       });
3652
3653       combine(predefined, predef);
3654
3655       for (var key in predef) {
3656         if (_.has(predef, key)) {
3657           declared[key] = nt;
3658         }
3659       }
3660     }
3661
3662     if (nt.type === "exported") {
3663       body.forEach(function(e, idx) {
3664         if (!e.length) {
3665           if (idx > 0 && idx === body.length - 1) {
3666             return;
3667           }
3668           error("E002", nt);
3669           return;
3670         }
3671
3672         state.funct["(scope)"].addExported(e);
3673       });
3674     }
3675
3676     if (nt.type === "members") {
3677       membersOnly = membersOnly || {};
3678
3679       body.forEach(function(m) {
3680         var ch1 = m.charAt(0);
3681         var ch2 = m.charAt(m.length - 1);
3682
3683         if (ch1 === ch2 && (ch1 === "\"" || ch1 === "'")) {
3684           m = m
3685             .substr(1, m.length - 2)
3686             .replace("\\\"", "\"");
3687         }
3688
3689         membersOnly[m] = false;
3690       });
3691     }
3692
3693     var numvals = [
3694       "maxstatements",
3695       "maxparams",
3696       "maxdepth",
3697       "maxcomplexity",
3698       "maxerr",
3699       "maxlen",
3700       "indent"
3701     ];
3702
3703     if (nt.type === "jshint" || nt.type === "jslint") {
3704       body.forEach(function(g) {
3705         g = g.split(":");
3706         var key = (g[0] || "").trim();
3707         var val = (g[1] || "").trim();
3708
3709         if (!checkOption(key, nt)) {
3710           return;
3711         }
3712
3713         if (numvals.indexOf(key) >= 0) {
3714           if (val !== "false") {
3715             val = +val;
3716
3717             if (typeof val !== "number" || !isFinite(val) || val <= 0 || Math.floor(val) !== val) {
3718               error("E032", nt, g[1].trim());
3719               return;
3720             }
3721
3722             state.option[key] = val;
3723           } else {
3724             state.option[key] = key === "indent" ? 4 : false;
3725           }
3726
3727           return;
3728         }
3729
3730         if (key === "validthis") {
3731
3732           if (state.funct["(global)"])
3733             return void error("E009");
3734
3735           if (val !== "true" && val !== "false")
3736             return void error("E002", nt);
3737
3738           state.option.validthis = (val === "true");
3739           return;
3740         }
3741
3742         if (key === "quotmark") {
3743           switch (val) {
3744           case "true":
3745           case "false":
3746             state.option.quotmark = (val === "true");
3747             break;
3748           case "double":
3749           case "single":
3750             state.option.quotmark = val;
3751             break;
3752           default:
3753             error("E002", nt);
3754           }
3755           return;
3756         }
3757
3758         if (key === "shadow") {
3759           switch (val) {
3760           case "true":
3761             state.option.shadow = true;
3762             break;
3763           case "outer":
3764             state.option.shadow = "outer";
3765             break;
3766           case "false":
3767           case "inner":
3768             state.option.shadow = "inner";
3769             break;
3770           default:
3771             error("E002", nt);
3772           }
3773           return;
3774         }
3775
3776         if (key === "unused") {
3777           switch (val) {
3778           case "true":
3779             state.option.unused = true;
3780             break;
3781           case "false":
3782             state.option.unused = false;
3783             break;
3784           case "vars":
3785           case "strict":
3786             state.option.unused = val;
3787             break;
3788           default:
3789             error("E002", nt);
3790           }
3791           return;
3792         }
3793
3794         if (key === "latedef") {
3795           switch (val) {
3796           case "true":
3797             state.option.latedef = true;
3798             break;
3799           case "false":
3800             state.option.latedef = false;
3801             break;
3802           case "nofunc":
3803             state.option.latedef = "nofunc";
3804             break;
3805           default:
3806             error("E002", nt);
3807           }
3808           return;
3809         }
3810
3811         if (key === "ignore") {
3812           switch (val) {
3813           case "line":
3814             state.ignoredLines[nt.line] = true;
3815             removeIgnoredMessages();
3816             break;
3817           default:
3818             error("E002", nt);
3819           }
3820           return;
3821         }
3822
3823         if (key === "strict") {
3824           switch (val) {
3825           case "true":
3826             state.option.strict = true;
3827             break;
3828           case "false":
3829             state.option.strict = false;
3830             break;
3831           case "func":
3832           case "global":
3833           case "implied":
3834             state.option.strict = val;
3835             break;
3836           default:
3837             error("E002", nt);
3838           }
3839           return;
3840         }
3841
3842         if (key === "module") {
3843           if (!hasParsedCode(state.funct)) {
3844             error("E055", state.tokens.next, "module");
3845           }
3846         }
3847         var esversions = {
3848           es3   : 3,
3849           es5   : 5,
3850           esnext: 6
3851         };
3852         if (_.has(esversions, key)) {
3853           switch (val) {
3854           case "true":
3855             state.option.moz = false;
3856             state.option.esversion = esversions[key];
3857             break;
3858           case "false":
3859             if (!state.option.moz) {
3860               state.option.esversion = 5;
3861             }
3862             break;
3863           default:
3864             error("E002", nt);
3865           }
3866           return;
3867         }
3868
3869         if (key === "esversion") {
3870           switch (val) {
3871           case "5":
3872             if (state.inES5(true)) {
3873               warning("I003");
3874             }
3875           case "3":
3876           case "6":
3877             state.option.moz = false;
3878             state.option.esversion = +val;
3879             break;
3880           case "2015":
3881             state.option.moz = false;
3882             state.option.esversion = 6;
3883             break;
3884           default:
3885             error("E002", nt);
3886           }
3887           if (!hasParsedCode(state.funct)) {
3888             error("E055", state.tokens.next, "esversion");
3889           }
3890           return;
3891         }
3892
3893         var match = /^([+-])(W\d{3})$/g.exec(key);
3894         if (match) {
3895           state.ignored[match[2]] = (match[1] === "-");
3896           return;
3897         }
3898
3899         var tn;
3900         if (val === "true" || val === "false") {
3901           if (nt.type === "jslint") {
3902             tn = options.renamed[key] || key;
3903             state.option[tn] = (val === "true");
3904
3905             if (options.inverted[tn] !== undefined) {
3906               state.option[tn] = !state.option[tn];
3907             }
3908           } else {
3909             state.option[key] = (val === "true");
3910           }
3911
3912           if (key === "newcap") {
3913             state.option["(explicitNewcap)"] = true;
3914           }
3915           return;
3916         }
3917
3918         error("E002", nt);
3919       });
3920
3921       assume();
3922     }
3923   }
3924
3925   function peek(p) {
3926     var i = p || 0, j = lookahead.length, t;
3927
3928     if (i < j) {
3929       return lookahead[i];
3930     }
3931
3932     while (j <= i) {
3933       t = lookahead[j];
3934       if (!t) {
3935         t = lookahead[j] = lex.token();
3936       }
3937       j += 1;
3938     }
3939     if (!t && state.tokens.next.id === "(end)") {
3940       return state.tokens.next;
3941     }
3942
3943     return t;
3944   }
3945
3946   function peekIgnoreEOL() {
3947     var i = 0;
3948     var t;
3949     do {
3950       t = peek(i++);
3951     } while (t.id === "(endline)");
3952     return t;
3953   }
3954
3955   function advance(id, t) {
3956
3957     switch (state.tokens.curr.id) {
3958     case "(number)":
3959       if (state.tokens.next.id === ".") {
3960         warning("W005", state.tokens.curr);
3961       }
3962       break;
3963     case "-":
3964       if (state.tokens.next.id === "-" || state.tokens.next.id === "--") {
3965         warning("W006");
3966       }
3967       break;
3968     case "+":
3969       if (state.tokens.next.id === "+" || state.tokens.next.id === "++") {
3970         warning("W007");
3971       }
3972       break;
3973     }
3974
3975     if (id && state.tokens.next.id !== id) {
3976       if (t) {
3977         if (state.tokens.next.id === "(end)") {
3978           error("E019", t, t.id);
3979         } else {
3980           error("E020", state.tokens.next, id, t.id, t.line, state.tokens.next.value);
3981         }
3982       } else if (state.tokens.next.type !== "(identifier)" || state.tokens.next.value !== id) {
3983         warning("W116", state.tokens.next, id, state.tokens.next.value);
3984       }
3985     }
3986
3987     state.tokens.prev = state.tokens.curr;
3988     state.tokens.curr = state.tokens.next;
3989     for (;;) {
3990       state.tokens.next = lookahead.shift() || lex.token();
3991
3992       if (!state.tokens.next) { // No more tokens left, give up
3993         quit("E041", state.tokens.curr.line);
3994       }
3995
3996       if (state.tokens.next.id === "(end)" || state.tokens.next.id === "(error)") {
3997         return;
3998       }
3999
4000       if (state.tokens.next.check) {
4001         state.tokens.next.check();
4002       }
4003
4004       if (state.tokens.next.isSpecial) {
4005         if (state.tokens.next.type === "falls through") {
4006           state.tokens.curr.caseFallsThrough = true;
4007         } else {
4008           doOption();
4009         }
4010       } else {
4011         if (state.tokens.next.id !== "(endline)") {
4012           break;
4013         }
4014       }
4015     }
4016   }
4017
4018   function isInfix(token) {
4019     return token.infix || (!token.identifier && !token.template && !!token.led);
4020   }
4021
4022   function isEndOfExpr() {
4023     var curr = state.tokens.curr;
4024     var next = state.tokens.next;
4025     if (next.id === ";" || next.id === "}" || next.id === ":") {
4026       return true;
4027     }
4028     if (isInfix(next) === isInfix(curr) || (curr.id === "yield" && state.inMoz())) {
4029       return curr.line !== startLine(next);
4030     }
4031     return false;
4032   }
4033
4034   function isBeginOfExpr(prev) {
4035     return !prev.left && prev.arity !== "unary";
4036   }
4037
4038   function expression(rbp, initial) {
4039     var left, isArray = false, isObject = false, isLetExpr = false;
4040
4041     state.nameStack.push();
4042     if (!initial && state.tokens.next.value === "let" && peek(0).value === "(") {
4043       if (!state.inMoz()) {
4044         warning("W118", state.tokens.next, "let expressions");
4045       }
4046       isLetExpr = true;
4047       state.funct["(scope)"].stack();
4048       advance("let");
4049       advance("(");
4050       state.tokens.prev.fud();
4051       advance(")");
4052     }
4053
4054     if (state.tokens.next.id === "(end)")
4055       error("E006", state.tokens.curr);
4056
4057     var isDangerous =
4058       state.option.asi &&
4059       state.tokens.prev.line !== startLine(state.tokens.curr) &&
4060       _.contains(["]", ")"], state.tokens.prev.id) &&
4061       _.contains(["[", "("], state.tokens.curr.id);
4062
4063     if (isDangerous)
4064       warning("W014", state.tokens.curr, state.tokens.curr.id);
4065
4066     advance();
4067
4068     if (initial) {
4069       state.funct["(verb)"] = state.tokens.curr.value;
4070       state.tokens.curr.beginsStmt = true;
4071     }
4072
4073     if (initial === true && state.tokens.curr.fud) {
4074       left = state.tokens.curr.fud();
4075     } else {
4076       if (state.tokens.curr.nud) {
4077         left = state.tokens.curr.nud();
4078       } else {
4079         error("E030", state.tokens.curr, state.tokens.curr.id);
4080       }
4081       while ((rbp < state.tokens.next.lbp || state.tokens.next.type === "(template)") &&
4082               !isEndOfExpr()) {
4083         isArray = state.tokens.curr.value === "Array";
4084         isObject = state.tokens.curr.value === "Object";
4085         if (left && (left.value || (left.first && left.first.value))) {
4086           if (left.value !== "new" ||
4087             (left.first && left.first.value && left.first.value === ".")) {
4088             isArray = false;
4089             if (left.value !== state.tokens.curr.value) {
4090               isObject = false;
4091             }
4092           }
4093         }
4094
4095         advance();
4096
4097         if (isArray && state.tokens.curr.id === "(" && state.tokens.next.id === ")") {
4098           warning("W009", state.tokens.curr);
4099         }
4100
4101         if (isObject && state.tokens.curr.id === "(" && state.tokens.next.id === ")") {
4102           warning("W010", state.tokens.curr);
4103         }
4104
4105         if (left && state.tokens.curr.led) {
4106           left = state.tokens.curr.led(left);
4107         } else {
4108           error("E033", state.tokens.curr, state.tokens.curr.id);
4109         }
4110       }
4111     }
4112     if (isLetExpr) {
4113       state.funct["(scope)"].unstack();
4114     }
4115
4116     state.nameStack.pop();
4117
4118     return left;
4119   }
4120
4121   function startLine(token) {
4122     return token.startLine || token.line;
4123   }
4124
4125   function nobreaknonadjacent(left, right) {
4126     left = left || state.tokens.curr;
4127     right = right || state.tokens.next;
4128     if (!state.option.laxbreak && left.line !== startLine(right)) {
4129       warning("W014", right, right.value);
4130     }
4131   }
4132
4133   function nolinebreak(t) {
4134     t = t || state.tokens.curr;
4135     if (t.line !== startLine(state.tokens.next)) {
4136       warning("E022", t, t.value);
4137     }
4138   }
4139
4140   function nobreakcomma(left, right) {
4141     if (left.line !== startLine(right)) {
4142       if (!state.option.laxcomma) {
4143         if (comma.first) {
4144           warning("I001");
4145           comma.first = false;
4146         }
4147         warning("W014", left, right.value);
4148       }
4149     }
4150   }
4151
4152   function comma(opts) {
4153     opts = opts || {};
4154
4155     if (!opts.peek) {
4156       nobreakcomma(state.tokens.curr, state.tokens.next);
4157       advance(",");
4158     } else {
4159       nobreakcomma(state.tokens.prev, state.tokens.curr);
4160     }
4161
4162     if (state.tokens.next.identifier && !(opts.property && state.inES5())) {
4163       switch (state.tokens.next.value) {
4164       case "break":
4165       case "case":
4166       case "catch":
4167       case "continue":
4168       case "default":
4169       case "do":
4170       case "else":
4171       case "finally":
4172       case "for":
4173       case "if":
4174       case "in":
4175       case "instanceof":
4176       case "return":
4177       case "switch":
4178       case "throw":
4179       case "try":
4180       case "var":
4181       case "let":
4182       case "while":
4183       case "with":
4184         error("E024", state.tokens.next, state.tokens.next.value);
4185         return false;
4186       }
4187     }
4188
4189     if (state.tokens.next.type === "(punctuator)") {
4190       switch (state.tokens.next.value) {
4191       case "}":
4192       case "]":
4193       case ",":
4194         if (opts.allowTrailing) {
4195           return true;
4196         }
4197       case ")":
4198         error("E024", state.tokens.next, state.tokens.next.value);
4199         return false;
4200       }
4201     }
4202     return true;
4203   }
4204
4205   function symbol(s, p) {
4206     var x = state.syntax[s];
4207     if (!x || typeof x !== "object") {
4208       state.syntax[s] = x = {
4209         id: s,
4210         lbp: p,
4211         value: s
4212       };
4213     }
4214     return x;
4215   }
4216
4217   function delim(s) {
4218     var x = symbol(s, 0);
4219     x.delim = true;
4220     return x;
4221   }
4222
4223   function stmt(s, f) {
4224     var x = delim(s);
4225     x.identifier = x.reserved = true;
4226     x.fud = f;
4227     return x;
4228   }
4229
4230   function blockstmt(s, f) {
4231     var x = stmt(s, f);
4232     x.block = true;
4233     return x;
4234   }
4235
4236   function reserveName(x) {
4237     var c = x.id.charAt(0);
4238     if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z")) {
4239       x.identifier = x.reserved = true;
4240     }
4241     return x;
4242   }
4243
4244   function prefix(s, f) {
4245     var x = symbol(s, 150);
4246     reserveName(x);
4247
4248     x.nud = (typeof f === "function") ? f : function() {
4249       this.arity = "unary";
4250       this.right = expression(150);
4251
4252       if (this.id === "++" || this.id === "--") {
4253         if (state.option.plusplus) {
4254           warning("W016", this, this.id);
4255         } else if (this.right && (!this.right.identifier || isReserved(this.right)) &&
4256             this.right.id !== "." && this.right.id !== "[") {
4257           warning("W017", this);
4258         }
4259
4260         if (this.right && this.right.isMetaProperty) {
4261           error("E031", this);
4262         } else if (this.right && this.right.identifier) {
4263           state.funct["(scope)"].block.modify(this.right.value, this);
4264         }
4265       }
4266
4267       return this;
4268     };
4269
4270     return x;
4271   }
4272
4273   function type(s, f) {
4274     var x = delim(s);
4275     x.type = s;
4276     x.nud = f;
4277     return x;
4278   }
4279
4280   function reserve(name, func) {
4281     var x = type(name, func);
4282     x.identifier = true;
4283     x.reserved = true;
4284     return x;
4285   }
4286
4287   function FutureReservedWord(name, meta) {
4288     var x = type(name, (meta && meta.nud) || function() {
4289       return this;
4290     });
4291
4292     meta = meta || {};
4293     meta.isFutureReservedWord = true;
4294
4295     x.value = name;
4296     x.identifier = true;
4297     x.reserved = true;
4298     x.meta = meta;
4299
4300     return x;
4301   }
4302
4303   function reservevar(s, v) {
4304     return reserve(s, function() {
4305       if (typeof v === "function") {
4306         v(this);
4307       }
4308       return this;
4309     });
4310   }
4311
4312   function infix(s, f, p, w) {
4313     var x = symbol(s, p);
4314     reserveName(x);
4315     x.infix = true;
4316     x.led = function(left) {
4317       if (!w) {
4318         nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
4319       }
4320       if ((s === "in" || s === "instanceof") && left.id === "!") {
4321         warning("W018", left, "!");
4322       }
4323       if (typeof f === "function") {
4324         return f(left, this);
4325       } else {
4326         this.left = left;
4327         this.right = expression(p);
4328         return this;
4329       }
4330     };
4331     return x;
4332   }
4333
4334   function application(s) {
4335     var x = symbol(s, 42);
4336
4337     x.led = function(left) {
4338       nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
4339
4340       this.left = left;
4341       this.right = doFunction({ type: "arrow", loneArg: left });
4342       return this;
4343     };
4344     return x;
4345   }
4346
4347   function relation(s, f) {
4348     var x = symbol(s, 100);
4349
4350     x.led = function(left) {
4351       nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
4352       this.left = left;
4353       var right = this.right = expression(100);
4354
4355       if (isIdentifier(left, "NaN") || isIdentifier(right, "NaN")) {
4356         warning("W019", this);
4357       } else if (f) {
4358         f.apply(this, [left, right]);
4359       }
4360
4361       if (!left || !right) {
4362         quit("E041", state.tokens.curr.line);
4363       }
4364
4365       if (left.id === "!") {
4366         warning("W018", left, "!");
4367       }
4368
4369       if (right.id === "!") {
4370         warning("W018", right, "!");
4371       }
4372
4373       return this;
4374     };
4375     return x;
4376   }
4377
4378   function isPoorRelation(node) {
4379     return node &&
4380         ((node.type === "(number)" && +node.value === 0) ||
4381          (node.type === "(string)" && node.value === "") ||
4382          (node.type === "null" && !state.option.eqnull) ||
4383         node.type === "true" ||
4384         node.type === "false" ||
4385         node.type === "undefined");
4386   }
4387
4388   var typeofValues = {};
4389   typeofValues.legacy = [
4390     "xml",
4391     "unknown"
4392   ];
4393   typeofValues.es3 = [
4394     "undefined", "boolean", "number", "string", "function", "object",
4395   ];
4396   typeofValues.es3 = typeofValues.es3.concat(typeofValues.legacy);
4397   typeofValues.es6 = typeofValues.es3.concat("symbol");
4398   function isTypoTypeof(left, right, state) {
4399     var values;
4400
4401     if (state.option.notypeof)
4402       return false;
4403
4404     if (!left || !right)
4405       return false;
4406
4407     values = state.inES6() ? typeofValues.es6 : typeofValues.es3;
4408
4409     if (right.type === "(identifier)" && right.value === "typeof" && left.type === "(string)")
4410       return !_.contains(values, left.value);
4411
4412     return false;
4413   }
4414
4415   function isGlobalEval(left, state) {
4416     var isGlobal = false;
4417     if (left.type === "this" && state.funct["(context)"] === null) {
4418       isGlobal = true;
4419     }
4420     else if (left.type === "(identifier)") {
4421       if (state.option.node && left.value === "global") {
4422         isGlobal = true;
4423       }
4424
4425       else if (state.option.browser && (left.value === "window" || left.value === "document")) {
4426         isGlobal = true;
4427       }
4428     }
4429
4430     return isGlobal;
4431   }
4432
4433   function findNativePrototype(left) {
4434     var natives = [
4435       "Array", "ArrayBuffer", "Boolean", "Collator", "DataView", "Date",
4436       "DateTimeFormat", "Error", "EvalError", "Float32Array", "Float64Array",
4437       "Function", "Infinity", "Intl", "Int16Array", "Int32Array", "Int8Array",
4438       "Iterator", "Number", "NumberFormat", "Object", "RangeError",
4439       "ReferenceError", "RegExp", "StopIteration", "String", "SyntaxError",
4440       "TypeError", "Uint16Array", "Uint32Array", "Uint8Array", "Uint8ClampedArray",
4441       "URIError"
4442     ];
4443
4444     function walkPrototype(obj) {
4445       if (typeof obj !== "object") return;
4446       return obj.right === "prototype" ? obj : walkPrototype(obj.left);
4447     }
4448
4449     function walkNative(obj) {
4450       while (!obj.identifier && typeof obj.left === "object")
4451         obj = obj.left;
4452
4453       if (obj.identifier && natives.indexOf(obj.value) >= 0)
4454         return obj.value;
4455     }
4456
4457     var prototype = walkPrototype(left);
4458     if (prototype) return walkNative(prototype);
4459   }
4460   function checkLeftSideAssign(left, assignToken, options) {
4461
4462     var allowDestructuring = options && options.allowDestructuring;
4463
4464     assignToken = assignToken || left;
4465
4466     if (state.option.freeze) {
4467       var nativeObject = findNativePrototype(left);
4468       if (nativeObject)
4469         warning("W121", left, nativeObject);
4470     }
4471
4472     if (left.identifier && !left.isMetaProperty) {
4473       state.funct["(scope)"].block.reassign(left.value, left);
4474     }
4475
4476     if (left.id === ".") {
4477       if (!left.left || left.left.value === "arguments" && !state.isStrict()) {
4478         warning("E031", assignToken);
4479       }
4480
4481       state.nameStack.set(state.tokens.prev);
4482       return true;
4483     } else if (left.id === "{" || left.id === "[") {
4484       if (allowDestructuring && state.tokens.curr.left.destructAssign) {
4485         state.tokens.curr.left.destructAssign.forEach(function(t) {
4486           if (t.id) {
4487             state.funct["(scope)"].block.modify(t.id, t.token);
4488           }
4489         });
4490       } else {
4491         if (left.id === "{" || !left.left) {
4492           warning("E031", assignToken);
4493         } else if (left.left.value === "arguments" && !state.isStrict()) {
4494           warning("E031", assignToken);
4495         }
4496       }
4497
4498       if (left.id === "[") {
4499         state.nameStack.set(left.right);
4500       }
4501
4502       return true;
4503     } else if (left.isMetaProperty) {
4504       error("E031", assignToken);
4505       return true;
4506     } else if (left.identifier && !isReserved(left)) {
4507       if (state.funct["(scope)"].labeltype(left.value) === "exception") {
4508         warning("W022", left);
4509       }
4510       state.nameStack.set(left);
4511       return true;
4512     }
4513
4514     if (left === state.syntax["function"]) {
4515       warning("W023", state.tokens.curr);
4516     }
4517
4518     return false;
4519   }
4520
4521   function assignop(s, f, p) {
4522     var x = infix(s, typeof f === "function" ? f : function(left, that) {
4523       that.left = left;
4524
4525       if (left && checkLeftSideAssign(left, that, { allowDestructuring: true })) {
4526         that.right = expression(10);
4527         return that;
4528       }
4529
4530       error("E031", that);
4531     }, p);
4532
4533     x.exps = true;
4534     x.assign = true;
4535     return x;
4536   }
4537
4538
4539   function bitwise(s, f, p) {
4540     var x = symbol(s, p);
4541     reserveName(x);
4542     x.led = (typeof f === "function") ? f : function(left) {
4543       if (state.option.bitwise) {
4544         warning("W016", this, this.id);
4545       }
4546       this.left = left;
4547       this.right = expression(p);
4548       return this;
4549     };
4550     return x;
4551   }
4552
4553   function bitwiseassignop(s) {
4554     return assignop(s, function(left, that) {
4555       if (state.option.bitwise) {
4556         warning("W016", that, that.id);
4557       }
4558
4559       if (left && checkLeftSideAssign(left, that)) {
4560         that.right = expression(10);
4561         return that;
4562       }
4563       error("E031", that);
4564     }, 20);
4565   }
4566
4567   function suffix(s) {
4568     var x = symbol(s, 150);
4569
4570     x.led = function(left) {
4571       if (state.option.plusplus) {
4572         warning("W016", this, this.id);
4573       } else if ((!left.identifier || isReserved(left)) && left.id !== "." && left.id !== "[") {
4574         warning("W017", this);
4575       }
4576
4577       if (left.isMetaProperty) {
4578         error("E031", this);
4579       } else if (left && left.identifier) {
4580         state.funct["(scope)"].block.modify(left.value, left);
4581       }
4582
4583       this.left = left;
4584       return this;
4585     };
4586     return x;
4587   }
4588
4589   function optionalidentifier(fnparam, prop, preserve) {
4590     if (!state.tokens.next.identifier) {
4591       return;
4592     }
4593
4594     if (!preserve) {
4595       advance();
4596     }
4597
4598     var curr = state.tokens.curr;
4599     var val  = state.tokens.curr.value;
4600
4601     if (!isReserved(curr)) {
4602       return val;
4603     }
4604
4605     if (prop) {
4606       if (state.inES5()) {
4607         return val;
4608       }
4609     }
4610
4611     if (fnparam && val === "undefined") {
4612       return val;
4613     }
4614
4615     warning("W024", state.tokens.curr, state.tokens.curr.id);
4616     return val;
4617   }
4618   function identifier(fnparam, prop) {
4619     var i = optionalidentifier(fnparam, prop, false);
4620     if (i) {
4621       return i;
4622     }
4623     if (state.tokens.next.value === "...") {
4624       if (!state.inES6(true)) {
4625         warning("W119", state.tokens.next, "spread/rest operator", "6");
4626       }
4627       advance();
4628
4629       if (checkPunctuator(state.tokens.next, "...")) {
4630         warning("E024", state.tokens.next, "...");
4631         while (checkPunctuator(state.tokens.next, "...")) {
4632           advance();
4633         }
4634       }
4635
4636       if (!state.tokens.next.identifier) {
4637         warning("E024", state.tokens.curr, "...");
4638         return;
4639       }
4640
4641       return identifier(fnparam, prop);
4642     } else {
4643       error("E030", state.tokens.next, state.tokens.next.value);
4644       if (state.tokens.next.id !== ";") {
4645         advance();
4646       }
4647     }
4648   }
4649
4650
4651   function reachable(controlToken) {
4652     var i = 0, t;
4653     if (state.tokens.next.id !== ";" || controlToken.inBracelessBlock) {
4654       return;
4655     }
4656     for (;;) {
4657       do {
4658         t = peek(i);
4659         i += 1;
4660       } while (t.id !== "(end)" && t.id === "(comment)");
4661
4662       if (t.reach) {
4663         return;
4664       }
4665       if (t.id !== "(endline)") {
4666         if (t.id === "function") {
4667           if (state.option.latedef === true) {
4668             warning("W026", t);
4669           }
4670           break;
4671         }
4672
4673         warning("W027", t, t.value, controlToken.value);
4674         break;
4675       }
4676     }
4677   }
4678
4679   function parseFinalSemicolon() {
4680     if (state.tokens.next.id !== ";") {
4681       if (state.tokens.next.isUnclosed) return advance();
4682
4683       var sameLine = startLine(state.tokens.next) === state.tokens.curr.line &&
4684                      state.tokens.next.id !== "(end)";
4685       var blockEnd = checkPunctuator(state.tokens.next, "}");
4686
4687       if (sameLine && !blockEnd) {
4688         errorAt("E058", state.tokens.curr.line, state.tokens.curr.character);
4689       } else if (!state.option.asi) {
4690         if ((blockEnd && !state.option.lastsemic) || !sameLine) {
4691           warningAt("W033", state.tokens.curr.line, state.tokens.curr.character);
4692         }
4693       }
4694     } else {
4695       advance(";");
4696     }
4697   }
4698
4699   function statement() {
4700     var i = indent, r, t = state.tokens.next, hasOwnScope = false;
4701
4702     if (t.id === ";") {
4703       advance(";");
4704       return;
4705     }
4706     var res = isReserved(t);
4707
4708     if (res && t.meta && t.meta.isFutureReservedWord && peek().id === ":") {
4709       warning("W024", t, t.id);
4710       res = false;
4711     }
4712
4713     if (t.identifier && !res && peek().id === ":") {
4714       advance();
4715       advance(":");
4716
4717       hasOwnScope = true;
4718       state.funct["(scope)"].stack();
4719       state.funct["(scope)"].block.addBreakLabel(t.value, { token: state.tokens.curr });
4720
4721       if (!state.tokens.next.labelled && state.tokens.next.value !== "{") {
4722         warning("W028", state.tokens.next, t.value, state.tokens.next.value);
4723       }
4724
4725       state.tokens.next.label = t.value;
4726       t = state.tokens.next;
4727     }
4728
4729     if (t.id === "{") {
4730       var iscase = (state.funct["(verb)"] === "case" && state.tokens.curr.value === ":");
4731       block(true, true, false, false, iscase);
4732       return;
4733     }
4734
4735     r = expression(0, true);
4736
4737     if (r && !(r.identifier && r.value === "function") &&
4738         !(r.type === "(punctuator)" && r.left &&
4739           r.left.identifier && r.left.value === "function")) {
4740       if (!state.isStrict() &&
4741           state.option.strict === "global") {
4742         warning("E007");
4743       }
4744     }
4745
4746     if (!t.block) {
4747       if (!state.option.expr && (!r || !r.exps)) {
4748         warning("W030", state.tokens.curr);
4749       } else if (state.option.nonew && r && r.left && r.id === "(" && r.left.id === "new") {
4750         warning("W031", t);
4751       }
4752       parseFinalSemicolon();
4753     }
4754
4755     indent = i;
4756     if (hasOwnScope) {
4757       state.funct["(scope)"].unstack();
4758     }
4759     return r;
4760   }
4761
4762
4763   function statements() {
4764     var a = [], p;
4765
4766     while (!state.tokens.next.reach && state.tokens.next.id !== "(end)") {
4767       if (state.tokens.next.id === ";") {
4768         p = peek();
4769
4770         if (!p || (p.id !== "(" && p.id !== "[")) {
4771           warning("W032");
4772         }
4773
4774         advance(";");
4775       } else {
4776         a.push(statement());
4777       }
4778     }
4779     return a;
4780   }
4781   function directives() {
4782     var i, p, pn;
4783
4784     while (state.tokens.next.id === "(string)") {
4785       p = peek(0);
4786       if (p.id === "(endline)") {
4787         i = 1;
4788         do {
4789           pn = peek(i++);
4790         } while (pn.id === "(endline)");
4791         if (pn.id === ";") {
4792           p = pn;
4793         } else if (pn.value === "[" || pn.value === ".") {
4794           break;
4795         } else if (!state.option.asi || pn.value === "(") {
4796           warning("W033", state.tokens.next);
4797         }
4798       } else if (p.id === "." || p.id === "[") {
4799         break;
4800       } else if (p.id !== ";") {
4801         warning("W033", p);
4802       }
4803
4804       advance();
4805       var directive = state.tokens.curr.value;
4806       if (state.directive[directive] ||
4807           (directive === "use strict" && state.option.strict === "implied")) {
4808         warning("W034", state.tokens.curr, directive);
4809       }
4810       state.directive[directive] = true;
4811
4812       if (p.id === ";") {
4813         advance(";");
4814       }
4815     }
4816
4817     if (state.isStrict()) {
4818       if (!state.option["(explicitNewcap)"]) {
4819         state.option.newcap = true;
4820       }
4821       state.option.undef = true;
4822     }
4823   }
4824   function block(ordinary, stmt, isfunc, isfatarrow, iscase) {
4825     var a,
4826       b = inblock,
4827       old_indent = indent,
4828       m,
4829       t,
4830       line,
4831       d;
4832
4833     inblock = ordinary;
4834
4835     t = state.tokens.next;
4836
4837     var metrics = state.funct["(metrics)"];
4838     metrics.nestedBlockDepth += 1;
4839     metrics.verifyMaxNestedBlockDepthPerFunction();
4840
4841     if (state.tokens.next.id === "{") {
4842       advance("{");
4843       state.funct["(scope)"].stack();
4844
4845       line = state.tokens.curr.line;
4846       if (state.tokens.next.id !== "}") {
4847         indent += state.option.indent;
4848         while (!ordinary && state.tokens.next.from > indent) {
4849           indent += state.option.indent;
4850         }
4851
4852         if (isfunc) {
4853           m = {};
4854           for (d in state.directive) {
4855             if (_.has(state.directive, d)) {
4856               m[d] = state.directive[d];
4857             }
4858           }
4859           directives();
4860
4861           if (state.option.strict && state.funct["(context)"]["(global)"]) {
4862             if (!m["use strict"] && !state.isStrict()) {
4863               warning("E007");
4864             }
4865           }
4866         }
4867
4868         a = statements();
4869
4870         metrics.statementCount += a.length;
4871
4872         indent -= state.option.indent;
4873       }
4874
4875       advance("}", t);
4876
4877       if (isfunc) {
4878         state.funct["(scope)"].validateParams();
4879         if (m) {
4880           state.directive = m;
4881         }
4882       }
4883
4884       state.funct["(scope)"].unstack();
4885
4886       indent = old_indent;
4887     } else if (!ordinary) {
4888       if (isfunc) {
4889         state.funct["(scope)"].stack();
4890
4891         m = {};
4892         if (stmt && !isfatarrow && !state.inMoz()) {
4893           error("W118", state.tokens.curr, "function closure expressions");
4894         }
4895
4896         if (!stmt) {
4897           for (d in state.directive) {
4898             if (_.has(state.directive, d)) {
4899               m[d] = state.directive[d];
4900             }
4901           }
4902         }
4903         expression(10);
4904
4905         if (state.option.strict && state.funct["(context)"]["(global)"]) {
4906           if (!m["use strict"] && !state.isStrict()) {
4907             warning("E007");
4908           }
4909         }
4910
4911         state.funct["(scope)"].unstack();
4912       } else {
4913         error("E021", state.tokens.next, "{", state.tokens.next.value);
4914       }
4915     } else {
4916       state.funct["(noblockscopedvar)"] = state.tokens.next.id !== "for";
4917       state.funct["(scope)"].stack();
4918
4919       if (!stmt || state.option.curly) {
4920         warning("W116", state.tokens.next, "{", state.tokens.next.value);
4921       }
4922
4923       state.tokens.next.inBracelessBlock = true;
4924       indent += state.option.indent;
4925       a = [statement()];
4926       indent -= state.option.indent;
4927
4928       state.funct["(scope)"].unstack();
4929       delete state.funct["(noblockscopedvar)"];
4930     }
4931     switch (state.funct["(verb)"]) {
4932     case "break":
4933     case "continue":
4934     case "return":
4935     case "throw":
4936       if (iscase) {
4937         break;
4938       }
4939     default:
4940       state.funct["(verb)"] = null;
4941     }
4942
4943     inblock = b;
4944     if (ordinary && state.option.noempty && (!a || a.length === 0)) {
4945       warning("W035", state.tokens.prev);
4946     }
4947     metrics.nestedBlockDepth -= 1;
4948     return a;
4949   }
4950
4951
4952   function countMember(m) {
4953     if (membersOnly && typeof membersOnly[m] !== "boolean") {
4954       warning("W036", state.tokens.curr, m);
4955     }
4956     if (typeof member[m] === "number") {
4957       member[m] += 1;
4958     } else {
4959       member[m] = 1;
4960     }
4961   }
4962
4963   type("(number)", function() {
4964     return this;
4965   });
4966
4967   type("(string)", function() {
4968     return this;
4969   });
4970
4971   state.syntax["(identifier)"] = {
4972     type: "(identifier)",
4973     lbp: 0,
4974     identifier: true,
4975
4976     nud: function() {
4977       var v = this.value;
4978       if (state.tokens.next.id === "=>") {
4979         return this;
4980       }
4981
4982       if (!state.funct["(comparray)"].check(v)) {
4983         state.funct["(scope)"].block.use(v, state.tokens.curr);
4984       }
4985       return this;
4986     },
4987
4988     led: function() {
4989       error("E033", state.tokens.next, state.tokens.next.value);
4990     }
4991   };
4992
4993   var baseTemplateSyntax = {
4994     lbp: 0,
4995     identifier: false,
4996     template: true,
4997   };
4998   state.syntax["(template)"] = _.extend({
4999     type: "(template)",
5000     nud: doTemplateLiteral,
5001     led: doTemplateLiteral,
5002     noSubst: false
5003   }, baseTemplateSyntax);
5004
5005   state.syntax["(template middle)"] = _.extend({
5006     type: "(template middle)",
5007     middle: true,
5008     noSubst: false
5009   }, baseTemplateSyntax);
5010
5011   state.syntax["(template tail)"] = _.extend({
5012     type: "(template tail)",
5013     tail: true,
5014     noSubst: false
5015   }, baseTemplateSyntax);
5016
5017   state.syntax["(no subst template)"] = _.extend({
5018     type: "(template)",
5019     nud: doTemplateLiteral,
5020     led: doTemplateLiteral,
5021     noSubst: true,
5022     tail: true // mark as tail, since it's always the last component
5023   }, baseTemplateSyntax);
5024
5025   type("(regexp)", function() {
5026     return this;
5027   });
5028
5029   delim("(endline)");
5030   delim("(begin)");
5031   delim("(end)").reach = true;
5032   delim("(error)").reach = true;
5033   delim("}").reach = true;
5034   delim(")");
5035   delim("]");
5036   delim("\"").reach = true;
5037   delim("'").reach = true;
5038   delim(";");
5039   delim(":").reach = true;
5040   delim("#");
5041
5042   reserve("else");
5043   reserve("case").reach = true;
5044   reserve("catch");
5045   reserve("default").reach = true;
5046   reserve("finally");
5047   reservevar("arguments", function(x) {
5048     if (state.isStrict() && state.funct["(global)"]) {
5049       warning("E008", x);
5050     }
5051   });
5052   reservevar("eval");
5053   reservevar("false");
5054   reservevar("Infinity");
5055   reservevar("null");
5056   reservevar("this", function(x) {
5057     if (state.isStrict() && !isMethod() &&
5058         !state.option.validthis && ((state.funct["(statement)"] &&
5059         state.funct["(name)"].charAt(0) > "Z") || state.funct["(global)"])) {
5060       warning("W040", x);
5061     }
5062   });
5063   reservevar("true");
5064   reservevar("undefined");
5065
5066   assignop("=", "assign", 20);
5067   assignop("+=", "assignadd", 20);
5068   assignop("-=", "assignsub", 20);
5069   assignop("*=", "assignmult", 20);
5070   assignop("/=", "assigndiv", 20).nud = function() {
5071     error("E014");
5072   };
5073   assignop("%=", "assignmod", 20);
5074
5075   bitwiseassignop("&=");
5076   bitwiseassignop("|=");
5077   bitwiseassignop("^=");
5078   bitwiseassignop("<<=");
5079   bitwiseassignop(">>=");
5080   bitwiseassignop(">>>=");
5081   infix(",", function(left, that) {
5082     var expr;
5083     that.exprs = [left];
5084
5085     if (state.option.nocomma) {
5086       warning("W127");
5087     }
5088
5089     if (!comma({ peek: true })) {
5090       return that;
5091     }
5092     while (true) {
5093       if (!(expr = expression(10))) {
5094         break;
5095       }
5096       that.exprs.push(expr);
5097       if (state.tokens.next.value !== "," || !comma()) {
5098         break;
5099       }
5100     }
5101     return that;
5102   }, 10, true);
5103
5104   infix("?", function(left, that) {
5105     increaseComplexityCount();
5106     that.left = left;
5107     that.right = expression(10);
5108     advance(":");
5109     that["else"] = expression(10);
5110     return that;
5111   }, 30);
5112
5113   var orPrecendence = 40;
5114   infix("||", function(left, that) {
5115     increaseComplexityCount();
5116     that.left = left;
5117     that.right = expression(orPrecendence);
5118     return that;
5119   }, orPrecendence);
5120   infix("&&", "and", 50);
5121   bitwise("|", "bitor", 70);
5122   bitwise("^", "bitxor", 80);
5123   bitwise("&", "bitand", 90);
5124   relation("==", function(left, right) {
5125     var eqnull = state.option.eqnull &&
5126       ((left && left.value) === "null" || (right && right.value) === "null");
5127
5128     switch (true) {
5129       case !eqnull && state.option.eqeqeq:
5130         this.from = this.character;
5131         warning("W116", this, "===", "==");
5132         break;
5133       case isPoorRelation(left):
5134         warning("W041", this, "===", left.value);
5135         break;
5136       case isPoorRelation(right):
5137         warning("W041", this, "===", right.value);
5138         break;
5139       case isTypoTypeof(right, left, state):
5140         warning("W122", this, right.value);
5141         break;
5142       case isTypoTypeof(left, right, state):
5143         warning("W122", this, left.value);
5144         break;
5145     }
5146
5147     return this;
5148   });
5149   relation("===", function(left, right) {
5150     if (isTypoTypeof(right, left, state)) {
5151       warning("W122", this, right.value);
5152     } else if (isTypoTypeof(left, right, state)) {
5153       warning("W122", this, left.value);
5154     }
5155     return this;
5156   });
5157   relation("!=", function(left, right) {
5158     var eqnull = state.option.eqnull &&
5159         ((left && left.value) === "null" || (right && right.value) === "null");
5160
5161     if (!eqnull && state.option.eqeqeq) {
5162       this.from = this.character;
5163       warning("W116", this, "!==", "!=");
5164     } else if (isPoorRelation(left)) {
5165       warning("W041", this, "!==", left.value);
5166     } else if (isPoorRelation(right)) {
5167       warning("W041", this, "!==", right.value);
5168     } else if (isTypoTypeof(right, left, state)) {
5169       warning("W122", this, right.value);
5170     } else if (isTypoTypeof(left, right, state)) {
5171       warning("W122", this, left.value);
5172     }
5173     return this;
5174   });
5175   relation("!==", function(left, right) {
5176     if (isTypoTypeof(right, left, state)) {
5177       warning("W122", this, right.value);
5178     } else if (isTypoTypeof(left, right, state)) {
5179       warning("W122", this, left.value);
5180     }
5181     return this;
5182   });
5183   relation("<");
5184   relation(">");
5185   relation("<=");
5186   relation(">=");
5187   bitwise("<<", "shiftleft", 120);
5188   bitwise(">>", "shiftright", 120);
5189   bitwise(">>>", "shiftrightunsigned", 120);
5190   infix("in", "in", 120);
5191   infix("instanceof", "instanceof", 120);
5192   infix("+", function(left, that) {
5193     var right;
5194     that.left = left;
5195     that.right = right = expression(130);
5196
5197     if (left && right && left.id === "(string)" && right.id === "(string)") {
5198       left.value += right.value;
5199       left.character = right.character;
5200       if (!state.option.scripturl && reg.javascriptURL.test(left.value)) {
5201         warning("W050", left);
5202       }
5203       return left;
5204     }
5205
5206     return that;
5207   }, 130);
5208   prefix("+", "num");
5209   prefix("+++", function() {
5210     warning("W007");
5211     this.arity = "unary";
5212     this.right = expression(150);
5213     return this;
5214   });
5215   infix("+++", function(left) {
5216     warning("W007");
5217     this.left = left;
5218     this.right = expression(130);
5219     return this;
5220   }, 130);
5221   infix("-", "sub", 130);
5222   prefix("-", "neg");
5223   prefix("---", function() {
5224     warning("W006");
5225     this.arity = "unary";
5226     this.right = expression(150);
5227     return this;
5228   });
5229   infix("---", function(left) {
5230     warning("W006");
5231     this.left = left;
5232     this.right = expression(130);
5233     return this;
5234   }, 130);
5235   infix("*", "mult", 140);
5236   infix("/", "div", 140);
5237   infix("%", "mod", 140);
5238
5239   suffix("++");
5240   prefix("++", "preinc");
5241   state.syntax["++"].exps = true;
5242
5243   suffix("--");
5244   prefix("--", "predec");
5245   state.syntax["--"].exps = true;
5246   prefix("delete", function() {
5247     var p = expression(10);
5248     if (!p) {
5249       return this;
5250     }
5251
5252     if (p.id !== "." && p.id !== "[") {
5253       warning("W051");
5254     }
5255     this.first = p;
5256     if (p.identifier && !state.isStrict()) {
5257       p.forgiveUndef = true;
5258     }
5259     return this;
5260   }).exps = true;
5261
5262   prefix("~", function() {
5263     if (state.option.bitwise) {
5264       warning("W016", this, "~");
5265     }
5266     this.arity = "unary";
5267     this.right = expression(150);
5268     return this;
5269   });
5270
5271   prefix("...", function() {
5272     if (!state.inES6(true)) {
5273       warning("W119", this, "spread/rest operator", "6");
5274     }
5275     if (!state.tokens.next.identifier &&
5276         state.tokens.next.type !== "(string)" &&
5277           !checkPunctuators(state.tokens.next, ["[", "("])) {
5278
5279       error("E030", state.tokens.next, state.tokens.next.value);
5280     }
5281     expression(150);
5282     return this;
5283   });
5284
5285   prefix("!", function() {
5286     this.arity = "unary";
5287     this.right = expression(150);
5288
5289     if (!this.right) { // '!' followed by nothing? Give up.
5290       quit("E041", this.line || 0);
5291     }
5292
5293     if (bang[this.right.id] === true) {
5294       warning("W018", this, "!");
5295     }
5296     return this;
5297   });
5298
5299   prefix("typeof", (function() {
5300     var p = expression(150);
5301     this.first = this.right = p;
5302
5303     if (!p) { // 'typeof' followed by nothing? Give up.
5304       quit("E041", this.line || 0, this.character || 0);
5305     }
5306     if (p.identifier) {
5307       p.forgiveUndef = true;
5308     }
5309     return this;
5310   }));
5311   prefix("new", function() {
5312     var mp = metaProperty("target", function() {
5313       if (!state.inES6(true)) {
5314         warning("W119", state.tokens.prev, "new.target", "6");
5315       }
5316       var inFunction, c = state.funct;
5317       while (c) {
5318         inFunction = !c["(global)"];
5319         if (!c["(arrow)"]) { break; }
5320         c = c["(context)"];
5321       }
5322       if (!inFunction) {
5323         warning("W136", state.tokens.prev, "new.target");
5324       }
5325     });
5326     if (mp) { return mp; }
5327
5328     var c = expression(155), i;
5329     if (c && c.id !== "function") {
5330       if (c.identifier) {
5331         c["new"] = true;
5332         switch (c.value) {
5333         case "Number":
5334         case "String":
5335         case "Boolean":
5336         case "Math":
5337         case "JSON":
5338           warning("W053", state.tokens.prev, c.value);
5339           break;
5340         case "Symbol":
5341           if (state.inES6()) {
5342             warning("W053", state.tokens.prev, c.value);
5343           }
5344           break;
5345         case "Function":
5346           if (!state.option.evil) {
5347             warning("W054");
5348           }
5349           break;
5350         case "Date":
5351         case "RegExp":
5352         case "this":
5353           break;
5354         default:
5355           if (c.id !== "function") {
5356             i = c.value.substr(0, 1);
5357             if (state.option.newcap && (i < "A" || i > "Z") &&
5358               !state.funct["(scope)"].isPredefined(c.value)) {
5359               warning("W055", state.tokens.curr);
5360             }
5361           }
5362         }
5363       } else {
5364         if (c.id !== "." && c.id !== "[" && c.id !== "(") {
5365           warning("W056", state.tokens.curr);
5366         }
5367       }
5368     } else {
5369       if (!state.option.supernew)
5370         warning("W057", this);
5371     }
5372     if (state.tokens.next.id !== "(" && !state.option.supernew) {
5373       warning("W058", state.tokens.curr, state.tokens.curr.value);
5374     }
5375     this.first = this.right = c;
5376     return this;
5377   });
5378   state.syntax["new"].exps = true;
5379
5380   prefix("void").exps = true;
5381
5382   infix(".", function(left, that) {
5383     var m = identifier(false, true);
5384
5385     if (typeof m === "string") {
5386       countMember(m);
5387     }
5388
5389     that.left = left;
5390     that.right = m;
5391
5392     if (m && m === "hasOwnProperty" && state.tokens.next.value === "=") {
5393       warning("W001");
5394     }
5395
5396     if (left && left.value === "arguments" && (m === "callee" || m === "caller")) {
5397       if (state.option.noarg)
5398         warning("W059", left, m);
5399       else if (state.isStrict())
5400         error("E008");
5401     } else if (!state.option.evil && left && left.value === "document" &&
5402         (m === "write" || m === "writeln")) {
5403       warning("W060", left);
5404     }
5405
5406     if (!state.option.evil && (m === "eval" || m === "execScript")) {
5407       if (isGlobalEval(left, state)) {
5408         warning("W061");
5409       }
5410     }
5411
5412     return that;
5413   }, 160, true);
5414
5415   infix("(", function(left, that) {
5416     if (state.option.immed && left && !left.immed && left.id === "function") {
5417       warning("W062");
5418     }
5419
5420     var n = 0;
5421     var p = [];
5422
5423     if (left) {
5424       if (left.type === "(identifier)") {
5425         if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) {
5426           if ("Array Number String Boolean Date Object Error Symbol".indexOf(left.value) === -1) {
5427             if (left.value === "Math") {
5428               warning("W063", left);
5429             } else if (state.option.newcap) {
5430               warning("W064", left);
5431             }
5432           }
5433         }
5434       }
5435     }
5436
5437     if (state.tokens.next.id !== ")") {
5438       for (;;) {
5439         p[p.length] = expression(10);
5440         n += 1;
5441         if (state.tokens.next.id !== ",") {
5442           break;
5443         }
5444         comma();
5445       }
5446     }
5447
5448     advance(")");
5449
5450     if (typeof left === "object") {
5451       if (!state.inES5() && left.value === "parseInt" && n === 1) {
5452         warning("W065", state.tokens.curr);
5453       }
5454       if (!state.option.evil) {
5455         if (left.value === "eval" || left.value === "Function" ||
5456             left.value === "execScript") {
5457           warning("W061", left);
5458
5459           if (p[0] && [0].id === "(string)") {
5460             addInternalSrc(left, p[0].value);
5461           }
5462         } else if (p[0] && p[0].id === "(string)" &&
5463              (left.value === "setTimeout" ||
5464             left.value === "setInterval")) {
5465           warning("W066", left);
5466           addInternalSrc(left, p[0].value);
5467         } else if (p[0] && p[0].id === "(string)" &&
5468              left.value === "." &&
5469              left.left.value === "window" &&
5470              (left.right === "setTimeout" ||
5471             left.right === "setInterval")) {
5472           warning("W066", left);
5473           addInternalSrc(left, p[0].value);
5474         }
5475       }
5476       if (!left.identifier && left.id !== "." && left.id !== "[" && left.id !== "=>" &&
5477           left.id !== "(" && left.id !== "&&" && left.id !== "||" && left.id !== "?" &&
5478           !(state.inES6() && left["(name)"])) {
5479         warning("W067", that);
5480       }
5481     }
5482
5483     that.left = left;
5484     return that;
5485   }, 155, true).exps = true;
5486
5487   prefix("(", function() {
5488     var pn = state.tokens.next, pn1, i = -1;
5489     var ret, triggerFnExpr, first, last;
5490     var parens = 1;
5491     var opening = state.tokens.curr;
5492     var preceeding = state.tokens.prev;
5493     var isNecessary = !state.option.singleGroups;
5494
5495     do {
5496       if (pn.value === "(") {
5497         parens += 1;
5498       } else if (pn.value === ")") {
5499         parens -= 1;
5500       }
5501
5502       i += 1;
5503       pn1 = pn;
5504       pn = peek(i);
5505     } while (!(parens === 0 && pn1.value === ")") && pn.value !== ";" && pn.type !== "(end)");
5506
5507     if (state.tokens.next.id === "function") {
5508       triggerFnExpr = state.tokens.next.immed = true;
5509     }
5510     if (pn.value === "=>") {
5511       return doFunction({ type: "arrow", parsedOpening: true });
5512     }
5513
5514     var exprs = [];
5515
5516     if (state.tokens.next.id !== ")") {
5517       for (;;) {
5518         exprs.push(expression(10));
5519
5520         if (state.tokens.next.id !== ",") {
5521           break;
5522         }
5523
5524         if (state.option.nocomma) {
5525           warning("W127");
5526         }
5527
5528         comma();
5529       }
5530     }
5531
5532     advance(")", this);
5533     if (state.option.immed && exprs[0] && exprs[0].id === "function") {
5534       if (state.tokens.next.id !== "(" &&
5535         state.tokens.next.id !== "." && state.tokens.next.id !== "[") {
5536         warning("W068", this);
5537       }
5538     }
5539
5540     if (!exprs.length) {
5541       return;
5542     }
5543     if (exprs.length > 1) {
5544       ret = Object.create(state.syntax[","]);
5545       ret.exprs = exprs;
5546
5547       first = exprs[0];
5548       last = exprs[exprs.length - 1];
5549
5550       if (!isNecessary) {
5551         isNecessary = preceeding.assign || preceeding.delim;
5552       }
5553     } else {
5554       ret = first = last = exprs[0];
5555
5556       if (!isNecessary) {
5557         isNecessary =
5558           (opening.beginsStmt && (ret.id === "{" || triggerFnExpr || isFunctor(ret))) ||
5559           (triggerFnExpr &&
5560             (!isEndOfExpr() || state.tokens.prev.id !== "}")) ||
5561           (isFunctor(ret) && !isEndOfExpr()) ||
5562           (ret.id === "{" && preceeding.id === "=>") ||
5563           (ret.type === "(number)" &&
5564             checkPunctuator(pn, ".") && /^\d+$/.test(ret.value));
5565       }
5566     }
5567
5568     if (ret) {
5569       if (!isNecessary && (first.left || first.right || ret.exprs)) {
5570         isNecessary =
5571           (!isBeginOfExpr(preceeding) && first.lbp <= preceeding.lbp) ||
5572           (!isEndOfExpr() && last.lbp < state.tokens.next.lbp);
5573       }
5574
5575       if (!isNecessary) {
5576         warning("W126", opening);
5577       }
5578
5579       ret.paren = true;
5580     }
5581
5582     return ret;
5583   });
5584
5585   application("=>");
5586
5587   infix("[", function(left, that) {
5588     var e = expression(10), s;
5589     if (e && e.type === "(string)") {
5590       if (!state.option.evil && (e.value === "eval" || e.value === "execScript")) {
5591         if (isGlobalEval(left, state)) {
5592           warning("W061");
5593         }
5594       }
5595
5596       countMember(e.value);
5597       if (!state.option.sub && reg.identifier.test(e.value)) {
5598         s = state.syntax[e.value];
5599         if (!s || !isReserved(s)) {
5600           warning("W069", state.tokens.prev, e.value);
5601         }
5602       }
5603     }
5604     advance("]", that);
5605
5606     if (e && e.value === "hasOwnProperty" && state.tokens.next.value === "=") {
5607       warning("W001");
5608     }
5609
5610     that.left = left;
5611     that.right = e;
5612     return that;
5613   }, 160, true);
5614
5615   function comprehensiveArrayExpression() {
5616     var res = {};
5617     res.exps = true;
5618     state.funct["(comparray)"].stack();
5619     var reversed = false;
5620     if (state.tokens.next.value !== "for") {
5621       reversed = true;
5622       if (!state.inMoz()) {
5623         warning("W116", state.tokens.next, "for", state.tokens.next.value);
5624       }
5625       state.funct["(comparray)"].setState("use");
5626       res.right = expression(10);
5627     }
5628
5629     advance("for");
5630     if (state.tokens.next.value === "each") {
5631       advance("each");
5632       if (!state.inMoz()) {
5633         warning("W118", state.tokens.curr, "for each");
5634       }
5635     }
5636     advance("(");
5637     state.funct["(comparray)"].setState("define");
5638     res.left = expression(130);
5639     if (_.contains(["in", "of"], state.tokens.next.value)) {
5640       advance();
5641     } else {
5642       error("E045", state.tokens.curr);
5643     }
5644     state.funct["(comparray)"].setState("generate");
5645     expression(10);
5646
5647     advance(")");
5648     if (state.tokens.next.value === "if") {
5649       advance("if");
5650       advance("(");
5651       state.funct["(comparray)"].setState("filter");
5652       res.filter = expression(10);
5653       advance(")");
5654     }
5655
5656     if (!reversed) {
5657       state.funct["(comparray)"].setState("use");
5658       res.right = expression(10);
5659     }
5660
5661     advance("]");
5662     state.funct["(comparray)"].unstack();
5663     return res;
5664   }
5665
5666   prefix("[", function() {
5667     var blocktype = lookupBlockType();
5668     if (blocktype.isCompArray) {
5669       if (!state.option.esnext && !state.inMoz()) {
5670         warning("W118", state.tokens.curr, "array comprehension");
5671       }
5672       return comprehensiveArrayExpression();
5673     } else if (blocktype.isDestAssign) {
5674       this.destructAssign = destructuringPattern({ openingParsed: true, assignment: true });
5675       return this;
5676     }
5677     var b = state.tokens.curr.line !== startLine(state.tokens.next);
5678     this.first = [];
5679     if (b) {
5680       indent += state.option.indent;
5681       if (state.tokens.next.from === indent + state.option.indent) {
5682         indent += state.option.indent;
5683       }
5684     }
5685     while (state.tokens.next.id !== "(end)") {
5686       while (state.tokens.next.id === ",") {
5687         if (!state.option.elision) {
5688           if (!state.inES5()) {
5689             warning("W070");
5690           } else {
5691             warning("W128");
5692             do {
5693               advance(",");
5694             } while (state.tokens.next.id === ",");
5695             continue;
5696           }
5697         }
5698         advance(",");
5699       }
5700
5701       if (state.tokens.next.id === "]") {
5702         break;
5703       }
5704
5705       this.first.push(expression(10));
5706       if (state.tokens.next.id === ",") {
5707         comma({ allowTrailing: true });
5708         if (state.tokens.next.id === "]" && !state.inES5()) {
5709           warning("W070", state.tokens.curr);
5710           break;
5711         }
5712       } else {
5713         break;
5714       }
5715     }
5716     if (b) {
5717       indent -= state.option.indent;
5718     }
5719     advance("]", this);
5720     return this;
5721   });
5722
5723
5724   function isMethod() {
5725     return state.funct["(statement)"] && state.funct["(statement)"].type === "class" ||
5726            state.funct["(context)"] && state.funct["(context)"]["(verb)"] === "class";
5727   }
5728
5729
5730   function isPropertyName(token) {
5731     return token.identifier || token.id === "(string)" || token.id === "(number)";
5732   }
5733
5734
5735   function propertyName(preserveOrToken) {
5736     var id;
5737     var preserve = true;
5738     if (typeof preserveOrToken === "object") {
5739       id = preserveOrToken;
5740     } else {
5741       preserve = preserveOrToken;
5742       id = optionalidentifier(false, true, preserve);
5743     }
5744
5745     if (!id) {
5746       if (state.tokens.next.id === "(string)") {
5747         id = state.tokens.next.value;
5748         if (!preserve) {
5749           advance();
5750         }
5751       } else if (state.tokens.next.id === "(number)") {
5752         id = state.tokens.next.value.toString();
5753         if (!preserve) {
5754           advance();
5755         }
5756       }
5757     } else if (typeof id === "object") {
5758       if (id.id === "(string)" || id.id === "(identifier)") id = id.value;
5759       else if (id.id === "(number)") id = id.value.toString();
5760     }
5761
5762     if (id === "hasOwnProperty") {
5763       warning("W001");
5764     }
5765
5766     return id;
5767   }
5768   function functionparams(options) {
5769     var next;
5770     var paramsIds = [];
5771     var ident;
5772     var tokens = [];
5773     var t;
5774     var pastDefault = false;
5775     var pastRest = false;
5776     var arity = 0;
5777     var loneArg = options && options.loneArg;
5778
5779     if (loneArg && loneArg.identifier === true) {
5780       state.funct["(scope)"].addParam(loneArg.value, loneArg);
5781       return { arity: 1, params: [ loneArg.value ] };
5782     }
5783
5784     next = state.tokens.next;
5785
5786     if (!options || !options.parsedOpening) {
5787       advance("(");
5788     }
5789
5790     if (state.tokens.next.id === ")") {
5791       advance(")");
5792       return;
5793     }
5794
5795     function addParam(addParamArgs) {
5796       state.funct["(scope)"].addParam.apply(state.funct["(scope)"], addParamArgs);
5797     }
5798
5799     for (;;) {
5800       arity++;
5801       var currentParams = [];
5802
5803       if (_.contains(["{", "["], state.tokens.next.id)) {
5804         tokens = destructuringPattern();
5805         for (t in tokens) {
5806           t = tokens[t];
5807           if (t.id) {
5808             paramsIds.push(t.id);
5809             currentParams.push([t.id, t.token]);
5810           }
5811         }
5812       } else {
5813         if (checkPunctuator(state.tokens.next, "...")) pastRest = true;
5814         ident = identifier(true);
5815         if (ident) {
5816           paramsIds.push(ident);
5817           currentParams.push([ident, state.tokens.curr]);
5818         } else {
5819           while (!checkPunctuators(state.tokens.next, [",", ")"])) advance();
5820         }
5821       }
5822       if (pastDefault) {
5823         if (state.tokens.next.id !== "=") {
5824           error("W138", state.tokens.current);
5825         }
5826       }
5827       if (state.tokens.next.id === "=") {
5828         if (!state.inES6()) {
5829           warning("W119", state.tokens.next, "default parameters", "6");
5830         }
5831         advance("=");
5832         pastDefault = true;
5833         expression(10);
5834       }
5835       currentParams.forEach(addParam);
5836
5837       if (state.tokens.next.id === ",") {
5838         if (pastRest) {
5839           warning("W131", state.tokens.next);
5840         }
5841         comma();
5842       } else {
5843         advance(")", next);
5844         return { arity: arity, params: paramsIds };
5845       }
5846     }
5847   }
5848
5849   function functor(name, token, overwrites) {
5850     var funct = {
5851       "(name)"      : name,
5852       "(breakage)"  : 0,
5853       "(loopage)"   : 0,
5854       "(tokens)"    : {},
5855       "(properties)": {},
5856
5857       "(catch)"     : false,
5858       "(global)"    : false,
5859
5860       "(line)"      : null,
5861       "(character)" : null,
5862       "(metrics)"   : null,
5863       "(statement)" : null,
5864       "(context)"   : null,
5865       "(scope)"     : null,
5866       "(comparray)" : null,
5867       "(generator)" : null,
5868       "(arrow)"     : null,
5869       "(params)"    : null
5870     };
5871
5872     if (token) {
5873       _.extend(funct, {
5874         "(line)"     : token.line,
5875         "(character)": token.character,
5876         "(metrics)"  : createMetrics(token)
5877       });
5878     }
5879
5880     _.extend(funct, overwrites);
5881
5882     if (funct["(context)"]) {
5883       funct["(scope)"] = funct["(context)"]["(scope)"];
5884       funct["(comparray)"]  = funct["(context)"]["(comparray)"];
5885     }
5886
5887     return funct;
5888   }
5889
5890   function isFunctor(token) {
5891     return "(scope)" in token;
5892   }
5893   function hasParsedCode(funct) {
5894     return funct["(global)"] && !funct["(verb)"];
5895   }
5896
5897   function doTemplateLiteral(left) {
5898     var ctx = this.context;
5899     var noSubst = this.noSubst;
5900     var depth = this.depth;
5901
5902     if (!noSubst) {
5903       while (!end()) {
5904         if (!state.tokens.next.template || state.tokens.next.depth > depth) {
5905           expression(0); // should probably have different rbp?
5906         } else {
5907           advance();
5908         }
5909       }
5910     }
5911
5912     return {
5913       id: "(template)",
5914       type: "(template)",
5915       tag: left
5916     };
5917
5918     function end() {
5919       if (state.tokens.curr.template && state.tokens.curr.tail &&
5920           state.tokens.curr.context === ctx) return true;
5921       var complete = (state.tokens.next.template && state.tokens.next.tail &&
5922                       state.tokens.next.context === ctx);
5923       if (complete) advance();
5924       return complete || state.tokens.next.isUnclosed;
5925     }
5926   }
5927   function doFunction(options) {
5928     var f, token, name, statement, classExprBinding, isGenerator, isArrow, ignoreLoopFunc;
5929     var oldOption = state.option;
5930     var oldIgnored = state.ignored;
5931
5932     if (options) {
5933       name = options.name;
5934       statement = options.statement;
5935       classExprBinding = options.classExprBinding;
5936       isGenerator = options.type === "generator";
5937       isArrow = options.type === "arrow";
5938       ignoreLoopFunc = options.ignoreLoopFunc;
5939     }
5940
5941     state.option = Object.create(state.option);
5942     state.ignored = Object.create(state.ignored);
5943
5944     state.funct = functor(name || state.nameStack.infer(), state.tokens.next, {
5945       "(statement)": statement,
5946       "(context)":   state.funct,
5947       "(arrow)":     isArrow,
5948       "(generator)": isGenerator
5949     });
5950
5951     f = state.funct;
5952     token = state.tokens.curr;
5953     token.funct = state.funct;
5954
5955     functions.push(state.funct);
5956     state.funct["(scope)"].stack("functionouter");
5957     var internallyAccessibleName = name || classExprBinding;
5958     if (internallyAccessibleName) {
5959       state.funct["(scope)"].block.add(internallyAccessibleName,
5960         classExprBinding ? "class" : "function", state.tokens.curr, false);
5961     }
5962     state.funct["(scope)"].stack("functionparams");
5963
5964     var paramsInfo = functionparams(options);
5965
5966     if (paramsInfo) {
5967       state.funct["(params)"] = paramsInfo.params;
5968       state.funct["(metrics)"].arity = paramsInfo.arity;
5969       state.funct["(metrics)"].verifyMaxParametersPerFunction();
5970     } else {
5971       state.funct["(metrics)"].arity = 0;
5972     }
5973
5974     if (isArrow) {
5975       if (!state.inES6(true)) {
5976         warning("W119", state.tokens.curr, "arrow function syntax (=>)", "6");
5977       }
5978
5979       if (!options.loneArg) {
5980         advance("=>");
5981       }
5982     }
5983
5984     block(false, true, true, isArrow);
5985
5986     if (!state.option.noyield && isGenerator &&
5987         state.funct["(generator)"] !== "yielded") {
5988       warning("W124", state.tokens.curr);
5989     }
5990
5991     state.funct["(metrics)"].verifyMaxStatementsPerFunction();
5992     state.funct["(metrics)"].verifyMaxComplexityPerFunction();
5993     state.funct["(unusedOption)"] = state.option.unused;
5994     state.option = oldOption;
5995     state.ignored = oldIgnored;
5996     state.funct["(last)"] = state.tokens.curr.line;
5997     state.funct["(lastcharacter)"] = state.tokens.curr.character;
5998     state.funct["(scope)"].unstack(); // also does usage and label checks
5999     state.funct["(scope)"].unstack();
6000
6001     state.funct = state.funct["(context)"];
6002
6003     if (!ignoreLoopFunc && !state.option.loopfunc && state.funct["(loopage)"]) {
6004       if (f["(isCapturing)"]) {
6005         warning("W083", token);
6006       }
6007     }
6008
6009     return f;
6010   }
6011
6012   function createMetrics(functionStartToken) {
6013     return {
6014       statementCount: 0,
6015       nestedBlockDepth: -1,
6016       ComplexityCount: 1,
6017       arity: 0,
6018
6019       verifyMaxStatementsPerFunction: function() {
6020         if (state.option.maxstatements &&
6021           this.statementCount > state.option.maxstatements) {
6022           warning("W071", functionStartToken, this.statementCount);
6023         }
6024       },
6025
6026       verifyMaxParametersPerFunction: function() {
6027         if (_.isNumber(state.option.maxparams) &&
6028           this.arity > state.option.maxparams) {
6029           warning("W072", functionStartToken, this.arity);
6030         }
6031       },
6032
6033       verifyMaxNestedBlockDepthPerFunction: function() {
6034         if (state.option.maxdepth &&
6035           this.nestedBlockDepth > 0 &&
6036           this.nestedBlockDepth === state.option.maxdepth + 1) {
6037           warning("W073", null, this.nestedBlockDepth);
6038         }
6039       },
6040
6041       verifyMaxComplexityPerFunction: function() {
6042         var max = state.option.maxcomplexity;
6043         var cc = this.ComplexityCount;
6044         if (max && cc > max) {
6045           warning("W074", functionStartToken, cc);
6046         }
6047       }
6048     };
6049   }
6050
6051   function increaseComplexityCount() {
6052     state.funct["(metrics)"].ComplexityCount += 1;
6053   }
6054
6055   function checkCondAssignment(expr) {
6056     var id, paren;
6057     if (expr) {
6058       id = expr.id;
6059       paren = expr.paren;
6060       if (id === "," && (expr = expr.exprs[expr.exprs.length - 1])) {
6061         id = expr.id;
6062         paren = paren || expr.paren;
6063       }
6064     }
6065     switch (id) {
6066     case "=":
6067     case "+=":
6068     case "-=":
6069     case "*=":
6070     case "%=":
6071     case "&=":
6072     case "|=":
6073     case "^=":
6074     case "/=":
6075       if (!paren && !state.option.boss) {
6076         warning("W084");
6077       }
6078     }
6079   }
6080   function checkProperties(props) {
6081     if (state.inES5()) {
6082       for (var name in props) {
6083         if (props[name] && props[name].setterToken && !props[name].getterToken) {
6084           warning("W078", props[name].setterToken);
6085         }
6086       }
6087     }
6088   }
6089
6090   function metaProperty(name, c) {
6091     if (checkPunctuator(state.tokens.next, ".")) {
6092       var left = state.tokens.curr.id;
6093       advance(".");
6094       var id = identifier();
6095       state.tokens.curr.isMetaProperty = true;
6096       if (name !== id) {
6097         error("E057", state.tokens.prev, left, id);
6098       } else {
6099         c();
6100       }
6101       return state.tokens.curr;
6102     }
6103   }
6104
6105   (function(x) {
6106     x.nud = function() {
6107       var b, f, i, p, t, isGeneratorMethod = false, nextVal;
6108       var props = Object.create(null); // All properties, including accessors
6109
6110       b = state.tokens.curr.line !== startLine(state.tokens.next);
6111       if (b) {
6112         indent += state.option.indent;
6113         if (state.tokens.next.from === indent + state.option.indent) {
6114           indent += state.option.indent;
6115         }
6116       }
6117
6118       var blocktype = lookupBlockType();
6119       if (blocktype.isDestAssign) {
6120         this.destructAssign = destructuringPattern({ openingParsed: true, assignment: true });
6121         return this;
6122       }
6123
6124       for (;;) {
6125         if (state.tokens.next.id === "}") {
6126           break;
6127         }
6128
6129         nextVal = state.tokens.next.value;
6130         if (state.tokens.next.identifier &&
6131             (peekIgnoreEOL().id === "," || peekIgnoreEOL().id === "}")) {
6132           if (!state.inES6()) {
6133             warning("W104", state.tokens.next, "object short notation", "6");
6134           }
6135           i = propertyName(true);
6136           saveProperty(props, i, state.tokens.next);
6137
6138           expression(10);
6139
6140         } else if (peek().id !== ":" && (nextVal === "get" || nextVal === "set")) {
6141           advance(nextVal);
6142
6143           if (!state.inES5()) {
6144             error("E034");
6145           }
6146
6147           i = propertyName();
6148           if (!i && !state.inES6()) {
6149             error("E035");
6150           }
6151           if (i) {
6152             saveAccessor(nextVal, props, i, state.tokens.curr);
6153           }
6154
6155           t = state.tokens.next;
6156           f = doFunction();
6157           p = f["(params)"];
6158           if (nextVal === "get" && i && p) {
6159             warning("W076", t, p[0], i);
6160           } else if (nextVal === "set" && i && (!p || p.length !== 1)) {
6161             warning("W077", t, i);
6162           }
6163         } else {
6164           if (state.tokens.next.value === "*" && state.tokens.next.type === "(punctuator)") {
6165             if (!state.inES6()) {
6166               warning("W104", state.tokens.next, "generator functions", "6");
6167             }
6168             advance("*");
6169             isGeneratorMethod = true;
6170           } else {
6171             isGeneratorMethod = false;
6172           }
6173
6174           if (state.tokens.next.id === "[") {
6175             i = computedPropertyName();
6176             state.nameStack.set(i);
6177           } else {
6178             state.nameStack.set(state.tokens.next);
6179             i = propertyName();
6180             saveProperty(props, i, state.tokens.next);
6181
6182             if (typeof i !== "string") {
6183               break;
6184             }
6185           }
6186
6187           if (state.tokens.next.value === "(") {
6188             if (!state.inES6()) {
6189               warning("W104", state.tokens.curr, "concise methods", "6");
6190             }
6191             doFunction({ type: isGeneratorMethod ? "generator" : null });
6192           } else {
6193             advance(":");
6194             expression(10);
6195           }
6196         }
6197
6198         countMember(i);
6199
6200         if (state.tokens.next.id === ",") {
6201           comma({ allowTrailing: true, property: true });
6202           if (state.tokens.next.id === ",") {
6203             warning("W070", state.tokens.curr);
6204           } else if (state.tokens.next.id === "}" && !state.inES5()) {
6205             warning("W070", state.tokens.curr);
6206           }
6207         } else {
6208           break;
6209         }
6210       }
6211       if (b) {
6212         indent -= state.option.indent;
6213       }
6214       advance("}", this);
6215
6216       checkProperties(props);
6217
6218       return this;
6219     };
6220     x.fud = function() {
6221       error("E036", state.tokens.curr);
6222     };
6223   }(delim("{")));
6224
6225   function destructuringPattern(options) {
6226     var isAssignment = options && options.assignment;
6227
6228     if (!state.inES6()) {
6229       warning("W104", state.tokens.curr,
6230         isAssignment ? "destructuring assignment" : "destructuring binding", "6");
6231     }
6232
6233     return destructuringPatternRecursive(options);
6234   }
6235
6236   function destructuringPatternRecursive(options) {
6237     var ids;
6238     var identifiers = [];
6239     var openingParsed = options && options.openingParsed;
6240     var isAssignment = options && options.assignment;
6241     var recursiveOptions = isAssignment ? { assignment: isAssignment } : null;
6242     var firstToken = openingParsed ? state.tokens.curr : state.tokens.next;
6243
6244     var nextInnerDE = function() {
6245       var ident;
6246       if (checkPunctuators(state.tokens.next, ["[", "{"])) {
6247         ids = destructuringPatternRecursive(recursiveOptions);
6248         for (var id in ids) {
6249           id = ids[id];
6250           identifiers.push({ id: id.id, token: id.token });
6251         }
6252       } else if (checkPunctuator(state.tokens.next, ",")) {
6253         identifiers.push({ id: null, token: state.tokens.curr });
6254       } else if (checkPunctuator(state.tokens.next, "(")) {
6255         advance("(");
6256         nextInnerDE();
6257         advance(")");
6258       } else {
6259         var is_rest = checkPunctuator(state.tokens.next, "...");
6260
6261         if (isAssignment) {
6262           var identifierToken = is_rest ? peek(0) : state.tokens.next;
6263           if (!identifierToken.identifier) {
6264             warning("E030", identifierToken, identifierToken.value);
6265           }
6266           var assignTarget = expression(155);
6267           if (assignTarget) {
6268             checkLeftSideAssign(assignTarget);
6269             if (assignTarget.identifier) {
6270               ident = assignTarget.value;
6271             }
6272           }
6273         } else {
6274           ident = identifier();
6275         }
6276         if (ident) {
6277           identifiers.push({ id: ident, token: state.tokens.curr });
6278         }
6279         return is_rest;
6280       }
6281       return false;
6282     };
6283     var assignmentProperty = function() {
6284       var id;
6285       if (checkPunctuator(state.tokens.next, "[")) {
6286         advance("[");
6287         expression(10);
6288         advance("]");
6289         advance(":");
6290         nextInnerDE();
6291       } else if (state.tokens.next.id === "(string)" ||
6292                  state.tokens.next.id === "(number)") {
6293         advance();
6294         advance(":");
6295         nextInnerDE();
6296       } else {
6297         id = identifier();
6298         if (checkPunctuator(state.tokens.next, ":")) {
6299           advance(":");
6300           nextInnerDE();
6301         } else if (id) {
6302           if (isAssignment) {
6303             checkLeftSideAssign(state.tokens.curr);
6304           }
6305           identifiers.push({ id: id, token: state.tokens.curr });
6306         }
6307       }
6308     };
6309     if (checkPunctuator(firstToken, "[")) {
6310       if (!openingParsed) {
6311         advance("[");
6312       }
6313       if (checkPunctuator(state.tokens.next, "]")) {
6314         warning("W137", state.tokens.curr);
6315       }
6316       var element_after_rest = false;
6317       while (!checkPunctuator(state.tokens.next, "]")) {
6318         if (nextInnerDE() && !element_after_rest &&
6319             checkPunctuator(state.tokens.next, ",")) {
6320           warning("W130", state.tokens.next);
6321           element_after_rest = true;
6322         }
6323         if (checkPunctuator(state.tokens.next, "=")) {
6324           if (checkPunctuator(state.tokens.prev, "...")) {
6325             advance("]");
6326           } else {
6327             advance("=");
6328           }
6329           if (state.tokens.next.id === "undefined") {
6330             warning("W080", state.tokens.prev, state.tokens.prev.value);
6331           }
6332           expression(10);
6333         }
6334         if (!checkPunctuator(state.tokens.next, "]")) {
6335           advance(",");
6336         }
6337       }
6338       advance("]");
6339     } else if (checkPunctuator(firstToken, "{")) {
6340
6341       if (!openingParsed) {
6342         advance("{");
6343       }
6344       if (checkPunctuator(state.tokens.next, "}")) {
6345         warning("W137", state.tokens.curr);
6346       }
6347       while (!checkPunctuator(state.tokens.next, "}")) {
6348         assignmentProperty();
6349         if (checkPunctuator(state.tokens.next, "=")) {
6350           advance("=");
6351           if (state.tokens.next.id === "undefined") {
6352             warning("W080", state.tokens.prev, state.tokens.prev.value);
6353           }
6354           expression(10);
6355         }
6356         if (!checkPunctuator(state.tokens.next, "}")) {
6357           advance(",");
6358           if (checkPunctuator(state.tokens.next, "}")) {
6359             break;
6360           }
6361         }
6362       }
6363       advance("}");
6364     }
6365     return identifiers;
6366   }
6367
6368   function destructuringPatternMatch(tokens, value) {
6369     var first = value.first;
6370
6371     if (!first)
6372       return;
6373
6374     _.zip(tokens, Array.isArray(first) ? first : [ first ]).forEach(function(val) {
6375       var token = val[0];
6376       var value = val[1];
6377
6378       if (token && value)
6379         token.first = value;
6380       else if (token && token.first && !value)
6381         warning("W080", token.first, token.first.value);
6382     });
6383   }
6384
6385   function blockVariableStatement(type, statement, context) {
6386
6387     var prefix = context && context.prefix;
6388     var inexport = context && context.inexport;
6389     var isLet = type === "let";
6390     var isConst = type === "const";
6391     var tokens, lone, value, letblock;
6392
6393     if (!state.inES6()) {
6394       warning("W104", state.tokens.curr, type, "6");
6395     }
6396
6397     if (isLet && state.tokens.next.value === "(") {
6398       if (!state.inMoz()) {
6399         warning("W118", state.tokens.next, "let block");
6400       }
6401       advance("(");
6402       state.funct["(scope)"].stack();
6403       letblock = true;
6404     } else if (state.funct["(noblockscopedvar)"]) {
6405       error("E048", state.tokens.curr, isConst ? "Const" : "Let");
6406     }
6407
6408     statement.first = [];
6409     for (;;) {
6410       var names = [];
6411       if (_.contains(["{", "["], state.tokens.next.value)) {
6412         tokens = destructuringPattern();
6413         lone = false;
6414       } else {
6415         tokens = [ { id: identifier(), token: state.tokens.curr } ];
6416         lone = true;
6417       }
6418
6419       if (!prefix && isConst && state.tokens.next.id !== "=") {
6420         warning("E012", state.tokens.curr, state.tokens.curr.value);
6421       }
6422
6423       for (var t in tokens) {
6424         if (tokens.hasOwnProperty(t)) {
6425           t = tokens[t];
6426           if (state.funct["(scope)"].block.isGlobal()) {
6427             if (predefined[t.id] === false) {
6428               warning("W079", t.token, t.id);
6429             }
6430           }
6431           if (t.id && !state.funct["(noblockscopedvar)"]) {
6432             state.funct["(scope)"].addlabel(t.id, {
6433               type: type,
6434               token: t.token });
6435             names.push(t.token);
6436
6437             if (lone && inexport) {
6438               state.funct["(scope)"].setExported(t.token.value, t.token);
6439             }
6440           }
6441         }
6442       }
6443
6444       if (state.tokens.next.id === "=") {
6445         advance("=");
6446         if (!prefix && state.tokens.next.id === "undefined") {
6447           warning("W080", state.tokens.prev, state.tokens.prev.value);
6448         }
6449         if (!prefix && peek(0).id === "=" && state.tokens.next.identifier) {
6450           warning("W120", state.tokens.next, state.tokens.next.value);
6451         }
6452         value = expression(prefix ? 120 : 10);
6453         if (lone) {
6454           tokens[0].first = value;
6455         } else {
6456           destructuringPatternMatch(names, value);
6457         }
6458       }
6459
6460       statement.first = statement.first.concat(names);
6461
6462       if (state.tokens.next.id !== ",") {
6463         break;
6464       }
6465       comma();
6466     }
6467     if (letblock) {
6468       advance(")");
6469       block(true, true);
6470       statement.block = true;
6471       state.funct["(scope)"].unstack();
6472     }
6473
6474     return statement;
6475   }
6476
6477   var conststatement = stmt("const", function(context) {
6478     return blockVariableStatement("const", this, context);
6479   });
6480   conststatement.exps = true;
6481
6482   var letstatement = stmt("let", function(context) {
6483     return blockVariableStatement("let", this, context);
6484   });
6485   letstatement.exps = true;
6486
6487   var varstatement = stmt("var", function(context) {
6488     var prefix = context && context.prefix;
6489     var inexport = context && context.inexport;
6490     var tokens, lone, value;
6491     var implied = context && context.implied;
6492     var report = !(context && context.ignore);
6493
6494     this.first = [];
6495     for (;;) {
6496       var names = [];
6497       if (_.contains(["{", "["], state.tokens.next.value)) {
6498         tokens = destructuringPattern();
6499         lone = false;
6500       } else {
6501         tokens = [ { id: identifier(), token: state.tokens.curr } ];
6502         lone = true;
6503       }
6504
6505       if (!(prefix && implied) && report && state.option.varstmt) {
6506         warning("W132", this);
6507       }
6508
6509       this.first = this.first.concat(names);
6510
6511       for (var t in tokens) {
6512         if (tokens.hasOwnProperty(t)) {
6513           t = tokens[t];
6514           if (!implied && state.funct["(global)"]) {
6515             if (predefined[t.id] === false) {
6516               warning("W079", t.token, t.id);
6517             } else if (state.option.futurehostile === false) {
6518               if ((!state.inES5() && vars.ecmaIdentifiers[5][t.id] === false) ||
6519                 (!state.inES6() && vars.ecmaIdentifiers[6][t.id] === false)) {
6520                 warning("W129", t.token, t.id);
6521               }
6522             }
6523           }
6524           if (t.id) {
6525             if (implied === "for") {
6526
6527               if (!state.funct["(scope)"].has(t.id)) {
6528                 if (report) warning("W088", t.token, t.id);
6529               }
6530               state.funct["(scope)"].block.use(t.id, t.token);
6531             } else {
6532               state.funct["(scope)"].addlabel(t.id, {
6533                 type: "var",
6534                 token: t.token });
6535
6536               if (lone && inexport) {
6537                 state.funct["(scope)"].setExported(t.id, t.token);
6538               }
6539             }
6540             names.push(t.token);
6541           }
6542         }
6543       }
6544
6545       if (state.tokens.next.id === "=") {
6546         state.nameStack.set(state.tokens.curr);
6547
6548         advance("=");
6549         if (!prefix && report && !state.funct["(loopage)"] &&
6550           state.tokens.next.id === "undefined") {
6551           warning("W080", state.tokens.prev, state.tokens.prev.value);
6552         }
6553         if (peek(0).id === "=" && state.tokens.next.identifier) {
6554           if (!prefix && report &&
6555               !state.funct["(params)"] ||
6556               state.funct["(params)"].indexOf(state.tokens.next.value) === -1) {
6557             warning("W120", state.tokens.next, state.tokens.next.value);
6558           }
6559         }
6560         value = expression(prefix ? 120 : 10);
6561         if (lone) {
6562           tokens[0].first = value;
6563         } else {
6564           destructuringPatternMatch(names, value);
6565         }
6566       }
6567
6568       if (state.tokens.next.id !== ",") {
6569         break;
6570       }
6571       comma();
6572     }
6573
6574     return this;
6575   });
6576   varstatement.exps = true;
6577
6578   blockstmt("class", function() {
6579     return classdef.call(this, true);
6580   });
6581
6582   function classdef(isStatement) {
6583     if (!state.inES6()) {
6584       warning("W104", state.tokens.curr, "class", "6");
6585     }
6586     if (isStatement) {
6587       this.name = identifier();
6588
6589       state.funct["(scope)"].addlabel(this.name, {
6590         type: "class",
6591         token: state.tokens.curr });
6592     } else if (state.tokens.next.identifier && state.tokens.next.value !== "extends") {
6593       this.name = identifier();
6594       this.namedExpr = true;
6595     } else {
6596       this.name = state.nameStack.infer();
6597     }
6598     classtail(this);
6599     return this;
6600   }
6601
6602   function classtail(c) {
6603     var wasInClassBody = state.inClassBody;
6604     if (state.tokens.next.value === "extends") {
6605       advance("extends");
6606       c.heritage = expression(10);
6607     }
6608
6609     state.inClassBody = true;
6610     advance("{");
6611     c.body = classbody(c);
6612     advance("}");
6613     state.inClassBody = wasInClassBody;
6614   }
6615
6616   function classbody(c) {
6617     var name;
6618     var isStatic;
6619     var isGenerator;
6620     var getset;
6621     var props = Object.create(null);
6622     var staticProps = Object.create(null);
6623     var computed;
6624     for (var i = 0; state.tokens.next.id !== "}"; ++i) {
6625       name = state.tokens.next;
6626       isStatic = false;
6627       isGenerator = false;
6628       getset = null;
6629       if (name.id === ";") {
6630         warning("W032");
6631         advance(";");
6632         continue;
6633       }
6634
6635       if (name.id === "*") {
6636         isGenerator = true;
6637         advance("*");
6638         name = state.tokens.next;
6639       }
6640       if (name.id === "[") {
6641         name = computedPropertyName();
6642         computed = true;
6643       } else if (isPropertyName(name)) {
6644         advance();
6645         computed = false;
6646         if (name.identifier && name.value === "static") {
6647           if (checkPunctuator(state.tokens.next, "*")) {
6648             isGenerator = true;
6649             advance("*");
6650           }
6651           if (isPropertyName(state.tokens.next) || state.tokens.next.id === "[") {
6652             computed = state.tokens.next.id === "[";
6653             isStatic = true;
6654             name = state.tokens.next;
6655             if (state.tokens.next.id === "[") {
6656               name = computedPropertyName();
6657             } else advance();
6658           }
6659         }
6660
6661         if (name.identifier && (name.value === "get" || name.value === "set")) {
6662           if (isPropertyName(state.tokens.next) || state.tokens.next.id === "[") {
6663             computed = state.tokens.next.id === "[";
6664             getset = name;
6665             name = state.tokens.next;
6666             if (state.tokens.next.id === "[") {
6667               name = computedPropertyName();
6668             } else advance();
6669           }
6670         }
6671       } else {
6672         warning("W052", state.tokens.next, state.tokens.next.value || state.tokens.next.type);
6673         advance();
6674         continue;
6675       }
6676
6677       if (!checkPunctuator(state.tokens.next, "(")) {
6678         error("E054", state.tokens.next, state.tokens.next.value);
6679         while (state.tokens.next.id !== "}" &&
6680                !checkPunctuator(state.tokens.next, "(")) {
6681           advance();
6682         }
6683         if (state.tokens.next.value !== "(") {
6684           doFunction({ statement: c });
6685         }
6686       }
6687
6688       if (!computed) {
6689         if (getset) {
6690           saveAccessor(
6691             getset.value, isStatic ? staticProps : props, name.value, name, true, isStatic);
6692         } else {
6693           if (name.value === "constructor") {
6694             state.nameStack.set(c);
6695           } else {
6696             state.nameStack.set(name);
6697           }
6698           saveProperty(isStatic ? staticProps : props, name.value, name, true, isStatic);
6699         }
6700       }
6701
6702       if (getset && name.value === "constructor") {
6703         var propDesc = getset.value === "get" ? "class getter method" : "class setter method";
6704         error("E049", name, propDesc, "constructor");
6705       } else if (name.value === "prototype") {
6706         error("E049", name, "class method", "prototype");
6707       }
6708
6709       propertyName(name);
6710
6711       doFunction({
6712         statement: c,
6713         type: isGenerator ? "generator" : null,
6714         classExprBinding: c.namedExpr ? c.name : null
6715       });
6716     }
6717
6718     checkProperties(props);
6719   }
6720
6721   blockstmt("function", function(context) {
6722     var inexport = context && context.inexport;
6723     var generator = false;
6724     if (state.tokens.next.value === "*") {
6725       advance("*");
6726       if (state.inES6({ strict: true })) {
6727         generator = true;
6728       } else {
6729         warning("W119", state.tokens.curr, "function*", "6");
6730       }
6731     }
6732     if (inblock) {
6733       warning("W082", state.tokens.curr);
6734     }
6735     var i = optionalidentifier();
6736
6737     state.funct["(scope)"].addlabel(i, {
6738       type: "function",
6739       token: state.tokens.curr });
6740
6741     if (i === undefined) {
6742       warning("W025");
6743     } else if (inexport) {
6744       state.funct["(scope)"].setExported(i, state.tokens.prev);
6745     }
6746
6747     doFunction({
6748       name: i,
6749       statement: this,
6750       type: generator ? "generator" : null,
6751       ignoreLoopFunc: inblock // a declaration may already have warned
6752     });
6753     if (state.tokens.next.id === "(" && state.tokens.next.line === state.tokens.curr.line) {
6754       error("E039");
6755     }
6756     return this;
6757   });
6758
6759   prefix("function", function() {
6760     var generator = false;
6761
6762     if (state.tokens.next.value === "*") {
6763       if (!state.inES6()) {
6764         warning("W119", state.tokens.curr, "function*", "6");
6765       }
6766       advance("*");
6767       generator = true;
6768     }
6769
6770     var i = optionalidentifier();
6771     doFunction({ name: i, type: generator ? "generator" : null });
6772     return this;
6773   });
6774
6775   blockstmt("if", function() {
6776     var t = state.tokens.next;
6777     increaseComplexityCount();
6778     state.condition = true;
6779     advance("(");
6780     var expr = expression(0);
6781     checkCondAssignment(expr);
6782     var forinifcheck = null;
6783     if (state.option.forin && state.forinifcheckneeded) {
6784       state.forinifcheckneeded = false; // We only need to analyze the first if inside the loop
6785       forinifcheck = state.forinifchecks[state.forinifchecks.length - 1];
6786       if (expr.type === "(punctuator)" && expr.value === "!") {
6787         forinifcheck.type = "(negative)";
6788       } else {
6789         forinifcheck.type = "(positive)";
6790       }
6791     }
6792
6793     advance(")", t);
6794     state.condition = false;
6795     var s = block(true, true);
6796     if (forinifcheck && forinifcheck.type === "(negative)") {
6797       if (s && s[0] && s[0].type === "(identifier)" && s[0].value === "continue") {
6798         forinifcheck.type = "(negative-with-continue)";
6799       }
6800     }
6801
6802     if (state.tokens.next.id === "else") {
6803       advance("else");
6804       if (state.tokens.next.id === "if" || state.tokens.next.id === "switch") {
6805         statement();
6806       } else {
6807         block(true, true);
6808       }
6809     }
6810     return this;
6811   });
6812
6813   blockstmt("try", function() {
6814     var b;
6815
6816     function doCatch() {
6817       advance("catch");
6818       advance("(");
6819
6820       state.funct["(scope)"].stack("catchparams");
6821
6822       if (checkPunctuators(state.tokens.next, ["[", "{"])) {
6823         var tokens = destructuringPattern();
6824         _.each(tokens, function(token) {
6825           if (token.id) {
6826             state.funct["(scope)"].addParam(token.id, token, "exception");
6827           }
6828         });
6829       } else if (state.tokens.next.type !== "(identifier)") {
6830         warning("E030", state.tokens.next, state.tokens.next.value);
6831       } else {
6832         state.funct["(scope)"].addParam(identifier(), state.tokens.curr, "exception");
6833       }
6834
6835       if (state.tokens.next.value === "if") {
6836         if (!state.inMoz()) {
6837           warning("W118", state.tokens.curr, "catch filter");
6838         }
6839         advance("if");
6840         expression(0);
6841       }
6842
6843       advance(")");
6844
6845       block(false);
6846
6847       state.funct["(scope)"].unstack();
6848     }
6849
6850     block(true);
6851
6852     while (state.tokens.next.id === "catch") {
6853       increaseComplexityCount();
6854       if (b && (!state.inMoz())) {
6855         warning("W118", state.tokens.next, "multiple catch blocks");
6856       }
6857       doCatch();
6858       b = true;
6859     }
6860
6861     if (state.tokens.next.id === "finally") {
6862       advance("finally");
6863       block(true);
6864       return;
6865     }
6866
6867     if (!b) {
6868       error("E021", state.tokens.next, "catch", state.tokens.next.value);
6869     }
6870
6871     return this;
6872   });
6873
6874   blockstmt("while", function() {
6875     var t = state.tokens.next;
6876     state.funct["(breakage)"] += 1;
6877     state.funct["(loopage)"] += 1;
6878     increaseComplexityCount();
6879     advance("(");
6880     checkCondAssignment(expression(0));
6881     advance(")", t);
6882     block(true, true);
6883     state.funct["(breakage)"] -= 1;
6884     state.funct["(loopage)"] -= 1;
6885     return this;
6886   }).labelled = true;
6887
6888   blockstmt("with", function() {
6889     var t = state.tokens.next;
6890     if (state.isStrict()) {
6891       error("E010", state.tokens.curr);
6892     } else if (!state.option.withstmt) {
6893       warning("W085", state.tokens.curr);
6894     }
6895
6896     advance("(");
6897     expression(0);
6898     advance(")", t);
6899     block(true, true);
6900
6901     return this;
6902   });
6903
6904   blockstmt("switch", function() {
6905     var t = state.tokens.next;
6906     var g = false;
6907     var noindent = false;
6908
6909     state.funct["(breakage)"] += 1;
6910     advance("(");
6911     checkCondAssignment(expression(0));
6912     advance(")", t);
6913     t = state.tokens.next;
6914     advance("{");
6915
6916     if (state.tokens.next.from === indent)
6917       noindent = true;
6918
6919     if (!noindent)
6920       indent += state.option.indent;
6921
6922     this.cases = [];
6923
6924     for (;;) {
6925       switch (state.tokens.next.id) {
6926       case "case":
6927         switch (state.funct["(verb)"]) {
6928         case "yield":
6929         case "break":
6930         case "case":
6931         case "continue":
6932         case "return":
6933         case "switch":
6934         case "throw":
6935           break;
6936         default:
6937           if (!state.tokens.curr.caseFallsThrough) {
6938             warning("W086", state.tokens.curr, "case");
6939           }
6940         }
6941
6942         advance("case");
6943         this.cases.push(expression(0));
6944         increaseComplexityCount();
6945         g = true;
6946         advance(":");
6947         state.funct["(verb)"] = "case";
6948         break;
6949       case "default":
6950         switch (state.funct["(verb)"]) {
6951         case "yield":
6952         case "break":
6953         case "continue":
6954         case "return":
6955         case "throw":
6956           break;
6957         default:
6958           if (this.cases.length) {
6959             if (!state.tokens.curr.caseFallsThrough) {
6960               warning("W086", state.tokens.curr, "default");
6961             }
6962           }
6963         }
6964
6965         advance("default");
6966         g = true;
6967         advance(":");
6968         break;
6969       case "}":
6970         if (!noindent)
6971           indent -= state.option.indent;
6972
6973         advance("}", t);
6974         state.funct["(breakage)"] -= 1;
6975         state.funct["(verb)"] = undefined;
6976         return;
6977       case "(end)":
6978         error("E023", state.tokens.next, "}");
6979         return;
6980       default:
6981         indent += state.option.indent;
6982         if (g) {
6983           switch (state.tokens.curr.id) {
6984           case ",":
6985             error("E040");
6986             return;
6987           case ":":
6988             g = false;
6989             statements();
6990             break;
6991           default:
6992             error("E025", state.tokens.curr);
6993             return;
6994           }
6995         } else {
6996           if (state.tokens.curr.id === ":") {
6997             advance(":");
6998             error("E024", state.tokens.curr, ":");
6999             statements();
7000           } else {
7001             error("E021", state.tokens.next, "case", state.tokens.next.value);
7002             return;
7003           }
7004         }
7005         indent -= state.option.indent;
7006       }
7007     }
7008     return this;
7009   }).labelled = true;
7010
7011   stmt("debugger", function() {
7012     if (!state.option.debug) {
7013       warning("W087", this);
7014     }
7015     return this;
7016   }).exps = true;
7017
7018   (function() {
7019     var x = stmt("do", function() {
7020       state.funct["(breakage)"] += 1;
7021       state.funct["(loopage)"] += 1;
7022       increaseComplexityCount();
7023
7024       this.first = block(true, true);
7025       advance("while");
7026       var t = state.tokens.next;
7027       advance("(");
7028       checkCondAssignment(expression(0));
7029       advance(")", t);
7030       state.funct["(breakage)"] -= 1;
7031       state.funct["(loopage)"] -= 1;
7032       return this;
7033     });
7034     x.labelled = true;
7035     x.exps = true;
7036   }());
7037
7038   blockstmt("for", function() {
7039     var s, t = state.tokens.next;
7040     var letscope = false;
7041     var foreachtok = null;
7042
7043     if (t.value === "each") {
7044       foreachtok = t;
7045       advance("each");
7046       if (!state.inMoz()) {
7047         warning("W118", state.tokens.curr, "for each");
7048       }
7049     }
7050
7051     increaseComplexityCount();
7052     advance("(");
7053     var nextop; // contains the token of the "in" or "of" operator
7054     var i = 0;
7055     var inof = ["in", "of"];
7056     var level = 0; // BindingPattern "level" --- level 0 === no BindingPattern
7057     var comma; // First comma punctuator at level 0
7058     var initializer; // First initializer at level 0
7059     if (checkPunctuators(state.tokens.next, ["{", "["])) ++level;
7060     do {
7061       nextop = peek(i);
7062       ++i;
7063       if (checkPunctuators(nextop, ["{", "["])) ++level;
7064       else if (checkPunctuators(nextop, ["}", "]"])) --level;
7065       if (level < 0) break;
7066       if (level === 0) {
7067         if (!comma && checkPunctuator(nextop, ",")) comma = nextop;
7068         else if (!initializer && checkPunctuator(nextop, "=")) initializer = nextop;
7069       }
7070     } while (level > 0 || !_.contains(inof, nextop.value) && nextop.value !== ";" &&
7071     nextop.type !== "(end)"); // Is this a JSCS bug? This looks really weird.
7072     if (_.contains(inof, nextop.value)) {
7073       if (!state.inES6() && nextop.value === "of") {
7074         warning("W104", nextop, "for of", "6");
7075       }
7076
7077       var ok = !(initializer || comma);
7078       if (initializer) {
7079         error("W133", comma, nextop.value, "initializer is forbidden");
7080       }
7081
7082       if (comma) {
7083         error("W133", comma, nextop.value, "more than one ForBinding");
7084       }
7085
7086       if (state.tokens.next.id === "var") {
7087         advance("var");
7088         state.tokens.curr.fud({ prefix: true });
7089       } else if (state.tokens.next.id === "let" || state.tokens.next.id === "const") {
7090         advance(state.tokens.next.id);
7091         letscope = true;
7092         state.funct["(scope)"].stack();
7093         state.tokens.curr.fud({ prefix: true });
7094       } else {
7095         Object.create(varstatement).fud({ prefix: true, implied: "for", ignore: !ok });
7096       }
7097       advance(nextop.value);
7098       expression(20);
7099       advance(")", t);
7100
7101       if (nextop.value === "in" && state.option.forin) {
7102         state.forinifcheckneeded = true;
7103
7104         if (state.forinifchecks === undefined) {
7105           state.forinifchecks = [];
7106         }
7107         state.forinifchecks.push({
7108           type: "(none)"
7109         });
7110       }
7111
7112       state.funct["(breakage)"] += 1;
7113       state.funct["(loopage)"] += 1;
7114
7115       s = block(true, true);
7116
7117       if (nextop.value === "in" && state.option.forin) {
7118         if (state.forinifchecks && state.forinifchecks.length > 0) {
7119           var check = state.forinifchecks.pop();
7120
7121           if (// No if statement or not the first statement in loop body
7122               s && s.length > 0 && (typeof s[0] !== "object" || s[0].value !== "if") ||
7123               check.type === "(positive)" && s.length > 1 ||
7124               check.type === "(negative)") {
7125             warning("W089", this);
7126           }
7127         }
7128         state.forinifcheckneeded = false;
7129       }
7130
7131       state.funct["(breakage)"] -= 1;
7132       state.funct["(loopage)"] -= 1;
7133     } else {
7134       if (foreachtok) {
7135         error("E045", foreachtok);
7136       }
7137       if (state.tokens.next.id !== ";") {
7138         if (state.tokens.next.id === "var") {
7139           advance("var");
7140           state.tokens.curr.fud();
7141         } else if (state.tokens.next.id === "let") {
7142           advance("let");
7143           letscope = true;
7144           state.funct["(scope)"].stack();
7145           state.tokens.curr.fud();
7146         } else {
7147           for (;;) {
7148             expression(0, "for");
7149             if (state.tokens.next.id !== ",") {
7150               break;
7151             }
7152             comma();
7153           }
7154         }
7155       }
7156       nolinebreak(state.tokens.curr);
7157       advance(";");
7158       state.funct["(loopage)"] += 1;
7159       if (state.tokens.next.id !== ";") {
7160         checkCondAssignment(expression(0));
7161       }
7162       nolinebreak(state.tokens.curr);
7163       advance(";");
7164       if (state.tokens.next.id === ";") {
7165         error("E021", state.tokens.next, ")", ";");
7166       }
7167       if (state.tokens.next.id !== ")") {
7168         for (;;) {
7169           expression(0, "for");
7170           if (state.tokens.next.id !== ",") {
7171             break;
7172           }
7173           comma();
7174         }
7175       }
7176       advance(")", t);
7177       state.funct["(breakage)"] += 1;
7178       block(true, true);
7179       state.funct["(breakage)"] -= 1;
7180       state.funct["(loopage)"] -= 1;
7181
7182     }
7183     if (letscope) {
7184       state.funct["(scope)"].unstack();
7185     }
7186     return this;
7187   }).labelled = true;
7188
7189
7190   stmt("break", function() {
7191     var v = state.tokens.next.value;
7192
7193     if (!state.option.asi)
7194       nolinebreak(this);
7195
7196     if (state.tokens.next.id !== ";" && !state.tokens.next.reach &&
7197         state.tokens.curr.line === startLine(state.tokens.next)) {
7198       if (!state.funct["(scope)"].funct.hasBreakLabel(v)) {
7199         warning("W090", state.tokens.next, v);
7200       }
7201       this.first = state.tokens.next;
7202       advance();
7203     } else {
7204       if (state.funct["(breakage)"] === 0)
7205         warning("W052", state.tokens.next, this.value);
7206     }
7207
7208     reachable(this);
7209
7210     return this;
7211   }).exps = true;
7212
7213
7214   stmt("continue", function() {
7215     var v = state.tokens.next.value;
7216
7217     if (state.funct["(breakage)"] === 0)
7218       warning("W052", state.tokens.next, this.value);
7219     if (!state.funct["(loopage)"])
7220       warning("W052", state.tokens.next, this.value);
7221
7222     if (!state.option.asi)
7223       nolinebreak(this);
7224
7225     if (state.tokens.next.id !== ";" && !state.tokens.next.reach) {
7226       if (state.tokens.curr.line === startLine(state.tokens.next)) {
7227         if (!state.funct["(scope)"].funct.hasBreakLabel(v)) {
7228           warning("W090", state.tokens.next, v);
7229         }
7230         this.first = state.tokens.next;
7231         advance();
7232       }
7233     }
7234
7235     reachable(this);
7236
7237     return this;
7238   }).exps = true;
7239
7240
7241   stmt("return", function() {
7242     if (this.line === startLine(state.tokens.next)) {
7243       if (state.tokens.next.id !== ";" && !state.tokens.next.reach) {
7244         this.first = expression(0);
7245
7246         if (this.first &&
7247             this.first.type === "(punctuator)" && this.first.value === "=" &&
7248             !this.first.paren && !state.option.boss) {
7249           warningAt("W093", this.first.line, this.first.character);
7250         }
7251       }
7252     } else {
7253       if (state.tokens.next.type === "(punctuator)" &&
7254         ["[", "{", "+", "-"].indexOf(state.tokens.next.value) > -1) {
7255         nolinebreak(this); // always warn (Line breaking error)
7256       }
7257     }
7258
7259     reachable(this);
7260
7261     return this;
7262   }).exps = true;
7263
7264   (function(x) {
7265     x.exps = true;
7266     x.lbp = 25;
7267   }(prefix("yield", function() {
7268     var prev = state.tokens.prev;
7269     if (state.inES6(true) && !state.funct["(generator)"]) {
7270       if (!("(catch)" === state.funct["(name)"] && state.funct["(context)"]["(generator)"])) {
7271         error("E046", state.tokens.curr, "yield");
7272       }
7273     } else if (!state.inES6()) {
7274       warning("W104", state.tokens.curr, "yield", "6");
7275     }
7276     state.funct["(generator)"] = "yielded";
7277     var delegatingYield = false;
7278
7279     if (state.tokens.next.value === "*") {
7280       delegatingYield = true;
7281       advance("*");
7282     }
7283
7284     if (this.line === startLine(state.tokens.next) || !state.inMoz()) {
7285       if (delegatingYield ||
7286           (state.tokens.next.id !== ";" && !state.option.asi &&
7287            !state.tokens.next.reach && state.tokens.next.nud)) {
7288
7289         nobreaknonadjacent(state.tokens.curr, state.tokens.next);
7290         this.first = expression(10);
7291
7292         if (this.first.type === "(punctuator)" && this.first.value === "=" &&
7293             !this.first.paren && !state.option.boss) {
7294           warningAt("W093", this.first.line, this.first.character);
7295         }
7296       }
7297
7298       if (state.inMoz() && state.tokens.next.id !== ")" &&
7299           (prev.lbp > 30 || (!prev.assign && !isEndOfExpr()) || prev.id === "yield")) {
7300         error("E050", this);
7301       }
7302     } else if (!state.option.asi) {
7303       nolinebreak(this); // always warn (Line breaking error)
7304     }
7305     return this;
7306   })));
7307
7308
7309   stmt("throw", function() {
7310     nolinebreak(this);
7311     this.first = expression(20);
7312
7313     reachable(this);
7314
7315     return this;
7316   }).exps = true;
7317
7318   stmt("import", function() {
7319     if (!state.inES6()) {
7320       warning("W119", state.tokens.curr, "import", "6");
7321     }
7322
7323     if (state.tokens.next.type === "(string)") {
7324       advance("(string)");
7325       return this;
7326     }
7327
7328     if (state.tokens.next.identifier) {
7329       this.name = identifier();
7330       state.funct["(scope)"].addlabel(this.name, {
7331         type: "const",
7332         token: state.tokens.curr });
7333
7334       if (state.tokens.next.value === ",") {
7335         advance(",");
7336       } else {
7337         advance("from");
7338         advance("(string)");
7339         return this;
7340       }
7341     }
7342
7343     if (state.tokens.next.id === "*") {
7344       advance("*");
7345       advance("as");
7346       if (state.tokens.next.identifier) {
7347         this.name = identifier();
7348         state.funct["(scope)"].addlabel(this.name, {
7349           type: "const",
7350           token: state.tokens.curr });
7351       }
7352     } else {
7353       advance("{");
7354       for (;;) {
7355         if (state.tokens.next.value === "}") {
7356           advance("}");
7357           break;
7358         }
7359         var importName;
7360         if (state.tokens.next.type === "default") {
7361           importName = "default";
7362           advance("default");
7363         } else {
7364           importName = identifier();
7365         }
7366         if (state.tokens.next.value === "as") {
7367           advance("as");
7368           importName = identifier();
7369         }
7370         state.funct["(scope)"].addlabel(importName, {
7371           type: "const",
7372           token: state.tokens.curr });
7373
7374         if (state.tokens.next.value === ",") {
7375           advance(",");
7376         } else if (state.tokens.next.value === "}") {
7377           advance("}");
7378           break;
7379         } else {
7380           error("E024", state.tokens.next, state.tokens.next.value);
7381           break;
7382         }
7383       }
7384     }
7385     advance("from");
7386     advance("(string)");
7387     return this;
7388   }).exps = true;
7389
7390   stmt("export", function() {
7391     var ok = true;
7392     var token;
7393     var identifier;
7394
7395     if (!state.inES6()) {
7396       warning("W119", state.tokens.curr, "export", "6");
7397       ok = false;
7398     }
7399
7400     if (!state.funct["(scope)"].block.isGlobal()) {
7401       error("E053", state.tokens.curr);
7402       ok = false;
7403     }
7404
7405     if (state.tokens.next.value === "*") {
7406       advance("*");
7407       advance("from");
7408       advance("(string)");
7409       return this;
7410     }
7411
7412     if (state.tokens.next.type === "default") {
7413       state.nameStack.set(state.tokens.next);
7414       advance("default");
7415       var exportType = state.tokens.next.id;
7416       if (exportType === "function" || exportType === "class") {
7417         this.block = true;
7418       }
7419
7420       token = peek();
7421
7422       expression(10);
7423
7424       identifier = token.value;
7425
7426       if (this.block) {
7427         state.funct["(scope)"].addlabel(identifier, {
7428           type: exportType,
7429           token: token });
7430
7431         state.funct["(scope)"].setExported(identifier, token);
7432       }
7433
7434       return this;
7435     }
7436
7437     if (state.tokens.next.value === "{") {
7438       advance("{");
7439       var exportedTokens = [];
7440       for (;;) {
7441         if (!state.tokens.next.identifier) {
7442           error("E030", state.tokens.next, state.tokens.next.value);
7443         }
7444         advance();
7445
7446         exportedTokens.push(state.tokens.curr);
7447
7448         if (state.tokens.next.value === "as") {
7449           advance("as");
7450           if (!state.tokens.next.identifier) {
7451             error("E030", state.tokens.next, state.tokens.next.value);
7452           }
7453           advance();
7454         }
7455
7456         if (state.tokens.next.value === ",") {
7457           advance(",");
7458         } else if (state.tokens.next.value === "}") {
7459           advance("}");
7460           break;
7461         } else {
7462           error("E024", state.tokens.next, state.tokens.next.value);
7463           break;
7464         }
7465       }
7466       if (state.tokens.next.value === "from") {
7467         advance("from");
7468         advance("(string)");
7469       } else if (ok) {
7470         exportedTokens.forEach(function(token) {
7471           state.funct["(scope)"].setExported(token.value, token);
7472         });
7473       }
7474       return this;
7475     }
7476
7477     if (state.tokens.next.id === "var") {
7478       advance("var");
7479       state.tokens.curr.fud({ inexport:true });
7480     } else if (state.tokens.next.id === "let") {
7481       advance("let");
7482       state.tokens.curr.fud({ inexport:true });
7483     } else if (state.tokens.next.id === "const") {
7484       advance("const");
7485       state.tokens.curr.fud({ inexport:true });
7486     } else if (state.tokens.next.id === "function") {
7487       this.block = true;
7488       advance("function");
7489       state.syntax["function"].fud({ inexport:true });
7490     } else if (state.tokens.next.id === "class") {
7491       this.block = true;
7492       advance("class");
7493       var classNameToken = state.tokens.next;
7494       state.syntax["class"].fud();
7495       state.funct["(scope)"].setExported(classNameToken.value, classNameToken);
7496     } else {
7497       error("E024", state.tokens.next, state.tokens.next.value);
7498     }
7499
7500     return this;
7501   }).exps = true;
7502
7503   FutureReservedWord("abstract");
7504   FutureReservedWord("boolean");
7505   FutureReservedWord("byte");
7506   FutureReservedWord("char");
7507   FutureReservedWord("class", { es5: true, nud: classdef });
7508   FutureReservedWord("double");
7509   FutureReservedWord("enum", { es5: true });
7510   FutureReservedWord("export", { es5: true });
7511   FutureReservedWord("extends", { es5: true });
7512   FutureReservedWord("final");
7513   FutureReservedWord("float");
7514   FutureReservedWord("goto");
7515   FutureReservedWord("implements", { es5: true, strictOnly: true });
7516   FutureReservedWord("import", { es5: true });
7517   FutureReservedWord("int");
7518   FutureReservedWord("interface", { es5: true, strictOnly: true });
7519   FutureReservedWord("long");
7520   FutureReservedWord("native");
7521   FutureReservedWord("package", { es5: true, strictOnly: true });
7522   FutureReservedWord("private", { es5: true, strictOnly: true });
7523   FutureReservedWord("protected", { es5: true, strictOnly: true });
7524   FutureReservedWord("public", { es5: true, strictOnly: true });
7525   FutureReservedWord("short");
7526   FutureReservedWord("static", { es5: true, strictOnly: true });
7527   FutureReservedWord("super", { es5: true });
7528   FutureReservedWord("synchronized");
7529   FutureReservedWord("transient");
7530   FutureReservedWord("volatile");
7531
7532   var lookupBlockType = function() {
7533     var pn, pn1, prev;
7534     var i = -1;
7535     var bracketStack = 0;
7536     var ret = {};
7537     if (checkPunctuators(state.tokens.curr, ["[", "{"])) {
7538       bracketStack += 1;
7539     }
7540     do {
7541       prev = i === -1 ? state.tokens.curr : pn;
7542       pn = i === -1 ? state.tokens.next : peek(i);
7543       pn1 = peek(i + 1);
7544       i = i + 1;
7545       if (checkPunctuators(pn, ["[", "{"])) {
7546         bracketStack += 1;
7547       } else if (checkPunctuators(pn, ["]", "}"])) {
7548         bracketStack -= 1;
7549       }
7550       if (bracketStack === 1 && pn.identifier && pn.value === "for" &&
7551           !checkPunctuator(prev, ".")) {
7552         ret.isCompArray = true;
7553         ret.notJson = true;
7554         break;
7555       }
7556       if (bracketStack === 0 && checkPunctuators(pn, ["}", "]"])) {
7557         if (pn1.value === "=") {
7558           ret.isDestAssign = true;
7559           ret.notJson = true;
7560           break;
7561         } else if (pn1.value === ".") {
7562           ret.notJson = true;
7563           break;
7564         }
7565       }
7566       if (checkPunctuator(pn, ";")) {
7567         ret.isBlock = true;
7568         ret.notJson = true;
7569       }
7570     } while (bracketStack > 0 && pn.id !== "(end)");
7571     return ret;
7572   };
7573
7574   function saveProperty(props, name, tkn, isClass, isStatic) {
7575     var msg = ["key", "class method", "static class method"];
7576     msg = msg[(isClass || false) + (isStatic || false)];
7577     if (tkn.identifier) {
7578       name = tkn.value;
7579     }
7580
7581     if (props[name] && name !== "__proto__") {
7582       warning("W075", state.tokens.next, msg, name);
7583     } else {
7584       props[name] = Object.create(null);
7585     }
7586
7587     props[name].basic = true;
7588     props[name].basictkn = tkn;
7589   }
7590   function saveAccessor(accessorType, props, name, tkn, isClass, isStatic) {
7591     var flagName = accessorType === "get" ? "getterToken" : "setterToken";
7592     var msg = "";
7593
7594     if (isClass) {
7595       if (isStatic) {
7596         msg += "static ";
7597       }
7598       msg += accessorType + "ter method";
7599     } else {
7600       msg = "key";
7601     }
7602
7603     state.tokens.curr.accessorType = accessorType;
7604     state.nameStack.set(tkn);
7605
7606     if (props[name]) {
7607       if ((props[name].basic || props[name][flagName]) && name !== "__proto__") {
7608         warning("W075", state.tokens.next, msg, name);
7609       }
7610     } else {
7611       props[name] = Object.create(null);
7612     }
7613
7614     props[name][flagName] = tkn;
7615   }
7616
7617   function computedPropertyName() {
7618     advance("[");
7619     if (!state.inES6()) {
7620       warning("W119", state.tokens.curr, "computed property names", "6");
7621     }
7622     var value = expression(10);
7623     advance("]");
7624     return value;
7625   }
7626   function checkPunctuators(token, values) {
7627     if (token.type === "(punctuator)") {
7628       return _.contains(values, token.value);
7629     }
7630     return false;
7631   }
7632   function checkPunctuator(token, value) {
7633     return token.type === "(punctuator)" && token.value === value;
7634   }
7635   function destructuringAssignOrJsonValue() {
7636
7637     var block = lookupBlockType();
7638     if (block.notJson) {
7639       if (!state.inES6() && block.isDestAssign) {
7640         warning("W104", state.tokens.curr, "destructuring assignment", "6");
7641       }
7642       statements();
7643     } else {
7644       state.option.laxbreak = true;
7645       state.jsonMode = true;
7646       jsonValue();
7647     }
7648   }
7649
7650   var arrayComprehension = function() {
7651     var CompArray = function() {
7652       this.mode = "use";
7653       this.variables = [];
7654     };
7655     var _carrays = [];
7656     var _current;
7657     function declare(v) {
7658       var l = _current.variables.filter(function(elt) {
7659         if (elt.value === v) {
7660           elt.undef = false;
7661           return v;
7662         }
7663       }).length;
7664       return l !== 0;
7665     }
7666     function use(v) {
7667       var l = _current.variables.filter(function(elt) {
7668         if (elt.value === v && !elt.undef) {
7669           if (elt.unused === true) {
7670             elt.unused = false;
7671           }
7672           return v;
7673         }
7674       }).length;
7675       return (l === 0);
7676     }
7677     return { stack: function() {
7678           _current = new CompArray();
7679           _carrays.push(_current);
7680         },
7681         unstack: function() {
7682           _current.variables.filter(function(v) {
7683             if (v.unused)
7684               warning("W098", v.token, v.raw_text || v.value);
7685             if (v.undef)
7686               state.funct["(scope)"].block.use(v.value, v.token);
7687           });
7688           _carrays.splice(-1, 1);
7689           _current = _carrays[_carrays.length - 1];
7690         },
7691         setState: function(s) {
7692           if (_.contains(["use", "define", "generate", "filter"], s))
7693             _current.mode = s;
7694         },
7695         check: function(v) {
7696           if (!_current) {
7697             return;
7698           }
7699           if (_current && _current.mode === "use") {
7700             if (use(v)) {
7701               _current.variables.push({
7702                 funct: state.funct,
7703                 token: state.tokens.curr,
7704                 value: v,
7705                 undef: true,
7706                 unused: false
7707               });
7708             }
7709             return true;
7710           } else if (_current && _current.mode === "define") {
7711             if (!declare(v)) {
7712               _current.variables.push({
7713                 funct: state.funct,
7714                 token: state.tokens.curr,
7715                 value: v,
7716                 undef: false,
7717                 unused: true
7718               });
7719             }
7720             return true;
7721           } else if (_current && _current.mode === "generate") {
7722             state.funct["(scope)"].block.use(v, state.tokens.curr);
7723             return true;
7724           } else if (_current && _current.mode === "filter") {
7725             if (use(v)) {
7726               state.funct["(scope)"].block.use(v, state.tokens.curr);
7727             }
7728             return true;
7729           }
7730           return false;
7731         }
7732         };
7733   };
7734
7735   function jsonValue() {
7736     function jsonObject() {
7737       var o = {}, t = state.tokens.next;
7738       advance("{");
7739       if (state.tokens.next.id !== "}") {
7740         for (;;) {
7741           if (state.tokens.next.id === "(end)") {
7742             error("E026", state.tokens.next, t.line);
7743           } else if (state.tokens.next.id === "}") {
7744             warning("W094", state.tokens.curr);
7745             break;
7746           } else if (state.tokens.next.id === ",") {
7747             error("E028", state.tokens.next);
7748           } else if (state.tokens.next.id !== "(string)") {
7749             warning("W095", state.tokens.next, state.tokens.next.value);
7750           }
7751           if (o[state.tokens.next.value] === true) {
7752             warning("W075", state.tokens.next, "key", state.tokens.next.value);
7753           } else if ((state.tokens.next.value === "__proto__" &&
7754             !state.option.proto) || (state.tokens.next.value === "__iterator__" &&
7755             !state.option.iterator)) {
7756             warning("W096", state.tokens.next, state.tokens.next.value);
7757           } else {
7758             o[state.tokens.next.value] = true;
7759           }
7760           advance();
7761           advance(":");
7762           jsonValue();
7763           if (state.tokens.next.id !== ",") {
7764             break;
7765           }
7766           advance(",");
7767         }
7768       }
7769       advance("}");
7770     }
7771
7772     function jsonArray() {
7773       var t = state.tokens.next;
7774       advance("[");
7775       if (state.tokens.next.id !== "]") {
7776         for (;;) {
7777           if (state.tokens.next.id === "(end)") {
7778             error("E027", state.tokens.next, t.line);
7779           } else if (state.tokens.next.id === "]") {
7780             warning("W094", state.tokens.curr);
7781             break;
7782           } else if (state.tokens.next.id === ",") {
7783             error("E028", state.tokens.next);
7784           }
7785           jsonValue();
7786           if (state.tokens.next.id !== ",") {
7787             break;
7788           }
7789           advance(",");
7790         }
7791       }
7792       advance("]");
7793     }
7794
7795     switch (state.tokens.next.id) {
7796     case "{":
7797       jsonObject();
7798       break;
7799     case "[":
7800       jsonArray();
7801       break;
7802     case "true":
7803     case "false":
7804     case "null":
7805     case "(number)":
7806     case "(string)":
7807       advance();
7808       break;
7809     case "-":
7810       advance("-");
7811       advance("(number)");
7812       break;
7813     default:
7814       error("E003", state.tokens.next);
7815     }
7816   }
7817
7818   var escapeRegex = function(str) {
7819     return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
7820   };
7821   var itself = function(s, o, g) {
7822     var i, k, x, reIgnoreStr, reIgnore;
7823     var optionKeys;
7824     var newOptionObj = {};
7825     var newIgnoredObj = {};
7826
7827     o = _.clone(o);
7828     state.reset();
7829
7830     if (o && o.scope) {
7831       JSHINT.scope = o.scope;
7832     } else {
7833       JSHINT.errors = [];
7834       JSHINT.undefs = [];
7835       JSHINT.internals = [];
7836       JSHINT.blacklist = {};
7837       JSHINT.scope = "(main)";
7838     }
7839
7840     predefined = Object.create(null);
7841     combine(predefined, vars.ecmaIdentifiers[3]);
7842     combine(predefined, vars.reservedVars);
7843
7844     combine(predefined, g || {});
7845
7846     declared = Object.create(null);
7847     var exported = Object.create(null); // Variables that live outside the current file
7848
7849     function each(obj, cb) {
7850       if (!obj)
7851         return;
7852
7853       if (!Array.isArray(obj) && typeof obj === "object")
7854         obj = Object.keys(obj);
7855
7856       obj.forEach(cb);
7857     }
7858
7859     if (o) {
7860       each(o.predef || null, function(item) {
7861         var slice, prop;
7862
7863         if (item[0] === "-") {
7864           slice = item.slice(1);
7865           JSHINT.blacklist[slice] = slice;
7866           delete predefined[slice];
7867         } else {
7868           prop = Object.getOwnPropertyDescriptor(o.predef, item);
7869           predefined[item] = prop ? prop.value : false;
7870         }
7871       });
7872
7873       each(o.exported || null, function(item) {
7874         exported[item] = true;
7875       });
7876
7877       delete o.predef;
7878       delete o.exported;
7879
7880       optionKeys = Object.keys(o);
7881       for (x = 0; x < optionKeys.length; x++) {
7882         if (/^-W\d{3}$/g.test(optionKeys[x])) {
7883           newIgnoredObj[optionKeys[x].slice(1)] = true;
7884         } else {
7885           var optionKey = optionKeys[x];
7886           newOptionObj[optionKey] = o[optionKey];
7887           if ((optionKey === "esversion" && o[optionKey] === 5) ||
7888               (optionKey === "es5" && o[optionKey])) {
7889             warning("I003");
7890           }
7891
7892           if (optionKeys[x] === "newcap" && o[optionKey] === false)
7893             newOptionObj["(explicitNewcap)"] = true;
7894         }
7895       }
7896     }
7897
7898     state.option = newOptionObj;
7899     state.ignored = newIgnoredObj;
7900
7901     state.option.indent = state.option.indent || 4;
7902     state.option.maxerr = state.option.maxerr || 50;
7903
7904     indent = 1;
7905
7906     var scopeManagerInst = scopeManager(state, predefined, exported, declared);
7907     scopeManagerInst.on("warning", function(ev) {
7908       warning.apply(null, [ ev.code, ev.token].concat(ev.data));
7909     });
7910
7911     scopeManagerInst.on("error", function(ev) {
7912       error.apply(null, [ ev.code, ev.token ].concat(ev.data));
7913     });
7914
7915     state.funct = functor("(global)", null, {
7916       "(global)"    : true,
7917       "(scope)"     : scopeManagerInst,
7918       "(comparray)" : arrayComprehension(),
7919       "(metrics)"   : createMetrics(state.tokens.next)
7920     });
7921
7922     functions = [state.funct];
7923     urls = [];
7924     stack = null;
7925     member = {};
7926     membersOnly = null;
7927     inblock = false;
7928     lookahead = [];
7929
7930     if (!isString(s) && !Array.isArray(s)) {
7931       errorAt("E004", 0);
7932       return false;
7933     }
7934
7935     api = {
7936       get isJSON() {
7937         return state.jsonMode;
7938       },
7939
7940       getOption: function(name) {
7941         return state.option[name] || null;
7942       },
7943
7944       getCache: function(name) {
7945         return state.cache[name];
7946       },
7947
7948       setCache: function(name, value) {
7949         state.cache[name] = value;
7950       },
7951
7952       warn: function(code, data) {
7953         warningAt.apply(null, [ code, data.line, data.char ].concat(data.data));
7954       },
7955
7956       on: function(names, listener) {
7957         names.split(" ").forEach(function(name) {
7958           emitter.on(name, listener);
7959         }.bind(this));
7960       }
7961     };
7962
7963     emitter.removeAllListeners();
7964     (extraModules || []).forEach(function(func) {
7965       func(api);
7966     });
7967
7968     state.tokens.prev = state.tokens.curr = state.tokens.next = state.syntax["(begin)"];
7969
7970     if (o && o.ignoreDelimiters) {
7971
7972       if (!Array.isArray(o.ignoreDelimiters)) {
7973         o.ignoreDelimiters = [o.ignoreDelimiters];
7974       }
7975
7976       o.ignoreDelimiters.forEach(function(delimiterPair) {
7977         if (!delimiterPair.start || !delimiterPair.end)
7978             return;
7979
7980         reIgnoreStr = escapeRegex(delimiterPair.start) +
7981                       "[\\s\\S]*?" +
7982                       escapeRegex(delimiterPair.end);
7983
7984         reIgnore = new RegExp(reIgnoreStr, "ig");
7985
7986         s = s.replace(reIgnore, function(match) {
7987           return match.replace(/./g, " ");
7988         });
7989       });
7990     }
7991
7992     lex = new Lexer(s);
7993
7994     lex.on("warning", function(ev) {
7995       warningAt.apply(null, [ ev.code, ev.line, ev.character].concat(ev.data));
7996     });
7997
7998     lex.on("error", function(ev) {
7999       errorAt.apply(null, [ ev.code, ev.line, ev.character ].concat(ev.data));
8000     });
8001
8002     lex.on("fatal", function(ev) {
8003       quit("E041", ev.line, ev.from);
8004     });
8005
8006     lex.on("Identifier", function(ev) {
8007       emitter.emit("Identifier", ev);
8008     });
8009
8010     lex.on("String", function(ev) {
8011       emitter.emit("String", ev);
8012     });
8013
8014     lex.on("Number", function(ev) {
8015       emitter.emit("Number", ev);
8016     });
8017
8018     lex.start();
8019     for (var name in o) {
8020       if (_.has(o, name)) {
8021         checkOption(name, state.tokens.curr);
8022       }
8023     }
8024
8025     assume();
8026     combine(predefined, g || {});
8027     comma.first = true;
8028
8029     try {
8030       advance();
8031       switch (state.tokens.next.id) {
8032       case "{":
8033       case "[":
8034         destructuringAssignOrJsonValue();
8035         break;
8036       default:
8037         directives();
8038
8039         if (state.directive["use strict"]) {
8040           if (state.option.strict !== "global") {
8041             warning("W097", state.tokens.prev);
8042           }
8043         }
8044
8045         statements();
8046       }
8047
8048       if (state.tokens.next.id !== "(end)") {
8049         quit("E041", state.tokens.curr.line);
8050       }
8051
8052       state.funct["(scope)"].unstack();
8053
8054     } catch (err) {
8055       if (err && err.name === "JSHintError") {
8056         var nt = state.tokens.next || {};
8057         JSHINT.errors.push({
8058           scope     : "(main)",
8059           raw       : err.raw,
8060           code      : err.code,
8061           reason    : err.message,
8062           line      : err.line || nt.line,
8063           character : err.character || nt.from
8064         }, null);
8065       } else {
8066         throw err;
8067       }
8068     }
8069
8070     if (JSHINT.scope === "(main)") {
8071       o = o || {};
8072
8073       for (i = 0; i < JSHINT.internals.length; i += 1) {
8074         k = JSHINT.internals[i];
8075         o.scope = k.elem;
8076         itself(k.value, o, g);
8077       }
8078     }
8079
8080     return JSHINT.errors.length === 0;
8081   };
8082   itself.addModule = function(func) {
8083     extraModules.push(func);
8084   };
8085
8086   itself.addModule(style.register);
8087   itself.data = function() {
8088     var data = {
8089       functions: [],
8090       options: state.option
8091     };
8092
8093     var fu, f, i, j, n, globals;
8094
8095     if (itself.errors.length) {
8096       data.errors = itself.errors;
8097     }
8098
8099     if (state.jsonMode) {
8100       data.json = true;
8101     }
8102
8103     var impliedGlobals = state.funct["(scope)"].getImpliedGlobals();
8104     if (impliedGlobals.length > 0) {
8105       data.implieds = impliedGlobals;
8106     }
8107
8108     if (urls.length > 0) {
8109       data.urls = urls;
8110     }
8111
8112     globals = state.funct["(scope)"].getUsedOrDefinedGlobals();
8113     if (globals.length > 0) {
8114       data.globals = globals;
8115     }
8116
8117     for (i = 1; i < functions.length; i += 1) {
8118       f = functions[i];
8119       fu = {};
8120
8121       for (j = 0; j < functionicity.length; j += 1) {
8122         fu[functionicity[j]] = [];
8123       }
8124
8125       for (j = 0; j < functionicity.length; j += 1) {
8126         if (fu[functionicity[j]].length === 0) {
8127           delete fu[functionicity[j]];
8128         }
8129       }
8130
8131       fu.name = f["(name)"];
8132       fu.param = f["(params)"];
8133       fu.line = f["(line)"];
8134       fu.character = f["(character)"];
8135       fu.last = f["(last)"];
8136       fu.lastcharacter = f["(lastcharacter)"];
8137
8138       fu.metrics = {
8139         complexity: f["(metrics)"].ComplexityCount,
8140         parameters: f["(metrics)"].arity,
8141         statements: f["(metrics)"].statementCount
8142       };
8143
8144       data.functions.push(fu);
8145     }
8146
8147     var unuseds = state.funct["(scope)"].getUnuseds();
8148     if (unuseds.length > 0) {
8149       data.unused = unuseds;
8150     }
8151
8152     for (n in member) {
8153       if (typeof member[n] === "number") {
8154         data.member = member;
8155         break;
8156       }
8157     }
8158
8159     return data;
8160   };
8161
8162   itself.jshint = itself;
8163
8164   return itself;
8165 }());
8166 if (typeof exports === "object" && exports) {
8167   exports.JSHINT = JSHINT;
8168 }
8169
8170 },{"../lodash":"/node_modules/jshint/lodash.js","./lex.js":"/node_modules/jshint/src/lex.js","./messages.js":"/node_modules/jshint/src/messages.js","./options.js":"/node_modules/jshint/src/options.js","./reg.js":"/node_modules/jshint/src/reg.js","./scope-manager.js":"/node_modules/jshint/src/scope-manager.js","./state.js":"/node_modules/jshint/src/state.js","./style.js":"/node_modules/jshint/src/style.js","./vars.js":"/node_modules/jshint/src/vars.js","events":"/node_modules/browserify/node_modules/events/events.js"}],"/node_modules/jshint/src/lex.js":[function(_dereq_,module,exports){
8171
8172 "use strict";
8173
8174 var _      = _dereq_("../lodash");
8175 var events = _dereq_("events");
8176 var reg    = _dereq_("./reg.js");
8177 var state  = _dereq_("./state.js").state;
8178
8179 var unicodeData = _dereq_("../data/ascii-identifier-data.js");
8180 var asciiIdentifierStartTable = unicodeData.asciiIdentifierStartTable;
8181 var asciiIdentifierPartTable = unicodeData.asciiIdentifierPartTable;
8182
8183 var Token = {
8184   Identifier: 1,
8185   Punctuator: 2,
8186   NumericLiteral: 3,
8187   StringLiteral: 4,
8188   Comment: 5,
8189   Keyword: 6,
8190   NullLiteral: 7,
8191   BooleanLiteral: 8,
8192   RegExp: 9,
8193   TemplateHead: 10,
8194   TemplateMiddle: 11,
8195   TemplateTail: 12,
8196   NoSubstTemplate: 13
8197 };
8198
8199 var Context = {
8200   Block: 1,
8201   Template: 2
8202 };
8203
8204 function asyncTrigger() {
8205   var _checks = [];
8206
8207   return {
8208     push: function(fn) {
8209       _checks.push(fn);
8210     },
8211
8212     check: function() {
8213       for (var check = 0; check < _checks.length; ++check) {
8214         _checks[check]();
8215       }
8216
8217       _checks.splice(0, _checks.length);
8218     }
8219   };
8220 }
8221 function Lexer(source) {
8222   var lines = source;
8223
8224   if (typeof lines === "string") {
8225     lines = lines
8226       .replace(/\r\n/g, "\n")
8227       .replace(/\r/g, "\n")
8228       .split("\n");
8229   }
8230
8231   if (lines[0] && lines[0].substr(0, 2) === "#!") {
8232     if (lines[0].indexOf("node") !== -1) {
8233       state.option.node = true;
8234     }
8235     lines[0] = "";
8236   }
8237
8238   this.emitter = new events.EventEmitter();
8239   this.source = source;
8240   this.setLines(lines);
8241   this.prereg = true;
8242
8243   this.line = 0;
8244   this.char = 1;
8245   this.from = 1;
8246   this.input = "";
8247   this.inComment = false;
8248   this.context = [];
8249   this.templateStarts = [];
8250
8251   for (var i = 0; i < state.option.indent; i += 1) {
8252     state.tab += " ";
8253   }
8254   this.ignoreLinterErrors = false;
8255 }
8256
8257 Lexer.prototype = {
8258   _lines: [],
8259
8260   inContext: function(ctxType) {
8261     return this.context.length > 0 && this.context[this.context.length - 1].type === ctxType;
8262   },
8263
8264   pushContext: function(ctxType) {
8265     this.context.push({ type: ctxType });
8266   },
8267
8268   popContext: function() {
8269     return this.context.pop();
8270   },
8271
8272   isContext: function(context) {
8273     return this.context.length > 0 && this.context[this.context.length - 1] === context;
8274   },
8275
8276   currentContext: function() {
8277     return this.context.length > 0 && this.context[this.context.length - 1];
8278   },
8279
8280   getLines: function() {
8281     this._lines = state.lines;
8282     return this._lines;
8283   },
8284
8285   setLines: function(val) {
8286     this._lines = val;
8287     state.lines = this._lines;
8288   },
8289   peek: function(i) {
8290     return this.input.charAt(i || 0);
8291   },
8292   skip: function(i) {
8293     i = i || 1;
8294     this.char += i;
8295     this.input = this.input.slice(i);
8296   },
8297   on: function(names, listener) {
8298     names.split(" ").forEach(function(name) {
8299       this.emitter.on(name, listener);
8300     }.bind(this));
8301   },
8302   trigger: function() {
8303     this.emitter.emit.apply(this.emitter, Array.prototype.slice.call(arguments));
8304   },
8305   triggerAsync: function(type, args, checks, fn) {
8306     checks.push(function() {
8307       if (fn()) {
8308         this.trigger(type, args);
8309       }
8310     }.bind(this));
8311   },
8312   scanPunctuator: function() {
8313     var ch1 = this.peek();
8314     var ch2, ch3, ch4;
8315
8316     switch (ch1) {
8317     case ".":
8318       if ((/^[0-9]$/).test(this.peek(1))) {
8319         return null;
8320       }
8321       if (this.peek(1) === "." && this.peek(2) === ".") {
8322         return {
8323           type: Token.Punctuator,
8324           value: "..."
8325         };
8326       }
8327     case "(":
8328     case ")":
8329     case ";":
8330     case ",":
8331     case "[":
8332     case "]":
8333     case ":":
8334     case "~":
8335     case "?":
8336       return {
8337         type: Token.Punctuator,
8338         value: ch1
8339       };
8340     case "{":
8341       this.pushContext(Context.Block);
8342       return {
8343         type: Token.Punctuator,
8344         value: ch1
8345       };
8346     case "}":
8347       if (this.inContext(Context.Block)) {
8348         this.popContext();
8349       }
8350       return {
8351         type: Token.Punctuator,
8352         value: ch1
8353       };
8354     case "#":
8355       return {
8356         type: Token.Punctuator,
8357         value: ch1
8358       };
8359     case "":
8360       return null;
8361     }
8362
8363     ch2 = this.peek(1);
8364     ch3 = this.peek(2);
8365     ch4 = this.peek(3);
8366
8367     if (ch1 === ">" && ch2 === ">" && ch3 === ">" && ch4 === "=") {
8368       return {
8369         type: Token.Punctuator,
8370         value: ">>>="
8371       };
8372     }
8373
8374     if (ch1 === "=" && ch2 === "=" && ch3 === "=") {
8375       return {
8376         type: Token.Punctuator,
8377         value: "==="
8378       };
8379     }
8380
8381     if (ch1 === "!" && ch2 === "=" && ch3 === "=") {
8382       return {
8383         type: Token.Punctuator,
8384         value: "!=="
8385       };
8386     }
8387
8388     if (ch1 === ">" && ch2 === ">" && ch3 === ">") {
8389       return {
8390         type: Token.Punctuator,
8391         value: ">>>"
8392       };
8393     }
8394
8395     if (ch1 === "<" && ch2 === "<" && ch3 === "=") {
8396       return {
8397         type: Token.Punctuator,
8398         value: "<<="
8399       };
8400     }
8401
8402     if (ch1 === ">" && ch2 === ">" && ch3 === "=") {
8403       return {
8404         type: Token.Punctuator,
8405         value: ">>="
8406       };
8407     }
8408     if (ch1 === "=" && ch2 === ">") {
8409       return {
8410         type: Token.Punctuator,
8411         value: ch1 + ch2
8412       };
8413     }
8414     if (ch1 === ch2 && ("+-<>&|".indexOf(ch1) >= 0)) {
8415       return {
8416         type: Token.Punctuator,
8417         value: ch1 + ch2
8418       };
8419     }
8420
8421     if ("<>=!+-*%&|^".indexOf(ch1) >= 0) {
8422       if (ch2 === "=") {
8423         return {
8424           type: Token.Punctuator,
8425           value: ch1 + ch2
8426         };
8427       }
8428
8429       return {
8430         type: Token.Punctuator,
8431         value: ch1
8432       };
8433     }
8434
8435     if (ch1 === "/") {
8436       if (ch2 === "=") {
8437         return {
8438           type: Token.Punctuator,
8439           value: "/="
8440         };
8441       }
8442
8443       return {
8444         type: Token.Punctuator,
8445         value: "/"
8446       };
8447     }
8448
8449     return null;
8450   },
8451   scanComments: function() {
8452     var ch1 = this.peek();
8453     var ch2 = this.peek(1);
8454     var rest = this.input.substr(2);
8455     var startLine = this.line;
8456     var startChar = this.char;
8457     var self = this;
8458
8459     function commentToken(label, body, opt) {
8460       var special = ["jshint", "jslint", "members", "member", "globals", "global", "exported"];
8461       var isSpecial = false;
8462       var value = label + body;
8463       var commentType = "plain";
8464       opt = opt || {};
8465
8466       if (opt.isMultiline) {
8467         value += "*/";
8468       }
8469
8470       body = body.replace(/\n/g, " ");
8471
8472       if (label === "/*" && reg.fallsThrough.test(body)) {
8473         isSpecial = true;
8474         commentType = "falls through";
8475       }
8476
8477       special.forEach(function(str) {
8478         if (isSpecial) {
8479           return;
8480         }
8481         if (label === "//" && str !== "jshint") {
8482           return;
8483         }
8484
8485         if (body.charAt(str.length) === " " && body.substr(0, str.length) === str) {
8486           isSpecial = true;
8487           label = label + str;
8488           body = body.substr(str.length);
8489         }
8490
8491         if (!isSpecial && body.charAt(0) === " " && body.charAt(str.length + 1) === " " &&
8492           body.substr(1, str.length) === str) {
8493           isSpecial = true;
8494           label = label + " " + str;
8495           body = body.substr(str.length + 1);
8496         }
8497
8498         if (!isSpecial) {
8499           return;
8500         }
8501
8502         switch (str) {
8503         case "member":
8504           commentType = "members";
8505           break;
8506         case "global":
8507           commentType = "globals";
8508           break;
8509         default:
8510           var options = body.split(":").map(function(v) {
8511             return v.replace(/^\s+/, "").replace(/\s+$/, "");
8512           });
8513
8514           if (options.length === 2) {
8515             switch (options[0]) {
8516             case "ignore":
8517               switch (options[1]) {
8518               case "start":
8519                 self.ignoringLinterErrors = true;
8520                 isSpecial = false;
8521                 break;
8522               case "end":
8523                 self.ignoringLinterErrors = false;
8524                 isSpecial = false;
8525                 break;
8526               }
8527             }
8528           }
8529
8530           commentType = str;
8531         }
8532       });
8533
8534       return {
8535         type: Token.Comment,
8536         commentType: commentType,
8537         value: value,
8538         body: body,
8539         isSpecial: isSpecial,
8540         isMultiline: opt.isMultiline || false,
8541         isMalformed: opt.isMalformed || false
8542       };
8543     }
8544     if (ch1 === "*" && ch2 === "/") {
8545       this.trigger("error", {
8546         code: "E018",
8547         line: startLine,
8548         character: startChar
8549       });
8550
8551       this.skip(2);
8552       return null;
8553     }
8554     if (ch1 !== "/" || (ch2 !== "*" && ch2 !== "/")) {
8555       return null;
8556     }
8557     if (ch2 === "/") {
8558       this.skip(this.input.length); // Skip to the EOL.
8559       return commentToken("//", rest);
8560     }
8561
8562     var body = "";
8563     if (ch2 === "*") {
8564       this.inComment = true;
8565       this.skip(2);
8566
8567       while (this.peek() !== "*" || this.peek(1) !== "/") {
8568         if (this.peek() === "") { // End of Line
8569           body += "\n";
8570           if (!this.nextLine()) {
8571             this.trigger("error", {
8572               code: "E017",
8573               line: startLine,
8574               character: startChar
8575             });
8576
8577             this.inComment = false;
8578             return commentToken("/*", body, {
8579               isMultiline: true,
8580               isMalformed: true
8581             });
8582           }
8583         } else {
8584           body += this.peek();
8585           this.skip();
8586         }
8587       }
8588
8589       this.skip(2);
8590       this.inComment = false;
8591       return commentToken("/*", body, { isMultiline: true });
8592     }
8593   },
8594   scanKeyword: function() {
8595     var result = /^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input);
8596     var keywords = [
8597       "if", "in", "do", "var", "for", "new",
8598       "try", "let", "this", "else", "case",
8599       "void", "with", "enum", "while", "break",
8600       "catch", "throw", "const", "yield", "class",
8601       "super", "return", "typeof", "delete",
8602       "switch", "export", "import", "default",
8603       "finally", "extends", "function", "continue",
8604       "debugger", "instanceof"
8605     ];
8606
8607     if (result && keywords.indexOf(result[0]) >= 0) {
8608       return {
8609         type: Token.Keyword,
8610         value: result[0]
8611       };
8612     }
8613
8614     return null;
8615   },
8616   scanIdentifier: function() {
8617     var id = "";
8618     var index = 0;
8619     var type, char;
8620
8621     function isNonAsciiIdentifierStart(code) {
8622       return code > 256;
8623     }
8624
8625     function isNonAsciiIdentifierPart(code) {
8626       return code > 256;
8627     }
8628
8629     function isHexDigit(str) {
8630       return (/^[0-9a-fA-F]$/).test(str);
8631     }
8632
8633     var readUnicodeEscapeSequence = function() {
8634       index += 1;
8635
8636       if (this.peek(index) !== "u") {
8637         return null;
8638       }
8639
8640       var ch1 = this.peek(index + 1);
8641       var ch2 = this.peek(index + 2);
8642       var ch3 = this.peek(index + 3);
8643       var ch4 = this.peek(index + 4);
8644       var code;
8645
8646       if (isHexDigit(ch1) && isHexDigit(ch2) && isHexDigit(ch3) && isHexDigit(ch4)) {
8647         code = parseInt(ch1 + ch2 + ch3 + ch4, 16);
8648
8649         if (asciiIdentifierPartTable[code] || isNonAsciiIdentifierPart(code)) {
8650           index += 5;
8651           return "\\u" + ch1 + ch2 + ch3 + ch4;
8652         }
8653
8654         return null;
8655       }
8656
8657       return null;
8658     }.bind(this);
8659
8660     var getIdentifierStart = function() {
8661       var chr = this.peek(index);
8662       var code = chr.charCodeAt(0);
8663
8664       if (code === 92) {
8665         return readUnicodeEscapeSequence();
8666       }
8667
8668       if (code < 128) {
8669         if (asciiIdentifierStartTable[code]) {
8670           index += 1;
8671           return chr;
8672         }
8673
8674         return null;
8675       }
8676
8677       if (isNonAsciiIdentifierStart(code)) {
8678         index += 1;
8679         return chr;
8680       }
8681
8682       return null;
8683     }.bind(this);
8684
8685     var getIdentifierPart = function() {
8686       var chr = this.peek(index);
8687       var code = chr.charCodeAt(0);
8688
8689       if (code === 92) {
8690         return readUnicodeEscapeSequence();
8691       }
8692
8693       if (code < 128) {
8694         if (asciiIdentifierPartTable[code]) {
8695           index += 1;
8696           return chr;
8697         }
8698
8699         return null;
8700       }
8701
8702       if (isNonAsciiIdentifierPart(code)) {
8703         index += 1;
8704         return chr;
8705       }
8706
8707       return null;
8708     }.bind(this);
8709
8710     function removeEscapeSequences(id) {
8711       return id.replace(/\\u([0-9a-fA-F]{4})/g, function(m0, codepoint) {
8712         return String.fromCharCode(parseInt(codepoint, 16));
8713       });
8714     }
8715
8716     char = getIdentifierStart();
8717     if (char === null) {
8718       return null;
8719     }
8720
8721     id = char;
8722     for (;;) {
8723       char = getIdentifierPart();
8724
8725       if (char === null) {
8726         break;
8727       }
8728
8729       id += char;
8730     }
8731
8732     switch (id) {
8733     case "true":
8734     case "false":
8735       type = Token.BooleanLiteral;
8736       break;
8737     case "null":
8738       type = Token.NullLiteral;
8739       break;
8740     default:
8741       type = Token.Identifier;
8742     }
8743
8744     return {
8745       type: type,
8746       value: removeEscapeSequences(id),
8747       text: id,
8748       tokenLength: id.length
8749     };
8750   },
8751   scanNumericLiteral: function() {
8752     var index = 0;
8753     var value = "";
8754     var length = this.input.length;
8755     var char = this.peek(index);
8756     var bad;
8757     var isAllowedDigit = isDecimalDigit;
8758     var base = 10;
8759     var isLegacy = false;
8760
8761     function isDecimalDigit(str) {
8762       return (/^[0-9]$/).test(str);
8763     }
8764
8765     function isOctalDigit(str) {
8766       return (/^[0-7]$/).test(str);
8767     }
8768
8769     function isBinaryDigit(str) {
8770       return (/^[01]$/).test(str);
8771     }
8772
8773     function isHexDigit(str) {
8774       return (/^[0-9a-fA-F]$/).test(str);
8775     }
8776
8777     function isIdentifierStart(ch) {
8778       return (ch === "$") || (ch === "_") || (ch === "\\") ||
8779         (ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z");
8780     }
8781
8782     if (char !== "." && !isDecimalDigit(char)) {
8783       return null;
8784     }
8785
8786     if (char !== ".") {
8787       value = this.peek(index);
8788       index += 1;
8789       char = this.peek(index);
8790
8791       if (value === "0") {
8792         if (char === "x" || char === "X") {
8793           isAllowedDigit = isHexDigit;
8794           base = 16;
8795
8796           index += 1;
8797           value += char;
8798         }
8799         if (char === "o" || char === "O") {
8800           isAllowedDigit = isOctalDigit;
8801           base = 8;
8802
8803           if (!state.inES6(true)) {
8804             this.trigger("warning", {
8805               code: "W119",
8806               line: this.line,
8807               character: this.char,
8808               data: [ "Octal integer literal", "6" ]
8809             });
8810           }
8811
8812           index += 1;
8813           value += char;
8814         }
8815         if (char === "b" || char === "B") {
8816           isAllowedDigit = isBinaryDigit;
8817           base = 2;
8818
8819           if (!state.inES6(true)) {
8820             this.trigger("warning", {
8821               code: "W119",
8822               line: this.line,
8823               character: this.char,
8824               data: [ "Binary integer literal", "6" ]
8825             });
8826           }
8827
8828           index += 1;
8829           value += char;
8830         }
8831         if (isOctalDigit(char)) {
8832           isAllowedDigit = isOctalDigit;
8833           base = 8;
8834           isLegacy = true;
8835           bad = false;
8836
8837           index += 1;
8838           value += char;
8839         }
8840
8841         if (!isOctalDigit(char) && isDecimalDigit(char)) {
8842           index += 1;
8843           value += char;
8844         }
8845       }
8846
8847       while (index < length) {
8848         char = this.peek(index);
8849
8850         if (isLegacy && isDecimalDigit(char)) {
8851           bad = true;
8852         } else if (!isAllowedDigit(char)) {
8853           break;
8854         }
8855         value += char;
8856         index += 1;
8857       }
8858
8859       if (isAllowedDigit !== isDecimalDigit) {
8860         if (!isLegacy && value.length <= 2) { // 0x
8861           return {
8862             type: Token.NumericLiteral,
8863             value: value,
8864             isMalformed: true
8865           };
8866         }
8867
8868         if (index < length) {
8869           char = this.peek(index);
8870           if (isIdentifierStart(char)) {
8871             return null;
8872           }
8873         }
8874
8875         return {
8876           type: Token.NumericLiteral,
8877           value: value,
8878           base: base,
8879           isLegacy: isLegacy,
8880           isMalformed: false
8881         };
8882       }
8883     }
8884
8885     if (char === ".") {
8886       value += char;
8887       index += 1;
8888
8889       while (index < length) {
8890         char = this.peek(index);
8891         if (!isDecimalDigit(char)) {
8892           break;
8893         }
8894         value += char;
8895         index += 1;
8896       }
8897     }
8898
8899     if (char === "e" || char === "E") {
8900       value += char;
8901       index += 1;
8902       char = this.peek(index);
8903
8904       if (char === "+" || char === "-") {
8905         value += this.peek(index);
8906         index += 1;
8907       }
8908
8909       char = this.peek(index);
8910       if (isDecimalDigit(char)) {
8911         value += char;
8912         index += 1;
8913
8914         while (index < length) {
8915           char = this.peek(index);
8916           if (!isDecimalDigit(char)) {
8917             break;
8918           }
8919           value += char;
8920           index += 1;
8921         }
8922       } else {
8923         return null;
8924       }
8925     }
8926
8927     if (index < length) {
8928       char = this.peek(index);
8929       if (isIdentifierStart(char)) {
8930         return null;
8931       }
8932     }
8933
8934     return {
8935       type: Token.NumericLiteral,
8936       value: value,
8937       base: base,
8938       isMalformed: !isFinite(value)
8939     };
8940   },
8941   scanEscapeSequence: function(checks) {
8942     var allowNewLine = false;
8943     var jump = 1;
8944     this.skip();
8945     var char = this.peek();
8946
8947     switch (char) {
8948     case "'":
8949       this.triggerAsync("warning", {
8950         code: "W114",
8951         line: this.line,
8952         character: this.char,
8953         data: [ "\\'" ]
8954       }, checks, function() {return state.jsonMode; });
8955       break;
8956     case "b":
8957       char = "\\b";
8958       break;
8959     case "f":
8960       char = "\\f";
8961       break;
8962     case "n":
8963       char = "\\n";
8964       break;
8965     case "r":
8966       char = "\\r";
8967       break;
8968     case "t":
8969       char = "\\t";
8970       break;
8971     case "0":
8972       char = "\\0";
8973       var n = parseInt(this.peek(1), 10);
8974       this.triggerAsync("warning", {
8975         code: "W115",
8976         line: this.line,
8977         character: this.char
8978       }, checks,
8979       function() { return n >= 0 && n <= 7 && state.isStrict(); });
8980       break;
8981     case "u":
8982       var hexCode = this.input.substr(1, 4);
8983       var code = parseInt(hexCode, 16);
8984       if (isNaN(code)) {
8985         this.trigger("warning", {
8986           code: "W052",
8987           line: this.line,
8988           character: this.char,
8989           data: [ "u" + hexCode ]
8990         });
8991       }
8992       char = String.fromCharCode(code);
8993       jump = 5;
8994       break;
8995     case "v":
8996       this.triggerAsync("warning", {
8997         code: "W114",
8998         line: this.line,
8999         character: this.char,
9000         data: [ "\\v" ]
9001       }, checks, function() { return state.jsonMode; });
9002
9003       char = "\v";
9004       break;
9005     case "x":
9006       var  x = parseInt(this.input.substr(1, 2), 16);
9007
9008       this.triggerAsync("warning", {
9009         code: "W114",
9010         line: this.line,
9011         character: this.char,
9012         data: [ "\\x-" ]
9013       }, checks, function() { return state.jsonMode; });
9014
9015       char = String.fromCharCode(x);
9016       jump = 3;
9017       break;
9018     case "\\":
9019       char = "\\\\";
9020       break;
9021     case "\"":
9022       char = "\\\"";
9023       break;
9024     case "/":
9025       break;
9026     case "":
9027       allowNewLine = true;
9028       char = "";
9029       break;
9030     }
9031
9032     return { char: char, jump: jump, allowNewLine: allowNewLine };
9033   },
9034   scanTemplateLiteral: function(checks) {
9035     var tokenType;
9036     var value = "";
9037     var ch;
9038     var startLine = this.line;
9039     var startChar = this.char;
9040     var depth = this.templateStarts.length;
9041
9042     if (!state.inES6(true)) {
9043       return null;
9044     } else if (this.peek() === "`") {
9045       tokenType = Token.TemplateHead;
9046       this.templateStarts.push({ line: this.line, char: this.char });
9047       depth = this.templateStarts.length;
9048       this.skip(1);
9049       this.pushContext(Context.Template);
9050     } else if (this.inContext(Context.Template) && this.peek() === "}") {
9051       tokenType = Token.TemplateMiddle;
9052     } else {
9053       return null;
9054     }
9055
9056     while (this.peek() !== "`") {
9057       while ((ch = this.peek()) === "") {
9058         value += "\n";
9059         if (!this.nextLine()) {
9060           var startPos = this.templateStarts.pop();
9061           this.trigger("error", {
9062             code: "E052",
9063             line: startPos.line,
9064             character: startPos.char
9065           });
9066           return {
9067             type: tokenType,
9068             value: value,
9069             startLine: startLine,
9070             startChar: startChar,
9071             isUnclosed: true,
9072             depth: depth,
9073             context: this.popContext()
9074           };
9075         }
9076       }
9077
9078       if (ch === '$' && this.peek(1) === '{') {
9079         value += '${';
9080         this.skip(2);
9081         return {
9082           type: tokenType,
9083           value: value,
9084           startLine: startLine,
9085           startChar: startChar,
9086           isUnclosed: false,
9087           depth: depth,
9088           context: this.currentContext()
9089         };
9090       } else if (ch === '\\') {
9091         var escape = this.scanEscapeSequence(checks);
9092         value += escape.char;
9093         this.skip(escape.jump);
9094       } else if (ch !== '`') {
9095         value += ch;
9096         this.skip(1);
9097       }
9098     }
9099     tokenType = tokenType === Token.TemplateHead ? Token.NoSubstTemplate : Token.TemplateTail;
9100     this.skip(1);
9101     this.templateStarts.pop();
9102
9103     return {
9104       type: tokenType,
9105       value: value,
9106       startLine: startLine,
9107       startChar: startChar,
9108       isUnclosed: false,
9109       depth: depth,
9110       context: this.popContext()
9111     };
9112   },
9113   scanStringLiteral: function(checks) {
9114     var quote = this.peek();
9115     if (quote !== "\"" && quote !== "'") {
9116       return null;
9117     }
9118     this.triggerAsync("warning", {
9119       code: "W108",
9120       line: this.line,
9121       character: this.char // +1?
9122     }, checks, function() { return state.jsonMode && quote !== "\""; });
9123
9124     var value = "";
9125     var startLine = this.line;
9126     var startChar = this.char;
9127     var allowNewLine = false;
9128
9129     this.skip();
9130
9131     while (this.peek() !== quote) {
9132       if (this.peek() === "") { // End Of Line
9133
9134         if (!allowNewLine) {
9135           this.trigger("warning", {
9136             code: "W112",
9137             line: this.line,
9138             character: this.char
9139           });
9140         } else {
9141           allowNewLine = false;
9142
9143           this.triggerAsync("warning", {
9144             code: "W043",
9145             line: this.line,
9146             character: this.char
9147           }, checks, function() { return !state.option.multistr; });
9148
9149           this.triggerAsync("warning", {
9150             code: "W042",
9151             line: this.line,
9152             character: this.char
9153           }, checks, function() { return state.jsonMode && state.option.multistr; });
9154         }
9155
9156         if (!this.nextLine()) {
9157           this.trigger("error", {
9158             code: "E029",
9159             line: startLine,
9160             character: startChar
9161           });
9162
9163           return {
9164             type: Token.StringLiteral,
9165             value: value,
9166             startLine: startLine,
9167             startChar: startChar,
9168             isUnclosed: true,
9169             quote: quote
9170           };
9171         }
9172
9173       } else { // Any character other than End Of Line
9174
9175         allowNewLine = false;
9176         var char = this.peek();
9177         var jump = 1; // A length of a jump, after we're done
9178
9179         if (char < " ") {
9180           this.trigger("warning", {
9181             code: "W113",
9182             line: this.line,
9183             character: this.char,
9184             data: [ "<non-printable>" ]
9185           });
9186         }
9187         if (char === "\\") {
9188           var parsed = this.scanEscapeSequence(checks);
9189           char = parsed.char;
9190           jump = parsed.jump;
9191           allowNewLine = parsed.allowNewLine;
9192         }
9193
9194         value += char;
9195         this.skip(jump);
9196       }
9197     }
9198
9199     this.skip();
9200     return {
9201       type: Token.StringLiteral,
9202       value: value,
9203       startLine: startLine,
9204       startChar: startChar,
9205       isUnclosed: false,
9206       quote: quote
9207     };
9208   },
9209   scanRegExp: function() {
9210     var index = 0;
9211     var length = this.input.length;
9212     var char = this.peek();
9213     var value = char;
9214     var body = "";
9215     var flags = [];
9216     var malformed = false;
9217     var isCharSet = false;
9218     var terminated;
9219
9220     var scanUnexpectedChars = function() {
9221       if (char < " ") {
9222         malformed = true;
9223         this.trigger("warning", {
9224           code: "W048",
9225           line: this.line,
9226           character: this.char
9227         });
9228       }
9229       if (char === "<") {
9230         malformed = true;
9231         this.trigger("warning", {
9232           code: "W049",
9233           line: this.line,
9234           character: this.char,
9235           data: [ char ]
9236         });
9237       }
9238     }.bind(this);
9239     if (!this.prereg || char !== "/") {
9240       return null;
9241     }
9242
9243     index += 1;
9244     terminated = false;
9245
9246     while (index < length) {
9247       char = this.peek(index);
9248       value += char;
9249       body += char;
9250
9251       if (isCharSet) {
9252         if (char === "]") {
9253           if (this.peek(index - 1) !== "\\" || this.peek(index - 2) === "\\") {
9254             isCharSet = false;
9255           }
9256         }
9257
9258         if (char === "\\") {
9259           index += 1;
9260           char = this.peek(index);
9261           body += char;
9262           value += char;
9263
9264           scanUnexpectedChars();
9265         }
9266
9267         index += 1;
9268         continue;
9269       }
9270
9271       if (char === "\\") {
9272         index += 1;
9273         char = this.peek(index);
9274         body += char;
9275         value += char;
9276
9277         scanUnexpectedChars();
9278
9279         if (char === "/") {
9280           index += 1;
9281           continue;
9282         }
9283
9284         if (char === "[") {
9285           index += 1;
9286           continue;
9287         }
9288       }
9289
9290       if (char === "[") {
9291         isCharSet = true;
9292         index += 1;
9293         continue;
9294       }
9295
9296       if (char === "/") {
9297         body = body.substr(0, body.length - 1);
9298         terminated = true;
9299         index += 1;
9300         break;
9301       }
9302
9303       index += 1;
9304     }
9305
9306     if (!terminated) {
9307       this.trigger("error", {
9308         code: "E015",
9309         line: this.line,
9310         character: this.from
9311       });
9312
9313       return void this.trigger("fatal", {
9314         line: this.line,
9315         from: this.from
9316       });
9317     }
9318
9319     while (index < length) {
9320       char = this.peek(index);
9321       if (!/[gim]/.test(char)) {
9322         break;
9323       }
9324       flags.push(char);
9325       value += char;
9326       index += 1;
9327     }
9328
9329     try {
9330       new RegExp(body, flags.join(""));
9331     } catch (err) {
9332       malformed = true;
9333       this.trigger("error", {
9334         code: "E016",
9335         line: this.line,
9336         character: this.char,
9337         data: [ err.message ] // Platform dependent!
9338       });
9339     }
9340
9341     return {
9342       type: Token.RegExp,
9343       value: value,
9344       flags: flags,
9345       isMalformed: malformed
9346     };
9347   },
9348   scanNonBreakingSpaces: function() {
9349     return state.option.nonbsp ?
9350       this.input.search(/(\u00A0)/) : -1;
9351   },
9352   scanUnsafeChars: function() {
9353     return this.input.search(reg.unsafeChars);
9354   },
9355   next: function(checks) {
9356     this.from = this.char;
9357     var start;
9358     if (/\s/.test(this.peek())) {
9359       start = this.char;
9360
9361       while (/\s/.test(this.peek())) {
9362         this.from += 1;
9363         this.skip();
9364       }
9365     }
9366
9367     var match = this.scanComments() ||
9368       this.scanStringLiteral(checks) ||
9369       this.scanTemplateLiteral(checks);
9370
9371     if (match) {
9372       return match;
9373     }
9374
9375     match =
9376       this.scanRegExp() ||
9377       this.scanPunctuator() ||
9378       this.scanKeyword() ||
9379       this.scanIdentifier() ||
9380       this.scanNumericLiteral();
9381
9382     if (match) {
9383       this.skip(match.tokenLength || match.value.length);
9384       return match;
9385     }
9386
9387     return null;
9388   },
9389   nextLine: function() {
9390     var char;
9391
9392     if (this.line >= this.getLines().length) {
9393       return false;
9394     }
9395
9396     this.input = this.getLines()[this.line];
9397     this.line += 1;
9398     this.char = 1;
9399     this.from = 1;
9400
9401     var inputTrimmed = this.input.trim();
9402
9403     var startsWith = function() {
9404       return _.some(arguments, function(prefix) {
9405         return inputTrimmed.indexOf(prefix) === 0;
9406       });
9407     };
9408
9409     var endsWith = function() {
9410       return _.some(arguments, function(suffix) {
9411         return inputTrimmed.indexOf(suffix, inputTrimmed.length - suffix.length) !== -1;
9412       });
9413     };
9414     if (this.ignoringLinterErrors === true) {
9415       if (!startsWith("/*", "//") && !(this.inComment && endsWith("*/"))) {
9416         this.input = "";
9417       }
9418     }
9419
9420     char = this.scanNonBreakingSpaces();
9421     if (char >= 0) {
9422       this.trigger("warning", { code: "W125", line: this.line, character: char + 1 });
9423     }
9424
9425     this.input = this.input.replace(/\t/g, state.tab);
9426     char = this.scanUnsafeChars();
9427
9428     if (char >= 0) {
9429       this.trigger("warning", { code: "W100", line: this.line, character: char });
9430     }
9431
9432     if (!this.ignoringLinterErrors && state.option.maxlen &&
9433       state.option.maxlen < this.input.length) {
9434       var inComment = this.inComment ||
9435         startsWith.call(inputTrimmed, "//") ||
9436         startsWith.call(inputTrimmed, "/*");
9437
9438       var shouldTriggerError = !inComment || !reg.maxlenException.test(inputTrimmed);
9439
9440       if (shouldTriggerError) {
9441         this.trigger("warning", { code: "W101", line: this.line, character: this.input.length });
9442       }
9443     }
9444
9445     return true;
9446   },
9447   start: function() {
9448     this.nextLine();
9449   },
9450   token: function() {
9451     var checks = asyncTrigger();
9452     var token;
9453
9454
9455     function isReserved(token, isProperty) {
9456       if (!token.reserved) {
9457         return false;
9458       }
9459       var meta = token.meta;
9460
9461       if (meta && meta.isFutureReservedWord && state.inES5()) {
9462         if (!meta.es5) {
9463           return false;
9464         }
9465         if (meta.strictOnly) {
9466           if (!state.option.strict && !state.isStrict()) {
9467             return false;
9468           }
9469         }
9470
9471         if (isProperty) {
9472           return false;
9473         }
9474       }
9475
9476       return true;
9477     }
9478     var create = function(type, value, isProperty, token) {
9479       var obj;
9480
9481       if (type !== "(endline)" && type !== "(end)") {
9482         this.prereg = false;
9483       }
9484
9485       if (type === "(punctuator)") {
9486         switch (value) {
9487         case ".":
9488         case ")":
9489         case "~":
9490         case "#":
9491         case "]":
9492         case "++":
9493         case "--":
9494           this.prereg = false;
9495           break;
9496         default:
9497           this.prereg = true;
9498         }
9499
9500         obj = Object.create(state.syntax[value] || state.syntax["(error)"]);
9501       }
9502
9503       if (type === "(identifier)") {
9504         if (value === "return" || value === "case" || value === "typeof") {
9505           this.prereg = true;
9506         }
9507
9508         if (_.has(state.syntax, value)) {
9509           obj = Object.create(state.syntax[value] || state.syntax["(error)"]);
9510           if (!isReserved(obj, isProperty && type === "(identifier)")) {
9511             obj = null;
9512           }
9513         }
9514       }
9515
9516       if (!obj) {
9517         obj = Object.create(state.syntax[type]);
9518       }
9519
9520       obj.identifier = (type === "(identifier)");
9521       obj.type = obj.type || type;
9522       obj.value = value;
9523       obj.line = this.line;
9524       obj.character = this.char;
9525       obj.from = this.from;
9526       if (obj.identifier && token) obj.raw_text = token.text || token.value;
9527       if (token && token.startLine && token.startLine !== this.line) {
9528         obj.startLine = token.startLine;
9529       }
9530       if (token && token.context) {
9531         obj.context = token.context;
9532       }
9533       if (token && token.depth) {
9534         obj.depth = token.depth;
9535       }
9536       if (token && token.isUnclosed) {
9537         obj.isUnclosed = token.isUnclosed;
9538       }
9539
9540       if (isProperty && obj.identifier) {
9541         obj.isProperty = isProperty;
9542       }
9543
9544       obj.check = checks.check;
9545
9546       return obj;
9547     }.bind(this);
9548
9549     for (;;) {
9550       if (!this.input.length) {
9551         if (this.nextLine()) {
9552           return create("(endline)", "");
9553         }
9554
9555         if (this.exhausted) {
9556           return null;
9557         }
9558
9559         this.exhausted = true;
9560         return create("(end)", "");
9561       }
9562
9563       token = this.next(checks);
9564
9565       if (!token) {
9566         if (this.input.length) {
9567           this.trigger("error", {
9568             code: "E024",
9569             line: this.line,
9570             character: this.char,
9571             data: [ this.peek() ]
9572           });
9573
9574           this.input = "";
9575         }
9576
9577         continue;
9578       }
9579
9580       switch (token.type) {
9581       case Token.StringLiteral:
9582         this.triggerAsync("String", {
9583           line: this.line,
9584           char: this.char,
9585           from: this.from,
9586           startLine: token.startLine,
9587           startChar: token.startChar,
9588           value: token.value,
9589           quote: token.quote
9590         }, checks, function() { return true; });
9591
9592         return create("(string)", token.value, null, token);
9593
9594       case Token.TemplateHead:
9595         this.trigger("TemplateHead", {
9596           line: this.line,
9597           char: this.char,
9598           from: this.from,
9599           startLine: token.startLine,
9600           startChar: token.startChar,
9601           value: token.value
9602         });
9603         return create("(template)", token.value, null, token);
9604
9605       case Token.TemplateMiddle:
9606         this.trigger("TemplateMiddle", {
9607           line: this.line,
9608           char: this.char,
9609           from: this.from,
9610           startLine: token.startLine,
9611           startChar: token.startChar,
9612           value: token.value
9613         });
9614         return create("(template middle)", token.value, null, token);
9615
9616       case Token.TemplateTail:
9617         this.trigger("TemplateTail", {
9618           line: this.line,
9619           char: this.char,
9620           from: this.from,
9621           startLine: token.startLine,
9622           startChar: token.startChar,
9623           value: token.value
9624         });
9625         return create("(template tail)", token.value, null, token);
9626
9627       case Token.NoSubstTemplate:
9628         this.trigger("NoSubstTemplate", {
9629           line: this.line,
9630           char: this.char,
9631           from: this.from,
9632           startLine: token.startLine,
9633           startChar: token.startChar,
9634           value: token.value
9635         });
9636         return create("(no subst template)", token.value, null, token);
9637
9638       case Token.Identifier:
9639         this.triggerAsync("Identifier", {
9640           line: this.line,
9641           char: this.char,
9642           from: this.form,
9643           name: token.value,
9644           raw_name: token.text,
9645           isProperty: state.tokens.curr.id === "."
9646         }, checks, function() { return true; });
9647       case Token.Keyword:
9648       case Token.NullLiteral:
9649       case Token.BooleanLiteral:
9650         return create("(identifier)", token.value, state.tokens.curr.id === ".", token);
9651
9652       case Token.NumericLiteral:
9653         if (token.isMalformed) {
9654           this.trigger("warning", {
9655             code: "W045",
9656             line: this.line,
9657             character: this.char,
9658             data: [ token.value ]
9659           });
9660         }
9661
9662         this.triggerAsync("warning", {
9663           code: "W114",
9664           line: this.line,
9665           character: this.char,
9666           data: [ "0x-" ]
9667         }, checks, function() { return token.base === 16 && state.jsonMode; });
9668
9669         this.triggerAsync("warning", {
9670           code: "W115",
9671           line: this.line,
9672           character: this.char
9673         }, checks, function() {
9674           return state.isStrict() && token.base === 8 && token.isLegacy;
9675         });
9676
9677         this.trigger("Number", {
9678           line: this.line,
9679           char: this.char,
9680           from: this.from,
9681           value: token.value,
9682           base: token.base,
9683           isMalformed: token.malformed
9684         });
9685
9686         return create("(number)", token.value);
9687
9688       case Token.RegExp:
9689         return create("(regexp)", token.value);
9690
9691       case Token.Comment:
9692         state.tokens.curr.comment = true;
9693
9694         if (token.isSpecial) {
9695           return {
9696             id: '(comment)',
9697             value: token.value,
9698             body: token.body,
9699             type: token.commentType,
9700             isSpecial: token.isSpecial,
9701             line: this.line,
9702             character: this.char,
9703             from: this.from
9704           };
9705         }
9706
9707         break;
9708
9709       case "":
9710         break;
9711
9712       default:
9713         return create("(punctuator)", token.value);
9714       }
9715     }
9716   }
9717 };
9718
9719 exports.Lexer = Lexer;
9720 exports.Context = Context;
9721
9722 },{"../data/ascii-identifier-data.js":"/node_modules/jshint/data/ascii-identifier-data.js","../lodash":"/node_modules/jshint/lodash.js","./reg.js":"/node_modules/jshint/src/reg.js","./state.js":"/node_modules/jshint/src/state.js","events":"/node_modules/browserify/node_modules/events/events.js"}],"/node_modules/jshint/src/messages.js":[function(_dereq_,module,exports){
9723 "use strict";
9724
9725 var _ = _dereq_("../lodash");
9726
9727 var errors = {
9728   E001: "Bad option: '{a}'.",
9729   E002: "Bad option value.",
9730   E003: "Expected a JSON value.",
9731   E004: "Input is neither a string nor an array of strings.",
9732   E005: "Input is empty.",
9733   E006: "Unexpected early end of program.",
9734   E007: "Missing \"use strict\" statement.",
9735   E008: "Strict violation.",
9736   E009: "Option 'validthis' can't be used in a global scope.",
9737   E010: "'with' is not allowed in strict mode.",
9738   E011: "'{a}' has already been declared.",
9739   E012: "const '{a}' is initialized to 'undefined'.",
9740   E013: "Attempting to override '{a}' which is a constant.",
9741   E014: "A regular expression literal can be confused with '/='.",
9742   E015: "Unclosed regular expression.",
9743   E016: "Invalid regular expression.",
9744   E017: "Unclosed comment.",
9745   E018: "Unbegun comment.",
9746   E019: "Unmatched '{a}'.",
9747   E020: "Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
9748   E021: "Expected '{a}' and instead saw '{b}'.",
9749   E022: "Line breaking error '{a}'.",
9750   E023: "Missing '{a}'.",
9751   E024: "Unexpected '{a}'.",
9752   E025: "Missing ':' on a case clause.",
9753   E026: "Missing '}' to match '{' from line {a}.",
9754   E027: "Missing ']' to match '[' from line {a}.",
9755   E028: "Illegal comma.",
9756   E029: "Unclosed string.",
9757   E030: "Expected an identifier and instead saw '{a}'.",
9758   E031: "Bad assignment.", // FIXME: Rephrase
9759   E032: "Expected a small integer or 'false' and instead saw '{a}'.",
9760   E033: "Expected an operator and instead saw '{a}'.",
9761   E034: "get/set are ES5 features.",
9762   E035: "Missing property name.",
9763   E036: "Expected to see a statement and instead saw a block.",
9764   E037: null,
9765   E038: null,
9766   E039: "Function declarations are not invocable. Wrap the whole function invocation in parens.",
9767   E040: "Each value should have its own case label.",
9768   E041: "Unrecoverable syntax error.",
9769   E042: "Stopping.",
9770   E043: "Too many errors.",
9771   E044: null,
9772   E045: "Invalid for each loop.",
9773   E046: "A yield statement shall be within a generator function (with syntax: `function*`)",
9774   E047: null,
9775   E048: "{a} declaration not directly within block.",
9776   E049: "A {a} cannot be named '{b}'.",
9777   E050: "Mozilla requires the yield expression to be parenthesized here.",
9778   E051: null,
9779   E052: "Unclosed template literal.",
9780   E053: "Export declaration must be in global scope.",
9781   E054: "Class properties must be methods. Expected '(' but instead saw '{a}'.",
9782   E055: "The '{a}' option cannot be set after any executable code.",
9783   E056: "'{a}' was used before it was declared, which is illegal for '{b}' variables.",
9784   E057: "Invalid meta property: '{a}.{b}'.",
9785   E058: "Missing semicolon."
9786 };
9787
9788 var warnings = {
9789   W001: "'hasOwnProperty' is a really bad name.",
9790   W002: "Value of '{a}' may be overwritten in IE 8 and earlier.",
9791   W003: "'{a}' was used before it was defined.",
9792   W004: "'{a}' is already defined.",
9793   W005: "A dot following a number can be confused with a decimal point.",
9794   W006: "Confusing minuses.",
9795   W007: "Confusing plusses.",
9796   W008: "A leading decimal point can be confused with a dot: '{a}'.",
9797   W009: "The array literal notation [] is preferable.",
9798   W010: "The object literal notation {} is preferable.",
9799   W011: null,
9800   W012: null,
9801   W013: null,
9802   W014: "Bad line breaking before '{a}'.",
9803   W015: null,
9804   W016: "Unexpected use of '{a}'.",
9805   W017: "Bad operand.",
9806   W018: "Confusing use of '{a}'.",
9807   W019: "Use the isNaN function to compare with NaN.",
9808   W020: "Read only.",
9809   W021: "Reassignment of '{a}', which is is a {b}. " +
9810     "Use 'var' or 'let' to declare bindings that may change.",
9811   W022: "Do not assign to the exception parameter.",
9812   W023: "Expected an identifier in an assignment and instead saw a function invocation.",
9813   W024: "Expected an identifier and instead saw '{a}' (a reserved word).",
9814   W025: "Missing name in function declaration.",
9815   W026: "Inner functions should be listed at the top of the outer function.",
9816   W027: "Unreachable '{a}' after '{b}'.",
9817   W028: "Label '{a}' on {b} statement.",
9818   W030: "Expected an assignment or function call and instead saw an expression.",
9819   W031: "Do not use 'new' for side effects.",
9820   W032: "Unnecessary semicolon.",
9821   W033: "Missing semicolon.",
9822   W034: "Unnecessary directive \"{a}\".",
9823   W035: "Empty block.",
9824   W036: "Unexpected /*member '{a}'.",
9825   W037: "'{a}' is a statement label.",
9826   W038: "'{a}' used out of scope.",
9827   W039: "'{a}' is not allowed.",
9828   W040: "Possible strict violation.",
9829   W041: "Use '{a}' to compare with '{b}'.",
9830   W042: "Avoid EOL escaping.",
9831   W043: "Bad escaping of EOL. Use option multistr if needed.",
9832   W044: "Bad or unnecessary escaping.", /* TODO(caitp): remove W044 */
9833   W045: "Bad number '{a}'.",
9834   W046: "Don't use extra leading zeros '{a}'.",
9835   W047: "A trailing decimal point can be confused with a dot: '{a}'.",
9836   W048: "Unexpected control character in regular expression.",
9837   W049: "Unexpected escaped character '{a}' in regular expression.",
9838   W050: "JavaScript URL.",
9839   W051: "Variables should not be deleted.",
9840   W052: "Unexpected '{a}'.",
9841   W053: "Do not use {a} as a constructor.",
9842   W054: "The Function constructor is a form of eval.",
9843   W055: "A constructor name should start with an uppercase letter.",
9844   W056: "Bad constructor.",
9845   W057: "Weird construction. Is 'new' necessary?",
9846   W058: "Missing '()' invoking a constructor.",
9847   W059: "Avoid arguments.{a}.",
9848   W060: "document.write can be a form of eval.",
9849   W061: "eval can be harmful.",
9850   W062: "Wrap an immediate function invocation in parens " +
9851     "to assist the reader in understanding that the expression " +
9852     "is the result of a function, and not the function itself.",
9853   W063: "Math is not a function.",
9854   W064: "Missing 'new' prefix when invoking a constructor.",
9855   W065: "Missing radix parameter.",
9856   W066: "Implied eval. Consider passing a function instead of a string.",
9857   W067: "Bad invocation.",
9858   W068: "Wrapping non-IIFE function literals in parens is unnecessary.",
9859   W069: "['{a}'] is better written in dot notation.",
9860   W070: "Extra comma. (it breaks older versions of IE)",
9861   W071: "This function has too many statements. ({a})",
9862   W072: "This function has too many parameters. ({a})",
9863   W073: "Blocks are nested too deeply. ({a})",
9864   W074: "This function's cyclomatic complexity is too high. ({a})",
9865   W075: "Duplicate {a} '{b}'.",
9866   W076: "Unexpected parameter '{a}' in get {b} function.",
9867   W077: "Expected a single parameter in set {a} function.",
9868   W078: "Setter is defined without getter.",
9869   W079: "Redefinition of '{a}'.",
9870   W080: "It's not necessary to initialize '{a}' to 'undefined'.",
9871   W081: null,
9872   W082: "Function declarations should not be placed in blocks. " +
9873     "Use a function expression or move the statement to the top of " +
9874     "the outer function.",
9875   W083: "Don't make functions within a loop.",
9876   W084: "Assignment in conditional expression",
9877   W085: "Don't use 'with'.",
9878   W086: "Expected a 'break' statement before '{a}'.",
9879   W087: "Forgotten 'debugger' statement?",
9880   W088: "Creating global 'for' variable. Should be 'for (var {a} ...'.",
9881   W089: "The body of a for in should be wrapped in an if statement to filter " +
9882     "unwanted properties from the prototype.",
9883   W090: "'{a}' is not a statement label.",
9884   W091: null,
9885   W093: "Did you mean to return a conditional instead of an assignment?",
9886   W094: "Unexpected comma.",
9887   W095: "Expected a string and instead saw {a}.",
9888   W096: "The '{a}' key may produce unexpected results.",
9889   W097: "Use the function form of \"use strict\".",
9890   W098: "'{a}' is defined but never used.",
9891   W099: null,
9892   W100: "This character may get silently deleted by one or more browsers.",
9893   W101: "Line is too long.",
9894   W102: null,
9895   W103: "The '{a}' property is deprecated.",
9896   W104: "'{a}' is available in ES{b} (use 'esversion: {b}') or Mozilla JS extensions (use moz).",
9897   W105: "Unexpected {a} in '{b}'.",
9898   W106: "Identifier '{a}' is not in camel case.",
9899   W107: "Script URL.",
9900   W108: "Strings must use doublequote.",
9901   W109: "Strings must use singlequote.",
9902   W110: "Mixed double and single quotes.",
9903   W112: "Unclosed string.",
9904   W113: "Control character in string: {a}.",
9905   W114: "Avoid {a}.",
9906   W115: "Octal literals are not allowed in strict mode.",
9907   W116: "Expected '{a}' and instead saw '{b}'.",
9908   W117: "'{a}' is not defined.",
9909   W118: "'{a}' is only available in Mozilla JavaScript extensions (use moz option).",
9910   W119: "'{a}' is only available in ES{b} (use 'esversion: {b}').",
9911   W120: "You might be leaking a variable ({a}) here.",
9912   W121: "Extending prototype of native object: '{a}'.",
9913   W122: "Invalid typeof value '{a}'",
9914   W123: "'{a}' is already defined in outer scope.",
9915   W124: "A generator function shall contain a yield statement.",
9916   W125: "This line contains non-breaking spaces: http://jshint.com/doc/options/#nonbsp",
9917   W126: "Unnecessary grouping operator.",
9918   W127: "Unexpected use of a comma operator.",
9919   W128: "Empty array elements require elision=true.",
9920   W129: "'{a}' is defined in a future version of JavaScript. Use a " +
9921     "different variable name to avoid migration issues.",
9922   W130: "Invalid element after rest element.",
9923   W131: "Invalid parameter after rest parameter.",
9924   W132: "`var` declarations are forbidden. Use `let` or `const` instead.",
9925   W133: "Invalid for-{a} loop left-hand-side: {b}.",
9926   W134: "The '{a}' option is only available when linting ECMAScript {b} code.",
9927   W135: "{a} may not be supported by non-browser environments.",
9928   W136: "'{a}' must be in function scope.",
9929   W137: "Empty destructuring.",
9930   W138: "Regular parameters should not come after default parameters."
9931 };
9932
9933 var info = {
9934   I001: "Comma warnings can be turned off with 'laxcomma'.",
9935   I002: null,
9936   I003: "ES5 option is now set per default"
9937 };
9938
9939 exports.errors = {};
9940 exports.warnings = {};
9941 exports.info = {};
9942
9943 _.each(errors, function(desc, code) {
9944   exports.errors[code] = { code: code, desc: desc };
9945 });
9946
9947 _.each(warnings, function(desc, code) {
9948   exports.warnings[code] = { code: code, desc: desc };
9949 });
9950
9951 _.each(info, function(desc, code) {
9952   exports.info[code] = { code: code, desc: desc };
9953 });
9954
9955 },{"../lodash":"/node_modules/jshint/lodash.js"}],"/node_modules/jshint/src/name-stack.js":[function(_dereq_,module,exports){
9956 "use strict";
9957
9958 function NameStack() {
9959   this._stack = [];
9960 }
9961
9962 Object.defineProperty(NameStack.prototype, "length", {
9963   get: function() {
9964     return this._stack.length;
9965   }
9966 });
9967 NameStack.prototype.push = function() {
9968   this._stack.push(null);
9969 };
9970 NameStack.prototype.pop = function() {
9971   this._stack.pop();
9972 };
9973 NameStack.prototype.set = function(token) {
9974   this._stack[this.length - 1] = token;
9975 };
9976 NameStack.prototype.infer = function() {
9977   var nameToken = this._stack[this.length - 1];
9978   var prefix = "";
9979   var type;
9980   if (!nameToken || nameToken.type === "class") {
9981     nameToken = this._stack[this.length - 2];
9982   }
9983
9984   if (!nameToken) {
9985     return "(empty)";
9986   }
9987
9988   type = nameToken.type;
9989
9990   if (type !== "(string)" && type !== "(number)" && type !== "(identifier)" && type !== "default") {
9991     return "(expression)";
9992   }
9993
9994   if (nameToken.accessorType) {
9995     prefix = nameToken.accessorType + " ";
9996   }
9997
9998   return prefix + nameToken.value;
9999 };
10000
10001 module.exports = NameStack;
10002
10003 },{}],"/node_modules/jshint/src/options.js":[function(_dereq_,module,exports){
10004 "use strict";
10005 exports.bool = {
10006   enforcing: {
10007     bitwise     : true,
10008     freeze      : true,
10009     camelcase   : true,
10010     curly       : true,
10011     eqeqeq      : true,
10012     futurehostile: true,
10013     notypeof    : true,
10014     es3         : true,
10015     es5         : true,
10016     forin       : true,
10017     funcscope   : true,
10018     immed       : true,
10019     iterator    : true,
10020     newcap      : true,
10021     noarg       : true,
10022     nocomma     : true,
10023     noempty     : true,
10024     nonbsp      : true,
10025     nonew       : true,
10026     undef       : true,
10027     singleGroups: false,
10028     varstmt: false,
10029     enforceall : false
10030   },
10031   relaxing: {
10032     asi         : true,
10033     multistr    : true,
10034     debug       : true,
10035     boss        : true,
10036     evil        : true,
10037     globalstrict: true,
10038     plusplus    : true,
10039     proto       : true,
10040     scripturl   : true,
10041     sub         : true,
10042     supernew    : true,
10043     laxbreak    : true,
10044     laxcomma    : true,
10045     validthis   : true,
10046     withstmt    : true,
10047     moz         : true,
10048     noyield     : true,
10049     eqnull      : true,
10050     lastsemic   : true,
10051     loopfunc    : true,
10052     expr        : true,
10053     esnext      : true,
10054     elision     : true,
10055   },
10056   environments: {
10057     mootools    : true,
10058     couch       : true,
10059     jasmine     : true,
10060     jquery      : true,
10061     node        : true,
10062     qunit       : true,
10063     rhino       : true,
10064     shelljs     : true,
10065     prototypejs : true,
10066     yui         : true,
10067     mocha       : true,
10068     module      : true,
10069     wsh         : true,
10070     worker      : true,
10071     nonstandard : true,
10072     browser     : true,
10073     browserify  : true,
10074     devel       : true,
10075     dojo        : true,
10076     typed       : true,
10077     phantom     : true
10078   },
10079   obsolete: {
10080     onecase     : true, // if one case switch statements should be allowed
10081     regexp      : true, // if the . should not be allowed in regexp literals
10082     regexdash   : true  // if unescaped first/last dash (-) inside brackets
10083   }
10084 };
10085 exports.val = {
10086   maxlen       : false,
10087   indent       : false,
10088   maxerr       : false,
10089   predef       : false,
10090   globals      : false,
10091   quotmark     : false,
10092
10093   scope        : false,
10094   maxstatements: false,
10095   maxdepth     : false,
10096   maxparams    : false,
10097   maxcomplexity: false,
10098   shadow       : false,
10099   strict      : true,
10100   unused       : true,
10101   latedef      : false,
10102
10103   ignore       : false, // start/end ignoring lines of code, bypassing the lexer
10104
10105   ignoreDelimiters: false, // array of start/end delimiters used to ignore
10106   esversion: 5
10107 };
10108 exports.inverted = {
10109   bitwise : true,
10110   forin   : true,
10111   newcap  : true,
10112   plusplus: true,
10113   regexp  : true,
10114   undef   : true,
10115   eqeqeq  : true,
10116   strict  : true
10117 };
10118
10119 exports.validNames = Object.keys(exports.val)
10120   .concat(Object.keys(exports.bool.relaxing))
10121   .concat(Object.keys(exports.bool.enforcing))
10122   .concat(Object.keys(exports.bool.obsolete))
10123   .concat(Object.keys(exports.bool.environments));
10124 exports.renamed = {
10125   eqeq   : "eqeqeq",
10126   windows: "wsh",
10127   sloppy : "strict"
10128 };
10129
10130 exports.removed = {
10131   nomen: true,
10132   onevar: true,
10133   passfail: true,
10134   white: true,
10135   gcl: true,
10136   smarttabs: true,
10137   trailing: true
10138 };
10139 exports.noenforceall = {
10140   varstmt: true,
10141   strict: true
10142 };
10143
10144 },{}],"/node_modules/jshint/src/reg.js":[function(_dereq_,module,exports){
10145
10146 "use strict";
10147 exports.unsafeString =
10148   /@cc|<\/?|script|\]\s*\]|<\s*!|&lt/i;
10149 exports.unsafeChars =
10150   /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
10151 exports.needEsc =
10152   /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
10153
10154 exports.needEscGlobal =
10155   /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
10156 exports.starSlash = /\*\//;
10157 exports.identifier = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/;
10158 exports.javascriptURL = /^(?:javascript|jscript|ecmascript|vbscript|livescript)\s*:/i;
10159 exports.fallsThrough = /^\s*falls?\sthrough\s*$/;
10160 exports.maxlenException = /^(?:(?:\/\/|\/\*|\*) ?)?[^ ]+$/;
10161
10162 },{}],"/node_modules/jshint/src/scope-manager.js":[function(_dereq_,module,exports){
10163 "use strict";
10164
10165 var _      = _dereq_("../lodash");
10166 var events = _dereq_("events");
10167 var marker = {};
10168 var scopeManager = function(state, predefined, exported, declared) {
10169
10170   var _current;
10171   var _scopeStack = [];
10172
10173   function _newScope(type) {
10174     _current = {
10175       "(labels)": Object.create(null),
10176       "(usages)": Object.create(null),
10177       "(breakLabels)": Object.create(null),
10178       "(parent)": _current,
10179       "(type)": type,
10180       "(params)": (type === "functionparams" || type === "catchparams") ? [] : null
10181     };
10182     _scopeStack.push(_current);
10183   }
10184
10185   _newScope("global");
10186   _current["(predefined)"] = predefined;
10187
10188   var _currentFunctBody = _current; // this is the block after the params = function
10189
10190   var usedPredefinedAndGlobals = Object.create(null);
10191   var impliedGlobals = Object.create(null);
10192   var unuseds = [];
10193   var emitter = new events.EventEmitter();
10194
10195   function warning(code, token) {
10196     emitter.emit("warning", {
10197       code: code,
10198       token: token,
10199       data: _.slice(arguments, 2)
10200     });
10201   }
10202
10203   function error(code, token) {
10204     emitter.emit("warning", {
10205       code: code,
10206       token: token,
10207       data: _.slice(arguments, 2)
10208     });
10209   }
10210
10211   function _setupUsages(labelName) {
10212     if (!_current["(usages)"][labelName]) {
10213       _current["(usages)"][labelName] = {
10214         "(modified)": [],
10215         "(reassigned)": [],
10216         "(tokens)": []
10217       };
10218     }
10219   }
10220
10221   var _getUnusedOption = function(unused_opt) {
10222     if (unused_opt === undefined) {
10223       unused_opt = state.option.unused;
10224     }
10225
10226     if (unused_opt === true) {
10227       unused_opt = "last-param";
10228     }
10229
10230     return unused_opt;
10231   };
10232
10233   var _warnUnused = function(name, tkn, type, unused_opt) {
10234     var line = tkn.line;
10235     var chr  = tkn.from;
10236     var raw_name = tkn.raw_text || name;
10237
10238     unused_opt = _getUnusedOption(unused_opt);
10239
10240     var warnable_types = {
10241       "vars": ["var"],
10242       "last-param": ["var", "param"],
10243       "strict": ["var", "param", "last-param"]
10244     };
10245
10246     if (unused_opt) {
10247       if (warnable_types[unused_opt] && warnable_types[unused_opt].indexOf(type) !== -1) {
10248         warning("W098", { line: line, from: chr }, raw_name);
10249       }
10250     }
10251     if (unused_opt || type === "var") {
10252       unuseds.push({
10253         name: name,
10254         line: line,
10255         character: chr
10256       });
10257     }
10258   };
10259   function _checkForUnused() {
10260     if (_current["(type)"] === "functionparams") {
10261       _checkParams();
10262       return;
10263     }
10264     var curentLabels = _current["(labels)"];
10265     for (var labelName in curentLabels) {
10266       if (curentLabels[labelName]) {
10267         if (curentLabels[labelName]["(type)"] !== "exception" &&
10268           curentLabels[labelName]["(unused)"]) {
10269           _warnUnused(labelName, curentLabels[labelName]["(token)"], "var");
10270         }
10271       }
10272     }
10273   }
10274   function _checkParams() {
10275     var params = _current["(params)"];
10276
10277     if (!params) {
10278       return;
10279     }
10280
10281     var param = params.pop();
10282     var unused_opt;
10283
10284     while (param) {
10285       var label = _current["(labels)"][param];
10286
10287       unused_opt = _getUnusedOption(state.funct["(unusedOption)"]);
10288       if (param === "undefined")
10289         return;
10290
10291       if (label["(unused)"]) {
10292         _warnUnused(param, label["(token)"], "param", state.funct["(unusedOption)"]);
10293       } else if (unused_opt === "last-param") {
10294         return;
10295       }
10296
10297       param = params.pop();
10298     }
10299   }
10300   function _getLabel(labelName) {
10301     for (var i = _scopeStack.length - 1 ; i >= 0; --i) {
10302       var scopeLabels = _scopeStack[i]["(labels)"];
10303       if (scopeLabels[labelName]) {
10304         return scopeLabels;
10305       }
10306     }
10307   }
10308
10309   function usedSoFarInCurrentFunction(labelName) {
10310     for (var i = _scopeStack.length - 1; i >= 0; i--) {
10311       var current = _scopeStack[i];
10312       if (current["(usages)"][labelName]) {
10313         return current["(usages)"][labelName];
10314       }
10315       if (current === _currentFunctBody) {
10316         break;
10317       }
10318     }
10319     return false;
10320   }
10321
10322   function _checkOuterShadow(labelName, token) {
10323     if (state.option.shadow !== "outer") {
10324       return;
10325     }
10326
10327     var isGlobal = _currentFunctBody["(type)"] === "global",
10328       isNewFunction = _current["(type)"] === "functionparams";
10329
10330     var outsideCurrentFunction = !isGlobal;
10331     for (var i = 0; i < _scopeStack.length; i++) {
10332       var stackItem = _scopeStack[i];
10333
10334       if (!isNewFunction && _scopeStack[i + 1] === _currentFunctBody) {
10335         outsideCurrentFunction = false;
10336       }
10337       if (outsideCurrentFunction && stackItem["(labels)"][labelName]) {
10338         warning("W123", token, labelName);
10339       }
10340       if (stackItem["(breakLabels)"][labelName]) {
10341         warning("W123", token, labelName);
10342       }
10343     }
10344   }
10345
10346   function _latedefWarning(type, labelName, token) {
10347     if (state.option.latedef) {
10348       if ((state.option.latedef === true && type === "function") ||
10349         type !== "function") {
10350         warning("W003", token, labelName);
10351       }
10352     }
10353   }
10354
10355   var scopeManagerInst = {
10356
10357     on: function(names, listener) {
10358       names.split(" ").forEach(function(name) {
10359         emitter.on(name, listener);
10360       });
10361     },
10362
10363     isPredefined: function(labelName) {
10364       return !this.has(labelName) && _.has(_scopeStack[0]["(predefined)"], labelName);
10365     },
10366     stack: function(type) {
10367       var previousScope = _current;
10368       _newScope(type);
10369
10370       if (!type && previousScope["(type)"] === "functionparams") {
10371
10372         _current["(isFuncBody)"] = true;
10373         _current["(context)"] = _currentFunctBody;
10374         _currentFunctBody = _current;
10375       }
10376     },
10377
10378     unstack: function() {
10379       var subScope = _scopeStack.length > 1 ? _scopeStack[_scopeStack.length - 2] : null;
10380       var isUnstackingFunctionBody = _current === _currentFunctBody,
10381         isUnstackingFunctionParams = _current["(type)"] === "functionparams",
10382         isUnstackingFunctionOuter = _current["(type)"] === "functionouter";
10383
10384       var i, j;
10385       var currentUsages = _current["(usages)"];
10386       var currentLabels = _current["(labels)"];
10387       var usedLabelNameList = Object.keys(currentUsages);
10388
10389       if (currentUsages.__proto__ && usedLabelNameList.indexOf("__proto__") === -1) {
10390         usedLabelNameList.push("__proto__");
10391       }
10392
10393       for (i = 0; i < usedLabelNameList.length; i++) {
10394         var usedLabelName = usedLabelNameList[i];
10395
10396         var usage = currentUsages[usedLabelName];
10397         var usedLabel = currentLabels[usedLabelName];
10398         if (usedLabel) {
10399           var usedLabelType = usedLabel["(type)"];
10400
10401           if (usedLabel["(useOutsideOfScope)"] && !state.option.funcscope) {
10402             var usedTokens = usage["(tokens)"];
10403             if (usedTokens) {
10404               for (j = 0; j < usedTokens.length; j++) {
10405                 if (usedLabel["(function)"] === usedTokens[j]["(function)"]) {
10406                   error("W038", usedTokens[j], usedLabelName);
10407                 }
10408               }
10409             }
10410           }
10411           _current["(labels)"][usedLabelName]["(unused)"] = false;
10412           if (usedLabelType === "const" && usage["(modified)"]) {
10413             for (j = 0; j < usage["(modified)"].length; j++) {
10414               error("E013", usage["(modified)"][j], usedLabelName);
10415             }
10416           }
10417           if ((usedLabelType === "function" || usedLabelType === "class") &&
10418               usage["(reassigned)"]) {
10419             for (j = 0; j < usage["(reassigned)"].length; j++) {
10420               error("W021", usage["(reassigned)"][j], usedLabelName, usedLabelType);
10421             }
10422           }
10423           continue;
10424         }
10425
10426         if (isUnstackingFunctionOuter) {
10427           state.funct["(isCapturing)"] = true;
10428         }
10429
10430         if (subScope) {
10431           if (!subScope["(usages)"][usedLabelName]) {
10432             subScope["(usages)"][usedLabelName] = usage;
10433             if (isUnstackingFunctionBody) {
10434               subScope["(usages)"][usedLabelName]["(onlyUsedSubFunction)"] = true;
10435             }
10436           } else {
10437             var subScopeUsage = subScope["(usages)"][usedLabelName];
10438             subScopeUsage["(modified)"] = subScopeUsage["(modified)"].concat(usage["(modified)"]);
10439             subScopeUsage["(tokens)"] = subScopeUsage["(tokens)"].concat(usage["(tokens)"]);
10440             subScopeUsage["(reassigned)"] =
10441               subScopeUsage["(reassigned)"].concat(usage["(reassigned)"]);
10442             subScopeUsage["(onlyUsedSubFunction)"] = false;
10443           }
10444         } else {
10445           if (typeof _current["(predefined)"][usedLabelName] === "boolean") {
10446             delete declared[usedLabelName];
10447             usedPredefinedAndGlobals[usedLabelName] = marker;
10448             if (_current["(predefined)"][usedLabelName] === false && usage["(reassigned)"]) {
10449               for (j = 0; j < usage["(reassigned)"].length; j++) {
10450                 warning("W020", usage["(reassigned)"][j]);
10451               }
10452             }
10453           }
10454           else {
10455             if (usage["(tokens)"]) {
10456               for (j = 0; j < usage["(tokens)"].length; j++) {
10457                 var undefinedToken = usage["(tokens)"][j];
10458                 if (!undefinedToken.forgiveUndef) {
10459                   if (state.option.undef && !undefinedToken.ignoreUndef) {
10460                     warning("W117", undefinedToken, usedLabelName);
10461                   }
10462                   if (impliedGlobals[usedLabelName]) {
10463                     impliedGlobals[usedLabelName].line.push(undefinedToken.line);
10464                   } else {
10465                     impliedGlobals[usedLabelName] = {
10466                       name: usedLabelName,
10467                       line: [undefinedToken.line]
10468                     };
10469                   }
10470                 }
10471               }
10472             }
10473           }
10474         }
10475       }
10476       if (!subScope) {
10477         Object.keys(declared)
10478           .forEach(function(labelNotUsed) {
10479             _warnUnused(labelNotUsed, declared[labelNotUsed], "var");
10480           });
10481       }
10482       if (subScope && !isUnstackingFunctionBody &&
10483         !isUnstackingFunctionParams && !isUnstackingFunctionOuter) {
10484         var labelNames = Object.keys(currentLabels);
10485         for (i = 0; i < labelNames.length; i++) {
10486
10487           var defLabelName = labelNames[i];
10488           if (!currentLabels[defLabelName]["(blockscoped)"] &&
10489             currentLabels[defLabelName]["(type)"] !== "exception" &&
10490             !this.funct.has(defLabelName, { excludeCurrent: true })) {
10491             subScope["(labels)"][defLabelName] = currentLabels[defLabelName];
10492             if (_currentFunctBody["(type)"] !== "global") {
10493               subScope["(labels)"][defLabelName]["(useOutsideOfScope)"] = true;
10494             }
10495             delete currentLabels[defLabelName];
10496           }
10497         }
10498       }
10499
10500       _checkForUnused();
10501
10502       _scopeStack.pop();
10503       if (isUnstackingFunctionBody) {
10504         _currentFunctBody = _scopeStack[_.findLastIndex(_scopeStack, function(scope) {
10505           return scope["(isFuncBody)"] || scope["(type)"] === "global";
10506         })];
10507       }
10508
10509       _current = subScope;
10510     },
10511     addParam: function(labelName, token, type) {
10512       type = type || "param";
10513
10514       if (type === "exception") {
10515         var previouslyDefinedLabelType = this.funct.labeltype(labelName);
10516         if (previouslyDefinedLabelType && previouslyDefinedLabelType !== "exception") {
10517           if (!state.option.node) {
10518             warning("W002", state.tokens.next, labelName);
10519           }
10520         }
10521       }
10522       if (_.has(_current["(labels)"], labelName)) {
10523         _current["(labels)"][labelName].duplicated = true;
10524       } else {
10525         _checkOuterShadow(labelName, token, type);
10526
10527         _current["(labels)"][labelName] = {
10528           "(type)" : type,
10529           "(token)": token,
10530           "(unused)": true };
10531
10532         _current["(params)"].push(labelName);
10533       }
10534
10535       if (_.has(_current["(usages)"], labelName)) {
10536         var usage = _current["(usages)"][labelName];
10537         if (usage["(onlyUsedSubFunction)"]) {
10538           _latedefWarning(type, labelName, token);
10539         } else {
10540           warning("E056", token, labelName, type);
10541         }
10542       }
10543     },
10544
10545     validateParams: function() {
10546       if (_currentFunctBody["(type)"] === "global") {
10547         return;
10548       }
10549
10550       var isStrict = state.isStrict();
10551       var currentFunctParamScope = _currentFunctBody["(parent)"];
10552
10553       if (!currentFunctParamScope["(params)"]) {
10554         return;
10555       }
10556
10557       currentFunctParamScope["(params)"].forEach(function(labelName) {
10558         var label = currentFunctParamScope["(labels)"][labelName];
10559
10560         if (label && label.duplicated) {
10561           if (isStrict) {
10562             warning("E011", label["(token)"], labelName);
10563           } else if (state.option.shadow !== true) {
10564             warning("W004", label["(token)"], labelName);
10565           }
10566         }
10567       });
10568     },
10569
10570     getUsedOrDefinedGlobals: function() {
10571       var list = Object.keys(usedPredefinedAndGlobals);
10572       if (usedPredefinedAndGlobals.__proto__ === marker &&
10573         list.indexOf("__proto__") === -1) {
10574         list.push("__proto__");
10575       }
10576
10577       return list;
10578     },
10579     getImpliedGlobals: function() {
10580       var values = _.values(impliedGlobals);
10581       var hasProto = false;
10582       if (impliedGlobals.__proto__) {
10583         hasProto = values.some(function(value) {
10584           return value.name === "__proto__";
10585         });
10586
10587         if (!hasProto) {
10588           values.push(impliedGlobals.__proto__);
10589         }
10590       }
10591
10592       return values;
10593     },
10594     getUnuseds: function() {
10595       return unuseds;
10596     },
10597
10598     has: function(labelName) {
10599       return Boolean(_getLabel(labelName));
10600     },
10601
10602     labeltype: function(labelName) {
10603       var scopeLabels = _getLabel(labelName);
10604       if (scopeLabels) {
10605         return scopeLabels[labelName]["(type)"];
10606       }
10607       return null;
10608     },
10609     addExported: function(labelName) {
10610       var globalLabels = _scopeStack[0]["(labels)"];
10611       if (_.has(declared, labelName)) {
10612         delete declared[labelName];
10613       } else if (_.has(globalLabels, labelName)) {
10614         globalLabels[labelName]["(unused)"] = false;
10615       } else {
10616         for (var i = 1; i < _scopeStack.length; i++) {
10617           var scope = _scopeStack[i];
10618           if (!scope["(type)"]) {
10619             if (_.has(scope["(labels)"], labelName) &&
10620                 !scope["(labels)"][labelName]["(blockscoped)"]) {
10621               scope["(labels)"][labelName]["(unused)"] = false;
10622               return;
10623             }
10624           } else {
10625             break;
10626           }
10627         }
10628         exported[labelName] = true;
10629       }
10630     },
10631     setExported: function(labelName, token) {
10632       this.block.use(labelName, token);
10633     },
10634     addlabel: function(labelName, opts) {
10635
10636       var type  = opts.type;
10637       var token = opts.token;
10638       var isblockscoped = type === "let" || type === "const" || type === "class";
10639       var isexported    = (isblockscoped ? _current : _currentFunctBody)["(type)"] === "global" &&
10640                           _.has(exported, labelName);
10641       _checkOuterShadow(labelName, token, type);
10642       if (isblockscoped) {
10643
10644         var declaredInCurrentScope = _current["(labels)"][labelName];
10645         if (!declaredInCurrentScope && _current === _currentFunctBody &&
10646           _current["(type)"] !== "global") {
10647           declaredInCurrentScope = !!_currentFunctBody["(parent)"]["(labels)"][labelName];
10648         }
10649         if (!declaredInCurrentScope && _current["(usages)"][labelName]) {
10650           var usage = _current["(usages)"][labelName];
10651           if (usage["(onlyUsedSubFunction)"]) {
10652             _latedefWarning(type, labelName, token);
10653           } else {
10654             warning("E056", token, labelName, type);
10655           }
10656         }
10657         if (declaredInCurrentScope) {
10658           warning("E011", token, labelName);
10659         }
10660         else if (state.option.shadow === "outer") {
10661           if (scopeManagerInst.funct.has(labelName)) {
10662             warning("W004", token, labelName);
10663           }
10664         }
10665
10666         scopeManagerInst.block.add(labelName, type, token, !isexported);
10667
10668       } else {
10669
10670         var declaredInCurrentFunctionScope = scopeManagerInst.funct.has(labelName);
10671         if (!declaredInCurrentFunctionScope && usedSoFarInCurrentFunction(labelName)) {
10672           _latedefWarning(type, labelName, token);
10673         }
10674         if (scopeManagerInst.funct.has(labelName, { onlyBlockscoped: true })) {
10675           warning("E011", token, labelName);
10676         } else if (state.option.shadow !== true) {
10677           if (declaredInCurrentFunctionScope && labelName !== "__proto__") {
10678             if (_currentFunctBody["(type)"] !== "global") {
10679               warning("W004", token, labelName);
10680             }
10681           }
10682         }
10683
10684         scopeManagerInst.funct.add(labelName, type, token, !isexported);
10685
10686         if (_currentFunctBody["(type)"] === "global") {
10687           usedPredefinedAndGlobals[labelName] = marker;
10688         }
10689       }
10690     },
10691
10692     funct: {
10693       labeltype: function(labelName, options) {
10694         var onlyBlockscoped = options && options.onlyBlockscoped;
10695         var excludeParams = options && options.excludeParams;
10696         var currentScopeIndex = _scopeStack.length - (options && options.excludeCurrent ? 2 : 1);
10697         for (var i = currentScopeIndex; i >= 0; i--) {
10698           var current = _scopeStack[i];
10699           if (current["(labels)"][labelName] &&
10700             (!onlyBlockscoped || current["(labels)"][labelName]["(blockscoped)"])) {
10701             return current["(labels)"][labelName]["(type)"];
10702           }
10703           var scopeCheck = excludeParams ? _scopeStack[ i - 1 ] : current;
10704           if (scopeCheck && scopeCheck["(type)"] === "functionparams") {
10705             return null;
10706           }
10707         }
10708         return null;
10709       },
10710       hasBreakLabel: function(labelName) {
10711         for (var i = _scopeStack.length - 1; i >= 0; i--) {
10712           var current = _scopeStack[i];
10713
10714           if (current["(breakLabels)"][labelName]) {
10715             return true;
10716           }
10717           if (current["(type)"] === "functionparams") {
10718             return false;
10719           }
10720         }
10721         return false;
10722       },
10723       has: function(labelName, options) {
10724         return Boolean(this.labeltype(labelName, options));
10725       },
10726       add: function(labelName, type, tok, unused) {
10727         _current["(labels)"][labelName] = {
10728           "(type)" : type,
10729           "(token)": tok,
10730           "(blockscoped)": false,
10731           "(function)": _currentFunctBody,
10732           "(unused)": unused };
10733       }
10734     },
10735
10736     block: {
10737       isGlobal: function() {
10738         return _current["(type)"] === "global";
10739       },
10740
10741       use: function(labelName, token) {
10742         var paramScope = _currentFunctBody["(parent)"];
10743         if (paramScope && paramScope["(labels)"][labelName] &&
10744           paramScope["(labels)"][labelName]["(type)"] === "param") {
10745           if (!scopeManagerInst.funct.has(labelName,
10746                 { excludeParams: true, onlyBlockscoped: true })) {
10747             paramScope["(labels)"][labelName]["(unused)"] = false;
10748           }
10749         }
10750
10751         if (token && (state.ignored.W117 || state.option.undef === false)) {
10752           token.ignoreUndef = true;
10753         }
10754
10755         _setupUsages(labelName);
10756
10757         if (token) {
10758           token["(function)"] = _currentFunctBody;
10759           _current["(usages)"][labelName]["(tokens)"].push(token);
10760         }
10761       },
10762
10763       reassign: function(labelName, token) {
10764
10765         this.modify(labelName, token);
10766
10767         _current["(usages)"][labelName]["(reassigned)"].push(token);
10768       },
10769
10770       modify: function(labelName, token) {
10771
10772         _setupUsages(labelName);
10773
10774         _current["(usages)"][labelName]["(modified)"].push(token);
10775       },
10776       add: function(labelName, type, tok, unused) {
10777         _current["(labels)"][labelName] = {
10778           "(type)" : type,
10779           "(token)": tok,
10780           "(blockscoped)": true,
10781           "(unused)": unused };
10782       },
10783
10784       addBreakLabel: function(labelName, opts) {
10785         var token = opts.token;
10786         if (scopeManagerInst.funct.hasBreakLabel(labelName)) {
10787           warning("E011", token, labelName);
10788         }
10789         else if (state.option.shadow === "outer") {
10790           if (scopeManagerInst.funct.has(labelName)) {
10791             warning("W004", token, labelName);
10792           } else {
10793             _checkOuterShadow(labelName, token);
10794           }
10795         }
10796         _current["(breakLabels)"][labelName] = token;
10797       }
10798     }
10799   };
10800   return scopeManagerInst;
10801 };
10802
10803 module.exports = scopeManager;
10804
10805 },{"../lodash":"/node_modules/jshint/lodash.js","events":"/node_modules/browserify/node_modules/events/events.js"}],"/node_modules/jshint/src/state.js":[function(_dereq_,module,exports){
10806 "use strict";
10807 var NameStack = _dereq_("./name-stack.js");
10808
10809 var state = {
10810   syntax: {},
10811   isStrict: function() {
10812     return this.directive["use strict"] || this.inClassBody ||
10813       this.option.module || this.option.strict === "implied";
10814   },
10815
10816   inMoz: function() {
10817     return this.option.moz;
10818   },
10819   inES6: function() {
10820     return this.option.moz || this.option.esversion >= 6;
10821   },
10822   inES5: function(strict) {
10823     if (strict) {
10824       return (!this.option.esversion || this.option.esversion === 5) && !this.option.moz;
10825     }
10826     return !this.option.esversion || this.option.esversion >= 5 || this.option.moz;
10827   },
10828
10829
10830   reset: function() {
10831     this.tokens = {
10832       prev: null,
10833       next: null,
10834       curr: null
10835     };
10836
10837     this.option = {};
10838     this.funct = null;
10839     this.ignored = {};
10840     this.directive = {};
10841     this.jsonMode = false;
10842     this.jsonWarnings = [];
10843     this.lines = [];
10844     this.tab = "";
10845     this.cache = {}; // Node.JS doesn't have Map. Sniff.
10846     this.ignoredLines = {};
10847     this.forinifcheckneeded = false;
10848     this.nameStack = new NameStack();
10849     this.inClassBody = false;
10850   }
10851 };
10852
10853 exports.state = state;
10854
10855 },{"./name-stack.js":"/node_modules/jshint/src/name-stack.js"}],"/node_modules/jshint/src/style.js":[function(_dereq_,module,exports){
10856 "use strict";
10857
10858 exports.register = function(linter) {
10859
10860   linter.on("Identifier", function style_scanProto(data) {
10861     if (linter.getOption("proto")) {
10862       return;
10863     }
10864
10865     if (data.name === "__proto__") {
10866       linter.warn("W103", {
10867         line: data.line,
10868         char: data.char,
10869         data: [ data.name, "6" ]
10870       });
10871     }
10872   });
10873
10874   linter.on("Identifier", function style_scanIterator(data) {
10875     if (linter.getOption("iterator")) {
10876       return;
10877     }
10878
10879     if (data.name === "__iterator__") {
10880       linter.warn("W103", {
10881         line: data.line,
10882         char: data.char,
10883         data: [ data.name ]
10884       });
10885     }
10886   });
10887
10888   linter.on("Identifier", function style_scanCamelCase(data) {
10889     if (!linter.getOption("camelcase")) {
10890       return;
10891     }
10892
10893     if (data.name.replace(/^_+|_+$/g, "").indexOf("_") > -1 && !data.name.match(/^[A-Z0-9_]*$/)) {
10894       linter.warn("W106", {
10895         line: data.line,
10896         char: data.from,
10897         data: [ data.name ]
10898       });
10899     }
10900   });
10901
10902   linter.on("String", function style_scanQuotes(data) {
10903     var quotmark = linter.getOption("quotmark");
10904     var code;
10905
10906     if (!quotmark) {
10907       return;
10908     }
10909
10910     if (quotmark === "single" && data.quote !== "'") {
10911       code = "W109";
10912     }
10913
10914     if (quotmark === "double" && data.quote !== "\"") {
10915       code = "W108";
10916     }
10917
10918     if (quotmark === true) {
10919       if (!linter.getCache("quotmark")) {
10920         linter.setCache("quotmark", data.quote);
10921       }
10922
10923       if (linter.getCache("quotmark") !== data.quote) {
10924         code = "W110";
10925       }
10926     }
10927
10928     if (code) {
10929       linter.warn(code, {
10930         line: data.line,
10931         char: data.char,
10932       });
10933     }
10934   });
10935
10936   linter.on("Number", function style_scanNumbers(data) {
10937     if (data.value.charAt(0) === ".") {
10938       linter.warn("W008", {
10939         line: data.line,
10940         char: data.char,
10941         data: [ data.value ]
10942       });
10943     }
10944
10945     if (data.value.substr(data.value.length - 1) === ".") {
10946       linter.warn("W047", {
10947         line: data.line,
10948         char: data.char,
10949         data: [ data.value ]
10950       });
10951     }
10952
10953     if (/^00+/.test(data.value)) {
10954       linter.warn("W046", {
10955         line: data.line,
10956         char: data.char,
10957         data: [ data.value ]
10958       });
10959     }
10960   });
10961
10962   linter.on("String", function style_scanJavaScriptURLs(data) {
10963     var re = /^(?:javascript|jscript|ecmascript|vbscript|livescript)\s*:/i;
10964
10965     if (linter.getOption("scripturl")) {
10966       return;
10967     }
10968
10969     if (re.test(data.value)) {
10970       linter.warn("W107", {
10971         line: data.line,
10972         char: data.char
10973       });
10974     }
10975   });
10976 };
10977
10978 },{}],"/node_modules/jshint/src/vars.js":[function(_dereq_,module,exports){
10979
10980 "use strict";
10981
10982 exports.reservedVars = {
10983   arguments : false,
10984   NaN       : false
10985 };
10986
10987 exports.ecmaIdentifiers = {
10988   3: {
10989     Array              : false,
10990     Boolean            : false,
10991     Date               : false,
10992     decodeURI          : false,
10993     decodeURIComponent : false,
10994     encodeURI          : false,
10995     encodeURIComponent : false,
10996     Error              : false,
10997     "eval"             : false,
10998     EvalError          : false,
10999     Function           : false,
11000     hasOwnProperty     : false,
11001     isFinite           : false,
11002     isNaN              : false,
11003     Math               : false,
11004     Number             : false,
11005     Object             : false,
11006     parseInt           : false,
11007     parseFloat         : false,
11008     RangeError         : false,
11009     ReferenceError     : false,
11010     RegExp             : false,
11011     String             : false,
11012     SyntaxError        : false,
11013     TypeError          : false,
11014     URIError           : false
11015   },
11016   5: {
11017     JSON               : false
11018   },
11019   6: {
11020     Map                : false,
11021     Promise            : false,
11022     Proxy              : false,
11023     Reflect            : false,
11024     Set                : false,
11025     Symbol             : false,
11026     WeakMap            : false,
11027     WeakSet            : false
11028   }
11029 };
11030
11031 exports.browser = {
11032   Audio                : false,
11033   Blob                 : false,
11034   addEventListener     : false,
11035   applicationCache     : false,
11036   atob                 : false,
11037   blur                 : false,
11038   btoa                 : false,
11039   cancelAnimationFrame : false,
11040   CanvasGradient       : false,
11041   CanvasPattern        : false,
11042   CanvasRenderingContext2D: false,
11043   CSS                  : false,
11044   clearInterval        : false,
11045   clearTimeout         : false,
11046   close                : false,
11047   closed               : false,
11048   Comment              : false,
11049   CustomEvent          : false,
11050   DOMParser            : false,
11051   defaultStatus        : false,
11052   Document             : false,
11053   document             : false,
11054   DocumentFragment     : false,
11055   Element              : false,
11056   ElementTimeControl   : false,
11057   Event                : false,
11058   event                : false,
11059   fetch                : false,
11060   FileReader           : false,
11061   FormData             : false,
11062   focus                : false,
11063   frames               : false,
11064   getComputedStyle     : false,
11065   HTMLElement          : false,
11066   HTMLAnchorElement    : false,
11067   HTMLBaseElement      : false,
11068   HTMLBlockquoteElement: false,
11069   HTMLBodyElement      : false,
11070   HTMLBRElement        : false,
11071   HTMLButtonElement    : false,
11072   HTMLCanvasElement    : false,
11073   HTMLCollection       : false,
11074   HTMLDirectoryElement : false,
11075   HTMLDivElement       : false,
11076   HTMLDListElement     : false,
11077   HTMLFieldSetElement  : false,
11078   HTMLFontElement      : false,
11079   HTMLFormElement      : false,
11080   HTMLFrameElement     : false,
11081   HTMLFrameSetElement  : false,
11082   HTMLHeadElement      : false,
11083   HTMLHeadingElement   : false,
11084   HTMLHRElement        : false,
11085   HTMLHtmlElement      : false,
11086   HTMLIFrameElement    : false,
11087   HTMLImageElement     : false,
11088   HTMLInputElement     : false,
11089   HTMLIsIndexElement   : false,
11090   HTMLLabelElement     : false,
11091   HTMLLayerElement     : false,
11092   HTMLLegendElement    : false,
11093   HTMLLIElement        : false,
11094   HTMLLinkElement      : false,
11095   HTMLMapElement       : false,
11096   HTMLMenuElement      : false,
11097   HTMLMetaElement      : false,
11098   HTMLModElement       : false,
11099   HTMLObjectElement    : false,
11100   HTMLOListElement     : false,
11101   HTMLOptGroupElement  : false,
11102   HTMLOptionElement    : false,
11103   HTMLParagraphElement : false,
11104   HTMLParamElement     : false,
11105   HTMLPreElement       : false,
11106   HTMLQuoteElement     : false,
11107   HTMLScriptElement    : false,
11108   HTMLSelectElement    : false,
11109   HTMLStyleElement     : false,
11110   HTMLTableCaptionElement: false,
11111   HTMLTableCellElement : false,
11112   HTMLTableColElement  : false,
11113   HTMLTableElement     : false,
11114   HTMLTableRowElement  : false,
11115   HTMLTableSectionElement: false,
11116   HTMLTemplateElement  : false,
11117   HTMLTextAreaElement  : false,
11118   HTMLTitleElement     : false,
11119   HTMLUListElement     : false,
11120   HTMLVideoElement     : false,
11121   history              : false,
11122   Image                : false,
11123   Intl                 : false,
11124   length               : false,
11125   localStorage         : false,
11126   location             : false,
11127   matchMedia           : false,
11128   MessageChannel       : false,
11129   MessageEvent         : false,
11130   MessagePort          : false,
11131   MouseEvent           : false,
11132   moveBy               : false,
11133   moveTo               : false,
11134   MutationObserver     : false,
11135   name                 : false,
11136   Node                 : false,
11137   NodeFilter           : false,
11138   NodeList             : false,
11139   Notification         : false,
11140   navigator            : false,
11141   onbeforeunload       : true,
11142   onblur               : true,
11143   onerror              : true,
11144   onfocus              : true,
11145   onload               : true,
11146   onresize             : true,
11147   onunload             : true,
11148   open                 : false,
11149   openDatabase         : false,
11150   opener               : false,
11151   Option               : false,
11152   parent               : false,
11153   performance          : false,
11154   print                : false,
11155   Range                : false,
11156   requestAnimationFrame : false,
11157   removeEventListener  : false,
11158   resizeBy             : false,
11159   resizeTo             : false,
11160   screen               : false,
11161   scroll               : false,
11162   scrollBy             : false,
11163   scrollTo             : false,
11164   sessionStorage       : false,
11165   setInterval          : false,
11166   setTimeout           : false,
11167   SharedWorker         : false,
11168   status               : false,
11169   SVGAElement          : false,
11170   SVGAltGlyphDefElement: false,
11171   SVGAltGlyphElement   : false,
11172   SVGAltGlyphItemElement: false,
11173   SVGAngle             : false,
11174   SVGAnimateColorElement: false,
11175   SVGAnimateElement    : false,
11176   SVGAnimateMotionElement: false,
11177   SVGAnimateTransformElement: false,
11178   SVGAnimatedAngle     : false,
11179   SVGAnimatedBoolean   : false,
11180   SVGAnimatedEnumeration: false,
11181   SVGAnimatedInteger   : false,
11182   SVGAnimatedLength    : false,
11183   SVGAnimatedLengthList: false,
11184   SVGAnimatedNumber    : false,
11185   SVGAnimatedNumberList: false,
11186   SVGAnimatedPathData  : false,
11187   SVGAnimatedPoints    : false,
11188   SVGAnimatedPreserveAspectRatio: false,
11189   SVGAnimatedRect      : false,
11190   SVGAnimatedString    : false,
11191   SVGAnimatedTransformList: false,
11192   SVGAnimationElement  : false,
11193   SVGCSSRule           : false,
11194   SVGCircleElement     : false,
11195   SVGClipPathElement   : false,
11196   SVGColor             : false,
11197   SVGColorProfileElement: false,
11198   SVGColorProfileRule  : false,
11199   SVGComponentTransferFunctionElement: false,
11200   SVGCursorElement     : false,
11201   SVGDefsElement       : false,
11202   SVGDescElement       : false,
11203   SVGDocument          : false,
11204   SVGElement           : false,
11205   SVGElementInstance   : false,
11206   SVGElementInstanceList: false,
11207   SVGEllipseElement    : false,
11208   SVGExternalResourcesRequired: false,
11209   SVGFEBlendElement    : false,
11210   SVGFEColorMatrixElement: false,
11211   SVGFEComponentTransferElement: false,
11212   SVGFECompositeElement: false,
11213   SVGFEConvolveMatrixElement: false,
11214   SVGFEDiffuseLightingElement: false,
11215   SVGFEDisplacementMapElement: false,
11216   SVGFEDistantLightElement: false,
11217   SVGFEFloodElement    : false,
11218   SVGFEFuncAElement    : false,
11219   SVGFEFuncBElement    : false,
11220   SVGFEFuncGElement    : false,
11221   SVGFEFuncRElement    : false,
11222   SVGFEGaussianBlurElement: false,
11223   SVGFEImageElement    : false,
11224   SVGFEMergeElement    : false,
11225   SVGFEMergeNodeElement: false,
11226   SVGFEMorphologyElement: false,
11227   SVGFEOffsetElement   : false,
11228   SVGFEPointLightElement: false,
11229   SVGFESpecularLightingElement: false,
11230   SVGFESpotLightElement: false,
11231   SVGFETileElement     : false,
11232   SVGFETurbulenceElement: false,
11233   SVGFilterElement     : false,
11234   SVGFilterPrimitiveStandardAttributes: false,
11235   SVGFitToViewBox      : false,
11236   SVGFontElement       : false,
11237   SVGFontFaceElement   : false,
11238   SVGFontFaceFormatElement: false,
11239   SVGFontFaceNameElement: false,
11240   SVGFontFaceSrcElement: false,
11241   SVGFontFaceUriElement: false,
11242   SVGForeignObjectElement: false,
11243   SVGGElement          : false,
11244   SVGGlyphElement      : false,
11245   SVGGlyphRefElement   : false,
11246   SVGGradientElement   : false,
11247   SVGHKernElement      : false,
11248   SVGICCColor          : false,
11249   SVGImageElement      : false,
11250   SVGLangSpace         : false,
11251   SVGLength            : false,
11252   SVGLengthList        : false,
11253   SVGLineElement       : false,
11254   SVGLinearGradientElement: false,
11255   SVGLocatable         : false,
11256   SVGMPathElement      : false,
11257   SVGMarkerElement     : false,
11258   SVGMaskElement       : false,
11259   SVGMatrix            : false,
11260   SVGMetadataElement   : false,
11261   SVGMissingGlyphElement: false,
11262   SVGNumber            : false,
11263   SVGNumberList        : false,
11264   SVGPaint             : false,
11265   SVGPathElement       : false,
11266   SVGPathSeg           : false,
11267   SVGPathSegArcAbs     : false,
11268   SVGPathSegArcRel     : false,
11269   SVGPathSegClosePath  : false,
11270   SVGPathSegCurvetoCubicAbs: false,
11271   SVGPathSegCurvetoCubicRel: false,
11272   SVGPathSegCurvetoCubicSmoothAbs: false,
11273   SVGPathSegCurvetoCubicSmoothRel: false,
11274   SVGPathSegCurvetoQuadraticAbs: false,
11275   SVGPathSegCurvetoQuadraticRel: false,
11276   SVGPathSegCurvetoQuadraticSmoothAbs: false,
11277   SVGPathSegCurvetoQuadraticSmoothRel: false,
11278   SVGPathSegLinetoAbs  : false,
11279   SVGPathSegLinetoHorizontalAbs: false,
11280   SVGPathSegLinetoHorizontalRel: false,
11281   SVGPathSegLinetoRel  : false,
11282   SVGPathSegLinetoVerticalAbs: false,
11283   SVGPathSegLinetoVerticalRel: false,
11284   SVGPathSegList       : false,
11285   SVGPathSegMovetoAbs  : false,
11286   SVGPathSegMovetoRel  : false,
11287   SVGPatternElement    : false,
11288   SVGPoint             : false,
11289   SVGPointList         : false,
11290   SVGPolygonElement    : false,
11291   SVGPolylineElement   : false,
11292   SVGPreserveAspectRatio: false,
11293   SVGRadialGradientElement: false,
11294   SVGRect              : false,
11295   SVGRectElement       : false,
11296   SVGRenderingIntent   : false,
11297   SVGSVGElement        : false,
11298   SVGScriptElement     : false,
11299   SVGSetElement        : false,
11300   SVGStopElement       : false,
11301   SVGStringList        : false,
11302   SVGStylable          : false,
11303   SVGStyleElement      : false,
11304   SVGSwitchElement     : false,
11305   SVGSymbolElement     : false,
11306   SVGTRefElement       : false,
11307   SVGTSpanElement      : false,
11308   SVGTests             : false,
11309   SVGTextContentElement: false,
11310   SVGTextElement       : false,
11311   SVGTextPathElement   : false,
11312   SVGTextPositioningElement: false,
11313   SVGTitleElement      : false,
11314   SVGTransform         : false,
11315   SVGTransformList     : false,
11316   SVGTransformable     : false,
11317   SVGURIReference      : false,
11318   SVGUnitTypes         : false,
11319   SVGUseElement        : false,
11320   SVGVKernElement      : false,
11321   SVGViewElement       : false,
11322   SVGViewSpec          : false,
11323   SVGZoomAndPan        : false,
11324   Text                 : false,
11325   TextDecoder          : false,
11326   TextEncoder          : false,
11327   TimeEvent            : false,
11328   top                  : false,
11329   URL                  : false,
11330   WebGLActiveInfo      : false,
11331   WebGLBuffer          : false,
11332   WebGLContextEvent    : false,
11333   WebGLFramebuffer     : false,
11334   WebGLProgram         : false,
11335   WebGLRenderbuffer    : false,
11336   WebGLRenderingContext: false,
11337   WebGLShader          : false,
11338   WebGLShaderPrecisionFormat: false,
11339   WebGLTexture         : false,
11340   WebGLUniformLocation : false,
11341   WebSocket            : false,
11342   window               : false,
11343   Window               : false,
11344   Worker               : false,
11345   XDomainRequest       : false,
11346   XMLHttpRequest       : false,
11347   XMLSerializer        : false,
11348   XPathEvaluator       : false,
11349   XPathException       : false,
11350   XPathExpression      : false,
11351   XPathNamespace       : false,
11352   XPathNSResolver      : false,
11353   XPathResult          : false
11354 };
11355
11356 exports.devel = {
11357   alert  : false,
11358   confirm: false,
11359   console: false,
11360   Debug  : false,
11361   opera  : false,
11362   prompt : false
11363 };
11364
11365 exports.worker = {
11366   importScripts  : true,
11367   postMessage    : true,
11368   self           : true,
11369   FileReaderSync : true
11370 };
11371 exports.nonstandard = {
11372   escape  : false,
11373   unescape: false
11374 };
11375
11376 exports.couch = {
11377   "require" : false,
11378   respond   : false,
11379   getRow    : false,
11380   emit      : false,
11381   send      : false,
11382   start     : false,
11383   sum       : false,
11384   log       : false,
11385   exports   : false,
11386   module    : false,
11387   provides  : false
11388 };
11389
11390 exports.node = {
11391   __filename    : false,
11392   __dirname     : false,
11393   GLOBAL        : false,
11394   global        : false,
11395   module        : false,
11396   require       : false,
11397
11398   Buffer        : true,
11399   console       : true,
11400   exports       : true,
11401   process       : true,
11402   setTimeout    : true,
11403   clearTimeout  : true,
11404   setInterval   : true,
11405   clearInterval : true,
11406   setImmediate  : true, // v0.9.1+
11407   clearImmediate: true  // v0.9.1+
11408 };
11409
11410 exports.browserify = {
11411   __filename    : false,
11412   __dirname     : false,
11413   global        : false,
11414   module        : false,
11415   require       : false,
11416   Buffer        : true,
11417   exports       : true,
11418   process       : true
11419 };
11420
11421 exports.phantom = {
11422   phantom      : true,
11423   require      : true,
11424   WebPage      : true,
11425   console      : true, // in examples, but undocumented
11426   exports      : true  // v1.7+
11427 };
11428
11429 exports.qunit = {
11430   asyncTest      : false,
11431   deepEqual      : false,
11432   equal          : false,
11433   expect         : false,
11434   module         : false,
11435   notDeepEqual   : false,
11436   notEqual       : false,
11437   notPropEqual   : false,
11438   notStrictEqual : false,
11439   ok             : false,
11440   propEqual      : false,
11441   QUnit          : false,
11442   raises         : false,
11443   start          : false,
11444   stop           : false,
11445   strictEqual    : false,
11446   test           : false,
11447   "throws"       : false
11448 };
11449
11450 exports.rhino = {
11451   defineClass  : false,
11452   deserialize  : false,
11453   gc           : false,
11454   help         : false,
11455   importClass  : false,
11456   importPackage: false,
11457   "java"       : false,
11458   load         : false,
11459   loadClass    : false,
11460   Packages     : false,
11461   print        : false,
11462   quit         : false,
11463   readFile     : false,
11464   readUrl      : false,
11465   runCommand   : false,
11466   seal         : false,
11467   serialize    : false,
11468   spawn        : false,
11469   sync         : false,
11470   toint32      : false,
11471   version      : false
11472 };
11473
11474 exports.shelljs = {
11475   target       : false,
11476   echo         : false,
11477   exit         : false,
11478   cd           : false,
11479   pwd          : false,
11480   ls           : false,
11481   find         : false,
11482   cp           : false,
11483   rm           : false,
11484   mv           : false,
11485   mkdir        : false,
11486   test         : false,
11487   cat          : false,
11488   sed          : false,
11489   grep         : false,
11490   which        : false,
11491   dirs         : false,
11492   pushd        : false,
11493   popd         : false,
11494   env          : false,
11495   exec         : false,
11496   chmod        : false,
11497   config       : false,
11498   error        : false,
11499   tempdir      : false
11500 };
11501
11502 exports.typed = {
11503   ArrayBuffer         : false,
11504   ArrayBufferView     : false,
11505   DataView            : false,
11506   Float32Array        : false,
11507   Float64Array        : false,
11508   Int16Array          : false,
11509   Int32Array          : false,
11510   Int8Array           : false,
11511   Uint16Array         : false,
11512   Uint32Array         : false,
11513   Uint8Array          : false,
11514   Uint8ClampedArray   : false
11515 };
11516
11517 exports.wsh = {
11518   ActiveXObject            : true,
11519   Enumerator               : true,
11520   GetObject                : true,
11521   ScriptEngine             : true,
11522   ScriptEngineBuildVersion : true,
11523   ScriptEngineMajorVersion : true,
11524   ScriptEngineMinorVersion : true,
11525   VBArray                  : true,
11526   WSH                      : true,
11527   WScript                  : true,
11528   XDomainRequest           : true
11529 };
11530
11531 exports.dojo = {
11532   dojo     : false,
11533   dijit    : false,
11534   dojox    : false,
11535   define   : false,
11536   "require": false
11537 };
11538
11539 exports.jquery = {
11540   "$"    : false,
11541   jQuery : false
11542 };
11543
11544 exports.mootools = {
11545   "$"           : false,
11546   "$$"          : false,
11547   Asset         : false,
11548   Browser       : false,
11549   Chain         : false,
11550   Class         : false,
11551   Color         : false,
11552   Cookie        : false,
11553   Core          : false,
11554   Document      : false,
11555   DomReady      : false,
11556   DOMEvent      : false,
11557   DOMReady      : false,
11558   Drag          : false,
11559   Element       : false,
11560   Elements      : false,
11561   Event         : false,
11562   Events        : false,
11563   Fx            : false,
11564   Group         : false,
11565   Hash          : false,
11566   HtmlTable     : false,
11567   IFrame        : false,
11568   IframeShim    : false,
11569   InputValidator: false,
11570   instanceOf    : false,
11571   Keyboard      : false,
11572   Locale        : false,
11573   Mask          : false,
11574   MooTools      : false,
11575   Native        : false,
11576   Options       : false,
11577   OverText      : false,
11578   Request       : false,
11579   Scroller      : false,
11580   Slick         : false,
11581   Slider        : false,
11582   Sortables     : false,
11583   Spinner       : false,
11584   Swiff         : false,
11585   Tips          : false,
11586   Type          : false,
11587   typeOf        : false,
11588   URI           : false,
11589   Window        : false
11590 };
11591
11592 exports.prototypejs = {
11593   "$"               : false,
11594   "$$"              : false,
11595   "$A"              : false,
11596   "$F"              : false,
11597   "$H"              : false,
11598   "$R"              : false,
11599   "$break"          : false,
11600   "$continue"       : false,
11601   "$w"              : false,
11602   Abstract          : false,
11603   Ajax              : false,
11604   Class             : false,
11605   Enumerable        : false,
11606   Element           : false,
11607   Event             : false,
11608   Field             : false,
11609   Form              : false,
11610   Hash              : false,
11611   Insertion         : false,
11612   ObjectRange       : false,
11613   PeriodicalExecuter: false,
11614   Position          : false,
11615   Prototype         : false,
11616   Selector          : false,
11617   Template          : false,
11618   Toggle            : false,
11619   Try               : false,
11620   Autocompleter     : false,
11621   Builder           : false,
11622   Control           : false,
11623   Draggable         : false,
11624   Draggables        : false,
11625   Droppables        : false,
11626   Effect            : false,
11627   Sortable          : false,
11628   SortableObserver  : false,
11629   Sound             : false,
11630   Scriptaculous     : false
11631 };
11632
11633 exports.yui = {
11634   YUI       : false,
11635   Y         : false,
11636   YUI_config: false
11637 };
11638
11639 exports.mocha = {
11640   mocha       : false,
11641   describe    : false,
11642   xdescribe   : false,
11643   it          : false,
11644   xit         : false,
11645   context     : false,
11646   xcontext    : false,
11647   before      : false,
11648   after       : false,
11649   beforeEach  : false,
11650   afterEach   : false,
11651   suite         : false,
11652   test          : false,
11653   setup         : false,
11654   teardown      : false,
11655   suiteSetup    : false,
11656   suiteTeardown : false
11657 };
11658
11659 exports.jasmine = {
11660   jasmine     : false,
11661   describe    : false,
11662   xdescribe   : false,
11663   it          : false,
11664   xit         : false,
11665   beforeEach  : false,
11666   afterEach   : false,
11667   setFixtures : false,
11668   loadFixtures: false,
11669   spyOn       : false,
11670   expect      : false,
11671   runs        : false,
11672   waitsFor    : false,
11673   waits       : false,
11674   beforeAll   : false,
11675   afterAll    : false,
11676   fail        : false,
11677   fdescribe   : false,
11678   fit         : false,
11679   pending     : false
11680 };
11681
11682 },{}]},{},["/node_modules/jshint/src/jshint.js"]);
11683
11684 });
11685
11686 define("ace/mode/javascript_worker",["require","exports","module","ace/lib/oop","ace/worker/mirror","ace/mode/javascript/jshint"], function(require, exports, module) {
11687 "use strict";
11688
11689 var oop = require("../lib/oop");
11690 var Mirror = require("../worker/mirror").Mirror;
11691 var lint = require("./javascript/jshint").JSHINT;
11692
11693 function startRegex(arr) {
11694     return RegExp("^(" + arr.join("|") + ")");
11695 }
11696
11697 var disabledWarningsRe = startRegex([
11698     "Bad for in variable '(.+)'.",
11699     'Missing "use strict"'
11700 ]);
11701 var errorsRe = startRegex([
11702     "Unexpected",
11703     "Expected ",
11704     "Confusing (plus|minus)",
11705     "\\{a\\} unterminated regular expression",
11706     "Unclosed ",
11707     "Unmatched ",
11708     "Unbegun comment",
11709     "Bad invocation",
11710     "Missing space after",
11711     "Missing operator at"
11712 ]);
11713 var infoRe = startRegex([
11714     "Expected an assignment",
11715     "Bad escapement of EOL",
11716     "Unexpected comma",
11717     "Unexpected space",
11718     "Missing radix parameter.",
11719     "A leading decimal point can",
11720     "\\['{a}'\\] is better written in dot notation.",
11721     "'{a}' used out of scope"
11722 ]);
11723
11724 var JavaScriptWorker = exports.JavaScriptWorker = function(sender) {
11725     Mirror.call(this, sender);
11726     this.setTimeout(500);
11727     this.setOptions();
11728 };
11729
11730 oop.inherits(JavaScriptWorker, Mirror);
11731
11732 (function() {
11733     this.setOptions = function(options) {
11734         this.options = options || {
11735             esnext: true,
11736             moz: true,
11737             devel: true,
11738             browser: true,
11739             node: true,
11740             laxcomma: true,
11741             laxbreak: true,
11742             lastsemic: true,
11743             onevar: false,
11744             passfail: false,
11745             maxerr: 100,
11746             expr: true,
11747             multistr: true,
11748             globalstrict: true
11749         };
11750         this.doc.getValue() && this.deferredUpdate.schedule(100);
11751     };
11752
11753     this.changeOptions = function(newOptions) {
11754         oop.mixin(this.options, newOptions);
11755         this.doc.getValue() && this.deferredUpdate.schedule(100);
11756     };
11757
11758     this.isValidJS = function(str) {
11759         try {
11760             eval("throw 0;" + str);
11761         } catch(e) {
11762             if (e === 0)
11763                 return true;
11764         }
11765         return false;
11766     };
11767
11768     this.onUpdate = function() {
11769         var value = this.doc.getValue();
11770         value = value.replace(/^#!.*\n/, "\n");
11771         if (!value)
11772             return this.sender.emit("annotate", []);
11773
11774         var errors = [];
11775         var maxErrorLevel = this.isValidJS(value) ? "warning" : "error";
11776         lint(value, this.options, this.options.globals);
11777         var results = lint.errors;
11778
11779         var errorAdded = false;
11780         for (var i = 0; i < results.length; i++) {
11781             var error = results[i];
11782             if (!error)
11783                 continue;
11784             var raw = error.raw;
11785             var type = "warning";
11786
11787             if (raw == "Missing semicolon.") {
11788                 var str = error.evidence.substr(error.character);
11789                 str = str.charAt(str.search(/\S/));
11790                 if (maxErrorLevel == "error" && str && /[\w\d{(['"]/.test(str)) {
11791                     error.reason = 'Missing ";" before statement';
11792                     type = "error";
11793                 } else {
11794                     type = "info";
11795                 }
11796             }
11797             else if (disabledWarningsRe.test(raw)) {
11798                 continue;
11799             }
11800             else if (infoRe.test(raw)) {
11801                 type = "info";
11802             }
11803             else if (errorsRe.test(raw)) {
11804                 errorAdded  = true;
11805                 type = maxErrorLevel;
11806             }
11807             else if (raw == "'{a}' is not defined.") {
11808                 type = "warning";
11809             }
11810             else if (raw == "'{a}' is defined but never used.") {
11811                 type = "info";
11812             }
11813
11814             errors.push({
11815                 row: error.line-1,
11816                 column: error.character-1,
11817                 text: error.reason,
11818                 type: type,
11819                 raw: raw
11820             });
11821
11822             if (errorAdded) {
11823             }
11824         }
11825
11826         this.sender.emit("annotate", errors);
11827     };
11828
11829 }).call(JavaScriptWorker.prototype);
11830
11831 });
11832
11833 define("ace/lib/es5-shim",["require","exports","module"], function(require, exports, module) {
11834
11835 function Empty() {}
11836
11837 if (!Function.prototype.bind) {
11838     Function.prototype.bind = function bind(that) { // .length is 1
11839         var target = this;
11840         if (typeof target != "function") {
11841             throw new TypeError("Function.prototype.bind called on incompatible " + target);
11842         }
11843         var args = slice.call(arguments, 1); // for normal call
11844         var bound = function () {
11845
11846             if (this instanceof bound) {
11847
11848                 var result = target.apply(
11849                     this,
11850                     args.concat(slice.call(arguments))
11851                 );
11852                 if (Object(result) === result) {
11853                     return result;
11854                 }
11855                 return this;
11856
11857             } else {
11858                 return target.apply(
11859                     that,
11860                     args.concat(slice.call(arguments))
11861                 );
11862
11863             }
11864
11865         };
11866         if(target.prototype) {
11867             Empty.prototype = target.prototype;
11868             bound.prototype = new Empty();
11869             Empty.prototype = null;
11870         }
11871         return bound;
11872     };
11873 }
11874 var call = Function.prototype.call;
11875 var prototypeOfArray = Array.prototype;
11876 var prototypeOfObject = Object.prototype;
11877 var slice = prototypeOfArray.slice;
11878 var _toString = call.bind(prototypeOfObject.toString);
11879 var owns = call.bind(prototypeOfObject.hasOwnProperty);
11880 var defineGetter;
11881 var defineSetter;
11882 var lookupGetter;
11883 var lookupSetter;
11884 var supportsAccessors;
11885 if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
11886     defineGetter = call.bind(prototypeOfObject.__defineGetter__);
11887     defineSetter = call.bind(prototypeOfObject.__defineSetter__);
11888     lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
11889     lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
11890 }
11891 if ([1,2].splice(0).length != 2) {
11892     if(function() { // test IE < 9 to splice bug - see issue #138
11893         function makeArray(l) {
11894             var a = new Array(l+2);
11895             a[0] = a[1] = 0;
11896             return a;
11897         }
11898         var array = [], lengthBefore;
11899         
11900         array.splice.apply(array, makeArray(20));
11901         array.splice.apply(array, makeArray(26));
11902
11903         lengthBefore = array.length; //46
11904         array.splice(5, 0, "XXX"); // add one element
11905
11906         lengthBefore + 1 == array.length
11907
11908         if (lengthBefore + 1 == array.length) {
11909             return true;// has right splice implementation without bugs
11910         }
11911     }()) {//IE 6/7
11912         var array_splice = Array.prototype.splice;
11913         Array.prototype.splice = function(start, deleteCount) {
11914             if (!arguments.length) {
11915                 return [];
11916             } else {
11917                 return array_splice.apply(this, [
11918                     start === void 0 ? 0 : start,
11919                     deleteCount === void 0 ? (this.length - start) : deleteCount
11920                 ].concat(slice.call(arguments, 2)))
11921             }
11922         };
11923     } else {//IE8
11924         Array.prototype.splice = function(pos, removeCount){
11925             var length = this.length;
11926             if (pos > 0) {
11927                 if (pos > length)
11928                     pos = length;
11929             } else if (pos == void 0) {
11930                 pos = 0;
11931             } else if (pos < 0) {
11932                 pos = Math.max(length + pos, 0);
11933             }
11934
11935             if (!(pos+removeCount < length))
11936                 removeCount = length - pos;
11937
11938             var removed = this.slice(pos, pos+removeCount);
11939             var insert = slice.call(arguments, 2);
11940             var add = insert.length;            
11941             if (pos === length) {
11942                 if (add) {
11943                     this.push.apply(this, insert);
11944                 }
11945             } else {
11946                 var remove = Math.min(removeCount, length - pos);
11947                 var tailOldPos = pos + remove;
11948                 var tailNewPos = tailOldPos + add - remove;
11949                 var tailCount = length - tailOldPos;
11950                 var lengthAfterRemove = length - remove;
11951
11952                 if (tailNewPos < tailOldPos) { // case A
11953                     for (var i = 0; i < tailCount; ++i) {
11954                         this[tailNewPos+i] = this[tailOldPos+i];
11955                     }
11956                 } else if (tailNewPos > tailOldPos) { // case B
11957                     for (i = tailCount; i--; ) {
11958                         this[tailNewPos+i] = this[tailOldPos+i];
11959                     }
11960                 } // else, add == remove (nothing to do)
11961
11962                 if (add && pos === lengthAfterRemove) {
11963                     this.length = lengthAfterRemove; // truncate array
11964                     this.push.apply(this, insert);
11965                 } else {
11966                     this.length = lengthAfterRemove + add; // reserves space
11967                     for (i = 0; i < add; ++i) {
11968                         this[pos+i] = insert[i];
11969                     }
11970                 }
11971             }
11972             return removed;
11973         };
11974     }
11975 }
11976 if (!Array.isArray) {
11977     Array.isArray = function isArray(obj) {
11978         return _toString(obj) == "[object Array]";
11979     };
11980 }
11981 var boxedString = Object("a"),
11982     splitString = boxedString[0] != "a" || !(0 in boxedString);
11983
11984 if (!Array.prototype.forEach) {
11985     Array.prototype.forEach = function forEach(fun /*, thisp*/) {
11986         var object = toObject(this),
11987             self = splitString && _toString(this) == "[object String]" ?
11988                 this.split("") :
11989                 object,
11990             thisp = arguments[1],
11991             i = -1,
11992             length = self.length >>> 0;
11993         if (_toString(fun) != "[object Function]") {
11994             throw new TypeError(); // TODO message
11995         }
11996
11997         while (++i < length) {
11998             if (i in self) {
11999                 fun.call(thisp, self[i], i, object);
12000             }
12001         }
12002     };
12003 }
12004 if (!Array.prototype.map) {
12005     Array.prototype.map = function map(fun /*, thisp*/) {
12006         var object = toObject(this),
12007             self = splitString && _toString(this) == "[object String]" ?
12008                 this.split("") :
12009                 object,
12010             length = self.length >>> 0,
12011             result = Array(length),
12012             thisp = arguments[1];
12013         if (_toString(fun) != "[object Function]") {
12014             throw new TypeError(fun + " is not a function");
12015         }
12016
12017         for (var i = 0; i < length; i++) {
12018             if (i in self)
12019                 result[i] = fun.call(thisp, self[i], i, object);
12020         }
12021         return result;
12022     };
12023 }
12024 if (!Array.prototype.filter) {
12025     Array.prototype.filter = function filter(fun /*, thisp */) {
12026         var object = toObject(this),
12027             self = splitString && _toString(this) == "[object String]" ?
12028                 this.split("") :
12029                     object,
12030             length = self.length >>> 0,
12031             result = [],
12032             value,
12033             thisp = arguments[1];
12034         if (_toString(fun) != "[object Function]") {
12035             throw new TypeError(fun + " is not a function");
12036         }
12037
12038         for (var i = 0; i < length; i++) {
12039             if (i in self) {
12040                 value = self[i];
12041                 if (fun.call(thisp, value, i, object)) {
12042                     result.push(value);
12043                 }
12044             }
12045         }
12046         return result;
12047     };
12048 }
12049 if (!Array.prototype.every) {
12050     Array.prototype.every = function every(fun /*, thisp */) {
12051         var object = toObject(this),
12052             self = splitString && _toString(this) == "[object String]" ?
12053                 this.split("") :
12054                 object,
12055             length = self.length >>> 0,
12056             thisp = arguments[1];
12057         if (_toString(fun) != "[object Function]") {
12058             throw new TypeError(fun + " is not a function");
12059         }
12060
12061         for (var i = 0; i < length; i++) {
12062             if (i in self && !fun.call(thisp, self[i], i, object)) {
12063                 return false;
12064             }
12065         }
12066         return true;
12067     };
12068 }
12069 if (!Array.prototype.some) {
12070     Array.prototype.some = function some(fun /*, thisp */) {
12071         var object = toObject(this),
12072             self = splitString && _toString(this) == "[object String]" ?
12073                 this.split("") :
12074                 object,
12075             length = self.length >>> 0,
12076             thisp = arguments[1];
12077         if (_toString(fun) != "[object Function]") {
12078             throw new TypeError(fun + " is not a function");
12079         }
12080
12081         for (var i = 0; i < length; i++) {
12082             if (i in self && fun.call(thisp, self[i], i, object)) {
12083                 return true;
12084             }
12085         }
12086         return false;
12087     };
12088 }
12089 if (!Array.prototype.reduce) {
12090     Array.prototype.reduce = function reduce(fun /*, initial*/) {
12091         var object = toObject(this),
12092             self = splitString && _toString(this) == "[object String]" ?
12093                 this.split("") :
12094                 object,
12095             length = self.length >>> 0;
12096         if (_toString(fun) != "[object Function]") {
12097             throw new TypeError(fun + " is not a function");
12098         }
12099         if (!length && arguments.length == 1) {
12100             throw new TypeError("reduce of empty array with no initial value");
12101         }
12102
12103         var i = 0;
12104         var result;
12105         if (arguments.length >= 2) {
12106             result = arguments[1];
12107         } else {
12108             do {
12109                 if (i in self) {
12110                     result = self[i++];
12111                     break;
12112                 }
12113                 if (++i >= length) {
12114                     throw new TypeError("reduce of empty array with no initial value");
12115                 }
12116             } while (true);
12117         }
12118
12119         for (; i < length; i++) {
12120             if (i in self) {
12121                 result = fun.call(void 0, result, self[i], i, object);
12122             }
12123         }
12124
12125         return result;
12126     };
12127 }
12128 if (!Array.prototype.reduceRight) {
12129     Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
12130         var object = toObject(this),
12131             self = splitString && _toString(this) == "[object String]" ?
12132                 this.split("") :
12133                 object,
12134             length = self.length >>> 0;
12135         if (_toString(fun) != "[object Function]") {
12136             throw new TypeError(fun + " is not a function");
12137         }
12138         if (!length && arguments.length == 1) {
12139             throw new TypeError("reduceRight of empty array with no initial value");
12140         }
12141
12142         var result, i = length - 1;
12143         if (arguments.length >= 2) {
12144             result = arguments[1];
12145         } else {
12146             do {
12147                 if (i in self) {
12148                     result = self[i--];
12149                     break;
12150                 }
12151                 if (--i < 0) {
12152                     throw new TypeError("reduceRight of empty array with no initial value");
12153                 }
12154             } while (true);
12155         }
12156
12157         do {
12158             if (i in this) {
12159                 result = fun.call(void 0, result, self[i], i, object);
12160             }
12161         } while (i--);
12162
12163         return result;
12164     };
12165 }
12166 if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {
12167     Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
12168         var self = splitString && _toString(this) == "[object String]" ?
12169                 this.split("") :
12170                 toObject(this),
12171             length = self.length >>> 0;
12172
12173         if (!length) {
12174             return -1;
12175         }
12176
12177         var i = 0;
12178         if (arguments.length > 1) {
12179             i = toInteger(arguments[1]);
12180         }
12181         i = i >= 0 ? i : Math.max(0, length + i);
12182         for (; i < length; i++) {
12183             if (i in self && self[i] === sought) {
12184                 return i;
12185             }
12186         }
12187         return -1;
12188     };
12189 }
12190 if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) {
12191     Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
12192         var self = splitString && _toString(this) == "[object String]" ?
12193                 this.split("") :
12194                 toObject(this),
12195             length = self.length >>> 0;
12196
12197         if (!length) {
12198             return -1;
12199         }
12200         var i = length - 1;
12201         if (arguments.length > 1) {
12202             i = Math.min(i, toInteger(arguments[1]));
12203         }
12204         i = i >= 0 ? i : length - Math.abs(i);
12205         for (; i >= 0; i--) {
12206             if (i in self && sought === self[i]) {
12207                 return i;
12208             }
12209         }
12210         return -1;
12211     };
12212 }
12213 if (!Object.getPrototypeOf) {
12214     Object.getPrototypeOf = function getPrototypeOf(object) {
12215         return object.__proto__ || (
12216             object.constructor ?
12217             object.constructor.prototype :
12218             prototypeOfObject
12219         );
12220     };
12221 }
12222 if (!Object.getOwnPropertyDescriptor) {
12223     var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " +
12224                          "non-object: ";
12225     Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
12226         if ((typeof object != "object" && typeof object != "function") || object === null)
12227             throw new TypeError(ERR_NON_OBJECT + object);
12228         if (!owns(object, property))
12229             return;
12230
12231         var descriptor, getter, setter;
12232         descriptor =  { enumerable: true, configurable: true };
12233         if (supportsAccessors) {
12234             var prototype = object.__proto__;
12235             object.__proto__ = prototypeOfObject;
12236
12237             var getter = lookupGetter(object, property);
12238             var setter = lookupSetter(object, property);
12239             object.__proto__ = prototype;
12240
12241             if (getter || setter) {
12242                 if (getter) descriptor.get = getter;
12243                 if (setter) descriptor.set = setter;
12244                 return descriptor;
12245             }
12246         }
12247         descriptor.value = object[property];
12248         return descriptor;
12249     };
12250 }
12251 if (!Object.getOwnPropertyNames) {
12252     Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
12253         return Object.keys(object);
12254     };
12255 }
12256 if (!Object.create) {
12257     var createEmpty;
12258     if (Object.prototype.__proto__ === null) {
12259         createEmpty = function () {
12260             return { "__proto__": null };
12261         };
12262     } else {
12263         createEmpty = function () {
12264             var empty = {};
12265             for (var i in empty)
12266                 empty[i] = null;
12267             empty.constructor =
12268             empty.hasOwnProperty =
12269             empty.propertyIsEnumerable =
12270             empty.isPrototypeOf =
12271             empty.toLocaleString =
12272             empty.toString =
12273             empty.valueOf =
12274             empty.__proto__ = null;
12275             return empty;
12276         }
12277     }
12278
12279     Object.create = function create(prototype, properties) {
12280         var object;
12281         if (prototype === null) {
12282             object = createEmpty();
12283         } else {
12284             if (typeof prototype != "object")
12285                 throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
12286             var Type = function () {};
12287             Type.prototype = prototype;
12288             object = new Type();
12289             object.__proto__ = prototype;
12290         }
12291         if (properties !== void 0)
12292             Object.defineProperties(object, properties);
12293         return object;
12294     };
12295 }
12296
12297 function doesDefinePropertyWork(object) {
12298     try {
12299         Object.defineProperty(object, "sentinel", {});
12300         return "sentinel" in object;
12301     } catch (exception) {
12302     }
12303 }
12304 if (Object.defineProperty) {
12305     var definePropertyWorksOnObject = doesDefinePropertyWork({});
12306     var definePropertyWorksOnDom = typeof document == "undefined" ||
12307         doesDefinePropertyWork(document.createElement("div"));
12308     if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
12309         var definePropertyFallback = Object.defineProperty;
12310     }
12311 }
12312
12313 if (!Object.defineProperty || definePropertyFallback) {
12314     var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
12315     var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: "
12316     var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
12317                                       "on this javascript engine";
12318
12319     Object.defineProperty = function defineProperty(object, property, descriptor) {
12320         if ((typeof object != "object" && typeof object != "function") || object === null)
12321             throw new TypeError(ERR_NON_OBJECT_TARGET + object);
12322         if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null)
12323             throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
12324         if (definePropertyFallback) {
12325             try {
12326                 return definePropertyFallback.call(Object, object, property, descriptor);
12327             } catch (exception) {
12328             }
12329         }
12330         if (owns(descriptor, "value")) {
12331
12332             if (supportsAccessors && (lookupGetter(object, property) ||
12333                                       lookupSetter(object, property)))
12334             {
12335                 var prototype = object.__proto__;
12336                 object.__proto__ = prototypeOfObject;
12337                 delete object[property];
12338                 object[property] = descriptor.value;
12339                 object.__proto__ = prototype;
12340             } else {
12341                 object[property] = descriptor.value;
12342             }
12343         } else {
12344             if (!supportsAccessors)
12345                 throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
12346             if (owns(descriptor, "get"))
12347                 defineGetter(object, property, descriptor.get);
12348             if (owns(descriptor, "set"))
12349                 defineSetter(object, property, descriptor.set);
12350         }
12351
12352         return object;
12353     };
12354 }
12355 if (!Object.defineProperties) {
12356     Object.defineProperties = function defineProperties(object, properties) {
12357         for (var property in properties) {
12358             if (owns(properties, property))
12359                 Object.defineProperty(object, property, properties[property]);
12360         }
12361         return object;
12362     };
12363 }
12364 if (!Object.seal) {
12365     Object.seal = function seal(object) {
12366         return object;
12367     };
12368 }
12369 if (!Object.freeze) {
12370     Object.freeze = function freeze(object) {
12371         return object;
12372     };
12373 }
12374 try {
12375     Object.freeze(function () {});
12376 } catch (exception) {
12377     Object.freeze = (function freeze(freezeObject) {
12378         return function freeze(object) {
12379             if (typeof object == "function") {
12380                 return object;
12381             } else {
12382                 return freezeObject(object);
12383             }
12384         };
12385     })(Object.freeze);
12386 }
12387 if (!Object.preventExtensions) {
12388     Object.preventExtensions = function preventExtensions(object) {
12389         return object;
12390     };
12391 }
12392 if (!Object.isSealed) {
12393     Object.isSealed = function isSealed(object) {
12394         return false;
12395     };
12396 }
12397 if (!Object.isFrozen) {
12398     Object.isFrozen = function isFrozen(object) {
12399         return false;
12400     };
12401 }
12402 if (!Object.isExtensible) {
12403     Object.isExtensible = function isExtensible(object) {
12404         if (Object(object) === object) {
12405             throw new TypeError(); // TODO message
12406         }
12407         var name = '';
12408         while (owns(object, name)) {
12409             name += '?';
12410         }
12411         object[name] = true;
12412         var returnValue = owns(object, name);
12413         delete object[name];
12414         return returnValue;
12415     };
12416 }
12417 if (!Object.keys) {
12418     var hasDontEnumBug = true,
12419         dontEnums = [
12420             "toString",
12421             "toLocaleString",
12422             "valueOf",
12423             "hasOwnProperty",
12424             "isPrototypeOf",
12425             "propertyIsEnumerable",
12426             "constructor"
12427         ],
12428         dontEnumsLength = dontEnums.length;
12429
12430     for (var key in {"toString": null}) {
12431         hasDontEnumBug = false;
12432     }
12433
12434     Object.keys = function keys(object) {
12435
12436         if (
12437             (typeof object != "object" && typeof object != "function") ||
12438             object === null
12439         ) {
12440             throw new TypeError("Object.keys called on a non-object");
12441         }
12442
12443         var keys = [];
12444         for (var name in object) {
12445             if (owns(object, name)) {
12446                 keys.push(name);
12447             }
12448         }
12449
12450         if (hasDontEnumBug) {
12451             for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
12452                 var dontEnum = dontEnums[i];
12453                 if (owns(object, dontEnum)) {
12454                     keys.push(dontEnum);
12455                 }
12456             }
12457         }
12458         return keys;
12459     };
12460
12461 }
12462 if (!Date.now) {
12463     Date.now = function now() {
12464         return new Date().getTime();
12465     };
12466 }
12467 var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
12468     "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
12469     "\u2029\uFEFF";
12470 if (!String.prototype.trim || ws.trim()) {
12471     ws = "[" + ws + "]";
12472     var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
12473         trimEndRegexp = new RegExp(ws + ws + "*$");
12474     String.prototype.trim = function trim() {
12475         return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
12476     };
12477 }
12478
12479 function toInteger(n) {
12480     n = +n;
12481     if (n !== n) { // isNaN
12482         n = 0;
12483     } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {
12484         n = (n > 0 || -1) * Math.floor(Math.abs(n));
12485     }
12486     return n;
12487 }
12488
12489 function isPrimitive(input) {
12490     var type = typeof input;
12491     return (
12492         input === null ||
12493         type === "undefined" ||
12494         type === "boolean" ||
12495         type === "number" ||
12496         type === "string"
12497     );
12498 }
12499
12500 function toPrimitive(input) {
12501     var val, valueOf, toString;
12502     if (isPrimitive(input)) {
12503         return input;
12504     }
12505     valueOf = input.valueOf;
12506     if (typeof valueOf === "function") {
12507         val = valueOf.call(input);
12508         if (isPrimitive(val)) {
12509             return val;
12510         }
12511     }
12512     toString = input.toString;
12513     if (typeof toString === "function") {
12514         val = toString.call(input);
12515         if (isPrimitive(val)) {
12516             return val;
12517         }
12518     }
12519     throw new TypeError();
12520 }
12521 var toObject = function (o) {
12522     if (o == null) { // this matches both null and undefined
12523         throw new TypeError("can't convert "+o+" to object");
12524     }
12525     return Object(o);
12526 };
12527
12528 });