/lenasys/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/lenasys/trunk

« back to all changes in this revision

Viewing changes to js/ace/worker-javascript.js

  • Committer: a11andoh
  • Date: 2013-05-24 11:28:43 UTC
  • mto: This revision was merged to the branch mainline in revision 97.
  • Revision ID: a11andoh@student.his.se-20130524112843-360je7hu7q13r171
added the cms controller to load all content pages.
added first time registration controller to load the views for the registration
pages.
added and fixed temporarypages for the controllers 
and edited the models to be able to get active courses.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"no use strict";
 
2
;(function(window) {
 
3
if (typeof window.window != "undefined" && window.document) {
 
4
    return;
 
5
}
 
6
 
 
7
window.console = {
 
8
    log: function() {
 
9
        var msgs = Array.prototype.slice.call(arguments, 0);
 
10
        postMessage({type: "log", data: msgs});
 
11
    },
 
12
    error: function() {
 
13
        var msgs = Array.prototype.slice.call(arguments, 0);
 
14
        postMessage({type: "log", data: msgs});
 
15
    }
 
16
};
 
17
window.window = window;
 
18
window.ace = window;
 
19
 
 
20
window.normalizeModule = function(parentId, moduleName) {
 
21
    // normalize plugin requires
 
22
    if (moduleName.indexOf("!") !== -1) {
 
23
        var chunks = moduleName.split("!");
 
24
        return normalizeModule(parentId, chunks[0]) + "!" + normalizeModule(parentId, chunks[1]);
 
25
    }
 
26
    // normalize relative requires
 
27
    if (moduleName.charAt(0) == ".") {
 
28
        var base = parentId.split("/").slice(0, -1).join("/");
 
29
        moduleName = base + "/" + moduleName;
 
30
        
 
31
        while(moduleName.indexOf(".") !== -1 && previous != moduleName) {
 
32
            var previous = moduleName;
 
33
            moduleName = moduleName.replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, "");
 
34
        }
 
35
    }
 
36
    
 
37
    return moduleName;
 
38
};
 
39
 
 
40
window.require = function(parentId, id) {
 
41
    if (!id.charAt)
 
42
        throw new Error("worker.js require() accepts only (parentId, id) as arguments");
 
43
 
 
44
    id = normalizeModule(parentId, id);
 
45
 
 
46
    var module = require.modules[id];
 
47
    if (module) {
 
48
        if (!module.initialized) {
 
49
            module.initialized = true;
 
50
            module.exports = module.factory().exports;
 
51
        }
 
52
        return module.exports;
 
53
    }
 
54
    
 
55
    var chunks = id.split("/");
 
56
    chunks[0] = require.tlns[chunks[0]] || chunks[0];
 
57
    var path = chunks.join("/") + ".js";
 
58
    
 
59
    require.id = id;
 
60
    importScripts(path);
 
61
    return require(parentId, id);    
 
62
};
 
63
 
 
64
require.modules = {};
 
65
require.tlns = {};
 
66
 
 
67
window.define = function(id, deps, factory) {
 
68
    if (arguments.length == 2) {
 
69
        factory = deps;
 
70
        if (typeof id != "string") {
 
71
            deps = id;
 
72
            id = require.id;
 
73
        }
 
74
    } else if (arguments.length == 1) {
 
75
        factory = id;
 
76
        id = require.id;
 
77
    }
 
78
 
 
79
    if (id.indexOf("text!") === 0) 
 
80
        return;
 
81
    
 
82
    var req = function(deps, factory) {
 
83
        return require(id, deps, factory);
 
84
    };
 
85
 
 
86
    require.modules[id] = {
 
87
        factory: function() {
 
88
            var module = {
 
89
                exports: {}
 
90
            };
 
91
            var returnExports = factory(req, module.exports, module);
 
92
            if (returnExports)
 
93
                module.exports = returnExports;
 
94
            return module;
 
95
        }
 
96
    };
 
97
};
 
98
 
 
99
window.initBaseUrls  = function initBaseUrls(topLevelNamespaces) {
 
100
    require.tlns = topLevelNamespaces;
 
101
}
 
102
 
 
103
window.initSender = function initSender() {
 
104
 
 
105
    var EventEmitter = require(null, "ace/lib/event_emitter").EventEmitter;
 
106
    var oop = require(null, "ace/lib/oop");
 
107
    
 
108
    var Sender = function() {};
 
109
    
 
110
    (function() {
 
111
        
 
112
        oop.implement(this, EventEmitter);
 
113
                
 
114
        this.callback = function(data, callbackId) {
 
115
            postMessage({
 
116
                type: "call",
 
117
                id: callbackId,
 
118
                data: data
 
119
            });
 
120
        };
 
121
    
 
122
        this.emit = function(name, data) {
 
123
            postMessage({
 
124
                type: "event",
 
125
                name: name,
 
126
                data: data
 
127
            });
 
128
        };
 
129
        
 
130
    }).call(Sender.prototype);
 
131
    
 
132
    return new Sender();
 
133
}
 
134
 
 
135
window.main = null;
 
136
window.sender = null;
 
137
 
 
138
window.onmessage = function(e) {
 
139
    var msg = e.data;
 
140
    if (msg.command) {
 
141
        if (main[msg.command])
 
142
            main[msg.command].apply(main, msg.args);
 
143
        else
 
144
            throw new Error("Unknown command:" + msg.command);
 
145
    }
 
146
    else if (msg.init) {        
 
147
        initBaseUrls(msg.tlns);
 
148
        require(null, "ace/lib/fixoldbrowsers");
 
149
        sender = initSender();
 
150
        var clazz = require(null, msg.module)[msg.classname];
 
151
        main = new clazz(sender);
 
152
    } 
 
153
    else if (msg.event && sender) {
 
154
        sender._emit(msg.event, msg.data);
 
155
    }
 
156
};
 
157
})(this);// vim:set ts=4 sts=4 sw=4 st:
 
158
 
 
159
define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module' , 'ace/lib/regexp', 'ace/lib/es5-shim'], function(require, exports, module) {
 
160
 
 
161
 
 
162
require("./regexp");
 
163
require("./es5-shim");
 
164
 
 
165
});
 
166
 
 
167
define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require, exports, module) {
 
168
 
 
169
    var real = {
 
170
            exec: RegExp.prototype.exec,
 
171
            test: RegExp.prototype.test,
 
172
            match: String.prototype.match,
 
173
            replace: String.prototype.replace,
 
174
            split: String.prototype.split
 
175
        },
 
176
        compliantExecNpcg = real.exec.call(/()??/, "")[1] === undefined, // check `exec` handling of nonparticipating capturing groups
 
177
        compliantLastIndexIncrement = function () {
 
178
            var x = /^/g;
 
179
            real.test.call(x, "");
 
180
            return !x.lastIndex;
 
181
        }();
 
182
 
 
183
    if (compliantLastIndexIncrement && compliantExecNpcg)
 
184
        return;
 
185
    RegExp.prototype.exec = function (str) {
 
186
        var match = real.exec.apply(this, arguments),
 
187
            name, r2;
 
188
        if ( typeof(str) == 'string' && match) {
 
189
            if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) {
 
190
                r2 = RegExp(this.source, real.replace.call(getNativeFlags(this), "g", ""));
 
191
                real.replace.call(str.slice(match.index), r2, function () {
 
192
                    for (var i = 1; i < arguments.length - 2; i++) {
 
193
                        if (arguments[i] === undefined)
 
194
                            match[i] = undefined;
 
195
                    }
 
196
                });
 
197
            }
 
198
            if (this._xregexp && this._xregexp.captureNames) {
 
199
                for (var i = 1; i < match.length; i++) {
 
200
                    name = this._xregexp.captureNames[i - 1];
 
201
                    if (name)
 
202
                       match[name] = match[i];
 
203
                }
 
204
            }
 
205
            if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))
 
206
                this.lastIndex--;
 
207
        }
 
208
        return match;
 
209
    };
 
210
    if (!compliantLastIndexIncrement) {
 
211
        RegExp.prototype.test = function (str) {
 
212
            var match = real.exec.call(this, str);
 
213
            if (match && this.global && !match[0].length && (this.lastIndex > match.index))
 
214
                this.lastIndex--;
 
215
            return !!match;
 
216
        };
 
217
    }
 
218
 
 
219
    function getNativeFlags (regex) {
 
220
        return (regex.global     ? "g" : "") +
 
221
               (regex.ignoreCase ? "i" : "") +
 
222
               (regex.multiline  ? "m" : "") +
 
223
               (regex.extended   ? "x" : "") + // Proposed for ES4; included in AS3
 
224
               (regex.sticky     ? "y" : "");
 
225
    }
 
226
 
 
227
    function indexOf (array, item, from) {
 
228
        if (Array.prototype.indexOf) // Use the native array method if available
 
229
            return array.indexOf(item, from);
 
230
        for (var i = from || 0; i < array.length; i++) {
 
231
            if (array[i] === item)
 
232
                return i;
 
233
        }
 
234
        return -1;
 
235
    }
 
236
 
 
237
});
 
238
 
 
239
define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) {
 
240
 
 
241
function Empty() {}
 
242
 
 
243
if (!Function.prototype.bind) {
 
244
    Function.prototype.bind = function bind(that) { // .length is 1
 
245
        var target = this;
 
246
        if (typeof target != "function") {
 
247
            throw new TypeError("Function.prototype.bind called on incompatible " + target);
 
248
        }
 
249
        var args = slice.call(arguments, 1); // for normal call
 
250
        var bound = function () {
 
251
 
 
252
            if (this instanceof bound) {
 
253
 
 
254
                var result = target.apply(
 
255
                    this,
 
256
                    args.concat(slice.call(arguments))
 
257
                );
 
258
                if (Object(result) === result) {
 
259
                    return result;
 
260
                }
 
261
                return this;
 
262
 
 
263
            } else {
 
264
                return target.apply(
 
265
                    that,
 
266
                    args.concat(slice.call(arguments))
 
267
                );
 
268
 
 
269
            }
 
270
 
 
271
        };
 
272
        if(target.prototype) {
 
273
            Empty.prototype = target.prototype;
 
274
            bound.prototype = new Empty();
 
275
            Empty.prototype = null;
 
276
        }
 
277
        return bound;
 
278
    };
 
279
}
 
280
var call = Function.prototype.call;
 
281
var prototypeOfArray = Array.prototype;
 
282
var prototypeOfObject = Object.prototype;
 
283
var slice = prototypeOfArray.slice;
 
284
var _toString = call.bind(prototypeOfObject.toString);
 
285
var owns = call.bind(prototypeOfObject.hasOwnProperty);
 
286
var defineGetter;
 
287
var defineSetter;
 
288
var lookupGetter;
 
289
var lookupSetter;
 
290
var supportsAccessors;
 
291
if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
 
292
    defineGetter = call.bind(prototypeOfObject.__defineGetter__);
 
293
    defineSetter = call.bind(prototypeOfObject.__defineSetter__);
 
294
    lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
 
295
    lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
 
296
}
 
297
if ([1,2].splice(0).length != 2) {
 
298
    if(function() { // test IE < 9 to splice bug - see issue #138
 
299
        function makeArray(l) {
 
300
            var a = new Array(l+2);
 
301
            a[0] = a[1] = 0;
 
302
            return a;
 
303
        }
 
304
        var array = [], lengthBefore;
 
305
        
 
306
        array.splice.apply(array, makeArray(20));
 
307
        array.splice.apply(array, makeArray(26));
 
308
 
 
309
        lengthBefore = array.length; //46
 
310
        array.splice(5, 0, "XXX"); // add one element
 
311
 
 
312
        lengthBefore + 1 == array.length
 
313
 
 
314
        if (lengthBefore + 1 == array.length) {
 
315
            return true;// has right splice implementation without bugs
 
316
        }
 
317
    }()) {//IE 6/7
 
318
        var array_splice = Array.prototype.splice;
 
319
        Array.prototype.splice = function(start, deleteCount) {
 
320
            if (!arguments.length) {
 
321
                return [];
 
322
            } else {
 
323
                return array_splice.apply(this, [
 
324
                    start === void 0 ? 0 : start,
 
325
                    deleteCount === void 0 ? (this.length - start) : deleteCount
 
326
                ].concat(slice.call(arguments, 2)))
 
327
            }
 
328
        };
 
329
    } else {//IE8
 
330
        Array.prototype.splice = function(pos, removeCount){
 
331
            var length = this.length;
 
332
            if (pos > 0) {
 
333
                if (pos > length)
 
334
                    pos = length;
 
335
            } else if (pos == void 0) {
 
336
                pos = 0;
 
337
            } else if (pos < 0) {
 
338
                pos = Math.max(length + pos, 0);
 
339
            }
 
340
 
 
341
            if (!(pos+removeCount < length))
 
342
                removeCount = length - pos;
 
343
 
 
344
            var removed = this.slice(pos, pos+removeCount);
 
345
            var insert = slice.call(arguments, 2);
 
346
            var add = insert.length;            
 
347
            if (pos === length) {
 
348
                if (add) {
 
349
                    this.push.apply(this, insert);
 
350
                }
 
351
            } else {
 
352
                var remove = Math.min(removeCount, length - pos);
 
353
                var tailOldPos = pos + remove;
 
354
                var tailNewPos = tailOldPos + add - remove;
 
355
                var tailCount = length - tailOldPos;
 
356
                var lengthAfterRemove = length - remove;
 
357
 
 
358
                if (tailNewPos < tailOldPos) { // case A
 
359
                    for (var i = 0; i < tailCount; ++i) {
 
360
                        this[tailNewPos+i] = this[tailOldPos+i];
 
361
                    }
 
362
                } else if (tailNewPos > tailOldPos) { // case B
 
363
                    for (i = tailCount; i--; ) {
 
364
                        this[tailNewPos+i] = this[tailOldPos+i];
 
365
                    }
 
366
                } // else, add == remove (nothing to do)
 
367
 
 
368
                if (add && pos === lengthAfterRemove) {
 
369
                    this.length = lengthAfterRemove; // truncate array
 
370
                    this.push.apply(this, insert);
 
371
                } else {
 
372
                    this.length = lengthAfterRemove + add; // reserves space
 
373
                    for (i = 0; i < add; ++i) {
 
374
                        this[pos+i] = insert[i];
 
375
                    }
 
376
                }
 
377
            }
 
378
            return removed;
 
379
        };
 
380
    }
 
381
}
 
382
if (!Array.isArray) {
 
383
    Array.isArray = function isArray(obj) {
 
384
        return _toString(obj) == "[object Array]";
 
385
    };
 
386
}
 
387
var boxedString = Object("a"),
 
388
    splitString = boxedString[0] != "a" || !(0 in boxedString);
 
389
 
 
390
if (!Array.prototype.forEach) {
 
391
    Array.prototype.forEach = function forEach(fun /*, thisp*/) {
 
392
        var object = toObject(this),
 
393
            self = splitString && _toString(this) == "[object String]" ?
 
394
                this.split("") :
 
395
                object,
 
396
            thisp = arguments[1],
 
397
            i = -1,
 
398
            length = self.length >>> 0;
 
399
        if (_toString(fun) != "[object Function]") {
 
400
            throw new TypeError(); // TODO message
 
401
        }
 
402
 
 
403
        while (++i < length) {
 
404
            if (i in self) {
 
405
                fun.call(thisp, self[i], i, object);
 
406
            }
 
407
        }
 
408
    };
 
409
}
 
410
if (!Array.prototype.map) {
 
411
    Array.prototype.map = function map(fun /*, thisp*/) {
 
412
        var object = toObject(this),
 
413
            self = splitString && _toString(this) == "[object String]" ?
 
414
                this.split("") :
 
415
                object,
 
416
            length = self.length >>> 0,
 
417
            result = Array(length),
 
418
            thisp = arguments[1];
 
419
        if (_toString(fun) != "[object Function]") {
 
420
            throw new TypeError(fun + " is not a function");
 
421
        }
 
422
 
 
423
        for (var i = 0; i < length; i++) {
 
424
            if (i in self)
 
425
                result[i] = fun.call(thisp, self[i], i, object);
 
426
        }
 
427
        return result;
 
428
    };
 
429
}
 
430
if (!Array.prototype.filter) {
 
431
    Array.prototype.filter = function filter(fun /*, thisp */) {
 
432
        var object = toObject(this),
 
433
            self = splitString && _toString(this) == "[object String]" ?
 
434
                this.split("") :
 
435
                    object,
 
436
            length = self.length >>> 0,
 
437
            result = [],
 
438
            value,
 
439
            thisp = arguments[1];
 
440
        if (_toString(fun) != "[object Function]") {
 
441
            throw new TypeError(fun + " is not a function");
 
442
        }
 
443
 
 
444
        for (var i = 0; i < length; i++) {
 
445
            if (i in self) {
 
446
                value = self[i];
 
447
                if (fun.call(thisp, value, i, object)) {
 
448
                    result.push(value);
 
449
                }
 
450
            }
 
451
        }
 
452
        return result;
 
453
    };
 
454
}
 
455
if (!Array.prototype.every) {
 
456
    Array.prototype.every = function every(fun /*, thisp */) {
 
457
        var object = toObject(this),
 
458
            self = splitString && _toString(this) == "[object String]" ?
 
459
                this.split("") :
 
460
                object,
 
461
            length = self.length >>> 0,
 
462
            thisp = arguments[1];
 
463
        if (_toString(fun) != "[object Function]") {
 
464
            throw new TypeError(fun + " is not a function");
 
465
        }
 
466
 
 
467
        for (var i = 0; i < length; i++) {
 
468
            if (i in self && !fun.call(thisp, self[i], i, object)) {
 
469
                return false;
 
470
            }
 
471
        }
 
472
        return true;
 
473
    };
 
474
}
 
475
if (!Array.prototype.some) {
 
476
    Array.prototype.some = function some(fun /*, thisp */) {
 
477
        var object = toObject(this),
 
478
            self = splitString && _toString(this) == "[object String]" ?
 
479
                this.split("") :
 
480
                object,
 
481
            length = self.length >>> 0,
 
482
            thisp = arguments[1];
 
483
        if (_toString(fun) != "[object Function]") {
 
484
            throw new TypeError(fun + " is not a function");
 
485
        }
 
486
 
 
487
        for (var i = 0; i < length; i++) {
 
488
            if (i in self && fun.call(thisp, self[i], i, object)) {
 
489
                return true;
 
490
            }
 
491
        }
 
492
        return false;
 
493
    };
 
494
}
 
495
if (!Array.prototype.reduce) {
 
496
    Array.prototype.reduce = function reduce(fun /*, initial*/) {
 
497
        var object = toObject(this),
 
498
            self = splitString && _toString(this) == "[object String]" ?
 
499
                this.split("") :
 
500
                object,
 
501
            length = self.length >>> 0;
 
502
        if (_toString(fun) != "[object Function]") {
 
503
            throw new TypeError(fun + " is not a function");
 
504
        }
 
505
        if (!length && arguments.length == 1) {
 
506
            throw new TypeError("reduce of empty array with no initial value");
 
507
        }
 
508
 
 
509
        var i = 0;
 
510
        var result;
 
511
        if (arguments.length >= 2) {
 
512
            result = arguments[1];
 
513
        } else {
 
514
            do {
 
515
                if (i in self) {
 
516
                    result = self[i++];
 
517
                    break;
 
518
                }
 
519
                if (++i >= length) {
 
520
                    throw new TypeError("reduce of empty array with no initial value");
 
521
                }
 
522
            } while (true);
 
523
        }
 
524
 
 
525
        for (; i < length; i++) {
 
526
            if (i in self) {
 
527
                result = fun.call(void 0, result, self[i], i, object);
 
528
            }
 
529
        }
 
530
 
 
531
        return result;
 
532
    };
 
533
}
 
534
if (!Array.prototype.reduceRight) {
 
535
    Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
 
536
        var object = toObject(this),
 
537
            self = splitString && _toString(this) == "[object String]" ?
 
538
                this.split("") :
 
539
                object,
 
540
            length = self.length >>> 0;
 
541
        if (_toString(fun) != "[object Function]") {
 
542
            throw new TypeError(fun + " is not a function");
 
543
        }
 
544
        if (!length && arguments.length == 1) {
 
545
            throw new TypeError("reduceRight of empty array with no initial value");
 
546
        }
 
547
 
 
548
        var result, i = length - 1;
 
549
        if (arguments.length >= 2) {
 
550
            result = arguments[1];
 
551
        } else {
 
552
            do {
 
553
                if (i in self) {
 
554
                    result = self[i--];
 
555
                    break;
 
556
                }
 
557
                if (--i < 0) {
 
558
                    throw new TypeError("reduceRight of empty array with no initial value");
 
559
                }
 
560
            } while (true);
 
561
        }
 
562
 
 
563
        do {
 
564
            if (i in this) {
 
565
                result = fun.call(void 0, result, self[i], i, object);
 
566
            }
 
567
        } while (i--);
 
568
 
 
569
        return result;
 
570
    };
 
571
}
 
572
if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {
 
573
    Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
 
574
        var self = splitString && _toString(this) == "[object String]" ?
 
575
                this.split("") :
 
576
                toObject(this),
 
577
            length = self.length >>> 0;
 
578
 
 
579
        if (!length) {
 
580
            return -1;
 
581
        }
 
582
 
 
583
        var i = 0;
 
584
        if (arguments.length > 1) {
 
585
            i = toInteger(arguments[1]);
 
586
        }
 
587
        i = i >= 0 ? i : Math.max(0, length + i);
 
588
        for (; i < length; i++) {
 
589
            if (i in self && self[i] === sought) {
 
590
                return i;
 
591
            }
 
592
        }
 
593
        return -1;
 
594
    };
 
595
}
 
596
if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) {
 
597
    Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
 
598
        var self = splitString && _toString(this) == "[object String]" ?
 
599
                this.split("") :
 
600
                toObject(this),
 
601
            length = self.length >>> 0;
 
602
 
 
603
        if (!length) {
 
604
            return -1;
 
605
        }
 
606
        var i = length - 1;
 
607
        if (arguments.length > 1) {
 
608
            i = Math.min(i, toInteger(arguments[1]));
 
609
        }
 
610
        i = i >= 0 ? i : length - Math.abs(i);
 
611
        for (; i >= 0; i--) {
 
612
            if (i in self && sought === self[i]) {
 
613
                return i;
 
614
            }
 
615
        }
 
616
        return -1;
 
617
    };
 
618
}
 
619
if (!Object.getPrototypeOf) {
 
620
    Object.getPrototypeOf = function getPrototypeOf(object) {
 
621
        return object.__proto__ || (
 
622
            object.constructor ?
 
623
            object.constructor.prototype :
 
624
            prototypeOfObject
 
625
        );
 
626
    };
 
627
}
 
628
if (!Object.getOwnPropertyDescriptor) {
 
629
    var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " +
 
630
                         "non-object: ";
 
631
    Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
 
632
        if ((typeof object != "object" && typeof object != "function") || object === null)
 
633
            throw new TypeError(ERR_NON_OBJECT + object);
 
634
        if (!owns(object, property))
 
635
            return;
 
636
 
 
637
        var descriptor, getter, setter;
 
638
        descriptor =  { enumerable: true, configurable: true };
 
639
        if (supportsAccessors) {
 
640
            var prototype = object.__proto__;
 
641
            object.__proto__ = prototypeOfObject;
 
642
 
 
643
            var getter = lookupGetter(object, property);
 
644
            var setter = lookupSetter(object, property);
 
645
            object.__proto__ = prototype;
 
646
 
 
647
            if (getter || setter) {
 
648
                if (getter) descriptor.get = getter;
 
649
                if (setter) descriptor.set = setter;
 
650
                return descriptor;
 
651
            }
 
652
        }
 
653
        descriptor.value = object[property];
 
654
        return descriptor;
 
655
    };
 
656
}
 
657
if (!Object.getOwnPropertyNames) {
 
658
    Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
 
659
        return Object.keys(object);
 
660
    };
 
661
}
 
662
if (!Object.create) {
 
663
    var createEmpty;
 
664
    if (Object.prototype.__proto__ === null) {
 
665
        createEmpty = function () {
 
666
            return { "__proto__": null };
 
667
        };
 
668
    } else {
 
669
        createEmpty = function () {
 
670
            var empty = {};
 
671
            for (var i in empty)
 
672
                empty[i] = null;
 
673
            empty.constructor =
 
674
            empty.hasOwnProperty =
 
675
            empty.propertyIsEnumerable =
 
676
            empty.isPrototypeOf =
 
677
            empty.toLocaleString =
 
678
            empty.toString =
 
679
            empty.valueOf =
 
680
            empty.__proto__ = null;
 
681
            return empty;
 
682
        }
 
683
    }
 
684
 
 
685
    Object.create = function create(prototype, properties) {
 
686
        var object;
 
687
        if (prototype === null) {
 
688
            object = createEmpty();
 
689
        } else {
 
690
            if (typeof prototype != "object")
 
691
                throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
 
692
            var Type = function () {};
 
693
            Type.prototype = prototype;
 
694
            object = new Type();
 
695
            object.__proto__ = prototype;
 
696
        }
 
697
        if (properties !== void 0)
 
698
            Object.defineProperties(object, properties);
 
699
        return object;
 
700
    };
 
701
}
 
702
 
 
703
function doesDefinePropertyWork(object) {
 
704
    try {
 
705
        Object.defineProperty(object, "sentinel", {});
 
706
        return "sentinel" in object;
 
707
    } catch (exception) {
 
708
    }
 
709
}
 
710
if (Object.defineProperty) {
 
711
    var definePropertyWorksOnObject = doesDefinePropertyWork({});
 
712
    var definePropertyWorksOnDom = typeof document == "undefined" ||
 
713
        doesDefinePropertyWork(document.createElement("div"));
 
714
    if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
 
715
        var definePropertyFallback = Object.defineProperty;
 
716
    }
 
717
}
 
718
 
 
719
if (!Object.defineProperty || definePropertyFallback) {
 
720
    var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
 
721
    var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: "
 
722
    var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
 
723
                                      "on this javascript engine";
 
724
 
 
725
    Object.defineProperty = function defineProperty(object, property, descriptor) {
 
726
        if ((typeof object != "object" && typeof object != "function") || object === null)
 
727
            throw new TypeError(ERR_NON_OBJECT_TARGET + object);
 
728
        if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null)
 
729
            throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
 
730
        if (definePropertyFallback) {
 
731
            try {
 
732
                return definePropertyFallback.call(Object, object, property, descriptor);
 
733
            } catch (exception) {
 
734
            }
 
735
        }
 
736
        if (owns(descriptor, "value")) {
 
737
 
 
738
            if (supportsAccessors && (lookupGetter(object, property) ||
 
739
                                      lookupSetter(object, property)))
 
740
            {
 
741
                var prototype = object.__proto__;
 
742
                object.__proto__ = prototypeOfObject;
 
743
                delete object[property];
 
744
                object[property] = descriptor.value;
 
745
                object.__proto__ = prototype;
 
746
            } else {
 
747
                object[property] = descriptor.value;
 
748
            }
 
749
        } else {
 
750
            if (!supportsAccessors)
 
751
                throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
 
752
            if (owns(descriptor, "get"))
 
753
                defineGetter(object, property, descriptor.get);
 
754
            if (owns(descriptor, "set"))
 
755
                defineSetter(object, property, descriptor.set);
 
756
        }
 
757
 
 
758
        return object;
 
759
    };
 
760
}
 
761
if (!Object.defineProperties) {
 
762
    Object.defineProperties = function defineProperties(object, properties) {
 
763
        for (var property in properties) {
 
764
            if (owns(properties, property))
 
765
                Object.defineProperty(object, property, properties[property]);
 
766
        }
 
767
        return object;
 
768
    };
 
769
}
 
770
if (!Object.seal) {
 
771
    Object.seal = function seal(object) {
 
772
        return object;
 
773
    };
 
774
}
 
775
if (!Object.freeze) {
 
776
    Object.freeze = function freeze(object) {
 
777
        return object;
 
778
    };
 
779
}
 
780
try {
 
781
    Object.freeze(function () {});
 
782
} catch (exception) {
 
783
    Object.freeze = (function freeze(freezeObject) {
 
784
        return function freeze(object) {
 
785
            if (typeof object == "function") {
 
786
                return object;
 
787
            } else {
 
788
                return freezeObject(object);
 
789
            }
 
790
        };
 
791
    })(Object.freeze);
 
792
}
 
793
if (!Object.preventExtensions) {
 
794
    Object.preventExtensions = function preventExtensions(object) {
 
795
        return object;
 
796
    };
 
797
}
 
798
if (!Object.isSealed) {
 
799
    Object.isSealed = function isSealed(object) {
 
800
        return false;
 
801
    };
 
802
}
 
803
if (!Object.isFrozen) {
 
804
    Object.isFrozen = function isFrozen(object) {
 
805
        return false;
 
806
    };
 
807
}
 
808
if (!Object.isExtensible) {
 
809
    Object.isExtensible = function isExtensible(object) {
 
810
        if (Object(object) === object) {
 
811
            throw new TypeError(); // TODO message
 
812
        }
 
813
        var name = '';
 
814
        while (owns(object, name)) {
 
815
            name += '?';
 
816
        }
 
817
        object[name] = true;
 
818
        var returnValue = owns(object, name);
 
819
        delete object[name];
 
820
        return returnValue;
 
821
    };
 
822
}
 
823
if (!Object.keys) {
 
824
    var hasDontEnumBug = true,
 
825
        dontEnums = [
 
826
            "toString",
 
827
            "toLocaleString",
 
828
            "valueOf",
 
829
            "hasOwnProperty",
 
830
            "isPrototypeOf",
 
831
            "propertyIsEnumerable",
 
832
            "constructor"
 
833
        ],
 
834
        dontEnumsLength = dontEnums.length;
 
835
 
 
836
    for (var key in {"toString": null}) {
 
837
        hasDontEnumBug = false;
 
838
    }
 
839
 
 
840
    Object.keys = function keys(object) {
 
841
 
 
842
        if (
 
843
            (typeof object != "object" && typeof object != "function") ||
 
844
            object === null
 
845
        ) {
 
846
            throw new TypeError("Object.keys called on a non-object");
 
847
        }
 
848
 
 
849
        var keys = [];
 
850
        for (var name in object) {
 
851
            if (owns(object, name)) {
 
852
                keys.push(name);
 
853
            }
 
854
        }
 
855
 
 
856
        if (hasDontEnumBug) {
 
857
            for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
 
858
                var dontEnum = dontEnums[i];
 
859
                if (owns(object, dontEnum)) {
 
860
                    keys.push(dontEnum);
 
861
                }
 
862
            }
 
863
        }
 
864
        return keys;
 
865
    };
 
866
 
 
867
}
 
868
if (!Date.now) {
 
869
    Date.now = function now() {
 
870
        return new Date().getTime();
 
871
    };
 
872
}
 
873
var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
 
874
    "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
 
875
    "\u2029\uFEFF";
 
876
if (!String.prototype.trim || ws.trim()) {
 
877
    ws = "[" + ws + "]";
 
878
    var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
 
879
        trimEndRegexp = new RegExp(ws + ws + "*$");
 
880
    String.prototype.trim = function trim() {
 
881
        return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
 
882
    };
 
883
}
 
884
 
 
885
function toInteger(n) {
 
886
    n = +n;
 
887
    if (n !== n) { // isNaN
 
888
        n = 0;
 
889
    } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {
 
890
        n = (n > 0 || -1) * Math.floor(Math.abs(n));
 
891
    }
 
892
    return n;
 
893
}
 
894
 
 
895
function isPrimitive(input) {
 
896
    var type = typeof input;
 
897
    return (
 
898
        input === null ||
 
899
        type === "undefined" ||
 
900
        type === "boolean" ||
 
901
        type === "number" ||
 
902
        type === "string"
 
903
    );
 
904
}
 
905
 
 
906
function toPrimitive(input) {
 
907
    var val, valueOf, toString;
 
908
    if (isPrimitive(input)) {
 
909
        return input;
 
910
    }
 
911
    valueOf = input.valueOf;
 
912
    if (typeof valueOf === "function") {
 
913
        val = valueOf.call(input);
 
914
        if (isPrimitive(val)) {
 
915
            return val;
 
916
        }
 
917
    }
 
918
    toString = input.toString;
 
919
    if (typeof toString === "function") {
 
920
        val = toString.call(input);
 
921
        if (isPrimitive(val)) {
 
922
            return val;
 
923
        }
 
924
    }
 
925
    throw new TypeError();
 
926
}
 
927
var toObject = function (o) {
 
928
    if (o == null) { // this matches both null and undefined
 
929
        throw new TypeError("can't convert "+o+" to object");
 
930
    }
 
931
    return Object(o);
 
932
};
 
933
 
 
934
});
 
935
 
 
936
define('ace/lib/event_emitter', ['require', 'exports', 'module' ], function(require, exports, module) {
 
937
 
 
938
 
 
939
var EventEmitter = {};
 
940
var stopPropagation = function() { this.propagationStopped = true; };
 
941
var preventDefault = function() { this.defaultPrevented = true; };
 
942
 
 
943
EventEmitter._emit =
 
944
EventEmitter._dispatchEvent = function(eventName, e) {
 
945
    this._eventRegistry || (this._eventRegistry = {});
 
946
    this._defaultHandlers || (this._defaultHandlers = {});
 
947
 
 
948
    var listeners = this._eventRegistry[eventName] || [];
 
949
    var defaultHandler = this._defaultHandlers[eventName];
 
950
    if (!listeners.length && !defaultHandler)
 
951
        return;
 
952
 
 
953
    if (typeof e != "object" || !e)
 
954
        e = {};
 
955
 
 
956
    if (!e.type)
 
957
        e.type = eventName;
 
958
    if (!e.stopPropagation)
 
959
        e.stopPropagation = stopPropagation;
 
960
    if (!e.preventDefault)
 
961
        e.preventDefault = preventDefault;
 
962
    if (!e.target)
 
963
        e.target = this;
 
964
 
 
965
    for (var i=0; i<listeners.length; i++) {
 
966
        listeners[i](e);
 
967
        if (e.propagationStopped)
 
968
            break;
 
969
    }
 
970
    
 
971
    if (defaultHandler && !e.defaultPrevented)
 
972
        return defaultHandler(e);
 
973
};
 
974
 
 
975
 
 
976
EventEmitter._signal = function(eventName, e) {
 
977
    var listeners = (this._eventRegistry || {})[eventName];
 
978
    if (!listeners)
 
979
        return;
 
980
 
 
981
    for (var i=0; i<listeners.length; i++)
 
982
        listeners[i](e);
 
983
};
 
984
 
 
985
EventEmitter.once = function(eventName, callback) {
 
986
    var _self = this;
 
987
    var newCallback = function() {
 
988
        fun && fun.apply(null, arguments);
 
989
        _self.removeEventListener(event, newCallback);
 
990
    };
 
991
    this.addEventListener(event, newCallback);
 
992
};
 
993
 
 
994
 
 
995
EventEmitter.setDefaultHandler = function(eventName, callback) {
 
996
    this._defaultHandlers = this._defaultHandlers || {};
 
997
    
 
998
    if (this._defaultHandlers[eventName])
 
999
        throw new Error("The default handler for '" + eventName + "' is already set");
 
1000
        
 
1001
    this._defaultHandlers[eventName] = callback;
 
1002
};
 
1003
 
 
1004
EventEmitter.on =
 
1005
EventEmitter.addEventListener = function(eventName, callback, capturing) {
 
1006
    this._eventRegistry = this._eventRegistry || {};
 
1007
 
 
1008
    var listeners = this._eventRegistry[eventName];
 
1009
    if (!listeners)
 
1010
        listeners = this._eventRegistry[eventName] = [];
 
1011
 
 
1012
    if (listeners.indexOf(callback) == -1)
 
1013
        listeners[capturing ? "unshift" : "push"](callback);
 
1014
    return callback;
 
1015
};
 
1016
 
 
1017
EventEmitter.removeListener =
 
1018
EventEmitter.removeEventListener = function(eventName, callback) {
 
1019
    this._eventRegistry = this._eventRegistry || {};
 
1020
 
 
1021
    var listeners = this._eventRegistry[eventName];
 
1022
    if (!listeners)
 
1023
        return;
 
1024
 
 
1025
    var index = listeners.indexOf(callback);
 
1026
    if (index !== -1)
 
1027
        listeners.splice(index, 1);
 
1028
};
 
1029
 
 
1030
EventEmitter.removeAllListeners = function(eventName) {
 
1031
    if (this._eventRegistry) this._eventRegistry[eventName] = [];
 
1032
};
 
1033
 
 
1034
exports.EventEmitter = EventEmitter;
 
1035
 
 
1036
});
 
1037
 
 
1038
define('ace/lib/oop', ['require', 'exports', 'module' ], function(require, exports, module) {
 
1039
 
 
1040
 
 
1041
exports.inherits = (function() {
 
1042
    var tempCtor = function() {};
 
1043
    return function(ctor, superCtor) {
 
1044
        tempCtor.prototype = superCtor.prototype;
 
1045
        ctor.super_ = superCtor.prototype;
 
1046
        ctor.prototype = new tempCtor();
 
1047
        ctor.prototype.constructor = ctor;
 
1048
    };
 
1049
}());
 
1050
 
 
1051
exports.mixin = function(obj, mixin) {
 
1052
    for (var key in mixin) {
 
1053
        obj[key] = mixin[key];
 
1054
    }
 
1055
};
 
1056
 
 
1057
exports.implement = function(proto, mixin) {
 
1058
    exports.mixin(proto, mixin);
 
1059
};
 
1060
 
 
1061
});
 
1062
 
 
1063
define('ace/mode/javascript_worker', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/worker/mirror', 'ace/mode/javascript/jshint'], function(require, exports, module) {
 
1064
 
 
1065
 
 
1066
var oop = require("../lib/oop");
 
1067
var Mirror = require("../worker/mirror").Mirror;
 
1068
var lint = require("./javascript/jshint").JSHINT;
 
1069
 
 
1070
function startRegex(arr) {
 
1071
    return RegExp("^(" + arr.join("|") + ")");
 
1072
}
 
1073
 
 
1074
var disabledWarningsRe = startRegex([
 
1075
    "Bad for in variable '(.+)'.",
 
1076
    'Missing "use strict"'
 
1077
]);
 
1078
var errorsRe = startRegex([
 
1079
    "Unexpected",
 
1080
    "Expected ",
 
1081
    "Confusing (plus|minus)",
 
1082
    "\\{a\\} unterminated regular expression",
 
1083
    "Unclosed ",
 
1084
    "Unmatched ",
 
1085
    "Unbegun comment",
 
1086
    "Bad invocation",
 
1087
    "Missing space after",
 
1088
    "Missing operator at"
 
1089
]);
 
1090
var infoRe = startRegex([
 
1091
    "Expected an assignment",
 
1092
    "Bad escapement of EOL",
 
1093
    "Unexpected comma",
 
1094
    "Unexpected space",
 
1095
    "Missing radix parameter.",
 
1096
    "A leading decimal point can",
 
1097
    "\\['{a}'\\] is better written in dot notation.",
 
1098
    "'{a}' used out of scope"
 
1099
]);
 
1100
 
 
1101
var JavaScriptWorker = exports.JavaScriptWorker = function(sender) {
 
1102
    Mirror.call(this, sender);
 
1103
    this.setTimeout(500);
 
1104
    this.setOptions();
 
1105
};
 
1106
 
 
1107
oop.inherits(JavaScriptWorker, Mirror);
 
1108
 
 
1109
(function() {
 
1110
    this.setOptions = function(options) {
 
1111
        this.options = options || {
 
1112
            es5: true,
 
1113
            esnext: true,
 
1114
            devel: true,
 
1115
            browser: true,
 
1116
            node: true,
 
1117
            laxcomma: true,
 
1118
            laxbreak: true,
 
1119
            lastsemic: true,
 
1120
            onevar: false,
 
1121
            passfail: false,
 
1122
            maxerr: 100,
 
1123
            expr: true,
 
1124
            multistr: true,
 
1125
            globalstrict: true
 
1126
        };
 
1127
        this.doc.getValue() && this.deferredUpdate.schedule(100);
 
1128
    };
 
1129
 
 
1130
    this.changeOptions = function(newOptions) {
 
1131
        oop.mixin(this.options, newOptions);
 
1132
        this.doc.getValue() && this.deferredUpdate.schedule(100);
 
1133
    };
 
1134
 
 
1135
    this.isValidJS = function(str) {
 
1136
        try {
 
1137
            eval("throw 0;" + str);
 
1138
        } catch(e) {
 
1139
            if (e === 0)
 
1140
                return true;
 
1141
        }
 
1142
        return false
 
1143
    };
 
1144
 
 
1145
    this.onUpdate = function() {
 
1146
        var value = this.doc.getValue();
 
1147
        value = value.replace(/^#!.*\n/, "\n");
 
1148
        if (!value) {
 
1149
            this.sender.emit("jslint", []);
 
1150
            return;
 
1151
        }
 
1152
        var errors = [];
 
1153
        var maxErrorLevel = this.isValidJS(value) ? "warning" : "error";
 
1154
        lint(value, this.options);
 
1155
        var results = lint.errors;
 
1156
 
 
1157
        var errorAdded = false
 
1158
        for (var i = 0; i < results.length; i++) {
 
1159
            var error = results[i];
 
1160
            if (!error)
 
1161
                continue;
 
1162
            var raw = error.raw;
 
1163
            var type = "warning";
 
1164
 
 
1165
            if (raw == "Missing semicolon.") {
 
1166
                var str = error.evidence.substr(error.character);
 
1167
                str = str.charAt(str.search(/\S/));
 
1168
                if (maxErrorLevel == "error" && str && /[\w\d{(['"]/.test(str)) {
 
1169
                    error.reason = 'Missing ";" before statement';
 
1170
                    type = "error";
 
1171
                } else {
 
1172
                    type = "info";
 
1173
                }
 
1174
            }
 
1175
            else if (disabledWarningsRe.test(raw)) {
 
1176
                continue;
 
1177
            }
 
1178
            else if (infoRe.test(raw)) {
 
1179
                type = "info"
 
1180
            }
 
1181
            else if (errorsRe.test(raw)) {
 
1182
                errorAdded  = true;
 
1183
                type = maxErrorLevel;
 
1184
            }
 
1185
            else if (raw == "'{a}' is not defined.") {
 
1186
                type = "warning";
 
1187
            }
 
1188
            else if (raw == "'{a}' is defined but never used.") {
 
1189
                type = "info";
 
1190
            }
 
1191
 
 
1192
            errors.push({
 
1193
                row: error.line-1,
 
1194
                column: error.character-1,
 
1195
                text: error.reason,
 
1196
                type: type,
 
1197
                raw: raw
 
1198
            });
 
1199
 
 
1200
            if (errorAdded) {
 
1201
            }
 
1202
        }
 
1203
 
 
1204
        this.sender.emit("jslint", errors);
 
1205
    };
 
1206
 
 
1207
}).call(JavaScriptWorker.prototype);
 
1208
 
 
1209
});
 
1210
define('ace/worker/mirror', ['require', 'exports', 'module' , 'ace/document', 'ace/lib/lang'], function(require, exports, module) {
 
1211
 
 
1212
 
 
1213
var Document = require("../document").Document;
 
1214
var lang = require("../lib/lang");
 
1215
    
 
1216
var Mirror = exports.Mirror = function(sender) {
 
1217
    this.sender = sender;
 
1218
    var doc = this.doc = new Document("");
 
1219
    
 
1220
    var deferredUpdate = this.deferredUpdate = lang.delayedCall(this.onUpdate.bind(this));
 
1221
    
 
1222
    var _self = this;
 
1223
    sender.on("change", function(e) {
 
1224
        doc.applyDeltas([e.data]);        
 
1225
        deferredUpdate.schedule(_self.$timeout);
 
1226
    });
 
1227
};
 
1228
 
 
1229
(function() {
 
1230
    
 
1231
    this.$timeout = 500;
 
1232
    
 
1233
    this.setTimeout = function(timeout) {
 
1234
        this.$timeout = timeout;
 
1235
    };
 
1236
    
 
1237
    this.setValue = function(value) {
 
1238
        this.doc.setValue(value);
 
1239
        this.deferredUpdate.schedule(this.$timeout);
 
1240
    };
 
1241
    
 
1242
    this.getValue = function(callbackId) {
 
1243
        this.sender.callback(this.doc.getValue(), callbackId);
 
1244
    };
 
1245
    
 
1246
    this.onUpdate = function() {
 
1247
    };
 
1248
    
 
1249
}).call(Mirror.prototype);
 
1250
 
 
1251
});
 
1252
 
 
1253
define('ace/document', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/range', 'ace/anchor'], function(require, exports, module) {
 
1254
 
 
1255
 
 
1256
var oop = require("./lib/oop");
 
1257
var EventEmitter = require("./lib/event_emitter").EventEmitter;
 
1258
var Range = require("./range").Range;
 
1259
var Anchor = require("./anchor").Anchor;
 
1260
 
 
1261
var Document = function(text) {
 
1262
    this.$lines = [];
 
1263
    if (text.length == 0) {
 
1264
        this.$lines = [""];
 
1265
    } else if (Array.isArray(text)) {
 
1266
        this.insertLines(0, text);
 
1267
    } else {
 
1268
        this.insert({row: 0, column:0}, text);
 
1269
    }
 
1270
};
 
1271
 
 
1272
(function() {
 
1273
 
 
1274
    oop.implement(this, EventEmitter);
 
1275
    this.setValue = function(text) {
 
1276
        var len = this.getLength();
 
1277
        this.remove(new Range(0, 0, len, this.getLine(len-1).length));
 
1278
        this.insert({row: 0, column:0}, text);
 
1279
    };
 
1280
    this.getValue = function() {
 
1281
        return this.getAllLines().join(this.getNewLineCharacter());
 
1282
    };
 
1283
    this.createAnchor = function(row, column) {
 
1284
        return new Anchor(this, row, column);
 
1285
    };
 
1286
    if ("aaa".split(/a/).length == 0)
 
1287
        this.$split = function(text) {
 
1288
            return text.replace(/\r\n|\r/g, "\n").split("\n");
 
1289
        }
 
1290
    else
 
1291
        this.$split = function(text) {
 
1292
            return text.split(/\r\n|\r|\n/);
 
1293
        };
 
1294
 
 
1295
 
 
1296
 
 
1297
    this.$detectNewLine = function(text) {
 
1298
        var match = text.match(/^.*?(\r\n|\r|\n)/m);
 
1299
        if (match) {
 
1300
            this.$autoNewLine = match[1];
 
1301
        } else {
 
1302
            this.$autoNewLine = "\n";
 
1303
        }
 
1304
    };
 
1305
    this.getNewLineCharacter = function() {
 
1306
        switch (this.$newLineMode) {
 
1307
          case "windows":
 
1308
            return "\r\n";
 
1309
 
 
1310
          case "unix":
 
1311
            return "\n";
 
1312
 
 
1313
          default:
 
1314
            return this.$autoNewLine;
 
1315
        }
 
1316
    };
 
1317
 
 
1318
    this.$autoNewLine = "\n";
 
1319
    this.$newLineMode = "auto";
 
1320
    this.setNewLineMode = function(newLineMode) {
 
1321
        if (this.$newLineMode === newLineMode)
 
1322
            return;
 
1323
 
 
1324
        this.$newLineMode = newLineMode;
 
1325
    };
 
1326
    this.getNewLineMode = function() {
 
1327
        return this.$newLineMode;
 
1328
    };
 
1329
    this.isNewLine = function(text) {
 
1330
        return (text == "\r\n" || text == "\r" || text == "\n");
 
1331
    };
 
1332
    this.getLine = function(row) {
 
1333
        return this.$lines[row] || "";
 
1334
    };
 
1335
    this.getLines = function(firstRow, lastRow) {
 
1336
        return this.$lines.slice(firstRow, lastRow + 1);
 
1337
    };
 
1338
    this.getAllLines = function() {
 
1339
        return this.getLines(0, this.getLength());
 
1340
    };
 
1341
    this.getLength = function() {
 
1342
        return this.$lines.length;
 
1343
    };
 
1344
    this.getTextRange = function(range) {
 
1345
        if (range.start.row == range.end.row) {
 
1346
            return this.$lines[range.start.row].substring(range.start.column,
 
1347
                                                         range.end.column);
 
1348
        }
 
1349
        else {
 
1350
            var lines = this.getLines(range.start.row+1, range.end.row-1);
 
1351
            lines.unshift((this.$lines[range.start.row] || "").substring(range.start.column));
 
1352
            lines.push((this.$lines[range.end.row] || "").substring(0, range.end.column));
 
1353
            return lines.join(this.getNewLineCharacter());
 
1354
        }
 
1355
    };
 
1356
 
 
1357
    this.$clipPosition = function(position) {
 
1358
        var length = this.getLength();
 
1359
        if (position.row >= length) {
 
1360
            position.row = Math.max(0, length - 1);
 
1361
            position.column = this.getLine(length-1).length;
 
1362
        }
 
1363
        return position;
 
1364
    };
 
1365
    this.insert = function(position, text) {
 
1366
        if (!text || text.length === 0)
 
1367
            return position;
 
1368
 
 
1369
        position = this.$clipPosition(position);
 
1370
        if (this.getLength() <= 1)
 
1371
            this.$detectNewLine(text);
 
1372
 
 
1373
        var lines = this.$split(text);
 
1374
        var firstLine = lines.splice(0, 1)[0];
 
1375
        var lastLine = lines.length == 0 ? null : lines.splice(lines.length - 1, 1)[0];
 
1376
 
 
1377
        position = this.insertInLine(position, firstLine);
 
1378
        if (lastLine !== null) {
 
1379
            position = this.insertNewLine(position); // terminate first line
 
1380
            position = this.insertLines(position.row, lines);
 
1381
            position = this.insertInLine(position, lastLine || "");
 
1382
        }
 
1383
        return position;
 
1384
    };
 
1385
    this.insertLines = function(row, lines) {
 
1386
        if (lines.length == 0)
 
1387
            return {row: row, column: 0};
 
1388
        if (lines.length > 0xFFFF) {
 
1389
            var end = this.insertLines(row, lines.slice(0xFFFF));
 
1390
            lines = lines.slice(0, 0xFFFF);
 
1391
        }
 
1392
 
 
1393
        var args = [row, 0];
 
1394
        args.push.apply(args, lines);
 
1395
        this.$lines.splice.apply(this.$lines, args);
 
1396
 
 
1397
        var range = new Range(row, 0, row + lines.length, 0);
 
1398
        var delta = {
 
1399
            action: "insertLines",
 
1400
            range: range,
 
1401
            lines: lines
 
1402
        };
 
1403
        this._emit("change", { data: delta });
 
1404
        return end || range.end;
 
1405
    };
 
1406
    this.insertNewLine = function(position) {
 
1407
        position = this.$clipPosition(position);
 
1408
        var line = this.$lines[position.row] || "";
 
1409
 
 
1410
        this.$lines[position.row] = line.substring(0, position.column);
 
1411
        this.$lines.splice(position.row + 1, 0, line.substring(position.column, line.length));
 
1412
 
 
1413
        var end = {
 
1414
            row : position.row + 1,
 
1415
            column : 0
 
1416
        };
 
1417
 
 
1418
        var delta = {
 
1419
            action: "insertText",
 
1420
            range: Range.fromPoints(position, end),
 
1421
            text: this.getNewLineCharacter()
 
1422
        };
 
1423
        this._emit("change", { data: delta });
 
1424
 
 
1425
        return end;
 
1426
    };
 
1427
    this.insertInLine = function(position, text) {
 
1428
        if (text.length == 0)
 
1429
            return position;
 
1430
 
 
1431
        var line = this.$lines[position.row] || "";
 
1432
 
 
1433
        this.$lines[position.row] = line.substring(0, position.column) + text
 
1434
                + line.substring(position.column);
 
1435
 
 
1436
        var end = {
 
1437
            row : position.row,
 
1438
            column : position.column + text.length
 
1439
        };
 
1440
 
 
1441
        var delta = {
 
1442
            action: "insertText",
 
1443
            range: Range.fromPoints(position, end),
 
1444
            text: text
 
1445
        };
 
1446
        this._emit("change", { data: delta });
 
1447
 
 
1448
        return end;
 
1449
    };
 
1450
    this.remove = function(range) {
 
1451
        range.start = this.$clipPosition(range.start);
 
1452
        range.end = this.$clipPosition(range.end);
 
1453
 
 
1454
        if (range.isEmpty())
 
1455
            return range.start;
 
1456
 
 
1457
        var firstRow = range.start.row;
 
1458
        var lastRow = range.end.row;
 
1459
 
 
1460
        if (range.isMultiLine()) {
 
1461
            var firstFullRow = range.start.column == 0 ? firstRow : firstRow + 1;
 
1462
            var lastFullRow = lastRow - 1;
 
1463
 
 
1464
            if (range.end.column > 0)
 
1465
                this.removeInLine(lastRow, 0, range.end.column);
 
1466
 
 
1467
            if (lastFullRow >= firstFullRow)
 
1468
                this.removeLines(firstFullRow, lastFullRow);
 
1469
 
 
1470
            if (firstFullRow != firstRow) {
 
1471
                this.removeInLine(firstRow, range.start.column, this.getLine(firstRow).length);
 
1472
                this.removeNewLine(range.start.row);
 
1473
            }
 
1474
        }
 
1475
        else {
 
1476
            this.removeInLine(firstRow, range.start.column, range.end.column);
 
1477
        }
 
1478
        return range.start;
 
1479
    };
 
1480
    this.removeInLine = function(row, startColumn, endColumn) {
 
1481
        if (startColumn == endColumn)
 
1482
            return;
 
1483
 
 
1484
        var range = new Range(row, startColumn, row, endColumn);
 
1485
        var line = this.getLine(row);
 
1486
        var removed = line.substring(startColumn, endColumn);
 
1487
        var newLine = line.substring(0, startColumn) + line.substring(endColumn, line.length);
 
1488
        this.$lines.splice(row, 1, newLine);
 
1489
 
 
1490
        var delta = {
 
1491
            action: "removeText",
 
1492
            range: range,
 
1493
            text: removed
 
1494
        };
 
1495
        this._emit("change", { data: delta });
 
1496
        return range.start;
 
1497
    };
 
1498
    this.removeLines = function(firstRow, lastRow) {
 
1499
        var range = new Range(firstRow, 0, lastRow + 1, 0);
 
1500
        var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);
 
1501
 
 
1502
        var delta = {
 
1503
            action: "removeLines",
 
1504
            range: range,
 
1505
            nl: this.getNewLineCharacter(),
 
1506
            lines: removed
 
1507
        };
 
1508
        this._emit("change", { data: delta });
 
1509
        return removed;
 
1510
    };
 
1511
    this.removeNewLine = function(row) {
 
1512
        var firstLine = this.getLine(row);
 
1513
        var secondLine = this.getLine(row+1);
 
1514
 
 
1515
        var range = new Range(row, firstLine.length, row+1, 0);
 
1516
        var line = firstLine + secondLine;
 
1517
 
 
1518
        this.$lines.splice(row, 2, line);
 
1519
 
 
1520
        var delta = {
 
1521
            action: "removeText",
 
1522
            range: range,
 
1523
            text: this.getNewLineCharacter()
 
1524
        };
 
1525
        this._emit("change", { data: delta });
 
1526
    };
 
1527
    this.replace = function(range, text) {
 
1528
        if (text.length == 0 && range.isEmpty())
 
1529
            return range.start;
 
1530
        if (text == this.getTextRange(range))
 
1531
            return range.end;
 
1532
 
 
1533
        this.remove(range);
 
1534
        if (text) {
 
1535
            var end = this.insert(range.start, text);
 
1536
        }
 
1537
        else {
 
1538
            end = range.start;
 
1539
        }
 
1540
 
 
1541
        return end;
 
1542
    };
 
1543
    this.applyDeltas = function(deltas) {
 
1544
        for (var i=0; i<deltas.length; i++) {
 
1545
            var delta = deltas[i];
 
1546
            var range = Range.fromPoints(delta.range.start, delta.range.end);
 
1547
 
 
1548
            if (delta.action == "insertLines")
 
1549
                this.insertLines(range.start.row, delta.lines);
 
1550
            else if (delta.action == "insertText")
 
1551
                this.insert(range.start, delta.text);
 
1552
            else if (delta.action == "removeLines")
 
1553
                this.removeLines(range.start.row, range.end.row - 1);
 
1554
            else if (delta.action == "removeText")
 
1555
                this.remove(range);
 
1556
        }
 
1557
    };
 
1558
    this.revertDeltas = function(deltas) {
 
1559
        for (var i=deltas.length-1; i>=0; i--) {
 
1560
            var delta = deltas[i];
 
1561
 
 
1562
            var range = Range.fromPoints(delta.range.start, delta.range.end);
 
1563
 
 
1564
            if (delta.action == "insertLines")
 
1565
                this.removeLines(range.start.row, range.end.row - 1);
 
1566
            else if (delta.action == "insertText")
 
1567
                this.remove(range);
 
1568
            else if (delta.action == "removeLines")
 
1569
                this.insertLines(range.start.row, delta.lines);
 
1570
            else if (delta.action == "removeText")
 
1571
                this.insert(range.start, delta.text);
 
1572
        }
 
1573
    };
 
1574
    this.indexToPosition = function(index, startRow) {
 
1575
        var lines = this.$lines || this.getAllLines();
 
1576
        var newlineLength = this.getNewLineCharacter().length;
 
1577
        for (var i = startRow || 0, l = lines.length; i < l; i++) {
 
1578
            index -= lines[i].length + newlineLength;
 
1579
            if (index < 0)
 
1580
                return {row: i, column: index + lines[i].length + newlineLength};
 
1581
        }
 
1582
        return {row: l-1, column: lines[l-1].length};
 
1583
    };
 
1584
    this.positionToIndex = function(pos, startRow) {
 
1585
        var lines = this.$lines || this.getAllLines();
 
1586
        var newlineLength = this.getNewLineCharacter().length;
 
1587
        var index = 0;
 
1588
        var row = Math.min(pos.row, lines.length);
 
1589
        for (var i = startRow || 0; i < row; ++i)
 
1590
            index += lines[i].length;
 
1591
 
 
1592
        return index + newlineLength * i + pos.column;
 
1593
    };
 
1594
 
 
1595
}).call(Document.prototype);
 
1596
 
 
1597
exports.Document = Document;
 
1598
});
 
1599
 
 
1600
define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) {
 
1601
 
 
1602
var comparePoints = function(p1, p2) {
 
1603
    return p1.row - p2.row || p1.column - p2.column;
 
1604
};
 
1605
var Range = function(startRow, startColumn, endRow, endColumn) {
 
1606
    this.start = {
 
1607
        row: startRow,
 
1608
        column: startColumn
 
1609
    };
 
1610
 
 
1611
    this.end = {
 
1612
        row: endRow,
 
1613
        column: endColumn
 
1614
    };
 
1615
};
 
1616
 
 
1617
(function() {
 
1618
    this.isEqual = function(range) {
 
1619
        return this.start.row === range.start.row &&
 
1620
            this.end.row === range.end.row &&
 
1621
            this.start.column === range.start.column &&
 
1622
            this.end.column === range.end.column;
 
1623
    };
 
1624
    this.toString = function() {
 
1625
        return ("Range: [" + this.start.row + "/" + this.start.column +
 
1626
            "] -> [" + this.end.row + "/" + this.end.column + "]");
 
1627
    };
 
1628
 
 
1629
    this.contains = function(row, column) {
 
1630
        return this.compare(row, column) == 0;
 
1631
    };
 
1632
    this.compareRange = function(range) {
 
1633
        var cmp,
 
1634
            end = range.end,
 
1635
            start = range.start;
 
1636
 
 
1637
        cmp = this.compare(end.row, end.column);
 
1638
        if (cmp == 1) {
 
1639
            cmp = this.compare(start.row, start.column);
 
1640
            if (cmp == 1) {
 
1641
                return 2;
 
1642
            } else if (cmp == 0) {
 
1643
                return 1;
 
1644
            } else {
 
1645
                return 0;
 
1646
            }
 
1647
        } else if (cmp == -1) {
 
1648
            return -2;
 
1649
        } else {
 
1650
            cmp = this.compare(start.row, start.column);
 
1651
            if (cmp == -1) {
 
1652
                return -1;
 
1653
            } else if (cmp == 1) {
 
1654
                return 42;
 
1655
            } else {
 
1656
                return 0;
 
1657
            }
 
1658
        }
 
1659
    };
 
1660
    this.comparePoint = function(p) {
 
1661
        return this.compare(p.row, p.column);
 
1662
    };
 
1663
    this.containsRange = function(range) {
 
1664
        return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
 
1665
    };
 
1666
    this.intersects = function(range) {
 
1667
        var cmp = this.compareRange(range);
 
1668
        return (cmp == -1 || cmp == 0 || cmp == 1);
 
1669
    };
 
1670
    this.isEnd = function(row, column) {
 
1671
        return this.end.row == row && this.end.column == column;
 
1672
    };
 
1673
    this.isStart = function(row, column) {
 
1674
        return this.start.row == row && this.start.column == column;
 
1675
    };
 
1676
    this.setStart = function(row, column) {
 
1677
        if (typeof row == "object") {
 
1678
            this.start.column = row.column;
 
1679
            this.start.row = row.row;
 
1680
        } else {
 
1681
            this.start.row = row;
 
1682
            this.start.column = column;
 
1683
        }
 
1684
    };
 
1685
    this.setEnd = function(row, column) {
 
1686
        if (typeof row == "object") {
 
1687
            this.end.column = row.column;
 
1688
            this.end.row = row.row;
 
1689
        } else {
 
1690
            this.end.row = row;
 
1691
            this.end.column = column;
 
1692
        }
 
1693
    };
 
1694
    this.inside = function(row, column) {
 
1695
        if (this.compare(row, column) == 0) {
 
1696
            if (this.isEnd(row, column) || this.isStart(row, column)) {
 
1697
                return false;
 
1698
            } else {
 
1699
                return true;
 
1700
            }
 
1701
        }
 
1702
        return false;
 
1703
    };
 
1704
    this.insideStart = function(row, column) {
 
1705
        if (this.compare(row, column) == 0) {
 
1706
            if (this.isEnd(row, column)) {
 
1707
                return false;
 
1708
            } else {
 
1709
                return true;
 
1710
            }
 
1711
        }
 
1712
        return false;
 
1713
    };
 
1714
    this.insideEnd = function(row, column) {
 
1715
        if (this.compare(row, column) == 0) {
 
1716
            if (this.isStart(row, column)) {
 
1717
                return false;
 
1718
            } else {
 
1719
                return true;
 
1720
            }
 
1721
        }
 
1722
        return false;
 
1723
    };
 
1724
    this.compare = function(row, column) {
 
1725
        if (!this.isMultiLine()) {
 
1726
            if (row === this.start.row) {
 
1727
                return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0);
 
1728
            };
 
1729
        }
 
1730
 
 
1731
        if (row < this.start.row)
 
1732
            return -1;
 
1733
 
 
1734
        if (row > this.end.row)
 
1735
            return 1;
 
1736
 
 
1737
        if (this.start.row === row)
 
1738
            return column >= this.start.column ? 0 : -1;
 
1739
 
 
1740
        if (this.end.row === row)
 
1741
            return column <= this.end.column ? 0 : 1;
 
1742
 
 
1743
        return 0;
 
1744
    };
 
1745
    this.compareStart = function(row, column) {
 
1746
        if (this.start.row == row && this.start.column == column) {
 
1747
            return -1;
 
1748
        } else {
 
1749
            return this.compare(row, column);
 
1750
        }
 
1751
    };
 
1752
    this.compareEnd = function(row, column) {
 
1753
        if (this.end.row == row && this.end.column == column) {
 
1754
            return 1;
 
1755
        } else {
 
1756
            return this.compare(row, column);
 
1757
        }
 
1758
    };
 
1759
    this.compareInside = function(row, column) {
 
1760
        if (this.end.row == row && this.end.column == column) {
 
1761
            return 1;
 
1762
        } else if (this.start.row == row && this.start.column == column) {
 
1763
            return -1;
 
1764
        } else {
 
1765
            return this.compare(row, column);
 
1766
        }
 
1767
    };
 
1768
    this.clipRows = function(firstRow, lastRow) {
 
1769
        if (this.end.row > lastRow)
 
1770
            var end = {row: lastRow + 1, column: 0};
 
1771
        else if (this.end.row < firstRow)
 
1772
            var end = {row: firstRow, column: 0};
 
1773
 
 
1774
        if (this.start.row > lastRow)
 
1775
            var start = {row: lastRow + 1, column: 0};
 
1776
        else if (this.start.row < firstRow)
 
1777
            var start = {row: firstRow, column: 0};
 
1778
 
 
1779
        return Range.fromPoints(start || this.start, end || this.end);
 
1780
    };
 
1781
    this.extend = function(row, column) {
 
1782
        var cmp = this.compare(row, column);
 
1783
 
 
1784
        if (cmp == 0)
 
1785
            return this;
 
1786
        else if (cmp == -1)
 
1787
            var start = {row: row, column: column};
 
1788
        else
 
1789
            var end = {row: row, column: column};
 
1790
 
 
1791
        return Range.fromPoints(start || this.start, end || this.end);
 
1792
    };
 
1793
 
 
1794
    this.isEmpty = function() {
 
1795
        return (this.start.row === this.end.row && this.start.column === this.end.column);
 
1796
    };
 
1797
    this.isMultiLine = function() {
 
1798
        return (this.start.row !== this.end.row);
 
1799
    };
 
1800
    this.clone = function() {
 
1801
        return Range.fromPoints(this.start, this.end);
 
1802
    };
 
1803
    this.collapseRows = function() {
 
1804
        if (this.end.column == 0)
 
1805
            return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0)
 
1806
        else
 
1807
            return new Range(this.start.row, 0, this.end.row, 0)
 
1808
    };
 
1809
    this.toScreenRange = function(session) {
 
1810
        var screenPosStart = session.documentToScreenPosition(this.start);
 
1811
        var screenPosEnd = session.documentToScreenPosition(this.end);
 
1812
 
 
1813
        return new Range(
 
1814
            screenPosStart.row, screenPosStart.column,
 
1815
            screenPosEnd.row, screenPosEnd.column
 
1816
        );
 
1817
    };
 
1818
    this.moveBy = function(row, column) {
 
1819
        this.start.row += row;
 
1820
        this.start.column += column;
 
1821
        this.end.row += row;
 
1822
        this.end.column += column;
 
1823
    };
 
1824
 
 
1825
}).call(Range.prototype);
 
1826
Range.fromPoints = function(start, end) {
 
1827
    return new Range(start.row, start.column, end.row, end.column);
 
1828
};
 
1829
Range.comparePoints = comparePoints;
 
1830
 
 
1831
exports.Range = Range;
 
1832
});
 
1833
 
 
1834
define('ace/anchor', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter'], function(require, exports, module) {
 
1835
 
 
1836
 
 
1837
var oop = require("./lib/oop");
 
1838
var EventEmitter = require("./lib/event_emitter").EventEmitter;
 
1839
 
 
1840
var Anchor = exports.Anchor = function(doc, row, column) {
 
1841
    this.document = doc;
 
1842
    
 
1843
    if (typeof column == "undefined")
 
1844
        this.setPosition(row.row, row.column);
 
1845
    else
 
1846
        this.setPosition(row, column);
 
1847
 
 
1848
    this.$onChange = this.onChange.bind(this);
 
1849
    doc.on("change", this.$onChange);
 
1850
};
 
1851
 
 
1852
(function() {
 
1853
 
 
1854
    oop.implement(this, EventEmitter);
 
1855
 
 
1856
    this.getPosition = function() {
 
1857
        return this.$clipPositionToDocument(this.row, this.column);
 
1858
    };
 
1859
        
 
1860
    this.getDocument = function() {
 
1861
        return this.document;
 
1862
    };
 
1863
 
 
1864
    this.onChange = function(e) {
 
1865
        var delta = e.data;
 
1866
        var range = delta.range;
 
1867
            
 
1868
        if (range.start.row == range.end.row && range.start.row != this.row)
 
1869
            return;
 
1870
            
 
1871
        if (range.start.row > this.row)
 
1872
            return;
 
1873
            
 
1874
        if (range.start.row == this.row && range.start.column > this.column)
 
1875
            return;
 
1876
    
 
1877
        var row = this.row;
 
1878
        var column = this.column;
 
1879
        
 
1880
        if (delta.action === "insertText") {
 
1881
            if (range.start.row === row && range.start.column <= column) {
 
1882
                if (range.start.row === range.end.row) {
 
1883
                    column += range.end.column - range.start.column;
 
1884
                }
 
1885
                else {
 
1886
                    column -= range.start.column;
 
1887
                    row += range.end.row - range.start.row;
 
1888
                }
 
1889
            }
 
1890
            else if (range.start.row !== range.end.row && range.start.row < row) {
 
1891
                row += range.end.row - range.start.row;
 
1892
            }
 
1893
        } else if (delta.action === "insertLines") {
 
1894
            if (range.start.row <= row) {
 
1895
                row += range.end.row - range.start.row;
 
1896
            }
 
1897
        }
 
1898
        else if (delta.action == "removeText") {
 
1899
            if (range.start.row == row && range.start.column < column) {
 
1900
                if (range.end.column >= column)
 
1901
                    column = range.start.column;
 
1902
                else
 
1903
                    column = Math.max(0, column - (range.end.column - range.start.column));
 
1904
                
 
1905
            } else if (range.start.row !== range.end.row && range.start.row < row) {
 
1906
                if (range.end.row == row) {
 
1907
                    column = Math.max(0, column - range.end.column) + range.start.column;
 
1908
                }
 
1909
                row -= (range.end.row - range.start.row);
 
1910
            }
 
1911
            else if (range.end.row == row) {
 
1912
                row -= range.end.row - range.start.row;
 
1913
                column = Math.max(0, column - range.end.column) + range.start.column;
 
1914
            }
 
1915
        } else if (delta.action == "removeLines") {
 
1916
            if (range.start.row <= row) {
 
1917
                if (range.end.row <= row)
 
1918
                    row -= range.end.row - range.start.row;
 
1919
                else {
 
1920
                    row = range.start.row;
 
1921
                    column = 0;
 
1922
                }
 
1923
            }
 
1924
        }
 
1925
 
 
1926
        this.setPosition(row, column, true);
 
1927
    };
 
1928
 
 
1929
    this.setPosition = function(row, column, noClip) {
 
1930
        var pos;
 
1931
        if (noClip) {
 
1932
            pos = {
 
1933
                row: row,
 
1934
                column: column
 
1935
            };
 
1936
        }
 
1937
        else {
 
1938
            pos = this.$clipPositionToDocument(row, column);
 
1939
        }
 
1940
        
 
1941
        if (this.row == pos.row && this.column == pos.column)
 
1942
            return;
 
1943
            
 
1944
        var old = {
 
1945
            row: this.row,
 
1946
            column: this.column
 
1947
        };
 
1948
        
 
1949
        this.row = pos.row;
 
1950
        this.column = pos.column;
 
1951
        this._emit("change", {
 
1952
            old: old,
 
1953
            value: pos
 
1954
        });
 
1955
    };
 
1956
 
 
1957
    this.detach = function() {
 
1958
        this.document.removeEventListener("change", this.$onChange);
 
1959
    };
 
1960
    this.$clipPositionToDocument = function(row, column) {
 
1961
        var pos = {};
 
1962
    
 
1963
        if (row >= this.document.getLength()) {
 
1964
            pos.row = Math.max(0, this.document.getLength() - 1);
 
1965
            pos.column = this.document.getLine(pos.row).length;
 
1966
        }
 
1967
        else if (row < 0) {
 
1968
            pos.row = 0;
 
1969
            pos.column = 0;
 
1970
        }
 
1971
        else {
 
1972
            pos.row = row;
 
1973
            pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));
 
1974
        }
 
1975
        
 
1976
        if (column < 0)
 
1977
            pos.column = 0;
 
1978
            
 
1979
        return pos;
 
1980
    };
 
1981
    
 
1982
}).call(Anchor.prototype);
 
1983
 
 
1984
});
 
1985
 
 
1986
define('ace/lib/lang', ['require', 'exports', 'module' ], function(require, exports, module) {
 
1987
 
 
1988
 
 
1989
exports.stringReverse = function(string) {
 
1990
    return string.split("").reverse().join("");
 
1991
};
 
1992
 
 
1993
exports.stringRepeat = function (string, count) {
 
1994
    var result = '';
 
1995
    while (count > 0) {
 
1996
        if (count & 1)
 
1997
            result += string;
 
1998
 
 
1999
        if (count >>= 1)
 
2000
            string += string;
 
2001
    }
 
2002
    return result;
 
2003
};
 
2004
 
 
2005
var trimBeginRegexp = /^\s\s*/;
 
2006
var trimEndRegexp = /\s\s*$/;
 
2007
 
 
2008
exports.stringTrimLeft = function (string) {
 
2009
    return string.replace(trimBeginRegexp, '');
 
2010
};
 
2011
 
 
2012
exports.stringTrimRight = function (string) {
 
2013
    return string.replace(trimEndRegexp, '');
 
2014
};
 
2015
 
 
2016
exports.copyObject = function(obj) {
 
2017
    var copy = {};
 
2018
    for (var key in obj) {
 
2019
        copy[key] = obj[key];
 
2020
    }
 
2021
    return copy;
 
2022
};
 
2023
 
 
2024
exports.copyArray = function(array){
 
2025
    var copy = [];
 
2026
    for (var i=0, l=array.length; i<l; i++) {
 
2027
        if (array[i] && typeof array[i] == "object")
 
2028
            copy[i] = this.copyObject( array[i] );
 
2029
        else 
 
2030
            copy[i] = array[i];
 
2031
    }
 
2032
    return copy;
 
2033
};
 
2034
 
 
2035
exports.deepCopy = function (obj) {
 
2036
    if (typeof obj != "object") {
 
2037
        return obj;
 
2038
    }
 
2039
    
 
2040
    var copy = obj.constructor();
 
2041
    for (var key in obj) {
 
2042
        if (typeof obj[key] == "object") {
 
2043
            copy[key] = this.deepCopy(obj[key]);
 
2044
        } else {
 
2045
            copy[key] = obj[key];
 
2046
        }
 
2047
    }
 
2048
    return copy;
 
2049
};
 
2050
 
 
2051
exports.arrayToMap = function(arr) {
 
2052
    var map = {};
 
2053
    for (var i=0; i<arr.length; i++) {
 
2054
        map[arr[i]] = 1;
 
2055
    }
 
2056
    return map;
 
2057
 
 
2058
};
 
2059
 
 
2060
exports.createMap = function(props) {
 
2061
    var map = Object.create(null);
 
2062
    for (var i in props) {
 
2063
        map[i] = props[i];
 
2064
    }
 
2065
    return map;
 
2066
};
 
2067
exports.arrayRemove = function(array, value) {
 
2068
  for (var i = 0; i <= array.length; i++) {
 
2069
    if (value === array[i]) {
 
2070
      array.splice(i, 1);
 
2071
    }
 
2072
  }
 
2073
};
 
2074
 
 
2075
exports.escapeRegExp = function(str) {
 
2076
    return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
 
2077
};
 
2078
 
 
2079
exports.escapeHTML = function(str) {
 
2080
    return str.replace(/&/g, "&#38;").replace(/"/g, "&#34;").replace(/'/g, "&#39;").replace(/</g, "&#60;");
 
2081
};
 
2082
 
 
2083
exports.getMatchOffsets = function(string, regExp) {
 
2084
    var matches = [];
 
2085
 
 
2086
    string.replace(regExp, function(str) {
 
2087
        matches.push({
 
2088
            offset: arguments[arguments.length-2],
 
2089
            length: str.length
 
2090
        });
 
2091
    });
 
2092
 
 
2093
    return matches;
 
2094
};
 
2095
exports.deferredCall = function(fcn) {
 
2096
 
 
2097
    var timer = null;
 
2098
    var callback = function() {
 
2099
        timer = null;
 
2100
        fcn();
 
2101
    };
 
2102
 
 
2103
    var deferred = function(timeout) {
 
2104
        deferred.cancel();
 
2105
        timer = setTimeout(callback, timeout || 0);
 
2106
        return deferred;
 
2107
    };
 
2108
 
 
2109
    deferred.schedule = deferred;
 
2110
 
 
2111
    deferred.call = function() {
 
2112
        this.cancel();
 
2113
        fcn();
 
2114
        return deferred;
 
2115
    };
 
2116
 
 
2117
    deferred.cancel = function() {
 
2118
        clearTimeout(timer);
 
2119
        timer = null;
 
2120
        return deferred;
 
2121
    };
 
2122
 
 
2123
    return deferred;
 
2124
};
 
2125
 
 
2126
 
 
2127
exports.delayedCall = function(fcn, defaultTimeout) {
 
2128
    var timer = null;
 
2129
    var callback = function() {
 
2130
        timer = null;
 
2131
        fcn();
 
2132
    };
 
2133
 
 
2134
    var _self = function(timeout) {
 
2135
        timer && clearTimeout(timer);
 
2136
        timer = setTimeout(callback, timeout || defaultTimeout);
 
2137
    };
 
2138
 
 
2139
    _self.delay = _self;
 
2140
    _self.schedule = function(timeout) {
 
2141
        if (timer == null)
 
2142
            timer = setTimeout(callback, timeout || 0);
 
2143
    };
 
2144
 
 
2145
    _self.call = function() {
 
2146
        this.cancel();
 
2147
        fcn();
 
2148
    };
 
2149
 
 
2150
    _self.cancel = function() {
 
2151
        timer && clearTimeout(timer);
 
2152
        timer = null;
 
2153
    };
 
2154
 
 
2155
    _self.isPending = function() {
 
2156
        return timer;
 
2157
    };
 
2158
 
 
2159
    return _self;
 
2160
};
 
2161
});
 
2162
define('ace/mode/javascript/jshint', ['require', 'exports', 'module' ], function(require, exports, module) {
 
2163
 
 
2164
var JSHINT = (function () {
 
2165
        
 
2166
 
 
2167
        var anonname,           // The guessed name for anonymous functions.
 
2168
 
 
2169
                bang = {
 
2170
                        "<"  : true,
 
2171
                        "<=" : true,
 
2172
                        "==" : true,
 
2173
                        "===": true,
 
2174
                        "!==": true,
 
2175
                        "!=" : true,
 
2176
                        ">"  : true,
 
2177
                        ">=" : true,
 
2178
                        "+"  : true,
 
2179
                        "-"  : true,
 
2180
                        "*"  : true,
 
2181
                        "/"  : true,
 
2182
                        "%"  : true
 
2183
                },
 
2184
                boolOptions = {
 
2185
                        asi                     : true, // if automatic semicolon insertion should be tolerated
 
2186
                        bitwise         : true, // if bitwise operators should not be allowed
 
2187
                        boss            : true, // if advanced usage of assignments should be allowed
 
2188
                        browser         : true, // if the standard browser globals should be predefined
 
2189
                        camelcase       : true, // if identifiers should be required in camel case
 
2190
                        couch           : true, // if CouchDB globals should be predefined
 
2191
                        curly           : true, // if curly braces around all blocks should be required
 
2192
                        debug           : true, // if debugger statements should be allowed
 
2193
                        devel           : true, // if logging globals should be predefined (console,
 
2194
                        dojo            : true, // if Dojo Toolkit globals should be predefined
 
2195
                        eqeqeq          : true, // if === should be required
 
2196
                        eqnull          : true, // if == null comparisons should be tolerated
 
2197
                        es5                     : true, // if ES5 syntax should be allowed
 
2198
                        esnext          : true, // if es.next specific syntax should be allowed
 
2199
                        evil            : true, // if eval should be allowed
 
2200
                        expr            : true, // if ExpressionStatement should be allowed as Programs
 
2201
                        forin           : true, // if for in statements must filter
 
2202
                        funcscope       : true, // if only function scope should be used for scope tests
 
2203
                        globalstrict: true, // if global  should be allowed (also
 
2204
                        immed           : true, // if immediate invocations must be wrapped in parens
 
2205
                        iterator        : true, // if the `__iterator__` property should be allowed
 
2206
                        jquery          : true, // if jQuery globals should be predefined
 
2207
                        lastsemic       : true, // if semicolons may be ommitted for the trailing
 
2208
                        latedef         : true, // if the use before definition should not be tolerated
 
2209
                        laxbreak        : true, // if line breaks should not be checked
 
2210
                        laxcomma        : true, // if line breaks should not be checked around commas
 
2211
                        loopfunc        : true, // if functions should be allowed to be defined within
 
2212
                        mootools        : true, // if MooTools globals should be predefined
 
2213
                        multistr        : true, // allow multiline strings
 
2214
                        newcap          : true, // if constructor names must be capitalized
 
2215
                        noarg           : true, // if arguments.caller and arguments.callee should be
 
2216
                        node            : true, // if the Node.js environment globals should be
 
2217
                        noempty         : true, // if empty blocks should be disallowed
 
2218
                        nonew           : true, // if using `new` for side-effects should be disallowed
 
2219
                        nonstandard : true, // if non-standard (but widely adopted) globals should
 
2220
                        nomen           : true, // if names should be checked
 
2221
                        onevar          : true, // if only one var statement per function should be
 
2222
                        onecase         : true, // if one case switch statements should be allowed
 
2223
                        passfail        : true, // if the scan should stop on first error
 
2224
                        plusplus        : true, // if increment/decrement should not be allowed
 
2225
                        proto           : true, // if the `__proto__` property should be allowed
 
2226
                        prototypejs : true, // if Prototype and Scriptaculous globals should be
 
2227
                        regexdash       : true, // if unescaped first/last dash (-) inside brackets
 
2228
                        regexp          : true, // if the . should not be allowed in regexp literals
 
2229
                        rhino           : true, // if the Rhino environment globals should be predefined
 
2230
                        undef           : true, // if variables should be declared before used
 
2231
                        unused          : true, // if variables should be always used
 
2232
                        scripturl       : true, // if script-targeted URLs should be tolerated
 
2233
                        shadow          : true, // if variable shadowing should be tolerated
 
2234
                        smarttabs       : true, // if smarttabs should be tolerated
 
2235
                        strict          : true, // require the  pragma
 
2236
                        sub                     : true, // if all forms of subscript notation are tolerated
 
2237
                        supernew        : true, // if `new function () { ... };` and `new Object;`
 
2238
                        trailing        : true, // if trailing whitespace rules apply
 
2239
                        validthis       : true, // if 'this' inside a non-constructor function is valid.
 
2240
                        withstmt        : true, // if with statements should be allowed
 
2241
                        white           : true, // if strict whitespace rules apply
 
2242
                        worker          : true, // if Web Worker script symbols should be allowed
 
2243
                        wsh                     : true, // if the Windows Scripting Host environment globals
 
2244
                        yui                     : true  // YUI variables should be predefined
 
2245
                },
 
2246
                valOptions = {
 
2247
                        maxlen           : false,
 
2248
                        indent           : false,
 
2249
                        maxerr           : false,
 
2250
                        predef           : false,
 
2251
                        quotmark         : false, //'single'|'double'|true
 
2252
                        scope            : false,
 
2253
                        maxstatements: false, // {int} max statements per function
 
2254
                        maxdepth         : false, // {int} max nested block depth per function
 
2255
                        maxparams        : false, // {int} max params per function
 
2256
                        maxcomplexity: false  // {int} max cyclomatic complexity per function
 
2257
                },
 
2258
                invertedOptions = {
 
2259
                        bitwise         : true,
 
2260
                        forin           : true,
 
2261
                        newcap          : true,
 
2262
                        nomen           : true,
 
2263
                        plusplus        : true,
 
2264
                        regexp          : true,
 
2265
                        undef           : true,
 
2266
                        white           : true,
 
2267
                        eqeqeq          : true,
 
2268
                        onevar          : true
 
2269
                },
 
2270
                renamedOptions = {
 
2271
                        eqeq            : "eqeqeq",
 
2272
                        vars            : "onevar",
 
2273
                        windows         : "wsh"
 
2274
                },
 
2275
                browser = {
 
2276
                        ArrayBuffer                              :      false,
 
2277
                        ArrayBufferView                  :      false,
 
2278
                        Audio                                    :      false,
 
2279
                        Blob                                     :      false,
 
2280
                        addEventListener                 :      false,
 
2281
                        applicationCache                 :      false,
 
2282
                        atob                                     :      false,
 
2283
                        blur                                     :      false,
 
2284
                        btoa                                     :      false,
 
2285
                        clearInterval                    :      false,
 
2286
                        clearTimeout                     :      false,
 
2287
                        close                                    :      false,
 
2288
                        closed                                   :      false,
 
2289
                        DataView                                 :      false,
 
2290
                        DOMParser                                :      false,
 
2291
                        defaultStatus                    :      false,
 
2292
                        document                                 :      false,
 
2293
                        event                                    :      false,
 
2294
                        FileReader                               :      false,
 
2295
                        Float32Array                     :      false,
 
2296
                        Float64Array                     :      false,
 
2297
                        FormData                                 :      false,
 
2298
                        focus                                    :      false,
 
2299
                        frames                                   :      false,
 
2300
                        getComputedStyle                 :      false,
 
2301
                        HTMLElement                              :      false,
 
2302
                        HTMLAnchorElement                :      false,
 
2303
                        HTMLBaseElement                  :      false,
 
2304
                        HTMLBlockquoteElement    :      false,
 
2305
                        HTMLBodyElement                  :      false,
 
2306
                        HTMLBRElement                    :      false,
 
2307
                        HTMLButtonElement                :      false,
 
2308
                        HTMLCanvasElement                :      false,
 
2309
                        HTMLDirectoryElement     :      false,
 
2310
                        HTMLDivElement                   :      false,
 
2311
                        HTMLDListElement                 :      false,
 
2312
                        HTMLFieldSetElement              :      false,
 
2313
                        HTMLFontElement                  :      false,
 
2314
                        HTMLFormElement                  :      false,
 
2315
                        HTMLFrameElement                 :      false,
 
2316
                        HTMLFrameSetElement              :      false,
 
2317
                        HTMLHeadElement                  :      false,
 
2318
                        HTMLHeadingElement               :      false,
 
2319
                        HTMLHRElement                    :      false,
 
2320
                        HTMLHtmlElement                  :      false,
 
2321
                        HTMLIFrameElement                :      false,
 
2322
                        HTMLImageElement                 :      false,
 
2323
                        HTMLInputElement                 :      false,
 
2324
                        HTMLIsIndexElement               :      false,
 
2325
                        HTMLLabelElement                 :      false,
 
2326
                        HTMLLayerElement                 :      false,
 
2327
                        HTMLLegendElement                :      false,
 
2328
                        HTMLLIElement                    :      false,
 
2329
                        HTMLLinkElement                  :      false,
 
2330
                        HTMLMapElement                   :      false,
 
2331
                        HTMLMenuElement                  :      false,
 
2332
                        HTMLMetaElement                  :      false,
 
2333
                        HTMLModElement                   :      false,
 
2334
                        HTMLObjectElement                :      false,
 
2335
                        HTMLOListElement                 :      false,
 
2336
                        HTMLOptGroupElement              :      false,
 
2337
                        HTMLOptionElement                :      false,
 
2338
                        HTMLParagraphElement     :      false,
 
2339
                        HTMLParamElement                 :      false,
 
2340
                        HTMLPreElement                   :      false,
 
2341
                        HTMLQuoteElement                 :      false,
 
2342
                        HTMLScriptElement                :      false,
 
2343
                        HTMLSelectElement                :      false,
 
2344
                        HTMLStyleElement                 :      false,
 
2345
                        HTMLTableCaptionElement  :      false,
 
2346
                        HTMLTableCellElement     :      false,
 
2347
                        HTMLTableColElement              :      false,
 
2348
                        HTMLTableElement                 :      false,
 
2349
                        HTMLTableRowElement              :      false,
 
2350
                        HTMLTableSectionElement  :      false,
 
2351
                        HTMLTextAreaElement              :      false,
 
2352
                        HTMLTitleElement                 :      false,
 
2353
                        HTMLUListElement                 :      false,
 
2354
                        HTMLVideoElement                 :      false,
 
2355
                        history                                  :      false,
 
2356
                        Int16Array                               :      false,
 
2357
                        Int32Array                               :      false,
 
2358
                        Int8Array                                :      false,
 
2359
                        Image                                    :      false,
 
2360
                        length                                   :      false,
 
2361
                        localStorage                     :      false,
 
2362
                        location                                 :      false,
 
2363
                        MessageChannel                   :      false,
 
2364
                        MessageEvent                     :      false,
 
2365
                        MessagePort                              :      false,
 
2366
                        moveBy                                   :      false,
 
2367
                        moveTo                                   :      false,
 
2368
                        MutationObserver                 :      false,
 
2369
                        name                                     :      false,
 
2370
                        Node                                     :      false,
 
2371
                        NodeFilter                               :      false,
 
2372
                        navigator                                :      false,
 
2373
                        onbeforeunload                   :      true,
 
2374
                        onblur                                   :      true,
 
2375
                        onerror                                  :      true,
 
2376
                        onfocus                                  :      true,
 
2377
                        onload                                   :      true,
 
2378
                        onresize                                 :      true,
 
2379
                        onunload                                 :      true,
 
2380
                        open                                     :      false,
 
2381
                        openDatabase                     :      false,
 
2382
                        opener                                   :      false,
 
2383
                        Option                                   :      false,
 
2384
                        parent                                   :      false,
 
2385
                        print                                    :      false,
 
2386
                        removeEventListener              :      false,
 
2387
                        resizeBy                                 :      false,
 
2388
                        resizeTo                                 :      false,
 
2389
                        screen                                   :      false,
 
2390
                        scroll                                   :      false,
 
2391
                        scrollBy                                 :      false,
 
2392
                        scrollTo                                 :      false,
 
2393
                        sessionStorage                   :      false,
 
2394
                        setInterval                              :      false,
 
2395
                        setTimeout                               :      false,
 
2396
                        SharedWorker                     :      false,
 
2397
                        status                                   :      false,
 
2398
                        top                                              :      false,
 
2399
                        Uint16Array                              :      false,
 
2400
                        Uint32Array                              :      false,
 
2401
                        Uint8Array                               :      false,
 
2402
                        WebSocket                                :      false,
 
2403
                        window                                   :      false,
 
2404
                        Worker                                   :      false,
 
2405
                        XMLHttpRequest                   :      false,
 
2406
                        XMLSerializer                    :      false,
 
2407
                        XPathEvaluator                   :      false,
 
2408
                        XPathException                   :      false,
 
2409
                        XPathExpression                  :      false,
 
2410
                        XPathNamespace                   :      false,
 
2411
                        XPathNSResolver                  :      false,
 
2412
                        XPathResult                              :      false
 
2413
                },
 
2414
 
 
2415
                couch = {
 
2416
                        "require" : false,
 
2417
                        respond   : false,
 
2418
                        getRow    : false,
 
2419
                        emit      : false,
 
2420
                        send      : false,
 
2421
                        start     : false,
 
2422
                        sum               : false,
 
2423
                        log               : false,
 
2424
                        exports   : false,
 
2425
                        module    : false,
 
2426
                        provides  : false
 
2427
                },
 
2428
 
 
2429
                declared, // Globals that were declared using /*global ... */ syntax.
 
2430
 
 
2431
                devel = {
 
2432
                        alert   : false,
 
2433
                        confirm : false,
 
2434
                        console : false,
 
2435
                        Debug   : false,
 
2436
                        opera   : false,
 
2437
                        prompt  : false
 
2438
                },
 
2439
 
 
2440
                dojo = {
 
2441
                        dojo      : false,
 
2442
                        dijit     : false,
 
2443
                        dojox     : false,
 
2444
                        define    : false,
 
2445
                        "require" : false
 
2446
                },
 
2447
 
 
2448
                funct,                  // The current function
 
2449
 
 
2450
                functionicity = [
 
2451
                        "closure", "exception", "global", "label",
 
2452
                        "outer", "unused", "var"
 
2453
                ],
 
2454
 
 
2455
                functions,              // All of the functions
 
2456
 
 
2457
                global,                 // The global scope
 
2458
                implied,                // Implied globals
 
2459
                inblock,
 
2460
                indent,
 
2461
                jsonmode,
 
2462
 
 
2463
                jquery = {
 
2464
                        "$"    : false,
 
2465
                        jQuery : false
 
2466
                },
 
2467
 
 
2468
                lines,
 
2469
                lookahead,
 
2470
                member,
 
2471
                membersOnly,
 
2472
 
 
2473
                mootools = {
 
2474
                        "$"                             : false,
 
2475
                        "$$"                    : false,
 
2476
                        Asset                   : false,
 
2477
                        Browser                 : false,
 
2478
                        Chain                   : false,
 
2479
                        Class                   : false,
 
2480
                        Color                   : false,
 
2481
                        Cookie                  : false,
 
2482
                        Core                    : false,
 
2483
                        Document                : false,
 
2484
                        DomReady                : false,
 
2485
                        DOMEvent                : false,
 
2486
                        DOMReady                : false,
 
2487
                        Drag                    : false,
 
2488
                        Element                 : false,
 
2489
                        Elements                : false,
 
2490
                        Event                   : false,
 
2491
                        Events                  : false,
 
2492
                        Fx                              : false,
 
2493
                        Group                   : false,
 
2494
                        Hash                    : false,
 
2495
                        HtmlTable               : false,
 
2496
                        Iframe                  : false,
 
2497
                        IframeShim              : false,
 
2498
                        InputValidator  : false,
 
2499
                        instanceOf              : false,
 
2500
                        Keyboard                : false,
 
2501
                        Locale                  : false,
 
2502
                        Mask                    : false,
 
2503
                        MooTools                : false,
 
2504
                        Native                  : false,
 
2505
                        Options                 : false,
 
2506
                        OverText                : false,
 
2507
                        Request                 : false,
 
2508
                        Scroller                : false,
 
2509
                        Slick                   : false,
 
2510
                        Slider                  : false,
 
2511
                        Sortables               : false,
 
2512
                        Spinner                 : false,
 
2513
                        Swiff                   : false,
 
2514
                        Tips                    : false,
 
2515
                        Type                    : false,
 
2516
                        typeOf                  : false,
 
2517
                        URI                             : false,
 
2518
                        Window                  : false
 
2519
                },
 
2520
 
 
2521
                nexttoken,
 
2522
 
 
2523
                node = {
 
2524
                        __filename        : false,
 
2525
                        __dirname         : false,
 
2526
                        Buffer            : false,
 
2527
                        console           : false,
 
2528
                        exports           : true,  // In Node it is ok to exports = module.exports = foo();
 
2529
                        GLOBAL            : false,
 
2530
                        global            : false,
 
2531
                        module            : false,
 
2532
                        process           : false,
 
2533
                        require           : false,
 
2534
                        setTimeout        : false,
 
2535
                        clearTimeout  : false,
 
2536
                        setInterval   : false,
 
2537
                        clearInterval : false
 
2538
                },
 
2539
 
 
2540
                noreach,
 
2541
                option,
 
2542
                predefined,             // Global variables defined by option
 
2543
                prereg,
 
2544
                prevtoken,
 
2545
 
 
2546
                prototypejs = {
 
2547
                        "$"                               : false,
 
2548
                        "$$"                      : false,
 
2549
                        "$A"                      : false,
 
2550
                        "$F"                      : false,
 
2551
                        "$H"                      : false,
 
2552
                        "$R"                      : false,
 
2553
                        "$break"                  : false,
 
2554
                        "$continue"               : false,
 
2555
                        "$w"                      : false,
 
2556
                        Abstract                  : false,
 
2557
                        Ajax                      : false,
 
2558
                        Class                     : false,
 
2559
                        Enumerable                : false,
 
2560
                        Element                   : false,
 
2561
                        Event                     : false,
 
2562
                        Field                     : false,
 
2563
                        Form                      : false,
 
2564
                        Hash                      : false,
 
2565
                        Insertion                 : false,
 
2566
                        ObjectRange               : false,
 
2567
                        PeriodicalExecuter: false,
 
2568
                        Position                  : false,
 
2569
                        Prototype                 : false,
 
2570
                        Selector                  : false,
 
2571
                        Template                  : false,
 
2572
                        Toggle                    : false,
 
2573
                        Try                               : false,
 
2574
                        Autocompleter     : false,
 
2575
                        Builder                   : false,
 
2576
                        Control                   : false,
 
2577
                        Draggable                 : false,
 
2578
                        Draggables                : false,
 
2579
                        Droppables                : false,
 
2580
                        Effect                    : false,
 
2581
                        Sortable                  : false,
 
2582
                        SortableObserver  : false,
 
2583
                        Sound                     : false,
 
2584
                        Scriptaculous     : false
 
2585
                },
 
2586
 
 
2587
                quotmark,
 
2588
 
 
2589
                rhino = {
 
2590
                        defineClass  : false,
 
2591
                        deserialize  : false,
 
2592
                        gc                       : false,
 
2593
                        help             : false,
 
2594
                        importPackage: false,
 
2595
                        "java"           : false,
 
2596
                        load             : false,
 
2597
                        loadClass        : false,
 
2598
                        print            : false,
 
2599
                        quit             : false,
 
2600
                        readFile         : false,
 
2601
                        readUrl          : false,
 
2602
                        runCommand       : false,
 
2603
                        seal             : false,
 
2604
                        serialize        : false,
 
2605
                        spawn            : false,
 
2606
                        sync             : false,
 
2607
                        toint32          : false,
 
2608
                        version          : false
 
2609
                },
 
2610
 
 
2611
                scope,          // The current scope
 
2612
                stack,
 
2613
                standard = {
 
2614
                        Array                           : false,
 
2615
                        Boolean                         : false,
 
2616
                        Date                            : false,
 
2617
                        decodeURI                       : false,
 
2618
                        decodeURIComponent      : false,
 
2619
                        encodeURI                       : false,
 
2620
                        encodeURIComponent      : false,
 
2621
                        Error                           : false,
 
2622
                        "eval"                          : false,
 
2623
                        EvalError                       : false,
 
2624
                        Function                        : false,
 
2625
                        hasOwnProperty          : false,
 
2626
                        isFinite                        : false,
 
2627
                        isNaN                           : false,
 
2628
                        JSON                            : false,
 
2629
                        Map                                     : false,
 
2630
                        Math                            : false,
 
2631
                        NaN                                     : false,
 
2632
                        Number                          : false,
 
2633
                        Object                          : false,
 
2634
                        parseInt                        : false,
 
2635
                        parseFloat                      : false,
 
2636
                        RangeError                      : false,
 
2637
                        ReferenceError          : false,
 
2638
                        RegExp                          : false,
 
2639
                        Set                                     : false,
 
2640
                        String                          : false,
 
2641
                        SyntaxError                     : false,
 
2642
                        TypeError                       : false,
 
2643
                        URIError                        : false,
 
2644
                        WeakMap                         : false
 
2645
                },
 
2646
                nonstandard = {
 
2647
                        escape                          : false,
 
2648
                        unescape                        : false
 
2649
                },
 
2650
 
 
2651
                directive,
 
2652
                syntax = {},
 
2653
                tab,
 
2654
                token,
 
2655
                unuseds,
 
2656
                urls,
 
2657
                useESNextSyntax,
 
2658
                warnings,
 
2659
 
 
2660
                worker = {
 
2661
                        importScripts           : true,
 
2662
                        postMessage                     : true,
 
2663
                        self                            : true
 
2664
                },
 
2665
 
 
2666
                wsh = {
 
2667
                        ActiveXObject                     : true,
 
2668
                        Enumerator                                : true,
 
2669
                        GetObject                                 : true,
 
2670
                        ScriptEngine                      : true,
 
2671
                        ScriptEngineBuildVersion  : true,
 
2672
                        ScriptEngineMajorVersion  : true,
 
2673
                        ScriptEngineMinorVersion  : true,
 
2674
                        VBArray                                   : true,
 
2675
                        WSH                                               : true,
 
2676
                        WScript                                   : true,
 
2677
                        XDomainRequest                    : true
 
2678
                },
 
2679
 
 
2680
                yui = {
 
2681
                        YUI                             : false,
 
2682
                        Y                               : false,
 
2683
                        YUI_config              : false
 
2684
                };
 
2685
        var ax, cx, tx, nx, nxg, lx, ix, jx, ft;
 
2686
        (function () {
 
2687
                ax = /@cc|<\/?|script|\]\s*\]|<\s*!|&lt/i;
 
2688
                cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
 
2689
                tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/=(?!(\S*\/[gim]?))|\/(\*(jshint|jslint|members?|global)?|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/;
 
2690
                nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
 
2691
                nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
 
2692
                lx = /\*\//;
 
2693
                ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/;
 
2694
                jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i;
 
2695
                ft = /^\s*\/\*\s*falls\sthrough\s*\*\/\s*$/;
 
2696
        }());
 
2697
 
 
2698
        function F() {}         // Used by Object.create
 
2699
 
 
2700
        function is_own(object, name) {
 
2701
                return Object.prototype.hasOwnProperty.call(object, name);
 
2702
        }
 
2703
 
 
2704
        function checkOption(name, t) {
 
2705
                if (valOptions[name] === undefined && boolOptions[name] === undefined) {
 
2706
                        warning("Bad option: '" + name + "'.", t);
 
2707
                }
 
2708
        }
 
2709
 
 
2710
        function isString(obj) {
 
2711
                return Object.prototype.toString.call(obj) === "[object String]";
 
2712
        }
 
2713
 
 
2714
        if (typeof Array.isArray !== "function") {
 
2715
                Array.isArray = function (o) {
 
2716
                        return Object.prototype.toString.apply(o) === "[object Array]";
 
2717
                };
 
2718
        }
 
2719
 
 
2720
        if (!Array.prototype.forEach) {
 
2721
                Array.prototype.forEach = function (fn, scope) {
 
2722
                        var len = this.length;
 
2723
 
 
2724
                        for (var i = 0; i < len; i++) {
 
2725
                                fn.call(scope || this, this[i], i, this);
 
2726
                        }
 
2727
                };
 
2728
        }
 
2729
 
 
2730
        if (!Array.prototype.indexOf) {
 
2731
                Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
 
2732
                        if (this === null || this === undefined) {
 
2733
                                throw new TypeError();
 
2734
                        }
 
2735
 
 
2736
                        var t = new Object(this);
 
2737
                        var len = t.length >>> 0;
 
2738
 
 
2739
                        if (len === 0) {
 
2740
                                return -1;
 
2741
                        }
 
2742
 
 
2743
                        var n = 0;
 
2744
                        if (arguments.length > 0) {
 
2745
                                n = Number(arguments[1]);
 
2746
                                if (n != n) { // shortcut for verifying if it's NaN
 
2747
                                        n = 0;
 
2748
                                } else if (n !== 0 && n != Infinity && n != -Infinity) {
 
2749
                                        n = (n > 0 || -1) * Math.floor(Math.abs(n));
 
2750
                                }
 
2751
                        }
 
2752
 
 
2753
                        if (n >= len) {
 
2754
                                return -1;
 
2755
                        }
 
2756
 
 
2757
                        var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
 
2758
                        for (; k < len; k++) {
 
2759
                                if (k in t && t[k] === searchElement) {
 
2760
                                        return k;
 
2761
                                }
 
2762
                        }
 
2763
 
 
2764
                        return -1;
 
2765
                };
 
2766
        }
 
2767
 
 
2768
        if (typeof Object.create !== "function") {
 
2769
                Object.create = function (o) {
 
2770
                        F.prototype = o;
 
2771
                        return new F();
 
2772
                };
 
2773
        }
 
2774
 
 
2775
        if (typeof Object.keys !== "function") {
 
2776
                Object.keys = function (o) {
 
2777
                        var a = [], k;
 
2778
                        for (k in o) {
 
2779
                                if (is_own(o, k)) {
 
2780
                                        a.push(k);
 
2781
                                }
 
2782
                        }
 
2783
                        return a;
 
2784
                };
 
2785
        }
 
2786
 
 
2787
        function isAlpha(str) {
 
2788
                return (str >= "a" && str <= "z\uffff") ||
 
2789
                        (str >= "A" && str <= "Z\uffff");
 
2790
        }
 
2791
 
 
2792
        function isDigit(str) {
 
2793
                return (str >= "0" && str <= "9");
 
2794
        }
 
2795
 
 
2796
        function isIdentifier(token, value) {
 
2797
                if (!token)
 
2798
                        return false;
 
2799
 
 
2800
                if (!token.identifier || token.value !== value)
 
2801
                        return false;
 
2802
 
 
2803
                return true;
 
2804
        }
 
2805
 
 
2806
        function supplant(str, data) {
 
2807
                return str.replace(/\{([^{}]*)\}/g, function (a, b) {
 
2808
                        var r = data[b];
 
2809
                        return typeof r === "string" || typeof r === "number" ? r : a;
 
2810
                });
 
2811
        }
 
2812
 
 
2813
        function combine(t, o) {
 
2814
                var n;
 
2815
                for (n in o) {
 
2816
                        if (is_own(o, n) && !is_own(JSHINT.blacklist, n)) {
 
2817
                                t[n] = o[n];
 
2818
                        }
 
2819
                }
 
2820
        }
 
2821
 
 
2822
        function updatePredefined() {
 
2823
                Object.keys(JSHINT.blacklist).forEach(function (key) {
 
2824
                        delete predefined[key];
 
2825
                });
 
2826
        }
 
2827
 
 
2828
        function assume() {
 
2829
                if (option.couch) {
 
2830
                        combine(predefined, couch);
 
2831
                }
 
2832
 
 
2833
                if (option.rhino) {
 
2834
                        combine(predefined, rhino);
 
2835
                }
 
2836
 
 
2837
                if (option.prototypejs) {
 
2838
                        combine(predefined, prototypejs);
 
2839
                }
 
2840
 
 
2841
                if (option.node) {
 
2842
                        combine(predefined, node);
 
2843
                        option.globalstrict = true;
 
2844
                }
 
2845
 
 
2846
                if (option.devel) {
 
2847
                        combine(predefined, devel);
 
2848
                }
 
2849
 
 
2850
                if (option.dojo) {
 
2851
                        combine(predefined, dojo);
 
2852
                }
 
2853
 
 
2854
                if (option.browser) {
 
2855
                        combine(predefined, browser);
 
2856
                }
 
2857
 
 
2858
                if (option.nonstandard) {
 
2859
                        combine(predefined, nonstandard);
 
2860
                }
 
2861
 
 
2862
                if (option.jquery) {
 
2863
                        combine(predefined, jquery);
 
2864
                }
 
2865
 
 
2866
                if (option.mootools) {
 
2867
                        combine(predefined, mootools);
 
2868
                }
 
2869
 
 
2870
                if (option.worker) {
 
2871
                        combine(predefined, worker);
 
2872
                }
 
2873
 
 
2874
                if (option.wsh) {
 
2875
                        combine(predefined, wsh);
 
2876
                }
 
2877
 
 
2878
                if (option.esnext) {
 
2879
                        useESNextSyntax();
 
2880
                }
 
2881
 
 
2882
                if (option.globalstrict && option.strict !== false) {
 
2883
                        option.strict = true;
 
2884
                }
 
2885
 
 
2886
                if (option.yui) {
 
2887
                        combine(predefined, yui);
 
2888
                }
 
2889
        }
 
2890
        function quit(message, line, chr) {
 
2891
                var percentage = Math.floor((line / lines.length) * 100);
 
2892
 
 
2893
                throw {
 
2894
                        name: "JSHintError",
 
2895
                        line: line,
 
2896
                        character: chr,
 
2897
                        message: message + " (" + percentage + "% scanned).",
 
2898
                        raw: message
 
2899
                };
 
2900
        }
 
2901
 
 
2902
        function isundef(scope, m, t, a) {
 
2903
                return JSHINT.undefs.push([scope, m, t, a]);
 
2904
        }
 
2905
 
 
2906
        function warning(m, t, a, b, c, d) {
 
2907
                var ch, l, w;
 
2908
                t = t || nexttoken;
 
2909
                if (t.id === "(end)") {  // `~
 
2910
                        t = token;
 
2911
                }
 
2912
                l = t.line || 0;
 
2913
                ch = t.from || 0;
 
2914
                w = {
 
2915
                        id: "(error)",
 
2916
                        raw: m,
 
2917
                        evidence: lines[l - 1] || "",
 
2918
                        line: l,
 
2919
                        character: ch,
 
2920
                        scope: JSHINT.scope,
 
2921
                        a: a,
 
2922
                        b: b,
 
2923
                        c: c,
 
2924
                        d: d
 
2925
                };
 
2926
                w.reason = supplant(m, w);
 
2927
                JSHINT.errors.push(w);
 
2928
                if (option.passfail) {
 
2929
                        quit("Stopping. ", l, ch);
 
2930
                }
 
2931
                warnings += 1;
 
2932
                if (warnings >= option.maxerr) {
 
2933
                        quit("Too many errors.", l, ch);
 
2934
                }
 
2935
                return w;
 
2936
        }
 
2937
 
 
2938
        function warningAt(m, l, ch, a, b, c, d) {
 
2939
                return warning(m, {
 
2940
                        line: l,
 
2941
                        from: ch
 
2942
                }, a, b, c, d);
 
2943
        }
 
2944
 
 
2945
        function error(m, t, a, b, c, d) {
 
2946
                warning(m, t, a, b, c, d);
 
2947
        }
 
2948
 
 
2949
        function errorAt(m, l, ch, a, b, c, d) {
 
2950
                return error(m, {
 
2951
                        line: l,
 
2952
                        from: ch
 
2953
                }, a, b, c, d);
 
2954
        }
 
2955
        function addInternalSrc(elem, src) {
 
2956
                var i;
 
2957
                i = {
 
2958
                        id: "(internal)",
 
2959
                        elem: elem,
 
2960
                        value: src
 
2961
                };
 
2962
                JSHINT.internals.push(i);
 
2963
                return i;
 
2964
        }
 
2965
 
 
2966
        var lex = (function lex() {
 
2967
                var character, from, line, s;
 
2968
 
 
2969
                function nextLine() {
 
2970
                        var at,
 
2971
                                match,
 
2972
                                tw; // trailing whitespace check
 
2973
 
 
2974
                        if (line >= lines.length)
 
2975
                                return false;
 
2976
 
 
2977
                        character = 1;
 
2978
                        s = lines[line];
 
2979
                        line += 1;
 
2980
                        if (option.smarttabs) {
 
2981
                                match = s.match(/(\/\/)? \t/);
 
2982
                                at = match && !match[1] ? 0 : -1;
 
2983
                        } else {
 
2984
                                at = s.search(/ \t|\t [^\*]/);
 
2985
                        }
 
2986
 
 
2987
                        if (at >= 0)
 
2988
                                warningAt("Mixed spaces and tabs.", line, at + 1);
 
2989
 
 
2990
                        s = s.replace(/\t/g, tab);
 
2991
                        at = s.search(cx);
 
2992
 
 
2993
                        if (at >= 0)
 
2994
                                warningAt("Unsafe character.", line, at);
 
2995
 
 
2996
                        if (option.maxlen && option.maxlen < s.length)
 
2997
                                warningAt("Line too long.", line, s.length);
 
2998
                        tw = option.trailing && s.match(/^(.*?)\s+$/);
 
2999
                        if (tw && !/^\s+$/.test(s)) {
 
3000
                                warningAt("Trailing whitespace.", line, tw[1].length + 1);
 
3001
                        }
 
3002
                        return true;
 
3003
                }
 
3004
 
 
3005
                function it(type, value) {
 
3006
                        var i, t;
 
3007
 
 
3008
                        function checkName(name) {
 
3009
                                if (!option.proto && name === "__proto__") {
 
3010
                                        warningAt("The '{a}' property is deprecated.", line, from, name);
 
3011
                                        return;
 
3012
                                }
 
3013
 
 
3014
                                if (!option.iterator && name === "__iterator__") {
 
3015
                                        warningAt("'{a}' is only available in JavaScript 1.7.", line, from, name);
 
3016
                                        return;
 
3017
                                }
 
3018
 
 
3019
                                var hasDangling = /^(_+.*|.*_+)$/.test(name);
 
3020
 
 
3021
                                if (option.nomen && hasDangling && name !== "_") {
 
3022
                                        if (option.node && token.id !== "." && /^(__dirname|__filename)$/.test(name))
 
3023
                                                return;
 
3024
 
 
3025
                                        warningAt("Unexpected {a} in '{b}'.", line, from, "dangling '_'", name);
 
3026
                                        return;
 
3027
                                }
 
3028
 
 
3029
                                if (option.camelcase) {
 
3030
                                        if (name.replace(/^_+/, "").indexOf("_") > -1 && !name.match(/^[A-Z0-9_]*$/)) {
 
3031
                                                warningAt("Identifier '{a}' is not in camel case.", line, from, value);
 
3032
                                        }
 
3033
                                }
 
3034
                        }
 
3035
 
 
3036
                        if (type === "(color)" || type === "(range)") {
 
3037
                                t = {type: type};
 
3038
                        } else if (type === "(punctuator)" ||
 
3039
                                        (type === "(identifier)" && is_own(syntax, value))) {
 
3040
                                t = syntax[value] || syntax["(error)"];
 
3041
                        } else {
 
3042
                                t = syntax[type];
 
3043
                        }
 
3044
 
 
3045
                        t = Object.create(t);
 
3046
 
 
3047
                        if (type === "(string)" || type === "(range)") {
 
3048
                                if (!option.scripturl && jx.test(value)) {
 
3049
                                        warningAt("Script URL.", line, from);
 
3050
                                }
 
3051
                        }
 
3052
 
 
3053
                        if (type === "(identifier)") {
 
3054
                                t.identifier = true;
 
3055
                                checkName(value);
 
3056
                        }
 
3057
 
 
3058
                        t.value = value;
 
3059
                        t.line = line;
 
3060
                        t.character = character;
 
3061
                        t.from = from;
 
3062
                        i = t.id;
 
3063
                        if (i !== "(endline)") {
 
3064
                                prereg = i &&
 
3065
                                        (("(,=:[!&|?{};".indexOf(i.charAt(i.length - 1)) >= 0) ||
 
3066
                                        i === "return" ||
 
3067
                                        i === "case");
 
3068
                        }
 
3069
                        return t;
 
3070
                }
 
3071
                return {
 
3072
                        init: function (source) {
 
3073
                                if (typeof source === "string") {
 
3074
                                        lines = source
 
3075
                                                .replace(/\r\n/g, "\n")
 
3076
                                                .replace(/\r/g, "\n")
 
3077
                                                .split("\n");
 
3078
                                } else {
 
3079
                                        lines = source;
 
3080
                                }
 
3081
                                if (lines[0] && lines[0].substr(0, 2) === "#!")
 
3082
                                        lines[0] = "";
 
3083
 
 
3084
                                line = 0;
 
3085
                                nextLine();
 
3086
                                from = 1;
 
3087
                        },
 
3088
 
 
3089
                        range: function (begin, end) {
 
3090
                                var c, value = "";
 
3091
                                from = character;
 
3092
                                if (s.charAt(0) !== begin) {
 
3093
                                        errorAt("Expected '{a}' and instead saw '{b}'.",
 
3094
                                                        line, character, begin, s.charAt(0));
 
3095
                                }
 
3096
                                for (;;) {
 
3097
                                        s = s.slice(1);
 
3098
                                        character += 1;
 
3099
                                        c = s.charAt(0);
 
3100
                                        switch (c) {
 
3101
                                        case "":
 
3102
                                                errorAt("Missing '{a}'.", line, character, c);
 
3103
                                                break;
 
3104
                                        case end:
 
3105
                                                s = s.slice(1);
 
3106
                                                character += 1;
 
3107
                                                return it("(range)", value);
 
3108
                                        case "\\":
 
3109
                                                warningAt("Unexpected '{a}'.", line, character, c);
 
3110
                                        }
 
3111
                                        value += c;
 
3112
                                }
 
3113
 
 
3114
                        },
 
3115
                        token: function () {
 
3116
                                var b, c, captures, d, depth, high, i, l, low, q, t, isLiteral, isInRange, n;
 
3117
 
 
3118
                                function match(x) {
 
3119
                                        var r = x.exec(s), r1;
 
3120
 
 
3121
                                        if (r) {
 
3122
                                                l = r[0].length;
 
3123
                                                r1 = r[1];
 
3124
                                                c = r1.charAt(0);
 
3125
                                                s = s.substr(l);
 
3126
                                                from = character + l - r1.length;
 
3127
                                                character += l;
 
3128
                                                return r1;
 
3129
                                        }
 
3130
                                }
 
3131
 
 
3132
                                function string(x) {
 
3133
                                        var c, j, r = "", allowNewLine = false;
 
3134
 
 
3135
                                        if (jsonmode && x !== "\"") {
 
3136
                                                warningAt("Strings must use doublequote.",
 
3137
                                                                line, character);
 
3138
                                        }
 
3139
 
 
3140
                                        if (option.quotmark) {
 
3141
                                                if (option.quotmark === "single" && x !== "'") {
 
3142
                                                        warningAt("Strings must use singlequote.",
 
3143
                                                                        line, character);
 
3144
                                                } else if (option.quotmark === "double" && x !== "\"") {
 
3145
                                                        warningAt("Strings must use doublequote.",
 
3146
                                                                        line, character);
 
3147
                                                } else if (option.quotmark === true) {
 
3148
                                                        quotmark = quotmark || x;
 
3149
                                                        if (quotmark !== x) {
 
3150
                                                                warningAt("Mixed double and single quotes.",
 
3151
                                                                                line, character);
 
3152
                                                        }
 
3153
                                                }
 
3154
                                        }
 
3155
 
 
3156
                                        function esc(n) {
 
3157
                                                var i = parseInt(s.substr(j + 1, n), 16);
 
3158
                                                j += n;
 
3159
                                                if (i >= 32 && i <= 126 &&
 
3160
                                                                i !== 34 && i !== 92 && i !== 39) {
 
3161
                                                        warningAt("Unnecessary escapement.", line, character);
 
3162
                                                }
 
3163
                                                character += n;
 
3164
                                                c = String.fromCharCode(i);
 
3165
                                        }
 
3166
 
 
3167
                                        j = 0;
 
3168
 
 
3169
unclosedString:
 
3170
                                        for (;;) {
 
3171
                                                while (j >= s.length) {
 
3172
                                                        j = 0;
 
3173
 
 
3174
                                                        var cl = line, cf = from;
 
3175
                                                        if (!nextLine()) {
 
3176
                                                                errorAt("Unclosed string.", cl, cf);
 
3177
                                                                break unclosedString;
 
3178
                                                        }
 
3179
 
 
3180
                                                        if (allowNewLine) {
 
3181
                                                                allowNewLine = false;
 
3182
                                                        } else {
 
3183
                                                                warningAt("Unclosed string.", cl, cf);
 
3184
                                                        }
 
3185
                                                }
 
3186
 
 
3187
                                                c = s.charAt(j);
 
3188
                                                if (c === x) {
 
3189
                                                        character += 1;
 
3190
                                                        s = s.substr(j + 1);
 
3191
                                                        return it("(string)", r, x);
 
3192
                                                }
 
3193
 
 
3194
                                                if (c < " ") {
 
3195
                                                        if (c === "\n" || c === "\r") {
 
3196
                                                                break;
 
3197
                                                        }
 
3198
                                                        warningAt("Control character in string: {a}.",
 
3199
                                                                        line, character + j, s.slice(0, j));
 
3200
                                                } else if (c === "\\") {
 
3201
                                                        j += 1;
 
3202
                                                        character += 1;
 
3203
                                                        c = s.charAt(j);
 
3204
                                                        n = s.charAt(j + 1);
 
3205
                                                        switch (c) {
 
3206
                                                        case "\\":
 
3207
                                                        case "\"":
 
3208
                                                        case "/":
 
3209
                                                                break;
 
3210
                                                        case "\'":
 
3211
                                                                if (jsonmode) {
 
3212
                                                                        warningAt("Avoid \\'.", line, character);
 
3213
                                                                }
 
3214
                                                                break;
 
3215
                                                        case "b":
 
3216
                                                                c = "\b";
 
3217
                                                                break;
 
3218
                                                        case "f":
 
3219
                                                                c = "\f";
 
3220
                                                                break;
 
3221
                                                        case "n":
 
3222
                                                                c = "\n";
 
3223
                                                                break;
 
3224
                                                        case "r":
 
3225
                                                                c = "\r";
 
3226
                                                                break;
 
3227
                                                        case "t":
 
3228
                                                                c = "\t";
 
3229
                                                                break;
 
3230
                                                        case "0":
 
3231
                                                                c = "\0";
 
3232
                                                                if (n >= 0 && n <= 7 && directive["use strict"]) {
 
3233
                                                                        warningAt(
 
3234
                                                                        "Octal literals are not allowed in strict mode.",
 
3235
                                                                        line, character);
 
3236
                                                                }
 
3237
                                                                break;
 
3238
                                                        case "u":
 
3239
                                                                esc(4);
 
3240
                                                                break;
 
3241
                                                        case "v":
 
3242
                                                                if (jsonmode) {
 
3243
                                                                        warningAt("Avoid \\v.", line, character);
 
3244
                                                                }
 
3245
                                                                c = "\v";
 
3246
                                                                break;
 
3247
                                                        case "x":
 
3248
                                                                if (jsonmode) {
 
3249
                                                                        warningAt("Avoid \\x-.", line, character);
 
3250
                                                                }
 
3251
                                                                esc(2);
 
3252
                                                                break;
 
3253
                                                        case "":
 
3254
                                                                allowNewLine = true;
 
3255
                                                                if (option.multistr) {
 
3256
                                                                        if (jsonmode) {
 
3257
                                                                                warningAt("Avoid EOL escapement.", line, character);
 
3258
                                                                        }
 
3259
                                                                        c = "";
 
3260
                                                                        character -= 1;
 
3261
                                                                        break;
 
3262
                                                                }
 
3263
                                                                warningAt("Bad escapement of EOL. Use option multistr if needed.",
 
3264
                                                                        line, character);
 
3265
                                                                break;
 
3266
                                                        case "!":
 
3267
                                                                if (s.charAt(j - 2) === "<")
 
3268
                                                                        break;
 
3269
                                                        default:
 
3270
                                                                warningAt("Bad escapement.", line, character);
 
3271
                                                        }
 
3272
                                                }
 
3273
                                                r += c;
 
3274
                                                character += 1;
 
3275
                                                j += 1;
 
3276
                                        }
 
3277
                                }
 
3278
 
 
3279
                                for (;;) {
 
3280
                                        if (!s) {
 
3281
                                                return it(nextLine() ? "(endline)" : "(end)", "");
 
3282
                                        }
 
3283
 
 
3284
                                        t = match(tx);
 
3285
 
 
3286
                                        if (!t) {
 
3287
                                                t = "";
 
3288
                                                c = "";
 
3289
                                                while (s && s < "!") {
 
3290
                                                        s = s.substr(1);
 
3291
                                                }
 
3292
                                                if (s) {
 
3293
                                                        errorAt("Unexpected '{a}'.", line, character, s.substr(0, 1));
 
3294
                                                        s = "";
 
3295
                                                }
 
3296
                                        } else {
 
3297
 
 
3298
                                                if (isAlpha(c) || c === "_" || c === "$") {
 
3299
                                                        return it("(identifier)", t);
 
3300
                                                }
 
3301
 
 
3302
                                                if (isDigit(c)) {
 
3303
                                                        if (!isFinite(Number(t))) {
 
3304
                                                                warningAt("Bad number '{a}'.",
 
3305
                                                                        line, character, t);
 
3306
                                                        }
 
3307
                                                        if (isAlpha(s.substr(0, 1))) {
 
3308
                                                                warningAt("Missing space after '{a}'.",
 
3309
                                                                                line, character, t);
 
3310
                                                        }
 
3311
                                                        if (c === "0") {
 
3312
                                                                d = t.substr(1, 1);
 
3313
                                                                if (isDigit(d)) {
 
3314
                                                                        if (token.id !== ".") {
 
3315
                                                                                warningAt("Don't use extra leading zeros '{a}'.",
 
3316
                                                                                        line, character, t);
 
3317
                                                                        }
 
3318
                                                                } else if (jsonmode && (d === "x" || d === "X")) {
 
3319
                                                                        warningAt("Avoid 0x-. '{a}'.",
 
3320
                                                                                        line, character, t);
 
3321
                                                                }
 
3322
                                                        }
 
3323
                                                        if (t.substr(t.length - 1) === ".") {
 
3324
                                                                warningAt(
 
3325
"A trailing decimal point can be confused with a dot '{a}'.", line, character, t);
 
3326
                                                        }
 
3327
                                                        return it("(number)", t);
 
3328
                                                }
 
3329
                                                switch (t) {
 
3330
 
 
3331
                                                case "\"":
 
3332
                                                case "'":
 
3333
                                                        return string(t);
 
3334
 
 
3335
                                                case "//":
 
3336
                                                        s = "";
 
3337
                                                        token.comment = true;
 
3338
                                                        break;
 
3339
 
 
3340
                                                case "/*":
 
3341
                                                        for (;;) {
 
3342
                                                                i = s.search(lx);
 
3343
                                                                if (i >= 0) {
 
3344
                                                                        break;
 
3345
                                                                }
 
3346
                                                                if (!nextLine()) {
 
3347
                                                                        errorAt("Unclosed comment.", line, character);
 
3348
                                                                }
 
3349
                                                        }
 
3350
                                                        s = s.substr(i + 2);
 
3351
                                                        token.comment = true;
 
3352
                                                        break;
 
3353
 
 
3354
                                                case "/*members":
 
3355
                                                case "/*member":
 
3356
                                                case "/*jshint":
 
3357
                                                case "/*jslint":
 
3358
                                                case "/*global":
 
3359
                                                case "*/":
 
3360
                                                        return {
 
3361
                                                                value: t,
 
3362
                                                                type: "special",
 
3363
                                                                line: line,
 
3364
                                                                character: character,
 
3365
                                                                from: from
 
3366
                                                        };
 
3367
 
 
3368
                                                case "":
 
3369
                                                        break;
 
3370
                                                case "/":
 
3371
                                                        if (s.charAt(0) === "=") {
 
3372
                                                                errorAt("A regular expression literal can be confused with '/='.",
 
3373
                                                                        line, from);
 
3374
                                                        }
 
3375
 
 
3376
                                                        if (prereg) {
 
3377
                                                                depth = 0;
 
3378
                                                                captures = 0;
 
3379
                                                                l = 0;
 
3380
                                                                for (;;) {
 
3381
                                                                        b = true;
 
3382
                                                                        c = s.charAt(l);
 
3383
                                                                        l += 1;
 
3384
                                                                        switch (c) {
 
3385
                                                                        case "":
 
3386
                                                                                errorAt("Unclosed regular expression.", line, from);
 
3387
                                                                                return quit("Stopping.", line, from);
 
3388
                                                                        case "/":
 
3389
                                                                                if (depth > 0) {
 
3390
                                                                                        warningAt("{a} unterminated regular expression " +
 
3391
                                                                                                "group(s).", line, from + l, depth);
 
3392
                                                                                }
 
3393
                                                                                c = s.substr(0, l - 1);
 
3394
                                                                                q = {
 
3395
                                                                                        g: true,
 
3396
                                                                                        i: true,
 
3397
                                                                                        m: true
 
3398
                                                                                };
 
3399
                                                                                while (q[s.charAt(l)] === true) {
 
3400
                                                                                        q[s.charAt(l)] = false;
 
3401
                                                                                        l += 1;
 
3402
                                                                                }
 
3403
                                                                                character += l;
 
3404
                                                                                s = s.substr(l);
 
3405
                                                                                q = s.charAt(0);
 
3406
                                                                                if (q === "/" || q === "*") {
 
3407
                                                                                        errorAt("Confusing regular expression.",
 
3408
                                                                                                        line, from);
 
3409
                                                                                }
 
3410
                                                                                return it("(regexp)", c);
 
3411
                                                                        case "\\":
 
3412
                                                                                c = s.charAt(l);
 
3413
                                                                                if (c < " ") {
 
3414
                                                                                        warningAt(
 
3415
"Unexpected control character in regular expression.", line, from + l);
 
3416
                                                                                } else if (c === "<") {
 
3417
                                                                                        warningAt(
 
3418
"Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
 
3419
                                                                                }
 
3420
                                                                                l += 1;
 
3421
                                                                                break;
 
3422
                                                                        case "(":
 
3423
                                                                                depth += 1;
 
3424
                                                                                b = false;
 
3425
                                                                                if (s.charAt(l) === "?") {
 
3426
                                                                                        l += 1;
 
3427
                                                                                        switch (s.charAt(l)) {
 
3428
                                                                                        case ":":
 
3429
                                                                                        case "=":
 
3430
                                                                                        case "!":
 
3431
                                                                                                l += 1;
 
3432
                                                                                                break;
 
3433
                                                                                        default:
 
3434
                                                                                                warningAt(
 
3435
"Expected '{a}' and instead saw '{b}'.", line, from + l, ":", s.charAt(l));
 
3436
                                                                                        }
 
3437
                                                                                } else {
 
3438
                                                                                        captures += 1;
 
3439
                                                                                }
 
3440
                                                                                break;
 
3441
                                                                        case "|":
 
3442
                                                                                b = false;
 
3443
                                                                                break;
 
3444
                                                                        case ")":
 
3445
                                                                                if (depth === 0) {
 
3446
                                                                                        warningAt("Unescaped '{a}'.",
 
3447
                                                                                                        line, from + l, ")");
 
3448
                                                                                } else {
 
3449
                                                                                        depth -= 1;
 
3450
                                                                                }
 
3451
                                                                                break;
 
3452
                                                                        case " ":
 
3453
                                                                                q = 1;
 
3454
                                                                                while (s.charAt(l) === " ") {
 
3455
                                                                                        l += 1;
 
3456
                                                                                        q += 1;
 
3457
                                                                                }
 
3458
                                                                                if (q > 1) {
 
3459
                                                                                        warningAt(
 
3460
"Spaces are hard to count. Use {{a}}.", line, from + l, q);
 
3461
                                                                                }
 
3462
                                                                                break;
 
3463
                                                                        case "[":
 
3464
                                                                                c = s.charAt(l);
 
3465
                                                                                if (c === "^") {
 
3466
                                                                                        l += 1;
 
3467
                                                                                        if (s.charAt(l) === "]") {
 
3468
                                                                                                errorAt("Unescaped '{a}'.",
 
3469
                                                                                                        line, from + l, "^");
 
3470
                                                                                        }
 
3471
                                                                                }
 
3472
                                                                                if (c === "]") {
 
3473
                                                                                        warningAt("Empty class.", line,
 
3474
                                                                                                        from + l - 1);
 
3475
                                                                                }
 
3476
                                                                                isLiteral = false;
 
3477
                                                                                isInRange = false;
 
3478
klass:
 
3479
                                                                                do {
 
3480
                                                                                        c = s.charAt(l);
 
3481
                                                                                        l += 1;
 
3482
                                                                                        switch (c) {
 
3483
                                                                                        case "[":
 
3484
                                                                                        case "^":
 
3485
                                                                                                warningAt("Unescaped '{a}'.",
 
3486
                                                                                                                line, from + l, c);
 
3487
                                                                                                if (isInRange) {
 
3488
                                                                                                        isInRange = false;
 
3489
                                                                                                } else {
 
3490
                                                                                                        isLiteral = true;
 
3491
                                                                                                }
 
3492
                                                                                                break;
 
3493
                                                                                        case "-":
 
3494
                                                                                                if (isLiteral && !isInRange) {
 
3495
                                                                                                        isLiteral = false;
 
3496
                                                                                                        isInRange = true;
 
3497
                                                                                                } else if (isInRange) {
 
3498
                                                                                                        isInRange = false;
 
3499
                                                                                                } else if (s.charAt(l) === "]") {
 
3500
                                                                                                        isInRange = true;
 
3501
                                                                                                } else {
 
3502
                                                                                                        if (option.regexdash !== (l === 2 || (l === 3 &&
 
3503
                                                                                                                s.charAt(1) === "^"))) {
 
3504
                                                                                                                warningAt("Unescaped '{a}'.",
 
3505
                                                                                                                        line, from + l - 1, "-");
 
3506
                                                                                                        }
 
3507
                                                                                                        isLiteral = true;
 
3508
                                                                                                }
 
3509
                                                                                                break;
 
3510
                                                                                        case "]":
 
3511
                                                                                                if (isInRange && !option.regexdash) {
 
3512
                                                                                                        warningAt("Unescaped '{a}'.",
 
3513
                                                                                                                        line, from + l - 1, "-");
 
3514
                                                                                                }
 
3515
                                                                                                break klass;
 
3516
                                                                                        case "\\":
 
3517
                                                                                                c = s.charAt(l);
 
3518
                                                                                                if (c < " ") {
 
3519
                                                                                                        warningAt(
 
3520
"Unexpected control character in regular expression.", line, from + l);
 
3521
                                                                                                } else if (c === "<") {
 
3522
                                                                                                        warningAt(
 
3523
"Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
 
3524
                                                                                                }
 
3525
                                                                                                l += 1;
 
3526
                                                                                                if (/[wsd]/i.test(c)) {
 
3527
                                                                                                        if (isInRange) {
 
3528
                                                                                                                warningAt("Unescaped '{a}'.",
 
3529
                                                                                                                        line, from + l, "-");
 
3530
                                                                                                                isInRange = false;
 
3531
                                                                                                        }
 
3532
                                                                                                        isLiteral = false;
 
3533
                                                                                                } else if (isInRange) {
 
3534
                                                                                                        isInRange = false;
 
3535
                                                                                                } else {
 
3536
                                                                                                        isLiteral = true;
 
3537
                                                                                                }
 
3538
                                                                                                break;
 
3539
                                                                                        case "/":
 
3540
                                                                                                warningAt("Unescaped '{a}'.",
 
3541
                                                                                                                line, from + l - 1, "/");
 
3542
 
 
3543
                                                                                                if (isInRange) {
 
3544
                                                                                                        isInRange = false;
 
3545
                                                                                                } else {
 
3546
                                                                                                        isLiteral = true;
 
3547
                                                                                                }
 
3548
                                                                                                break;
 
3549
                                                                                        case "<":
 
3550
                                                                                                if (isInRange) {
 
3551
                                                                                                        isInRange = false;
 
3552
                                                                                                } else {
 
3553
                                                                                                        isLiteral = true;
 
3554
                                                                                                }
 
3555
                                                                                                break;
 
3556
                                                                                        default:
 
3557
                                                                                                if (isInRange) {
 
3558
                                                                                                        isInRange = false;
 
3559
                                                                                                } else {
 
3560
                                                                                                        isLiteral = true;
 
3561
                                                                                                }
 
3562
                                                                                        }
 
3563
                                                                                } while (c);
 
3564
                                                                                break;
 
3565
                                                                        case ".":
 
3566
                                                                                if (option.regexp) {
 
3567
                                                                                        warningAt("Insecure '{a}'.", line,
 
3568
                                                                                                        from + l, c);
 
3569
                                                                                }
 
3570
                                                                                break;
 
3571
                                                                        case "]":
 
3572
                                                                        case "?":
 
3573
                                                                        case "{":
 
3574
                                                                        case "}":
 
3575
                                                                        case "+":
 
3576
                                                                        case "*":
 
3577
                                                                                warningAt("Unescaped '{a}'.", line,
 
3578
                                                                                                from + l, c);
 
3579
                                                                        }
 
3580
                                                                        if (b) {
 
3581
                                                                                switch (s.charAt(l)) {
 
3582
                                                                                case "?":
 
3583
                                                                                case "+":
 
3584
                                                                                case "*":
 
3585
                                                                                        l += 1;
 
3586
                                                                                        if (s.charAt(l) === "?") {
 
3587
                                                                                                l += 1;
 
3588
                                                                                        }
 
3589
                                                                                        break;
 
3590
                                                                                case "{":
 
3591
                                                                                        l += 1;
 
3592
                                                                                        c = s.charAt(l);
 
3593
                                                                                        if (c < "0" || c > "9") {
 
3594
                                                                                                warningAt(
 
3595
"Expected a number and instead saw '{a}'.", line, from + l, c);
 
3596
                                                                                                break; // No reason to continue checking numbers.
 
3597
                                                                                        }
 
3598
                                                                                        l += 1;
 
3599
                                                                                        low = +c;
 
3600
                                                                                        for (;;) {
 
3601
                                                                                                c = s.charAt(l);
 
3602
                                                                                                if (c < "0" || c > "9") {
 
3603
                                                                                                        break;
 
3604
                                                                                                }
 
3605
                                                                                                l += 1;
 
3606
                                                                                                low = +c + (low * 10);
 
3607
                                                                                        }
 
3608
                                                                                        high = low;
 
3609
                                                                                        if (c === ",") {
 
3610
                                                                                                l += 1;
 
3611
                                                                                                high = Infinity;
 
3612
                                                                                                c = s.charAt(l);
 
3613
                                                                                                if (c >= "0" && c <= "9") {
 
3614
                                                                                                        l += 1;
 
3615
                                                                                                        high = +c;
 
3616
                                                                                                        for (;;) {
 
3617
                                                                                                                c = s.charAt(l);
 
3618
                                                                                                                if (c < "0" || c > "9") {
 
3619
                                                                                                                        break;
 
3620
                                                                                                                }
 
3621
                                                                                                                l += 1;
 
3622
                                                                                                                high = +c + (high * 10);
 
3623
                                                                                                        }
 
3624
                                                                                                }
 
3625
                                                                                        }
 
3626
                                                                                        if (s.charAt(l) !== "}") {
 
3627
                                                                                                warningAt(
 
3628
"Expected '{a}' and instead saw '{b}'.", line, from + l, "}", c);
 
3629
                                                                                        } else {
 
3630
                                                                                                l += 1;
 
3631
                                                                                        }
 
3632
                                                                                        if (s.charAt(l) === "?") {
 
3633
                                                                                                l += 1;
 
3634
                                                                                        }
 
3635
                                                                                        if (low > high) {
 
3636
                                                                                                warningAt(
 
3637
"'{a}' should not be greater than '{b}'.", line, from + l, low, high);
 
3638
                                                                                        }
 
3639
                                                                                }
 
3640
                                                                        }
 
3641
                                                                }
 
3642
                                                                c = s.substr(0, l - 1);
 
3643
                                                                character += l;
 
3644
                                                                s = s.substr(l);
 
3645
                                                                return it("(regexp)", c);
 
3646
                                                        }
 
3647
                                                        return it("(punctuator)", t);
 
3648
 
 
3649
                                                case "#":
 
3650
                                                        return it("(punctuator)", t);
 
3651
                                                default:
 
3652
                                                        return it("(punctuator)", t);
 
3653
                                                }
 
3654
                                        }
 
3655
                                }
 
3656
                        }
 
3657
                };
 
3658
        }());
 
3659
 
 
3660
 
 
3661
        function addlabel(t, type, token) {
 
3662
                if (t === "hasOwnProperty") {
 
3663
                        warning("'hasOwnProperty' is a really bad name.");
 
3664
                }
 
3665
                if (type === "exception") {
 
3666
                        if (is_own(funct["(context)"], t)) {
 
3667
                                if (funct[t] !== true && !option.node) {
 
3668
                                        warning("Value of '{a}' may be overwritten in IE.", nexttoken, t);
 
3669
                                }
 
3670
                        }
 
3671
                }
 
3672
 
 
3673
                if (is_own(funct, t) && !funct["(global)"]) {
 
3674
                        if (funct[t] === true) {
 
3675
                                if (option.latedef)
 
3676
                                        warning("'{a}' was used before it was defined.", nexttoken, t);
 
3677
                        } else {
 
3678
                                if (!option.shadow && type !== "exception") {
 
3679
                                        warning("'{a}' is already defined.", nexttoken, t);
 
3680
                                }
 
3681
                        }
 
3682
                }
 
3683
 
 
3684
                funct[t] = type;
 
3685
 
 
3686
                if (token) {
 
3687
                        funct["(tokens)"][t] = token;
 
3688
                }
 
3689
 
 
3690
                if (funct["(global)"]) {
 
3691
                        global[t] = funct;
 
3692
                        if (is_own(implied, t)) {
 
3693
                                if (option.latedef)
 
3694
                                        warning("'{a}' was used before it was defined.", nexttoken, t);
 
3695
                                delete implied[t];
 
3696
                        }
 
3697
                } else {
 
3698
                        scope[t] = funct;
 
3699
                }
 
3700
        }
 
3701
 
 
3702
 
 
3703
        function doOption() {
 
3704
                var nt = nexttoken;
 
3705
                var o  = nt.value;
 
3706
                var quotmarkValue = option.quotmark;
 
3707
                var predef = {};
 
3708
                var b, obj, filter, t, tn, v, minus;
 
3709
 
 
3710
                switch (o) {
 
3711
                case "*/":
 
3712
                        error("Unbegun comment.");
 
3713
                        break;
 
3714
                case "/*members":
 
3715
                case "/*member":
 
3716
                        o = "/*members";
 
3717
                        if (!membersOnly) {
 
3718
                                membersOnly = {};
 
3719
                        }
 
3720
                        obj = membersOnly;
 
3721
                        option.quotmark = false;
 
3722
                        break;
 
3723
                case "/*jshint":
 
3724
                case "/*jslint":
 
3725
                        obj = option;
 
3726
                        filter = boolOptions;
 
3727
                        break;
 
3728
                case "/*global":
 
3729
                        obj = predef;
 
3730
                        break;
 
3731
                default:
 
3732
                        error("What?");
 
3733
                }
 
3734
 
 
3735
                t = lex.token();
 
3736
 
 
3737
                for (;;) {
 
3738
                        minus = false;
 
3739
                        var breakOuterLoop;
 
3740
                        for (;;) {
 
3741
                                if (t.type === "special" && t.value === "*/") {
 
3742
                                        breakOuterLoop = true;
 
3743
                                        break;
 
3744
                                }
 
3745
                                if (t.id !== "(endline)" && t.id !== ",") {
 
3746
                                        break;
 
3747
                                }
 
3748
                                t = lex.token();
 
3749
                        }
 
3750
                        if (breakOuterLoop)
 
3751
                                break;
 
3752
 
 
3753
                        if (o === "/*global" && t.value === "-") {
 
3754
                                minus = true;
 
3755
                                t = lex.token();
 
3756
                        }
 
3757
 
 
3758
                        if (t.type !== "(string)" && t.type !== "(identifier)" && o !== "/*members") {
 
3759
                                error("Bad option.", t);
 
3760
                        }
 
3761
 
 
3762
                        v = lex.token();
 
3763
                        if (v.id === ":") {
 
3764
                                v = lex.token();
 
3765
 
 
3766
                                if (obj === membersOnly) {
 
3767
                                        error("Expected '{a}' and instead saw '{b}'.", t, "*/", ":");
 
3768
                                }
 
3769
 
 
3770
                                if (o === "/*jshint") {
 
3771
                                        checkOption(t.value, t);
 
3772
                                }
 
3773
 
 
3774
                                var numericVals = [
 
3775
                                        "maxstatements",
 
3776
                                        "maxparams",
 
3777
                                        "maxdepth",
 
3778
                                        "maxcomplexity",
 
3779
                                        "maxerr",
 
3780
                                        "maxlen",
 
3781
                                        "indent"
 
3782
                                ];
 
3783
 
 
3784
                                if (numericVals.indexOf(t.value) > -1 && (o === "/*jshint" || o === "/*jslint")) {
 
3785
                                        b = +v.value;
 
3786
 
 
3787
                                        if (typeof b !== "number" || !isFinite(b) || b <= 0 || Math.floor(b) !== b) {
 
3788
                                                error("Expected a small integer and instead saw '{a}'.", v, v.value);
 
3789
                                        }
 
3790
 
 
3791
                                        if (t.value === "indent")
 
3792
                                                obj.white = true;
 
3793
 
 
3794
                                        obj[t.value] = b;
 
3795
                                } else if (t.value === "validthis") {
 
3796
                                        if (funct["(global)"]) {
 
3797
                                                error("Option 'validthis' can't be used in a global scope.");
 
3798
                                        } else {
 
3799
                                                if (v.value === "true" || v.value === "false")
 
3800
                                                        obj[t.value] = v.value === "true";
 
3801
                                                else
 
3802
                                                        error("Bad option value.", v);
 
3803
                                        }
 
3804
                                } else if (t.value === "quotmark" && (o === "/*jshint")) {
 
3805
                                        switch (v.value) {
 
3806
                                        case "true":
 
3807
                                                obj.quotmark = true;
 
3808
                                                break;
 
3809
                                        case "false":
 
3810
                                                obj.quotmark = false;
 
3811
                                                break;
 
3812
                                        case "double":
 
3813
                                        case "single":
 
3814
                                                obj.quotmark = v.value;
 
3815
                                                break;
 
3816
                                        default:
 
3817
                                                error("Bad option value.", v);
 
3818
                                        }
 
3819
                                } else if (v.value === "true" || v.value === "false") {
 
3820
                                        if (o === "/*jslint") {
 
3821
                                                tn = renamedOptions[t.value] || t.value;
 
3822
                                                obj[tn] = v.value === "true";
 
3823
                                                if (invertedOptions[tn] !== undefined) {
 
3824
                                                        obj[tn] = !obj[tn];
 
3825
                                                }
 
3826
                                        } else {
 
3827
                                                obj[t.value] = v.value === "true";
 
3828
                                        }
 
3829
 
 
3830
                                        if (t.value === "newcap")
 
3831
                                                obj["(explicitNewcap)"] = true;
 
3832
                                } else {
 
3833
                                        error("Bad option value.", v);
 
3834
                                }
 
3835
                                t = lex.token();
 
3836
                        } else {
 
3837
                                if (o === "/*jshint" || o === "/*jslint") {
 
3838
                                        error("Missing option value.", t);
 
3839
                                }
 
3840
 
 
3841
                                obj[t.value] = false;
 
3842
 
 
3843
                                if (o === "/*global" && minus === true) {
 
3844
                                        JSHINT.blacklist[t.value] = t.value;
 
3845
                                        updatePredefined();
 
3846
                                }
 
3847
 
 
3848
                                t = v;
 
3849
                        }
 
3850
                }
 
3851
 
 
3852
                if (o === "/*members") {
 
3853
                        option.quotmark = quotmarkValue;
 
3854
                }
 
3855
 
 
3856
                combine(predefined, predef);
 
3857
 
 
3858
                for (var key in predef) {
 
3859
                        if (is_own(predef, key)) {
 
3860
                                declared[key] = nt;
 
3861
                        }
 
3862
                }
 
3863
 
 
3864
                if (filter) {
 
3865
                        assume();
 
3866
                }
 
3867
        }
 
3868
 
 
3869
        function peek(p) {
 
3870
                var i = p || 0, j = 0, t;
 
3871
 
 
3872
                while (j <= i) {
 
3873
                        t = lookahead[j];
 
3874
                        if (!t) {
 
3875
                                t = lookahead[j] = lex.token();
 
3876
                        }
 
3877
                        j += 1;
 
3878
                }
 
3879
                return t;
 
3880
        }
 
3881
 
 
3882
        function advance(id, t) {
 
3883
                switch (token.id) {
 
3884
                case "(number)":
 
3885
                        if (nexttoken.id === ".") {
 
3886
                                warning("A dot following a number can be confused with a decimal point.", token);
 
3887
                        }
 
3888
                        break;
 
3889
                case "-":
 
3890
                        if (nexttoken.id === "-" || nexttoken.id === "--") {
 
3891
                                warning("Confusing minusses.");
 
3892
                        }
 
3893
                        break;
 
3894
                case "+":
 
3895
                        if (nexttoken.id === "+" || nexttoken.id === "++") {
 
3896
                                warning("Confusing plusses.");
 
3897
                        }
 
3898
                        break;
 
3899
                }
 
3900
 
 
3901
                if (token.type === "(string)" || token.identifier) {
 
3902
                        anonname = token.value;
 
3903
                }
 
3904
 
 
3905
                if (id && nexttoken.id !== id) {
 
3906
                        if (t) {
 
3907
                                if (nexttoken.id === "(end)") {
 
3908
                                        warning("Unmatched '{a}'.", t, t.id);
 
3909
                                } else {
 
3910
                                        warning("Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
 
3911
                                                        nexttoken, id, t.id, t.line, nexttoken.value);
 
3912
                                }
 
3913
                        } else if (nexttoken.type !== "(identifier)" ||
 
3914
                                                        nexttoken.value !== id) {
 
3915
                                warning("Expected '{a}' and instead saw '{b}'.",
 
3916
                                                nexttoken, id, nexttoken.value);
 
3917
                        }
 
3918
                }
 
3919
 
 
3920
                prevtoken = token;
 
3921
                token = nexttoken;
 
3922
                for (;;) {
 
3923
                        nexttoken = lookahead.shift() || lex.token();
 
3924
                        if (nexttoken.id === "(end)" || nexttoken.id === "(error)") {
 
3925
                                return;
 
3926
                        }
 
3927
                        if (nexttoken.type === "special") {
 
3928
                                doOption();
 
3929
                        } else {
 
3930
                                if (nexttoken.id !== "(endline)") {
 
3931
                                        break;
 
3932
                                }
 
3933
                        }
 
3934
                }
 
3935
        }
 
3936
 
 
3937
        function expression(rbp, initial) {
 
3938
                var left, isArray = false, isObject = false;
 
3939
 
 
3940
                if (nexttoken.id === "(end)")
 
3941
                        error("Unexpected early end of program.", token);
 
3942
 
 
3943
                advance();
 
3944
                if (initial) {
 
3945
                        anonname = "anonymous";
 
3946
                        funct["(verb)"] = token.value;
 
3947
                }
 
3948
                if (initial === true && token.fud) {
 
3949
                        left = token.fud();
 
3950
                } else {
 
3951
                        if (token.nud) {
 
3952
                                left = token.nud();
 
3953
                        } else {
 
3954
                                if (nexttoken.type === "(number)" && token.id === ".") {
 
3955
                                        warning("A leading decimal point can be confused with a dot: '.{a}'.",
 
3956
                                                        token, nexttoken.value);
 
3957
                                        advance();
 
3958
                                        return token;
 
3959
                                } else {
 
3960
                                        error("Expected an identifier and instead saw '{a}'.",
 
3961
                                                        token, token.id);
 
3962
                                }
 
3963
                        }
 
3964
                        while (rbp < nexttoken.lbp) {
 
3965
                                isArray = token.value === "Array";
 
3966
                                isObject = token.value === "Object";
 
3967
                                if (left && (left.value || (left.first && left.first.value))) {
 
3968
                                        if (left.value !== "new" ||
 
3969
                                          (left.first && left.first.value && left.first.value === ".")) {
 
3970
                                                isArray = false;
 
3971
                                                if (left.value !== token.value) {
 
3972
                                                        isObject = false;
 
3973
                                                }
 
3974
                                        }
 
3975
                                }
 
3976
 
 
3977
                                advance();
 
3978
                                if (isArray && token.id === "(" && nexttoken.id === ")")
 
3979
                                        warning("Use the array literal notation [].", token);
 
3980
                                if (isObject && token.id === "(" && nexttoken.id === ")")
 
3981
                                        warning("Use the object literal notation {}.", token);
 
3982
                                if (token.led) {
 
3983
                                        left = token.led(left);
 
3984
                                } else {
 
3985
                                        error("Expected an operator and instead saw '{a}'.",
 
3986
                                                token, token.id);
 
3987
                                }
 
3988
                        }
 
3989
                }
 
3990
                return left;
 
3991
        }
 
3992
 
 
3993
        function adjacent(left, right) {
 
3994
                left = left || token;
 
3995
                right = right || nexttoken;
 
3996
                if (option.white) {
 
3997
                        if (left.character !== right.from && left.line === right.line) {
 
3998
                                left.from += (left.character - left.from);
 
3999
                                warning("Unexpected space after '{a}'.", left, left.value);
 
4000
                        }
 
4001
                }
 
4002
        }
 
4003
 
 
4004
        function nobreak(left, right) {
 
4005
                left = left || token;
 
4006
                right = right || nexttoken;
 
4007
                if (option.white && (left.character !== right.from || left.line !== right.line)) {
 
4008
                        warning("Unexpected space before '{a}'.", right, right.value);
 
4009
                }
 
4010
        }
 
4011
 
 
4012
        function nospace(left, right) {
 
4013
                left = left || token;
 
4014
                right = right || nexttoken;
 
4015
                if (option.white && !left.comment) {
 
4016
                        if (left.line === right.line) {
 
4017
                                adjacent(left, right);
 
4018
                        }
 
4019
                }
 
4020
        }
 
4021
 
 
4022
        function nonadjacent(left, right) {
 
4023
                if (option.white) {
 
4024
                        left = left || token;
 
4025
                        right = right || nexttoken;
 
4026
                        if (left.value === ";" && right.value === ";") {
 
4027
                                return;
 
4028
                        }
 
4029
                        if (left.line === right.line && left.character === right.from) {
 
4030
                                left.from += (left.character - left.from);
 
4031
                                warning("Missing space after '{a}'.",
 
4032
                                                left, left.value);
 
4033
                        }
 
4034
                }
 
4035
        }
 
4036
 
 
4037
        function nobreaknonadjacent(left, right) {
 
4038
                left = left || token;
 
4039
                right = right || nexttoken;
 
4040
                if (!option.laxbreak && left.line !== right.line) {
 
4041
                        warning("Bad line breaking before '{a}'.", right, right.id);
 
4042
                } else if (option.white) {
 
4043
                        left = left || token;
 
4044
                        right = right || nexttoken;
 
4045
                        if (left.character === right.from) {
 
4046
                                left.from += (left.character - left.from);
 
4047
                                warning("Missing space after '{a}'.",
 
4048
                                                left, left.value);
 
4049
                        }
 
4050
                }
 
4051
        }
 
4052
 
 
4053
        function indentation(bias) {
 
4054
                var i;
 
4055
                if (option.white && nexttoken.id !== "(end)") {
 
4056
                        i = indent + (bias || 0);
 
4057
                        if (nexttoken.from !== i) {
 
4058
                                warning(
 
4059
"Expected '{a}' to have an indentation at {b} instead at {c}.",
 
4060
                                                nexttoken, nexttoken.value, i, nexttoken.from);
 
4061
                        }
 
4062
                }
 
4063
        }
 
4064
 
 
4065
        function nolinebreak(t) {
 
4066
                t = t || token;
 
4067
                if (t.line !== nexttoken.line) {
 
4068
                        warning("Line breaking error '{a}'.", t, t.value);
 
4069
                }
 
4070
        }
 
4071
 
 
4072
 
 
4073
        function comma() {
 
4074
                if (token.line !== nexttoken.line) {
 
4075
                        if (!option.laxcomma) {
 
4076
                                if (comma.first) {
 
4077
                                        warning("Comma warnings can be turned off with 'laxcomma'");
 
4078
                                        comma.first = false;
 
4079
                                }
 
4080
                                warning("Bad line breaking before '{a}'.", token, nexttoken.id);
 
4081
                        }
 
4082
                } else if (!token.comment && token.character !== nexttoken.from && option.white) {
 
4083
                        token.from += (token.character - token.from);
 
4084
                        warning("Unexpected space after '{a}'.", token, token.value);
 
4085
                }
 
4086
                advance(",");
 
4087
                nonadjacent(token, nexttoken);
 
4088
        }
 
4089
 
 
4090
        function symbol(s, p) {
 
4091
                var x = syntax[s];
 
4092
                if (!x || typeof x !== "object") {
 
4093
                        syntax[s] = x = {
 
4094
                                id: s,
 
4095
                                lbp: p,
 
4096
                                value: s
 
4097
                        };
 
4098
                }
 
4099
                return x;
 
4100
        }
 
4101
 
 
4102
 
 
4103
        function delim(s) {
 
4104
                return symbol(s, 0);
 
4105
        }
 
4106
 
 
4107
 
 
4108
        function stmt(s, f) {
 
4109
                var x = delim(s);
 
4110
                x.identifier = x.reserved = true;
 
4111
                x.fud = f;
 
4112
                return x;
 
4113
        }
 
4114
 
 
4115
 
 
4116
        function blockstmt(s, f) {
 
4117
                var x = stmt(s, f);
 
4118
                x.block = true;
 
4119
                return x;
 
4120
        }
 
4121
 
 
4122
 
 
4123
        function reserveName(x) {
 
4124
                var c = x.id.charAt(0);
 
4125
                if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z")) {
 
4126
                        x.identifier = x.reserved = true;
 
4127
                }
 
4128
                return x;
 
4129
        }
 
4130
 
 
4131
 
 
4132
        function prefix(s, f) {
 
4133
                var x = symbol(s, 150);
 
4134
                reserveName(x);
 
4135
                x.nud = (typeof f === "function") ? f : function () {
 
4136
                        this.right = expression(150);
 
4137
                        this.arity = "unary";
 
4138
                        if (this.id === "++" || this.id === "--") {
 
4139
                                if (option.plusplus) {
 
4140
                                        warning("Unexpected use of '{a}'.", this, this.id);
 
4141
                                } else if ((!this.right.identifier || this.right.reserved) &&
 
4142
                                                this.right.id !== "." && this.right.id !== "[") {
 
4143
                                        warning("Bad operand.", this);
 
4144
                                }
 
4145
                        }
 
4146
                        return this;
 
4147
                };
 
4148
                return x;
 
4149
        }
 
4150
 
 
4151
 
 
4152
        function type(s, f) {
 
4153
                var x = delim(s);
 
4154
                x.type = s;
 
4155
                x.nud = f;
 
4156
                return x;
 
4157
        }
 
4158
 
 
4159
 
 
4160
        function reserve(s, f) {
 
4161
                var x = type(s, f);
 
4162
                x.identifier = x.reserved = true;
 
4163
                return x;
 
4164
        }
 
4165
 
 
4166
 
 
4167
        function reservevar(s, v) {
 
4168
                return reserve(s, function () {
 
4169
                        if (typeof v === "function") {
 
4170
                                v(this);
 
4171
                        }
 
4172
                        return this;
 
4173
                });
 
4174
        }
 
4175
 
 
4176
 
 
4177
        function infix(s, f, p, w) {
 
4178
                var x = symbol(s, p);
 
4179
                reserveName(x);
 
4180
                x.led = function (left) {
 
4181
                        if (!w) {
 
4182
                                nobreaknonadjacent(prevtoken, token);
 
4183
                                nonadjacent(token, nexttoken);
 
4184
                        }
 
4185
                        if (s === "in" && left.id === "!") {
 
4186
                                warning("Confusing use of '{a}'.", left, "!");
 
4187
                        }
 
4188
                        if (typeof f === "function") {
 
4189
                                return f(left, this);
 
4190
                        } else {
 
4191
                                this.left = left;
 
4192
                                this.right = expression(p);
 
4193
                                return this;
 
4194
                        }
 
4195
                };
 
4196
                return x;
 
4197
        }
 
4198
 
 
4199
 
 
4200
        function relation(s, f) {
 
4201
                var x = symbol(s, 100);
 
4202
                x.led = function (left) {
 
4203
                        nobreaknonadjacent(prevtoken, token);
 
4204
                        nonadjacent(token, nexttoken);
 
4205
                        var right = expression(100);
 
4206
 
 
4207
                        if (isIdentifier(left, "NaN") || isIdentifier(right, "NaN")) {
 
4208
                                warning("Use the isNaN function to compare with NaN.", this);
 
4209
                        } else if (f) {
 
4210
                                f.apply(this, [left, right]);
 
4211
                        }
 
4212
                        if (left.id === "!") {
 
4213
                                warning("Confusing use of '{a}'.", left, "!");
 
4214
                        }
 
4215
                        if (right.id === "!") {
 
4216
                                warning("Confusing use of '{a}'.", right, "!");
 
4217
                        }
 
4218
                        this.left = left;
 
4219
                        this.right = right;
 
4220
                        return this;
 
4221
                };
 
4222
                return x;
 
4223
        }
 
4224
 
 
4225
 
 
4226
        function isPoorRelation(node) {
 
4227
                return node &&
 
4228
                          ((node.type === "(number)" && +node.value === 0) ||
 
4229
                           (node.type === "(string)" && node.value === "") ||
 
4230
                           (node.type === "null" && !option.eqnull) ||
 
4231
                                node.type === "true" ||
 
4232
                                node.type === "false" ||
 
4233
                                node.type === "undefined");
 
4234
        }
 
4235
 
 
4236
 
 
4237
        function assignop(s) {
 
4238
                symbol(s, 20).exps = true;
 
4239
 
 
4240
                return infix(s, function (left, that) {
 
4241
                        that.left = left;
 
4242
 
 
4243
                        if (predefined[left.value] === false &&
 
4244
                                        scope[left.value]["(global)"] === true) {
 
4245
                                warning("Read only.", left);
 
4246
                        } else if (left["function"]) {
 
4247
                                warning("'{a}' is a function.", left, left.value);
 
4248
                        }
 
4249
 
 
4250
                        if (left) {
 
4251
                                if (option.esnext && funct[left.value] === "const") {
 
4252
                                        warning("Attempting to override '{a}' which is a constant", left, left.value);
 
4253
                                }
 
4254
 
 
4255
                                if (left.id === "." || left.id === "[") {
 
4256
                                        if (!left.left || left.left.value === "arguments") {
 
4257
                                                warning("Bad assignment.", that);
 
4258
                                        }
 
4259
                                        that.right = expression(19);
 
4260
                                        return that;
 
4261
                                } else if (left.identifier && !left.reserved) {
 
4262
                                        if (funct[left.value] === "exception") {
 
4263
                                                warning("Do not assign to the exception parameter.", left);
 
4264
                                        }
 
4265
                                        that.right = expression(19);
 
4266
                                        return that;
 
4267
                                }
 
4268
 
 
4269
                                if (left === syntax["function"]) {
 
4270
                                        warning(
 
4271
"Expected an identifier in an assignment and instead saw a function invocation.",
 
4272
                                                                token);
 
4273
                                }
 
4274
                        }
 
4275
 
 
4276
                        error("Bad assignment.", that);
 
4277
                }, 20);
 
4278
        }
 
4279
 
 
4280
 
 
4281
        function bitwise(s, f, p) {
 
4282
                var x = symbol(s, p);
 
4283
                reserveName(x);
 
4284
                x.led = (typeof f === "function") ? f : function (left) {
 
4285
                        if (option.bitwise) {
 
4286
                                warning("Unexpected use of '{a}'.", this, this.id);
 
4287
                        }
 
4288
                        this.left = left;
 
4289
                        this.right = expression(p);
 
4290
                        return this;
 
4291
                };
 
4292
                return x;
 
4293
        }
 
4294
 
 
4295
 
 
4296
        function bitwiseassignop(s) {
 
4297
                symbol(s, 20).exps = true;
 
4298
                return infix(s, function (left, that) {
 
4299
                        if (option.bitwise) {
 
4300
                                warning("Unexpected use of '{a}'.", that, that.id);
 
4301
                        }
 
4302
                        nonadjacent(prevtoken, token);
 
4303
                        nonadjacent(token, nexttoken);
 
4304
                        if (left) {
 
4305
                                if (left.id === "." || left.id === "[" ||
 
4306
                                                (left.identifier && !left.reserved)) {
 
4307
                                        expression(19);
 
4308
                                        return that;
 
4309
                                }
 
4310
                                if (left === syntax["function"]) {
 
4311
                                        warning(
 
4312
"Expected an identifier in an assignment, and instead saw a function invocation.",
 
4313
                                                                token);
 
4314
                                }
 
4315
                                return that;
 
4316
                        }
 
4317
                        error("Bad assignment.", that);
 
4318
                }, 20);
 
4319
        }
 
4320
 
 
4321
 
 
4322
        function suffix(s) {
 
4323
                var x = symbol(s, 150);
 
4324
                x.led = function (left) {
 
4325
                        if (option.plusplus) {
 
4326
                                warning("Unexpected use of '{a}'.", this, this.id);
 
4327
                        } else if ((!left.identifier || left.reserved) &&
 
4328
                                        left.id !== "." && left.id !== "[") {
 
4329
                                warning("Bad operand.", this);
 
4330
                        }
 
4331
                        this.left = left;
 
4332
                        return this;
 
4333
                };
 
4334
                return x;
 
4335
        }
 
4336
        function optionalidentifier(fnparam) {
 
4337
                if (nexttoken.identifier) {
 
4338
                        advance();
 
4339
                        if (token.reserved && !option.es5) {
 
4340
                                if (!fnparam || token.value !== "undefined") {
 
4341
                                        warning("Expected an identifier and instead saw '{a}' (a reserved word).",
 
4342
                                                        token, token.id);
 
4343
                                }
 
4344
                        }
 
4345
                        return token.value;
 
4346
                }
 
4347
        }
 
4348
        function identifier(fnparam) {
 
4349
                var i = optionalidentifier(fnparam);
 
4350
                if (i) {
 
4351
                        return i;
 
4352
                }
 
4353
                if (token.id === "function" && nexttoken.id === "(") {
 
4354
                        warning("Missing name in function declaration.");
 
4355
                } else {
 
4356
                        error("Expected an identifier and instead saw '{a}'.",
 
4357
                                        nexttoken, nexttoken.value);
 
4358
                }
 
4359
        }
 
4360
 
 
4361
 
 
4362
        function reachable(s) {
 
4363
                var i = 0, t;
 
4364
                if (nexttoken.id !== ";" || noreach) {
 
4365
                        return;
 
4366
                }
 
4367
                for (;;) {
 
4368
                        t = peek(i);
 
4369
                        if (t.reach) {
 
4370
                                return;
 
4371
                        }
 
4372
                        if (t.id !== "(endline)") {
 
4373
                                if (t.id === "function") {
 
4374
                                        if (!option.latedef) {
 
4375
                                                break;
 
4376
                                        }
 
4377
                                        warning(
 
4378
"Inner functions should be listed at the top of the outer function.", t);
 
4379
                                        break;
 
4380
                                }
 
4381
                                warning("Unreachable '{a}' after '{b}'.", t, t.value, s);
 
4382
                                break;
 
4383
                        }
 
4384
                        i += 1;
 
4385
                }
 
4386
        }
 
4387
 
 
4388
 
 
4389
        function statement(noindent) {
 
4390
                var i = indent, r, s = scope, t = nexttoken;
 
4391
 
 
4392
                if (t.id === ";") {
 
4393
                        advance(";");
 
4394
                        return;
 
4395
                }
 
4396
 
 
4397
                if (t.identifier && !t.reserved && peek().id === ":") {
 
4398
                        advance();
 
4399
                        advance(":");
 
4400
                        scope = Object.create(s);
 
4401
                        addlabel(t.value, "label");
 
4402
 
 
4403
                        if (!nexttoken.labelled && nexttoken.value !== "{") {
 
4404
                                warning("Label '{a}' on {b} statement.", nexttoken, t.value, nexttoken.value);
 
4405
                        }
 
4406
 
 
4407
                        if (jx.test(t.value + ":")) {
 
4408
                                warning("Label '{a}' looks like a javascript url.", t, t.value);
 
4409
                        }
 
4410
 
 
4411
                        nexttoken.label = t.value;
 
4412
                        t = nexttoken;
 
4413
                }
 
4414
 
 
4415
                if (t.id === "{") {
 
4416
                        block(true, true);
 
4417
                        return;
 
4418
                }
 
4419
 
 
4420
                if (!noindent) {
 
4421
                        indentation();
 
4422
                }
 
4423
                r = expression(0, true);
 
4424
 
 
4425
                if (!t.block) {
 
4426
                        if (!option.expr && (!r || !r.exps)) {
 
4427
                                warning("Expected an assignment or function call and instead saw an expression.",
 
4428
                                        token);
 
4429
                        } else if (option.nonew && r.id === "(" && r.left.id === "new") {
 
4430
                                warning("Do not use 'new' for side effects.", t);
 
4431
                        }
 
4432
 
 
4433
                        if (nexttoken.id === ",") {
 
4434
                                return comma();
 
4435
                        }
 
4436
 
 
4437
                        if (nexttoken.id !== ";") {
 
4438
                                if (!option.asi) {
 
4439
                                        if (!option.lastsemic || nexttoken.id !== "}" ||
 
4440
                                                        nexttoken.line !== token.line) {
 
4441
                                                warningAt("Missing semicolon.", token.line, token.character);
 
4442
                                        }
 
4443
                                }
 
4444
                        } else {
 
4445
                                adjacent(token, nexttoken);
 
4446
                                advance(";");
 
4447
                                nonadjacent(token, nexttoken);
 
4448
                        }
 
4449
                }
 
4450
 
 
4451
                indent = i;
 
4452
                scope = s;
 
4453
                return r;
 
4454
        }
 
4455
 
 
4456
 
 
4457
        function statements(startLine) {
 
4458
                var a = [], p;
 
4459
 
 
4460
                while (!nexttoken.reach && nexttoken.id !== "(end)") {
 
4461
                        if (nexttoken.id === ";") {
 
4462
                                p = peek();
 
4463
                                if (!p || p.id !== "(") {
 
4464
                                        warning("Unnecessary semicolon.");
 
4465
                                }
 
4466
                                advance(";");
 
4467
                        } else {
 
4468
                                a.push(statement(startLine === nexttoken.line));
 
4469
                        }
 
4470
                }
 
4471
                return a;
 
4472
        }
 
4473
        function directives() {
 
4474
                var i, p, pn;
 
4475
 
 
4476
                for (;;) {
 
4477
                        if (nexttoken.id === "(string)") {
 
4478
                                p = peek(0);
 
4479
                                if (p.id === "(endline)") {
 
4480
                                        i = 1;
 
4481
                                        do {
 
4482
                                                pn = peek(i);
 
4483
                                                i = i + 1;
 
4484
                                        } while (pn.id === "(endline)");
 
4485
 
 
4486
                                        if (pn.id !== ";") {
 
4487
                                                if (pn.id !== "(string)" && pn.id !== "(number)" &&
 
4488
                                                        pn.id !== "(regexp)" && pn.identifier !== true &&
 
4489
                                                        pn.id !== "}") {
 
4490
                                                        break;
 
4491
                                                }
 
4492
                                                warning("Missing semicolon.", nexttoken);
 
4493
                                        } else {
 
4494
                                                p = pn;
 
4495
                                        }
 
4496
                                } else if (p.id === "}") {
 
4497
                                        warning("Missing semicolon.", p);
 
4498
                                } else if (p.id !== ";") {
 
4499
                                        break;
 
4500
                                }
 
4501
 
 
4502
                                indentation();
 
4503
                                advance();
 
4504
                                if (directive[token.value]) {
 
4505
                                        warning("Unnecessary directive \"{a}\".", token, token.value);
 
4506
                                }
 
4507
 
 
4508
                                if (token.value === "use strict") {
 
4509
                                        if (!option["(explicitNewcap)"])
 
4510
                                                option.newcap = true;
 
4511
                                        option.undef = true;
 
4512
                                }
 
4513
                                directive[token.value] = true;
 
4514
 
 
4515
                                if (p.id === ";") {
 
4516
                                        advance(";");
 
4517
                                }
 
4518
                                continue;
 
4519
                        }
 
4520
                        break;
 
4521
                }
 
4522
        }
 
4523
        function block(ordinary, stmt, isfunc) {
 
4524
                var a,
 
4525
                        b = inblock,
 
4526
                        old_indent = indent,
 
4527
                        m,
 
4528
                        s = scope,
 
4529
                        t,
 
4530
                        line,
 
4531
                        d;
 
4532
 
 
4533
                inblock = ordinary;
 
4534
 
 
4535
                if (!ordinary || !option.funcscope)
 
4536
                        scope = Object.create(scope);
 
4537
 
 
4538
                nonadjacent(token, nexttoken);
 
4539
                t = nexttoken;
 
4540
 
 
4541
                var metrics = funct["(metrics)"];
 
4542
                metrics.nestedBlockDepth += 1;
 
4543
                metrics.verifyMaxNestedBlockDepthPerFunction();
 
4544
 
 
4545
                if (nexttoken.id === "{") {
 
4546
                        advance("{");
 
4547
                        line = token.line;
 
4548
                        if (nexttoken.id !== "}") {
 
4549
                                indent += option.indent;
 
4550
                                while (!ordinary && nexttoken.from > indent) {
 
4551
                                        indent += option.indent;
 
4552
                                }
 
4553
 
 
4554
                                if (isfunc) {
 
4555
                                        m = {};
 
4556
                                        for (d in directive) {
 
4557
                                                if (is_own(directive, d)) {
 
4558
                                                        m[d] = directive[d];
 
4559
                                                }
 
4560
                                        }
 
4561
                                        directives();
 
4562
 
 
4563
                                        if (option.strict && funct["(context)"]["(global)"]) {
 
4564
                                                if (!m["use strict"] && !directive["use strict"]) {
 
4565
                                                        warning("Missing \"use strict\" statement.");
 
4566
                                                }
 
4567
                                        }
 
4568
                                }
 
4569
 
 
4570
                                a = statements(line);
 
4571
 
 
4572
                                metrics.statementCount += a.length;
 
4573
 
 
4574
                                if (isfunc) {
 
4575
                                        directive = m;
 
4576
                                }
 
4577
 
 
4578
                                indent -= option.indent;
 
4579
                                if (line !== nexttoken.line) {
 
4580
                                        indentation();
 
4581
                                }
 
4582
                        } else if (line !== nexttoken.line) {
 
4583
                                indentation();
 
4584
                        }
 
4585
                        advance("}", t);
 
4586
                        indent = old_indent;
 
4587
                } else if (!ordinary) {
 
4588
                        error("Expected '{a}' and instead saw '{b}'.",
 
4589
                                  nexttoken, "{", nexttoken.value);
 
4590
                } else {
 
4591
                        if (!stmt || option.curly)
 
4592
                                warning("Expected '{a}' and instead saw '{b}'.",
 
4593
                                                nexttoken, "{", nexttoken.value);
 
4594
 
 
4595
                        noreach = true;
 
4596
                        indent += option.indent;
 
4597
                        a = [statement(nexttoken.line === token.line)];
 
4598
                        indent -= option.indent;
 
4599
                        noreach = false;
 
4600
                }
 
4601
                funct["(verb)"] = null;
 
4602
                if (!ordinary || !option.funcscope) scope = s;
 
4603
                inblock = b;
 
4604
                if (ordinary && option.noempty && (!a || a.length === 0)) {
 
4605
                        warning("Empty block.");
 
4606
                }
 
4607
                metrics.nestedBlockDepth -= 1;
 
4608
                return a;
 
4609
        }
 
4610
 
 
4611
 
 
4612
        function countMember(m) {
 
4613
                if (membersOnly && typeof membersOnly[m] !== "boolean") {
 
4614
                        warning("Unexpected /*member '{a}'.", token, m);
 
4615
                }
 
4616
                if (typeof member[m] === "number") {
 
4617
                        member[m] += 1;
 
4618
                } else {
 
4619
                        member[m] = 1;
 
4620
                }
 
4621
        }
 
4622
 
 
4623
 
 
4624
        function note_implied(token) {
 
4625
                var name = token.value, line = token.line, a = implied[name];
 
4626
                if (typeof a === "function") {
 
4627
                        a = false;
 
4628
                }
 
4629
 
 
4630
                if (!a) {
 
4631
                        a = [line];
 
4632
                        implied[name] = a;
 
4633
                } else if (a[a.length - 1] !== line) {
 
4634
                        a.push(line);
 
4635
                }
 
4636
        }
 
4637
 
 
4638
        type("(number)", function () {
 
4639
                return this;
 
4640
        });
 
4641
 
 
4642
        type("(string)", function () {
 
4643
                return this;
 
4644
        });
 
4645
 
 
4646
        syntax["(identifier)"] = {
 
4647
                type: "(identifier)",
 
4648
                lbp: 0,
 
4649
                identifier: true,
 
4650
                nud: function () {
 
4651
                        var v = this.value,
 
4652
                                s = scope[v],
 
4653
                                f;
 
4654
 
 
4655
                        if (typeof s === "function") {
 
4656
                                s = undefined;
 
4657
                        } else if (typeof s === "boolean") {
 
4658
                                f = funct;
 
4659
                                funct = functions[0];
 
4660
                                addlabel(v, "var");
 
4661
                                s = funct;
 
4662
                                funct = f;
 
4663
                        }
 
4664
                        if (funct === s) {
 
4665
                                switch (funct[v]) {
 
4666
                                case "unused":
 
4667
                                        funct[v] = "var";
 
4668
                                        break;
 
4669
                                case "unction":
 
4670
                                        funct[v] = "function";
 
4671
                                        this["function"] = true;
 
4672
                                        break;
 
4673
                                case "function":
 
4674
                                        this["function"] = true;
 
4675
                                        break;
 
4676
                                case "label":
 
4677
                                        warning("'{a}' is a statement label.", token, v);
 
4678
                                        break;
 
4679
                                }
 
4680
                        } else if (funct["(global)"]) {
 
4681
 
 
4682
                                if (option.undef && typeof predefined[v] !== "boolean") {
 
4683
                                        if (!(anonname === "typeof" || anonname === "delete") ||
 
4684
                                                (nexttoken && (nexttoken.value === "." || nexttoken.value === "["))) {
 
4685
 
 
4686
                                                isundef(funct, "'{a}' is not defined.", token, v);
 
4687
                                        }
 
4688
                                }
 
4689
 
 
4690
                                note_implied(token);
 
4691
                        } else {
 
4692
 
 
4693
                                switch (funct[v]) {
 
4694
                                case "closure":
 
4695
                                case "function":
 
4696
                                case "var":
 
4697
                                case "unused":
 
4698
                                        warning("'{a}' used out of scope.", token, v);
 
4699
                                        break;
 
4700
                                case "label":
 
4701
                                        warning("'{a}' is a statement label.", token, v);
 
4702
                                        break;
 
4703
                                case "outer":
 
4704
                                case "global":
 
4705
                                        break;
 
4706
                                default:
 
4707
                                        if (s === true) {
 
4708
                                                funct[v] = true;
 
4709
                                        } else if (s === null) {
 
4710
                                                warning("'{a}' is not allowed.", token, v);
 
4711
                                                note_implied(token);
 
4712
                                        } else if (typeof s !== "object") {
 
4713
                                                if (option.undef) {
 
4714
                                                        if (!(anonname === "typeof" || anonname === "delete") ||
 
4715
                                                                (nexttoken &&
 
4716
                                                                        (nexttoken.value === "." || nexttoken.value === "["))) {
 
4717
 
 
4718
                                                                isundef(funct, "'{a}' is not defined.", token, v);
 
4719
                                                        }
 
4720
                                                }
 
4721
                                                funct[v] = true;
 
4722
                                                note_implied(token);
 
4723
                                        } else {
 
4724
                                                switch (s[v]) {
 
4725
                                                case "function":
 
4726
                                                case "unction":
 
4727
                                                        this["function"] = true;
 
4728
                                                        s[v] = "closure";
 
4729
                                                        funct[v] = s["(global)"] ? "global" : "outer";
 
4730
                                                        break;
 
4731
                                                case "var":
 
4732
                                                case "unused":
 
4733
                                                        s[v] = "closure";
 
4734
                                                        funct[v] = s["(global)"] ? "global" : "outer";
 
4735
                                                        break;
 
4736
                                                case "closure":
 
4737
                                                        funct[v] = s["(global)"] ? "global" : "outer";
 
4738
                                                        break;
 
4739
                                                case "label":
 
4740
                                                        warning("'{a}' is a statement label.", token, v);
 
4741
                                                }
 
4742
                                        }
 
4743
                                }
 
4744
                        }
 
4745
                        return this;
 
4746
                },
 
4747
                led: function () {
 
4748
                        error("Expected an operator and instead saw '{a}'.",
 
4749
                                nexttoken, nexttoken.value);
 
4750
                }
 
4751
        };
 
4752
 
 
4753
        type("(regexp)", function () {
 
4754
                return this;
 
4755
        });
 
4756
 
 
4757
        delim("(endline)");
 
4758
        delim("(begin)");
 
4759
        delim("(end)").reach = true;
 
4760
        delim("</").reach = true;
 
4761
        delim("<!");
 
4762
        delim("<!--");
 
4763
        delim("-->");
 
4764
        delim("(error)").reach = true;
 
4765
        delim("}").reach = true;
 
4766
        delim(")");
 
4767
        delim("]");
 
4768
        delim("\"").reach = true;
 
4769
        delim("'").reach = true;
 
4770
        delim(";");
 
4771
        delim(":").reach = true;
 
4772
        delim(",");
 
4773
        delim("#");
 
4774
        delim("@");
 
4775
        reserve("else");
 
4776
        reserve("case").reach = true;
 
4777
        reserve("catch");
 
4778
        reserve("default").reach = true;
 
4779
        reserve("finally");
 
4780
        reservevar("arguments", function (x) {
 
4781
                if (directive["use strict"] && funct["(global)"]) {
 
4782
                        warning("Strict violation.", x);
 
4783
                }
 
4784
        });
 
4785
        reservevar("eval");
 
4786
        reservevar("false");
 
4787
        reservevar("Infinity");
 
4788
        reservevar("null");
 
4789
        reservevar("this", function (x) {
 
4790
                if (directive["use strict"] && !option.validthis && ((funct["(statement)"] &&
 
4791
                                funct["(name)"].charAt(0) > "Z") || funct["(global)"])) {
 
4792
                        warning("Possible strict violation.", x);
 
4793
                }
 
4794
        });
 
4795
        reservevar("true");
 
4796
        reservevar("undefined");
 
4797
        assignop("=", "assign", 20);
 
4798
        assignop("+=", "assignadd", 20);
 
4799
        assignop("-=", "assignsub", 20);
 
4800
        assignop("*=", "assignmult", 20);
 
4801
        assignop("/=", "assigndiv", 20).nud = function () {
 
4802
                error("A regular expression literal can be confused with '/='.");
 
4803
        };
 
4804
        assignop("%=", "assignmod", 20);
 
4805
        bitwiseassignop("&=", "assignbitand", 20);
 
4806
        bitwiseassignop("|=", "assignbitor", 20);
 
4807
        bitwiseassignop("^=", "assignbitxor", 20);
 
4808
        bitwiseassignop("<<=", "assignshiftleft", 20);
 
4809
        bitwiseassignop(">>=", "assignshiftright", 20);
 
4810
        bitwiseassignop(">>>=", "assignshiftrightunsigned", 20);
 
4811
        infix("?", function (left, that) {
 
4812
                that.left = left;
 
4813
                that.right = expression(10);
 
4814
                advance(":");
 
4815
                that["else"] = expression(10);
 
4816
                return that;
 
4817
        }, 30);
 
4818
 
 
4819
        infix("||", "or", 40);
 
4820
        infix("&&", "and", 50);
 
4821
        bitwise("|", "bitor", 70);
 
4822
        bitwise("^", "bitxor", 80);
 
4823
        bitwise("&", "bitand", 90);
 
4824
        relation("==", function (left, right) {
 
4825
                var eqnull = option.eqnull && (left.value === "null" || right.value === "null");
 
4826
 
 
4827
                if (!eqnull && option.eqeqeq)
 
4828
                        warning("Expected '{a}' and instead saw '{b}'.", this, "===", "==");
 
4829
                else if (isPoorRelation(left))
 
4830
                        warning("Use '{a}' to compare with '{b}'.", this, "===", left.value);
 
4831
                else if (isPoorRelation(right))
 
4832
                        warning("Use '{a}' to compare with '{b}'.", this, "===", right.value);
 
4833
 
 
4834
                return this;
 
4835
        });
 
4836
        relation("===");
 
4837
        relation("!=", function (left, right) {
 
4838
                var eqnull = option.eqnull &&
 
4839
                                (left.value === "null" || right.value === "null");
 
4840
 
 
4841
                if (!eqnull && option.eqeqeq) {
 
4842
                        warning("Expected '{a}' and instead saw '{b}'.",
 
4843
                                        this, "!==", "!=");
 
4844
                } else if (isPoorRelation(left)) {
 
4845
                        warning("Use '{a}' to compare with '{b}'.",
 
4846
                                        this, "!==", left.value);
 
4847
                } else if (isPoorRelation(right)) {
 
4848
                        warning("Use '{a}' to compare with '{b}'.",
 
4849
                                        this, "!==", right.value);
 
4850
                }
 
4851
                return this;
 
4852
        });
 
4853
        relation("!==");
 
4854
        relation("<");
 
4855
        relation(">");
 
4856
        relation("<=");
 
4857
        relation(">=");
 
4858
        bitwise("<<", "shiftleft", 120);
 
4859
        bitwise(">>", "shiftright", 120);
 
4860
        bitwise(">>>", "shiftrightunsigned", 120);
 
4861
        infix("in", "in", 120);
 
4862
        infix("instanceof", "instanceof", 120);
 
4863
        infix("+", function (left, that) {
 
4864
                var right = expression(130);
 
4865
                if (left && right && left.id === "(string)" && right.id === "(string)") {
 
4866
                        left.value += right.value;
 
4867
                        left.character = right.character;
 
4868
                        if (!option.scripturl && jx.test(left.value)) {
 
4869
                                warning("JavaScript URL.", left);
 
4870
                        }
 
4871
                        return left;
 
4872
                }
 
4873
                that.left = left;
 
4874
                that.right = right;
 
4875
                return that;
 
4876
        }, 130);
 
4877
        prefix("+", "num");
 
4878
        prefix("+++", function () {
 
4879
                warning("Confusing pluses.");
 
4880
                this.right = expression(150);
 
4881
                this.arity = "unary";
 
4882
                return this;
 
4883
        });
 
4884
        infix("+++", function (left) {
 
4885
                warning("Confusing pluses.");
 
4886
                this.left = left;
 
4887
                this.right = expression(130);
 
4888
                return this;
 
4889
        }, 130);
 
4890
        infix("-", "sub", 130);
 
4891
        prefix("-", "neg");
 
4892
        prefix("---", function () {
 
4893
                warning("Confusing minuses.");
 
4894
                this.right = expression(150);
 
4895
                this.arity = "unary";
 
4896
                return this;
 
4897
        });
 
4898
        infix("---", function (left) {
 
4899
                warning("Confusing minuses.");
 
4900
                this.left = left;
 
4901
                this.right = expression(130);
 
4902
                return this;
 
4903
        }, 130);
 
4904
        infix("*", "mult", 140);
 
4905
        infix("/", "div", 140);
 
4906
        infix("%", "mod", 140);
 
4907
 
 
4908
        suffix("++", "postinc");
 
4909
        prefix("++", "preinc");
 
4910
        syntax["++"].exps = true;
 
4911
 
 
4912
        suffix("--", "postdec");
 
4913
        prefix("--", "predec");
 
4914
        syntax["--"].exps = true;
 
4915
        prefix("delete", function () {
 
4916
                var p = expression(0);
 
4917
                if (!p || (p.id !== "." && p.id !== "[")) {
 
4918
                        warning("Variables should not be deleted.");
 
4919
                }
 
4920
                this.first = p;
 
4921
                return this;
 
4922
        }).exps = true;
 
4923
 
 
4924
        prefix("~", function () {
 
4925
                if (option.bitwise) {
 
4926
                        warning("Unexpected '{a}'.", this, "~");
 
4927
                }
 
4928
                expression(150);
 
4929
                return this;
 
4930
        });
 
4931
 
 
4932
        prefix("!", function () {
 
4933
                this.right = expression(150);
 
4934
                this.arity = "unary";
 
4935
                if (bang[this.right.id] === true) {
 
4936
                        warning("Confusing use of '{a}'.", this, "!");
 
4937
                }
 
4938
                return this;
 
4939
        });
 
4940
        prefix("typeof", "typeof");
 
4941
        prefix("new", function () {
 
4942
                var c = expression(155), i;
 
4943
                if (c && c.id !== "function") {
 
4944
                        if (c.identifier) {
 
4945
                                c["new"] = true;
 
4946
                                switch (c.value) {
 
4947
                                case "Number":
 
4948
                                case "String":
 
4949
                                case "Boolean":
 
4950
                                case "Math":
 
4951
                                case "JSON":
 
4952
                                        warning("Do not use {a} as a constructor.", prevtoken, c.value);
 
4953
                                        break;
 
4954
                                case "Function":
 
4955
                                        if (!option.evil) {
 
4956
                                                warning("The Function constructor is eval.");
 
4957
                                        }
 
4958
                                        break;
 
4959
                                case "Date":
 
4960
                                case "RegExp":
 
4961
                                        break;
 
4962
                                default:
 
4963
                                        if (c.id !== "function") {
 
4964
                                                i = c.value.substr(0, 1);
 
4965
                                                if (option.newcap && (i < "A" || i > "Z") && !is_own(global, c.value)) {
 
4966
                                                        warning("A constructor name should start with an uppercase letter.",
 
4967
                                                                token);
 
4968
                                                }
 
4969
                                        }
 
4970
                                }
 
4971
                        } else {
 
4972
                                if (c.id !== "." && c.id !== "[" && c.id !== "(") {
 
4973
                                        warning("Bad constructor.", token);
 
4974
                                }
 
4975
                        }
 
4976
                } else {
 
4977
                        if (!option.supernew)
 
4978
                                warning("Weird construction. Delete 'new'.", this);
 
4979
                }
 
4980
                adjacent(token, nexttoken);
 
4981
                if (nexttoken.id !== "(" && !option.supernew) {
 
4982
                        warning("Missing '()' invoking a constructor.",
 
4983
                                token, token.value);
 
4984
                }
 
4985
                this.first = c;
 
4986
                return this;
 
4987
        });
 
4988
        syntax["new"].exps = true;
 
4989
 
 
4990
        prefix("void").exps = true;
 
4991
 
 
4992
        infix(".", function (left, that) {
 
4993
                adjacent(prevtoken, token);
 
4994
                nobreak();
 
4995
                var m = identifier();
 
4996
                if (typeof m === "string") {
 
4997
                        countMember(m);
 
4998
                }
 
4999
                that.left = left;
 
5000
                that.right = m;
 
5001
                if (left && left.value === "arguments" && (m === "callee" || m === "caller")) {
 
5002
                        if (option.noarg)
 
5003
                                warning("Avoid arguments.{a}.", left, m);
 
5004
                        else if (directive["use strict"])
 
5005
                                error("Strict violation.");
 
5006
                } else if (!option.evil && left && left.value === "document" &&
 
5007
                                (m === "write" || m === "writeln")) {
 
5008
                        warning("document.write can be a form of eval.", left);
 
5009
                }
 
5010
                if (!option.evil && (m === "eval" || m === "execScript")) {
 
5011
                        warning("eval is evil.");
 
5012
                }
 
5013
                return that;
 
5014
        }, 160, true);
 
5015
 
 
5016
        infix("(", function (left, that) {
 
5017
                if (prevtoken.id !== "}" && prevtoken.id !== ")") {
 
5018
                        nobreak(prevtoken, token);
 
5019
                }
 
5020
                nospace();
 
5021
                if (option.immed && !left.immed && left.id === "function") {
 
5022
                        warning("Wrap an immediate function invocation in parentheses " +
 
5023
                                "to assist the reader in understanding that the expression " +
 
5024
                                "is the result of a function, and not the function itself.");
 
5025
                }
 
5026
                var n = 0,
 
5027
                        p = [];
 
5028
                if (left) {
 
5029
                        if (left.type === "(identifier)") {
 
5030
                                if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) {
 
5031
                                        if ("Number String Boolean Date Object".indexOf(left.value) === -1) {
 
5032
                                                if (left.value === "Math") {
 
5033
                                                        warning("Math is not a function.", left);
 
5034
                                                } else if (option.newcap) {
 
5035
                                                        warning("Missing 'new' prefix when invoking a constructor.", left);
 
5036
                                                }
 
5037
                                        }
 
5038
                                }
 
5039
                        }
 
5040
                }
 
5041
                if (nexttoken.id !== ")") {
 
5042
                        for (;;) {
 
5043
                                p[p.length] = expression(10);
 
5044
                                n += 1;
 
5045
                                if (nexttoken.id !== ",") {
 
5046
                                        break;
 
5047
                                }
 
5048
                                comma();
 
5049
                        }
 
5050
                }
 
5051
                advance(")");
 
5052
                nospace(prevtoken, token);
 
5053
                if (typeof left === "object") {
 
5054
                        if (left.value === "parseInt" && n === 1) {
 
5055
                                warning("Missing radix parameter.", token);
 
5056
                        }
 
5057
                        if (!option.evil) {
 
5058
                                if (left.value === "eval" || left.value === "Function" ||
 
5059
                                                left.value === "execScript") {
 
5060
                                        warning("eval is evil.", left);
 
5061
 
 
5062
                                        if (p[0] && [0].id === "(string)") {
 
5063
                                                addInternalSrc(left, p[0].value);
 
5064
                                        }
 
5065
                                } else if (p[0] && p[0].id === "(string)" &&
 
5066
                                           (left.value === "setTimeout" ||
 
5067
                                                left.value === "setInterval")) {
 
5068
                                        warning(
 
5069
        "Implied eval is evil. Pass a function instead of a string.", left);
 
5070
                                        addInternalSrc(left, p[0].value);
 
5071
                                } else if (p[0] && p[0].id === "(string)" &&
 
5072
                                           left.value === "." &&
 
5073
                                           left.left.value === "window" &&
 
5074
                                           (left.right === "setTimeout" ||
 
5075
                                                left.right === "setInterval")) {
 
5076
                                        warning(
 
5077
        "Implied eval is evil. Pass a function instead of a string.", left);
 
5078
                                        addInternalSrc(left, p[0].value);
 
5079
                                }
 
5080
                        }
 
5081
                        if (!left.identifier && left.id !== "." && left.id !== "[" &&
 
5082
                                        left.id !== "(" && left.id !== "&&" && left.id !== "||" &&
 
5083
                                        left.id !== "?") {
 
5084
                                warning("Bad invocation.", left);
 
5085
                        }
 
5086
                }
 
5087
                that.left = left;
 
5088
                return that;
 
5089
        }, 155, true).exps = true;
 
5090
 
 
5091
        prefix("(", function () {
 
5092
                nospace();
 
5093
                if (nexttoken.id === "function") {
 
5094
                        nexttoken.immed = true;
 
5095
                }
 
5096
                var v = expression(0);
 
5097
                advance(")", this);
 
5098
                nospace(prevtoken, token);
 
5099
                if (option.immed && v.id === "function") {
 
5100
                        if (nexttoken.id !== "(" &&
 
5101
                          (nexttoken.id !== "." || (peek().value !== "call" && peek().value !== "apply"))) {
 
5102
                                warning(
 
5103
"Do not wrap function literals in parens unless they are to be immediately invoked.",
 
5104
                                                this);
 
5105
                        }
 
5106
                }
 
5107
 
 
5108
                return v;
 
5109
        });
 
5110
 
 
5111
        infix("[", function (left, that) {
 
5112
                nobreak(prevtoken, token);
 
5113
                nospace();
 
5114
                var e = expression(0), s;
 
5115
                if (e && e.type === "(string)") {
 
5116
                        if (!option.evil && (e.value === "eval" || e.value === "execScript")) {
 
5117
                                warning("eval is evil.", that);
 
5118
                        }
 
5119
                        countMember(e.value);
 
5120
                        if (!option.sub && ix.test(e.value)) {
 
5121
                                s = syntax[e.value];
 
5122
                                if (!s || !s.reserved) {
 
5123
                                        warning("['{a}'] is better written in dot notation.",
 
5124
                                                        prevtoken, e.value);
 
5125
                                }
 
5126
                        }
 
5127
                }
 
5128
                advance("]", that);
 
5129
                nospace(prevtoken, token);
 
5130
                that.left = left;
 
5131
                that.right = e;
 
5132
                return that;
 
5133
        }, 160, true);
 
5134
 
 
5135
        prefix("[", function () {
 
5136
                var b = token.line !== nexttoken.line;
 
5137
                this.first = [];
 
5138
                if (b) {
 
5139
                        indent += option.indent;
 
5140
                        if (nexttoken.from === indent + option.indent) {
 
5141
                                indent += option.indent;
 
5142
                        }
 
5143
                }
 
5144
                while (nexttoken.id !== "(end)") {
 
5145
                        while (nexttoken.id === ",") {
 
5146
                                if (!option.es5)
 
5147
                                        warning("Extra comma.");
 
5148
                                advance(",");
 
5149
                        }
 
5150
                        if (nexttoken.id === "]") {
 
5151
                                break;
 
5152
                        }
 
5153
                        if (b && token.line !== nexttoken.line) {
 
5154
                                indentation();
 
5155
                        }
 
5156
                        this.first.push(expression(10));
 
5157
                        if (nexttoken.id === ",") {
 
5158
                                comma();
 
5159
                                if (nexttoken.id === "]" && !option.es5) {
 
5160
                                        warning("Extra comma.", token);
 
5161
                                        break;
 
5162
                                }
 
5163
                        } else {
 
5164
                                break;
 
5165
                        }
 
5166
                }
 
5167
                if (b) {
 
5168
                        indent -= option.indent;
 
5169
                        indentation();
 
5170
                }
 
5171
                advance("]", this);
 
5172
                return this;
 
5173
        }, 160);
 
5174
 
 
5175
 
 
5176
        function property_name() {
 
5177
                var id = optionalidentifier(true);
 
5178
                if (!id) {
 
5179
                        if (nexttoken.id === "(string)") {
 
5180
                                id = nexttoken.value;
 
5181
                                advance();
 
5182
                        } else if (nexttoken.id === "(number)") {
 
5183
                                id = nexttoken.value.toString();
 
5184
                                advance();
 
5185
                        }
 
5186
                }
 
5187
                return id;
 
5188
        }
 
5189
 
 
5190
 
 
5191
        function functionparams() {
 
5192
                var next   = nexttoken;
 
5193
                var params = [];
 
5194
                var ident;
 
5195
 
 
5196
                advance("(");
 
5197
                nospace();
 
5198
 
 
5199
                if (nexttoken.id === ")") {
 
5200
                        advance(")");
 
5201
                        return;
 
5202
                }
 
5203
 
 
5204
                for (;;) {
 
5205
                        ident = identifier(true);
 
5206
                        params.push(ident);
 
5207
                        addlabel(ident, "unused", token);
 
5208
                        if (nexttoken.id === ",") {
 
5209
                                comma();
 
5210
                        } else {
 
5211
                                advance(")", next);
 
5212
                                nospace(prevtoken, token);
 
5213
                                return params;
 
5214
                        }
 
5215
                }
 
5216
        }
 
5217
 
 
5218
 
 
5219
        function doFunction(name, statement) {
 
5220
                var f;
 
5221
                var oldOption = option;
 
5222
                var oldScope  = scope;
 
5223
 
 
5224
                option = Object.create(option);
 
5225
                scope  = Object.create(scope);
 
5226
 
 
5227
                funct = {
 
5228
                        "(name)"         : name || "\"" + anonname + "\"",
 
5229
                        "(line)"         : nexttoken.line,
 
5230
                        "(character)": nexttoken.character,
 
5231
                        "(context)"  : funct,
 
5232
                        "(breakage)" : 0,
 
5233
                        "(loopage)"  : 0,
 
5234
                        "(metrics)"  : createMetrics(nexttoken),
 
5235
                        "(scope)"        : scope,
 
5236
                        "(statement)": statement,
 
5237
                        "(tokens)"       : {}
 
5238
                };
 
5239
 
 
5240
                f = funct;
 
5241
                token.funct = funct;
 
5242
 
 
5243
                functions.push(funct);
 
5244
 
 
5245
                if (name) {
 
5246
                        addlabel(name, "function");
 
5247
                }
 
5248
 
 
5249
                funct["(params)"] = functionparams();
 
5250
                funct["(metrics)"].verifyMaxParametersPerFunction(funct["(params)"]);
 
5251
 
 
5252
                block(false, false, true);
 
5253
 
 
5254
                funct["(metrics)"].verifyMaxStatementsPerFunction();
 
5255
                funct["(metrics)"].verifyMaxComplexityPerFunction();
 
5256
 
 
5257
                scope = oldScope;
 
5258
                option = oldOption;
 
5259
                funct["(last)"] = token.line;
 
5260
                funct["(lastcharacter)"] = token.character;
 
5261
                funct = funct["(context)"];
 
5262
 
 
5263
                return f;
 
5264
        }
 
5265
 
 
5266
        function createMetrics(functionStartToken) {
 
5267
                return {
 
5268
                        statementCount: 0,
 
5269
                        nestedBlockDepth: -1,
 
5270
                        ComplexityCount: 1,
 
5271
                        verifyMaxStatementsPerFunction: function () {
 
5272
                                if (option.maxstatements &&
 
5273
                                        this.statementCount > option.maxstatements) {
 
5274
                                        var message = "Too many statements per function (" + this.statementCount + ").";
 
5275
                                        warning(message, functionStartToken);
 
5276
                                }
 
5277
                        },
 
5278
 
 
5279
                        verifyMaxParametersPerFunction: function (params) {
 
5280
                                params = params || [];
 
5281
 
 
5282
                                if (option.maxparams && params.length > option.maxparams) {
 
5283
                                        var message = "Too many parameters per function (" + params.length + ").";
 
5284
                                        warning(message, functionStartToken);
 
5285
                                }
 
5286
                        },
 
5287
 
 
5288
                        verifyMaxNestedBlockDepthPerFunction: function () {
 
5289
                                if (option.maxdepth &&
 
5290
                                        this.nestedBlockDepth > 0 &&
 
5291
                                        this.nestedBlockDepth === option.maxdepth + 1) {
 
5292
                                        var message = "Blocks are nested too deeply (" + this.nestedBlockDepth + ").";
 
5293
                                        warning(message);
 
5294
                                }
 
5295
                        },
 
5296
 
 
5297
                        verifyMaxComplexityPerFunction: function () {
 
5298
                                var max = option.maxcomplexity;
 
5299
                                var cc = this.ComplexityCount;
 
5300
                                if (max && cc > max) {
 
5301
                                        var message = "Cyclomatic complexity is too high per function (" + cc + ").";
 
5302
                                        warning(message, functionStartToken);
 
5303
                                }
 
5304
                        }
 
5305
                };
 
5306
        }
 
5307
 
 
5308
        function increaseComplexityCount() {
 
5309
                funct["(metrics)"].ComplexityCount += 1;
 
5310
        }
 
5311
 
 
5312
 
 
5313
        (function (x) {
 
5314
                x.nud = function () {
 
5315
                        var b, f, i, p, t;
 
5316
                        var props = {}; // All properties, including accessors
 
5317
 
 
5318
                        function saveProperty(name, token) {
 
5319
                                if (props[name] && is_own(props, name))
 
5320
                                        warning("Duplicate member '{a}'.", nexttoken, i);
 
5321
                                else
 
5322
                                        props[name] = {};
 
5323
 
 
5324
                                props[name].basic = true;
 
5325
                                props[name].basicToken = token;
 
5326
                        }
 
5327
 
 
5328
                        function saveSetter(name, token) {
 
5329
                                if (props[name] && is_own(props, name)) {
 
5330
                                        if (props[name].basic || props[name].setter)
 
5331
                                                warning("Duplicate member '{a}'.", nexttoken, i);
 
5332
                                } else {
 
5333
                                        props[name] = {};
 
5334
                                }
 
5335
 
 
5336
                                props[name].setter = true;
 
5337
                                props[name].setterToken = token;
 
5338
                        }
 
5339
 
 
5340
                        function saveGetter(name) {
 
5341
                                if (props[name] && is_own(props, name)) {
 
5342
                                        if (props[name].basic || props[name].getter)
 
5343
                                                warning("Duplicate member '{a}'.", nexttoken, i);
 
5344
                                } else {
 
5345
                                        props[name] = {};
 
5346
                                }
 
5347
 
 
5348
                                props[name].getter = true;
 
5349
                                props[name].getterToken = token;
 
5350
                        }
 
5351
 
 
5352
                        b = token.line !== nexttoken.line;
 
5353
                        if (b) {
 
5354
                                indent += option.indent;
 
5355
                                if (nexttoken.from === indent + option.indent) {
 
5356
                                        indent += option.indent;
 
5357
                                }
 
5358
                        }
 
5359
                        for (;;) {
 
5360
                                if (nexttoken.id === "}") {
 
5361
                                        break;
 
5362
                                }
 
5363
                                if (b) {
 
5364
                                        indentation();
 
5365
                                }
 
5366
                                if (nexttoken.value === "get" && peek().id !== ":") {
 
5367
                                        advance("get");
 
5368
                                        if (!option.es5) {
 
5369
                                                error("get/set are ES5 features.");
 
5370
                                        }
 
5371
                                        i = property_name();
 
5372
                                        if (!i) {
 
5373
                                                error("Missing property name.");
 
5374
                                        }
 
5375
                                        saveGetter(i);
 
5376
                                        t = nexttoken;
 
5377
                                        adjacent(token, nexttoken);
 
5378
                                        f = doFunction();
 
5379
                                        p = f["(params)"];
 
5380
                                        if (p) {
 
5381
                                                warning("Unexpected parameter '{a}' in get {b} function.", t, p[0], i);
 
5382
                                        }
 
5383
                                        adjacent(token, nexttoken);
 
5384
                                } else if (nexttoken.value === "set" && peek().id !== ":") {
 
5385
                                        advance("set");
 
5386
                                        if (!option.es5) {
 
5387
                                                error("get/set are ES5 features.");
 
5388
                                        }
 
5389
                                        i = property_name();
 
5390
                                        if (!i) {
 
5391
                                                error("Missing property name.");
 
5392
                                        }
 
5393
                                        saveSetter(i, nexttoken);
 
5394
                                        t = nexttoken;
 
5395
                                        adjacent(token, nexttoken);
 
5396
                                        f = doFunction();
 
5397
                                        p = f["(params)"];
 
5398
                                        if (!p || p.length !== 1) {
 
5399
                                                warning("Expected a single parameter in set {a} function.", t, i);
 
5400
                                        }
 
5401
                                } else {
 
5402
                                        i = property_name();
 
5403
                                        saveProperty(i, nexttoken);
 
5404
                                        if (typeof i !== "string") {
 
5405
                                                break;
 
5406
                                        }
 
5407
                                        advance(":");
 
5408
                                        nonadjacent(token, nexttoken);
 
5409
                                        expression(10);
 
5410
                                }
 
5411
 
 
5412
                                countMember(i);
 
5413
                                if (nexttoken.id === ",") {
 
5414
                                        comma();
 
5415
                                        if (nexttoken.id === ",") {
 
5416
                                                warning("Extra comma.", token);
 
5417
                                        } else if (nexttoken.id === "}" && !option.es5) {
 
5418
                                                warning("Extra comma.", token);
 
5419
                                        }
 
5420
                                } else {
 
5421
                                        break;
 
5422
                                }
 
5423
                        }
 
5424
                        if (b) {
 
5425
                                indent -= option.indent;
 
5426
                                indentation();
 
5427
                        }
 
5428
                        advance("}", this);
 
5429
                        if (option.es5) {
 
5430
                                for (var name in props) {
 
5431
                                        if (is_own(props, name) && props[name].setter && !props[name].getter) {
 
5432
                                                warning("Setter is defined without getter.", props[name].setterToken);
 
5433
                                        }
 
5434
                                }
 
5435
                        }
 
5436
                        return this;
 
5437
                };
 
5438
                x.fud = function () {
 
5439
                        error("Expected to see a statement and instead saw a block.", token);
 
5440
                };
 
5441
        }(delim("{")));
 
5442
 
 
5443
        useESNextSyntax = function () {
 
5444
                var conststatement = stmt("const", function (prefix) {
 
5445
                        var id, name, value;
 
5446
 
 
5447
                        this.first = [];
 
5448
                        for (;;) {
 
5449
                                nonadjacent(token, nexttoken);
 
5450
                                id = identifier();
 
5451
                                if (funct[id] === "const") {
 
5452
                                        warning("const '" + id + "' has already been declared");
 
5453
                                }
 
5454
                                if (funct["(global)"] && predefined[id] === false) {
 
5455
                                        warning("Redefinition of '{a}'.", token, id);
 
5456
                                }
 
5457
                                addlabel(id, "const");
 
5458
                                if (prefix) {
 
5459
                                        break;
 
5460
                                }
 
5461
                                name = token;
 
5462
                                this.first.push(token);
 
5463
 
 
5464
                                if (nexttoken.id !== "=") {
 
5465
                                        warning("const " +
 
5466
                                          "'{a}' is initialized to 'undefined'.", token, id);
 
5467
                                }
 
5468
 
 
5469
                                if (nexttoken.id === "=") {
 
5470
                                        nonadjacent(token, nexttoken);
 
5471
                                        advance("=");
 
5472
                                        nonadjacent(token, nexttoken);
 
5473
                                        if (nexttoken.id === "undefined") {
 
5474
                                                warning("It is not necessary to initialize " +
 
5475
                                                  "'{a}' to 'undefined'.", token, id);
 
5476
                                        }
 
5477
                                        if (peek(0).id === "=" && nexttoken.identifier) {
 
5478
                                                error("Constant {a} was not declared correctly.",
 
5479
                                                                nexttoken, nexttoken.value);
 
5480
                                        }
 
5481
                                        value = expression(0);
 
5482
                                        name.first = value;
 
5483
                                }
 
5484
 
 
5485
                                if (nexttoken.id !== ",") {
 
5486
                                        break;
 
5487
                                }
 
5488
                                comma();
 
5489
                        }
 
5490
                        return this;
 
5491
                });
 
5492
                conststatement.exps = true;
 
5493
        };
 
5494
 
 
5495
        var varstatement = stmt("var", function (prefix) {
 
5496
                var id, name, value;
 
5497
 
 
5498
                if (funct["(onevar)"] && option.onevar) {
 
5499
                        warning("Too many var statements.");
 
5500
                } else if (!funct["(global)"]) {
 
5501
                        funct["(onevar)"] = true;
 
5502
                }
 
5503
 
 
5504
                this.first = [];
 
5505
 
 
5506
                for (;;) {
 
5507
                        nonadjacent(token, nexttoken);
 
5508
                        id = identifier();
 
5509
 
 
5510
                        if (option.esnext && funct[id] === "const") {
 
5511
                                warning("const '" + id + "' has already been declared");
 
5512
                        }
 
5513
 
 
5514
                        if (funct["(global)"] && predefined[id] === false) {
 
5515
                                warning("Redefinition of '{a}'.", token, id);
 
5516
                        }
 
5517
 
 
5518
                        addlabel(id, "unused", token);
 
5519
 
 
5520
                        if (prefix) {
 
5521
                                break;
 
5522
                        }
 
5523
 
 
5524
                        name = token;
 
5525
                        this.first.push(token);
 
5526
 
 
5527
                        if (nexttoken.id === "=") {
 
5528
                                nonadjacent(token, nexttoken);
 
5529
                                advance("=");
 
5530
                                nonadjacent(token, nexttoken);
 
5531
                                if (nexttoken.id === "undefined") {
 
5532
                                        warning("It is not necessary to initialize '{a}' to 'undefined'.", token, id);
 
5533
                                }
 
5534
                                if (peek(0).id === "=" && nexttoken.identifier) {
 
5535
                                        error("Variable {a} was not declared correctly.",
 
5536
                                                        nexttoken, nexttoken.value);
 
5537
                                }
 
5538
                                value = expression(0);
 
5539
                                name.first = value;
 
5540
                        }
 
5541
                        if (nexttoken.id !== ",") {
 
5542
                                break;
 
5543
                        }
 
5544
                        comma();
 
5545
                }
 
5546
                return this;
 
5547
        });
 
5548
        varstatement.exps = true;
 
5549
 
 
5550
        blockstmt("function", function () {
 
5551
                if (inblock) {
 
5552
                        warning("Function declarations should not be placed in blocks. " +
 
5553
                                "Use a function expression or move the statement to the top of " +
 
5554
                                "the outer function.", token);
 
5555
 
 
5556
                }
 
5557
                var i = identifier();
 
5558
                if (option.esnext && funct[i] === "const") {
 
5559
                        warning("const '" + i + "' has already been declared");
 
5560
                }
 
5561
                adjacent(token, nexttoken);
 
5562
                addlabel(i, "unction", token);
 
5563
 
 
5564
                doFunction(i, { statement: true });
 
5565
                if (nexttoken.id === "(" && nexttoken.line === token.line) {
 
5566
                        error(
 
5567
"Function declarations are not invocable. Wrap the whole function invocation in parens.");
 
5568
                }
 
5569
                return this;
 
5570
        });
 
5571
 
 
5572
        prefix("function", function () {
 
5573
                var i = optionalidentifier();
 
5574
                if (i) {
 
5575
                        adjacent(token, nexttoken);
 
5576
                } else {
 
5577
                        nonadjacent(token, nexttoken);
 
5578
                }
 
5579
                doFunction(i);
 
5580
                if (!option.loopfunc && funct["(loopage)"]) {
 
5581
                        warning("Don't make functions within a loop.");
 
5582
                }
 
5583
                return this;
 
5584
        });
 
5585
 
 
5586
        blockstmt("if", function () {
 
5587
                var t = nexttoken;
 
5588
                increaseComplexityCount();
 
5589
                advance("(");
 
5590
                nonadjacent(this, t);
 
5591
                nospace();
 
5592
                expression(20);
 
5593
                if (nexttoken.id === "=") {
 
5594
                        if (!option.boss)
 
5595
                                warning("Assignment in conditional expression");
 
5596
                        advance("=");
 
5597
                        expression(20);
 
5598
                }
 
5599
                advance(")", t);
 
5600
                nospace(prevtoken, token);
 
5601
                block(true, true);
 
5602
                if (nexttoken.id === "else") {
 
5603
                        nonadjacent(token, nexttoken);
 
5604
                        advance("else");
 
5605
                        if (nexttoken.id === "if" || nexttoken.id === "switch") {
 
5606
                                statement(true);
 
5607
                        } else {
 
5608
                                block(true, true);
 
5609
                        }
 
5610
                }
 
5611
                return this;
 
5612
        });
 
5613
 
 
5614
        blockstmt("try", function () {
 
5615
                var b;
 
5616
 
 
5617
                function doCatch() {
 
5618
                        var oldScope = scope;
 
5619
                        var e;
 
5620
 
 
5621
                        advance("catch");
 
5622
                        nonadjacent(token, nexttoken);
 
5623
                        advance("(");
 
5624
 
 
5625
                        scope = Object.create(oldScope);
 
5626
 
 
5627
                        e = nexttoken.value;
 
5628
                        if (nexttoken.type !== "(identifier)") {
 
5629
                                e = null;
 
5630
                                warning("Expected an identifier and instead saw '{a}'.", nexttoken, e);
 
5631
                        }
 
5632
 
 
5633
                        advance();
 
5634
                        advance(")");
 
5635
 
 
5636
                        funct = {
 
5637
                                "(name)"         : "(catch)",
 
5638
                                "(line)"         : nexttoken.line,
 
5639
                                "(character)": nexttoken.character,
 
5640
                                "(context)"  : funct,
 
5641
                                "(breakage)" : funct["(breakage)"],
 
5642
                                "(loopage)"  : funct["(loopage)"],
 
5643
                                "(scope)"        : scope,
 
5644
                                "(statement)": false,
 
5645
                                "(metrics)"  : createMetrics(nexttoken),
 
5646
                                "(catch)"        : true,
 
5647
                                "(tokens)"       : {}
 
5648
                        };
 
5649
 
 
5650
                        if (e) {
 
5651
                                addlabel(e, "exception");
 
5652
                        }
 
5653
 
 
5654
                        token.funct = funct;
 
5655
                        functions.push(funct);
 
5656
 
 
5657
                        block(false);
 
5658
 
 
5659
                        scope = oldScope;
 
5660
 
 
5661
                        funct["(last)"] = token.line;
 
5662
                        funct["(lastcharacter)"] = token.character;
 
5663
                        funct = funct["(context)"];
 
5664
                }
 
5665
 
 
5666
                block(false);
 
5667
 
 
5668
                if (nexttoken.id === "catch") {
 
5669
                        increaseComplexityCount();
 
5670
                        doCatch();
 
5671
                        b = true;
 
5672
                }
 
5673
 
 
5674
                if (nexttoken.id === "finally") {
 
5675
                        advance("finally");
 
5676
                        block(false);
 
5677
                        return;
 
5678
                } else if (!b) {
 
5679
                        error("Expected '{a}' and instead saw '{b}'.",
 
5680
                                        nexttoken, "catch", nexttoken.value);
 
5681
                }
 
5682
 
 
5683
                return this;
 
5684
        });
 
5685
 
 
5686
        blockstmt("while", function () {
 
5687
                var t = nexttoken;
 
5688
                funct["(breakage)"] += 1;
 
5689
                funct["(loopage)"] += 1;
 
5690
                increaseComplexityCount();
 
5691
                advance("(");
 
5692
                nonadjacent(this, t);
 
5693
                nospace();
 
5694
                expression(20);
 
5695
                if (nexttoken.id === "=") {
 
5696
                        if (!option.boss)
 
5697
                                warning("Assignment in conditional expression");
 
5698
                        advance("=");
 
5699
                        expression(20);
 
5700
                }
 
5701
                advance(")", t);
 
5702
                nospace(prevtoken, token);
 
5703
                block(true, true);
 
5704
                funct["(breakage)"] -= 1;
 
5705
                funct["(loopage)"] -= 1;
 
5706
                return this;
 
5707
        }).labelled = true;
 
5708
 
 
5709
        blockstmt("with", function () {
 
5710
                var t = nexttoken;
 
5711
                if (directive["use strict"]) {
 
5712
                        error("'with' is not allowed in strict mode.", token);
 
5713
                } else if (!option.withstmt) {
 
5714
                        warning("Don't use 'with'.", token);
 
5715
                }
 
5716
 
 
5717
                advance("(");
 
5718
                nonadjacent(this, t);
 
5719
                nospace();
 
5720
                expression(0);
 
5721
                advance(")", t);
 
5722
                nospace(prevtoken, token);
 
5723
                block(true, true);
 
5724
 
 
5725
                return this;
 
5726
        });
 
5727
 
 
5728
        blockstmt("switch", function () {
 
5729
                var t = nexttoken,
 
5730
                        g = false;
 
5731
                funct["(breakage)"] += 1;
 
5732
                advance("(");
 
5733
                nonadjacent(this, t);
 
5734
                nospace();
 
5735
                this.condition = expression(20);
 
5736
                advance(")", t);
 
5737
                nospace(prevtoken, token);
 
5738
                nonadjacent(token, nexttoken);
 
5739
                t = nexttoken;
 
5740
                advance("{");
 
5741
                nonadjacent(token, nexttoken);
 
5742
                indent += option.indent;
 
5743
                this.cases = [];
 
5744
                for (;;) {
 
5745
                        switch (nexttoken.id) {
 
5746
                        case "case":
 
5747
                                switch (funct["(verb)"]) {
 
5748
                                case "break":
 
5749
                                case "case":
 
5750
                                case "continue":
 
5751
                                case "return":
 
5752
                                case "switch":
 
5753
                                case "throw":
 
5754
                                        break;
 
5755
                                default:
 
5756
                                        if (!ft.test(lines[nexttoken.line - 2])) {
 
5757
                                                warning(
 
5758
                                                        "Expected a 'break' statement before 'case'.",
 
5759
                                                        token);
 
5760
                                        }
 
5761
                                }
 
5762
                                indentation(-option.indent);
 
5763
                                advance("case");
 
5764
                                this.cases.push(expression(20));
 
5765
                                increaseComplexityCount();
 
5766
                                g = true;
 
5767
                                advance(":");
 
5768
                                funct["(verb)"] = "case";
 
5769
                                break;
 
5770
                        case "default":
 
5771
                                switch (funct["(verb)"]) {
 
5772
                                case "break":
 
5773
                                case "continue":
 
5774
                                case "return":
 
5775
                                case "throw":
 
5776
                                        break;
 
5777
                                default:
 
5778
                                        if (!ft.test(lines[nexttoken.line - 2])) {
 
5779
                                                warning(
 
5780
                                                        "Expected a 'break' statement before 'default'.",
 
5781
                                                        token);
 
5782
                                        }
 
5783
                                }
 
5784
                                indentation(-option.indent);
 
5785
                                advance("default");
 
5786
                                g = true;
 
5787
                                advance(":");
 
5788
                                break;
 
5789
                        case "}":
 
5790
                                indent -= option.indent;
 
5791
                                indentation();
 
5792
                                advance("}", t);
 
5793
                                if (this.cases.length === 1 || this.condition.id === "true" ||
 
5794
                                                this.condition.id === "false") {
 
5795
                                        if (!option.onecase)
 
5796
                                                warning("This 'switch' should be an 'if'.", this);
 
5797
                                }
 
5798
                                funct["(breakage)"] -= 1;
 
5799
                                funct["(verb)"] = undefined;
 
5800
                                return;
 
5801
                        case "(end)":
 
5802
                                error("Missing '{a}'.", nexttoken, "}");
 
5803
                                return;
 
5804
                        default:
 
5805
                                if (g) {
 
5806
                                        switch (token.id) {
 
5807
                                        case ",":
 
5808
                                                error("Each value should have its own case label.");
 
5809
                                                return;
 
5810
                                        case ":":
 
5811
                                                g = false;
 
5812
                                                statements();
 
5813
                                                break;
 
5814
                                        default:
 
5815
                                                error("Missing ':' on a case clause.", token);
 
5816
                                                return;
 
5817
                                        }
 
5818
                                } else {
 
5819
                                        if (token.id === ":") {
 
5820
                                                advance(":");
 
5821
                                                error("Unexpected '{a}'.", token, ":");
 
5822
                                                statements();
 
5823
                                        } else {
 
5824
                                                error("Expected '{a}' and instead saw '{b}'.",
 
5825
                                                        nexttoken, "case", nexttoken.value);
 
5826
                                                return;
 
5827
                                        }
 
5828
                                }
 
5829
                        }
 
5830
                }
 
5831
        }).labelled = true;
 
5832
 
 
5833
        stmt("debugger", function () {
 
5834
                if (!option.debug) {
 
5835
                        warning("All 'debugger' statements should be removed.");
 
5836
                }
 
5837
                return this;
 
5838
        }).exps = true;
 
5839
 
 
5840
        (function () {
 
5841
                var x = stmt("do", function () {
 
5842
                        funct["(breakage)"] += 1;
 
5843
                        funct["(loopage)"] += 1;
 
5844
                        increaseComplexityCount();
 
5845
 
 
5846
                        this.first = block(true);
 
5847
                        advance("while");
 
5848
                        var t = nexttoken;
 
5849
                        nonadjacent(token, t);
 
5850
                        advance("(");
 
5851
                        nospace();
 
5852
                        expression(20);
 
5853
                        if (nexttoken.id === "=") {
 
5854
                                if (!option.boss)
 
5855
                                        warning("Assignment in conditional expression");
 
5856
                                advance("=");
 
5857
                                expression(20);
 
5858
                        }
 
5859
                        advance(")", t);
 
5860
                        nospace(prevtoken, token);
 
5861
                        funct["(breakage)"] -= 1;
 
5862
                        funct["(loopage)"] -= 1;
 
5863
                        return this;
 
5864
                });
 
5865
                x.labelled = true;
 
5866
                x.exps = true;
 
5867
        }());
 
5868
 
 
5869
        blockstmt("for", function () {
 
5870
                var s, t = nexttoken;
 
5871
                funct["(breakage)"] += 1;
 
5872
                funct["(loopage)"] += 1;
 
5873
                increaseComplexityCount();
 
5874
                advance("(");
 
5875
                nonadjacent(this, t);
 
5876
                nospace();
 
5877
                if (peek(nexttoken.id === "var" ? 1 : 0).id === "in") {
 
5878
                        if (nexttoken.id === "var") {
 
5879
                                advance("var");
 
5880
                                varstatement.fud.call(varstatement, true);
 
5881
                        } else {
 
5882
                                switch (funct[nexttoken.value]) {
 
5883
                                case "unused":
 
5884
                                        funct[nexttoken.value] = "var";
 
5885
                                        break;
 
5886
                                case "var":
 
5887
                                        break;
 
5888
                                default:
 
5889
                                        warning("Bad for in variable '{a}'.",
 
5890
                                                        nexttoken, nexttoken.value);
 
5891
                                }
 
5892
                                advance();
 
5893
                        }
 
5894
                        advance("in");
 
5895
                        expression(20);
 
5896
                        advance(")", t);
 
5897
                        s = block(true, true);
 
5898
                        if (option.forin && s && (s.length > 1 || typeof s[0] !== "object" ||
 
5899
                                        s[0].value !== "if")) {
 
5900
                                warning("The body of a for in should be wrapped in an if statement to filter " +
 
5901
                                                "unwanted properties from the prototype.", this);
 
5902
                        }
 
5903
                        funct["(breakage)"] -= 1;
 
5904
                        funct["(loopage)"] -= 1;
 
5905
                        return this;
 
5906
                } else {
 
5907
                        if (nexttoken.id !== ";") {
 
5908
                                if (nexttoken.id === "var") {
 
5909
                                        advance("var");
 
5910
                                        varstatement.fud.call(varstatement);
 
5911
                                } else {
 
5912
                                        for (;;) {
 
5913
                                                expression(0, "for");
 
5914
                                                if (nexttoken.id !== ",") {
 
5915
                                                        break;
 
5916
                                                }
 
5917
                                                comma();
 
5918
                                        }
 
5919
                                }
 
5920
                        }
 
5921
                        nolinebreak(token);
 
5922
                        advance(";");
 
5923
                        if (nexttoken.id !== ";") {
 
5924
                                expression(20);
 
5925
                                if (nexttoken.id === "=") {
 
5926
                                        if (!option.boss)
 
5927
                                                warning("Assignment in conditional expression");
 
5928
                                        advance("=");
 
5929
                                        expression(20);
 
5930
                                }
 
5931
                        }
 
5932
                        nolinebreak(token);
 
5933
                        advance(";");
 
5934
                        if (nexttoken.id === ";") {
 
5935
                                error("Expected '{a}' and instead saw '{b}'.",
 
5936
                                                nexttoken, ")", ";");
 
5937
                        }
 
5938
                        if (nexttoken.id !== ")") {
 
5939
                                for (;;) {
 
5940
                                        expression(0, "for");
 
5941
                                        if (nexttoken.id !== ",") {
 
5942
                                                break;
 
5943
                                        }
 
5944
                                        comma();
 
5945
                                }
 
5946
                        }
 
5947
                        advance(")", t);
 
5948
                        nospace(prevtoken, token);
 
5949
                        block(true, true);
 
5950
                        funct["(breakage)"] -= 1;
 
5951
                        funct["(loopage)"] -= 1;
 
5952
                        return this;
 
5953
                }
 
5954
        }).labelled = true;
 
5955
 
 
5956
 
 
5957
        stmt("break", function () {
 
5958
                var v = nexttoken.value;
 
5959
 
 
5960
                if (funct["(breakage)"] === 0)
 
5961
                        warning("Unexpected '{a}'.", nexttoken, this.value);
 
5962
 
 
5963
                if (!option.asi)
 
5964
                        nolinebreak(this);
 
5965
 
 
5966
                if (nexttoken.id !== ";") {
 
5967
                        if (token.line === nexttoken.line) {
 
5968
                                if (funct[v] !== "label") {
 
5969
                                        warning("'{a}' is not a statement label.", nexttoken, v);
 
5970
                                } else if (scope[v] !== funct) {
 
5971
                                        warning("'{a}' is out of scope.", nexttoken, v);
 
5972
                                }
 
5973
                                this.first = nexttoken;
 
5974
                                advance();
 
5975
                        }
 
5976
                }
 
5977
                reachable("break");
 
5978
                return this;
 
5979
        }).exps = true;
 
5980
 
 
5981
 
 
5982
        stmt("continue", function () {
 
5983
                var v = nexttoken.value;
 
5984
 
 
5985
                if (funct["(breakage)"] === 0)
 
5986
                        warning("Unexpected '{a}'.", nexttoken, this.value);
 
5987
 
 
5988
                if (!option.asi)
 
5989
                        nolinebreak(this);
 
5990
 
 
5991
                if (nexttoken.id !== ";") {
 
5992
                        if (token.line === nexttoken.line) {
 
5993
                                if (funct[v] !== "label") {
 
5994
                                        warning("'{a}' is not a statement label.", nexttoken, v);
 
5995
                                } else if (scope[v] !== funct) {
 
5996
                                        warning("'{a}' is out of scope.", nexttoken, v);
 
5997
                                }
 
5998
                                this.first = nexttoken;
 
5999
                                advance();
 
6000
                        }
 
6001
                } else if (!funct["(loopage)"]) {
 
6002
                        warning("Unexpected '{a}'.", nexttoken, this.value);
 
6003
                }
 
6004
                reachable("continue");
 
6005
                return this;
 
6006
        }).exps = true;
 
6007
 
 
6008
 
 
6009
        stmt("return", function () {
 
6010
                if (this.line === nexttoken.line) {
 
6011
                        if (nexttoken.id === "(regexp)")
 
6012
                                warning("Wrap the /regexp/ literal in parens to disambiguate the slash operator.");
 
6013
 
 
6014
                        if (nexttoken.id !== ";" && !nexttoken.reach) {
 
6015
                                nonadjacent(token, nexttoken);
 
6016
                                if (peek().value === "=" && !option.boss) {
 
6017
                                        warningAt("Did you mean to return a conditional instead of an assignment?",
 
6018
                                                          token.line, token.character + 1);
 
6019
                                }
 
6020
                                this.first = expression(0);
 
6021
                        }
 
6022
                } else if (!option.asi) {
 
6023
                        nolinebreak(this); // always warn (Line breaking error)
 
6024
                }
 
6025
                reachable("return");
 
6026
                return this;
 
6027
        }).exps = true;
 
6028
 
 
6029
 
 
6030
        stmt("throw", function () {
 
6031
                nolinebreak(this);
 
6032
                nonadjacent(token, nexttoken);
 
6033
                this.first = expression(20);
 
6034
                reachable("throw");
 
6035
                return this;
 
6036
        }).exps = true;
 
6037
 
 
6038
        reserve("class");
 
6039
        reserve("const");
 
6040
        reserve("enum");
 
6041
        reserve("export");
 
6042
        reserve("extends");
 
6043
        reserve("import");
 
6044
        reserve("super");
 
6045
 
 
6046
        reserve("let");
 
6047
        reserve("yield");
 
6048
        reserve("implements");
 
6049
        reserve("interface");
 
6050
        reserve("package");
 
6051
        reserve("private");
 
6052
        reserve("protected");
 
6053
        reserve("public");
 
6054
        reserve("static");
 
6055
 
 
6056
        function jsonValue() {
 
6057
 
 
6058
                function jsonObject() {
 
6059
                        var o = {}, t = nexttoken;
 
6060
                        advance("{");
 
6061
                        if (nexttoken.id !== "}") {
 
6062
                                for (;;) {
 
6063
                                        if (nexttoken.id === "(end)") {
 
6064
                                                error("Missing '}' to match '{' from line {a}.",
 
6065
                                                                nexttoken, t.line);
 
6066
                                        } else if (nexttoken.id === "}") {
 
6067
                                                warning("Unexpected comma.", token);
 
6068
                                                break;
 
6069
                                        } else if (nexttoken.id === ",") {
 
6070
                                                error("Unexpected comma.", nexttoken);
 
6071
                                        } else if (nexttoken.id !== "(string)") {
 
6072
                                                warning("Expected a string and instead saw {a}.",
 
6073
                                                                nexttoken, nexttoken.value);
 
6074
                                        }
 
6075
                                        if (o[nexttoken.value] === true) {
 
6076
                                                warning("Duplicate key '{a}'.",
 
6077
                                                                nexttoken, nexttoken.value);
 
6078
                                        } else if ((nexttoken.value === "__proto__" &&
 
6079
                                                !option.proto) || (nexttoken.value === "__iterator__" &&
 
6080
                                                !option.iterator)) {
 
6081
                                                warning("The '{a}' key may produce unexpected results.",
 
6082
                                                        nexttoken, nexttoken.value);
 
6083
                                        } else {
 
6084
                                                o[nexttoken.value] = true;
 
6085
                                        }
 
6086
                                        advance();
 
6087
                                        advance(":");
 
6088
                                        jsonValue();
 
6089
                                        if (nexttoken.id !== ",") {
 
6090
                                                break;
 
6091
                                        }
 
6092
                                        advance(",");
 
6093
                                }
 
6094
                        }
 
6095
                        advance("}");
 
6096
                }
 
6097
 
 
6098
                function jsonArray() {
 
6099
                        var t = nexttoken;
 
6100
                        advance("[");
 
6101
                        if (nexttoken.id !== "]") {
 
6102
                                for (;;) {
 
6103
                                        if (nexttoken.id === "(end)") {
 
6104
                                                error("Missing ']' to match '[' from line {a}.",
 
6105
                                                                nexttoken, t.line);
 
6106
                                        } else if (nexttoken.id === "]") {
 
6107
                                                warning("Unexpected comma.", token);
 
6108
                                                break;
 
6109
                                        } else if (nexttoken.id === ",") {
 
6110
                                                error("Unexpected comma.", nexttoken);
 
6111
                                        }
 
6112
                                        jsonValue();
 
6113
                                        if (nexttoken.id !== ",") {
 
6114
                                                break;
 
6115
                                        }
 
6116
                                        advance(",");
 
6117
                                }
 
6118
                        }
 
6119
                        advance("]");
 
6120
                }
 
6121
 
 
6122
                switch (nexttoken.id) {
 
6123
                case "{":
 
6124
                        jsonObject();
 
6125
                        break;
 
6126
                case "[":
 
6127
                        jsonArray();
 
6128
                        break;
 
6129
                case "true":
 
6130
                case "false":
 
6131
                case "null":
 
6132
                case "(number)":
 
6133
                case "(string)":
 
6134
                        advance();
 
6135
                        break;
 
6136
                case "-":
 
6137
                        advance("-");
 
6138
                        if (token.character !== nexttoken.from) {
 
6139
                                warning("Unexpected space after '-'.", token);
 
6140
                        }
 
6141
                        adjacent(token, nexttoken);
 
6142
                        advance("(number)");
 
6143
                        break;
 
6144
                default:
 
6145
                        error("Expected a JSON value.", nexttoken);
 
6146
                }
 
6147
        }
 
6148
        var itself = function (s, o, g) {
 
6149
                var a, i, k, x;
 
6150
                var optionKeys;
 
6151
                var newOptionObj = {};
 
6152
 
 
6153
                if (o && o.scope) {
 
6154
                        JSHINT.scope = o.scope;
 
6155
                } else {
 
6156
                        JSHINT.errors = [];
 
6157
                        JSHINT.undefs = [];
 
6158
                        JSHINT.internals = [];
 
6159
                        JSHINT.blacklist = {};
 
6160
                        JSHINT.scope = "(main)";
 
6161
                }
 
6162
 
 
6163
                predefined = Object.create(standard);
 
6164
                declared = Object.create(null);
 
6165
                combine(predefined, g || {});
 
6166
 
 
6167
                if (o) {
 
6168
                        a = o.predef;
 
6169
                        if (a) {
 
6170
                                if (!Array.isArray(a) && typeof a === "object") {
 
6171
                                        a = Object.keys(a);
 
6172
                                }
 
6173
                                a.forEach(function (item) {
 
6174
                                        var slice;
 
6175
                                        if (item[0] === "-") {
 
6176
                                                slice = item.slice(1);
 
6177
                                                JSHINT.blacklist[slice] = slice;
 
6178
                                        } else {
 
6179
                                                predefined[item] = true;
 
6180
                                        }
 
6181
                                });
 
6182
                        }
 
6183
 
 
6184
                        optionKeys = Object.keys(o);
 
6185
                        for (x = 0; x < optionKeys.length; x++) {
 
6186
                                newOptionObj[optionKeys[x]] = o[optionKeys[x]];
 
6187
 
 
6188
                                if (optionKeys[x] === "newcap" && o[optionKeys[x]] === false)
 
6189
                                        newOptionObj["(explicitNewcap)"] = true;
 
6190
 
 
6191
                                if (optionKeys[x] === "indent")
 
6192
                                        newOptionObj.white = true;
 
6193
                        }
 
6194
                }
 
6195
 
 
6196
                option = newOptionObj;
 
6197
 
 
6198
                option.indent = option.indent || 4;
 
6199
                option.maxerr = option.maxerr || 50;
 
6200
 
 
6201
                tab = "";
 
6202
                for (i = 0; i < option.indent; i += 1) {
 
6203
                        tab += " ";
 
6204
                }
 
6205
                indent = 1;
 
6206
                global = Object.create(predefined);
 
6207
                scope = global;
 
6208
                funct = {
 
6209
                        "(global)":   true,
 
6210
                        "(name)":         "(global)",
 
6211
                        "(scope)":        scope,
 
6212
                        "(breakage)": 0,
 
6213
                        "(loopage)":  0,
 
6214
                        "(tokens)":   {},
 
6215
                        "(metrics)":   createMetrics(nexttoken)
 
6216
                };
 
6217
                functions = [funct];
 
6218
                urls = [];
 
6219
                stack = null;
 
6220
                member = {};
 
6221
                membersOnly = null;
 
6222
                implied = {};
 
6223
                inblock = false;
 
6224
                lookahead = [];
 
6225
                jsonmode = false;
 
6226
                warnings = 0;
 
6227
                lines = [];
 
6228
                unuseds = [];
 
6229
 
 
6230
                if (!isString(s) && !Array.isArray(s)) {
 
6231
                        errorAt("Input is neither a string nor an array of strings.", 0);
 
6232
                        return false;
 
6233
                }
 
6234
 
 
6235
                if (isString(s) && /^\s*$/g.test(s)) {
 
6236
                        errorAt("Input is an empty string.", 0);
 
6237
                        return false;
 
6238
                }
 
6239
 
 
6240
                if (s.length === 0) {
 
6241
                        errorAt("Input is an empty array.", 0);
 
6242
                        return false;
 
6243
                }
 
6244
 
 
6245
                lex.init(s);
 
6246
 
 
6247
                prereg = true;
 
6248
                directive = {};
 
6249
 
 
6250
                prevtoken = token = nexttoken = syntax["(begin)"];
 
6251
                for (var name in o) {
 
6252
                        if (is_own(o, name)) {
 
6253
                                checkOption(name, token);
 
6254
                        }
 
6255
                }
 
6256
 
 
6257
                assume();
 
6258
                combine(predefined, g || {});
 
6259
                comma.first = true;
 
6260
                quotmark = undefined;
 
6261
 
 
6262
                try {
 
6263
                        advance();
 
6264
                        switch (nexttoken.id) {
 
6265
                        case "{":
 
6266
                        case "[":
 
6267
                                option.laxbreak = true;
 
6268
                                jsonmode = true;
 
6269
                                jsonValue();
 
6270
                                break;
 
6271
                        default:
 
6272
                                directives();
 
6273
                                if (directive["use strict"] && !option.globalstrict) {
 
6274
                                        warning("Use the function form of \"use strict\".", prevtoken);
 
6275
                                }
 
6276
 
 
6277
                                statements();
 
6278
                        }
 
6279
                        advance((nexttoken && nexttoken.value !== ".")  ? "(end)" : undefined);
 
6280
 
 
6281
                        var markDefined = function (name, context) {
 
6282
                                do {
 
6283
                                        if (typeof context[name] === "string") {
 
6284
 
 
6285
                                                if (context[name] === "unused")
 
6286
                                                        context[name] = "var";
 
6287
                                                else if (context[name] === "unction")
 
6288
                                                        context[name] = "closure";
 
6289
 
 
6290
                                                return true;
 
6291
                                        }
 
6292
 
 
6293
                                        context = context["(context)"];
 
6294
                                } while (context);
 
6295
 
 
6296
                                return false;
 
6297
                        };
 
6298
 
 
6299
                        var clearImplied = function (name, line) {
 
6300
                                if (!implied[name])
 
6301
                                        return;
 
6302
 
 
6303
                                var newImplied = [];
 
6304
                                for (var i = 0; i < implied[name].length; i += 1) {
 
6305
                                        if (implied[name][i] !== line)
 
6306
                                                newImplied.push(implied[name][i]);
 
6307
                                }
 
6308
 
 
6309
                                if (newImplied.length === 0)
 
6310
                                        delete implied[name];
 
6311
                                else
 
6312
                                        implied[name] = newImplied;
 
6313
                        };
 
6314
 
 
6315
                        var warnUnused = function (name, token) {
 
6316
                                var line = token.line;
 
6317
                                var chr  = token.character;
 
6318
 
 
6319
                                if (option.unused)
 
6320
                                        warningAt("'{a}' is defined but never used.", line, chr, name);
 
6321
 
 
6322
                                unuseds.push({
 
6323
                                        name: name,
 
6324
                                        line: line,
 
6325
                                        character: chr
 
6326
                                });
 
6327
                        };
 
6328
 
 
6329
                        var checkUnused = function (func, key) {
 
6330
                                var type = func[key];
 
6331
                                var token = func["(tokens)"][key];
 
6332
 
 
6333
                                if (key.charAt(0) === "(")
 
6334
                                        return;
 
6335
 
 
6336
                                if (type !== "unused" && type !== "unction")
 
6337
                                        return;
 
6338
                                if (func["(params)"] && func["(params)"].indexOf(key) !== -1)
 
6339
                                        return;
 
6340
 
 
6341
                                warnUnused(key, token);
 
6342
                        };
 
6343
                        for (i = 0; i < JSHINT.undefs.length; i += 1) {
 
6344
                                k = JSHINT.undefs[i].slice(0);
 
6345
 
 
6346
                                if (markDefined(k[2].value, k[0])) {
 
6347
                                        clearImplied(k[2].value, k[2].line);
 
6348
                                } else {
 
6349
                                        warning.apply(warning, k.slice(1));
 
6350
                                }
 
6351
                        }
 
6352
 
 
6353
                        functions.forEach(function (func) {
 
6354
                                for (var key in func) {
 
6355
                                        if (is_own(func, key)) {
 
6356
                                                checkUnused(func, key);
 
6357
                                        }
 
6358
                                }
 
6359
 
 
6360
                                if (!func["(params)"])
 
6361
                                        return;
 
6362
 
 
6363
                                var params = func["(params)"].slice();
 
6364
                                var param  = params.pop();
 
6365
                                var type;
 
6366
 
 
6367
                                while (param) {
 
6368
                                        type = func[param];
 
6369
 
 
6370
                                        if (param === "undefined")
 
6371
                                                return;
 
6372
 
 
6373
                                        if (type !== "unused" && type !== "unction")
 
6374
                                                return;
 
6375
 
 
6376
                                        warnUnused(param, func["(tokens)"][param]);
 
6377
                                        param = params.pop();
 
6378
                                }
 
6379
                        });
 
6380
 
 
6381
                        for (var key in declared) {
 
6382
                                if (is_own(declared, key) && !is_own(global, key)) {
 
6383
                                        warnUnused(key, declared[key]);
 
6384
                                }
 
6385
                        }
 
6386
                } catch (e) {
 
6387
                        if (e) {
 
6388
                                var nt = nexttoken || {};
 
6389
                                JSHINT.errors.push({
 
6390
                                        raw               : e.raw,
 
6391
                                        reason    : e.message,
 
6392
                                        line      : e.line || nt.line,
 
6393
                                        character : e.character || nt.from
 
6394
                                }, null);
 
6395
                        }
 
6396
                }
 
6397
 
 
6398
                if (JSHINT.scope === "(main)") {
 
6399
                        o = o || {};
 
6400
 
 
6401
                        for (i = 0; i < JSHINT.internals.length; i += 1) {
 
6402
                                k = JSHINT.internals[i];
 
6403
                                o.scope = k.elem;
 
6404
                                itself(k.value, o, g);
 
6405
                        }
 
6406
                }
 
6407
 
 
6408
                return JSHINT.errors.length === 0;
 
6409
        };
 
6410
        itself.data = function () {
 
6411
                var data = {
 
6412
                        functions: [],
 
6413
                        options: option
 
6414
                };
 
6415
                var implieds = [];
 
6416
                var members = [];
 
6417
                var fu, f, i, j, n, globals;
 
6418
 
 
6419
                if (itself.errors.length) {
 
6420
                        data.errors = itself.errors;
 
6421
                }
 
6422
 
 
6423
                if (jsonmode) {
 
6424
                        data.json = true;
 
6425
                }
 
6426
 
 
6427
                for (n in implied) {
 
6428
                        if (is_own(implied, n)) {
 
6429
                                implieds.push({
 
6430
                                        name: n,
 
6431
                                        line: implied[n]
 
6432
                                });
 
6433
                        }
 
6434
                }
 
6435
 
 
6436
                if (implieds.length > 0) {
 
6437
                        data.implieds = implieds;
 
6438
                }
 
6439
 
 
6440
                if (urls.length > 0) {
 
6441
                        data.urls = urls;
 
6442
                }
 
6443
 
 
6444
                globals = Object.keys(scope);
 
6445
                if (globals.length > 0) {
 
6446
                        data.globals = globals;
 
6447
                }
 
6448
 
 
6449
                for (i = 1; i < functions.length; i += 1) {
 
6450
                        f = functions[i];
 
6451
                        fu = {};
 
6452
 
 
6453
                        for (j = 0; j < functionicity.length; j += 1) {
 
6454
                                fu[functionicity[j]] = [];
 
6455
                        }
 
6456
 
 
6457
                        for (j = 0; j < functionicity.length; j += 1) {
 
6458
                                if (fu[functionicity[j]].length === 0) {
 
6459
                                        delete fu[functionicity[j]];
 
6460
                                }
 
6461
                        }
 
6462
 
 
6463
                        fu.name = f["(name)"];
 
6464
                        fu.param = f["(params)"];
 
6465
                        fu.line = f["(line)"];
 
6466
                        fu.character = f["(character)"];
 
6467
                        fu.last = f["(last)"];
 
6468
                        fu.lastcharacter = f["(lastcharacter)"];
 
6469
                        data.functions.push(fu);
 
6470
                }
 
6471
 
 
6472
                if (unuseds.length > 0) {
 
6473
                        data.unused = unuseds;
 
6474
                }
 
6475
 
 
6476
                members = [];
 
6477
                for (n in member) {
 
6478
                        if (typeof member[n] === "number") {
 
6479
                                data.member = member;
 
6480
                                break;
 
6481
                        }
 
6482
                }
 
6483
 
 
6484
                return data;
 
6485
        };
 
6486
 
 
6487
        itself.jshint = itself;
 
6488
 
 
6489
        return itself;
 
6490
}());
 
6491
if (typeof exports === "object" && exports) {
 
6492
        exports.JSHINT = JSHINT;
 
6493
}
 
6494
 
 
6495
});
 
 
b'\\ No newline at end of file'